AddSongToQueue.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <template>
  2. <modal title="Add Song To Queue">
  3. <div slot="body">
  4. <aside class="menu" v-if="loggedIn && station.type === 'community'">
  5. <ul class="menu-list">
  6. <li v-for="(playlist, index) in playlists" :key="index">
  7. <a
  8. href="#"
  9. target="_blank"
  10. v-on:click="editPlaylist(playlist._id)"
  11. >{{ playlist.displayName }}</a
  12. >
  13. <div class="controls">
  14. <a
  15. href="#"
  16. v-on:click="selectPlaylist(playlist._id)"
  17. v-if="!isPlaylistSelected(playlist._id)"
  18. >
  19. <i class="material-icons">panorama_fish_eye</i>
  20. </a>
  21. <a
  22. href="#"
  23. v-on:click="unSelectPlaylist()"
  24. v-if="isPlaylistSelected(playlist._id)"
  25. >
  26. <i class="material-icons">lens</i>
  27. </a>
  28. </div>
  29. </li>
  30. </ul>
  31. <br />
  32. </aside>
  33. <div class="control is-grouped">
  34. <p class="control is-expanded">
  35. <input
  36. class="input"
  37. type="text"
  38. placeholder="YouTube Query"
  39. v-model="querySearch"
  40. autofocus
  41. @keyup.enter="submitQuery()"
  42. />
  43. </p>
  44. <p class="control">
  45. <a
  46. class="button is-info"
  47. v-on:click="submitQuery()"
  48. href="#"
  49. >Search</a
  50. >
  51. </p>
  52. </div>
  53. <div class="control is-grouped" v-if="station.type === 'official'">
  54. <p class="control is-expanded">
  55. <input
  56. class="input"
  57. type="text"
  58. placeholder="YouTube Playlist URL"
  59. v-model="importQuery"
  60. @keyup.enter="importPlaylist()"
  61. />
  62. </p>
  63. <p class="control">
  64. <a
  65. class="button is-info"
  66. v-on:click="importPlaylist()"
  67. href="#"
  68. >Import</a
  69. >
  70. </p>
  71. </div>
  72. <table class="table" v-if="queryResults.length > 0">
  73. <tbody>
  74. <tr v-for="(result, index) in queryResults" :key="index">
  75. <td>
  76. <img :src="result.thumbnail" />
  77. </td>
  78. <td>{{ result.title }}</td>
  79. <td>
  80. <a
  81. class="button is-success"
  82. v-on:click="addSongToQueue(result.id)"
  83. href="#"
  84. >Add</a
  85. >
  86. </td>
  87. </tr>
  88. </tbody>
  89. </table>
  90. </div>
  91. </modal>
  92. </template>
  93. <script>
  94. import { mapState, mapActions } from "vuex";
  95. import Toast from "toasters";
  96. import Modal from "./Modal.vue";
  97. import io from "../../io";
  98. export default {
  99. data() {
  100. return {
  101. querySearch: "",
  102. queryResults: [],
  103. playlists: [],
  104. privatePlaylistQueueSelected: null,
  105. importQuery: ""
  106. };
  107. },
  108. computed: mapState({
  109. loggedIn: state => state.user.auth.loggedIn,
  110. station: state => state.station.station
  111. }),
  112. methods: {
  113. isPlaylistSelected(playlistId) {
  114. return this.privatePlaylistQueueSelected === playlistId;
  115. },
  116. selectPlaylist(playlistId) {
  117. if (this.station.type === "community") {
  118. this.privatePlaylistQueueSelected = playlistId;
  119. this.$parent.privatePlaylistQueueSelected = playlistId;
  120. this.$parent.addFirstPrivatePlaylistSongToQueue();
  121. }
  122. },
  123. unSelectPlaylist() {
  124. if (this.station.type === "community") {
  125. this.privatePlaylistQueueSelected = null;
  126. this.$parent.privatePlaylistQueueSelected = null;
  127. }
  128. },
  129. addSongToQueue(songId) {
  130. console.log(this.station.type);
  131. if (this.station.type === "community") {
  132. this.socket.emit(
  133. "stations.addToQueue",
  134. this.station._id,
  135. songId,
  136. data => {
  137. if (data.status !== "success")
  138. new Toast({
  139. content: `Error: ${data.message}`,
  140. timeout: 8000
  141. });
  142. else
  143. new Toast({
  144. content: `${data.message}`,
  145. timeout: 4000
  146. });
  147. }
  148. );
  149. } else {
  150. this.socket.emit("queueSongs.add", songId, data => {
  151. if (data.status !== "success")
  152. new Toast({
  153. content: `Error: ${data.message}`,
  154. timeout: 8000
  155. });
  156. else
  157. new Toast({
  158. content: `${data.message}`,
  159. timeout: 4000
  160. });
  161. });
  162. }
  163. },
  164. importPlaylist() {
  165. new Toast({
  166. content:
  167. "Starting to import your playlist. This can take some time to do.",
  168. timeout: 4000
  169. });
  170. this.socket.emit(
  171. "queueSongs.addSetToQueue",
  172. this.importQuery,
  173. res => {
  174. new Toast({ content: res.message, timeout: 4000 });
  175. }
  176. );
  177. },
  178. submitQuery() {
  179. let query = this.querySearch;
  180. if (query.indexOf("&index=") !== -1) {
  181. query = query.split("&index=");
  182. query.pop();
  183. query = query.join("");
  184. }
  185. if (query.indexOf("&list=") !== -1) {
  186. query = query.split("&list=");
  187. query.pop();
  188. query = query.join("");
  189. }
  190. this.socket.emit("apis.searchYoutube", query, res => {
  191. // check for error
  192. const { data } = res;
  193. this.queryResults = [];
  194. for (let i = 0; i < data.items.length; i += 1) {
  195. this.queryResults.push({
  196. id: data.items[i].id.videoId,
  197. url: `https://www.youtube.com/watch?v=${this.id}`,
  198. title: data.items[i].snippet.title,
  199. thumbnail: data.items[i].snippet.thumbnails.default.url
  200. });
  201. }
  202. });
  203. },
  204. ...mapActions("user/playlists", ["editPlaylist"])
  205. },
  206. mounted() {
  207. io.getSocket(socket => {
  208. this.socket = socket;
  209. this.socket.emit("playlists.indexForUser", res => {
  210. if (res.status === "success") this.playlists = res.data;
  211. });
  212. this.privatePlaylistQueueSelected = this.$parent.privatePlaylistQueueSelected;
  213. });
  214. },
  215. components: { Modal }
  216. };
  217. </script>
  218. <style lang="scss" scoped>
  219. @import "styles/global.scss";
  220. tr td {
  221. vertical-align: middle;
  222. img {
  223. width: 55px;
  224. }
  225. }
  226. .table {
  227. margin-bottom: 0;
  228. }
  229. </style>