-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(web): update all stores to use runes
Signed-off-by: Jordan Shatford <[email protected]>
- Loading branch information
1 parent
274cab5
commit 0a46ee0
Showing
12 changed files
with
303 additions
and
352 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import { SESSION_ID_KEY } from '$lib/api'; | ||
import { settings, userSettings } from '$lib/stores/settings.svelte'; | ||
import { saveAs } from '$lib/utils/files'; | ||
|
||
import type { Download, Video } from '@yd/client'; | ||
import { | ||
deleteDownload, | ||
getDownloadFile, | ||
getDownloads, | ||
getDownloadsStatus, | ||
postDownloads, | ||
putDownloads | ||
} from '@yd/client'; | ||
import { toasts } from '@yd/ui'; | ||
|
||
class DownloadsStore { | ||
public downloads = $state<Record<string, Download>>({}); | ||
|
||
public async init() { | ||
// Setup listener for status updates of any downloads. | ||
getDownloadsStatus(() => sessionStorage.getItem(SESSION_ID_KEY) ?? '', { | ||
onMessage: (download) => { | ||
this.updateDownload(download.video.id, download); | ||
} | ||
}); | ||
// Get all previous downloads still available. | ||
const downloads = (await getDownloads()).data ?? []; | ||
this.downloads = downloads.reduce((prev, curr) => ({ ...prev, [curr.video.id]: curr }), {}); | ||
} | ||
|
||
public async add(video: Video) { | ||
if (video.id in this.downloads) return; | ||
|
||
const download: Download = { | ||
video, | ||
status: { state: 'WAITING', progress: null }, | ||
options: settings.settings | ||
}; | ||
|
||
// Add initial value for the download | ||
this.downloads[download.video.id] = download; | ||
|
||
try { | ||
const result = await postDownloads({ | ||
body: download | ||
}); | ||
if (result.data) { | ||
this.updateDownload(result.data.video.id, result.data); | ||
} | ||
} catch (err) { | ||
this.handleError(download.video.id, `Failed to add '${video.title}' to downloads.`, err); | ||
} | ||
} | ||
|
||
public async restart(id: string) { | ||
if (!(id in this.downloads)) return; | ||
|
||
const download = this.downloads[id]; | ||
|
||
try { | ||
const result = await putDownloads({ | ||
body: download | ||
}); | ||
if (result.data) { | ||
this.updateDownload(result.data.video.id, result.data); | ||
} | ||
} catch (err) { | ||
this.handleError( | ||
download.video.id, | ||
`Failed to restart '${download.video.title}' download.`, | ||
err | ||
); | ||
} | ||
} | ||
|
||
public async remove(id: string) { | ||
if (!(id in this.downloads)) return; | ||
|
||
try { | ||
await deleteDownload({ path: { download_id: id } }); | ||
toasts.success('Deleted', 'Download removed successfully.'); | ||
delete this.downloads[id]; | ||
} catch (err) { | ||
this.handleError(id, 'Failed to remove download.', err); | ||
} | ||
} | ||
|
||
public async getFile(id: string) { | ||
if (!(id in this.downloads)) return; | ||
|
||
try { | ||
const response = await getDownloadFile({ path: { download_id: id } }); | ||
if (response.data) { | ||
const download = this.downloads[id]; | ||
const filename = `${download.video.title}.${download.options.format}`; | ||
saveAs(response.data as Blob, filename); | ||
} | ||
} catch (err) { | ||
this.handleError(id, 'Failed to get file for download.', err); | ||
} | ||
} | ||
|
||
private updateDownload(id: string, updatedValue: Partial<Download>) { | ||
if (id in this.downloads) { | ||
// Merge and update values. | ||
const oldValue = this.downloads[id]; | ||
const value: Download = { ...oldValue, ...updatedValue }; | ||
this.downloads[id] = value; | ||
// Automatically download file if enabled by the user. | ||
if (userSettings.settings.autoDownloadOnComplete) { | ||
if (updatedValue.status?.state === 'DONE') { | ||
this.getFile(value.video.id); | ||
} | ||
} | ||
} else { | ||
console.error('Attempted to update download that does not exist.'); | ||
} | ||
} | ||
|
||
private handleError(downloadId: string, msg: string, error: unknown) { | ||
toasts.error('Error', msg); | ||
console.error(msg, error); | ||
this.updateDownload(downloadId, { status: { state: 'ERROR', progress: null } }); | ||
} | ||
} | ||
|
||
export const downloads = new DownloadsStore(); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import type { Video } from '@yd/client'; | ||
import { getNextSearch, getSearch } from '@yd/client'; | ||
import { toasts } from '@yd/ui'; | ||
|
||
class SearchStore { | ||
public query = $state<string>(''); | ||
public loading = $state<boolean>(false); | ||
public results = $state<Video[]>([]); | ||
|
||
public async get(q: string) { | ||
if (this.query === q) { | ||
return; | ||
} | ||
this.query = q; | ||
this.loading = true; | ||
try { | ||
const response = await getSearch({ query: { query: q } }); | ||
if (response.data) { | ||
this.results = response.data; | ||
} | ||
toasts.success('Success', `Found ${this.results.length} search results.`); | ||
} catch (err) { | ||
toasts.error('Error', 'Failed to get search results.'); | ||
console.error('Failed to search for videos ', err); | ||
} | ||
this.loading = false; | ||
} | ||
|
||
public async getMore() { | ||
this.loading = true; | ||
try { | ||
const response = await getNextSearch(); | ||
if (response.data) { | ||
this.results = [...this.results, ...response.data]; | ||
} | ||
toasts.success('Success', `Found ${this.results.length} more search results.`); | ||
} catch (err) { | ||
toasts.error('Error', 'Failed to get more search results.'); | ||
console.error('Failed to get more search videos ', err); | ||
} | ||
this.loading = false; | ||
} | ||
|
||
public reset() { | ||
this.query = ''; | ||
this.loading = false; | ||
this.results = []; | ||
} | ||
} | ||
|
||
export const search = new SearchStore(); |
Oops, something went wrong.