index.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <template>
  2. <div id="queue">
  3. <div
  4. id="queue-items"
  5. :class="{
  6. 'actionable-button-hidden': !actionableButtonVisible,
  7. 'scrollable-list': true
  8. }"
  9. >
  10. <queue-item
  11. v-for="(song, index) in songsList"
  12. :key="index + song.songId"
  13. :song="song"
  14. :station="{
  15. type: station.type,
  16. partyMode: station.partyMode
  17. }"
  18. />
  19. <p class="nothing-here-text" v-if="songsList.length < 1">
  20. There are no songs currently queued
  21. </p>
  22. </div>
  23. <button
  24. class="button is-primary tab-actionable-button"
  25. v-if="
  26. loggedIn &&
  27. ((station.type === 'community' &&
  28. station.partyMode &&
  29. ((station.locked && isOwnerOnly()) ||
  30. !station.locked ||
  31. (station.locked &&
  32. isAdminOnly() &&
  33. dismissedWarning))) ||
  34. station.type === 'official')
  35. "
  36. @click="
  37. openModal({
  38. sector: 'station',
  39. modal: 'addSongToQueue'
  40. })
  41. "
  42. >
  43. <i class="material-icons icon-with-button">queue</i>
  44. <span class="optional-desktop-only-text"> Add Song To Queue </span>
  45. </button>
  46. <button
  47. class="button is-primary tab-actionable-button tooltip tooltip-top tooltip-center disabled"
  48. v-if="
  49. !loggedIn &&
  50. ((station.type === 'community' &&
  51. station.partyMode &&
  52. !station.locked) ||
  53. station.type === 'official')
  54. "
  55. data-tooltip="Login to add songs to queue"
  56. >
  57. <i class="material-icons icon-with-button">queue</i>
  58. <span class="optional-desktop-only-text"> Add Song To Queue </span>
  59. </button>
  60. <div
  61. id="queue-locked"
  62. v-if="station.type === 'community' && station.locked"
  63. >
  64. <button
  65. v-if="isAdminOnly() && !isOwnerOnly() && !dismissedWarning"
  66. class="button tab-actionable-button"
  67. @click="dismissedWarning = true"
  68. >
  69. THIS STATION'S QUEUE IS LOCKED.
  70. </button>
  71. <button
  72. v-if="!isAdminOnly() && !isOwnerOnly()"
  73. class="button tab-actionable-button"
  74. >
  75. THIS STATION'S QUEUE IS LOCKED.
  76. </button>
  77. </div>
  78. </div>
  79. </template>
  80. <script>
  81. import { mapActions, mapState, mapGetters } from "vuex";
  82. import Toast from "toasters";
  83. import QueueItem from "./QueueItem.vue";
  84. export default {
  85. components: { QueueItem },
  86. data() {
  87. return {
  88. dismissedWarning: false,
  89. actionableButtonVisible: false
  90. };
  91. },
  92. computed: {
  93. ...mapState({
  94. loggedIn: state => state.user.auth.loggedIn,
  95. userId: state => state.user.auth.userId,
  96. userRole: state => state.user.auth.role,
  97. station: state => state.station.station,
  98. songsList: state => state.station.songsList,
  99. noSong: state => state.station.noSong
  100. }),
  101. ...mapGetters({
  102. socket: "websockets/getSocket"
  103. })
  104. },
  105. updated() {
  106. // check if actionable button is visible, if not: set max-height of queue items to 100%
  107. if (
  108. document
  109. .getElementById("queue")
  110. .querySelectorAll(".tab-actionable-button").length > 0
  111. )
  112. this.actionableButtonVisible = true;
  113. else this.actionableButtonVisible = false;
  114. },
  115. methods: {
  116. isOwnerOnly() {
  117. return this.loggedIn && this.userId === this.station.owner;
  118. },
  119. isAdminOnly() {
  120. return this.loggedIn && this.userRole === "admin";
  121. },
  122. removeFromQueue(songId) {
  123. this.socket.dispatch(
  124. "stations.removeFromQueue",
  125. this.station._id,
  126. songId,
  127. res => {
  128. if (res.status === "success") {
  129. new Toast({
  130. content:
  131. "Successfully removed song from the queue.",
  132. timeout: 4000
  133. });
  134. } else new Toast({ content: res.message, timeout: 8000 });
  135. }
  136. );
  137. },
  138. ...mapActions("modalVisibility", ["openModal"])
  139. }
  140. };
  141. </script>
  142. <style lang="scss" scoped>
  143. .night-mode {
  144. #queue {
  145. background-color: var(--dark-grey-3) !important;
  146. border: 0 !important;
  147. }
  148. }
  149. #queue {
  150. background-color: var(--white);
  151. border-radius: 0 0 5px 5px;
  152. .actionable-button-hidden {
  153. max-height: 100%;
  154. }
  155. .queue-item:not(:last-of-type) {
  156. margin-bottom: 10px;
  157. }
  158. #queue-locked {
  159. display: flex;
  160. justify-content: center;
  161. }
  162. button.disabled {
  163. filter: grayscale(0.4);
  164. }
  165. }
  166. </style>