mirror of
https://github.com/immich-app/immich.git
synced 2025-05-24 01:12:58 -04:00
use Date
This commit is contained in:
parent
c9728a107e
commit
12381f6b3c
@ -7,7 +7,7 @@ import {
|
|||||||
type CommonLayoutOptions,
|
type CommonLayoutOptions,
|
||||||
type CommonPosition,
|
type CommonPosition,
|
||||||
} from '$lib/utils/layout-utils';
|
} from '$lib/utils/layout-utils';
|
||||||
import { formatDateGroupTitle, toTimelineAsset } from '$lib/utils/timeline-util';
|
import { toTimelineAsset } from '$lib/utils/timeline-util';
|
||||||
import { TUNABLES } from '$lib/utils/tunables';
|
import { TUNABLES } from '$lib/utils/tunables';
|
||||||
import {
|
import {
|
||||||
AssetOrder,
|
AssetOrder,
|
||||||
@ -18,7 +18,6 @@ import {
|
|||||||
type TimeBucketAssetResponseDto,
|
type TimeBucketAssetResponseDto,
|
||||||
} from '@immich/sdk';
|
} from '@immich/sdk';
|
||||||
import { clamp, debounce, isEqual, throttle } from 'lodash-es';
|
import { clamp, debounce, isEqual, throttle } from 'lodash-es';
|
||||||
import { DateTime } from 'luxon';
|
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import { SvelteSet } from 'svelte/reactivity';
|
import { SvelteSet } from 'svelte/reactivity';
|
||||||
import { get, writable, type Unsubscriber } from 'svelte/store';
|
import { get, writable, type Unsubscriber } from 'svelte/store';
|
||||||
@ -71,7 +70,7 @@ export type TimelineAsset = {
|
|||||||
ownerId: string;
|
ownerId: string;
|
||||||
ratio: number;
|
ratio: number;
|
||||||
thumbhash: string | null;
|
thumbhash: string | null;
|
||||||
localDateTime: string;
|
localDateTime: Date;
|
||||||
isArchived: boolean;
|
isArchived: boolean;
|
||||||
isFavorite: boolean;
|
isFavorite: boolean;
|
||||||
isTrashed: boolean;
|
isTrashed: boolean;
|
||||||
@ -123,7 +122,8 @@ export class AssetDateGroup {
|
|||||||
// --- public
|
// --- public
|
||||||
readonly bucket: AssetBucket;
|
readonly bucket: AssetBucket;
|
||||||
readonly index: number;
|
readonly index: number;
|
||||||
readonly date: DateTime;
|
readonly date: Date;
|
||||||
|
readonly groupTitle: string;
|
||||||
readonly dayOfMonth: number;
|
readonly dayOfMonth: number;
|
||||||
intersetingAssets: IntersectingAsset[] = $state([]);
|
intersetingAssets: IntersectingAsset[] = $state([]);
|
||||||
|
|
||||||
@ -138,24 +138,23 @@ export class AssetDateGroup {
|
|||||||
col = $state(0);
|
col = $state(0);
|
||||||
deferredLayout = false;
|
deferredLayout = false;
|
||||||
|
|
||||||
constructor(bucket: AssetBucket, index: number, date: DateTime, dayOfMonth: number) {
|
constructor(bucket: AssetBucket, index: number, date: Date, dayOfMonth: number) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.bucket = bucket;
|
this.bucket = bucket;
|
||||||
this.date = date;
|
this.date = date;
|
||||||
this.dayOfMonth = dayOfMonth;
|
this.dayOfMonth = dayOfMonth;
|
||||||
|
this.groupTitle = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()).toLocaleString(
|
||||||
|
get(locale),
|
||||||
|
{ timeZone: 'UTC', weekday: 'short', year: 'numeric', month: 'long', day: 'numeric' },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
sortAssets(sortOrder: AssetOrder = AssetOrder.Desc) {
|
sortAssets(sortOrder: AssetOrder = AssetOrder.Desc) {
|
||||||
this.intersetingAssets.sort((a, b) => {
|
if (sortOrder === AssetOrder.Asc) {
|
||||||
const aDate = DateTime.fromISO(a.asset!.localDateTime).toUTC();
|
this.intersetingAssets.sort((a, b) => a.asset!.localDateTime.valueOf() - b.asset!.localDateTime.valueOf());
|
||||||
const bDate = DateTime.fromISO(b.asset!.localDateTime).toUTC();
|
} else {
|
||||||
|
this.intersetingAssets.sort((a, b) => b.asset!.localDateTime.valueOf() - a.asset!.localDateTime.valueOf());
|
||||||
if (sortOrder === AssetOrder.Asc) {
|
}
|
||||||
return aDate.diff(bDate).milliseconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bDate.diff(aDate).milliseconds;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getFirstAsset() {
|
getFirstAsset() {
|
||||||
@ -185,27 +184,28 @@ export class AssetDateGroup {
|
|||||||
let changedGeometry = false;
|
let changedGeometry = false;
|
||||||
for (const assetId of unprocessedIds) {
|
for (const assetId of unprocessedIds) {
|
||||||
const index = this.intersetingAssets.findIndex((ia) => ia.id == assetId);
|
const index = this.intersetingAssets.findIndex((ia) => ia.id == assetId);
|
||||||
if (index !== -1) {
|
if (index === -1) {
|
||||||
const asset = this.intersetingAssets[index].asset!;
|
continue;
|
||||||
const oldTime = asset.localDateTime;
|
}
|
||||||
let { remove } = operation(asset);
|
|
||||||
const newTime = asset.localDateTime;
|
const asset = this.intersetingAssets[index].asset!;
|
||||||
if (oldTime !== newTime) {
|
const oldTime = asset.localDateTime;
|
||||||
const utc = DateTime.fromISO(asset.localDateTime).toUTC().startOf('month');
|
let { remove } = operation(asset);
|
||||||
const year = utc.get('year');
|
const newTime = asset.localDateTime;
|
||||||
const month = utc.get('month');
|
if (oldTime.valueOf() !== newTime.valueOf()) {
|
||||||
if (this.bucket.year !== year || this.bucket.month !== month) {
|
const year = newTime.getUTCFullYear();
|
||||||
remove = true;
|
const month = newTime.getUTCMonth();
|
||||||
moveAssets.push({ asset, year, month });
|
if (this.bucket.year !== year || this.bucket.month !== month) {
|
||||||
}
|
remove = true;
|
||||||
}
|
moveAssets.push({ asset, year, month });
|
||||||
unprocessedIds.delete(assetId);
|
|
||||||
processedIds.add(assetId);
|
|
||||||
if (remove || this.bucket.store.isExcluded(asset)) {
|
|
||||||
this.intersetingAssets.splice(index, 1);
|
|
||||||
changedGeometry = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unprocessedIds.delete(assetId);
|
||||||
|
processedIds.add(assetId);
|
||||||
|
if (remove || this.bucket.store.isExcluded(asset)) {
|
||||||
|
this.intersetingAssets.splice(index, 1);
|
||||||
|
changedGeometry = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return { moveAssets, processedIds, unprocessedIds, changedGeometry };
|
return { moveAssets, processedIds, unprocessedIds, changedGeometry };
|
||||||
}
|
}
|
||||||
@ -228,10 +228,6 @@ export class AssetDateGroup {
|
|||||||
get absoluteDateGroupTop() {
|
get absoluteDateGroupTop() {
|
||||||
return this.bucket.top + this.top;
|
return this.bucket.top + this.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
get groupTitle() {
|
|
||||||
return formatDateGroupTitle(this.date);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Viewport {
|
export interface Viewport {
|
||||||
@ -262,6 +258,7 @@ class AddContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AssetBucket {
|
export class AssetBucket {
|
||||||
// --- public ---
|
// --- public ---
|
||||||
#intersecting: boolean = $state(false);
|
#intersecting: boolean = $state(false);
|
||||||
@ -298,22 +295,20 @@ export class AssetBucket {
|
|||||||
readonly month: number;
|
readonly month: number;
|
||||||
readonly year: number;
|
readonly year: number;
|
||||||
|
|
||||||
constructor(store: AssetStore, utcDate: DateTime, initialCount: number, order: AssetOrder = AssetOrder.Desc) {
|
constructor(store: AssetStore, date: Date, initialCount: number, order: AssetOrder = AssetOrder.Desc) {
|
||||||
this.store = store;
|
this.store = store;
|
||||||
this.#initialCount = initialCount;
|
this.#initialCount = initialCount;
|
||||||
this.#sortOrder = order;
|
this.#sortOrder = order;
|
||||||
|
|
||||||
const year = utcDate.get('year');
|
const bucketDateFormatted = date.toLocaleString(get(locale), {
|
||||||
const month = utcDate.get('month');
|
|
||||||
const bucketDateFormatted = utcDate.toJSDate().toLocaleString(get(locale), {
|
|
||||||
month: 'short',
|
month: 'short',
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
timeZone: 'UTC',
|
timeZone: 'UTC',
|
||||||
});
|
});
|
||||||
this.bucketDate = utcDate.toISO()!.toString();
|
this.bucketDate = date.toISOString();
|
||||||
this.bucketDateFormatted = bucketDateFormatted;
|
this.bucketDateFormatted = bucketDateFormatted;
|
||||||
this.month = month;
|
this.month = date.getUTCMonth();
|
||||||
this.year = year;
|
this.year = date.getUTCFullYear();
|
||||||
|
|
||||||
this.loader = new CancellableTask(
|
this.loader = new CancellableTask(
|
||||||
() => {
|
() => {
|
||||||
@ -370,10 +365,10 @@ export class AssetBucket {
|
|||||||
|
|
||||||
sortDateGroups() {
|
sortDateGroups() {
|
||||||
if (this.#sortOrder === AssetOrder.Asc) {
|
if (this.#sortOrder === AssetOrder.Asc) {
|
||||||
return this.dateGroups.sort((a, b) => a.date.diff(b.date).milliseconds);
|
return this.dateGroups.sort((a, b) => a.date.valueOf() - b.date.valueOf());
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.dateGroups.sort((a, b) => b.date.diff(a.date).milliseconds);
|
return this.dateGroups.sort((a, b) => b.date.valueOf() - a.date.valueOf());
|
||||||
}
|
}
|
||||||
|
|
||||||
runAssetOperation(ids: Set<string>, operation: AssetOperation) {
|
runAssetOperation(ids: Set<string>, operation: AssetOperation) {
|
||||||
@ -419,7 +414,9 @@ export class AssetBucket {
|
|||||||
|
|
||||||
// note - if the assets are not part of this bucket, they will not be added
|
// note - if the assets are not part of this bucket, they will not be added
|
||||||
addAssets(bucketAssets: TimeBucketAssetResponseDto) {
|
addAssets(bucketAssets: TimeBucketAssetResponseDto) {
|
||||||
|
const time1 = performance.now();
|
||||||
const addContext = new AddContext();
|
const addContext = new AddContext();
|
||||||
|
const people: string[] = [];
|
||||||
for (let i = 0; i < bucketAssets.id.length; i++) {
|
for (let i = 0; i < bucketAssets.id.length; i++) {
|
||||||
const timelineAsset: TimelineAsset = {
|
const timelineAsset: TimelineAsset = {
|
||||||
city: bucketAssets.city[i],
|
city: bucketAssets.city[i],
|
||||||
@ -432,9 +429,9 @@ export class AssetBucket {
|
|||||||
isTrashed: Boolean(bucketAssets.isTrashed[i]),
|
isTrashed: Boolean(bucketAssets.isTrashed[i]),
|
||||||
isVideo: !bucketAssets.isImage[i],
|
isVideo: !bucketAssets.isImage[i],
|
||||||
livePhotoVideoId: bucketAssets.livePhotoVideoId[i],
|
livePhotoVideoId: bucketAssets.livePhotoVideoId[i],
|
||||||
localDateTime: bucketAssets.localDateTime[i],
|
localDateTime: new Date(bucketAssets.localDateTime[i]),
|
||||||
ownerId: bucketAssets.ownerId[i],
|
ownerId: bucketAssets.ownerId[i],
|
||||||
people: [],
|
people,
|
||||||
projectionType: bucketAssets.projectionType[i],
|
projectionType: bucketAssets.projectionType[i],
|
||||||
ratio: bucketAssets.ratio[i],
|
ratio: bucketAssets.ratio[i],
|
||||||
stack: bucketAssets.stack?.[i]
|
stack: bucketAssets.stack?.[i]
|
||||||
@ -450,18 +447,17 @@ export class AssetBucket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addContext.sort(this, this.#sortOrder);
|
addContext.sort(this, this.#sortOrder);
|
||||||
|
const time2 = performance.now();
|
||||||
|
const time = time2 - time1;
|
||||||
|
console.log(`AssetBucket.addAssets took ${time}ms`);
|
||||||
return addContext.unprocessedAssets;
|
return addContext.unprocessedAssets;
|
||||||
}
|
}
|
||||||
|
|
||||||
addTimelineAsset(timelineAsset: TimelineAsset, addContext: AddContext) {
|
addTimelineAsset(timelineAsset: TimelineAsset, addContext: AddContext) {
|
||||||
const { id, localDateTime } = timelineAsset;
|
const month = timelineAsset.localDateTime.getUTCMonth();
|
||||||
const date = DateTime.fromISO(localDateTime).toUTC();
|
const year = timelineAsset.localDateTime.getUTCFullYear();
|
||||||
|
|
||||||
const month = date.get('month');
|
|
||||||
const year = date.get('year');
|
|
||||||
|
|
||||||
if (this.month === month && this.year === year) {
|
if (this.month === month && this.year === year) {
|
||||||
const day = date.get('day');
|
const day = timelineAsset.localDateTime.getUTCDay();
|
||||||
let dateGroup: AssetDateGroup | undefined = addContext.lookupCache[day];
|
let dateGroup: AssetDateGroup | undefined = addContext.lookupCache[day];
|
||||||
if (!dateGroup) {
|
if (!dateGroup) {
|
||||||
dateGroup = this.findDateGroupByDay(day);
|
dateGroup = this.findDateGroupByDay(day);
|
||||||
@ -469,25 +465,26 @@ export class AssetBucket {
|
|||||||
addContext.lookupCache[day] = dateGroup;
|
addContext.lookupCache[day] = dateGroup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dateGroup) {
|
if (dateGroup) {
|
||||||
const intersectingAsset = new IntersectingAsset(dateGroup, timelineAsset);
|
const intersectingAsset = new IntersectingAsset(dateGroup, timelineAsset);
|
||||||
if (dateGroup.intersetingAssets.some((a) => a.id === id)) {
|
dateGroup.intersetingAssets.push(intersectingAsset);
|
||||||
console.error(`Ignoring attempt to add duplicate asset ${id} to ${dateGroup.groupTitle}`);
|
addContext.changedDateGroups.add(dateGroup);
|
||||||
} else {
|
|
||||||
dateGroup.intersetingAssets.push(intersectingAsset);
|
|
||||||
addContext.changedDateGroups.add(dateGroup);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
dateGroup = new AssetDateGroup(this, this.dateGroups.length, date, day);
|
dateGroup = new AssetDateGroup(this, this.dateGroups.length, timelineAsset.localDateTime, day);
|
||||||
dateGroup.intersetingAssets.push(new IntersectingAsset(dateGroup, timelineAsset));
|
dateGroup.intersetingAssets.push(new IntersectingAsset(dateGroup, timelineAsset));
|
||||||
this.dateGroups.push(dateGroup);
|
this.dateGroups.push(dateGroup);
|
||||||
addContext.lookupCache[day] = dateGroup;
|
addContext.lookupCache[day] = dateGroup;
|
||||||
addContext.newDateGroups.add(dateGroup);
|
addContext.newDateGroups.add(dateGroup);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
console.warn(
|
||||||
|
`Year ${year} and month ${month} do not match bucket year ${this.year} and month ${this.month} (${this.bucketDate} vs ${timelineAsset.localDateTime.toISOString()})`,
|
||||||
|
);
|
||||||
addContext.unprocessedAssets.push(timelineAsset);
|
addContext.unprocessedAssets.push(timelineAsset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getRandomDateGroup() {
|
getRandomDateGroup() {
|
||||||
const random = Math.floor(Math.random() * this.dateGroups.length);
|
const random = Math.floor(Math.random() * this.dateGroups.length);
|
||||||
return this.dateGroups[random];
|
return this.dateGroups[random];
|
||||||
@ -536,6 +533,7 @@ export class AssetBucket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get bucketHeight() {
|
get bucketHeight() {
|
||||||
return this.#bucketHeight;
|
return this.#bucketHeight;
|
||||||
}
|
}
|
||||||
@ -929,8 +927,7 @@ export class AssetStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.buckets = timebuckets.map((bucket) => {
|
this.buckets = timebuckets.map((bucket) => {
|
||||||
const utcDate = DateTime.fromISO(bucket.timeBucket).toUTC();
|
return new AssetBucket(this, new Date(bucket.timeBucket), bucket.count, this.#options.order);
|
||||||
return new AssetBucket(this, utcDate, bucket.count, this.#options.order);
|
|
||||||
});
|
});
|
||||||
this.albumAssets.clear();
|
this.albumAssets.clear();
|
||||||
this.#updateViewportGeometry(false);
|
this.#updateViewportGeometry(false);
|
||||||
@ -964,6 +961,7 @@ export class AssetStore {
|
|||||||
await this.#initialiazeTimeBuckets();
|
await this.#initialiazeTimeBuckets();
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
this.disconnect();
|
this.disconnect();
|
||||||
this.isInitialized = false;
|
this.isInitialized = false;
|
||||||
@ -1031,6 +1029,7 @@ export class AssetStore {
|
|||||||
rowWidth: Math.floor(viewportWidth),
|
rowWidth: Math.floor(viewportWidth),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#updateGeometry(bucket: AssetBucket, invalidateHeight: boolean) {
|
#updateGeometry(bucket: AssetBucket, invalidateHeight: boolean) {
|
||||||
if (invalidateHeight) {
|
if (invalidateHeight) {
|
||||||
bucket.isBucketHeightActual = false;
|
bucket.isBucketHeightActual = false;
|
||||||
@ -1110,9 +1109,9 @@ export class AssetStore {
|
|||||||
cancelable = options.cancelable;
|
cancelable = options.cancelable;
|
||||||
}
|
}
|
||||||
|
|
||||||
const date = DateTime.fromISO(bucketDate).toUTC();
|
const date = new Date(bucketDate);
|
||||||
const year = date.get('year');
|
const year = date.getUTCFullYear();
|
||||||
const month = date.get('month');
|
const month = date.getUTCMonth();
|
||||||
const bucket = this.getBucketByDate(year, month);
|
const bucket = this.getBucketByDate(year, month);
|
||||||
if (!bucket) {
|
if (!bucket) {
|
||||||
return;
|
return;
|
||||||
@ -1187,13 +1186,12 @@ export class AssetStore {
|
|||||||
const updatedDateGroups = new Set<AssetDateGroup>();
|
const updatedDateGroups = new Set<AssetDateGroup>();
|
||||||
|
|
||||||
for (const asset of assets) {
|
for (const asset of assets) {
|
||||||
const utc = DateTime.fromISO(asset.localDateTime).toUTC().startOf('month');
|
const year = asset.localDateTime.getUTCFullYear();
|
||||||
const year = utc.get('year');
|
const month = asset.localDateTime.getUTCMonth();
|
||||||
const month = utc.get('month');
|
|
||||||
let bucket = this.getBucketByDate(year, month);
|
let bucket = this.getBucketByDate(year, month);
|
||||||
|
|
||||||
if (!bucket) {
|
if (!bucket) {
|
||||||
bucket = new AssetBucket(this, utc, 1, this.#options.order);
|
bucket = new AssetBucket(this, asset.localDateTime, 1, this.#options.order);
|
||||||
this.buckets.push(bucket);
|
this.buckets.push(bucket);
|
||||||
}
|
}
|
||||||
const addContext = new AddContext();
|
const addContext = new AddContext();
|
||||||
@ -1236,23 +1234,21 @@ export class AssetStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async #loadBucketAtTime(localDateTime: string, options?: { cancelable: boolean }) {
|
async #loadBucketAtTime(localDateTime: Date, options?: { cancelable: boolean }) {
|
||||||
let date = DateTime.fromISO(localDateTime).toUTC();
|
|
||||||
// Only support TimeBucketSize.Month
|
// Only support TimeBucketSize.Month
|
||||||
date = date.set({ day: 1, hour: 0, minute: 0, second: 0, millisecond: 0 });
|
const year = localDateTime.getUTCFullYear();
|
||||||
const iso = date.toISO()!;
|
const month = localDateTime.getUTCMonth();
|
||||||
const year = date.get('year');
|
localDateTime = new Date(year, month);
|
||||||
const month = date.get('month');
|
await this.loadBucket(localDateTime.toISOString(), options);
|
||||||
await this.loadBucket(iso, options);
|
|
||||||
return this.getBucketByDate(year, month);
|
return this.getBucketByDate(year, month);
|
||||||
}
|
}
|
||||||
|
|
||||||
async #getBucketInfoForAsset(asset: { id: string; localDateTime: string }, options?: { cancelable: boolean }) {
|
async #getBucketInfoForAsset(asset: { id: string; localDateTime: Date | string }, options?: { cancelable: boolean }) {
|
||||||
const bucketInfo = this.#findBucketForAsset(asset.id);
|
const bucketInfo = this.#findBucketForAsset(asset.id);
|
||||||
if (bucketInfo) {
|
if (bucketInfo) {
|
||||||
return bucketInfo;
|
return bucketInfo;
|
||||||
}
|
}
|
||||||
await this.#loadBucketAtTime(asset.localDateTime, options);
|
await this.#loadBucketAtTime(new Date(asset.localDateTime), options);
|
||||||
return this.#findBucketForAsset(asset.id);
|
return this.#findBucketForAsset(asset.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1351,7 +1347,7 @@ export class AssetStore {
|
|||||||
return this.buckets[0]?.getFirstAsset();
|
return this.buckets[0]?.getFirstAsset();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPreviousAsset(asset: { id: string; localDateTime: string }): Promise<TimelineAsset | undefined> {
|
async getPreviousAsset(asset: { id: string; localDateTime: Date | string }): Promise<TimelineAsset | undefined> {
|
||||||
let bucket = await this.#getBucketInfoForAsset(asset);
|
let bucket = await this.#getBucketInfoForAsset(asset);
|
||||||
if (!bucket) {
|
if (!bucket) {
|
||||||
return;
|
return;
|
||||||
@ -1394,7 +1390,7 @@ export class AssetStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getNextAsset(asset: { id: string; localDateTime: string }): Promise<TimelineAsset | undefined> {
|
async getNextAsset(asset: { id: string; localDateTime: Date | string }): Promise<TimelineAsset | undefined> {
|
||||||
let bucket = await this.#getBucketInfoForAsset(asset);
|
let bucket = await this.#getBucketInfoForAsset(asset);
|
||||||
if (!bucket) {
|
if (!bucket) {
|
||||||
return;
|
return;
|
||||||
|
@ -2,7 +2,6 @@ import type { TimelineAsset } from '$lib/stores/assets-store.svelte';
|
|||||||
import { locale } from '$lib/stores/preferences.store';
|
import { locale } from '$lib/stores/preferences.store';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import { derived, get } from 'svelte/store';
|
import { derived, get } from 'svelte/store';
|
||||||
import { fromLocalDateTime } from './timeline-util';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate thumbnail size based on number of assets and viewport width
|
* Calculate thumbnail size based on number of assets and viewport width
|
||||||
@ -40,7 +39,7 @@ export function getThumbnailSize(assetCount: number, viewWidth: number): number
|
|||||||
|
|
||||||
export const getAltText = derived(t, ($t) => {
|
export const getAltText = derived(t, ($t) => {
|
||||||
return (asset: TimelineAsset) => {
|
return (asset: TimelineAsset) => {
|
||||||
const date = fromLocalDateTime(asset.localDateTime).toLocaleString({ dateStyle: 'long' }, { locale: get(locale) });
|
const date = asset.localDateTime.toLocaleString(get(locale), { dateStyle: 'long', timeZone: 'UTC' });
|
||||||
const hasPlace = asset.city && asset.country;
|
const hasPlace = asset.city && asset.country;
|
||||||
|
|
||||||
const peopleCount = asset.people.length;
|
const peopleCount = asset.people.length;
|
||||||
|
@ -19,6 +19,8 @@ export const fromLocalDateTime = (localDateTime: string) =>
|
|||||||
export const fromDateTimeOriginal = (dateTimeOriginal: string, timeZone: string) =>
|
export const fromDateTimeOriginal = (dateTimeOriginal: string, timeZone: string) =>
|
||||||
DateTime.fromISO(dateTimeOriginal, { zone: timeZone });
|
DateTime.fromISO(dateTimeOriginal, { zone: timeZone });
|
||||||
|
|
||||||
|
export const startOfMonth = (date: Date) => new Date(date.getFullYear(), date.getMonth());
|
||||||
|
|
||||||
export function formatGroupTitle(_date: DateTime): string {
|
export function formatGroupTitle(_date: DateTime): string {
|
||||||
if (!_date.isValid) {
|
if (!_date.isValid) {
|
||||||
return _date.toString();
|
return _date.toString();
|
||||||
@ -77,7 +79,7 @@ export const toTimelineAsset = (unknownAsset: AssetResponseDto | TimelineAsset):
|
|||||||
ownerId: assetResponse.ownerId,
|
ownerId: assetResponse.ownerId,
|
||||||
ratio,
|
ratio,
|
||||||
thumbhash: assetResponse.thumbhash,
|
thumbhash: assetResponse.thumbhash,
|
||||||
localDateTime: assetResponse.localDateTime,
|
localDateTime: new Date(assetResponse.localDateTime),
|
||||||
isFavorite: assetResponse.isFavorite,
|
isFavorite: assetResponse.isFavorite,
|
||||||
isArchived: assetResponse.isArchived,
|
isArchived: assetResponse.isArchived,
|
||||||
isTrashed: assetResponse.isTrashed,
|
isTrashed: assetResponse.isTrashed,
|
||||||
|
@ -32,7 +32,7 @@ export const timelineAssetFactory = Sync.makeFactory<TimelineAsset>({
|
|||||||
ratio: Sync.each(() => faker.number.int()),
|
ratio: Sync.each(() => faker.number.int()),
|
||||||
ownerId: Sync.each(() => faker.string.uuid()),
|
ownerId: Sync.each(() => faker.string.uuid()),
|
||||||
thumbhash: Sync.each(() => faker.string.alphanumeric(28)),
|
thumbhash: Sync.each(() => faker.string.alphanumeric(28)),
|
||||||
localDateTime: Sync.each(() => faker.date.past().toISOString()),
|
localDateTime: Sync.each(() => faker.date.past()),
|
||||||
isFavorite: Sync.each(() => faker.datatype.boolean()),
|
isFavorite: Sync.each(() => faker.datatype.boolean()),
|
||||||
isArchived: false,
|
isArchived: false,
|
||||||
isTrashed: false,
|
isTrashed: false,
|
||||||
@ -75,7 +75,7 @@ export const toResponseDto = (...timelineAsset: TimelineAsset[]) => {
|
|||||||
bucketAssets.isImage.push(asset.isImage ? 1 : 0);
|
bucketAssets.isImage.push(asset.isImage ? 1 : 0);
|
||||||
bucketAssets.isTrashed.push(asset.isTrashed ? 1 : 0);
|
bucketAssets.isTrashed.push(asset.isTrashed ? 1 : 0);
|
||||||
bucketAssets.livePhotoVideoId.push(asset.livePhotoVideoId!);
|
bucketAssets.livePhotoVideoId.push(asset.livePhotoVideoId!);
|
||||||
bucketAssets.localDateTime.push(asset.localDateTime);
|
bucketAssets.localDateTime.push(asset.localDateTime.toISOString());
|
||||||
bucketAssets.ownerId.push(asset.ownerId);
|
bucketAssets.ownerId.push(asset.ownerId);
|
||||||
bucketAssets.projectionType.push(asset.projectionType!);
|
bucketAssets.projectionType.push(asset.projectionType!);
|
||||||
bucketAssets.ratio.push(asset.ratio);
|
bucketAssets.ratio.push(asset.ratio);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user