StationInfoBox.vue 5.2 KB

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