CurrentlyPlaying.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <template>
  2. <div class="currently-playing">
  3. <figure class="thumbnail">
  4. <div
  5. v-if="song.ytThumbnail"
  6. id="yt-thumbnail-bg"
  7. :style="{
  8. 'background-image': 'url(' + song.ytThumbnail + ')'
  9. }"
  10. ></div>
  11. <img
  12. v-if="song.ytThumbnail"
  13. :src="song.ytThumbnail"
  14. onerror="this.src='/assets/notes-transparent.png'"
  15. />
  16. <img
  17. v-else
  18. :src="song.thumbnail"
  19. onerror="this.src='/assets/notes-transparent.png'"
  20. />
  21. </figure>
  22. <div id="song-info">
  23. <div id="song-details">
  24. <h6 v-if="type === 'current'">Currently Playing...</h6>
  25. <h6 v-if="type === 'next'">Next Up...</h6>
  26. <h4
  27. id="song-title"
  28. :style="!song.artists ? { fontSize: '17px' } : null"
  29. >
  30. {{ song.title }}
  31. </h4>
  32. <h5 id="song-artists" v-if="song.artists">
  33. {{ song.artists.join(", ") }}
  34. </h5>
  35. <p
  36. id="song-request-time"
  37. v-if="
  38. station.type === 'community' &&
  39. station.partyMode === true
  40. "
  41. >
  42. Requested
  43. <strong>{{
  44. formatDistance(parseISO(song.requestedAt), Date.now(), {
  45. addSuffix: true
  46. })
  47. }}</strong>
  48. </p>
  49. </div>
  50. <div id="song-actions">
  51. <button
  52. class="button"
  53. id="report-icon"
  54. v-if="loggedIn && !song.simpleSong"
  55. @click="report(song)"
  56. >
  57. <i class="material-icons icon-with-button">flag</i>
  58. </button>
  59. <a
  60. class="button"
  61. id="youtube-icon"
  62. target="_blank"
  63. :href="`https://www.youtube.com/watch?v=${song.songId}`"
  64. >
  65. <div class="icon"></div>
  66. </a>
  67. <button
  68. class="button is-primary"
  69. id="editsong-icon"
  70. v-if="$parent.isAdminOnly() && !song.simpleSong"
  71. @click="$parent.editSong(song)"
  72. >
  73. <i class="material-icons icon-with-button">edit</i>
  74. </button>
  75. </div>
  76. </div>
  77. </div>
  78. </template>
  79. <script>
  80. import { mapState, mapActions } from "vuex";
  81. import { formatDistance, parseISO } from "date-fns";
  82. export default {
  83. props: {
  84. song: {
  85. type: Object,
  86. default: () => {}
  87. },
  88. type: {
  89. type: String,
  90. default: "current"
  91. }
  92. },
  93. computed: {
  94. ...mapState("station", {
  95. station: state => state.station
  96. }),
  97. ...mapState({
  98. loggedIn: state => state.user.auth.loggedIn
  99. })
  100. },
  101. methods: {
  102. report(song) {
  103. this.reportSong(song);
  104. this.openModal({ sector: "station", modal: "report" });
  105. },
  106. ...mapActions("modals/report", ["reportSong"]),
  107. ...mapActions("modalVisibility", ["openModal"]),
  108. formatDistance,
  109. parseISO
  110. }
  111. };
  112. </script>
  113. <style lang="scss" scoped>
  114. .currently-playing {
  115. display: flex;
  116. flex-direction: row;
  117. align-items: center;
  118. width: 100%;
  119. height: 100%;
  120. padding: 10px;
  121. min-height: 130px;
  122. .thumbnail {
  123. min-width: 130px;
  124. height: 130px;
  125. position: relative;
  126. margin-top: -15px;
  127. margin-bottom: -15px;
  128. margin-left: -10px;
  129. #yt-thumbnail-bg {
  130. height: 100%;
  131. width: 100%;
  132. position: absolute;
  133. top: 0;
  134. filter: blur(1px);
  135. background: url("/assets/notes-transparent.png") no-repeat center
  136. center;
  137. }
  138. img {
  139. height: auto;
  140. width: 100%;
  141. margin-top: auto;
  142. margin-bottom: auto;
  143. z-index: 1;
  144. position: absolute;
  145. top: 0;
  146. bottom: 0;
  147. left: 0;
  148. right: 0;
  149. }
  150. }
  151. #song-info {
  152. display: flex;
  153. flex-direction: row;
  154. flex-wrap: wrap;
  155. margin-left: 20px;
  156. width: 100%;
  157. height: 100%;
  158. *:not(i) {
  159. margin: 0;
  160. font-family: Karla, Arial, sans-serif;
  161. }
  162. #song-details {
  163. display: flex;
  164. justify-content: center;
  165. flex-direction: column;
  166. flex-grow: 1;
  167. h6 {
  168. color: var(--primary-color) !important;
  169. font-weight: bold;
  170. font-size: 17px;
  171. }
  172. #song-title {
  173. margin-top: 7px;
  174. font-size: 22px;
  175. }
  176. #song-artists {
  177. font-size: 16px;
  178. margin-bottom: 5px;
  179. }
  180. #song-request-time {
  181. font-size: 12px;
  182. margin-top: 7px;
  183. color: var(--dark-grey);
  184. }
  185. }
  186. #song-actions {
  187. display: flex;
  188. .button {
  189. color: var(--white);
  190. padding: 0 15px;
  191. border: 0;
  192. margin: auto 3px;
  193. }
  194. #report-icon {
  195. background-color: var(--yellow);
  196. }
  197. #youtube-icon {
  198. background-color: var(--youtube);
  199. .icon {
  200. margin-right: 3px;
  201. height: 20px;
  202. width: 20px;
  203. -webkit-mask: url("/assets/social/youtube.svg") no-repeat
  204. center;
  205. mask: url("/assets/social/youtube.svg") no-repeat center;
  206. background-color: var(--white);
  207. }
  208. }
  209. #editsong-icon.button.is-primary {
  210. background-color: var(--primary-color) !important;
  211. &:hover,
  212. &:focus {
  213. filter: brightness(90%);
  214. }
  215. }
  216. }
  217. }
  218. }
  219. </style>