Refine Journals UI and harden entry toggle logic

- Implemented 3-state (View/Eye/Save) toggle in journal entry header with Lucide icons.
- Hardened change detection logic using Svelte 5 .by for reliable UI updates.
- Improved header responsiveness and scaling across device sizes.
- Commented out experimental CodeMirror toolbar to maintain stability while keeping the helper code for reference.
This commit is contained in:
Scott Idem
2026-01-08 15:38:28 -05:00
parent 4c8f09e588
commit dd0390a5dd
2 changed files with 66 additions and 144 deletions

View File

@@ -1,35 +1,30 @@
import type { EditorView } from '@codemirror/view';
/**
* Wraps the current selection in CodeMirror with the given prefix and suffix.
*/
export function wrapSelection(view: EditorView, prefix: string, suffix: string = prefix) {
if (!view) return;
const { state, dispatch } = view;
const changes = state.changeByRange((range) => {
const selectedText = state.doc.sliceString(range.from, range.to);
export function wrapSelection(view: any, prefix: string, suffix: string = prefix) {
if (!view || view.updateInProgress) return;
const { state } = view;
view.dispatch(state.changeByRange((range: any) => {
return {
changes: [
{ from: range.from, insert: prefix },
{ from: range.to, insert: suffix }
{from: range.from, insert: prefix},
{from: range.to, insert: suffix}
],
range: {
from: range.from + prefix.length,
to: range.to + prefix.length
}
range: range.constructor.range(range.from + prefix.length, range.to + prefix.length)
};
});
dispatch(state.update(changes, { scrollIntoView: true, userEvent: 'input' }));
}));
view.focus();
}
/**
* Inserts a prefix at the start of each line in the selection (e.g., for lists or blockquotes).
*/
export function toggleLinePrefix(view: EditorView, prefix: string) {
if (!view) return;
const { state, dispatch } = view;
const changes = state.changeByRange((range) => {
export function toggleLinePrefix(view: any, prefix: string) {
if (!view || view.updateInProgress) return;
const { state } = view;
view.dispatch(state.changeByRange((range: any) => {
const lines = [];
for (let pos = range.from; pos <= range.to; ) {
const line = state.doc.lineAt(pos);
@@ -38,7 +33,6 @@ export function toggleLinePrefix(view: EditorView, prefix: string) {
}
const isAlreadyPrefixed = lines.every(l => l.text.startsWith(prefix));
const lineChanges = lines.map(l => {
if (isAlreadyPrefixed) {
return { from: l.from, to: l.from + prefix.length, insert: '' };
@@ -47,14 +41,13 @@ export function toggleLinePrefix(view: EditorView, prefix: string) {
}
});
const newFrom = range.from + (isAlreadyPrefixed ? -prefix.length : prefix.length);
const newTo = range.to + (isAlreadyPrefixed ? (-prefix.length * lines.length) : (prefix.length * lines.length));
return {
changes: lineChanges,
range: {
from: range.from + (isAlreadyPrefixed ? -prefix.length : prefix.length),
to: range.to + (isAlreadyPrefixed ? -prefix.length * lines.length : prefix.length * lines.length)
}
range: range.constructor.range(newFrom, Math.max(newFrom, newTo))
};
});
dispatch(state.update(changes, { scrollIntoView: true, userEvent: 'input' }));
}));
view.focus();
}
}