diff --git a/src/components/vue/PlaylistSearchInput.vue b/src/components/vue/PlaylistSearchInput.vue index 5a6b11b..658e54f 100644 --- a/src/components/vue/PlaylistSearchInput.vue +++ b/src/components/vue/PlaylistSearchInput.vue @@ -3,20 +3,18 @@ import { onMounted, ref, watch } from 'vue'; import { search } from 'fast-fuzzy'; import { debounce } from 'debounce'; + +import type { PlaylistSnapshot } from '../../models/playlist-snapshot'; +import type { SearchSuggestion } from '../../models/search-suggestion'; import { getPlaylistIdFromUrl } from '../../utils/getPlaylistIdFromUrl'; -interface PlaylistEntry { - name: string; - id: string; -} - const searchTerm = ref(''); -const searchHistory = ref( +const searchHistory = ref( JSON.parse(localStorage.getItem('searchHistory') || '[]') ); -const playlistRegistry = ref([]); -const searchSuggestions = ref(searchHistory.value); +const playlistRegistry = ref([]); +const searchSuggestions = ref(searchHistory.value); const isFetchingPlaylists = ref(true); const errorOccurred = ref(false); @@ -27,28 +25,16 @@ const fetchAvailablePlaylists = async () => { isFetchingPlaylists.value = true; errorOccurred.value = false; - const readmeFileContent = await ( + const playlistMetadata: Record = await ( await fetch( - 'https://raw.githubusercontent.com/mackorone/spotify-playlist-archive/main/README.md' + 'https://raw.githubusercontent.com/mackorone/spotify-playlist-archive/main/playlists/metadata.json' ) - ).text(); + ).json(); - const [, playlistLinksMdList] = readmeFileContent.split( - /## Playlists \\\([0-9]*\\\)\n\n/gm + const playlistEntries = Object.entries(playlistMetadata).map( + ([id, { original_name }]) => ({ id, name: original_name }) ); - const playlistEntries: PlaylistEntry[] = playlistLinksMdList - .replaceAll('- [', '') - .replaceAll('\\', '') - .replaceAll('](', '') - .replaceAll('.md)', '') - .split('\n') - .map((textEntry) => { - const [name, id] = textEntry.split('/playlists/pretty/'); - - return { name, id }; - }); - playlistRegistry.value = playlistEntries; } catch (error) { console.error(error); @@ -72,11 +58,10 @@ const findMatchingPlaylists = debounce(async (name: string) => { if (!githubResponse.ok) throw new Error('Entry does not exist'); - const playlist = await githubResponse.json(); + const playlist: PlaylistSnapshot = await githubResponse.json(); + const suggestion = { id: playlistId, name: playlist.original_name }; - return (searchSuggestions.value = [ - { id: playlistId, name: playlist.original_name } - ]); + return (searchSuggestions.value = [suggestion]); } catch (error) { const noopErrorMessages = ['Invalid playlist URL', 'Entry does not exist']; @@ -84,21 +69,21 @@ const findMatchingPlaylists = debounce(async (name: string) => { return (searchSuggestions.value = []); } - const matches = search(name, playlistRegistry.value, { + const suggestions = search(name, playlistRegistry.value, { keySelector: (obj) => obj.name }); - searchSuggestions.value = matches.slice(0, 5); + searchSuggestions.value = suggestions.slice(0, 5); } }, 250); -const saveMatchToHistory = (match: PlaylistEntry) => { +const saveMatchToHistory = (suggestion: SearchSuggestion) => { const isNewHistoryEntry = searchHistory.value.every( - (entry) => entry.id !== match.id + (entry) => entry.id !== suggestion.id ); if (isNewHistoryEntry) { - searchHistory.value = [match, ...searchHistory.value].slice(0, 5); + searchHistory.value = [suggestion, ...searchHistory.value].slice(0, 5); localStorage.setItem('searchHistory', JSON.stringify(searchHistory.value)); } }; @@ -137,14 +122,14 @@ watch(searchTerm, (newSearchTerm) => findMatchingPlaylists(newSearchTerm)); class="w-full absolute z-10 top-full left-0 right-0 bg-base-100 text-left border-l-[1px] border-r-[1px] border-solid border-base-content border-opacity-20" > - {{ match.name }} + {{ suggestion.name }} diff --git a/src/models/search-suggestion.ts b/src/models/search-suggestion.ts new file mode 100644 index 0000000..3292701 --- /dev/null +++ b/src/models/search-suggestion.ts @@ -0,0 +1,4 @@ +export interface SearchSuggestion { + id: string; + name: string; +}