fix: changing seek duration

feat: your list
fix: reduce thread queries
This commit is contained in:
ThaUnknown 2025-04-30 20:04:43 +02:00
parent 10c385e60f
commit 78d6037272
No known key found for this signature in database
10 changed files with 52 additions and 25 deletions

View file

@ -1,6 +1,6 @@
{
"name": "ui",
"version": "6.1.5",
"version": "6.1.6",
"license": "BUSL-1.1",
"private": true,
"packageManager": "pnpm@9.14.4",

View file

@ -19,8 +19,6 @@
const perPage = 15
$: count = $comments.data?.Page?.pageInfo?.total ?? 0
$: console.log($comments.fetching, $comments.error, $comments.data?.Page?.threadComments)
</script>
<Pagination {count} {perPage} bind:currentPage let:pages let:hasNext let:hasPrev let:range let:setPage siblingCount={1}>

View file

@ -404,10 +404,10 @@
if (['ArrowLeft', 'ArrowRight'].includes(event.key)) event.stopPropagation()
switch (event.key) {
case 'ArrowLeft':
seek(-$settings.playerSeek)
seek(-Number($settings.playerSeek))
break
case 'ArrowRight':
seek($settings.playerSeek)
seek(Number($settings.playerSeek))
break
case 'Enter':
playPause()
@ -509,7 +509,7 @@
},
ArrowLeft: {
fn: () => {
seek(-$settings.playerSeek)
seek(-Number($settings.playerSeek))
},
id: 'fast_rewind',
icon: Rewind,
@ -518,7 +518,7 @@
},
ArrowRight: {
fn: () => {
seek($settings.playerSeek)
seek(Number($settings.playerSeek))
},
id: 'fast_forward',
icon: FastForward,

View file

@ -36,7 +36,6 @@ export async function resolveFilesPoorly (promise: Promise<{media: Media, id: st
const resolved = videoFiles.length === 1 ? [{ episode: list.episode, parseObject: (await anitomyscript([videoFiles[0]!.name]))[0]!, media: list.media, failed: false }] : await AnimeResolver.resolveFileAnime(videoFiles.map(file => file.name))
console.log({ resolved, videoFiles })
const resolvedFiles: ResolvedFile[] = videoFiles.map(file => {
return {
...file,
@ -315,7 +314,6 @@ const AnimeResolver = new class AnimeResolver {
}
return false
}) as ResultOf<typeof MediaEdgeFrag> | undefined
console.log(res)
// this is hit-miss
if (!res && !skip && type === 'SEQUEL') res = this.findEdge(media, type, formats = ['TV', 'TV_SHORT', 'OVA'], true)
return res

View file

@ -15,9 +15,8 @@
import { Button, type Props } from '$lib/components/ui/button'
import { cn } from '$lib/utils.js'
type $$Props = Props & { disabled?: boolean | undefined | null }
type $$Props = Props
export let href: string | null | undefined = undefined
export let disabled: $$Props['disabled'] = undefined
function matchPath (path: string, page: { url: URL }) {
return page.url.pathname.startsWith(path)

View file

@ -5,8 +5,9 @@ import { refocusExchange } from '@urql/exchange-refocus'
import { Client, fetchExchange, queryStore, type OperationResultState, gql as _gql } from '@urql/svelte'
import Bottleneck from 'bottleneck'
import lavenshtein from 'js-levenshtein'
import { readable, writable, type Writable } from 'simple-store-svelte'
import { derived } from 'svelte/store'
import { writable as _writable } from 'simple-store-svelte'
import { derived, readable, writable, type Writable } from 'svelte/store'
import { toast } from 'svelte-sonner'
import gql from './gql'
import { CommentFrag, Comments, CustomLists, DeleteEntry, DeleteThreadComment, Entry, Following, FullMedia, FullMediaList, IDMedia, SaveThreadComment, Schedule, Search, ThreadFrag, Threads, ToggleFavourite, ToggleLike, UserLists, Viewer } from './queries'
@ -293,6 +294,7 @@ class AnilistClient {
}
setRateLimit (sec: number) {
toast.error('Anilist Error', { description: 'Rate limit exceeded, retrying in ' + Math.round(sec / 1000) + ' seconds.' })
if (!this.rateLimitPromise) this.rateLimitPromise = sleep(sec).then(() => { this.rateLimitPromise = null })
return sec
}
@ -303,8 +305,8 @@ class AnilistClient {
if (error.name === 'AbortError') return undefined
if (jobInfo.retryCount > 8) return undefined
if (error.message === 'Failed to fetch') return this.setRateLimit(6000)
if (!(error instanceof FetchError)) return 0
if (error.message === 'Failed to fetch' && !error.res.headers.get('retry-after')) return this.setRateLimit(60000)
if (error.res.status === 500) return 1000
const time = (parseInt(error.res.headers.get('retry-after') ?? '60') + 1) * 1000
@ -315,16 +317,17 @@ class AnilistClient {
this.continueIDs.subscribe(() => undefined)
}
viewer = writable<ViewerData | undefined>(safeLocalStorage('ALViewer'))
viewer = _writable<ViewerData | undefined>(safeLocalStorage('ALViewer'))
userlists = derived<typeof this.viewer, OperationResultState<ResultOf<typeof UserLists>>>(this.viewer, (store, set) => {
return queryStore({ client: this.client, query: UserLists, variables: { id: store?.viewer?.id } }).subscribe(set)
})
// these should be optimised to be called with ids.slice(index, index + perPage)
// WARN: these 3 sections are hacky, i use oldvalue to prevent re-running loops, I DO NOT KNOW WHY THE LOOPS HAPPEN!
// TODO: these should be optimised to be called with ids.slice(index, index + perPage)
continueIDs = readable<number[]>([], set => {
let oldvalue: number[] = []
this.userlists.subscribe(values => {
const sub = this.userlists.subscribe(values => {
if (!values.data?.MediaListCollection?.lists) return []
const mediaList = values.data.MediaListCollection.lists.reduce<NonNullable<NonNullable<NonNullable<NonNullable<ResultOf<typeof UserLists>['MediaListCollection']>['lists']>[0]>['entries']>>((filtered, list) => {
return (list?.status === 'CURRENT' || list?.status === 'REPEATING') ? filtered.concat(list.entries) : filtered
@ -340,12 +343,13 @@ class AnilistClient {
oldvalue = ids
set(ids)
})
return sub
})
// this needs to be called with onList: false
// TODO: this needs to be called with onList: false
sequelIDs = readable<number[]>([], set => {
let oldvalue: number[] = []
this.userlists.subscribe(values => {
const sub = this.userlists.subscribe(values => {
if (!values.data?.MediaListCollection?.lists) return []
const mediaList = values.data.MediaListCollection.lists.find(list => list?.status === 'COMPLETED')?.entries
if (!mediaList) return []
@ -358,6 +362,22 @@ class AnilistClient {
oldvalue = ids
set(ids)
})
return sub
})
planningIDs = readable<number[]>([], set => {
let oldvalue: number[] = []
const sub = this.userlists.subscribe(userLists => {
if (!userLists.data?.MediaListCollection?.lists) return []
const mediaList = userLists.data.MediaListCollection.lists.find(list => list?.status === 'PLANNING')?.entries
if (!mediaList) return []
const ids = mediaList.map(entry => entry?.media?.id) as number[]
if (arrayEqual(oldvalue, ids)) return
oldvalue = ids
set(ids)
})
return sub
})
search (variables: VariablesOf<typeof Search>, pause?: boolean) {

View file

@ -63,6 +63,12 @@ export default new class AuthAggregator {
if (this.anilist()) return client.following(id)
}
planningIDs () {
if (this.anilist()) return client.planningIDs
return client.planningIDs
}
continueIDs () {
if (this.anilist()) return client.continueIDs

View file

@ -36,7 +36,7 @@ export default {
idleAnimation: true,
enableExternal: false,
playerPath: '',
playerSeek: 2,
playerSeek: '2',
playerSkip: false,
playerSkipFiller: false,
minimalPlayerUI: false

View file

@ -74,7 +74,9 @@
</Tabs.Content>
<Tabs.Content value='threads' tabindex={-1}>
{#key mediaID}
<Threads {media} />
{#if value === 'threads'}
<Threads {media} />
{/if}
{/key}
</Tabs.Content>
</Tabs.Root>

View file

@ -1,9 +1,9 @@
<script lang='ts' context='module'>
import { derived } from 'svelte/store'
import { derived, type Readable } from 'svelte/store'
import type { Search } from '$lib/modules/anilist/queries'
import type { VariablesOf } from 'gql.tada'
import type { Readable } from 'simple-store-svelte'
// import type { Readable } from 'simple-store-svelte'
import { client, currentSeason, currentYear } from '$lib/modules/anilist'
import { authAggregator } from '$lib/modules/auth'
@ -36,11 +36,15 @@
}
const sectionQueries = derived<[
typeof authAggregator.hasAuth, Readable<number[]>, Readable<number[]>], SectionQuery[]
>([authAggregator.hasAuth, authAggregator.continueIDs(), authAggregator.sequelIDs()], ([hasAuth, continueIDs, sequelIDs], set) => {
typeof authAggregator.hasAuth, Readable<number[]>, Readable<number[]>, Readable<number[]>], SectionQuery[]
>([authAggregator.hasAuth, authAggregator.continueIDs(), authAggregator.sequelIDs(), authAggregator.planningIDs()], ([hasAuth, continueIDs, sequelIDs, planningIDs], set) => {
const sections = [...sectionsQueries]
const unsub: Array<() => void> = []
if (hasAuth) {
const planningQuery = client.search({ ids: planningIDs }, true)
unsub.push(planningQuery.subscribe(() => undefined))
sections.unshift({ title: 'Your List', query: planningQuery, variables: { ids: planningIDs } })
const sequelsQuery = client.search({ ids: sequelIDs, status: ['FINISHED', 'RELEASING'], onList: false }, true)
unsub.push(sequelsQuery.subscribe(() => undefined))
sections.unshift({ title: 'Sequels You Missed', query: sequelsQuery, variables: { ids: sequelIDs, status: ['FINISHED', 'RELEASING'], onList: false } })