From 5b79425a50b9c15d3f6624b6ecfef8ebfa80d330 Mon Sep 17 00:00:00 2001 From: Jacob <33708767+jacobtread@users.noreply.github.com> Date: Tue, 9 Jul 2024 20:38:46 +1200 Subject: [PATCH] fix: confirm modal breaks cursor (#52) * fix: confirm modal breaks cursor * fix: formatting and debug log --- src/confirm-modal.ts | 48 ++++++++++++++++++++++++++++++++++++++++++++ src/main.ts | 2 +- src/tracker.ts | 22 +++++++++++++++----- 3 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 src/confirm-modal.ts diff --git a/src/confirm-modal.ts b/src/confirm-modal.ts new file mode 100644 index 0000000..ee37fff --- /dev/null +++ b/src/confirm-modal.ts @@ -0,0 +1,48 @@ +import { App, Modal, Setting } from "obsidian"; + +export class ConfirmModal extends Modal { + // Message to show in the modal + message: string; + + // Callback to run on user choice + callback: (choice: boolean) => void; + + // Whether an option was picked + picked: boolean; + + constructor(app: App, message: string, callback: (choice: boolean) => void) { + super(app); + this.message = message; + this.callback = callback; + } + + onOpen(): void { + const { contentEl } = this; + contentEl.createEl("p", { text: this.message }); + + new Setting(contentEl) + .addButton((btn) => + btn + .setButtonText("Ok") + .setCta() + .onClick(() => { + this.picked = true; + this.close(); + this.callback(true); + }) + ) + .addButton((btn) => + btn.setButtonText("Cancel").onClick(() => { + this.picked = true; + this.close(); + this.callback(false); + }) + ); + } + + onClose(): void { + if (!this.picked) { + this.callback(false); + } + } +} diff --git a/src/main.ts b/src/main.ts index 23b1a92..1baeb49 100644 --- a/src/main.ts +++ b/src/main.ts @@ -33,7 +33,7 @@ export default class SimpleTimeTrackerPlugin extends Plugin { // Register the event to remove on unload component.registerEvent(renameEventRef); - displayTracker(tracker, e, getFile, () => i.getSectionInfo(e), this.settings, component); + displayTracker(this.app, tracker, e, getFile, () => i.getSectionInfo(e), this.settings, component); i.addChild(component) }); diff --git a/src/tracker.ts b/src/tracker.ts index 54bbb2f..f9e4750 100644 --- a/src/tracker.ts +++ b/src/tracker.ts @@ -1,5 +1,6 @@ import {moment, App, MarkdownSectionInformation, ButtonComponent, TextComponent, TFile, MarkdownRenderer, Component, MarkdownRenderChild} from "obsidian"; import {SimpleTimeTrackerSettings} from "./settings"; +import { ConfirmModal } from "./confirm-modal"; export interface Tracker { entries: Entry[]; @@ -43,7 +44,7 @@ export function loadTracker(json: string): Tracker { type GetFile = () => string; -export function displayTracker(tracker: Tracker, element: HTMLElement, getFile: GetFile, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings, component: MarkdownRenderChild): void { +export function displayTracker(app: App, tracker: Tracker, element: HTMLElement, getFile: GetFile, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings, component: MarkdownRenderChild): void { element.addClass("simple-time-tracker-container"); // add start/stop controls @@ -86,7 +87,7 @@ export function displayTracker(tracker: Tracker, element: HTMLElement, getFile: createEl("th")); for (let entry of orderedEntries(tracker.entries, settings)) - addEditableTableRow(tracker, entry, table, newSegmentNameBox, running, getFile, getSectionInfo, settings, 0, component); + addEditableTableRow(app, tracker, entry, table, newSegmentNameBox, running, getFile, getSectionInfo, settings, 0, component); // add copy buttons let buttons = element.createEl("div", {cls: "simple-time-tracker-bottom"}); @@ -306,7 +307,7 @@ function orderedEntries(entries: Entry[], settings: SimpleTimeTrackerSettings): return settings.reverseSegmentOrder ? entries.slice().reverse() : entries; } -function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableElement, newSegmentNameBox: TextComponent, trackerRunning: boolean, getFile: GetFile, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings, indent: number, component: MarkdownRenderChild): void { +function addEditableTableRow(app: App, tracker: Tracker, entry: Entry, table: HTMLTableElement, newSegmentNameBox: TextComponent, trackerRunning: boolean, getFile: GetFile, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings, indent: number, component: MarkdownRenderChild): void { let entryRunning = getRunningEntry(tracker.entries) == entry; let row = table.createEl("tr"); @@ -363,19 +364,30 @@ function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableEle .setIcon("lucide-trash") .setDisabled(entryRunning) .onClick(async () => { - if (!confirm("Are you sure you want to delete this entry?")) { + + const confirmed = await showConfirm(app, "Are you sure you want to delete this entry?") + + if (!confirmed) { return; } + removeEntry(tracker.entries, entry); await saveTracker(tracker, this.app, getFile(), getSectionInfo()); }); if (entry.subEntries) { for (let sub of orderedEntries(entry.subEntries, settings)) - addEditableTableRow(tracker, sub, table, newSegmentNameBox, trackerRunning, getFile, getSectionInfo, settings, indent + 1, component); + addEditableTableRow(app, tracker, sub, table, newSegmentNameBox, trackerRunning, getFile, getSectionInfo, settings, indent + 1, component); } } + function showConfirm(app: App, message: string): Promise { + return new Promise((resolve) => { + const modal = new ConfirmModal(app, message, resolve); + modal.open(); + }); +} + function renderNameAsMarkdown(label: HTMLSpanElement, getFile: GetFile, component: Component): void { void MarkdownRenderer.renderMarkdown(label.innerHTML, label, getFile(), component); // rendering wraps it in a paragraph