OfficialHeader.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. <template>
  2. <div>
  3. <nav class="nav">
  4. <div class="nav-left">
  5. <router-link class="nav-item is-brand" to="/">
  6. <img
  7. :src="`${this.siteSettings.logo}`"
  8. :alt="`${this.siteSettings.siteName}` || `Musare`"
  9. />
  10. </router-link>
  11. </div>
  12. <div class="nav-center stationDisplayName">
  13. {{ $parent.station.displayName }}
  14. </div>
  15. <span class="nav-toggle" v-on:click="controlBar = !controlBar">
  16. <span />
  17. <span />
  18. <span />
  19. </span>
  20. <div class="nav-right nav-menu" :class="{ 'is-active': isMobile }">
  21. <router-link
  22. v-if="role === 'admin'"
  23. class="nav-item is-tab admin"
  24. href="#"
  25. :to="{ path: '/admin' }"
  26. >
  27. <strong>Admin</strong>
  28. </router-link>
  29. <span v-if="loggedIn" class="grouped">
  30. <router-link
  31. class="nav-item is-tab"
  32. href="#"
  33. :to="{ path: '/u/' + username }"
  34. >Profile</router-link
  35. >
  36. <router-link class="nav-item is-tab" to="/settings"
  37. >Settings</router-link
  38. >
  39. <a class="nav-item is-tab" @click="logout()">Logout</a>
  40. </span>
  41. <span v-else class="grouped">
  42. <a
  43. class="nav-item"
  44. href="#"
  45. @click="openModal({ sector: 'header', modal: 'login' })"
  46. >Login</a
  47. >
  48. <a
  49. class="nav-item"
  50. href="#"
  51. @click="
  52. openModal({ sector: 'header', modal: 'register' })
  53. "
  54. >Register</a
  55. >
  56. </span>
  57. </div>
  58. </nav>
  59. <div class="control-sidebar" :class="{ 'show-controlBar': controlBar }">
  60. <div class="inner-wrapper">
  61. <div v-if="isOwner()">
  62. <a
  63. v-if="isOwner()"
  64. class="sidebar-item"
  65. href="#"
  66. @click="settings()"
  67. >
  68. <span class="icon">
  69. <i class="material-icons">settings</i>
  70. </span>
  71. <span class="icon-purpose">Station settings</span>
  72. </a>
  73. <a
  74. v-if="isOwner()"
  75. class="sidebar-item"
  76. href="#"
  77. @click="$parent.skipStation()"
  78. >
  79. <span class="icon">
  80. <i class="material-icons">skip_next</i>
  81. </span>
  82. <span class="icon-purpose">Skip current song</span>
  83. </a>
  84. <a
  85. v-if="isOwner() && !$parent.paused"
  86. class="sidebar-item"
  87. href="#"
  88. @click="$parent.pauseStation()"
  89. >
  90. <span class="icon">
  91. <i class="material-icons">pause</i>
  92. </span>
  93. <span class="icon-purpose">Pause station</span>
  94. </a>
  95. <a
  96. v-if="isOwner() && $parent.paused"
  97. class="sidebar-item"
  98. href="#"
  99. @click="$parent.resumeStation()"
  100. >
  101. <span class="icon">
  102. <i class="material-icons">play_arrow</i>
  103. </span>
  104. <span class="icon-purpose">Resume station</span>
  105. </a>
  106. <hr />
  107. </div>
  108. <div v-if="loggedIn">
  109. <a
  110. v-if="$parent.type === 'official' && loggedIn"
  111. class="sidebar-item"
  112. href="#"
  113. @click="
  114. openModal({
  115. sector: 'station',
  116. modal: 'addSongToQueue'
  117. })
  118. "
  119. >
  120. <span class="icon">
  121. <i class="material-icons">queue</i>
  122. </span>
  123. <span class="icon-purpose">Add song to queue</span>
  124. </a>
  125. <a
  126. v-if="!isOwner() && loggedIn && !$parent.noSong"
  127. class="sidebar-item"
  128. href="#"
  129. @click="$parent.voteSkipStation()"
  130. >
  131. <span class="icon">
  132. <i class="material-icons">skip_next</i>
  133. </span>
  134. <span class="skip-votes">{{
  135. $parent.currentSong.skipVotes
  136. }}</span>
  137. <span class="icon-purpose">Skip current song</span>
  138. </a>
  139. <a
  140. v-if="
  141. loggedIn && !$parent.noSong && !$parent.simpleSong
  142. "
  143. class="sidebar-item"
  144. href="#"
  145. @click="
  146. openModal({
  147. sector: 'station',
  148. modal: 'report'
  149. })
  150. "
  151. >
  152. <span class="icon">
  153. <i class="material-icons">report</i>
  154. </span>
  155. <span class="icon-purpose">Report a song</span>
  156. </a>
  157. <a
  158. v-if="loggedIn && !$parent.noSong"
  159. class="sidebar-item"
  160. href="#"
  161. @click="
  162. openModal({
  163. sector: 'station',
  164. modal: 'addSongToPlaylist'
  165. })
  166. "
  167. >
  168. <span class="icon">
  169. <i class="material-icons">playlist_add</i>
  170. </span>
  171. <span class="icon-purpose"
  172. >Add current song to playlist</span
  173. >
  174. </a>
  175. <hr />
  176. </div>
  177. <a
  178. class="sidebar-item"
  179. href="#"
  180. @click="$parent.toggleSidebar('songslist')"
  181. >
  182. <span class="icon">
  183. <i class="material-icons">queue_music</i>
  184. </span>
  185. <span class="icon-purpose">Show the station queue</span>
  186. </a>
  187. <a
  188. class="sidebar-item"
  189. href="#"
  190. @click="$parent.toggleSidebar('users')"
  191. >
  192. <span class="icon">
  193. <i class="material-icons">people</i>
  194. </span>
  195. <span class="icon-purpose"
  196. >Display users in the station</span
  197. >
  198. </a>
  199. </div>
  200. </div>
  201. </div>
  202. </template>
  203. <script>
  204. import { mapState, mapActions } from "vuex";
  205. export default {
  206. data() {
  207. return {
  208. title: this.$route.params.id,
  209. isMobile: false,
  210. controlBar: false,
  211. frontendDomain: "",
  212. siteSettings: {
  213. logo: "",
  214. siteName: ""
  215. }
  216. };
  217. },
  218. computed: mapState({
  219. role: state => state.user.auth.role,
  220. username: state => state.user.auth.username,
  221. loggedIn: state => state.user.auth.loggedIn
  222. }),
  223. mounted() {
  224. lofig.get("frontendDomain", res => {
  225. this.frontendDomain = res;
  226. return res;
  227. });
  228. lofig.get("siteSettings", res => {
  229. this.siteSettings = res;
  230. return res;
  231. });
  232. },
  233. methods: {
  234. isOwner() {
  235. return this.loggedIn && this.role === "admin";
  236. },
  237. settings() {
  238. this.editStation({
  239. _id: this.$parent.station._id,
  240. name: this.$parent.station.name,
  241. type: this.$parent.type,
  242. partyMode: this.$parent.station.partyMode,
  243. description: this.$parent.station.description,
  244. privacy: this.$parent.station.privacy,
  245. displayName: this.$parent.station.displayName
  246. });
  247. this.openModal({
  248. sector: "station",
  249. modal: "editStation"
  250. });
  251. },
  252. ...mapActions("modals", ["openModal"]),
  253. ...mapActions("station", ["editStation"]),
  254. ...mapActions("user/auth", ["logout"])
  255. }
  256. };
  257. </script>
  258. <style lang="scss" scoped>
  259. @import "styles/global.scss";
  260. .nav {
  261. background-color: $primary-color;
  262. line-height: 64px;
  263. border-radius: 0% 0% 33% 33% / 0% 0% 7% 7%;
  264. .is-brand {
  265. font-size: 2.1rem !important;
  266. line-height: 64px !important;
  267. padding: 0 20px;
  268. color: #ffffff;
  269. font-family: Pacifico, cursive;
  270. filter: brightness(0) invert(1);
  271. img {
  272. max-height: 38px;
  273. }
  274. }
  275. }
  276. a.nav-item {
  277. color: #ffffff;
  278. font-size: 17px;
  279. &:hover {
  280. color: #ffffff;
  281. }
  282. padding: 0 12px;
  283. .icon {
  284. height: 64px;
  285. i {
  286. font-size: 2rem;
  287. line-height: 64px;
  288. height: 64px;
  289. width: 34px;
  290. }
  291. }
  292. }
  293. a.nav-item.is-tab:hover {
  294. border-bottom: none;
  295. border-top: solid 1px #ffffff;
  296. }
  297. .admin strong {
  298. color: #9d42b1;
  299. }
  300. .grouped {
  301. margin: 0;
  302. display: flex;
  303. text-decoration: none;
  304. }
  305. .skip-votes {
  306. position: relative;
  307. left: 11px;
  308. }
  309. .nav-toggle {
  310. height: 64px;
  311. }
  312. @media screen and (max-width: 998px) {
  313. .nav-menu {
  314. background-color: white;
  315. box-shadow: 0 4px 7px rgba(10, 10, 10, 0.1);
  316. left: 0;
  317. display: none;
  318. right: 0;
  319. top: 100%;
  320. position: absolute;
  321. }
  322. .nav-toggle {
  323. display: block;
  324. }
  325. }
  326. .logo {
  327. font-size: 2.1rem;
  328. line-height: 64px;
  329. padding-left: 20px !important;
  330. padding-right: 20px !important;
  331. }
  332. .nav-center {
  333. display: flex;
  334. align-items: center;
  335. color: $primary-color;
  336. font-size: 22px;
  337. position: absolute;
  338. margin: auto;
  339. top: 50%;
  340. left: 50%;
  341. transform: translate(-50%, -50%);
  342. }
  343. .nav-right.is-active .nav-item {
  344. background: $primary-color;
  345. border: 0;
  346. }
  347. .hidden {
  348. display: none;
  349. }
  350. .control-sidebar {
  351. position: fixed;
  352. z-index: 1;
  353. top: 0;
  354. left: 0;
  355. width: 64px;
  356. height: 100vh;
  357. background-color: $primary-color;
  358. box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16),
  359. 0 2px 10px 0 rgba(0, 0, 0, 0.12);
  360. @media (max-width: 998px) {
  361. display: none;
  362. }
  363. .inner-wrapper {
  364. @media (min-width: 999px) {
  365. .mobile-only {
  366. display: none;
  367. }
  368. .desktop-only {
  369. display: flex;
  370. }
  371. }
  372. @media (max-width: 998px) {
  373. .mobile-only {
  374. display: flex;
  375. }
  376. .desktop-only {
  377. display: none;
  378. visibility: hidden;
  379. }
  380. }
  381. }
  382. }
  383. .show-controlBar {
  384. display: block;
  385. }
  386. .inner-wrapper {
  387. top: 64px;
  388. position: relative;
  389. }
  390. .control-sidebar .material-icons {
  391. width: 100%;
  392. font-size: 2rem;
  393. }
  394. .control-sidebar .sidebar-item {
  395. font-size: 2rem;
  396. height: 50px;
  397. color: white;
  398. -webkit-box-align: center;
  399. -ms-flex-align: center;
  400. align-items: center;
  401. display: -webkit-box;
  402. display: -ms-flexbox;
  403. display: flex;
  404. -webkit-box-flex: 0;
  405. -ms-flex-positive: 0;
  406. flex-grow: 0;
  407. -ms-flex-negative: 0;
  408. flex-shrink: 0;
  409. -webkit-box-pack: center;
  410. -ms-flex-pack: center;
  411. justify-content: center;
  412. width: 100%;
  413. position: relative;
  414. }
  415. .control-sidebar .sidebar-top-hr {
  416. margin: 0 0 20px 0;
  417. }
  418. .sidebar-item .icon-purpose {
  419. visibility: hidden;
  420. width: 160px;
  421. font-size: 12px;
  422. background-color: rgba(3, 169, 244, 0.8);
  423. color: #fff;
  424. text-align: center;
  425. border-radius: 6px;
  426. padding: 5px;
  427. position: absolute;
  428. z-index: 1;
  429. left: 115%;
  430. opacity: 0;
  431. transition: opacity 0.5s;
  432. display: none;
  433. }
  434. .sidebar-item .icon-purpose::after {
  435. content: "";
  436. position: absolute;
  437. top: 50%;
  438. right: 100%;
  439. margin-top: -5px;
  440. border-width: 5px;
  441. border-style: solid;
  442. border-color: transparent rgba(3, 169, 244, 0.8) transparent transparent;
  443. }
  444. .sidebar-item:hover .icon-purpose {
  445. visibility: visible;
  446. opacity: 1;
  447. display: block;
  448. }
  449. </style>