refactor: rename TimelineAsset -> Asset

This commit is contained in:
midzelis 2025-10-08 23:54:07 +00:00
parent 53680d9643
commit c6e1170e6d
57 changed files with 260 additions and 281 deletions

View file

@ -6,7 +6,7 @@ import { plainDateTimeCompare } from '$lib/utils/timeline-util';
import { SvelteSet } from 'svelte/reactivity';
import type { MonthGroup } from './month-group.svelte';
import type { AssetOperation, Direction, MoveAsset, TimelineAsset } from './types';
import type { Asset, AssetOperation, Direction, MoveAsset } from './types';
import { ViewerAsset } from './viewer-asset.svelte';
export class DayGroup {
@ -82,7 +82,7 @@ export class DayGroup {
return this.viewerAssets[0]?.asset;
}
*assetsIterator(options: { startAsset?: TimelineAsset; direction?: Direction } = {}) {
*assetsIterator(options: { startAsset?: Asset; direction?: Direction } = {}) {
const isEarlier = (options?.direction ?? 'earlier') === 'earlier';
let assetIndex = options?.startAsset
? this.viewerAssets.findIndex((viewerAsset) => viewerAsset.asset.id === options.startAsset!.id)

View file

@ -3,13 +3,13 @@ import { AssetOrder } from '@immich/sdk';
import { SvelteSet } from 'svelte/reactivity';
import type { DayGroup } from './day-group.svelte';
import type { MonthGroup } from './month-group.svelte';
import type { TimelineAsset } from './types';
import type { Asset } from './types';
export class GroupInsertionCache {
#lookupCache: {
[year: number]: { [month: number]: { [day: number]: DayGroup } };
} = {};
unprocessedAssets: TimelineAsset[] = [];
unprocessedAssets: Asset[] = [];
changedDayGroups = new SvelteSet<DayGroup>();
newDayGroups = new SvelteSet<DayGroup>();

View file

@ -5,13 +5,13 @@ import { SvelteSet } from 'svelte/reactivity';
import { GroupInsertionCache } from '../group-insertion-cache.svelte';
import { MonthGroup } from '../month-group.svelte';
import type { TimelineManager } from '../timeline-manager.svelte';
import type { AssetOperation, TimelineAsset } from '../types';
import type { Asset, AssetOperation } from '../types';
import { updateGeometry } from './layout-support.svelte';
import { getMonthGroupByDate } from './search-support.svelte';
export function addAssetsToMonthGroups(
timelineManager: TimelineManager,
assets: TimelineAsset[],
assets: Asset[],
options: { order: AssetOrder },
) {
if (assets.length === 0) {
@ -30,7 +30,7 @@ export function addAssetsToMonthGroups(
timelineManager.months.push(month);
}
month.addTimelineAsset(asset, addContext);
month.addAsset(asset, addContext);
updatedMonthGroups.add(month);
}
@ -70,7 +70,7 @@ export function runAssetOperation(
const changedMonthGroups = new SvelteSet<MonthGroup>();
let idsToProcess = new SvelteSet(ids);
const idsProcessed = new SvelteSet<string>();
const combinedMoveAssets: { asset: TimelineAsset; date: TimelineDate }[][] = [];
const combinedMoveAssets: { asset: Asset; date: TimelineDate }[][] = [];
for (const month of timelineManager.months) {
if (idsToProcess.size > 0) {
const { moveAssets, processedIds, changedGeometry } = month.runAssetOperation(idsToProcess, operation);

View file

@ -2,14 +2,14 @@ import { plainDateTimeCompare, type TimelineYearMonth } from '$lib/utils/timelin
import { AssetOrder } from '@immich/sdk';
import type { MonthGroup } from '../month-group.svelte';
import type { TimelineManager } from '../timeline-manager.svelte';
import type { AssetDescriptor, Direction, TimelineAsset } from '../types';
import type { Asset, AssetDescriptor, Direction } from '../types';
export async function getAssetWithOffset(
timelineManager: TimelineManager,
assetDescriptor: AssetDescriptor,
interval: 'asset' | 'day' | 'month' | 'year' = 'asset',
direction: Direction,
): Promise<TimelineAsset | undefined> {
): Promise<Asset | undefined> {
const { asset, monthGroup } = findMonthGroupForAsset(timelineManager, assetDescriptor.id) ?? {};
if (!monthGroup || !asset) {
return;
@ -51,7 +51,7 @@ export function getMonthGroupByDate(
async function getAssetByAssetOffset(
timelineManager: TimelineManager,
asset: TimelineAsset,
asset: Asset,
monthGroup: MonthGroup,
direction: Direction,
) {
@ -70,7 +70,7 @@ async function getAssetByAssetOffset(
async function getAssetByDayOffset(
timelineManager: TimelineManager,
asset: TimelineAsset,
asset: Asset,
monthGroup: MonthGroup,
direction: Direction,
) {
@ -120,7 +120,7 @@ export async function retrieveRange(timelineManager: TimelineManager, start: Ass
[startMonthGroup, endMonthGroup] = [endMonthGroup, startMonthGroup];
}
const range: TimelineAsset[] = [];
const range: Asset[] = [];
const startDayGroup = startMonthGroup.findDayGroupForAsset(startAsset);
for await (const targetAsset of timelineManager.assetsIterator({
startMonthGroup,

View file

@ -1,7 +1,7 @@
import type { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
import type { PendingChange, TimelineAsset } from '$lib/managers/timeline-manager/types';
import type { Asset, PendingChange } from '$lib/managers/timeline-manager/types';
import { websocketEvents } from '$lib/stores/websocket';
import { toTimelineAsset } from '$lib/utils/timeline-util';
import { toAsset } from '$lib/utils/timeline-util';
import { throttle } from 'lodash-es';
import type { Unsubscriber } from 'svelte/store';
@ -31,11 +31,11 @@ export class WebsocketSupport {
connectWebsocketEvents() {
this.#unsubscribers.push(
websocketEvents.on('on_upload_success', (asset) =>
this.#addPendingChanges({ type: 'add', values: [toTimelineAsset(asset)] }),
this.#addPendingChanges({ type: 'add', values: [toAsset(asset)] }),
),
websocketEvents.on('on_asset_trash', (ids) => this.#addPendingChanges({ type: 'trash', values: ids })),
websocketEvents.on('on_asset_update', (asset) =>
this.#addPendingChanges({ type: 'update', values: [toTimelineAsset(asset)] }),
this.#addPendingChanges({ type: 'update', values: [toAsset(asset)] }),
),
websocketEvents.on('on_asset_delete', (id: string) => this.#addPendingChanges({ type: 'delete', values: [id] })),
);
@ -55,8 +55,8 @@ export class WebsocketSupport {
#getPendingChangeBatches() {
const batch: {
add: TimelineAsset[];
update: TimelineAsset[];
add: Asset[];
update: Asset[];
remove: string[];
} = {
add: [],

View file

@ -21,7 +21,7 @@ import { SvelteSet } from 'svelte/reactivity';
import { DayGroup } from './day-group.svelte';
import { GroupInsertionCache } from './group-insertion-cache.svelte';
import type { TimelineManager } from './timeline-manager.svelte';
import type { AssetDescriptor, AssetOperation, Direction, MoveAsset, TimelineAsset } from './types';
import type { Asset, AssetDescriptor, AssetOperation, Direction, MoveAsset } from './types';
import { ViewerAsset } from './viewer-asset.svelte';
export class MonthGroup {
@ -101,7 +101,7 @@ export class MonthGroup {
getAssets() {
// eslint-disable-next-line unicorn/no-array-reduce
return this.dayGroups.reduce((accumulator: TimelineAsset[], g: DayGroup) => accumulator.concat(g.getAssets()), []);
return this.dayGroups.reduce((accumulator: Asset[], g: DayGroup) => accumulator.concat(g.getAssets()), []);
}
sortDayGroups() {
@ -161,7 +161,7 @@ export class MonthGroup {
bucketAssets.localOffsetHours[i],
);
const timelineAsset: TimelineAsset = {
const timelineAsset: Asset = {
city: bucketAssets.city[i],
country: bucketAssets.country[i],
duration: bucketAssets.duration[i],
@ -192,7 +192,7 @@ export class MonthGroup {
timelineAsset.latitude = bucketAssets.latitude?.[i];
timelineAsset.longitude = bucketAssets.longitude?.[i];
}
this.addTimelineAsset(timelineAsset, addContext);
this.addAsset(timelineAsset, addContext);
}
for (const group of addContext.existingDayGroups) {
@ -208,7 +208,7 @@ export class MonthGroup {
return addContext.unprocessedAssets;
}
addTimelineAsset(timelineAsset: TimelineAsset, addContext: GroupInsertionCache) {
addAsset(timelineAsset: Asset, addContext: GroupInsertionCache) {
const { localDateTime } = timelineAsset;
const { year, month } = this.yearMonth;
@ -294,7 +294,7 @@ export class MonthGroup {
handleError(error, _$t('errors.failed_to_load_assets'));
}
findDayGroupForAsset(asset: TimelineAsset) {
findDayGroupForAsset(asset: Asset) {
for (const group of this.dayGroups) {
if (group.viewerAssets.some((viewerAsset) => viewerAsset.id === asset.id)) {
return group;
@ -321,7 +321,7 @@ export class MonthGroup {
return -1;
}
*assetsIterator(options?: { startDayGroup?: DayGroup; startAsset?: TimelineAsset; direction?: Direction }) {
*assetsIterator(options?: { startDayGroup?: DayGroup; startAsset?: Asset; direction?: Direction }) {
const direction = options?.direction ?? 'earlier';
let { startAsset } = options ?? {};
const isEarlier = direction === 'earlier';

View file

@ -5,7 +5,7 @@ import { fromISODateTimeUTCToObject } from '$lib/utils/timeline-util';
import { type AssetResponseDto, type TimeBucketAssetResponseDto } from '@immich/sdk';
import { timelineAssetFactory, toResponseDto } from '@test-data/factories/asset-factory';
import { TimelineManager } from './timeline-manager.svelte';
import type { TimelineAsset } from './types';
import type { Asset } from './types';
async function getAssets(timelineManager: TimelineManager) {
const assets = [];
@ -15,7 +15,7 @@ async function getAssets(timelineManager: TimelineManager) {
return assets;
}
function deriveLocalDateTimeFromFileCreatedAt(arg: TimelineAsset): TimelineAsset {
function deriveLocalDateTimeFromFileCreatedAt(arg: Asset): Asset {
return {
...arg,
localDateTime: arg.fileCreatedAt,
@ -29,7 +29,7 @@ describe('TimelineManager', () => {
describe('init', () => {
let timelineManager: TimelineManager;
const bucketAssets: Record<string, TimelineAsset[]> = {
const bucketAssets: Record<string, Asset[]> = {
'2024-03-01T00:00:00.000Z': timelineAssetFactory.buildList(1).map((asset) =>
deriveLocalDateTimeFromFileCreatedAt({
...asset,
@ -94,7 +94,7 @@ describe('TimelineManager', () => {
describe('loadMonthGroup', () => {
let timelineManager: TimelineManager;
const bucketAssets: Record<string, TimelineAsset[]> = {
const bucketAssets: Record<string, Asset[]> = {
'2024-01-03T00:00:00.000Z': timelineAssetFactory.buildList(1).map((asset) =>
deriveLocalDateTimeFromFileCreatedAt({
...asset,
@ -436,7 +436,7 @@ describe('TimelineManager', () => {
describe('getLaterAsset', () => {
let timelineManager: TimelineManager;
const bucketAssets: Record<string, TimelineAsset[]> = {
const bucketAssets: Record<string, Asset[]> = {
'2024-03-01T00:00:00.000Z': timelineAssetFactory.buildList(1).map((asset) =>
deriveLocalDateTimeFromFileCreatedAt({
...asset,
@ -583,7 +583,7 @@ describe('TimelineManager', () => {
describe('getRandomAsset', () => {
let timelineManager: TimelineManager;
const bucketAssets: Record<string, TimelineAsset[]> = {
const bucketAssets: Record<string, Asset[]> = {
'2024-03-01T00:00:00.000Z': timelineAssetFactory.buildList(1).map((asset) =>
deriveLocalDateTimeFromFileCreatedAt({
...asset,

View file

@ -3,7 +3,7 @@ import { AssetOrder, getAssetInfo, getTimeBuckets } from '@immich/sdk';
import { authManager } from '$lib/managers/auth-manager.svelte';
import { CancellableTask } from '$lib/utils/cancellable-task';
import { toTimelineAsset, type TimelineDateTime, type TimelineYearMonth } from '$lib/utils/timeline-util';
import { toAsset, type TimelineDateTime, type TimelineYearMonth } from '$lib/utils/timeline-util';
import { clamp, debounce, isEqual } from 'lodash-es';
import { SvelteDate, SvelteMap, SvelteSet } from 'svelte/reactivity';
@ -27,11 +27,11 @@ import { DayGroup } from './day-group.svelte';
import { isMismatched, updateObject } from './internal/utils.svelte';
import { MonthGroup } from './month-group.svelte';
import type {
Asset,
AssetDescriptor,
AssetOperation,
Direction,
ScrubberMonth,
TimelineAsset,
TimelineManagerLayoutOptions,
TimelineManagerOptions,
Viewport,
@ -192,7 +192,7 @@ export class TimelineManager {
async *assetsIterator(options?: {
startMonthGroup?: MonthGroup;
startDayGroup?: DayGroup;
startAsset?: TimelineAsset;
startAsset?: Asset;
direction?: Direction;
}) {
const direction = options?.direction ?? 'earlier';
@ -409,7 +409,7 @@ export class TimelineManager {
}
}
addAssets(assets: TimelineAsset[]) {
addAssets(assets: Asset[]) {
const assetsToUpdate = assets.filter((asset) => !this.isExcluded(asset));
const notUpdated = this.updateAssets(assetsToUpdate);
addAssetsToMonthGroups(this, [...notUpdated], { order: this.#options.order ?? AssetOrder.Desc });
@ -430,7 +430,7 @@ export class TimelineManager {
return;
}
const asset = toTimelineAsset(response);
const asset = toAsset(response);
if (!asset || this.isExcluded(asset)) {
return;
}
@ -454,7 +454,7 @@ export class TimelineManager {
// note: the `index` input is expected to be in the range [0, assetCount). This
// value can be passed to make the method deterministic, which is mainly useful
// for testing.
async getRandomAsset(index?: number): Promise<TimelineAsset | undefined> {
async getRandomAsset(index?: number): Promise<Asset | undefined> {
const randomAssetIndex = index ?? Math.floor(Math.random() * this.assetCount);
let accumulatedCount = 0;
@ -493,8 +493,8 @@ export class TimelineManager {
runAssetOperation(this, new SvelteSet(ids), operation, { order: this.#options.order ?? AssetOrder.Desc });
}
updateAssets(assets: TimelineAsset[]) {
const lookup = new SvelteMap<string, TimelineAsset>(assets.map((asset) => [asset.id, asset]));
updateAssets(assets: Asset[]) {
const lookup = new SvelteMap<string, Asset>(assets.map((asset) => [asset.id, asset]));
const { unprocessedIds } = runAssetOperation(
this,
new SvelteSet(lookup.keys()),
@ -504,7 +504,7 @@ export class TimelineManager {
},
{ order: this.#options.order ?? AssetOrder.Desc },
);
const result: TimelineAsset[] = [];
const result: Asset[] = [];
for (const id of unprocessedIds.values()) {
result.push(lookup.get(id)!);
}
@ -530,21 +530,21 @@ export class TimelineManager {
this.updateIntersections();
}
getFirstAsset(): TimelineAsset | undefined {
getFirstAsset(): Asset | undefined {
return this.months[0]?.getFirstAsset();
}
async getLaterAsset(
assetDescriptor: AssetDescriptor,
interval: 'asset' | 'day' | 'month' | 'year' = 'asset',
): Promise<TimelineAsset | undefined> {
): Promise<Asset | undefined> {
return await getAssetWithOffset(this, assetDescriptor, interval, 'later');
}
async getEarlierAsset(
assetDescriptor: AssetDescriptor,
interval: 'asset' | 'day' | 'month' | 'year' = 'asset',
): Promise<TimelineAsset | undefined> {
): Promise<Asset | undefined> {
return await getAssetWithOffset(this, assetDescriptor, interval, 'earlier');
}
@ -567,7 +567,7 @@ export class TimelineManager {
return retrieveRangeUtil(this, start, end);
}
isExcluded(asset: TimelineAsset) {
isExcluded(asset: Asset) {
return (
isMismatched(this.#options.visibility, asset.visibility) ||
isMismatched(this.#options.isFavorite, asset.isFavorite) ||

View file

@ -12,7 +12,7 @@ export type AssetDescriptor = { id: string };
export type Direction = 'earlier' | 'later';
export type TimelineAsset = {
export type Asset = {
id: string;
ownerId: string;
ratio: number;
@ -35,9 +35,9 @@ export type TimelineAsset = {
longitude?: number | null;
};
export type AssetOperation = (asset: TimelineAsset) => { remove: boolean };
export type AssetOperation = (asset: Asset) => { remove: boolean };
export type MoveAsset = { asset: TimelineAsset; date: TimelineDate };
export type MoveAsset = { asset: Asset; date: TimelineDate };
export interface Viewport {
width: number;
@ -51,12 +51,12 @@ export type ViewportXY = Viewport & {
export interface AddAsset {
type: 'add';
values: TimelineAsset[];
values: Asset[];
}
export interface UpdateAsset {
type: 'update';
values: TimelineAsset[];
values: Asset[];
}
export interface DeleteAsset {

View file

@ -1,4 +1,4 @@
import type { TimelineAsset } from './types';
import type { Asset } from './types';
export const assetSnapshot = (asset: TimelineAsset): TimelineAsset => $state.snapshot(asset);
export const assetsSnapshot = (assets: TimelineAsset[]) => assets.map((asset) => $state.snapshot(asset));
export const assetSnapshot = (asset: Asset): Asset => $state.snapshot(asset);
export const assetsSnapshot = (assets: Asset[]) => assets.map((asset) => $state.snapshot(asset));

View file

@ -2,7 +2,7 @@ import type { CommonPosition } from '$lib/utils/layout-utils';
import type { DayGroup } from './day-group.svelte';
import { calculateViewerAssetIntersecting } from './internal/intersection-support.svelte';
import type { TimelineAsset } from './types';
import type { Asset } from './types';
export class ViewerAsset {
readonly #group: DayGroup;
@ -19,10 +19,10 @@ export class ViewerAsset {
});
position: CommonPosition | undefined = $state();
asset: TimelineAsset = <TimelineAsset>$state();
asset: Asset = <Asset>$state();
id: string = $derived(this.asset.id);
constructor(group: DayGroup, asset: TimelineAsset) {
constructor(group: DayGroup, asset: Asset) {
this.#group = group;
this.asset = asset;
}