feat: keyboard navigation to timeline (#17798)

* feat: improve focus

* feat: keyboard nav

* feat: improve focus

* typo

* test

* fix test

* lint

* bad merge

* lint

* inadvertent

* lint

* fix: flappy e2e test

* bad merge and fix tests

* use modulus in loop

* tests

* react to modal dialog refactor

* regression due to deferLayout

* Review comments

* Re-use change-date instead of new component

* bad merge

* Review comments

* rework moveFocus

* lint

* Fix outline

* use Date

* Finish up removing/reducing date parsing

* lint

* title

* strings

* Rework dates, rework earlier/later algorithm

* bad merge

* fix tests

* Fix race in scroll comp

* consolidate scroll methods

* Review comments

* console.log

* Edge cases in scroll compensation

* edge case, optimizations

* review comments

* lint

* lint

* More edge cases

* lint

---------

Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
Min Idzelis
2025-05-28 09:55:14 -04:00
committed by GitHub
parent b5593823a2
commit f029910dc7
21 changed files with 1077 additions and 598 deletions

View File

@@ -1,4 +1,5 @@
import type { TimelineAsset } from '$lib/stores/assets-store.svelte';
import { fromLocalDateTimeToObject, fromTimelinePlainDateTime } from '$lib/utils/timeline-util';
import { faker } from '@faker-js/faker';
import { AssetTypeEnum, AssetVisibility, type AssetResponseDto, type TimeBucketAssetResponseDto } from '@immich/sdk';
import { Sync } from 'factory.ts';
@@ -33,7 +34,7 @@ export const timelineAssetFactory = Sync.makeFactory<TimelineAsset>({
ratio: Sync.each(() => faker.number.int()),
ownerId: Sync.each(() => faker.string.uuid()),
thumbhash: Sync.each(() => faker.string.alphanumeric(28)),
localDateTime: Sync.each(() => faker.date.past().toISOString()),
localDateTime: Sync.each(() => fromLocalDateTimeToObject(faker.date.past().toISOString())),
isFavorite: Sync.each(() => faker.datatype.boolean()),
visibility: AssetVisibility.Timeline,
isTrashed: false,
@@ -76,7 +77,7 @@ export const toResponseDto = (...timelineAsset: TimelineAsset[]) => {
bucketAssets.isImage.push(asset.isImage);
bucketAssets.isTrashed.push(asset.isTrashed);
bucketAssets.livePhotoVideoId.push(asset.livePhotoVideoId!);
bucketAssets.localDateTime.push(asset.localDateTime);
bucketAssets.localDateTime.push(fromTimelinePlainDateTime(asset.localDateTime).toISO());
bucketAssets.ownerId.push(asset.ownerId);
bucketAssets.projectionType.push(asset.projectionType!);
bucketAssets.ratio.push(asset.ratio);