fix: confirm modal breaks cursor (#52)

* fix: confirm modal breaks cursor

* fix: formatting and debug log
This commit is contained in:
Jacob 2024-07-09 20:38:46 +12:00 committed by GitHub
parent 7f75b08e4d
commit 5b79425a50
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 66 additions and 6 deletions

48
src/confirm-modal.ts Normal file
View file

@ -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);
}
}
}

View file

@ -33,7 +33,7 @@ export default class SimpleTimeTrackerPlugin extends Plugin {
// Register the event to remove on unload // Register the event to remove on unload
component.registerEvent(renameEventRef); 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) i.addChild(component)
}); });

View file

@ -1,5 +1,6 @@
import {moment, App, MarkdownSectionInformation, ButtonComponent, TextComponent, TFile, MarkdownRenderer, Component, MarkdownRenderChild} from "obsidian"; import {moment, App, MarkdownSectionInformation, ButtonComponent, TextComponent, TFile, MarkdownRenderer, Component, MarkdownRenderChild} from "obsidian";
import {SimpleTimeTrackerSettings} from "./settings"; import {SimpleTimeTrackerSettings} from "./settings";
import { ConfirmModal } from "./confirm-modal";
export interface Tracker { export interface Tracker {
entries: Entry[]; entries: Entry[];
@ -43,7 +44,7 @@ export function loadTracker(json: string): Tracker {
type GetFile = () => string; 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"); element.addClass("simple-time-tracker-container");
// add start/stop controls // add start/stop controls
@ -86,7 +87,7 @@ export function displayTracker(tracker: Tracker, element: HTMLElement, getFile:
createEl("th")); createEl("th"));
for (let entry of orderedEntries(tracker.entries, settings)) 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 // add copy buttons
let buttons = element.createEl("div", {cls: "simple-time-tracker-bottom"}); 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; 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 entryRunning = getRunningEntry(tracker.entries) == entry;
let row = table.createEl("tr"); let row = table.createEl("tr");
@ -363,19 +364,30 @@ function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableEle
.setIcon("lucide-trash") .setIcon("lucide-trash")
.setDisabled(entryRunning) .setDisabled(entryRunning)
.onClick(async () => { .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; return;
} }
removeEntry(tracker.entries, entry); removeEntry(tracker.entries, entry);
await saveTracker(tracker, this.app, getFile(), getSectionInfo()); await saveTracker(tracker, this.app, getFile(), getSectionInfo());
}); });
if (entry.subEntries) { if (entry.subEntries) {
for (let sub of orderedEntries(entry.subEntries, settings)) 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<boolean> {
return new Promise((resolve) => {
const modal = new ConfirmModal(app, message, resolve);
modal.open();
});
}
function renderNameAsMarkdown(label: HTMLSpanElement, getFile: GetFile, component: Component): void { function renderNameAsMarkdown(label: HTMLSpanElement, getFile: GetFile, component: Component): void {
void MarkdownRenderer.renderMarkdown(label.innerHTML, label, getFile(), component); void MarkdownRenderer.renderMarkdown(label.innerHTML, label, getFile(), component);
// rendering wraps it in a paragraph // rendering wraps it in a paragraph