Inline DateGroupActionLib logic into asset-date-group-selection-aware (temp)
• Remove DateGroupActionLib dependency and inline all selection logic • Implement proper selection state predicates instead of placeholder true values • Move keyboard event handlers and selection logic directly into component
This commit is contained in:
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
import AssetDateGroupComp from '$lib/components/photos-page/asset-date-group-comp.svelte';
|
import AssetDateGroupComp from '$lib/components/photos-page/asset-date-group-comp.svelte';
|
||||||
import { DayGroup } from '$lib/managers/timeline-manager/day-group.svelte';
|
import { DayGroup } from '$lib/managers/timeline-manager/day-group.svelte';
|
||||||
import { onMount, type Snippet } from 'svelte';
|
import { assetsSnapshot, type Snippet } from '$lib/managers/timeline-manager/utils.svelte';
|
||||||
import { DateGroupActionLib } from './date-group-actions-lib.svelte';
|
import { searchStore } from '$lib/stores/search.svelte';
|
||||||
|
|
||||||
let { isUploading } = uploadAssetsStore;
|
let { isUploading } = uploadAssetsStore;
|
||||||
|
|
||||||
@@ -44,14 +44,20 @@
|
|||||||
onAssetOpen,
|
onAssetOpen,
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
const actionLib = new DateGroupActionLib();
|
let lastAssetMouseEvent: TimelineAsset | null = $state(null);
|
||||||
|
let shiftKeyIsDown = $state(false);
|
||||||
|
let isEmpty = $derived(timelineManager.isInitialized && timelineManager.months.length === 0);
|
||||||
|
|
||||||
onMount(() => {
|
$effect(() => {
|
||||||
actionLib.assetInteraction = assetInteraction;
|
if (!lastAssetMouseEvent || !lastAssetMouseEvent) {
|
||||||
actionLib.timelineManager = timelineManager;
|
assetInteraction.clearAssetSelectionCandidates();
|
||||||
actionLib.singleSelect = singleSelect;
|
}
|
||||||
actionLib.onSelect = onSelect;
|
if (shiftKeyIsDown && lastAssetMouseEvent) {
|
||||||
actionLib.onScrollToTop = onScrollToTop;
|
void selectAssetCandidates(lastAssetMouseEvent);
|
||||||
|
}
|
||||||
|
if (isEmpty) {
|
||||||
|
assetInteraction.clearMultiselect();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultAssetOpen = (dayGroup: DayGroup, asset: TimelineAsset) => {
|
const defaultAssetOpen = (dayGroup: DayGroup, asset: TimelineAsset) => {
|
||||||
@@ -72,7 +78,7 @@
|
|||||||
|
|
||||||
// called when clicking asset with shift key pressed or with mouse
|
// called when clicking asset with shift key pressed or with mouse
|
||||||
const handleAssetSelect = (dayGroup: DayGroup, asset: TimelineAsset) => {
|
const handleAssetSelect = (dayGroup: DayGroup, asset: TimelineAsset) => {
|
||||||
void actionLib.onSelectAssets(asset);
|
void onSelectAssets(asset);
|
||||||
|
|
||||||
const assetsInDayGroup = dayGroup.getAssets();
|
const assetsInDayGroup = dayGroup.getAssets();
|
||||||
const groupTitle = dayGroup.groupTitle;
|
const groupTitle = dayGroup.groupTitle;
|
||||||
@@ -95,14 +101,163 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSelectAsset = (asset: TimelineAsset) => {
|
||||||
|
if (!timelineManager.albumAssets.has(asset.id)) {
|
||||||
|
assetInteraction.selectAsset(asset);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onKeyDown = (event: KeyboardEvent) => {
|
||||||
|
if (searchStore.isSearchEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.key === 'Shift') {
|
||||||
|
event.preventDefault();
|
||||||
|
shiftKeyIsDown = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onKeyUp = (event: KeyboardEvent) => {
|
||||||
|
if (searchStore.isSearchEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.key === 'Shift') {
|
||||||
|
event.preventDefault();
|
||||||
|
shiftKeyIsDown = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleOnHover = (dayGroup: DayGroup, asset: TimelineAsset) => {
|
const handleOnHover = (dayGroup: DayGroup, asset: TimelineAsset) => {
|
||||||
if (assetInteraction.selectionActive) {
|
if (assetInteraction.selectionActive) {
|
||||||
actionLib.onSelectAssetCandidates(asset);
|
void selectAssetCandidates(asset);
|
||||||
}
|
}
|
||||||
|
lastAssetMouseEvent = asset;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDayGroupSelect = (dayGroup: DayGroup, assets: TimelineAsset[]) => {
|
||||||
|
const group = dayGroup.groupTitle;
|
||||||
|
if (assetInteraction.selectedGroup.has(group)) {
|
||||||
|
assetInteraction.removeGroupFromMultiselectGroup(group);
|
||||||
|
for (const asset of assets) {
|
||||||
|
assetInteraction.removeAssetFromMultiselectGroup(asset.id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assetInteraction.addGroupToMultiselectGroup(group);
|
||||||
|
for (const asset of assets) {
|
||||||
|
handleSelectAsset(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timelineManager.assetCount == assetInteraction.selectedAssets.length) {
|
||||||
|
isSelectingAllAssets.set(true);
|
||||||
|
} else {
|
||||||
|
isSelectingAllAssets.set(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSelectAssets = async (asset: TimelineAsset) => {
|
||||||
|
if (!asset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onSelect(asset);
|
||||||
|
|
||||||
|
if (singleSelect) {
|
||||||
|
onScrollToTop();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rangeSelection = assetInteraction.assetSelectionCandidates.length > 0;
|
||||||
|
const deselect = assetInteraction.hasSelectedAsset(asset.id);
|
||||||
|
|
||||||
|
// Select/deselect already loaded assets
|
||||||
|
if (deselect) {
|
||||||
|
for (const candidate of assetInteraction.assetSelectionCandidates) {
|
||||||
|
assetInteraction.removeAssetFromMultiselectGroup(candidate.id);
|
||||||
|
}
|
||||||
|
assetInteraction.removeAssetFromMultiselectGroup(asset.id);
|
||||||
|
} else {
|
||||||
|
for (const candidate of assetInteraction.assetSelectionCandidates) {
|
||||||
|
handleSelectAsset(candidate);
|
||||||
|
}
|
||||||
|
handleSelectAsset(asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
assetInteraction.clearAssetSelectionCandidates();
|
||||||
|
|
||||||
|
if (assetInteraction.assetSelectionStart && rangeSelection) {
|
||||||
|
let startBucket = timelineManager.getMonthGroupByAssetId(assetInteraction.assetSelectionStart.id);
|
||||||
|
let endBucket = timelineManager.getMonthGroupByAssetId(asset.id);
|
||||||
|
|
||||||
|
if (startBucket === null || endBucket === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select/deselect assets in range (start,end)
|
||||||
|
let started = false;
|
||||||
|
for (const monthGroup of timelineManager.months) {
|
||||||
|
if (monthGroup === endBucket) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (started) {
|
||||||
|
await timelineManager.loadMonthGroup(monthGroup.yearMonth);
|
||||||
|
for (const asset of monthGroup.assetsIterator()) {
|
||||||
|
if (deselect) {
|
||||||
|
assetInteraction.removeAssetFromMultiselectGroup(asset.id);
|
||||||
|
} else {
|
||||||
|
handleSelectAsset(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (monthGroup === startBucket) {
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update date group selection in range [start,end]
|
||||||
|
started = false;
|
||||||
|
for (const monthGroup of 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) => assetInteraction.hasSelectedAsset(a.id))) {
|
||||||
|
assetInteraction.addGroupToMultiselectGroup(dayGroupTitle);
|
||||||
|
} else {
|
||||||
|
assetInteraction.removeGroupFromMultiselectGroup(dayGroupTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (monthGroup === endBucket) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assetInteraction.setAssetSelectionStart(deselect ? null : asset);
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectAssetCandidates = async (endAsset: TimelineAsset) => {
|
||||||
|
if (!shiftKeyIsDown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startAsset = assetInteraction.assetSelectionStart;
|
||||||
|
if (!startAsset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const assets = assetsSnapshot(await timelineManager.retrieveRange(startAsset, endAsset));
|
||||||
|
assetInteraction.setAssetSelectionCandidates(assets);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:document onkeydown={actionLib.onKeyDown} onkeyup={actionLib.onKeyUp} />
|
<svelte:document onkeydown={onKeyDown} onkeyup={onKeyUp} />
|
||||||
|
|
||||||
<AssetDateGroupComp
|
<AssetDateGroupComp
|
||||||
{customLayout}
|
{customLayout}
|
||||||
@@ -112,13 +267,14 @@
|
|||||||
{showArchiveIcon}
|
{showArchiveIcon}
|
||||||
{monthGroup}
|
{monthGroup}
|
||||||
{timelineManager}
|
{timelineManager}
|
||||||
|
{onThumbnailClick}
|
||||||
{onScrollCompensation}
|
{onScrollCompensation}
|
||||||
onHover={handleOnHover}
|
onHover={handleOnHover}
|
||||||
onAssetOpen={handleOnAssetOpen}
|
onAssetOpen={handleOnAssetOpen}
|
||||||
onAssetSelect={handleAssetSelect}
|
onAssetSelect={handleAssetSelect}
|
||||||
onDayGroupSelect={actionLib.onDayGroupSelect}
|
onDayGroupSelect={handleDayGroupSelect}
|
||||||
isDayGroupSelected={(dayGroup: DayGroup) => true}
|
isDayGroupSelected={(dayGroup: DayGroup) => assetInteraction.selectedGroup.has(dayGroup.groupTitle)}
|
||||||
isAssetSelected={(asset) => true}
|
isAssetSelected={(asset) => assetInteraction.hasSelectedAsset(asset.id) || timelineManager.albumAssets.has(asset.id)}
|
||||||
isAssetSelectionCandidate={(asset) => true}
|
isAssetSelectionCandidate={(asset) => assetInteraction.hasSelectionCandidate(asset.id)}
|
||||||
isAssetDisabled={(asset) => true}
|
isAssetDisabled={(asset) => timelineManager.albumAssets.has(asset.id)}
|
||||||
></AssetDateGroupComp>
|
></AssetDateGroupComp>
|
||||||
|
|||||||
Reference in New Issue
Block a user