fix: reduce caching to 14 days

fix: episode list width on external player on mobile
fix: start miniplayer dragging at >3px of movement
fix: seekbar getting stuck when using android swipe gestures
fix: android popups being weird width [maybe]
This commit is contained in:
ThaUnknown 2025-08-27 23:01:45 +02:00
parent 3e94d66b29
commit c5c6c35799
No known key found for this signature in database
7 changed files with 22 additions and 8 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "ui", "name": "ui",
"version": "6.4.104", "version": "6.4.105",
"license": "BUSL-1.1", "license": "BUSL-1.1",
"private": true, "private": true,
"packageManager": "pnpm@9.15.5", "packageManager": "pnpm@9.15.5",

View file

@ -70,7 +70,7 @@
<div class='text-white text-lg font-normal leading-none line-clamp-1 hover:text-neutral-300 cursor-pointer' use:click={() => goto(`/app/anime/${mediaInfo.media.id}`)}>{mediaInfo.session.title}</div> <div class='text-white text-lg font-normal leading-none line-clamp-1 hover:text-neutral-300 cursor-pointer' use:click={() => goto(`/app/anime/${mediaInfo.media.id}`)}>{mediaInfo.session.title}</div>
<Sheet.Root portal={wrapper}> <Sheet.Root portal={wrapper}>
<Sheet.Trigger id='episode-list-button' class='text-[rgba(217,217,217,0.6)] hover:text-neutral-500 text-sm leading-none font-light line-clamp-1 text-left'>{mediaInfo.session.description}</Sheet.Trigger> <Sheet.Trigger id='episode-list-button' class='text-[rgba(217,217,217,0.6)] hover:text-neutral-500 text-sm leading-none font-light line-clamp-1 text-left'>{mediaInfo.session.description}</Sheet.Trigger>
<Sheet.Content class='w-[550px] sm:max-w-full h-full overflow-y-scroll flex flex-col pb-0 shrink-0 gap-0 bg-black'> <Sheet.Content class='w-full sm:w-[550px] p-3 sm:p-6 max-w-full sm:max-w-full h-full overflow-y-scroll flex flex-col !pb-0 shrink-0 gap-0 bg-black justify-between overflow-x-clip'>
{#if mediaInfo.media} {#if mediaInfo.media}
{#await episodes(mediaInfo.media.id) then eps} {#await episodes(mediaInfo.media.id) then eps}
<EpisodesList {eps} media={mediaInfo.media} /> <EpisodesList {eps} media={mediaInfo.media} />

View file

@ -904,7 +904,7 @@
<a class='text-white text-lg font-normal leading-none line-clamp-1 hover:text-neutral-300 hover:underline' href='/app/anime/{mediaInfo.media.id}' data-up='#player-options-button-top'>{mediaInfo.session.title}</a> <a class='text-white text-lg font-normal leading-none line-clamp-1 hover:text-neutral-300 hover:underline' href='/app/anime/{mediaInfo.media.id}' data-up='#player-options-button-top'>{mediaInfo.session.title}</a>
<Sheet.Root portal={wrapper} bind:open={episodeListOpen}> <Sheet.Root portal={wrapper} bind:open={episodeListOpen}>
<Sheet.Trigger id='episode-list-button' data-down='#player-seekbar' class='text-[rgba(217,217,217,0.6)] hover:text-neutral-500 text-sm leading-none font-light line-clamp-1 text-left hover:underline bg-transparent'>{mediaInfo.session.description}</Sheet.Trigger> <Sheet.Trigger id='episode-list-button' data-down='#player-seekbar' class='text-[rgba(217,217,217,0.6)] hover:text-neutral-500 text-sm leading-none font-light line-clamp-1 text-left hover:underline bg-transparent'>{mediaInfo.session.description}</Sheet.Trigger>
<Sheet.Content class='w-full sm:w-[550px] p-3 sm:p-6 max-w-full sm:max-w-full h-full overflow-y-scroll flex flex-col pb-0 shrink-0 gap-0 bg-black justify-between overflow-x-clip'> <Sheet.Content class='w-full sm:w-[550px] p-3 sm:p-6 max-w-full sm:max-w-full h-full overflow-y-scroll flex flex-col !pb-0 shrink-0 gap-0 bg-black justify-between overflow-x-clip'>
{#if mediaInfo.media} {#if mediaInfo.media}
{#await Promise.all([episodes(mediaInfo.media.id), client.single(mediaInfo.media.id)]) then [eps, media]} {#await Promise.all([episodes(mediaInfo.media.id), client.single(mediaInfo.media.id)]) then [eps, media]}
{#if media.data?.Media} {#if media.data?.Media}

View file

@ -138,6 +138,8 @@
} }
</script> </script>
<svelte:window on:blur={endHover} />
<div class='w-full flex cursor-pointer relative group/seekbar touch-none !transform-none' class:!cursor-grab={seeking} <div class='w-full flex cursor-pointer relative group/seekbar touch-none !transform-none' class:!cursor-grab={seeking}
tabindex='0' role='slider' aria-valuenow='0' tabindex='0' role='slider' aria-valuenow='0'
id='player-seekbar' id='player-seekbar'

View file

@ -29,9 +29,17 @@
let bottom = '0px' let bottom = '0px'
let right = '100%' let right = '100%'
let firstX = 0
let firstY = 0
function calculatePosition (e: PointerEvent) { function calculatePosition (e: PointerEvent) {
if (!isMiniplayer) return if (!isMiniplayer) return
dragging = true if (firstX === 0) {
firstX = e.offsetX
firstY = e.offsetY
} else if (!dragging && Math.abs(firstX - e.offsetX) > 3 && Math.abs(firstY - e.offsetY) > 3) {
dragging = true
}
bottom = e.offsetY - initialY + 'px' bottom = e.offsetY - initialY + 'px'
right = e.offsetX - initialX + 'px' right = e.offsetX - initialX + 'px'
} }
@ -39,6 +47,8 @@
function endHover () { function endHover () {
if (!isMiniplayer) return if (!isMiniplayer) return
dragging = false dragging = false
firstX = 0
firstY = 0
} }
let initialX = 0 let initialX = 0
@ -74,7 +84,7 @@
'pointer-events-auto w-full', 'pointer-events-auto w-full',
isMiniplayer ? 'max-w-80 absolute bottom-0 right-0 rounded-lg overflow-clip miniplayer transition-transform duration-[500ms] ease-[cubic-bezier(0.3,1.5,0.8,1)]' : 'h-full w-full', isMiniplayer ? 'max-w-80 absolute bottom-0 right-0 rounded-lg overflow-clip miniplayer transition-transform duration-[500ms] ease-[cubic-bezier(0.3,1.5,0.8,1)]' : 'h-full w-full',
dragging && isMiniplayer && 'dragging', dragging && isMiniplayer && 'dragging',
!$isPlaying && 'paused hover:paused-show' !$isPlaying && 'paused select:paused-show'
)} style:--top={bottom} style:--left={right}> )} style:--top={bottom} style:--left={right}>
{#if $active} {#if $active}
{#await $active} {#await $active}

View file

@ -36,7 +36,7 @@ export const storagePromise = Promise.withResolvers<void>()
export const storage = makeDefaultStorage({ export const storage = makeDefaultStorage({
idbName: 'graphcache-v3', idbName: 'graphcache-v3',
onCacheHydrated: () => storagePromise.resolve(), onCacheHydrated: () => storagePromise.resolve(),
maxAge: 31 // The maximum age of the persisted data in days maxAge: 14 // The maximum age of the persisted data in days
}) })
debug('Loading urql client') debug('Loading urql client')

View file

@ -1,3 +1,5 @@
import { SUPPORTS } from './settings'
import type { AuthResponse, Native, TorrentInfo } from 'native' import type { AuthResponse, Native, TorrentInfo } from 'native'
import { sleep } from '$lib/utils' import { sleep } from '$lib/utils'
@ -51,7 +53,7 @@ const dummyFiles = [
export default Object.assign<Native, Partial<Native>>({ export default Object.assign<Native, Partial<Native>>({
authAL: (url: string) => { authAL: (url: string) => {
return new Promise<AuthResponse>((resolve, reject) => { return new Promise<AuthResponse>((resolve, reject) => {
const popup = open(url, 'authframe', 'popup,width=382,height=582') const popup = open(url, 'authframe', SUPPORTS.isAndroid ? 'popup' : 'popup,width=382,height=582')
if (!popup) return reject(new Error('Failed to open popup')) if (!popup) return reject(new Error('Failed to open popup'))
const check = () => { const check = () => {
if (popup.closed) return reject(new Error('Popup closed')) if (popup.closed) return reject(new Error('Popup closed'))
@ -70,7 +72,7 @@ export default Object.assign<Native, Partial<Native>>({
}, },
authMAL: (url: string) => { authMAL: (url: string) => {
return new Promise<{ code: string, state: string }>((resolve, reject) => { return new Promise<{ code: string, state: string }>((resolve, reject) => {
const popup = open(url, 'authframe', 'popup,width=540,height=782') const popup = open(url, 'authframe', SUPPORTS.isAndroid ? 'popup' : 'popup,width=540,height=782')
if (!popup) return reject(new Error('Failed to open popup')) if (!popup) return reject(new Error('Failed to open popup'))
const check = () => { const check = () => {
if (popup.closed) return reject(new Error('Popup closed')) if (popup.closed) return reject(new Error('Popup closed'))