diff --git a/website/src/lib/components/Menu.svelte b/website/src/lib/components/Menu.svelte index 7cd47b8c..21f3e446 100644 --- a/website/src/lib/components/Menu.svelte +++ b/website/src/lib/components/Menu.svelte @@ -72,6 +72,7 @@ import { fileStateCollection } from '$lib/logic/file-state'; import { fileActionManager } from '$lib/logic/file-action-manager'; import { copied, selection } from '$lib/logic/selection'; + import { allHidden } from '$lib/logic/hidden'; const { distanceUnits, @@ -229,21 +230,21 @@ { - // if ($allHidden) { - // fileActions.setHiddenToSelection(false); - // } else { - // fileActions.setHiddenToSelection(true); - // } + if ($allHidden) { + fileActions.setHiddenToSelection(false); + } else { + fileActions.setHiddenToSelection(true); + } }} disabled={$selection.size == 0} > - + {/if} {#if $treeFileView} @@ -621,11 +622,11 @@ $treeFileView = !$treeFileView; e.preventDefault(); } else if (e.key === 'h' && (e.metaKey || e.ctrlKey)) { - // if ($allHidden) { - // fileActions.setHiddenToSelection(false); - // } else { - // fileActions.setHiddenToSelection(true); - // } + if ($allHidden) { + fileActions.setHiddenToSelection(false); + } else { + fileActions.setHiddenToSelection(true); + } e.preventDefault(); } else if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) { // if ($selection.size > 0) { diff --git a/website/src/lib/components/file-list/FileListNodeLabel.svelte b/website/src/lib/components/file-list/FileListNodeLabel.svelte index 49d239d0..551d1139 100644 --- a/website/src/lib/components/file-list/FileListNodeLabel.svelte +++ b/website/src/lib/components/file-list/FileListNodeLabel.svelte @@ -40,6 +40,7 @@ import { selection, copied, cut } from '$lib/logic/selection'; import { map } from '$lib/components/map/map'; import { fileActions, pasteSelection } from '$lib/logic/file-actions'; + import { allHidden } from '$lib/logic/hidden'; let { node, @@ -240,20 +241,20 @@ {/if} { - // if ($allHidden) { - // dbUtils.setHiddenToSelection(false); - // } else { - // dbUtils.setHiddenToSelection(true); - // } + if ($allHidden) { + fileActions.setHiddenToSelection(false); + } else { + fileActions.setHiddenToSelection(true); + } }} > - + {/if} diff --git a/website/src/lib/logic/file-actions.ts b/website/src/lib/logic/file-actions.ts index d1f21643..7a9bef1a 100644 --- a/website/src/lib/logic/file-actions.ts +++ b/website/src/lib/logic/file-actions.ts @@ -747,61 +747,61 @@ export const fileActions = { ); }, setStyleToSelection: (style: LineStyleExtension) => { - // if (get(selection).size === 0) { - // return; - // } - // applyGlobal((draft) => { - // applyToOrderedSelectedItemsFromFile((fileId, level, items) => { - // let file = draft.get(fileId); - // if (file && (level === ListLevel.FILE || level === ListLevel.TRACK)) { - // if (level === ListLevel.FILE) { - // file.setStyle(style); - // } else if (level === ListLevel.TRACK) { - // if (items.length === file.trk.length) { - // file.setStyle(style); - // } else { - // for (let item of items) { - // let trackIndex = (item as ListTrackItem).getTrackIndex(); - // file.trk[trackIndex].setStyle(style); - // } - // } - // } - // } - // }); - // }); + if (get(selection).size === 0) { + return; + } + fileActionManager.applyGlobal((draft) => { + selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => { + let file = draft.get(fileId); + if (file && (level === ListLevel.FILE || level === ListLevel.TRACK)) { + if (level === ListLevel.FILE) { + file.setStyle(style); + } else if (level === ListLevel.TRACK) { + if (items.length === file.trk.length) { + file.setStyle(style); + } else { + for (let item of items) { + let trackIndex = (item as ListTrackItem).getTrackIndex(); + file.trk[trackIndex].setStyle(style); + } + } + } + } + }); + }); }, setHiddenToSelection: (hidden: boolean) => { - // if (get(selection).size === 0) { - // return; - // } - // applyGlobal((draft) => { - // applyToOrderedSelectedItemsFromFile((fileId, level, items) => { - // let file = draft.get(fileId); - // if (file) { - // if (level === ListLevel.FILE) { - // file.setHidden(hidden); - // } else if (level === ListLevel.TRACK) { - // let trackIndices = items.map((item) => - // (item as ListTrackItem).getTrackIndex() - // ); - // file.setHidden(hidden, trackIndices); - // } else if (level === ListLevel.SEGMENT) { - // let trackIndices = [(items[0] as ListTrackSegmentItem).getTrackIndex()]; - // let segmentIndices = items.map((item) => - // (item as ListTrackSegmentItem).getSegmentIndex() - // ); - // file.setHidden(hidden, trackIndices, segmentIndices); - // } else if (level === ListLevel.WAYPOINTS) { - // file.setHiddenWaypoints(hidden); - // } else if (level === ListLevel.WAYPOINT) { - // let waypointIndices = items.map((item) => - // (item as ListWaypointItem).getWaypointIndex() - // ); - // file.setHiddenWaypoints(hidden, waypointIndices); - // } - // } - // }); - // }); + if (get(selection).size === 0) { + return; + } + fileActionManager.applyGlobal((draft) => { + selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => { + let file = draft.get(fileId); + if (file) { + if (level === ListLevel.FILE) { + file.setHidden(hidden); + } else if (level === ListLevel.TRACK) { + let trackIndices = items.map((item) => + (item as ListTrackItem).getTrackIndex() + ); + file.setHidden(hidden, trackIndices); + } else if (level === ListLevel.SEGMENT) { + let trackIndices = [(items[0] as ListTrackSegmentItem).getTrackIndex()]; + let segmentIndices = items.map((item) => + (item as ListTrackSegmentItem).getSegmentIndex() + ); + file.setHidden(hidden, trackIndices, segmentIndices); + } else if (level === ListLevel.WAYPOINTS) { + file.setHiddenWaypoints(hidden); + } else if (level === ListLevel.WAYPOINT) { + let waypointIndices = items.map((item) => + (item as ListWaypointItem).getWaypointIndex() + ); + file.setHiddenWaypoints(hidden, waypointIndices); + } + } + }); + }); }, deleteSelection: () => { if (get(selection).size === 0) { diff --git a/website/src/lib/logic/file-state.ts b/website/src/lib/logic/file-state.ts index 3714ce82..e4fbb389 100644 --- a/website/src/lib/logic/file-state.ts +++ b/website/src/lib/logic/file-state.ts @@ -31,10 +31,6 @@ export class GPXFileState { } this._file.set({ file, statistics }); - - // if (get(selection).hasAnyChildren(new ListFileItem(id))) { - // updateAllHidden(); - // } } }); } diff --git a/website/src/lib/logic/hidden.ts b/website/src/lib/logic/hidden.ts new file mode 100644 index 00000000..e00061f7 --- /dev/null +++ b/website/src/lib/logic/hidden.ts @@ -0,0 +1,67 @@ +import { get, writable, type Writable } from 'svelte/store'; +import { SelectedGPXFilesObserver, selection } from '$lib/logic/selection'; +import { fileStateCollection } from '$lib/logic/file-state'; +import { + ListFileItem, + ListTrackItem, + ListTrackSegmentItem, + ListWaypointItem, + ListWaypointsItem, +} from '$lib/components/file-list/file-list'; + +export class AllHidden { + private _value: Writable; + + constructor() { + this._value = writable(false); + new SelectedGPXFilesObserver(() => this.update()); + } + + subscribe(run: (value: boolean) => void, invalidate?: () => void) { + return this._value.subscribe(run, invalidate); + } + + update() { + let hidden = true; + selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => { + let file = fileStateCollection.getFile(fileId); + if (file) { + for (let item of items) { + if (!hidden) { + return; + } + + if (item instanceof ListFileItem) { + hidden = hidden && file._data.hidden === true; + } else if ( + item instanceof ListTrackItem && + item.getTrackIndex() < file.trk.length + ) { + hidden = hidden && file.trk[item.getTrackIndex()]._data.hidden === true; + } else if ( + item instanceof ListTrackSegmentItem && + item.getTrackIndex() < file.trk.length && + item.getSegmentIndex() < file.trk[item.getTrackIndex()].trkseg.length + ) { + hidden = + hidden && + file.trk[item.getTrackIndex()].trkseg[item.getSegmentIndex()]._data + .hidden === true; + } else if (item instanceof ListWaypointsItem) { + hidden = hidden && file._data.hiddenWpt === true; + } else if ( + item instanceof ListWaypointItem && + item.getWaypointIndex() < file.wpt.length + ) { + hidden = hidden && file.wpt[item.getWaypointIndex()]._data.hidden === true; + } + } + } + }); + if (hidden != get(this._value)) { + this._value.set(hidden); + } + } +} + +export const allHidden = new AllHidden(); diff --git a/website/src/lib/logic/selection.ts b/website/src/lib/logic/selection.ts index 5d3ad7a7..58d734c0 100644 --- a/website/src/lib/logic/selection.ts +++ b/website/src/lib/logic/selection.ts @@ -14,7 +14,6 @@ import { settings } from '$lib/logic/settings'; import type { GPXFile } from 'gpx'; import { get, writable, type Readable, type Writable } from 'svelte/store'; import { SelectionTreeType } from '$lib/logic/selection-tree'; -import { tick } from 'svelte'; export class Selection { private _selection: Writable; @@ -254,3 +253,33 @@ export function applyToOrderedItemsFromFile( } }); } + +export class SelectedGPXFilesObserver { + private _fileStateCollectionObserver: GPXFileStateCollectionObserver; + private _unsubscribes: Map void> = new Map(); + + constructor(onSelectedFileChange: () => void) { + this._unsubscribes = new Map(); + this._fileStateCollectionObserver = new GPXFileStateCollectionObserver( + (fileId, fileState) => { + this._unsubscribes.set( + fileId, + fileState.subscribe(() => { + if (get(selection).hasAnyChildren(new ListFileItem(fileId))) { + onSelectedFileChange(); + } + }) + ); + }, + (fileId) => { + this._unsubscribes.get(fileId)?.(); + this._unsubscribes.delete(fileId); + }, + () => { + this._unsubscribes.forEach((unsubscribe) => unsubscribe()); + this._unsubscribes.clear(); + } + ); + selection.subscribe(() => onSelectedFileChange()); + } +} diff --git a/website/src/lib/stores.ts b/website/src/lib/stores.ts index bb6805d7..561c98d9 100644 --- a/website/src/lib/stores.ts +++ b/website/src/lib/stores.ts @@ -1,68 +1,3 @@ -// import { writable, get, type Writable } from 'svelte/store'; - -// import { GPXFile, parseGPX, GPXStatistics } from 'gpx'; -// import { tick } from 'svelte'; -// import { i18n } from '$lib/i18n.svelte'; -// import type { GPXLayer } from '$lib/components/map/gpx-layer/GPXLayer'; -// import { dbUtils, fileObservers, getFile, getStatistics } from '$lib/db'; -// import { -// applyToOrderedSelectedItemsFromFile, -// selectFile, -// selection, -// } from '$lib/components/file-list/Selection'; -// import { -// ListFileItem, -// ListTrackItem, -// ListTrackSegmentItem, -// ListWaypointItem, -// ListWaypointsItem, -// } from '$lib/components/file-list/FileList'; -// import type { RoutingControls } from '$lib/components/toolbar/tools/routing/RoutingControls'; +// import { writable } from 'svelte/store'; // export const embedding = writable(false); -// export const selectFiles = writable<{ [key: string]: (fileId?: string) => void }>({}); - -// export const routingControls: Map = new Map(); - -// export const allHidden = writable(false); - -// export function updateAllHidden() { -// let hidden = true; -// applyToOrderedSelectedItemsFromFile((fileId, level, items) => { -// let file = getFile(fileId); -// if (file) { -// for (let item of items) { -// if (!hidden) { -// return; -// } - -// if (item instanceof ListFileItem) { -// hidden = hidden && file._data.hidden === true; -// } else if ( -// item instanceof ListTrackItem && -// item.getTrackIndex() < file.trk.length -// ) { -// hidden = hidden && file.trk[item.getTrackIndex()]._data.hidden === true; -// } else if ( -// item instanceof ListTrackSegmentItem && -// item.getTrackIndex() < file.trk.length && -// item.getSegmentIndex() < file.trk[item.getTrackIndex()].trkseg.length -// ) { -// hidden = -// hidden && -// file.trk[item.getTrackIndex()].trkseg[item.getSegmentIndex()]._data -// .hidden === true; -// } else if (item instanceof ListWaypointsItem) { -// hidden = hidden && file._data.hiddenWpt === true; -// } else if ( -// item instanceof ListWaypointItem && -// item.getWaypointIndex() < file.wpt.length -// ) { -// hidden = hidden && file.wpt[item.getWaypointIndex()]._data.hidden === true; -// } -// } -// } -// }); -// allHidden.set(hidden); -// } -// selection.subscribe(updateAllHidden);