mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-11 11:02:27 +08:00
feat(client): try a different approach to handling read-only threshold
feat(client): revert note_details.ts
This commit is contained in:
parent
f07ad03343
commit
caccbf49c0
@ -261,14 +261,33 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
|
||||
return true;
|
||||
}
|
||||
|
||||
const blob = await this.note.getBlob();
|
||||
if (!blob) {
|
||||
return false;
|
||||
// Store the initial decision about read-only status in the viewScope
|
||||
// This will be "remembered" until the viewScope is refreshed
|
||||
if (!this.viewScope) {
|
||||
this.resetViewScope();
|
||||
}
|
||||
|
||||
const sizeLimit = this.note.type === "text" ? options.getInt("autoReadonlySizeText") : options.getInt("autoReadonlySizeCode");
|
||||
// We've ensured viewScope exists by calling resetViewScope() if needed
|
||||
const viewScope = this.viewScope as ViewScope;
|
||||
|
||||
return sizeLimit && blob.contentLength > sizeLimit && !this.note.isLabelTruthy("autoReadOnlyDisabled");
|
||||
if (viewScope.readOnlyDecision === undefined) {
|
||||
const blob = await this.note.getBlob();
|
||||
if (!blob) {
|
||||
viewScope.readOnlyDecision = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
const sizeLimit = this.note.type === "text"
|
||||
? options.getInt("autoReadonlySizeText")
|
||||
: options.getInt("autoReadonlySizeCode");
|
||||
|
||||
viewScope.readOnlyDecision = Boolean(sizeLimit &&
|
||||
blob.contentLength > sizeLimit &&
|
||||
!this.note.isLabelTruthy("autoReadOnlyDisabled"));
|
||||
}
|
||||
|
||||
// Return the cached decision, which won't change until viewScope is reset
|
||||
return viewScope.readOnlyDecision || false;
|
||||
}
|
||||
|
||||
async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
|
||||
|
@ -48,6 +48,7 @@ export interface ViewScope {
|
||||
viewMode?: ViewMode;
|
||||
attachmentId?: string;
|
||||
readOnlyTemporarilyDisabled?: boolean;
|
||||
readOnlyDecision?: boolean;
|
||||
highlightsListPreviousVisible?: boolean;
|
||||
highlightsListTemporarilyHidden?: boolean;
|
||||
tocTemporarilyHidden?: boolean;
|
||||
|
@ -127,51 +127,12 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
|
||||
if (data === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if note is read-only before attempting to save
|
||||
const isReadOnlyBefore = await this.noteContext.isReadOnly();
|
||||
|
||||
// If the note is read-only due to size but user is still editing,
|
||||
// we need to temporarily disable read-only mode
|
||||
if (isReadOnlyBefore && !this.noteContext.viewScope?.readOnlyTemporarilyDisabled) {
|
||||
// Auto-enable temporary edit mode (same as "Edit this note" button)
|
||||
if (this.noteContext.viewScope) {
|
||||
this.noteContext.viewScope.readOnlyTemporarilyDisabled = true;
|
||||
appContext.triggerEvent("readOnlyTemporarilyDisabled", { noteContext: this.noteContext });
|
||||
}
|
||||
}
|
||||
|
||||
protectedSessionHolder.touchProtectedSessionIfNecessary(note);
|
||||
|
||||
try {
|
||||
await server.put(`notes/${noteId}/data`, data, this.componentId);
|
||||
this.getTypeWidget().dataSaved();
|
||||
|
||||
// Check if this save operation made the note cross the threshold
|
||||
if (!isReadOnlyBefore && (await this.noteContext.isReadOnly())) {
|
||||
// Note just became read-only after this save - enable temporary edit mode
|
||||
if (this.noteContext.viewScope) {
|
||||
this.noteContext.viewScope.readOnlyTemporarilyDisabled = true;
|
||||
appContext.triggerEvent("readOnlyTemporarilyDisabled", { noteContext: this.noteContext });
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
// If save failed because the note just became read-only,
|
||||
// enable temporary edit mode and try again
|
||||
if (!isReadOnlyBefore && (await this.noteContext.isReadOnly())) {
|
||||
if (this.noteContext.viewScope) {
|
||||
this.noteContext.viewScope.readOnlyTemporarilyDisabled = true;
|
||||
appContext.triggerEvent("readOnlyTemporarilyDisabled", { noteContext: this.noteContext });
|
||||
|
||||
// Try saving again with temporary edit mode enabled
|
||||
await server.put(`notes/${noteId}/data`, data, this.componentId);
|
||||
this.getTypeWidget().dataSaved();
|
||||
}
|
||||
} else {
|
||||
// For other errors, just rethrow
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
await server.put(`notes/${noteId}/data`, data, this.componentId);
|
||||
|
||||
this.getTypeWidget().dataSaved();
|
||||
});
|
||||
|
||||
appContext.addBeforeUnloadListener(this);
|
||||
@ -403,73 +364,9 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
|
||||
return this.spacedUpdate.isAllSavedAndTriggerUpdate();
|
||||
}
|
||||
|
||||
async readOnlyTemporarilyDisabledEvent({ noteContext }: EventData<"readOnlyTemporarilyDisabled">) {
|
||||
readOnlyTemporarilyDisabledEvent({ noteContext }: EventData<"readOnlyTemporarilyDisabled">) {
|
||||
if (this.isNoteContext(noteContext.ntxId)) {
|
||||
// Check if we're dealing with a text note/editor type
|
||||
const isTextNote = this.type === "editableText" || this.type === "readOnlyText";
|
||||
|
||||
if (isTextNote) {
|
||||
// Get current editor and selection before refresh
|
||||
const currentEditor = await this.noteContext?.getTextEditor();
|
||||
let cursorInfo = null;
|
||||
|
||||
if (currentEditor) {
|
||||
try {
|
||||
const selection = currentEditor.model.document.selection;
|
||||
if (selection) {
|
||||
const cursorPos = selection.getFirstPosition();
|
||||
if (cursorPos) {
|
||||
// Store minimal info about cursor position to restore later
|
||||
cursorInfo = {
|
||||
// Store paragraph index and character offset
|
||||
paraIndex: cursorPos.path[0] || 0,
|
||||
offset: cursorPos.offset
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore errors in getting selection
|
||||
}
|
||||
}
|
||||
|
||||
// Perform refresh to transition editor
|
||||
await this.refresh();
|
||||
|
||||
// Immediately attempt to restore cursor position without delay
|
||||
if (cursorInfo) {
|
||||
const newEditor = await this.noteContext?.getTextEditor();
|
||||
if (newEditor) {
|
||||
try {
|
||||
newEditor.model.change(writer => {
|
||||
const root = newEditor.model.document.getRoot();
|
||||
if (!root) return;
|
||||
|
||||
// Find the paragraph at the same index or closest available
|
||||
const targetParaIndex = Math.min(cursorInfo.paraIndex, root.childCount - 1);
|
||||
const paragraph = root.getChild(targetParaIndex);
|
||||
|
||||
if (paragraph) {
|
||||
// Use an explicit cast to access maxOffset
|
||||
const maxOffset = (paragraph as any).maxOffset || 0;
|
||||
const safeOffset = Math.min(cursorInfo.offset, maxOffset);
|
||||
|
||||
// Set cursor at the preserved position
|
||||
const position = writer.createPositionAt(paragraph, safeOffset);
|
||||
writer.setSelection(position);
|
||||
}
|
||||
});
|
||||
|
||||
// Focus editor to make cursor visible immediately
|
||||
newEditor.editing.view.focus();
|
||||
} catch (e) {
|
||||
// Silently fail if we can't restore cursor
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not a text editor, just do a regular refresh
|
||||
await this.refresh();
|
||||
}
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user