From b041d206c13c49b5f2ca7ac3f2afc167fb511c91 Mon Sep 17 00:00:00 2001 From: buttercat1791 Date: Tue, 26 Nov 2024 08:06:59 -0600 Subject: [PATCH] Improve event movement within the event tree It's still buggy, but it's better than before. --- src/lib/components/Preview.svelte | 47 ++++++++++------ src/lib/parser.ts | 90 +++++++++++++++---------------- 2 files changed, 75 insertions(+), 62 deletions(-) diff --git a/src/lib/components/Preview.svelte b/src/lib/components/Preview.svelte index fe28f9d..ab69da0 100644 --- a/src/lib/components/Preview.svelte +++ b/src/lib/components/Preview.svelte @@ -1,9 +1,11 @@ diff --git a/src/lib/parser.ts b/src/lib/parser.ts index ad369c0..0c0b0a8 100644 --- a/src/lib/parser.ts +++ b/src/lib/parser.ts @@ -277,7 +277,6 @@ export default class Pharos { */ getNearestSibling( targetDTag: string, - parentDTag: string, depth: number, direction: SiblingSearchDirection ): [string | null, string | null] { @@ -292,6 +291,12 @@ export default class Pharos { throw new Error(`The event indicated by #d:${targetDTag} does not exist at level ${depth} of the event tree.`); } + const parentDTag = this.getParent(targetDTag); + + if (!parentDTag) { + throw new Error(`The event indicated by #d:${targetDTag} does not have a parent.`); + } + const grandparentDTag = this.getParent(parentDTag); // If the target is the first node at its level and we're searching for a previous sibling, @@ -302,7 +307,7 @@ export default class Pharos { return [null, null]; } - return this.getNearestSibling(parentDTag, grandparentDTag!, depth - 1, direction); + return this.getNearestSibling(parentDTag, depth - 1, direction); } // If the target is the last node at its level and we're searching for a next sibling, @@ -313,7 +318,7 @@ export default class Pharos { return [null, null]; } - return this.getNearestSibling(parentDTag, grandparentDTag!, depth - 1, direction); + return this.getNearestSibling(parentDTag, depth - 1, direction); } // * Base case: There is an adjacent sibling at the same depth as the target. @@ -353,62 +358,55 @@ export default class Pharos { /** * Moves an event within the event tree. - * @param dTag The d tag of the event to be moved. - * @param oldParentDTag The d tag of the moved event's current parent. - * @param newParentDTag The d tag of the moved event's new parent. - * @param index The index at which to insert the event to be moved among the children of the new - * parent. - * @param insertAfter If true, the event will be inserted after the specified index, otherwise, - * it will be inserted immediately before the specified index. + * @param targetDTag The d tag of the event to be moved. + * @param destinationDTag The d tag another event, next to which the target will be placed. + * @param insertAfter If true, the target will be placed after the destination event, otherwise, + * it will be placed before the destination event. * @throws Throws an error if the parameters specify an invalid move. - * @remarks Both the old and new parent events must be kind 30040 index events. Moving the event - * within the tree changes the hash of several events, so the event tree will be regenerated when - * the consumer next invokes `getEvents()`. - */ - // TODO: Update this to work with two d tags and a direction. - moveEvent( - dTag: string, - oldParentDTag: string, - newParentDTag: string, - index?: number, - insertAfter: boolean = false - ): void { - const event = this.events.get(dTag); - if (!event) { - throw new Error(`No event found for #d:${dTag}.`); - } + * @remarks Moving the target event within the tree changes the hash of several events, so the + * event tree will be regenerated when the consumer next invokes `getEvents()`. + */ + moveEvent(targetDTag: string, destinationDTag: string, insertAfter: boolean = false): void { + const targetEvent = this.events.get(targetDTag); + const destinationEvent = this.events.get(destinationDTag); + const targetParent = this.getParent(targetDTag); + const destinationParent = this.getParent(destinationDTag); - if (this.eventToKindMap.get(oldParentDTag) !== 30040) { - throw new Error(`Old parent event #d:${oldParentDTag} is not an index event.`); + if (!targetEvent) { + throw new Error(`No event found for #d:${targetDTag}.`); } - if (this.eventToKindMap.get(newParentDTag) !== 30040) { - throw new Error(`New parent event #d:${newParentDTag} is not an index event.`); + if (!destinationEvent) { + throw new Error(`No event found for #d:${destinationDTag}.`); } - const oldParentMap = this.indexToChildEventsMap.get(oldParentDTag); - const newParentMap = this.indexToChildEventsMap.get(newParentDTag); + if (!targetParent) { + throw new Error(`The event indicated by #d:${targetDTag} does not have a parent.`); + } - if (!oldParentMap?.has(dTag)) { - throw new Error(`Event #d:${dTag} is not a child of parent #d:${oldParentDTag}.`); + if (!destinationParent) { + throw new Error(`The event indicated by #d:${destinationDTag} does not have a parent.`); } - // Remove the target event from the old parent. - oldParentMap?.delete(dTag); + // Remove the target from among the children of its current parent. + this.indexToChildEventsMap.get(targetParent)?.delete(targetDTag); - this.shouldUpdateEventTree = true; + // If necessary, remove the target event from among the children of its destination parent. + this.indexToChildEventsMap.get(destinationParent)?.delete(targetDTag); - if (index == null) { - newParentMap?.add(dTag); - return; - } + // Get the index of the destination event among the children of its parent. + const destinationIndex = Array.from(this.indexToChildEventsMap.get(destinationParent) ?? []) + .indexOf(destinationDTag); - // Add the target event to the new parent at the specified index. - const newParentChildren: string[] = Array.from(newParentMap || new Set()); - newParentChildren.splice(index + Number(insertAfter), 0, dTag); - this.indexToChildEventsMap.set(newParentDTag, new Set(newParentChildren)); + // Insert next to the index of the destination event, either before or after as specified by + // the insertAfter flag. + const destinationChildren = Array.from(this.indexToChildEventsMap.get(destinationParent) ?? []); + insertAfter + ? destinationChildren.splice(destinationIndex + 1, 0, targetDTag) + : destinationChildren.splice(destinationIndex, 0, targetDTag); + this.indexToChildEventsMap.set(destinationParent, new Set(destinationChildren)); - this.buildEventsByLevelMap(newParentDTag, 0); + this.shouldUpdateEventTree = true; } /**