1
0
mirror of https://github.com/immich-app/immich.git synced 2025-07-06 06:07:29 +02:00

feat(web): assets now have a permanent URL (#8532)

* Remove asest redirect pages

* Rename route paths to handle optional assetId

* Update old references to new routes

* Load and display asset from all routes that can show assetId

* Add <main> in base layout, update portals to target it

* Wire up updating navigation in response to open/close/prev/next

* Replace events with navigation functions

* Add types to param matcher

* misc cleanup

* Fix reload on /search pages

* Avoid loading bar between photos nav. Delay loading bar by 200ms for all navigations

* Update url for maps routes. Note: on page reload, next/prev is not available

* Dynamically load asset-viewer on map page

* When reloading a url with assetUrl, hide background page to prevent flash during load

* Mostly style, review comments

* Load buckets for assets on demand

* Forgot this update call

* typo

* fix test

* Fix carelessness

* Review comment

* merge main

* remove assets

* fix submodule

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
This commit is contained in:
Min Idzelis
2024-04-24 15:24:19 -04:00
committed by GitHub
parent 1e004611e4
commit a78260296c
48 changed files with 289 additions and 190 deletions

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { page } from '$app/stores';
import Portal from '../portal/portal.svelte';
import Thumbnail from '$lib/components/assets/thumbnail/thumbnail.svelte';
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import type { BucketPosition, Viewport } from '$lib/stores/assets.store';
@ -10,7 +10,7 @@
import justifiedLayout from 'justified-layout';
import { getAssetRatio } from '$lib/utils/asset-utils';
import { calculateWidth } from '$lib/utils/timeline-util';
import { pushState, replaceState } from '$app/navigation';
import { navigate } from '$lib/utils/navigation';
const dispatch = createEventDispatcher<{ intersected: { container: HTMLDivElement; position: BucketPosition } }>();
@ -20,17 +20,15 @@
export let showArchiveIcon = false;
export let viewport: Viewport;
let { isViewing: showAssetViewer } = assetViewingStore;
let { isViewing: showAssetViewer, asset: viewingAsset, setAsset } = assetViewingStore;
let selectedAsset: AssetResponseDto;
let currentViewAssetIndex = 0;
$: isMultiSelectionMode = selectedAssets.size > 0;
const viewAssetHandler = (asset: AssetResponseDto) => {
const viewAssetHandler = async (asset: AssetResponseDto) => {
currentViewAssetIndex = assets.findIndex((a) => a.id == asset.id);
selectedAsset = assets[currentViewAssetIndex];
$showAssetViewer = true;
updateAssetState(selectedAsset.id, false);
setAsset(assets[currentViewAssetIndex]);
await navigate({ targetRoute: 'current', assetId: $viewingAsset.id });
};
const selectAssetHandler = (asset: AssetResponseDto) => {
@ -45,45 +43,28 @@
selectedAssets = temporary;
};
const navigateAssetForward = () => {
const navigateAssetForward = async () => {
try {
if (currentViewAssetIndex < assets.length - 1) {
currentViewAssetIndex++;
selectedAsset = assets[currentViewAssetIndex];
updateAssetState(selectedAsset.id);
setAsset(assets[++currentViewAssetIndex]);
await navigate({ targetRoute: 'current', assetId: $viewingAsset.id });
}
} catch (error) {
handleError(error, 'Cannot navigate to the next asset');
}
};
const navigateAssetBackward = () => {
const navigateAssetBackward = async () => {
try {
if (currentViewAssetIndex > 0) {
currentViewAssetIndex--;
selectedAsset = assets[currentViewAssetIndex];
updateAssetState(selectedAsset.id);
setAsset(assets[--currentViewAssetIndex]);
await navigate({ targetRoute: 'current', assetId: $viewingAsset.id });
}
} catch (error) {
handleError(error, 'Cannot navigate to previous asset');
}
};
const updateAssetState = (assetId: string, replace = true) => {
const route = `${$page.url.pathname}/photos/${assetId}`;
if (replace) {
replaceState(route, {});
} else {
pushState(route, {});
}
};
const closeViewer = () => {
$showAssetViewer = false;
pushState(`${$page.url.pathname}${$page.url.search}`, {});
};
onDestroy(() => {
$showAssetViewer = false;
});
@ -107,8 +88,6 @@
})();
</script>
<svelte:window on:popstate|preventDefault={closeViewer} />
{#if assets.length > 0}
<div class="relative" style="height: {geometry.containerHeight}px;width: {geometry.containerWidth}px ">
{#each assets as asset, i (i)}
@ -136,10 +115,7 @@
<!-- Overlay Asset Viewer -->
{#if $showAssetViewer}
<AssetViewer
asset={selectedAsset}
on:previous={navigateAssetBackward}
on:next={navigateAssetForward}
on:close={closeViewer}
/>
<Portal target="body">
<AssetViewer asset={$viewingAsset} on:previous={navigateAssetBackward} on:next={navigateAssetForward} />
</Portal>
{/if}