AddSongs.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <template>
  2. <div class="youtube-tab section">
  3. <div>
  4. <label class="label"> Search for a song on Musare </label>
  5. <div class="control is-grouped input-with-button">
  6. <p class="control is-expanded">
  7. <input
  8. class="input"
  9. type="text"
  10. placeholder="Enter your song query here..."
  11. v-model="musareSearch.query"
  12. @keyup.enter="searchForMusareSongs(1)"
  13. />
  14. </p>
  15. <p class="control">
  16. <a class="button is-info" @click="searchForMusareSongs(1)"
  17. ><i class="material-icons icon-with-button">search</i
  18. >Search</a
  19. >
  20. </p>
  21. </div>
  22. <div
  23. v-if="musareSearch.results.length > 0"
  24. class="song-query-results"
  25. >
  26. <song-item
  27. v-for="song in musareSearch.results"
  28. :key="song._id"
  29. :song="song"
  30. />
  31. <button
  32. v-if="resultsLeftCount > 0"
  33. class="button is-primary load-more-button"
  34. @click="searchForMusareSongs(musareSearch.page + 1)"
  35. >
  36. Load {{ nextPageResultsCount }} more results
  37. </button>
  38. </div>
  39. </div>
  40. <br v-if="musareSearch.results.length > 0" />
  41. <div>
  42. <label class="label"> Search for a song from YouTube </label>
  43. <div class="control is-grouped input-with-button">
  44. <p class="control is-expanded">
  45. <input
  46. class="input"
  47. type="text"
  48. placeholder="Enter your YouTube query here..."
  49. v-model="youtubeSearch.songs.query"
  50. autofocus
  51. @keyup.enter="searchForSongs()"
  52. />
  53. </p>
  54. <p class="control">
  55. <a
  56. class="button is-info"
  57. @click.prevent="searchForSongs()"
  58. href="#"
  59. ><i class="material-icons icon-with-button">search</i
  60. >Search</a
  61. >
  62. </p>
  63. </div>
  64. <div
  65. v-if="youtubeSearch.songs.results.length > 0"
  66. class="song-query-results"
  67. >
  68. <search-query-item
  69. v-for="result in youtubeSearch.songs.results"
  70. :key="result.id"
  71. :result="result"
  72. >
  73. <template #actions>
  74. <add-to-playlist-dropdown
  75. :song="{ youtubeId: result.id }"
  76. placement="top-end"
  77. >
  78. <template #button>
  79. <i
  80. class="material-icons add-to-playlist-icon"
  81. content="Add Song to Playlist"
  82. v-tippy
  83. >playlist_add</i
  84. >
  85. </template>
  86. </add-to-playlist-dropdown>
  87. <!-- <transition name="search-query-actions" mode="out-in">
  88. <a
  89. class="button is-success"
  90. v-if="result.isAddedToQueue"
  91. href="#"
  92. key="added-to-playlist"
  93. >
  94. <i class="material-icons icon-with-button"
  95. >done</i
  96. >
  97. Added to playlist
  98. </a>
  99. <a
  100. class="button is-dark"
  101. v-else
  102. @click.prevent="
  103. addSongToPlaylist(result.id, index)
  104. "
  105. href="#"
  106. key="add-to-playlist"
  107. >
  108. <i class="material-icons icon-with-button"
  109. >add</i
  110. >
  111. Add to playlist
  112. </a>
  113. </transition> -->
  114. </template>
  115. </search-query-item>
  116. <a
  117. class="button is-primary load-more-button"
  118. @click.prevent="loadMoreSongs()"
  119. href="#"
  120. >
  121. Load more...
  122. </a>
  123. </div>
  124. </div>
  125. </div>
  126. </template>
  127. <script>
  128. import { mapState, mapGetters } from "vuex";
  129. import SearchYoutube from "@/mixins/SearchYoutube.vue";
  130. import SearchMusare from "@/mixins/SearchMusare.vue";
  131. import SongItem from "@/components/SongItem.vue";
  132. import AddToPlaylistDropdown from "@/components/AddToPlaylistDropdown.vue";
  133. import SearchQueryItem from "@/components/SearchQueryItem.vue";
  134. export default {
  135. components: { SearchQueryItem, SongItem, AddToPlaylistDropdown },
  136. mixins: [SearchYoutube, SearchMusare],
  137. computed: {
  138. ...mapState("modals/editPlaylist", {
  139. playlist: state => state.playlist
  140. }),
  141. ...mapGetters({
  142. socket: "websockets/getSocket"
  143. })
  144. },
  145. watch: {
  146. "youtubeSearch.songs.results": function checkIfSongInPlaylist(songs) {
  147. songs.forEach((searchItem, index) =>
  148. this.playlist.songs.find(song => {
  149. if (song.youtubeId === searchItem.id)
  150. this.youtubeSearch.songs.results[
  151. index
  152. ].isAddedToQueue = true;
  153. return song.youtubeId === searchItem.id;
  154. })
  155. );
  156. },
  157. "playlist.songs": function checkIfSongInPlaylist() {
  158. this.youtubeSearch.songs.results.forEach((searchItem, index) =>
  159. this.playlist.songs.find(song => {
  160. this.youtubeSearch.songs.results[
  161. index
  162. ].isAddedToQueue = false;
  163. if (song.youtubeId === searchItem.id)
  164. this.youtubeSearch.songs.results[
  165. index
  166. ].isAddedToQueue = true;
  167. return song.youtubeId === searchItem.id;
  168. })
  169. );
  170. }
  171. }
  172. };
  173. </script>
  174. <style lang="scss" scoped>
  175. .youtube-tab {
  176. .song-query-results {
  177. padding: 10px;
  178. margin-top: 10px;
  179. border: 1px solid var(--light-grey-3);
  180. border-radius: 3px;
  181. max-width: 565px;
  182. max-height: 500px;
  183. overflow: auto;
  184. .search-query-item:not(:last-of-type) {
  185. margin-bottom: 10px;
  186. }
  187. }
  188. .load-more-button {
  189. width: 100%;
  190. margin-top: 10px;
  191. }
  192. }
  193. @media screen and (max-width: 1300px) {
  194. .youtube-tab .song-query-results,
  195. .section {
  196. max-width: 100% !important;
  197. }
  198. }
  199. </style>