AddSongs.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <div class="youtube-tab section">
  3. <label class="label"> Search for a song from YouTube </label>
  4. <div class="control is-grouped input-with-button">
  5. <p class="control is-expanded">
  6. <input
  7. class="input"
  8. type="text"
  9. placeholder="Enter your YouTube query here..."
  10. v-model="search.songs.query"
  11. autofocus
  12. @keyup.enter="searchForSongs()"
  13. />
  14. </p>
  15. <p class="control">
  16. <a
  17. class="button is-info"
  18. @click.prevent="searchForSongs()"
  19. href="#"
  20. ><i class="material-icons icon-with-button">search</i
  21. >Search</a
  22. >
  23. </p>
  24. </div>
  25. <div v-if="search.songs.results.length > 0" id="song-query-results">
  26. <search-query-item
  27. v-for="(result, index) in search.songs.results"
  28. :key="result.id"
  29. :result="result"
  30. >
  31. <template #actions>
  32. <transition name="search-query-actions" mode="out-in">
  33. <a
  34. class="button is-success"
  35. v-if="result.isAddedToQueue"
  36. href="#"
  37. key="added-to-playlist"
  38. >
  39. <i class="material-icons icon-with-button">done</i>
  40. Added to playlist
  41. </a>
  42. <a
  43. class="button is-dark"
  44. v-else
  45. @click.prevent="addSongToPlaylist(result.id, index)"
  46. href="#"
  47. key="add-to-playlist"
  48. >
  49. <i class="material-icons icon-with-button">add</i>
  50. Add to playlist
  51. </a>
  52. </transition>
  53. </template>
  54. </search-query-item>
  55. <a
  56. class="button is-primary load-more-button"
  57. @click.prevent="loadMoreSongs()"
  58. href="#"
  59. >
  60. Load more...
  61. </a>
  62. </div>
  63. </div>
  64. </template>
  65. <script>
  66. import { mapState, mapGetters } from "vuex";
  67. import SearchYoutube from "@/mixins/SearchYoutube.vue";
  68. import SearchQueryItem from "../../../SearchQueryItem.vue";
  69. export default {
  70. components: { SearchQueryItem },
  71. mixins: [SearchYoutube],
  72. data() {
  73. return {};
  74. },
  75. computed: {
  76. ...mapState("modals/editPlaylist", {
  77. playlist: state => state.playlist
  78. }),
  79. ...mapGetters({
  80. socket: "websockets/getSocket"
  81. })
  82. },
  83. watch: {
  84. "search.songs.results": function checkIfSongInPlaylist(songs) {
  85. songs.forEach((searchItem, index) =>
  86. this.playlist.songs.find(song => {
  87. if (song.youtubeId === searchItem.id)
  88. this.search.songs.results[index].isAddedToQueue = true;
  89. return song.youtubeId === searchItem.id;
  90. })
  91. );
  92. },
  93. "playlist.songs": function checkIfSongInPlaylist() {
  94. this.search.songs.results.forEach((searchItem, index) =>
  95. this.playlist.songs.find(song => {
  96. this.search.songs.results[index].isAddedToQueue = false;
  97. if (song.youtubeId === searchItem.id)
  98. this.search.songs.results[index].isAddedToQueue = true;
  99. return song.youtubeId === searchItem.id;
  100. })
  101. );
  102. }
  103. }
  104. };
  105. </script>
  106. <style lang="scss" scoped>
  107. .youtube-tab {
  108. #song-query-results {
  109. padding: 10px;
  110. margin-top: 10px;
  111. border: 1px solid var(--light-grey-3);
  112. border-radius: 3px;
  113. max-width: 565px;
  114. max-height: 500px;
  115. overflow: auto;
  116. .search-query-item:not(:last-of-type) {
  117. margin-bottom: 10px;
  118. }
  119. }
  120. .load-more-button {
  121. width: 100%;
  122. margin-top: 10px;
  123. }
  124. }
  125. @media screen and (max-width: 1300px) {
  126. .youtube-tab #song-query-results,
  127. .section {
  128. max-width: 100% !important;
  129. }
  130. }
  131. </style>