index.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. <div
  47. id="queue-locked"
  48. v-if="station.type === 'community' && station.locked"
  49. >
  50. <button
  51. v-if="isAdminOnly() && !isOwnerOnly() && !dismissedWarning"
  52. class="button tab-actionable-button"
  53. @click="dismissedWarning = true"
  54. >
  55. THIS STATION'S QUEUE IS LOCKED.
  56. </button>
  57. <button
  58. v-if="!isAdminOnly() && !isOwnerOnly()"
  59. class="button tab-actionable-button"
  60. >
  61. THIS STATION'S QUEUE IS LOCKED.
  62. </button>
  63. </div>
  64. </div>
  65. </template>
  66. <script>
  67. import { mapActions, mapState } from "vuex";
  68. import Toast from "toasters";
  69. import QueueItem from "./QueueItem.vue";
  70. export default {
  71. components: { QueueItem },
  72. data() {
  73. return {
  74. dismissedWarning: false,
  75. actionableButtonVisible: false
  76. };
  77. },
  78. computed: mapState({
  79. loggedIn: state => state.user.auth.loggedIn,
  80. userId: state => state.user.auth.userId,
  81. userRole: state => state.user.auth.role,
  82. station: state => state.station.station,
  83. songsList: state => state.station.songsList,
  84. noSong: state => state.station.noSong
  85. }),
  86. updated() {
  87. // check if actionable button is visible, if not: set max-height of queue items to 100%
  88. if (
  89. document
  90. .getElementById("queue")
  91. .querySelectorAll(".tab-actionable-button").length > 0
  92. )
  93. this.actionableButtonVisible = true;
  94. else this.actionableButtonVisible = false;
  95. },
  96. methods: {
  97. isOwnerOnly() {
  98. return this.loggedIn && this.userId === this.station.owner;
  99. },
  100. isAdminOnly() {
  101. return this.loggedIn && this.userRole === "admin";
  102. },
  103. removeFromQueue(songId) {
  104. window.socket.emit(
  105. "stations.removeFromQueue",
  106. this.station._id,
  107. songId,
  108. res => {
  109. if (res.status === "success") {
  110. new Toast({
  111. content:
  112. "Successfully removed song from the queue.",
  113. timeout: 4000
  114. });
  115. } else new Toast({ content: res.message, timeout: 8000 });
  116. }
  117. );
  118. },
  119. ...mapActions("modalVisibility", ["openModal"])
  120. }
  121. };
  122. </script>
  123. <style lang="scss" scoped>
  124. @import "../../../../../styles/global.scss";
  125. .night-mode {
  126. #queue {
  127. background-color: $night-mode-bg-secondary !important;
  128. border: 0 !important;
  129. }
  130. }
  131. #queue {
  132. background-color: #fff;
  133. border-radius: 0 0 5px 5px;
  134. .actionable-button-hidden {
  135. max-height: 100%;
  136. }
  137. .queue-item:not(:last-of-type) {
  138. margin-bottom: 10px;
  139. }
  140. #queue-locked {
  141. display: flex;
  142. justify-content: center;
  143. }
  144. }
  145. </style>