feat(web): timeline bucket for albums (4) (#3604)

* feat: server changes for album timeline

* feat(web): album timeline view

* chore: open api

* chore: remove archive action

* fix: favorite for non-owners
This commit is contained in:
Jason Rasmussen
2023-08-11 12:00:51 -04:00
committed by GitHub
parent 36dc7bd924
commit 5cd13227ad
47 changed files with 1014 additions and 757 deletions

View File

@@ -1,8 +1,8 @@
import type { AssetResponseDto } from '@api';
import { derived, writable } from 'svelte/store';
import type { AssetResponseDto } from '../../api/open-api';
export interface AssetInteractionStore {
addAssetToMultiselectGroup: (asset: AssetResponseDto) => void;
selectAsset: (asset: AssetResponseDto) => void;
removeAssetFromMultiselectGroup: (asset: AssetResponseDto) => void;
addGroupToMultiselectGroup: (group: string) => void;
removeGroupFromMultiselectGroup: (group: string) => void;
@@ -13,13 +13,6 @@ export interface AssetInteractionStore {
isMultiSelectState: {
subscribe: (run: (value: boolean) => void, invalidate?: (value?: boolean) => void) => () => void;
};
assetsInAlbumState: {
subscribe: (
run: (value: AssetResponseDto[]) => void,
invalidate?: (value?: AssetResponseDto[]) => void,
) => () => void;
set: (value: AssetResponseDto[]) => void;
};
selectedAssets: {
subscribe: (
run: (value: Set<AssetResponseDto>) => void,
@@ -46,11 +39,9 @@ export interface AssetInteractionStore {
export function createAssetInteractionStore(): AssetInteractionStore {
let _selectedAssets: Set<AssetResponseDto>;
let _selectedGroup: Set<string>;
let _assetsInAlbums: AssetResponseDto[];
let _assetSelectionCandidates: Set<AssetResponseDto>;
let _assetSelectionStart: AssetResponseDto | null;
const assetsInAlbumStoreState = writable<AssetResponseDto[]>([]);
// Selected assets
const selectedAssets = writable<Set<AssetResponseDto>>(new Set());
// Selected date groups
@@ -72,10 +63,6 @@ export function createAssetInteractionStore(): AssetInteractionStore {
_selectedGroup = group;
});
assetsInAlbumStoreState.subscribe((assets) => {
_assetsInAlbums = assets;
});
assetSelectionCandidates.subscribe((assets) => {
_assetSelectionCandidates = assets;
});
@@ -84,12 +71,7 @@ export function createAssetInteractionStore(): AssetInteractionStore {
_assetSelectionStart = asset;
});
const addAssetToMultiselectGroup = (asset: AssetResponseDto) => {
// Not select if in album already
if (_assetsInAlbums.find((a) => a.id === asset.id)) {
return;
}
const selectAsset = (asset: AssetResponseDto) => {
_selectedAssets.add(asset);
selectedAssets.set(_selectedAssets);
};
@@ -128,7 +110,6 @@ export function createAssetInteractionStore(): AssetInteractionStore {
// Multi-selection
_selectedAssets.clear();
_selectedGroup.clear();
_assetsInAlbums = [];
// Range selection
_assetSelectionCandidates.clear();
@@ -136,13 +117,12 @@ export function createAssetInteractionStore(): AssetInteractionStore {
selectedAssets.set(_selectedAssets);
selectedGroup.set(_selectedGroup);
assetsInAlbumStoreState.set(_assetsInAlbums);
assetSelectionCandidates.set(_assetSelectionCandidates);
assetSelectionStart.set(_assetSelectionStart);
};
return {
addAssetToMultiselectGroup,
selectAsset,
removeAssetFromMultiselectGroup,
addGroupToMultiselectGroup,
removeGroupFromMultiselectGroup,
@@ -153,10 +133,6 @@ export function createAssetInteractionStore(): AssetInteractionStore {
isMultiSelectState: {
subscribe: isMultiSelectStoreState.subscribe,
},
assetsInAlbumState: {
subscribe: assetsInAlbumStoreState.subscribe,
set: assetsInAlbumStoreState.set,
},
selectedAssets: {
subscribe: selectedAssets.subscribe,
},

View File

@@ -43,14 +43,21 @@ export class AssetStore {
timelineHeight = 0;
buckets: AssetBucket[] = [];
assets: AssetResponseDto[] = [];
albumAssets: Set<string> = new Set();
constructor(private options: AssetStoreOptions) {
constructor(private options: AssetStoreOptions, private albumId?: string) {
this.store$.set(this);
}
subscribe = this.store$.subscribe;
async init(viewport: Viewport) {
this.timelineHeight = 0;
this.buckets = [];
this.assets = [];
this.assetToBucket = {};
this.albumAssets = new Set();
const { data: buckets } = await api.assetApi.getTimeBuckets(this.options);
this.buckets = buckets.map((bucket) => {
@@ -104,6 +111,22 @@ export class AssetStore {
{ signal: bucket.cancelToken.signal },
);
if (this.albumId) {
const { data: albumAssets } = await api.assetApi.getByTimeBucket(
{
albumId: this.albumId,
timeBucket: bucketDate,
size: this.options.size,
key: this.options.key,
},
{ signal: bucket.cancelToken.signal },
);
for (const asset of albumAssets) {
this.albumAssets.add(asset.id);
}
}
bucket.assets = assets;
this.emit(true);
} catch (error) {