diff --git a/website/src/lib/logic/file-action-manager.ts b/website/src/lib/logic/file-action-manager.ts index 63b19050..3df1d179 100644 --- a/website/src/lib/logic/file-action-manager.ts +++ b/website/src/lib/logic/file-action-manager.ts @@ -15,6 +15,7 @@ import { type Unsubscriber, type Writable, } from 'svelte/store'; +import { selection } from '$lib/logic/selection'; const MAX_PATCHES = 100; @@ -150,7 +151,7 @@ export class FileActionManager { .filter((file) => file !== undefined) as GPXFile[]; updatedFileIds = updatedFiles.map((file) => file._data.id); - // updateSelection(updatedFiles, deletedFileIds); + selection.update(updatedFiles, deletedFileIds); // @ts-ignore return db.transaction('rw', db.fileids, db.files, async () => { diff --git a/website/src/lib/logic/file-actions.ts b/website/src/lib/logic/file-actions.ts index 99c95abb..9783ed56 100644 --- a/website/src/lib/logic/file-actions.ts +++ b/website/src/lib/logic/file-actions.ts @@ -28,6 +28,7 @@ import { type WaypointType, } from 'gpx'; import { get } from 'svelte/store'; +import { settings } from '$lib/logic/settings'; // Generate unique file ids, different from the ones in the database export function getFileIds(n: number) { @@ -67,7 +68,7 @@ export function createFile() { fileActions.add(file); // selectFileWhenLoaded(file._data.id); - tool.current = Tool.ROUTING; + currentTool.set(Tool.ROUTING); } export function triggerFileInput() { @@ -143,59 +144,59 @@ export const fileActions = { return ids; }, duplicateSelection: () => { - // if (get(selection).size === 0) { - // return; - // } - // fileActionManager.applyGlobal((draft) => { - // let ids = getFileIds(get(settings.fileOrder).length); - // let index = 0; - // applyToOrderedSelectedItemsFromFile((fileId, level, items) => { - // if (level === ListLevel.FILE) { - // let file = getFile(fileId); - // if (file) { - // let newFile = file.clone(); - // newFile._data.id = ids[index++]; - // draft.set(newFile._data.id, freeze(newFile)); - // } - // } else { - // let file = draft.get(fileId); - // if (file) { - // if (level === ListLevel.TRACK) { - // for (let item of items) { - // let trackIndex = (item as ListTrackItem).getTrackIndex(); - // file.replaceTracks(trackIndex + 1, trackIndex, [ - // file.trk[trackIndex].clone(), - // ]); - // } - // } else if (level === ListLevel.SEGMENT) { - // for (let item of items) { - // let trackIndex = (item as ListTrackSegmentItem).getTrackIndex(); - // let segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex(); - // file.replaceTrackSegments( - // trackIndex, - // segmentIndex + 1, - // segmentIndex, - // [file.trk[trackIndex].trkseg[segmentIndex].clone()] - // ); - // } - // } else if (level === ListLevel.WAYPOINTS) { - // file.replaceWaypoints( - // file.wpt.length, - // file.wpt.length - 1, - // file.wpt.map((wpt) => wpt.clone()) - // ); - // } else if (level === ListLevel.WAYPOINT) { - // for (let item of items) { - // let waypointIndex = (item as ListWaypointItem).getWaypointIndex(); - // file.replaceWaypoints(waypointIndex + 1, waypointIndex, [ - // file.wpt[waypointIndex].clone(), - // ]); - // } - // } - // } - // } - // }); - // }); + if (get(selection).size === 0) { + return; + } + fileActionManager.applyGlobal((draft) => { + let ids = getFileIds(get(settings.fileOrder).length); + let index = 0; + selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => { + if (level === ListLevel.FILE) { + let file = fileStateCollection.getFile(fileId); + if (file) { + let newFile = file.clone(); + newFile._data.id = ids[index++]; + draft.set(newFile._data.id, freeze(newFile)); + } + } else { + let file = draft.get(fileId); + if (file) { + if (level === ListLevel.TRACK) { + for (let item of items) { + let trackIndex = (item as ListTrackItem).getTrackIndex(); + file.replaceTracks(trackIndex + 1, trackIndex, [ + file.trk[trackIndex].clone(), + ]); + } + } else if (level === ListLevel.SEGMENT) { + for (let item of items) { + let trackIndex = (item as ListTrackSegmentItem).getTrackIndex(); + let segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex(); + file.replaceTrackSegments( + trackIndex, + segmentIndex + 1, + segmentIndex, + [file.trk[trackIndex].trkseg[segmentIndex].clone()] + ); + } + } else if (level === ListLevel.WAYPOINTS) { + file.replaceWaypoints( + file.wpt.length, + file.wpt.length - 1, + file.wpt.map((wpt) => wpt.clone()) + ); + } else if (level === ListLevel.WAYPOINT) { + for (let item of items) { + let waypointIndex = (item as ListWaypointItem).getWaypointIndex(); + file.replaceWaypoints(waypointIndex + 1, waypointIndex, [ + file.wpt[waypointIndex].clone(), + ]); + } + } + } + } + }); + }); }, addNewTrack: (fileId: string) => { fileActionManager.applyToFile(fileId, (file) => @@ -801,44 +802,44 @@ export const fileActions = { // }); }, deleteSelection: () => { - // if (get(selection).size === 0) { - // return; - // } - // applyGlobal((draft) => { - // applyToOrderedSelectedItemsFromFile((fileId, level, items) => { - // if (level === ListLevel.FILE) { - // draft.delete(fileId); - // } else { - // let file = draft.get(fileId); - // if (file) { - // if (level === ListLevel.TRACK) { - // for (let item of items) { - // let trackIndex = (item as ListTrackItem).getTrackIndex(); - // file.replaceTracks(trackIndex, trackIndex, []); - // } - // } else if (level === ListLevel.SEGMENT) { - // for (let item of items) { - // let trackIndex = (item as ListTrackSegmentItem).getTrackIndex(); - // let segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex(); - // file.replaceTrackSegments( - // trackIndex, - // segmentIndex, - // segmentIndex, - // [] - // ); - // } - // } else if (level === ListLevel.WAYPOINTS) { - // file.replaceWaypoints(0, file.wpt.length - 1, []); - // } else if (level === ListLevel.WAYPOINT) { - // for (let item of items) { - // let waypointIndex = (item as ListWaypointItem).getWaypointIndex(); - // file.replaceWaypoints(waypointIndex, waypointIndex, []); - // } - // } - // } - // } - // }); - // }); + if (get(selection).size === 0) { + return; + } + fileActionManager.applyGlobal((draft) => { + selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => { + if (level === ListLevel.FILE) { + draft.delete(fileId); + } else { + let file = draft.get(fileId); + if (file) { + if (level === ListLevel.TRACK) { + for (let item of items) { + let trackIndex = (item as ListTrackItem).getTrackIndex(); + file.replaceTracks(trackIndex, trackIndex, []); + } + } else if (level === ListLevel.SEGMENT) { + for (let item of items) { + let trackIndex = (item as ListTrackSegmentItem).getTrackIndex(); + let segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex(); + file.replaceTrackSegments( + trackIndex, + segmentIndex, + segmentIndex, + [] + ); + } + } else if (level === ListLevel.WAYPOINTS) { + file.replaceWaypoints(0, file.wpt.length - 1, []); + } else if (level === ListLevel.WAYPOINT) { + for (let item of items) { + let waypointIndex = (item as ListWaypointItem).getWaypointIndex(); + file.replaceWaypoints(waypointIndex, waypointIndex, []); + } + } + } + } + }); + }); }, addElevationToSelection: async (map: mapboxgl.Map) => { // if (get(selection).size === 0) { @@ -909,14 +910,14 @@ export const fileActions = { // }); }, deleteSelectedFiles: () => { - // if (get(selection).size === 0) { - // return; - // } - // applyGlobal((draft) => { - // applyToOrderedSelectedItemsFromFile((fileId, level, items) => { - // draft.delete(fileId); - // }); - // }); + if (get(selection).size === 0) { + return; + } + fileActionManager.applyGlobal((draft) => { + selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => { + draft.delete(fileId); + }); + }); }, deleteAllFiles: () => { fileActionManager.applyGlobal((draft) => { diff --git a/website/src/lib/logic/selection.ts b/website/src/lib/logic/selection.ts index a7878ffa..3f0db604 100644 --- a/website/src/lib/logic/selection.ts +++ b/website/src/lib/logic/selection.ts @@ -9,7 +9,7 @@ import { sortItems, ListWaypointsItem, } from '$lib/components/file-list/file-list'; -import { fileStateCollection } from '$lib/logic/file-state'; +import { fileStateCollection, GPXFileStateCollectionObserver } from '$lib/logic/file-state'; import { settings } from '$lib/logic/settings'; import type { GPXFile } from 'gpx'; import { get, writable, type Readable, type Writable } from 'svelte/store'; @@ -111,60 +111,59 @@ export class Selection { } update(updatedFiles: GPXFile[], deletedFileIds: string[]) { - // TODO do it the other way around: get all selected items, and check if they still exist? - // let removedItems: ListItem[] = []; - // applyToOrderedItemsFromFile(selection.value.getSelected(), (fileId, level, items) => { - // let file = updatedFiles.find((file) => file._data.id === fileId); - // if (file) { - // items.forEach((item) => { - // if (item instanceof ListTrackItem) { - // let newTrackIndex = file.trk.findIndex( - // (track) => track._data.trackIndex === item.getTrackIndex() - // ); - // if (newTrackIndex === -1) { - // removedItems.push(item); - // } - // } else if (item instanceof ListTrackSegmentItem) { - // let newTrackIndex = file.trk.findIndex( - // (track) => track._data.trackIndex === item.getTrackIndex() - // ); - // if (newTrackIndex === -1) { - // removedItems.push(item); - // } else { - // let newSegmentIndex = file.trk[newTrackIndex].trkseg.findIndex( - // (segment) => segment._data.segmentIndex === item.getSegmentIndex() - // ); - // if (newSegmentIndex === -1) { - // removedItems.push(item); - // } - // } - // } else if (item instanceof ListWaypointItem) { - // let newWaypointIndex = file.wpt.findIndex( - // (wpt) => wpt._data.index === item.getWaypointIndex() - // ); - // if (newWaypointIndex === -1) { - // removedItems.push(item); - // } - // } - // }); - // } else if (deletedFileIds.includes(fileId)) { - // items.forEach((item) => { - // removedItems.push(item); - // }); - // } - // }); - // if (removedItems.length > 0) { - // selection.update(($selection) => { - // removedItems.forEach((item) => { - // if (item instanceof ListFileItem) { - // $selection.deleteChild(item.getFileId()); - // } else { - // $selection.set(item, false); - // } - // }); - // return $selection; - // }); - // } + let removedItems: ListItem[] = []; + applyToOrderedItemsFromFile(get(this._selection).getSelected(), (fileId, level, items) => { + let file = updatedFiles.find((file) => file._data.id === fileId); + if (file) { + items.forEach((item) => { + if (item instanceof ListTrackItem) { + let newTrackIndex = file.trk.findIndex( + (track) => track._data.trackIndex === item.getTrackIndex() + ); + if (newTrackIndex === -1) { + removedItems.push(item); + } + } else if (item instanceof ListTrackSegmentItem) { + let newTrackIndex = file.trk.findIndex( + (track) => track._data.trackIndex === item.getTrackIndex() + ); + if (newTrackIndex === -1) { + removedItems.push(item); + } else { + let newSegmentIndex = file.trk[newTrackIndex].trkseg.findIndex( + (segment) => segment._data.segmentIndex === item.getSegmentIndex() + ); + if (newSegmentIndex === -1) { + removedItems.push(item); + } + } + } else if (item instanceof ListWaypointItem) { + let newWaypointIndex = file.wpt.findIndex( + (wpt) => wpt._data.index === item.getWaypointIndex() + ); + if (newWaypointIndex === -1) { + removedItems.push(item); + } + } + }); + } else if (deletedFileIds.includes(fileId)) { + items.forEach((item) => { + removedItems.push(item); + }); + } + }); + if (removedItems.length > 0) { + this._selection.update(($selection) => { + removedItems.forEach((item) => { + if (item instanceof ListFileItem) { + $selection.deleteChild(item.getFileId()); + } else { + $selection.set(item, false); + } + }); + return $selection; + }); + } } getOrderedSelection(reverse: boolean = false): ListItem[] {