index.vue 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <template>
  2. <div class="head-wrap">
  3. <div class="left">
  4. <div
  5. class="logo"
  6. @click="router.push('/')"
  7. >
  8. Billd直播
  9. </div>
  10. <div class="nav">
  11. <a
  12. :class="{
  13. item: 1,
  14. active: router.currentRoute.value.name === routerName.rank,
  15. }"
  16. href="/rank"
  17. @click.prevent="router.push({ name: routerName.rank })"
  18. >
  19. 排行榜
  20. </a>
  21. <a
  22. :class="{
  23. item: 1,
  24. active: router.currentRoute.value.name === routerName.support,
  25. }"
  26. href="/support"
  27. @click.prevent="router.push({ name: routerName.support })"
  28. >
  29. 付费支持
  30. </a>
  31. <div
  32. v-for="(item, index) in navLeftList.filter(
  33. (item) => router.currentRoute.value.query.liveType === item.liveType
  34. )"
  35. :key="index"
  36. :class="{
  37. item: 1,
  38. active: router.currentRoute.value.query.liveType === item.liveType,
  39. }"
  40. @click="goPushPage(item.routerName)"
  41. >
  42. {{ item.title }}
  43. </div>
  44. <div
  45. v-for="(item, index) in pullList.filter(
  46. (item) => router.currentRoute.value.query.liveType === item.liveType
  47. )"
  48. :key="index"
  49. :class="{
  50. item: 1,
  51. active: router.currentRoute.value.query.liveType === item.liveType,
  52. }"
  53. >
  54. {{ item.title }}
  55. </div>
  56. </div>
  57. </div>
  58. <div class="right">
  59. <div
  60. v-if="!userStore.userInfo"
  61. class="qqlogin"
  62. @click="useQQLogin()"
  63. >
  64. 登录
  65. </div>
  66. <n-dropdown
  67. v-else
  68. trigger="hover"
  69. :options="userOptions"
  70. @select="handleUserSelect"
  71. >
  72. <div
  73. class="qqlogin"
  74. :style="{ backgroundImage: `url(${userStore.userInfo.avatar})` }"
  75. @click="useQQLogin()"
  76. ></div>
  77. </n-dropdown>
  78. <a
  79. class="sponsors"
  80. href="/sponsors"
  81. @click.prevent="router.push({ name: routerName.sponsors })"
  82. >
  83. 赞助
  84. </a>
  85. <a
  86. class="about"
  87. href="/about"
  88. @click.prevent="router.push({ name: routerName.about })"
  89. >
  90. 关于
  91. </a>
  92. <a
  93. class="bilibili"
  94. target="_blank"
  95. href="https://space.bilibili.com/381307133/channel/seriesdetail?sid=3285689"
  96. >
  97. b站视频
  98. </a>
  99. <a
  100. class="github"
  101. target="_blank"
  102. href="https://github.com/galaxy-s10/billd-live"
  103. >
  104. <span class="txt">github</span>
  105. <img
  106. :src="githubStar"
  107. alt=""
  108. />
  109. </a>
  110. <n-dropdown
  111. v-if="router.currentRoute.value.name !== routerName.push"
  112. trigger="hover"
  113. :options="options"
  114. @select="handlePushSelect"
  115. >
  116. <div class="start-live">我要开播</div>
  117. </n-dropdown>
  118. </div>
  119. </div>
  120. </template>
  121. <script lang="ts" setup>
  122. import { openToTarget } from 'billd-utils';
  123. import { onMounted, ref } from 'vue';
  124. import { useRouter } from 'vue-router';
  125. import { useQQLogin } from '@/hooks/use-login';
  126. import { liveTypeEnum } from '@/interface';
  127. import { routerName } from '@/router';
  128. import { useUserStore } from '@/store/user';
  129. const router = useRouter();
  130. const userStore = useUserStore();
  131. const githubStar = ref('');
  132. const navLeftList = ref([
  133. {
  134. title: 'Webrtc Push',
  135. routerName: routerName.push,
  136. liveType: liveTypeEnum.webrtcPush,
  137. },
  138. {
  139. title: 'SRS WebRTC Push',
  140. routerName: routerName.push,
  141. liveType: liveTypeEnum.srsPush,
  142. },
  143. ]);
  144. const pullList = ref([
  145. {
  146. title: 'Webrtc Pull',
  147. routerName: routerName.pull,
  148. liveType: liveTypeEnum.webrtcPull,
  149. },
  150. {
  151. title: 'SRS WebRTC Pull Flv',
  152. routerName: routerName.pull,
  153. liveType: liveTypeEnum.srsFlvPull,
  154. },
  155. {
  156. title: 'SRS WebRTC Pull',
  157. routerName: routerName.pull,
  158. liveType: liveTypeEnum.srsWebrtcPull,
  159. },
  160. ]);
  161. const userOptions = ref([
  162. {
  163. label: '退出',
  164. key: '1',
  165. },
  166. ]);
  167. const options = ref([
  168. {
  169. label: 'webrtc开播',
  170. key: liveTypeEnum.webrtcPush,
  171. },
  172. {
  173. label: 'srs-webrtc开播',
  174. key: liveTypeEnum.srsPush,
  175. },
  176. ]);
  177. onMounted(() => {
  178. githubStar.value =
  179. 'https://img.shields.io/github/stars/galaxy-s10/billd-live?label=Star&logo=GitHub&labelColor=white&logoColor=black&style=social&cacheSeconds=3600';
  180. });
  181. function handleUserSelect(key) {
  182. if (key === '1') {
  183. userStore.logout();
  184. }
  185. }
  186. function handlePushSelect(key) {
  187. if (key === liveTypeEnum.webrtcPush || key === liveTypeEnum.srsPush) {
  188. const url = router.resolve({
  189. name: routerName.push,
  190. query: { liveType: key },
  191. });
  192. openToTarget(url.href);
  193. }
  194. }
  195. function goPushPage(routerName: string) {
  196. const url = router.resolve({ name: routerName });
  197. openToTarget(url.href);
  198. }
  199. </script>
  200. <style lang="scss" scoped>
  201. .head-wrap {
  202. display: flex;
  203. align-items: center;
  204. justify-content: space-between;
  205. min-width: $medium-width;
  206. height: 64px;
  207. background-color: #fff;
  208. box-shadow: inset 0 -1px #f1f2f3 !important;
  209. .left {
  210. display: flex;
  211. align-items: center;
  212. .logo {
  213. margin: 0 20px;
  214. width: 100px;
  215. height: 40px;
  216. background-color: skyblue;
  217. color: white;
  218. text-align: center;
  219. line-height: 40px;
  220. cursor: pointer;
  221. }
  222. .nav {
  223. display: flex;
  224. align-items: center;
  225. .item {
  226. position: relative;
  227. padding: 0 10px;
  228. color: black;
  229. text-decoration: none;
  230. cursor: pointer;
  231. &.active {
  232. &::after {
  233. position: absolute;
  234. bottom: -6px;
  235. left: 50%;
  236. width: 40% !important;
  237. height: 2px;
  238. background-color: red;
  239. content: '';
  240. transition: all 0.1s ease;
  241. transform: translateX(-50%);
  242. }
  243. }
  244. &::after {
  245. width: 0px !important;
  246. @extend .active;
  247. }
  248. &:hover {
  249. &::after {
  250. width: 40% !important;
  251. }
  252. }
  253. }
  254. }
  255. }
  256. .right {
  257. display: flex;
  258. align-items: center;
  259. margin-right: 20px;
  260. .qqlogin {
  261. box-sizing: border-box;
  262. margin-right: 15px;
  263. width: 35px;
  264. height: 35px;
  265. border-radius: 50%;
  266. background-color: skyblue;
  267. background-position: center;
  268. background-size: cover;
  269. background-repeat: no-repeat;
  270. color: white;
  271. text-align: center;
  272. font-size: 13px;
  273. line-height: 35px;
  274. cursor: pointer;
  275. }
  276. .sponsors,
  277. .bilibili,
  278. .about,
  279. .github {
  280. position: relative;
  281. margin-right: 15px;
  282. border-radius: 6px;
  283. color: black;
  284. text-decoration: none;
  285. font-size: 14px;
  286. cursor: pointer;
  287. &.active {
  288. &::after {
  289. position: absolute;
  290. bottom: -6px;
  291. left: 50%;
  292. width: 40%;
  293. height: 2px;
  294. background-color: red;
  295. content: '';
  296. transition: all 0.1s ease;
  297. transform: translateX(-50%);
  298. }
  299. }
  300. &::after {
  301. width: 0px !important;
  302. @extend .active;
  303. }
  304. &:hover {
  305. &::after {
  306. width: 40% !important;
  307. }
  308. }
  309. }
  310. .github {
  311. display: flex;
  312. align-items: center;
  313. .txt {
  314. margin-right: 5px;
  315. }
  316. }
  317. .start-live {
  318. margin-right: 10px;
  319. padding: 5px 10px;
  320. border-radius: 6px;
  321. background-color: skyblue;
  322. color: white;
  323. font-size: 14px;
  324. cursor: pointer;
  325. }
  326. }
  327. }
  328. </style>