2024-04-15 20:20:32 +02:00
|
|
|
import { goto } from '$app/navigation';
|
2024-04-24 15:24:19 -04:00
|
|
|
import { page } from '$app/stores';
|
|
|
|
|
import { AppRoute } from '$lib/constants';
|
|
|
|
|
import { getAssetInfo } from '@immich/sdk';
|
|
|
|
|
import type { NavigationTarget } from '@sveltejs/kit';
|
|
|
|
|
import { get } from 'svelte/store';
|
2024-04-15 20:20:32 +02:00
|
|
|
|
feat(web): Scroll to asset in gridview; increase gridview perf; reduce memory; scrollbar ticks in fixed position (#10646)
* Squashed
* Change strategy - now pre-measure buckets offscreen, so don't need to worry about sub-bucket scroll preservation
* Reduce jank on scroll, delay DOM updates until after scroll
* css opt, log measure time
* Trickle out queue while scrolling, flush when stopped
* yay
* Cleanup cleanup...
* everybody...
* everywhere...
* Clean up cleanup!
* Everybody do their share
* CLEANUP!
* package-lock ?
* dynamic measure, todo
* Fix web test
* type lint
* fix e2e
* e2e test
* Better scrollbar
* Tuning, and more tunables
* Tunable tweaks, more tunables
* Scrollbar dots and viewport events
* lint
* Tweaked tunnables, use requestIdleCallback for garbage tasks, bug fixes
* New tunables, and don't update url by default
* Bug fixes
* Bug fix, with debug
* Fix flickr, fix graybox bug, reduced debug
* Refactor/cleanup
* Fix
* naming
* Final cleanup
* review comment
* Forgot to update this after naming change
* scrubber works, with debug
* cleanup
* Rename scrollbar to scrubber
* rename to
* left over rename and change to previous album bar
* bugfix addassets, comments
* missing destroy(), cleanup
---------
Co-authored-by: Alex <alex.tran1502@gmail.com>
2024-08-21 22:15:21 -04:00
|
|
|
export type AssetGridRouteSearchParams = {
|
|
|
|
|
at: string | null | undefined;
|
|
|
|
|
};
|
2023-11-14 23:55:03 +01:00
|
|
|
export const isExternalUrl = (url: string): boolean => {
|
2024-12-18 15:19:48 +01:00
|
|
|
return new URL(url, globalThis.location.href).origin !== globalThis.location.origin;
|
2023-11-14 23:55:03 +01:00
|
|
|
};
|
2024-04-15 20:20:32 +02:00
|
|
|
|
2024-04-24 15:24:19 -04:00
|
|
|
export const isPhotosRoute = (route?: string | null) => !!route?.startsWith('/(user)/photos/[[assetId=id]]');
|
|
|
|
|
export const isSharedLinkRoute = (route?: string | null) => !!route?.startsWith('/(user)/share/[key]');
|
|
|
|
|
export const isSearchRoute = (route?: string | null) => !!route?.startsWith('/(user)/search');
|
|
|
|
|
export const isAlbumsRoute = (route?: string | null) => !!route?.startsWith('/(user)/albums/[albumId=id]');
|
|
|
|
|
export const isPeopleRoute = (route?: string | null) => !!route?.startsWith('/(user)/people/[personId]');
|
2025-06-02 04:45:39 +02:00
|
|
|
export const isLockedFolderRoute = (route?: string | null) => !!route?.startsWith('/(user)/locked');
|
2024-04-24 15:24:19 -04:00
|
|
|
|
|
|
|
|
export const isAssetViewerRoute = (target?: NavigationTarget | null) =>
|
|
|
|
|
!!(target?.route.id?.endsWith('/[[assetId=id]]') && 'assetId' in (target?.params || {}));
|
|
|
|
|
|
2024-04-25 14:32:21 -05:00
|
|
|
export function getAssetInfoFromParam({ assetId, key }: { assetId?: string; key?: string }) {
|
2025-06-09 11:02:16 -04:00
|
|
|
return assetId ? getAssetInfo({ id: assetId, key }) : undefined;
|
2024-04-24 15:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function currentUrlWithoutAsset() {
|
|
|
|
|
const $page = get(page);
|
|
|
|
|
// This contains special casing for the /photos/:assetId route, which hangs directly
|
|
|
|
|
// off / instead of a subpath, unlike every other asset-containing route.
|
|
|
|
|
return isPhotosRoute($page.route.id)
|
|
|
|
|
? AppRoute.PHOTOS + $page.url.search
|
|
|
|
|
: $page.url.pathname.replace(/(\/photos.*)$/, '') + $page.url.search;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-08 16:33:23 -04:00
|
|
|
export function currentUrlReplaceAssetId(assetId: string) {
|
2024-04-24 15:24:19 -04:00
|
|
|
const $page = get(page);
|
feat(web): Scroll to asset in gridview; increase gridview perf; reduce memory; scrollbar ticks in fixed position (#10646)
* Squashed
* Change strategy - now pre-measure buckets offscreen, so don't need to worry about sub-bucket scroll preservation
* Reduce jank on scroll, delay DOM updates until after scroll
* css opt, log measure time
* Trickle out queue while scrolling, flush when stopped
* yay
* Cleanup cleanup...
* everybody...
* everywhere...
* Clean up cleanup!
* Everybody do their share
* CLEANUP!
* package-lock ?
* dynamic measure, todo
* Fix web test
* type lint
* fix e2e
* e2e test
* Better scrollbar
* Tuning, and more tunables
* Tunable tweaks, more tunables
* Scrollbar dots and viewport events
* lint
* Tweaked tunnables, use requestIdleCallback for garbage tasks, bug fixes
* New tunables, and don't update url by default
* Bug fixes
* Bug fix, with debug
* Fix flickr, fix graybox bug, reduced debug
* Refactor/cleanup
* Fix
* naming
* Final cleanup
* review comment
* Forgot to update this after naming change
* scrubber works, with debug
* cleanup
* Rename scrollbar to scrubber
* rename to
* left over rename and change to previous album bar
* bugfix addassets, comments
* missing destroy(), cleanup
---------
Co-authored-by: Alex <alex.tran1502@gmail.com>
2024-08-21 22:15:21 -04:00
|
|
|
const params = new URLSearchParams($page.url.search);
|
|
|
|
|
// always remove the assetGridScrollTargetParams
|
|
|
|
|
params.delete('at');
|
2025-06-13 15:54:59 +01:00
|
|
|
const paramsString = params.toString();
|
|
|
|
|
const searchparams = paramsString == '' ? '' : '?' + params.toString();
|
2024-04-24 15:24:19 -04:00
|
|
|
// this contains special casing for the /photos/:assetId photos route, which hangs directly
|
|
|
|
|
// off / instead of a subpath, unlike every other asset-containing route.
|
|
|
|
|
return isPhotosRoute($page.route.id)
|
feat(web): Scroll to asset in gridview; increase gridview perf; reduce memory; scrollbar ticks in fixed position (#10646)
* Squashed
* Change strategy - now pre-measure buckets offscreen, so don't need to worry about sub-bucket scroll preservation
* Reduce jank on scroll, delay DOM updates until after scroll
* css opt, log measure time
* Trickle out queue while scrolling, flush when stopped
* yay
* Cleanup cleanup...
* everybody...
* everywhere...
* Clean up cleanup!
* Everybody do their share
* CLEANUP!
* package-lock ?
* dynamic measure, todo
* Fix web test
* type lint
* fix e2e
* e2e test
* Better scrollbar
* Tuning, and more tunables
* Tunable tweaks, more tunables
* Scrollbar dots and viewport events
* lint
* Tweaked tunnables, use requestIdleCallback for garbage tasks, bug fixes
* New tunables, and don't update url by default
* Bug fixes
* Bug fix, with debug
* Fix flickr, fix graybox bug, reduced debug
* Refactor/cleanup
* Fix
* naming
* Final cleanup
* review comment
* Forgot to update this after naming change
* scrubber works, with debug
* cleanup
* Rename scrollbar to scrubber
* rename to
* left over rename and change to previous album bar
* bugfix addassets, comments
* missing destroy(), cleanup
---------
Co-authored-by: Alex <alex.tran1502@gmail.com>
2024-08-21 22:15:21 -04:00
|
|
|
? `${AppRoute.PHOTOS}/${assetId}${searchparams}`
|
|
|
|
|
: `${$page.url.pathname.replace(/(\/photos.*)$/, '')}/photos/${assetId}${searchparams}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function replaceScrollTarget(url: string, searchParams?: AssetGridRouteSearchParams | null) {
|
|
|
|
|
const $page = get(page);
|
|
|
|
|
const parsed = new URL(url, $page.url);
|
|
|
|
|
|
|
|
|
|
const { at: assetId } = searchParams || { at: null };
|
|
|
|
|
|
|
|
|
|
if (!assetId) {
|
|
|
|
|
return parsed.pathname;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const params = new URLSearchParams($page.url.search);
|
|
|
|
|
if (assetId) {
|
|
|
|
|
params.set('at', assetId);
|
|
|
|
|
}
|
|
|
|
|
return parsed.pathname + '?' + params.toString();
|
2024-04-24 15:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function currentUrl() {
|
|
|
|
|
const $page = get(page);
|
|
|
|
|
const current = $page.url;
|
feat(web): Scroll to asset in gridview; increase gridview perf; reduce memory; scrollbar ticks in fixed position (#10646)
* Squashed
* Change strategy - now pre-measure buckets offscreen, so don't need to worry about sub-bucket scroll preservation
* Reduce jank on scroll, delay DOM updates until after scroll
* css opt, log measure time
* Trickle out queue while scrolling, flush when stopped
* yay
* Cleanup cleanup...
* everybody...
* everywhere...
* Clean up cleanup!
* Everybody do their share
* CLEANUP!
* package-lock ?
* dynamic measure, todo
* Fix web test
* type lint
* fix e2e
* e2e test
* Better scrollbar
* Tuning, and more tunables
* Tunable tweaks, more tunables
* Scrollbar dots and viewport events
* lint
* Tweaked tunnables, use requestIdleCallback for garbage tasks, bug fixes
* New tunables, and don't update url by default
* Bug fixes
* Bug fix, with debug
* Fix flickr, fix graybox bug, reduced debug
* Refactor/cleanup
* Fix
* naming
* Final cleanup
* review comment
* Forgot to update this after naming change
* scrubber works, with debug
* cleanup
* Rename scrollbar to scrubber
* rename to
* left over rename and change to previous album bar
* bugfix addassets, comments
* missing destroy(), cleanup
---------
Co-authored-by: Alex <alex.tran1502@gmail.com>
2024-08-21 22:15:21 -04:00
|
|
|
return current.pathname + current.search + current.hash;
|
2024-04-24 15:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface Route {
|
|
|
|
|
/**
|
|
|
|
|
* The route to target, or 'current' to stay on current route.
|
|
|
|
|
*/
|
|
|
|
|
targetRoute: string | 'current';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface AssetRoute extends Route {
|
|
|
|
|
targetRoute: 'current';
|
feat(web): Scroll to asset in gridview; increase gridview perf; reduce memory; scrollbar ticks in fixed position (#10646)
* Squashed
* Change strategy - now pre-measure buckets offscreen, so don't need to worry about sub-bucket scroll preservation
* Reduce jank on scroll, delay DOM updates until after scroll
* css opt, log measure time
* Trickle out queue while scrolling, flush when stopped
* yay
* Cleanup cleanup...
* everybody...
* everywhere...
* Clean up cleanup!
* Everybody do their share
* CLEANUP!
* package-lock ?
* dynamic measure, todo
* Fix web test
* type lint
* fix e2e
* e2e test
* Better scrollbar
* Tuning, and more tunables
* Tunable tweaks, more tunables
* Scrollbar dots and viewport events
* lint
* Tweaked tunnables, use requestIdleCallback for garbage tasks, bug fixes
* New tunables, and don't update url by default
* Bug fixes
* Bug fix, with debug
* Fix flickr, fix graybox bug, reduced debug
* Refactor/cleanup
* Fix
* naming
* Final cleanup
* review comment
* Forgot to update this after naming change
* scrubber works, with debug
* cleanup
* Rename scrollbar to scrubber
* rename to
* left over rename and change to previous album bar
* bugfix addassets, comments
* missing destroy(), cleanup
---------
Co-authored-by: Alex <alex.tran1502@gmail.com>
2024-08-21 22:15:21 -04:00
|
|
|
assetId: string | null | undefined;
|
2024-04-24 15:24:19 -04:00
|
|
|
}
|
feat(web): Scroll to asset in gridview; increase gridview perf; reduce memory; scrollbar ticks in fixed position (#10646)
* Squashed
* Change strategy - now pre-measure buckets offscreen, so don't need to worry about sub-bucket scroll preservation
* Reduce jank on scroll, delay DOM updates until after scroll
* css opt, log measure time
* Trickle out queue while scrolling, flush when stopped
* yay
* Cleanup cleanup...
* everybody...
* everywhere...
* Clean up cleanup!
* Everybody do their share
* CLEANUP!
* package-lock ?
* dynamic measure, todo
* Fix web test
* type lint
* fix e2e
* e2e test
* Better scrollbar
* Tuning, and more tunables
* Tunable tweaks, more tunables
* Scrollbar dots and viewport events
* lint
* Tweaked tunnables, use requestIdleCallback for garbage tasks, bug fixes
* New tunables, and don't update url by default
* Bug fixes
* Bug fix, with debug
* Fix flickr, fix graybox bug, reduced debug
* Refactor/cleanup
* Fix
* naming
* Final cleanup
* review comment
* Forgot to update this after naming change
* scrubber works, with debug
* cleanup
* Rename scrollbar to scrubber
* rename to
* left over rename and change to previous album bar
* bugfix addassets, comments
* missing destroy(), cleanup
---------
Co-authored-by: Alex <alex.tran1502@gmail.com>
2024-08-21 22:15:21 -04:00
|
|
|
interface AssetGridRoute extends Route {
|
|
|
|
|
targetRoute: 'current';
|
|
|
|
|
assetId: string | null | undefined;
|
|
|
|
|
assetGridRouteSearchParams: AssetGridRouteSearchParams | null | undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ImmichRoute = AssetRoute | AssetGridRoute;
|
|
|
|
|
|
|
|
|
|
type NavOptions = {
|
|
|
|
|
/* navigate even if url is the same */
|
|
|
|
|
forceNavigate?: boolean | undefined;
|
|
|
|
|
replaceState?: boolean | undefined;
|
|
|
|
|
noScroll?: boolean | undefined;
|
|
|
|
|
keepFocus?: boolean | undefined;
|
|
|
|
|
invalidateAll?: boolean | undefined;
|
|
|
|
|
state?: App.PageState | undefined;
|
|
|
|
|
};
|
2024-04-24 15:24:19 -04:00
|
|
|
|
|
|
|
|
function isAssetRoute(route: Route): route is AssetRoute {
|
|
|
|
|
return route.targetRoute === 'current' && 'assetId' in route;
|
|
|
|
|
}
|
|
|
|
|
|
feat(web): Scroll to asset in gridview; increase gridview perf; reduce memory; scrollbar ticks in fixed position (#10646)
* Squashed
* Change strategy - now pre-measure buckets offscreen, so don't need to worry about sub-bucket scroll preservation
* Reduce jank on scroll, delay DOM updates until after scroll
* css opt, log measure time
* Trickle out queue while scrolling, flush when stopped
* yay
* Cleanup cleanup...
* everybody...
* everywhere...
* Clean up cleanup!
* Everybody do their share
* CLEANUP!
* package-lock ?
* dynamic measure, todo
* Fix web test
* type lint
* fix e2e
* e2e test
* Better scrollbar
* Tuning, and more tunables
* Tunable tweaks, more tunables
* Scrollbar dots and viewport events
* lint
* Tweaked tunnables, use requestIdleCallback for garbage tasks, bug fixes
* New tunables, and don't update url by default
* Bug fixes
* Bug fix, with debug
* Fix flickr, fix graybox bug, reduced debug
* Refactor/cleanup
* Fix
* naming
* Final cleanup
* review comment
* Forgot to update this after naming change
* scrubber works, with debug
* cleanup
* Rename scrollbar to scrubber
* rename to
* left over rename and change to previous album bar
* bugfix addassets, comments
* missing destroy(), cleanup
---------
Co-authored-by: Alex <alex.tran1502@gmail.com>
2024-08-21 22:15:21 -04:00
|
|
|
function isAssetGridRoute(route: Route): route is AssetGridRoute {
|
|
|
|
|
return route.targetRoute === 'current' && 'assetId' in route && 'assetGridRouteSearchParams' in route;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function navigateAssetRoute(route: AssetRoute, options?: NavOptions) {
|
2024-04-24 15:24:19 -04:00
|
|
|
const { assetId } = route;
|
|
|
|
|
const next = assetId ? currentUrlReplaceAssetId(assetId) : currentUrlWithoutAsset();
|
feat(web): Scroll to asset in gridview; increase gridview perf; reduce memory; scrollbar ticks in fixed position (#10646)
* Squashed
* Change strategy - now pre-measure buckets offscreen, so don't need to worry about sub-bucket scroll preservation
* Reduce jank on scroll, delay DOM updates until after scroll
* css opt, log measure time
* Trickle out queue while scrolling, flush when stopped
* yay
* Cleanup cleanup...
* everybody...
* everywhere...
* Clean up cleanup!
* Everybody do their share
* CLEANUP!
* package-lock ?
* dynamic measure, todo
* Fix web test
* type lint
* fix e2e
* e2e test
* Better scrollbar
* Tuning, and more tunables
* Tunable tweaks, more tunables
* Scrollbar dots and viewport events
* lint
* Tweaked tunnables, use requestIdleCallback for garbage tasks, bug fixes
* New tunables, and don't update url by default
* Bug fixes
* Bug fix, with debug
* Fix flickr, fix graybox bug, reduced debug
* Refactor/cleanup
* Fix
* naming
* Final cleanup
* review comment
* Forgot to update this after naming change
* scrubber works, with debug
* cleanup
* Rename scrollbar to scrubber
* rename to
* left over rename and change to previous album bar
* bugfix addassets, comments
* missing destroy(), cleanup
---------
Co-authored-by: Alex <alex.tran1502@gmail.com>
2024-08-21 22:15:21 -04:00
|
|
|
const current = currentUrl();
|
|
|
|
|
if (next !== current || options?.forceNavigate) {
|
2025-02-25 09:27:34 -06:00
|
|
|
await goto(next, options);
|
feat(web): Scroll to asset in gridview; increase gridview perf; reduce memory; scrollbar ticks in fixed position (#10646)
* Squashed
* Change strategy - now pre-measure buckets offscreen, so don't need to worry about sub-bucket scroll preservation
* Reduce jank on scroll, delay DOM updates until after scroll
* css opt, log measure time
* Trickle out queue while scrolling, flush when stopped
* yay
* Cleanup cleanup...
* everybody...
* everywhere...
* Clean up cleanup!
* Everybody do their share
* CLEANUP!
* package-lock ?
* dynamic measure, todo
* Fix web test
* type lint
* fix e2e
* e2e test
* Better scrollbar
* Tuning, and more tunables
* Tunable tweaks, more tunables
* Scrollbar dots and viewport events
* lint
* Tweaked tunnables, use requestIdleCallback for garbage tasks, bug fixes
* New tunables, and don't update url by default
* Bug fixes
* Bug fix, with debug
* Fix flickr, fix graybox bug, reduced debug
* Refactor/cleanup
* Fix
* naming
* Final cleanup
* review comment
* Forgot to update this after naming change
* scrubber works, with debug
* cleanup
* Rename scrollbar to scrubber
* rename to
* left over rename and change to previous album bar
* bugfix addassets, comments
* missing destroy(), cleanup
---------
Co-authored-by: Alex <alex.tran1502@gmail.com>
2024-08-21 22:15:21 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function navigateAssetGridRoute(route: AssetGridRoute, options?: NavOptions) {
|
|
|
|
|
const { assetId, assetGridRouteSearchParams: assetGridScrollTarget } = route;
|
|
|
|
|
const assetUrl = assetId ? currentUrlReplaceAssetId(assetId) : currentUrlWithoutAsset();
|
|
|
|
|
const next = replaceScrollTarget(assetUrl, assetGridScrollTarget);
|
|
|
|
|
const current = currentUrl();
|
|
|
|
|
if (next !== current || options?.forceNavigate) {
|
2025-02-25 09:27:34 -06:00
|
|
|
await goto(next, options);
|
2024-04-24 15:24:19 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
feat(web): Scroll to asset in gridview; increase gridview perf; reduce memory; scrollbar ticks in fixed position (#10646)
* Squashed
* Change strategy - now pre-measure buckets offscreen, so don't need to worry about sub-bucket scroll preservation
* Reduce jank on scroll, delay DOM updates until after scroll
* css opt, log measure time
* Trickle out queue while scrolling, flush when stopped
* yay
* Cleanup cleanup...
* everybody...
* everywhere...
* Clean up cleanup!
* Everybody do their share
* CLEANUP!
* package-lock ?
* dynamic measure, todo
* Fix web test
* type lint
* fix e2e
* e2e test
* Better scrollbar
* Tuning, and more tunables
* Tunable tweaks, more tunables
* Scrollbar dots and viewport events
* lint
* Tweaked tunnables, use requestIdleCallback for garbage tasks, bug fixes
* New tunables, and don't update url by default
* Bug fixes
* Bug fix, with debug
* Fix flickr, fix graybox bug, reduced debug
* Refactor/cleanup
* Fix
* naming
* Final cleanup
* review comment
* Forgot to update this after naming change
* scrubber works, with debug
* cleanup
* Rename scrollbar to scrubber
* rename to
* left over rename and change to previous album bar
* bugfix addassets, comments
* missing destroy(), cleanup
---------
Co-authored-by: Alex <alex.tran1502@gmail.com>
2024-08-21 22:15:21 -04:00
|
|
|
export function navigate(change: ImmichRoute, options?: NavOptions): Promise<void> {
|
|
|
|
|
if (isAssetGridRoute(change)) {
|
|
|
|
|
return navigateAssetGridRoute(change, options);
|
|
|
|
|
} else if (isAssetRoute(change)) {
|
|
|
|
|
return navigateAssetRoute(change, options);
|
2024-04-24 15:24:19 -04:00
|
|
|
}
|
|
|
|
|
// future navigation requests here
|
|
|
|
|
throw `Invalid navigation: ${JSON.stringify(change)}`;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-15 20:20:32 +02:00
|
|
|
export const clearQueryParam = async (queryParam: string, url: URL) => {
|
|
|
|
|
if (url.searchParams.has(queryParam)) {
|
|
|
|
|
url.searchParams.delete(queryParam);
|
2024-04-29 23:38:15 +02:00
|
|
|
await goto(url, { keepFocus: true });
|
2024-04-15 20:20:32 +02:00
|
|
|
}
|
|
|
|
|
};
|