mirror of
https://github.com/immich-app/immich.git
synced 2025-05-24 01:12:58 -04:00
fix: hard link navigation (#18489)
This commit is contained in:
parent
2fa7a40996
commit
4878c500a5
@ -124,26 +124,38 @@
|
|||||||
scrollTo(0);
|
scrollTo(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const scrollToAsset = async (assetId: string) => {
|
||||||
|
try {
|
||||||
|
const bucket = await assetStore.findBucketForAsset(assetId);
|
||||||
|
if (bucket) {
|
||||||
|
const height = bucket.findAssetAbsolutePosition(assetId);
|
||||||
|
if (height) {
|
||||||
|
scrollTo(height);
|
||||||
|
assetStore.updateIntersections();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore errors - asset may not be in the store
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
const completeNav = async () => {
|
const completeNav = async () => {
|
||||||
const scrollTarget = $gridScrollTarget?.at;
|
const scrollTarget = $gridScrollTarget?.at;
|
||||||
|
let scrolled = false;
|
||||||
if (scrollTarget) {
|
if (scrollTarget) {
|
||||||
try {
|
scrolled = await scrollToAsset(scrollTarget);
|
||||||
const bucket = await assetStore.findBucketForAsset(scrollTarget);
|
}
|
||||||
if (bucket) {
|
|
||||||
const height = bucket.findAssetAbsolutePosition(scrollTarget);
|
if (!scrolled) {
|
||||||
if (height) {
|
// if the asset is not found, scroll to the top
|
||||||
scrollTo(height);
|
scrollToTop();
|
||||||
assetStore.updateIntersections();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// ignore errors - asset may not be in the store
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
scrollToTop();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeNavigate(() => (assetStore.suspendTransitions = true));
|
beforeNavigate(() => (assetStore.suspendTransitions = true));
|
||||||
|
|
||||||
afterNavigate((nav) => {
|
afterNavigate((nav) => {
|
||||||
const { complete } = nav;
|
const { complete } = nav;
|
||||||
complete.then(completeNav, completeNav);
|
complete.then(completeNav, completeNav);
|
||||||
|
@ -217,8 +217,8 @@ export class AssetDateGroup {
|
|||||||
return { moveAssets, processedIds, unprocessedIds, changedGeometry };
|
return { moveAssets, processedIds, unprocessedIds, changedGeometry };
|
||||||
}
|
}
|
||||||
|
|
||||||
layout(options: CommonLayoutOptions) {
|
layout(options: CommonLayoutOptions, noDefer: boolean) {
|
||||||
if (!this.bucket.intersecting) {
|
if (!noDefer && !this.bucket.intersecting) {
|
||||||
this.deferredLayout = true;
|
this.deferredLayout = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -602,6 +602,8 @@ export class AssetBucket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
findAssetAbsolutePosition(assetId: string) {
|
findAssetAbsolutePosition(assetId: string) {
|
||||||
|
this.store.clearDeferredLayout(this);
|
||||||
|
|
||||||
for (const group of this.dateGroups) {
|
for (const group of this.dateGroups) {
|
||||||
const intersectingAsset = group.intersetingAssets.find((asset) => asset.id === assetId);
|
const intersectingAsset = group.intersetingAssets.find((asset) => asset.id === assetId);
|
||||||
if (intersectingAsset) {
|
if (intersectingAsset) {
|
||||||
@ -658,6 +660,12 @@ type AssetStoreLayoutOptions = {
|
|||||||
headerHeight?: number;
|
headerHeight?: number;
|
||||||
gap?: number;
|
gap?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface UpdateGeometryOptions {
|
||||||
|
invalidateHeight: boolean;
|
||||||
|
noDefer?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export class AssetStore {
|
export class AssetStore {
|
||||||
// --- public ----
|
// --- public ----
|
||||||
isInitialized = $state(false);
|
isInitialized = $state(false);
|
||||||
@ -932,6 +940,16 @@ export class AssetStore {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearDeferredLayout(bucket: AssetBucket) {
|
||||||
|
const hasDeferred = bucket.dateGroups.some((group) => group.deferredLayout);
|
||||||
|
if (hasDeferred) {
|
||||||
|
this.#updateGeometry(bucket, { invalidateHeight: true, noDefer: true });
|
||||||
|
for (const group of bucket.dateGroups) {
|
||||||
|
group.deferredLayout = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#updateIntersection(bucket: AssetBucket) {
|
#updateIntersection(bucket: AssetBucket) {
|
||||||
const actuallyIntersecting = this.#calculateIntersecting(bucket, 0, 0);
|
const actuallyIntersecting = this.#calculateIntersecting(bucket, 0, 0);
|
||||||
let preIntersecting = false;
|
let preIntersecting = false;
|
||||||
@ -941,13 +959,7 @@ export class AssetStore {
|
|||||||
bucket.intersecting = actuallyIntersecting || preIntersecting;
|
bucket.intersecting = actuallyIntersecting || preIntersecting;
|
||||||
bucket.actuallyIntersecting = actuallyIntersecting;
|
bucket.actuallyIntersecting = actuallyIntersecting;
|
||||||
if (preIntersecting || actuallyIntersecting) {
|
if (preIntersecting || actuallyIntersecting) {
|
||||||
const hasDeferred = bucket.dateGroups.some((group) => group.deferredLayout);
|
this.clearDeferredLayout(bucket);
|
||||||
if (hasDeferred) {
|
|
||||||
this.#updateGeometry(bucket, true);
|
|
||||||
for (const group of bucket.dateGroups) {
|
|
||||||
group.deferredLayout = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1052,7 +1064,7 @@ export class AssetStore {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const bucket of this.buckets) {
|
for (const bucket of this.buckets) {
|
||||||
this.#updateGeometry(bucket, changedWidth);
|
this.#updateGeometry(bucket, { invalidateHeight: changedWidth });
|
||||||
}
|
}
|
||||||
this.updateIntersections();
|
this.updateIntersections();
|
||||||
this.#createScrubBuckets();
|
this.#createScrubBuckets();
|
||||||
@ -1079,7 +1091,8 @@ export class AssetStore {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#updateGeometry(bucket: AssetBucket, invalidateHeight: boolean) {
|
#updateGeometry(bucket: AssetBucket, options: UpdateGeometryOptions) {
|
||||||
|
const { invalidateHeight, noDefer = false } = options;
|
||||||
if (invalidateHeight) {
|
if (invalidateHeight) {
|
||||||
bucket.isBucketHeightActual = false;
|
bucket.isBucketHeightActual = false;
|
||||||
}
|
}
|
||||||
@ -1094,10 +1107,10 @@ export class AssetStore {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.#layoutBucket(bucket);
|
this.#layoutBucket(bucket, noDefer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#layoutBucket(bucket: AssetBucket) {
|
#layoutBucket(bucket: AssetBucket, noDefer: boolean = false) {
|
||||||
// these are top offsets, for each row
|
// these are top offsets, for each row
|
||||||
let cummulativeHeight = 0;
|
let cummulativeHeight = 0;
|
||||||
// these are left offsets of each group, for each row
|
// these are left offsets of each group, for each row
|
||||||
@ -1112,7 +1125,7 @@ export class AssetStore {
|
|||||||
rowSpaceRemaining.fill(this.viewportWidth, 0, bucket.dateGroups.length);
|
rowSpaceRemaining.fill(this.viewportWidth, 0, bucket.dateGroups.length);
|
||||||
const options = this.createLayoutOptions();
|
const options = this.createLayoutOptions();
|
||||||
for (const assetGroup of bucket.dateGroups) {
|
for (const assetGroup of bucket.dateGroups) {
|
||||||
assetGroup.layout(options);
|
assetGroup.layout(options, noDefer);
|
||||||
rowSpaceRemaining[dateGroupRow] -= assetGroup.width - 1;
|
rowSpaceRemaining[dateGroupRow] -= assetGroup.width - 1;
|
||||||
if (dateGroupCol > 0) {
|
if (dateGroupCol > 0) {
|
||||||
rowSpaceRemaining[dateGroupRow] -= this.gap;
|
rowSpaceRemaining[dateGroupRow] -= this.gap;
|
||||||
@ -1266,7 +1279,7 @@ export class AssetStore {
|
|||||||
|
|
||||||
for (const bucket of addContext.updatedBuckets) {
|
for (const bucket of addContext.updatedBuckets) {
|
||||||
bucket.sortDateGroups();
|
bucket.sortDateGroups();
|
||||||
this.#updateGeometry(bucket, true);
|
this.#updateGeometry(bucket, { invalidateHeight: true });
|
||||||
}
|
}
|
||||||
this.updateIntersections();
|
this.updateIntersections();
|
||||||
}
|
}
|
||||||
@ -1357,7 +1370,7 @@ export class AssetStore {
|
|||||||
}
|
}
|
||||||
const changedGeometry = changedBuckets.size > 0;
|
const changedGeometry = changedBuckets.size > 0;
|
||||||
for (const bucket of changedBuckets) {
|
for (const bucket of changedBuckets) {
|
||||||
this.#updateGeometry(bucket, true);
|
this.#updateGeometry(bucket, { invalidateHeight: true });
|
||||||
}
|
}
|
||||||
if (changedGeometry) {
|
if (changedGeometry) {
|
||||||
this.updateIntersections();
|
this.updateIntersections();
|
||||||
@ -1397,7 +1410,7 @@ export class AssetStore {
|
|||||||
|
|
||||||
refreshLayout() {
|
refreshLayout() {
|
||||||
for (const bucket of this.buckets) {
|
for (const bucket of this.buckets) {
|
||||||
this.#updateGeometry(bucket, true);
|
this.#updateGeometry(bucket, { invalidateHeight: true });
|
||||||
}
|
}
|
||||||
this.updateIntersections();
|
this.updateIntersections();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user