mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
refactor: rename TimelineAsset -> Asset
This commit is contained in:
parent
53680d9643
commit
c6e1170e6d
57 changed files with 260 additions and 281 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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>();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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: [],
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) ||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue