Replace AssetDateGroup with AssetDateGroupSelectionAware throughout - merge/replace temp
• Update asset-grid-without-scrubber to use AssetDateGroupSelectionAware • Remove original asset-date-group.svelte component • Remove date-group-actions-lib.svelte.ts class
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
import { afterNavigate, beforeNavigate } from '$app/navigation';
|
import { afterNavigate, beforeNavigate } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { resizeObserver, type OnResizeCallback } from '$lib/actions/resize-observer';
|
import { resizeObserver, type OnResizeCallback } from '$lib/actions/resize-observer';
|
||||||
|
import AssetDateGroupSelectionAware from '$lib/components/photos-page/asset-date-group-selection-aware.svelte';
|
||||||
import AssetGridActions from '$lib/components/photos-page/asset-grid-actions.svelte';
|
import AssetGridActions from '$lib/components/photos-page/asset-grid-actions.svelte';
|
||||||
import AssetViewerAndActions from '$lib/components/photos-page/asset-viewer-and-actions.svelte';
|
import AssetViewerAndActions from '$lib/components/photos-page/asset-viewer-and-actions.svelte';
|
||||||
import Skeleton from '$lib/components/photos-page/skeleton.svelte';
|
import Skeleton from '$lib/components/photos-page/skeleton.svelte';
|
||||||
@@ -18,7 +19,6 @@
|
|||||||
import { onMount, type Snippet } from 'svelte';
|
import { onMount, type Snippet } from 'svelte';
|
||||||
import type { UpdatePayload } from 'vite';
|
import type { UpdatePayload } from 'vite';
|
||||||
import Portal from '../shared-components/portal/portal.svelte';
|
import Portal from '../shared-components/portal/portal.svelte';
|
||||||
import AssetDateGroup from './asset-date-group.svelte';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isSelectionMode?: boolean;
|
isSelectionMode?: boolean;
|
||||||
@@ -339,7 +339,7 @@
|
|||||||
style:transform={`translate3d(0,${absoluteHeight}px,0)`}
|
style:transform={`translate3d(0,${absoluteHeight}px,0)`}
|
||||||
style:width="100%"
|
style:width="100%"
|
||||||
>
|
>
|
||||||
<AssetDateGroup
|
<AssetDateGroupSelectionAware
|
||||||
{withStacked}
|
{withStacked}
|
||||||
{showArchiveIcon}
|
{showArchiveIcon}
|
||||||
{assetInteraction}
|
{assetInteraction}
|
||||||
|
|||||||
@@ -1,190 +0,0 @@
|
|||||||
import { DayGroup } from '$lib/managers/timeline-manager/day-group.svelte';
|
|
||||||
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
|
|
||||||
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
|
||||||
import { assetsSnapshot } from '$lib/managers/timeline-manager/utils.svelte';
|
|
||||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
|
||||||
import { isSelectingAllAssets } from '$lib/stores/assets-store.svelte';
|
|
||||||
import { searchStore } from '$lib/stores/search.svelte';
|
|
||||||
|
|
||||||
/** Glue functions that update the assetInteraction (asset selection) in response to AssetDateGroup UI
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export class DateGroupActionLib {
|
|
||||||
onSelect: (asset: TimelineAsset) => void = () => void 0;
|
|
||||||
onScrollToTop: () => void = () => void 0;
|
|
||||||
assetInteraction: AssetInteraction = $state(new AssetInteraction());
|
|
||||||
timelineManager: TimelineManager = $state(new TimelineManager());
|
|
||||||
singleSelect: boolean = $state(false);
|
|
||||||
lastAssetMouseEvent: TimelineAsset | null = $state(null);
|
|
||||||
shiftKeyIsDown = $state(false);
|
|
||||||
isEmpty = $derived(this.timelineManager.isInitialized && this.timelineManager.months.length === 0);
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
$effect(() => {
|
|
||||||
if (!this.lastAssetMouseEvent || !this.lastAssetMouseEvent) {
|
|
||||||
this.assetInteraction.clearAssetSelectionCandidates();
|
|
||||||
}
|
|
||||||
if (this.shiftKeyIsDown && this.lastAssetMouseEvent) {
|
|
||||||
void this.selectAssetCandidates(this.lastAssetMouseEvent);
|
|
||||||
}
|
|
||||||
if (this.isEmpty) {
|
|
||||||
this.assetInteraction.clearMultiselect();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSelectAsset(asset: TimelineAsset) {
|
|
||||||
if (!this.timelineManager.albumAssets.has(asset.id)) {
|
|
||||||
this.assetInteraction.selectAsset(asset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onKeyDown = (event: KeyboardEvent) => {
|
|
||||||
if (searchStore.isSearchEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === 'Shift') {
|
|
||||||
event.preventDefault();
|
|
||||||
this.shiftKeyIsDown = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onKeyUp = (event: KeyboardEvent) => {
|
|
||||||
if (searchStore.isSearchEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === 'Shift') {
|
|
||||||
event.preventDefault();
|
|
||||||
this.shiftKeyIsDown = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onSelectAssetCandidates = (asset: TimelineAsset | null) => {
|
|
||||||
if (asset) {
|
|
||||||
void this.selectAssetCandidates(asset);
|
|
||||||
}
|
|
||||||
this.lastAssetMouseEvent = asset;
|
|
||||||
};
|
|
||||||
|
|
||||||
onDayGroupSelect = (dayGroup: DayGroup, assets: TimelineAsset[]) => {
|
|
||||||
const group = dayGroup.groupTitle;
|
|
||||||
if (this.assetInteraction.selectedGroup.has(group)) {
|
|
||||||
this.assetInteraction.removeGroupFromMultiselectGroup(group);
|
|
||||||
for (const asset of assets) {
|
|
||||||
this.assetInteraction.removeAssetFromMultiselectGroup(asset.id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.assetInteraction.addGroupToMultiselectGroup(group);
|
|
||||||
for (const asset of assets) {
|
|
||||||
this.handleSelectAsset(asset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.timelineManager.assetCount == this.assetInteraction.selectedAssets.length) {
|
|
||||||
isSelectingAllAssets.set(true);
|
|
||||||
} else {
|
|
||||||
isSelectingAllAssets.set(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onSelectAssets = async (asset: TimelineAsset) => {
|
|
||||||
if (!asset) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.onSelect(asset);
|
|
||||||
|
|
||||||
if (this.singleSelect) {
|
|
||||||
this.onScrollToTop();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const rangeSelection = this.assetInteraction.assetSelectionCandidates.length > 0;
|
|
||||||
const deselect = this.assetInteraction.hasSelectedAsset(asset.id);
|
|
||||||
|
|
||||||
// Select/deselect already loaded assets
|
|
||||||
if (deselect) {
|
|
||||||
for (const candidate of this.assetInteraction.assetSelectionCandidates) {
|
|
||||||
this.assetInteraction.removeAssetFromMultiselectGroup(candidate.id);
|
|
||||||
}
|
|
||||||
this.assetInteraction.removeAssetFromMultiselectGroup(asset.id);
|
|
||||||
} else {
|
|
||||||
for (const candidate of this.assetInteraction.assetSelectionCandidates) {
|
|
||||||
this.handleSelectAsset(candidate);
|
|
||||||
}
|
|
||||||
this.handleSelectAsset(asset);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.assetInteraction.clearAssetSelectionCandidates();
|
|
||||||
|
|
||||||
if (this.assetInteraction.assetSelectionStart && rangeSelection) {
|
|
||||||
let startBucket = this.timelineManager.getMonthGroupByAssetId(this.assetInteraction.assetSelectionStart.id);
|
|
||||||
let endBucket = this.timelineManager.getMonthGroupByAssetId(asset.id);
|
|
||||||
|
|
||||||
if (startBucket === null || endBucket === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select/deselect assets in range (start,end)
|
|
||||||
let started = false;
|
|
||||||
for (const monthGroup of this.timelineManager.months) {
|
|
||||||
if (monthGroup === endBucket) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (started) {
|
|
||||||
await this.timelineManager.loadMonthGroup(monthGroup.yearMonth);
|
|
||||||
for (const asset of monthGroup.assetsIterator()) {
|
|
||||||
if (deselect) {
|
|
||||||
this.assetInteraction.removeAssetFromMultiselectGroup(asset.id);
|
|
||||||
} else {
|
|
||||||
this.handleSelectAsset(asset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (monthGroup === startBucket) {
|
|
||||||
started = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update date group selection in range [start,end]
|
|
||||||
started = false;
|
|
||||||
for (const monthGroup of this.timelineManager.months) {
|
|
||||||
if (monthGroup === startBucket) {
|
|
||||||
started = true;
|
|
||||||
}
|
|
||||||
if (started) {
|
|
||||||
// Split month group into day groups and check each group
|
|
||||||
for (const dayGroup of monthGroup.dayGroups) {
|
|
||||||
const dayGroupTitle = dayGroup.groupTitle;
|
|
||||||
if (dayGroup.getAssets().every((a) => this.assetInteraction.hasSelectedAsset(a.id))) {
|
|
||||||
this.assetInteraction.addGroupToMultiselectGroup(dayGroupTitle);
|
|
||||||
} else {
|
|
||||||
this.assetInteraction.removeGroupFromMultiselectGroup(dayGroupTitle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (monthGroup === endBucket) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.assetInteraction.setAssetSelectionStart(deselect ? null : asset);
|
|
||||||
};
|
|
||||||
|
|
||||||
selectAssetCandidates = async (endAsset: TimelineAsset) => {
|
|
||||||
if (!this.shiftKeyIsDown) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const startAsset = this.assetInteraction.assetSelectionStart;
|
|
||||||
if (!startAsset) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const assets = assetsSnapshot(await this.timelineManager.retrieveRange(startAsset, endAsset));
|
|
||||||
this.assetInteraction.setAssetSelectionCandidates(assets);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user