From 541e6a9768919c62baa5e33aeb321fd4d134c17a Mon Sep 17 00:00:00 2001 From: Caleb Owens Date: Wed, 19 Jun 2024 12:01:28 +0200 Subject: [PATCH] Refactor dropzone manager --- .../lib/dragging/reorderDropzoneManager.ts | 141 ++++++++++-------- 1 file changed, 76 insertions(+), 65 deletions(-) diff --git a/app/src/lib/dragging/reorderDropzoneManager.ts b/app/src/lib/dragging/reorderDropzoneManager.ts index da7e79bf9..d89b9ffbb 100644 --- a/app/src/lib/dragging/reorderDropzoneManager.ts +++ b/app/src/lib/dragging/reorderDropzoneManager.ts @@ -2,35 +2,18 @@ import { DraggableCommit } from '$lib/dragging/draggables'; import type { BranchController } from '$lib/vbranches/branchController'; import type { Branch, Commit } from '$lib/vbranches/types'; -/** - * This class is used to determine how far a commit has been drag and dropped. - * - * We expect the dropzones to be in the following order: - * - * ``` - * const indexer = new ReorderDropzoneIndexer(commits); - * - * - * - * - * - * - * ``` - */ - // Exported for type access only export class ReorderDropzone { constructor( private branchController: BranchController, private branch: Branch, - private index: number, - private indexer: ReorderDropzoneManager + private entry: Entry ) {} accepts(data: any) { if (!(data instanceof DraggableCommit)) return false; if (data.branchId !== this.branch.id) return false; - if (this.indexer.dropzoneCommitOffset(this.index, data.commit.id) === 0) return false; + if (this.entry.distanceToOtherCommit(data.commit.id) === 0) return false; return true; } @@ -39,71 +22,32 @@ export class ReorderDropzone { if (!(data instanceof DraggableCommit)) return; if (data.branchId !== this.branch.id) return; - const offset = this.indexer.dropzoneCommitOffset(this.index, data.commit.id); + const offset = this.entry.distanceToOtherCommit(data.commit.id); this.branchController.reorderCommit(this.branch.id, data.commit.id, offset); } } export class ReorderDropzoneManager { - private dropzoneIndexes = new Map(); - private commitIndexes = new Map(); + private indexer: Indexer; constructor( private branchController: BranchController, private branch: Branch, commits: Commit[] ) { - this.dropzoneIndexes.set('top', 0); - - commits.forEach((commit, index) => { - this.dropzoneIndexes.set(commit.id, index + 1); - this.commitIndexes.set(commit.id, index); - }); + this.indexer = new Indexer(commits); } get topDropzone() { - const index = this.dropzoneIndexes.get('top') ?? 0; + const entry = this.indexer.get('top'); - return new ReorderDropzone(this.branchController, this.branch, index, this); + return new ReorderDropzone(this.branchController, this.branch, entry); } dropzoneBelowCommit(commitId: string) { - const index = this.dropzoneIndexes.get(commitId); + const entry = this.indexer.get(commitId); - if (index === undefined) { - throw new Error(`Commit ${commitId} not found in dropzoneIndexes`); - } - - return new ReorderDropzone(this.branchController, this.branch, index, this); - } - - commitIndex(commitId: string) { - const index = this.commitIndexes.get(commitId); - - if (index === undefined) { - throw new Error(`Commit ${commitId} not found in commitIndexes`); - } - - return index; - } - - /** - * A negative offset means the commit has been dragged up, and a positive offset means the commit has been dragged down. - */ - dropzoneCommitOffset(dropzoneIndex: number, commitId: string) { - const commitIndex = this.commitIndexes.get(commitId); - - if (commitIndex === undefined) { - throw new Error(`Commit ${commitId} not found in commitIndexes`); - } - - const offset = dropzoneIndex - commitIndex; - - if (offset > 0) { - return offset - 1; - } else { - return offset; - } + return new ReorderDropzone(this.branchController, this.branch, entry); } } @@ -114,3 +58,70 @@ export class ReorderDropzoneManagerFactory { return new ReorderDropzoneManager(this.branchController, branch, commits); } } + +// Private classes used to calculate distances between commtis +class Indexer { + private dropzoneIndexes = new Map(); + private commitIndexes = new Map(); + + constructor(commits: Commit[]) { + this.dropzoneIndexes.set('top', 0); + + commits.forEach((commit, index) => { + this.dropzoneIndexes.set(commit.id, index + 1); + this.commitIndexes.set(commit.id, index); + }); + } + + get(key: string) { + const index = this.getIndex(key); + + return new Entry(this.commitIndexes, index); + } + + private getIndex(key: string) { + if (key === 'top') { + return this.dropzoneIndexes.get(key) ?? 0; + } else { + const index = this.dropzoneIndexes.get(key); + + if (index === undefined) { + throw new Error(`Commit ${key} not found in dropzoneIndexes`); + } + + return index; + } + } +} + +class Entry { + constructor( + private commitIndexes: Map, + private index: number + ) {} + + /** + * A negative offset means the commit has been dragged up, and a positive offset means the commit has been dragged down. + */ + distanceToOtherCommit(commitId: string) { + const commitIndex = this.commitIndex(commitId); + + const offset = this.index - commitIndex; + + if (offset > 0) { + return offset - 1; + } else { + return offset; + } + } + + private commitIndex(commitId: string) { + const index = this.commitIndexes.get(commitId); + + if (index === undefined) { + throw new Error(`Commit ${commitId} not found in commitIndexes`); + } + + return index; + } +}