Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 12 additions & 27 deletions src/application/services/useNote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ interface UseNoteComposableState {
/**
* Creates/updates the note
*/
save: (content: NoteContent, parentId: NoteId | undefined) => Promise<void>;
save: (content: NoteContent, parentId: NoteId | undefined, currentNoteId: NoteId | null) => Promise<void>;

/**
* Returns list of tools used in note
Expand Down Expand Up @@ -141,12 +141,6 @@ export default function (options: UseNoteComposableOptions): UseNoteComposableSt

const route = useRoute();

/**
* Is there any note currently saving
* Used to prevent re-load note after draft is saved
*/
const isNoteSaving = ref<boolean>(false);

/**
* Note Title identifier
*/
Expand Down Expand Up @@ -202,6 +196,7 @@ export default function (options: UseNoteComposableOptions): UseNoteComposableSt
const response = await noteService.getNoteById(id);

note.value = response.note;
lastUpdateContent.value = response.note.content;
canEdit.value = response.accessRights.canEdit;
noteTools.value = response.tools;
parentNote.value = response.parentNote;
Expand Down Expand Up @@ -244,8 +239,9 @@ export default function (options: UseNoteComposableOptions): UseNoteComposableSt
* Saves the note
* @param content - Note content (Editor.js data)
* @param parentId - Id of the parent note. If null, then it's a root note
* @param currentNoteId - Id of the current note
*/
async function save(content: NoteContent, parentId: NoteId | undefined): Promise<void> {
async function save(content: NoteContent, parentId: NoteId | undefined, currentNoteId: NoteId | null): Promise<void> {
if (note.value === null) {
throw new Error('Note is not loaded yet');
}
Expand All @@ -255,9 +251,7 @@ export default function (options: UseNoteComposableOptions): UseNoteComposableSt
*/
const specifiedNoteTools = resolveToolsByContent(content);

isNoteSaving.value = true;

if (currentId.value === null) {
if (currentNoteId === null) {
/**
* @todo try-catch domain errors
*/
Expand Down Expand Up @@ -285,15 +279,16 @@ export default function (options: UseNoteComposableOptions): UseNoteComposableSt
*/
void getNoteHierarchy(noteCreated.id);
} else {
await noteService.updateNoteContentAndTools(currentId.value, content, specifiedNoteTools);
await noteService.updateNoteContentAndTools(currentNoteId, content, specifiedNoteTools);
}

/**
* Store just saved content in memory
* Store just saved content in memory only if the current note hasn't changed
* This prevents race conditions when switching between notes quickly
*/
lastUpdateContent.value = content;

isNoteSaving.value = false;
if (currentId.value === currentNoteId) {
lastUpdateContent.value = content;
}
}

/**
Expand Down Expand Up @@ -366,7 +361,7 @@ export default function (options: UseNoteComposableOptions): UseNoteComposableSt
}
}

watch(currentId, (newId, prevId) => {
watch(currentId, (newId, _prevId) => {
/**
* One note is open, user clicks on "+" to create another new note
* Clear existing note
Expand All @@ -377,16 +372,6 @@ export default function (options: UseNoteComposableOptions): UseNoteComposableSt
return;
}

const isDraftSaving = prevId === null && isNoteSaving.value;

/**
* Case for newly created note,
* we don't need to re-load it
*/
if (isDraftSaving) {
return;
}

void load(newId);
});

Expand Down
1 change: 0 additions & 1 deletion src/application/services/useNoteEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ export const useNoteEditor = function useNoteEditor(options: UseNoteEditorOption

const loadId = ++currentLoadId;

isEditorReady.value = false;
toolsUserConfigLoaded.value = false;

try {
Expand Down
17 changes: 13 additions & 4 deletions src/presentation/pages/Note.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
<Editor
v-if="isEditorReady"
ref="editor"
:key="id || 'new'"
v-bind="editorConfig"
@change="noteChanged"
/>
Expand All @@ -68,7 +69,7 @@ import { computed, ref, toRef, watch } from 'vue';
import { Button, Editor, PageBlock, VerticalMenu, type VerticalMenuItem } from '@codexteam/ui/vue';
import useNote from '@/application/services/useNote';
import { useRoute, useRouter } from 'vue-router';
import { NoteContent } from '@/domain/entities/Note';
import { NoteContent, type NoteId } from '@/domain/entities/Note';
import { useHead } from 'unhead';
import { useI18n } from 'vue-i18n';
import { makeElementScreenshot } from '@/infrastructure/utils/screenshot';
Expand Down Expand Up @@ -153,7 +154,13 @@ async function noteChanged(data: NoteContent): Promise<void> {
const editorElement = editor.value ? editor.value.element : null;

if (!isEmpty) {
await save(data, props.parentId);
/**
* Capture the current note id at the time of the call
* to avoid race conditions when fast switching between notes
*/
const noteIdAtCallTime = props.id;

await save(data, props.parentId, noteIdAtCallTime);
/**
* In case if we do not have note id, we can change its cover, and we need successful data for cover
* We need to do it after saving in case of note creation
Expand All @@ -169,8 +176,8 @@ async function noteChanged(data: NoteContent): Promise<void> {
paddingTop: '100px',
});
}
if (updatedNoteCover !== null && props.id !== null) {
await updateCover(props.id, updatedNoteCover);
if (updatedNoteCover !== null && noteIdAtCallTime !== null && noteIdAtCallTime === props.id) {
await updateCover(noteIdAtCallTime as NoteId, updatedNoteCover);
}
}
}
Expand Down Expand Up @@ -210,6 +217,8 @@ const verticalMenuItems = computed<VerticalMenuItem>(() => {
watch(
() => props.id,
() => {
isEditorReady.value = false;

/** If new child note is created, refresh editor with empty data */
if (props.id === null) {
useHead({
Expand Down
Loading