mirror of
https://github.com/immich-app/immich.git
synced 2025-07-09 03:04:16 -04:00
Review comments
This commit is contained in:
parent
47ffe946c4
commit
b038917f7a
@ -19,7 +19,7 @@
|
|||||||
import { thumbhash } from '$lib/actions/thumbhash';
|
import { thumbhash } from '$lib/actions/thumbhash';
|
||||||
import { authManager } from '$lib/managers/auth-manager.svelte';
|
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||||
import { mobileDevice } from '$lib/stores/mobile-device.svelte';
|
import { mobileDevice } from '$lib/stores/mobile-device.svelte';
|
||||||
import { focusNext } from '$lib/utils/focus-util';
|
import { moveFocus } from '$lib/utils/focus-util';
|
||||||
import { currentUrlReplaceAssetId } from '$lib/utils/navigation';
|
import { currentUrlReplaceAssetId } from '$lib/utils/navigation';
|
||||||
import { TUNABLES } from '$lib/utils/tunables';
|
import { TUNABLES } from '$lib/utils/tunables';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
@ -136,17 +136,13 @@
|
|||||||
let startX: number = 0;
|
let startX: number = 0;
|
||||||
let startY: number = 0;
|
let startY: number = 0;
|
||||||
|
|
||||||
// As of iOS17, there is a preference for long press speed, which is not available for mobile web.
|
|
||||||
// The defaults are as follows:
|
|
||||||
// fast: 200ms
|
|
||||||
// default: 500ms
|
|
||||||
// slow: ??ms
|
|
||||||
function longPress(element: HTMLElement, { onLongPress }: { onLongPress: () => void }) {
|
function longPress(element: HTMLElement, { onLongPress }: { onLongPress: () => void }) {
|
||||||
let didPress = false;
|
let didPress = false;
|
||||||
const start = (evt: PointerEvent) => {
|
const start = (evt: PointerEvent) => {
|
||||||
startX = evt.clientX;
|
startX = evt.clientX;
|
||||||
startY = evt.clientY;
|
startY = evt.clientY;
|
||||||
didPress = false;
|
didPress = false;
|
||||||
|
// 350ms for longpress. For reference: iOS uses 500ms for default long press, or 200ms for fast long press.
|
||||||
timer = setTimeout(() => {
|
timer = setTimeout(() => {
|
||||||
onLongPress();
|
onLongPress();
|
||||||
element.addEventListener('contextmenu', preventContextMenu, { once: true });
|
element.addEventListener('contextmenu', preventContextMenu, { once: true });
|
||||||
@ -211,7 +207,7 @@
|
|||||||
onSelect?.(asset);
|
onSelect?.(asset);
|
||||||
}
|
}
|
||||||
if (document.activeElement === element && evt.key === 'Escape') {
|
if (document.activeElement === element && evt.key === 'Escape') {
|
||||||
focusNext((element) => element.dataset.thumbnailFocusContainer === undefined, true);
|
moveFocus((element) => element.dataset.thumbnailFocusContainer === undefined, true);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onclick={handleClick}
|
onclick={handleClick}
|
||||||
@ -243,25 +239,6 @@
|
|||||||
class={['group absolute top-[0px] bottom-[0px]', { 'cursor-not-allowed': disabled, 'cursor-pointer': !disabled }]}
|
class={['group absolute top-[0px] bottom-[0px]', { 'cursor-not-allowed': disabled, 'cursor-pointer': !disabled }]}
|
||||||
style:width="inherit"
|
style:width="inherit"
|
||||||
style:height="inherit"
|
style:height="inherit"
|
||||||
onmouseenter={onMouseEnter}
|
|
||||||
onmouseleave={onMouseLeave}
|
|
||||||
use:longPress={{ onLongPress: () => onSelect?.($state.snapshot(asset)) }}
|
|
||||||
onkeydown={(evt) => {
|
|
||||||
if (evt.key === 'Enter') {
|
|
||||||
callClickHandlers();
|
|
||||||
}
|
|
||||||
if (evt.key === 'x') {
|
|
||||||
onSelect?.(asset);
|
|
||||||
}
|
|
||||||
if (document.activeElement === element && evt.key === 'Escape') {
|
|
||||||
focusNext((element) => element.dataset.thumbnailFocusContainer === undefined, true);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onclick={handleClick}
|
|
||||||
bind:this={element}
|
|
||||||
data-thumbnail-focus-container
|
|
||||||
tabindex={0}
|
|
||||||
role="link"
|
|
||||||
>
|
>
|
||||||
<!-- Select asset button -->
|
<!-- Select asset button -->
|
||||||
{#if !usingMobileDevice && mouseOver && !disableLinkMouseOver}
|
{#if !usingMobileDevice && mouseOver && !disableLinkMouseOver}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { AssetStore } from '$lib/stores/assets-store.svelte';
|
import type { AssetStore } from '$lib/stores/assets-store.svelte';
|
||||||
import { focusNext } from '$lib/utils/focus-util';
|
import { moveFocus } from '$lib/utils/focus-util';
|
||||||
import { InvocationTracker } from '$lib/utils/invocationTracker';
|
import { InvocationTracker } from '$lib/utils/invocationTracker';
|
||||||
import { retry } from '$lib/utils/retry';
|
import { retry } from '$lib/utils/retry';
|
||||||
|
|
||||||
@ -12,9 +12,9 @@ const getFocusedThumb = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const focusNextAsset = () => focusNext((element) => element.dataset.thumbnailFocusContainer !== undefined, true);
|
export const focusNextAsset = () => moveFocus((element) => element.dataset.thumbnailFocusContainer !== undefined, true);
|
||||||
export const focusPreviousAsset = () =>
|
export const focusPreviousAsset = () =>
|
||||||
focusNext((element) => element.dataset.thumbnailFocusContainer !== undefined, false);
|
moveFocus((element) => element.dataset.thumbnailFocusContainer !== undefined, false);
|
||||||
|
|
||||||
export const setFocusToAsset = async (scrollToAsset: (id: string) => Promise<boolean>, asset: { id: string }) => {
|
export const setFocusToAsset = async (scrollToAsset: (id: string) => Promise<boolean>, asset: { id: string }) => {
|
||||||
const scrolled = await scrollToAsset(asset.id);
|
const scrolled = await scrollToAsset(asset.id);
|
||||||
@ -40,25 +40,30 @@ export const setFocusTo = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const invocation = tracker.startInvocation();
|
const invocation = tracker.startInvocation();
|
||||||
|
const id = thumb.dataset.asset;
|
||||||
|
if (!thumb || !id) {
|
||||||
|
invocation.endInvocation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (thumb) {
|
|
||||||
const id = thumb?.dataset.asset;
|
|
||||||
if (id) {
|
|
||||||
const asset =
|
const asset =
|
||||||
direction === 'next' ? await store.getNextAsset({ id }, skip) : await store.getPreviousAsset({ id }, skip);
|
direction === 'next' ? await store.getNextAsset({ id }, skip) : await store.getPreviousAsset({ id }, skip);
|
||||||
invocation.checkStillValid();
|
invocation.checkStillValid();
|
||||||
if (asset) {
|
|
||||||
|
if (!asset) {
|
||||||
|
invocation.endInvocation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const scrolled = await scrollToAsset(asset.id);
|
const scrolled = await scrollToAsset(asset.id);
|
||||||
invocation.checkStillValid();
|
invocation.checkStillValid();
|
||||||
|
|
||||||
if (scrolled) {
|
if (scrolled) {
|
||||||
invocation.checkStillValid();
|
|
||||||
const element = await waitForElement(`[data-thumbnail-focus-container][data-asset="${asset.id}"]`);
|
const element = await waitForElement(`[data-thumbnail-focus-container][data-asset="${asset.id}"]`);
|
||||||
invocation.checkStillValid();
|
invocation.checkStillValid();
|
||||||
element?.focus();
|
element?.focus();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
invocation.endInvocation();
|
invocation.endInvocation();
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (invocation.isInvalidInvocationError(error)) {
|
if (invocation.isInvalidInvocationError(error)) {
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
import { handlePromiseError } from '$lib/utils';
|
import { handlePromiseError } from '$lib/utils';
|
||||||
import { deleteAssets, updateStackedAssetInTimeline, updateUnstackedAssetInTimeline } from '$lib/utils/actions';
|
import { deleteAssets, updateStackedAssetInTimeline, updateUnstackedAssetInTimeline } from '$lib/utils/actions';
|
||||||
import { archiveAssets, cancelMultiselect, selectAllAssets, stackAssets } from '$lib/utils/asset-utils';
|
import { archiveAssets, cancelMultiselect, selectAllAssets, stackAssets } from '$lib/utils/asset-utils';
|
||||||
import { focusNext } from '$lib/utils/focus-util';
|
import { moveFocus } from '$lib/utils/focus-util';
|
||||||
import { navigate } from '$lib/utils/navigation';
|
import { navigate } from '$lib/utils/navigation';
|
||||||
import { type ScrubberListener } from '$lib/utils/timeline-util';
|
import { type ScrubberListener } from '$lib/utils/timeline-util';
|
||||||
import type { AlbumResponseDto, AssetResponseDto, PersonResponseDto } from '@immich/sdk';
|
import type { AlbumResponseDto, AssetResponseDto, PersonResponseDto } from '@immich/sdk';
|
||||||
@ -629,8 +629,8 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const focusNextAsset = () => focusNext((element) => element.dataset.thumbnailFocusContainer !== undefined, true);
|
const focusNextAsset = () => moveFocus((element) => element.dataset.thumbnailFocusContainer !== undefined, true);
|
||||||
const focusPreviousAsset = () => focusNext((element) => element.dataset.thumbnailFocusContainer !== undefined, false);
|
const focusPreviousAsset = () => moveFocus((element) => element.dataset.thumbnailFocusContainer !== undefined, false);
|
||||||
|
|
||||||
let isTrashEnabled = $derived($featureFlags.loaded && $featureFlags.trash);
|
let isTrashEnabled = $derived($featureFlags.loaded && $featureFlags.trash);
|
||||||
let isEmpty = $derived(assetStore.isInitialized && assetStore.buckets.length === 0);
|
let isEmpty = $derived(assetStore.isInitialized && assetStore.buckets.length === 0);
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { type ShortcutOptions, shortcuts } from '$lib/actions/shortcut';
|
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
|
import { shortcuts, type ShortcutOptions } from '$lib/actions/shortcut';
|
||||||
import type { Action } from '$lib/components/asset-viewer/actions/action';
|
import type { Action } from '$lib/components/asset-viewer/actions/action';
|
||||||
import Thumbnail from '$lib/components/assets/thumbnail/thumbnail.svelte';
|
import Thumbnail from '$lib/components/assets/thumbnail/thumbnail.svelte';
|
||||||
import { AppRoute, AssetAction } from '$lib/constants';
|
import { AppRoute, AssetAction } from '$lib/constants';
|
||||||
|
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||||
import type { Viewport } from '$lib/stores/assets-store.svelte';
|
import type { Viewport } from '$lib/stores/assets-store.svelte';
|
||||||
import { showDeleteModal } from '$lib/stores/preferences.store';
|
import { showDeleteModal } from '$lib/stores/preferences.store';
|
||||||
|
import { featureFlags } from '$lib/stores/server-config.store';
|
||||||
|
import { handlePromiseError } from '$lib/utils';
|
||||||
import { deleteAssets } from '$lib/utils/actions';
|
import { deleteAssets } from '$lib/utils/actions';
|
||||||
import { archiveAssets, cancelMultiselect } from '$lib/utils/asset-utils';
|
import { archiveAssets, cancelMultiselect } from '$lib/utils/asset-utils';
|
||||||
import { featureFlags } from '$lib/stores/server-config.store';
|
import { moveFocus } from '$lib/utils/focus-util';
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
|
import { getJustifiedLayoutFromAssets, type CommonJustifiedLayout } from '$lib/utils/layout-utils';
|
||||||
import { navigate } from '$lib/utils/navigation';
|
import { navigate } from '$lib/utils/navigation';
|
||||||
import { type AssetResponseDto } from '@immich/sdk';
|
import { type AssetResponseDto } from '@immich/sdk';
|
||||||
|
import { debounce } from 'lodash-es';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import AssetViewer from '../../asset-viewer/asset-viewer.svelte';
|
import AssetViewer from '../../asset-viewer/asset-viewer.svelte';
|
||||||
import ShowShortcuts from '../show-shortcuts.svelte';
|
|
||||||
import Portal from '../portal/portal.svelte';
|
|
||||||
import { handlePromiseError } from '$lib/utils';
|
|
||||||
import DeleteAssetDialog from '../../photos-page/delete-asset-dialog.svelte';
|
import DeleteAssetDialog from '../../photos-page/delete-asset-dialog.svelte';
|
||||||
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
import Portal from '../portal/portal.svelte';
|
||||||
import { debounce } from 'lodash-es';
|
import ShowShortcuts from '../show-shortcuts.svelte';
|
||||||
import { getJustifiedLayoutFromAssets, type CommonJustifiedLayout } from '$lib/utils/layout-utils';
|
|
||||||
import { focusNext } from '$lib/utils/focus-util';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
assets: AssetResponseDto[];
|
assets: AssetResponseDto[];
|
||||||
@ -260,8 +260,8 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const focusNextAsset = () => focusNext((element) => element.dataset.thumbnailFocusContainer !== undefined, true);
|
const focusNextAsset = () => moveFocus((element) => element.dataset.thumbnailFocusContainer !== undefined, true);
|
||||||
const focusPreviousAsset = () => focusNext((element) => element.dataset.thumbnailFocusContainer !== undefined, false);
|
const focusPreviousAsset = () => moveFocus((element) => element.dataset.thumbnailFocusContainer !== undefined, false);
|
||||||
|
|
||||||
let shortcutList = $derived(
|
let shortcutList = $derived(
|
||||||
(() => {
|
(() => {
|
||||||
|
@ -12,18 +12,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let { initialDate = DateTime.now(), onCancel, onConfirm }: Props = $props();
|
let { initialDate = DateTime.now(), onCancel, onConfirm }: Props = $props();
|
||||||
|
|
||||||
let selectedDate = $state(initialDate.toFormat("yyyy-MM-dd'T'HH:mm"));
|
let selectedDate = $state(initialDate.toFormat("yyyy-MM-dd'T'HH:mm"));
|
||||||
|
|
||||||
|
// when changing the time zone, assume the configured date/time is meant for that time zone (instead of updating it)
|
||||||
|
const date = $derived(DateTime.fromISO(selectedDate));
|
||||||
|
|
||||||
const handleConfirm = () => {
|
const handleConfirm = () => {
|
||||||
const value = date;
|
if (date) {
|
||||||
if (value) {
|
onConfirm(date);
|
||||||
onConfirm(value);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// when changing the time zone, assume the configured date/time is meant for that time zone (instead of updating it)
|
|
||||||
let date = $derived(DateTime.fromISO(selectedDate));
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
|
@ -322,13 +322,7 @@ export class AssetBucket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
containsAssetId(id: string) {
|
containsAssetId(id: string) {
|
||||||
for (const group of this.dateGroups) {
|
return this.assets().some((asset) => asset.id == id);
|
||||||
const index = group.intersetingAssets.findIndex((a) => a.id == id);
|
|
||||||
if (index !== -1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sortDateGroups() {
|
sortDateGroups() {
|
||||||
@ -1333,7 +1327,7 @@ export class AssetStore {
|
|||||||
idable: { id: string },
|
idable: { id: string },
|
||||||
skipTo: 'asset' | 'day' | 'month' | 'year' = 'asset',
|
skipTo: 'asset' | 'day' | 'month' | 'year' = 'asset',
|
||||||
): Promise<AssetResponseDto | undefined> {
|
): Promise<AssetResponseDto | undefined> {
|
||||||
let bucket = this.#findBucketForAsset(idable.id);
|
const bucket = this.#findBucketForAsset(idable.id);
|
||||||
if (!bucket) {
|
if (!bucket) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1343,8 +1337,23 @@ export class AssetStore {
|
|||||||
}
|
}
|
||||||
switch (skipTo) {
|
switch (skipTo) {
|
||||||
case 'day': {
|
case 'day': {
|
||||||
|
return this.#getPreviousDay(asset, bucket);
|
||||||
|
}
|
||||||
|
case 'month': {
|
||||||
|
return this.#getPreviousMonth(asset, bucket);
|
||||||
|
}
|
||||||
|
case 'year': {
|
||||||
|
return this.#getPreviousYear(asset, bucket);
|
||||||
|
}
|
||||||
|
case 'asset': {
|
||||||
|
return this.#getPreviousAsset(asset, bucket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async #getPreviousDay(asset: AssetResponseDto, bucket: AssetBucket) {
|
||||||
let nextDay = DateTime.fromISO(asset.localDateTime).toUTC().get('day') + 1;
|
let nextDay = DateTime.fromISO(asset.localDateTime).toUTC().get('day') + 1;
|
||||||
const bIdx = this.buckets.indexOf(bucket);
|
const bucketIndex = this.buckets.indexOf(bucket);
|
||||||
|
|
||||||
let nextDaygroup;
|
let nextDaygroup;
|
||||||
while (nextDay <= 31) {
|
while (nextDay <= 31) {
|
||||||
@ -1355,9 +1364,9 @@ export class AssetStore {
|
|||||||
nextDay++;
|
nextDay++;
|
||||||
}
|
}
|
||||||
if (nextDaygroup === undefined) {
|
if (nextDaygroup === undefined) {
|
||||||
let bucketIndex = bIdx - 1;
|
let previousBucketIndex = bucketIndex - 1;
|
||||||
while (bucketIndex >= 0) {
|
while (previousBucketIndex >= 0) {
|
||||||
bucket = this.buckets[bucketIndex];
|
bucket = this.buckets[previousBucketIndex];
|
||||||
if (!bucket) {
|
if (!bucket) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1366,23 +1375,24 @@ export class AssetStore {
|
|||||||
if (previous) {
|
if (previous) {
|
||||||
return previous;
|
return previous;
|
||||||
}
|
}
|
||||||
bucketIndex--;
|
previousBucketIndex--;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nextDaygroup.intersetingAssets.at(0)?.asset;
|
return nextDaygroup.intersetingAssets.at(0)?.asset;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
case 'month': {
|
|
||||||
const bIdx = this.buckets.indexOf(bucket);
|
async #getPreviousMonth(asset: AssetResponseDto, bucket: AssetBucket) {
|
||||||
const otherBucket = this.buckets[bIdx - 1];
|
const bucketIndex = this.buckets.indexOf(bucket);
|
||||||
if (otherBucket) {
|
const previousBucket = this.buckets[bucketIndex - 1];
|
||||||
await this.loadBucket(otherBucket.bucketDate, { cancelable: false });
|
if (previousBucket) {
|
||||||
return otherBucket.dateGroups[0]?.intersetingAssets[0]?.asset;
|
await this.loadBucket(previousBucket.bucketDate, { cancelable: false });
|
||||||
|
return previousBucket.dateGroups[0]?.intersetingAssets[0]?.asset;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 'year': {
|
|
||||||
|
async #getPreviousYear(asset: AssetResponseDto, bucket: AssetBucket) {
|
||||||
const nextYear = DateTime.fromISO(asset.localDateTime).toUTC().get('year') + 1;
|
const nextYear = DateTime.fromISO(asset.localDateTime).toUTC().get('year') + 1;
|
||||||
const bIdx = this.buckets.indexOf(bucket);
|
const bIdx = this.buckets.indexOf(bucket);
|
||||||
|
|
||||||
@ -1396,8 +1406,8 @@ export class AssetStore {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
async #getPreviousAsset(asset: AssetResponseDto, bucket: AssetBucket) {
|
||||||
// Find which date group contains this asset
|
// Find which date group contains this asset
|
||||||
for (let groupIndex = 0; groupIndex < bucket.dateGroups.length; groupIndex++) {
|
for (let groupIndex = 0; groupIndex < bucket.dateGroups.length; groupIndex++) {
|
||||||
const group = bucket.dateGroups[groupIndex];
|
const group = bucket.dateGroups[groupIndex];
|
||||||
@ -1462,7 +1472,7 @@ export class AssetStore {
|
|||||||
idable: { id: string },
|
idable: { id: string },
|
||||||
skipTo: 'asset' | 'day' | 'month' | 'year' = 'asset',
|
skipTo: 'asset' | 'day' | 'month' | 'year' = 'asset',
|
||||||
): Promise<AssetResponseDto | undefined> {
|
): Promise<AssetResponseDto | undefined> {
|
||||||
let bucket = this.#findBucketForAsset(idable.id);
|
const bucket = this.#findBucketForAsset(idable.id);
|
||||||
if (!bucket) {
|
if (!bucket) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1473,8 +1483,23 @@ export class AssetStore {
|
|||||||
|
|
||||||
switch (skipTo) {
|
switch (skipTo) {
|
||||||
case 'day': {
|
case 'day': {
|
||||||
|
return this.#getNextDay(asset, bucket);
|
||||||
|
}
|
||||||
|
case 'month': {
|
||||||
|
return this.#getNextMonth(asset, bucket);
|
||||||
|
}
|
||||||
|
case 'year': {
|
||||||
|
return this.#getNextYear(asset, bucket);
|
||||||
|
}
|
||||||
|
case 'asset': {
|
||||||
|
return this.#getNextAsset(asset, bucket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async #getNextDay(asset: AssetResponseDto, bucket: AssetBucket) {
|
||||||
let prevDay = DateTime.fromISO(asset.localDateTime).toUTC().get('day') - 1;
|
let prevDay = DateTime.fromISO(asset.localDateTime).toUTC().get('day') - 1;
|
||||||
const bIdx = this.buckets.indexOf(bucket);
|
const bucketIndex = this.buckets.indexOf(bucket);
|
||||||
|
|
||||||
let prevDayGroup;
|
let prevDayGroup;
|
||||||
while (prevDay >= 0) {
|
while (prevDay >= 0) {
|
||||||
@ -1485,46 +1510,46 @@ export class AssetStore {
|
|||||||
prevDay--;
|
prevDay--;
|
||||||
}
|
}
|
||||||
if (prevDayGroup === undefined) {
|
if (prevDayGroup === undefined) {
|
||||||
let bucketIndex = bIdx + 1;
|
let nextBucketIndex = bucketIndex + 1;
|
||||||
while (bucketIndex < this.buckets.length) {
|
while (nextBucketIndex < this.buckets.length) {
|
||||||
const otherBucket = this.buckets[bucketIndex];
|
const otherBucket = this.buckets[nextBucketIndex];
|
||||||
await this.loadBucket(otherBucket.bucketDate, { cancelable: false });
|
await this.loadBucket(otherBucket.bucketDate, { cancelable: false });
|
||||||
const next = otherBucket.dateGroups[0]?.intersetingAssets[0]?.asset;
|
const next = otherBucket.dateGroups[0]?.intersetingAssets[0]?.asset;
|
||||||
if (next) {
|
if (next) {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
bucketIndex++;
|
nextBucketIndex++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return prevDayGroup.intersetingAssets.at(0)?.asset;
|
return prevDayGroup.intersetingAssets.at(0)?.asset;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
async #getNextMonth(asset: AssetResponseDto, bucket: AssetBucket) {
|
||||||
}
|
const bucketIndex = this.buckets.indexOf(bucket);
|
||||||
case 'month': {
|
const nextMonthBucketIndex = this.buckets[bucketIndex + 1];
|
||||||
const bIdx = this.buckets.indexOf(bucket);
|
if (nextMonthBucketIndex) {
|
||||||
const otherBucket = this.buckets[bIdx + 1];
|
await this.loadBucket(nextMonthBucketIndex.bucketDate, { cancelable: false });
|
||||||
if (otherBucket) {
|
return nextMonthBucketIndex.dateGroups[0]?.intersetingAssets[0]?.asset;
|
||||||
await this.loadBucket(otherBucket.bucketDate, { cancelable: false });
|
|
||||||
return otherBucket.dateGroups[0]?.intersetingAssets[0]?.asset;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 'year': {
|
|
||||||
|
async #getNextYear(asset: AssetResponseDto, bucket: AssetBucket) {
|
||||||
const prevYear = DateTime.fromISO(asset.localDateTime).toUTC().get('year') - 1;
|
const prevYear = DateTime.fromISO(asset.localDateTime).toUTC().get('year') - 1;
|
||||||
const bIdx = this.buckets.indexOf(bucket);
|
const bucketIndex = this.buckets.indexOf(bucket);
|
||||||
for (let idx = bIdx; idx < this.buckets.length - 1; idx++) {
|
for (let idx = bucketIndex; idx < this.buckets.length - 1; idx++) {
|
||||||
const otherBucket = this.buckets[idx];
|
const otherBucket = this.buckets[idx];
|
||||||
const otherBucketYear = DateTime.fromISO(otherBucket.bucketDate).toUTC().get('year');
|
const otherBucketYear = DateTime.fromISO(otherBucket.bucketDate).toUTC().get('year');
|
||||||
if (otherBucketYear <= prevYear) {
|
if (otherBucketYear <= prevYear) {
|
||||||
await this.loadBucket(otherBucket.bucketDate, { cancelable: false });
|
await this.loadBucket(otherBucket.bucketDate, { cancelable: false });
|
||||||
const a = otherBucket.dateGroups[0]?.intersetingAssets[0]?.asset;
|
return otherBucket.dateGroups[0]?.intersetingAssets[0]?.asset;
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
async #getNextAsset(asset: AssetResponseDto, bucket: AssetBucket) {
|
||||||
// Find which date group contains this asset
|
// Find which date group contains this asset
|
||||||
for (let groupIndex = 0; groupIndex < bucket.dateGroups.length; groupIndex++) {
|
for (let groupIndex = 0; groupIndex < bucket.dateGroups.length; groupIndex++) {
|
||||||
const group = bucket.dateGroups[groupIndex];
|
const group = bucket.dateGroups[groupIndex];
|
||||||
|
@ -12,7 +12,7 @@ export const setDefaultTabbleOptions = (options: TabbableOpts) => {
|
|||||||
export const getTabbable = (container: Element, includeContainer: boolean = false) =>
|
export const getTabbable = (container: Element, includeContainer: boolean = false) =>
|
||||||
tabbable(container, { ...defaultOpts, includeContainer });
|
tabbable(container, { ...defaultOpts, includeContainer });
|
||||||
|
|
||||||
export const focusNext = (selector: (element: HTMLElement | SVGElement) => boolean, forwardDirection: boolean) => {
|
export const moveFocus = (selector: (element: HTMLElement | SVGElement) => boolean, forwardDirection: boolean) => {
|
||||||
const focusElements = focusable(document.body, { includeContainer: true });
|
const focusElements = focusable(document.body, { includeContainer: true });
|
||||||
const current = document.activeElement as HTMLElement;
|
const current = document.activeElement as HTMLElement;
|
||||||
const index = focusElements.indexOf(current);
|
const index = focusElements.indexOf(current);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export const retry = <R, A = unknown>(
|
export const retry = <R, A>(
|
||||||
fn: (arg: A) => R,
|
fn: (arg: A) => R,
|
||||||
interval: number = 10,
|
interval: number = 10,
|
||||||
timeout: number = 1000,
|
timeout: number = 1000,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user