Skip to content

Commit 637ed75

Browse files
committed
chore: update
1 parent e39ffa9 commit 637ed75

File tree

1 file changed

+100
-36
lines changed

1 file changed

+100
-36
lines changed

src/editor-ext/taskTimer.ts

Lines changed: 100 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
WidgetType,
88
} from "@codemirror/view";
99
import { EditorState, Range, StateField } from "@codemirror/state";
10-
import { TFile, App, MetadataCache, editorInfoField } from "obsidian";
10+
import { TFile, App, MetadataCache, editorInfoField, editorViewField } from "obsidian";
1111
import { TaskTimerSettings } from "../common/setting-definition";
1212
import { TaskTimerMetadataDetector } from "../utils/TaskTimerMetadataDetector";
1313
import { TaskTimerManager, TimerState } from "../utils/TaskTimerManager";
@@ -138,42 +138,76 @@ class TaskTimerWidget extends WidgetType {
138138
if (!taskId) {
139139
const blockId = this.timerManager.generateBlockId(this.settings.blockRefPrefix);
140140

141-
// Get the active editor through the app
142-
const activeView = (window as any).app?.workspace?.getActiveViewOfType((window as any).app?.viewRegistry?.getViewCreatorByType("markdown"));
143-
const editor = activeView?.editor;
141+
// Get EditorView - try multiple methods
142+
let view = this.state.field(editorViewField, false);
144143

145-
console.log("[TaskTimer] Active view:", activeView);
146-
console.log("[TaskTimer] Editor:", editor);
144+
// If that doesn't work, try through the app
145+
if (!view) {
146+
const app = (window as any).app;
147+
const activeLeaf = app?.workspace?.activeLeaf;
148+
if (activeLeaf?.view?.editor?.cm) {
149+
view = activeLeaf.view.editor.cm;
150+
console.log("[TaskTimer] Got EditorView from activeLeaf");
151+
}
152+
}
153+
154+
console.log("[TaskTimer] EditorView:", view);
147155

148-
if (editor) {
156+
if (view) {
149157
const line = this.state.doc.lineAt(this.lineFrom);
150158
const lineText = line.text;
151-
const updatedText = lineText.trimEnd() + ` ^${blockId}`;
159+
const blockRef = ` ^${blockId}`;
152160

153161
console.log(`[TaskTimer] Inserting block ID at line ${line.number}: ^${blockId}`);
154162
console.log("[TaskTimer] Original text:", lineText);
155-
console.log("[TaskTimer] Updated text:", updatedText);
163+
console.log("[TaskTimer] Insertion position:", line.to);
156164

157165
try {
158-
// Use Obsidian's Editor API
159-
const lineNumber = line.number - 1;
160-
editor.replaceRange(updatedText,
161-
{ line: lineNumber, ch: 0 },
162-
{ line: lineNumber, ch: lineText.length }
163-
);
166+
// Use CodeMirror's dispatch to insert the block reference
167+
view.dispatch({
168+
changes: {
169+
from: line.to,
170+
insert: blockRef
171+
}
172+
});
164173

165174
// Update our local reference
166175
this.existingBlockId = blockId;
167176
taskId = `${this.filePath}#^${blockId}`;
177+
178+
// Force widget refresh after successful insertion
179+
setTimeout(() => {
180+
this.updateTimerState();
181+
this.refreshUI();
182+
}, 100);
168183
} catch (err) {
169-
console.error("[TaskTimer] Error replacing text:", err);
184+
console.error("[TaskTimer] Error dispatching change:", err);
170185
return;
171186
}
172187
} else {
173-
console.error("[TaskTimer] No editor available to insert block ID");
174-
// Try alternative approach
188+
console.error("[TaskTimer] No EditorView available");
189+
// Fallback: try to get editor from editorInfoField
175190
const editorInfo = this.state.field(editorInfoField);
176-
console.log("[TaskTimer] EditorInfo from state:", editorInfo);
191+
console.log("[TaskTimer] Trying editorInfo:", editorInfo);
192+
193+
if (editorInfo?.editor) {
194+
const line = this.state.doc.lineAt(this.lineFrom);
195+
const lineText = line.text;
196+
const updatedText = lineText.trimEnd() + ` ^${blockId}`;
197+
198+
try {
199+
editorInfo.editor.replaceRange(updatedText,
200+
{ line: line.number - 1, ch: 0 },
201+
{ line: line.number - 1, ch: lineText.length }
202+
);
203+
204+
this.existingBlockId = blockId;
205+
taskId = `${this.filePath}#^${blockId}`;
206+
} catch (err) {
207+
console.error("[TaskTimer] Fallback also failed:", err);
208+
return;
209+
}
210+
}
177211
return;
178212
}
179213
}
@@ -281,26 +315,56 @@ class TaskTimerWidget extends WidgetType {
281315
const elapsedMs = this.timerManager.completeTimer(taskId);
282316
const formattedDuration = TaskTimerFormatter.formatDuration(elapsedMs, this.settings.timeFormat);
283317

284-
// Get editor info to access editor
285-
const editorInfo = this.state.field(editorInfoField);
286-
if (!editorInfo?.editor) {
287-
console.warn("[TaskTimer] Cannot access editor");
318+
// Get EditorView to modify document
319+
let view = this.state.field(editorViewField, false);
320+
321+
// If that doesn't work, try through the app
322+
if (!view) {
323+
const app = (window as any).app;
324+
const activeLeaf = app?.workspace?.activeLeaf;
325+
if (activeLeaf?.view?.editor?.cm) {
326+
view = activeLeaf.view.editor.cm;
327+
console.log("[TaskTimer] Got EditorView from activeLeaf for completion");
328+
}
329+
}
330+
331+
if (view) {
332+
const line = this.state.doc.lineAt(this.lineFrom);
333+
const lineText = line.text;
334+
335+
// Create the updated text
336+
const updatedText = lineText
337+
.replace(/\[[ ]\]/, '[x]') // Mark as completed
338+
.replace(/\s*$/, ` (${formattedDuration})`); // Add duration at end
339+
340+
console.log("[TaskTimer] Completing task - original:", lineText);
341+
console.log("[TaskTimer] Completing task - updated:", updatedText);
342+
343+
try {
344+
// Use dispatch to replace the entire line
345+
view.dispatch({
346+
changes: {
347+
from: line.from,
348+
to: line.to,
349+
insert: updatedText
350+
}
351+
});
352+
} catch (err) {
353+
console.error("[TaskTimer] Error updating task:", err);
354+
// Try fallback
355+
const editorInfo = this.state.field(editorInfoField);
356+
if (editorInfo?.editor) {
357+
editorInfo.editor.replaceRange(updatedText,
358+
{ line: line.number - 1, ch: 0 },
359+
{ line: line.number - 1, ch: lineText.length }
360+
);
361+
}
362+
}
363+
} else {
364+
console.error("[TaskTimer] No view available to complete task");
288365
return;
289366
}
290367

291-
// Update the task line to mark as complete and add duration
292-
const lineText = this.state.doc.lineAt(this.lineFrom).text;
293-
const completedTaskText = lineText
294-
.replace(/\[[ ]\]/, '[x]') // Mark as completed
295-
.replace(/\s*$/, ` (${formattedDuration})`); // Add duration at end
296-
297-
// Apply the change to the document using the editor
298-
const line = this.state.doc.lineAt(this.lineFrom);
299-
editorInfo.editor.replaceRange(completedTaskText,
300-
{ line: line.number - 1, ch: 0 },
301-
{ line: line.number - 1, ch: line.text.length }
302-
);
303-
304368
this.stopRealtimeUpdates();
305369
this.updateTimerState();
306370
console.log(`[TaskTimer] Timer completed successfully: ${formattedDuration}`);

0 commit comments

Comments
 (0)