OfficialHeader.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  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. {{ 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() && !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() && 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="station.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 && !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. currentSong.skipVotes
  136. }}</span>
  137. <span class="icon-purpose">Skip current song</span>
  138. </a>
  139. <a
  140. v-if="loggedIn && !noSong && !currentSong.simpleSong"
  141. class="sidebar-item"
  142. href="#"
  143. @click="
  144. openModal({
  145. sector: 'station',
  146. modal: 'report'
  147. })
  148. "
  149. >
  150. <span class="icon">
  151. <i class="material-icons">report</i>
  152. </span>
  153. <span class="icon-purpose">Report a song</span>
  154. </a>
  155. <a
  156. v-if="loggedIn && !noSong"
  157. class="sidebar-item"
  158. href="#"
  159. @click="
  160. openModal({
  161. sector: 'station',
  162. modal: 'addSongToPlaylist'
  163. })
  164. "
  165. >
  166. <span class="icon">
  167. <i class="material-icons">playlist_add</i>
  168. </span>
  169. <span class="icon-purpose"
  170. >Add current song to playlist</span
  171. >
  172. </a>
  173. <hr />
  174. </div>
  175. <a
  176. class="sidebar-item"
  177. href="#"
  178. @click="$parent.toggleSidebar('songslist')"
  179. >
  180. <span class="icon">
  181. <i class="material-icons">queue_music</i>
  182. </span>
  183. <span class="icon-purpose">Show the station queue</span>
  184. </a>
  185. <a
  186. class="sidebar-item"
  187. href="#"
  188. @click="$parent.toggleSidebar('users')"
  189. >
  190. <span class="icon">
  191. <i class="material-icons">people</i>
  192. </span>
  193. <span class="icon-purpose"
  194. >Display users in the station</span
  195. >
  196. </a>
  197. </div>
  198. </div>
  199. </div>
  200. </template>
  201. <script>
  202. import { mapState, mapActions } from "vuex";
  203. export default {
  204. data() {
  205. return {
  206. title: this.$route.params.id,
  207. isMobile: false,
  208. controlBar: false,
  209. frontendDomain: "",
  210. siteSettings: {
  211. logo: "",
  212. siteName: ""
  213. }
  214. };
  215. },
  216. computed: mapState({
  217. role: state => state.user.auth.role,
  218. username: state => state.user.auth.username,
  219. loggedIn: state => state.user.auth.loggedIn,
  220. station: state => state.station.station,
  221. currentSong: state => state.station.currentSong,
  222. paused: state => state.station.paused,
  223. noSong: state => state.station.noSong
  224. }),
  225. mounted() {
  226. lofig.get("frontendDomain", res => {
  227. this.frontendDomain = res;
  228. return res;
  229. });
  230. lofig.get("siteSettings", res => {
  231. this.siteSettings = res;
  232. return res;
  233. });
  234. },
  235. methods: {
  236. isOwner() {
  237. return this.loggedIn && this.role === "admin";
  238. },
  239. settings() {
  240. this.editStation({
  241. _id: this.station._id,
  242. name: this.station.name,
  243. type: this.station.type,
  244. partyMode: this.station.partyMode,
  245. description: this.station.description,
  246. privacy: this.station.privacy,
  247. displayName: this.station.displayName
  248. });
  249. this.openModal({
  250. sector: "station",
  251. modal: "editStation"
  252. });
  253. },
  254. ...mapActions("modals", ["openModal"]),
  255. ...mapActions("station", ["editStation"]),
  256. ...mapActions("user/auth", ["logout"])
  257. }
  258. };
  259. </script>
  260. <style lang="scss" scoped>
  261. @import "styles/global.scss";
  262. .nav {
  263. background-color: $primary-color;
  264. line-height: 64px;
  265. border-radius: 0% 0% 33% 33% / 0% 0% 7% 7%;
  266. .is-brand {
  267. font-size: 2.1rem !important;
  268. line-height: 64px !important;
  269. padding: 0 20px;
  270. color: $white;
  271. font-family: Pacifico, cursive;
  272. filter: brightness(0) invert(1);
  273. img {
  274. max-height: 38px;
  275. }
  276. }
  277. }
  278. a.nav-item {
  279. color: $white;
  280. font-size: 17px;
  281. &:hover {
  282. color: $white;
  283. }
  284. padding: 0 12px;
  285. .icon {
  286. height: 64px;
  287. i {
  288. font-size: 2rem;
  289. line-height: 64px;
  290. height: 64px;
  291. width: 34px;
  292. }
  293. }
  294. }
  295. a.nav-item.is-tab:hover {
  296. border-bottom: none;
  297. border-top: solid 1px $white;
  298. }
  299. .admin strong {
  300. color: $purple;
  301. }
  302. .grouped {
  303. margin: 0;
  304. display: flex;
  305. text-decoration: none;
  306. }
  307. .skip-votes {
  308. position: relative;
  309. left: 11px;
  310. }
  311. .nav-toggle {
  312. height: 64px;
  313. }
  314. @media screen and (max-width: 998px) {
  315. .nav-menu {
  316. background-color: $white;
  317. box-shadow: 0 4px 7px rgba(10, 10, 10, 0.1);
  318. left: 0;
  319. display: none;
  320. right: 0;
  321. top: 100%;
  322. position: absolute;
  323. }
  324. .nav-toggle {
  325. display: block;
  326. }
  327. }
  328. .logo {
  329. font-size: 2.1rem;
  330. line-height: 64px;
  331. padding-left: 20px !important;
  332. padding-right: 20px !important;
  333. }
  334. .nav-center {
  335. display: flex;
  336. align-items: center;
  337. color: $primary-color;
  338. font-size: 22px;
  339. position: absolute;
  340. margin: auto;
  341. top: 50%;
  342. left: 50%;
  343. transform: translate(-50%, -50%);
  344. }
  345. .nav-right.is-active .nav-item {
  346. background: $primary-color;
  347. border: 0;
  348. }
  349. .hidden {
  350. display: none;
  351. }
  352. .control-sidebar {
  353. position: fixed;
  354. z-index: 1;
  355. top: 0;
  356. left: 0;
  357. width: 64px;
  358. height: 100vh;
  359. background-color: $primary-color;
  360. box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16),
  361. 0 2px 10px 0 rgba(0, 0, 0, 0.12);
  362. @media (max-width: 998px) {
  363. display: none;
  364. }
  365. .inner-wrapper {
  366. @media (min-width: 999px) {
  367. .mobile-only {
  368. display: none;
  369. }
  370. .desktop-only {
  371. display: flex;
  372. }
  373. }
  374. @media (max-width: 998px) {
  375. .mobile-only {
  376. display: flex;
  377. }
  378. .desktop-only {
  379. display: none;
  380. visibility: hidden;
  381. }
  382. }
  383. }
  384. }
  385. .show-controlBar {
  386. display: block;
  387. }
  388. .inner-wrapper {
  389. top: 64px;
  390. position: relative;
  391. }
  392. .control-sidebar .material-icons {
  393. width: 100%;
  394. font-size: 2rem;
  395. }
  396. .control-sidebar .sidebar-item {
  397. font-size: 2rem;
  398. height: 50px;
  399. color: $white;
  400. -webkit-box-align: center;
  401. -ms-flex-align: center;
  402. align-items: center;
  403. display: -webkit-box;
  404. display: -ms-flexbox;
  405. display: flex;
  406. -webkit-box-flex: 0;
  407. -ms-flex-positive: 0;
  408. flex-grow: 0;
  409. -ms-flex-negative: 0;
  410. flex-shrink: 0;
  411. -webkit-box-pack: center;
  412. -ms-flex-pack: center;
  413. justify-content: center;
  414. width: 100%;
  415. position: relative;
  416. }
  417. .control-sidebar .sidebar-top-hr {
  418. margin: 0 0 20px 0;
  419. }
  420. .sidebar-item .icon-purpose {
  421. visibility: hidden;
  422. width: 160px;
  423. font-size: 12px;
  424. background-color: rgba(3, 169, 244, 0.8);
  425. color: $white;
  426. text-align: center;
  427. border-radius: 6px;
  428. padding: 5px;
  429. position: absolute;
  430. z-index: 1;
  431. left: 115%;
  432. opacity: 0;
  433. transition: opacity 0.5s;
  434. display: none;
  435. }
  436. .sidebar-item .icon-purpose::after {
  437. content: "";
  438. position: absolute;
  439. top: 50%;
  440. right: 100%;
  441. margin-top: -5px;
  442. border-width: 5px;
  443. border-style: solid;
  444. border-color: transparent rgba(3, 169, 244, 0.8) transparent transparent;
  445. }
  446. .sidebar-item:hover .icon-purpose {
  447. visibility: visible;
  448. opacity: 1;
  449. display: block;
  450. }
  451. </style>