StationInfoBox.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <script setup lang="ts">
  2. import { computed } from "vue";
  3. import { useStore } from "vuex";
  4. import Toast from "toasters";
  5. const store = useStore();
  6. const props = defineProps({
  7. station: { type: Object, default: null },
  8. stationPaused: { type: Boolean, default: null },
  9. showManageStation: { type: Boolean, default: false },
  10. showGoToStation: { type: Boolean, default: false }
  11. });
  12. const loggedIn = computed(() => store.state.user.auth.loggedIn);
  13. const userId = computed(() => store.state.user.auth.userId);
  14. const role = computed(() => store.state.user.auth.role);
  15. const { socket } = store.state.websockets;
  16. const isOwnerOnly = () =>
  17. loggedIn.value && userId.value === props.station.owner;
  18. const isAdminOnly = () => loggedIn.value && role.value === "admin";
  19. const isOwnerOrAdmin = () => isOwnerOnly() || isAdminOnly();
  20. const resumeStation = () => {
  21. socket.dispatch("stations.resume", props.station._id, data => {
  22. if (data.status !== "success") new Toast(`Error: ${data.message}`);
  23. else new Toast("Successfully resumed the station.");
  24. });
  25. };
  26. const pauseStation = () => {
  27. socket.dispatch("stations.pause", props.station._id, data => {
  28. if (data.status !== "success") new Toast(`Error: ${data.message}`);
  29. else new Toast("Successfully paused the station.");
  30. });
  31. };
  32. const skipStation = () => {
  33. socket.dispatch("stations.forceSkip", props.station._id, data => {
  34. if (data.status !== "success") new Toast(`Error: ${data.message}`);
  35. else new Toast("Successfully skipped the station's current song.");
  36. });
  37. };
  38. const favoriteStation = () => {
  39. socket.dispatch("stations.favoriteStation", props.station._id, res => {
  40. if (res.status === "success") {
  41. new Toast("Successfully favorited station.");
  42. } else new Toast(res.message);
  43. });
  44. };
  45. const unfavoriteStation = () => {
  46. socket.dispatch("stations.unfavoriteStation", props.station._id, res => {
  47. if (res.status === "success") {
  48. new Toast("Successfully unfavorited station.");
  49. } else new Toast(res.message);
  50. });
  51. };
  52. const openModal = payload =>
  53. store.dispatch("modalVisibility/openModal", payload);
  54. </script>
  55. <template>
  56. <div class="about-station-container">
  57. <div class="station-info">
  58. <div class="row station-name">
  59. <h1>{{ station.displayName }}</h1>
  60. <i
  61. v-if="station.type === 'official'"
  62. class="material-icons verified-station"
  63. content="Verified Station"
  64. v-tippy
  65. >
  66. check_circle
  67. </i>
  68. <a>
  69. <!-- Favorite Station Button -->
  70. <i
  71. v-if="loggedIn && station.isFavorited"
  72. @click.prevent="unfavoriteStation()"
  73. content="Unfavorite Station"
  74. v-tippy
  75. class="material-icons"
  76. >star</i
  77. >
  78. <i
  79. v-if="loggedIn && !station.isFavorited"
  80. @click.prevent="favoriteStation()"
  81. class="material-icons"
  82. content="Favorite Station"
  83. v-tippy
  84. >star_border</i
  85. >
  86. </a>
  87. </div>
  88. <p>{{ station.description }}</p>
  89. </div>
  90. <div class="admin-buttons">
  91. <!-- (Admin) Pause/Resume Button -->
  92. <button
  93. class="button is-danger"
  94. v-if="isOwnerOrAdmin() && stationPaused"
  95. @click="resumeStation()"
  96. >
  97. <i class="material-icons icon-with-button">play_arrow</i>
  98. <span> Resume Station </span>
  99. </button>
  100. <button
  101. class="button is-danger"
  102. @click="pauseStation()"
  103. v-if="isOwnerOrAdmin() && !stationPaused"
  104. >
  105. <i class="material-icons icon-with-button">pause</i>
  106. <span> Pause Station </span>
  107. </button>
  108. <!-- (Admin) Skip Button -->
  109. <button
  110. class="button is-danger"
  111. @click="skipStation()"
  112. v-if="isOwnerOrAdmin()"
  113. >
  114. <i class="material-icons icon-with-button">skip_next</i>
  115. <span> Force Skip </span>
  116. </button>
  117. <!-- (Admin) Station Settings Button -->
  118. <button
  119. class="button is-primary"
  120. @click="
  121. openModal({
  122. modal: 'manageStation',
  123. data: {
  124. stationId: station._id,
  125. sector: 'station'
  126. }
  127. })
  128. "
  129. v-if="isOwnerOrAdmin() && showManageStation"
  130. >
  131. <i class="material-icons icon-with-button">settings</i>
  132. <span> Manage Station </span>
  133. </button>
  134. <router-link
  135. v-if="showGoToStation"
  136. :to="{
  137. name: 'station',
  138. params: { id: station.name }
  139. }"
  140. class="button is-primary"
  141. >
  142. Go To Station
  143. </router-link>
  144. </div>
  145. </div>
  146. </template>
  147. <style lang="less">
  148. .night-mode {
  149. .about-station-container {
  150. background-color: var(--dark-grey-3) !important;
  151. }
  152. }
  153. .about-station-container {
  154. padding: 20px;
  155. display: flex;
  156. flex-direction: column;
  157. flex-grow: unset;
  158. .row {
  159. display: flex;
  160. flex-direction: row;
  161. max-width: 100%;
  162. }
  163. .station-info {
  164. .station-name {
  165. flex-direction: row !important;
  166. h1 {
  167. margin: 0;
  168. font-size: 36px;
  169. line-height: 0.8;
  170. text-overflow: ellipsis;
  171. overflow: hidden;
  172. }
  173. i {
  174. margin-left: 10px;
  175. font-size: 30px;
  176. color: var(--yellow);
  177. &.stationMode {
  178. padding-left: 10px;
  179. margin-left: auto;
  180. color: var(--primary-color);
  181. }
  182. }
  183. .verified-station {
  184. color: var(--primary-color);
  185. }
  186. }
  187. p {
  188. display: -webkit-box;
  189. max-width: 700px;
  190. margin-bottom: 10px;
  191. overflow: hidden;
  192. text-overflow: ellipsis;
  193. -webkit-box-orient: vertical;
  194. -webkit-line-clamp: 3;
  195. }
  196. }
  197. .admin-buttons {
  198. display: flex;
  199. .button {
  200. margin: 3px;
  201. }
  202. }
  203. }
  204. </style>