CommunityHeader.vue 9.4 KB

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