Youtube.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <script setup lang="ts">
  2. import { storeToRefs } from "pinia";
  3. import { onMounted, ref } from "vue";
  4. import { useEditSongStore } from "@/stores/editSong";
  5. import { useSearchYoutube } from "@/composables/useSearchYoutube";
  6. import { useYoutubeDirect } from "@/composables/useYoutubeDirect";
  7. import SearchQueryItem from "../../../SearchQueryItem.vue";
  8. const props = defineProps({
  9. modalUuid: { type: String, required: true },
  10. modalModulePath: { type: String, default: "modals/editSong/MODAL_UUID" }
  11. });
  12. const editSongStore = useEditSongStore({ modalUuid: props.modalUuid });
  13. const { form, newSong } = storeToRefs(editSongStore);
  14. const { updateYoutubeId } = editSongStore;
  15. const { youtubeSearch, searchForSongs, loadMoreSongs } = useSearchYoutube();
  16. const { youtubeDirect, getYoutubeVideoId } = useYoutubeDirect();
  17. const experimentalDisableYoutubeSearch = ref(false);
  18. const selectSong = (youtubeId, result = null) => {
  19. updateYoutubeId(youtubeId);
  20. if (newSong && result)
  21. form.value.setValue({
  22. title: result.title,
  23. thumbnail: result.thumbnail
  24. });
  25. };
  26. onMounted(() => {
  27. lofig.get("experimental").then(experimental => {
  28. if (
  29. experimental &&
  30. Object.hasOwn(experimental, "disable_youtube_search") &&
  31. experimental.disable_youtube_search
  32. ) {
  33. experimentalDisableYoutubeSearch.value = true;
  34. }
  35. });
  36. });
  37. </script>
  38. <template>
  39. <div class="youtube-tab">
  40. <label class="label"> Add a YouTube song from a URL </label>
  41. <div class="control is-grouped input-with-button">
  42. <p class="control is-expanded">
  43. <input
  44. class="input"
  45. type="text"
  46. placeholder="Enter your YouTube song URL here..."
  47. v-model="youtubeDirect"
  48. @keyup.enter="selectSong(getYoutubeVideoId())"
  49. />
  50. </p>
  51. <p class="control">
  52. <a
  53. class="button is-info"
  54. @click="selectSong(getYoutubeVideoId())"
  55. ><i class="material-icons icon-with-button">add</i>Add</a
  56. >
  57. </p>
  58. </div>
  59. <div v-if="!experimentalDisableYoutubeSearch">
  60. <label class="label"> Search for a song from YouTube </label>
  61. <div class="control is-grouped input-with-button">
  62. <p class="control is-expanded">
  63. <input
  64. class="input"
  65. type="text"
  66. placeholder="Enter your YouTube query here..."
  67. v-model="youtubeSearch.songs.query"
  68. autofocus
  69. @keyup.enter="searchForSongs()"
  70. />
  71. </p>
  72. <p class="control">
  73. <button
  74. class="button is-info"
  75. @click.prevent="searchForSongs()"
  76. >
  77. <i class="material-icons icon-with-button">search</i
  78. >Search
  79. </button>
  80. </p>
  81. </div>
  82. <div
  83. v-if="youtubeSearch.songs.results.length > 0"
  84. id="song-query-results"
  85. >
  86. <search-query-item
  87. v-for="result in youtubeSearch.songs.results"
  88. :key="result.id"
  89. :result="result"
  90. >
  91. <template #actions>
  92. <i
  93. class="material-icons icon-selected"
  94. v-if="result.id === form.inputs.youtubeId.value"
  95. key="selected"
  96. >radio_button_checked
  97. </i>
  98. <i
  99. class="material-icons icon-not-selected"
  100. v-else
  101. @click.prevent="selectSong(result.id, result)"
  102. key="not-selected"
  103. >radio_button_unchecked
  104. </i>
  105. </template>
  106. </search-query-item>
  107. <button
  108. class="button is-primary load-more-button"
  109. @click.prevent="loadMoreSongs()"
  110. >
  111. Load more...
  112. </button>
  113. </div>
  114. </div>
  115. </div>
  116. </template>
  117. <style lang="less" scoped>
  118. .youtube-tab #song-query-results {
  119. height: calc(100% - 74px);
  120. overflow: auto;
  121. .search-query-item {
  122. .icon-selected {
  123. color: var(--green) !important;
  124. }
  125. .icon-not-selected {
  126. color: var(--grey) !important;
  127. }
  128. }
  129. .search-query-item:not(:last-of-type) {
  130. margin-bottom: 10px;
  131. }
  132. .load-more-button {
  133. width: 100%;
  134. margin-top: 10px;
  135. }
  136. }
  137. </style>