Implement fuzzy page search using fuse.js (#86)

This commit is contained in:
Mungai Njoroge
2022-09-10 10:46:45 -04:00
committed by GitHub
parent befdf383b6
commit 5770a66d67
67 changed files with 568 additions and 558 deletions
+12
View File
@@ -4,20 +4,32 @@ export default defineStore("Loader", {
state: () => ({
loading: false,
duration: 0,
page: <HTMLHtmlElement | null>null,
}),
actions: {
startLoading() {
this.loading = true;
this.duration = new Date().getTime();
if (!this.page) {
this.page = document.getElementsByTagName("html")[0] as HTMLHtmlElement;
}
this.page.classList.add("loading");
},
stopLoading() {
const diff = new Date().getTime() - this.duration;
const resetCursor = () => {
this.page ? this.page.classList.remove("loading") : null;
};
if (diff <= 250) {
setTimeout(() => {
resetCursor();
this.loading = false;
}, 250 - diff);
} else {
resetCursor();
this.loading = false;
}
},
+34 -22
View File
@@ -1,11 +1,12 @@
import { useFuse } from "@/utils";
import { defineStore } from "pinia";
import { ComputedRef } from "vue";
import { FuseTrackOptions } from "@/composables/enums";
import { getAlbumBio, getAlbumTracks } from "../../composables/fetch/album";
import { AlbumInfo, Artist, FuseResult, Track } from "../../interfaces";
import { useNotifStore } from "../notification";
import { Track, Artist, AlbumInfo } from "../../interfaces";
import {
getAlbumTracks,
getAlbumArtists,
getAlbumBio,
} from "../../composables/fetch/album";
function sortTracks(tracks: Track[]) {
return tracks.sort((a, b) => {
@@ -32,9 +33,9 @@ function createDiscs(tracks: Track[]): Discs {
export default defineStore("album", {
state: () => ({
query: "",
info: <AlbumInfo>{},
tracks: <Track[]>[],
discs: <Discs>{},
allTracks: <Track[]>[],
artists: <Artist[]>[],
bio: null,
}),
@@ -45,27 +46,38 @@ export default defineStore("album", {
* @param hash title of the album
*/
async fetchTracksAndArtists(hash: string) {
this.tracks = [];
this.allTracks = [];
const album = await getAlbumTracks(hash, useNotifStore);
const artists = await getAlbumArtists(hash);
this.discs = createDiscs(sortTracks(album.tracks));
Object.keys(this.discs).forEach((disc) => {
this.tracks.push(...this.discs[disc]);
const discs = createDiscs(sortTracks(album.tracks));
Object.keys(discs).forEach((disc) => {
this.allTracks.push(...discs[disc]);
});
this.info = album.info;
this.artists = artists;
},
/**
* Fetches the album bio from the server
* @param {string} hash title of the album
*/
fetchBio(hash: string) {
this.bio = null;
getAlbumBio(hash).then((bio) => {
this.bio = bio;
resetQuery() {
this.query = "";
},
},
getters: {
filteredTracks(): ComputedRef<FuseResult[]> {
return useFuse(this.query, this.allTracks, FuseTrackOptions);
},
tracks(): Track[] {
const tracks = this.filteredTracks.value.map((result: FuseResult) => {
const t = {
...result.item,
index: result.refIndex,
};
return t;
});
return tracks;
},
discs(): Discs {
return createDiscs(this.tracks);
},
},
});
+39 -5
View File
@@ -1,19 +1,53 @@
import { defineStore } from "pinia";
import { Folder, Track } from "../../interfaces";
import { ComputedRef } from "vue";
import fetchThem from "../../composables/fetch/folders";
import { useFuse } from "@/utils";
import { FuseTrackOptions } from "@/composables/enums";
import fetchThem from "@/composables/fetch/folders";
import { Folder, FuseResult, Track } from "@/interfaces";
export default defineStore("FolderDirs&Tracks", {
state: () => ({
query: "",
path: <string>{},
dirs: <Folder[]>[],
tracks: <Track[]>[],
allDirs: <Folder[]>[],
allTracks: <Track[]>[],
}),
actions: {
async fetchAll(path: string) {
const { tracks, folders } = await fetchThem(path);
[this.path, this.dirs, this.tracks] = [path, folders, tracks];
[this.path, this.allDirs, this.allTracks] = [path, folders, tracks];
},
resetQuery() {
this.query = "";
},
},
getters: {
filteredTracks(): ComputedRef<FuseResult[]> {
return useFuse(this.query, this.allTracks, FuseTrackOptions);
},
tracks(): Track[] {
const tracks = this.filteredTracks.value.map((result: FuseResult) => {
const t = {
...result.item,
index: result.refIndex,
};
return t;
});
return tracks;
},
dirs(): Folder[] {
const dirs = useFuse(this.query, this.allDirs, {
keys: ["name"],
});
return dirs.value.map((result) => {
return result.item;
});
},
},
});
+34 -11
View File
@@ -1,15 +1,17 @@
import { Artist } from "./../../interfaces";
import { defineStore } from "pinia";
import {
getPlaylist,
getPlaylistArtists,
} from "../../composables/fetch/playlists";
import { Track, Playlist } from "../../interfaces";
import { ComputedRef } from "vue";
import { useFuse } from "@/utils";
import { FuseTrackOptions } from "@/composables/enums";
import { getPlaylist } from "@/composables/fetch/playlists";
import { Artist, FuseResult, Playlist, Track } from "@/interfaces";
export default defineStore("playlist-tracks", {
state: () => ({
info: <Playlist>{},
tracks: <Track[]>[],
query: "",
allTracks: <Track[]>[],
artists: <Artist[]>[],
}),
actions: {
@@ -21,12 +23,12 @@ export default defineStore("playlist-tracks", {
const playlist = await getPlaylist(playlistid);
this.info = playlist?.info || ({} as Playlist);
this.tracks = playlist?.tracks || [];
this.allTracks = playlist?.tracks || [];
},
async fetchArtists(playlistid: string) {
this.artists = await getPlaylistArtists(playlistid);
},
// async fetchArtists(playlistid: string) {
// this.artists = await getPlaylistArtists(playlistid);
// },
/**
* Updates the playlist header info. This is used when the playlist is
* updated.
@@ -40,5 +42,26 @@ export default defineStore("playlist-tracks", {
resetArtists() {
this.artists = [];
},
resetQuery() {
this.query = "";
},
},
getters: {
filteredTracks(): ComputedRef<FuseResult[]> {
return useFuse(this.query, this.allTracks, FuseTrackOptions);
},
tracks(): Track[] {
const tracks = this.filteredTracks.value.map((result: FuseResult) => {
const t = {
...result.item,
index: result.refIndex,
};
return t;
});
return tracks;
},
},
});