diff --git a/appinfo/routes.php b/appinfo/routes.php index 1c43732bc..90e673896 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -43,6 +43,12 @@ 'url' => '/notes/undo', 'verb' => 'POST', ], + [ + 'name' => 'notes#autotitle', + 'url' => '/notes/{id}/autotitle', + 'verb' => 'PUT', + 'requirements' => ['id' => '\d+'], + ], [ 'name' => 'notes#update', 'url' => '/notes/{id}', diff --git a/lib/Controller/NotesController.php b/lib/Controller/NotesController.php index f99123a4b..98775937d 100644 --- a/lib/Controller/NotesController.php +++ b/lib/Controller/NotesController.php @@ -79,7 +79,7 @@ public function index(int $pruneBefore = 0) : JSONResponse { return $note->getData([ 'content' ]); } }, $data['notes']); - if ($lastViewedNote) { + if ($lastViewedNote && !$pruneBefore) { // check if note exists try { $this->notesService->get($userId, $lastViewedNote); @@ -191,14 +191,26 @@ public function undo( /** * @NoAdminRequired */ - public function update(int $id, string $content, bool $autotitle) : JSONResponse { - return $this->helper->handleErrorResponse(function () use ($id, $content, $autotitle) { + public function autotitle(int $id) : JSONResponse { + return $this->helper->handleErrorResponse(function () use ($id) { $note = $this->notesService->get($this->helper->getUID(), $id); - $note->setContent($content); - if ($autotitle) { - $title = $this->notesService->getTitleFromContent($content); - $note->setTitle($title); + $oldTitle = $note->getTitle(); + $newTitle = $this->notesService->getTitleFromContent($note->getContent()); + if ($oldTitle !== $newTitle) { + $note->setTitle($newTitle); } + return $note->getTitle(); + }); + } + + + /** + * @NoAdminRequired + */ + public function update(int $id, string $content) : JSONResponse { + return $this->helper->handleErrorResponse(function () use ($id, $content) { + $note = $this->notesService->get($this->helper->getUID(), $id); + $note->setContent($content); return $note->getData(); }); } diff --git a/src/App.vue b/src/App.vue index cc4378f26..c6d0f1d52 100644 --- a/src/App.vue +++ b/src/App.vue @@ -180,7 +180,9 @@ export default { if (availableNotes.length > 0) { this.routeToNote(availableNotes[0].id) } else { - this.$router.push({ name: 'welcome' }) + if (this.$route.name !== 'welcome') { + this.$router.push({ name: 'welcome' }) + } } }, diff --git a/src/NotesService.js b/src/NotesService.js index 2feca408c..a20a5a973 100644 --- a/src/NotesService.js +++ b/src/NotesService.js @@ -167,7 +167,7 @@ export const createNote = category => { function _updateNote(note) { return axios - .put(url('/notes/' + note.id), { content: note.content, autotitle: note.autotitle }) + .put(url('/notes/' + note.id), { content: note.content }) .then(response => { const updated = response.data note.saveError = false @@ -186,6 +186,18 @@ function _updateNote(note) { }) } +export const autotitleNote = noteId => { + return axios + .put(url('/notes/' + noteId + '/autotitle')) + .then((response) => { + store.commit('setNoteAttribute', { noteId: noteId, attribute: 'title', value: response.data }) + }) + .catch(err => { + console.error(err) + handleSyncError(t('notes', 'Updating title for note {id} has failed.', { id: noteId }), err) + }) +} + export const undoDeleteNote = (note) => { return axios .post(url('/notes/undo'), note) diff --git a/src/components/Note.vue b/src/components/Note.vue index 68b8d5584..69111ef08 100644 --- a/src/components/Note.vue +++ b/src/components/Note.vue @@ -20,19 +20,12 @@ > {{ t('notes', 'Details') }} - - {{ t('notes', 'Preview') }} - - - {{ t('notes', 'Edit') }} + {{ preview ? t('notes', 'Edit') : t('notes', 'Preview') }} { this.refreshTimer = null this.refreshNote() - }, 10000) + }, config.interval.note.refresh * 1000) }, refreshNote() { @@ -260,18 +258,36 @@ export default { ...this.note, content: newContent, unsaved: true, - autotitle: routeIsNewNote(this.$route), } store.commit('updateNote', note) this.$forceUpdate() + + // queue auto saving note content if (this.autosaveTimer === null) { this.autosaveTimer = setTimeout(() => { this.autosaveTimer = null saveNote(note.id) - }, 2000) + }, config.interval.note.autosave * 1000) } + + // (re-) start auto refresh timer // TODO should be after save is finished this.startRefreshTimer() + + // stop old autotitle timer + if (this.autotitleTimer !== null) { + clearTimeout(this.autotitleTimer) + this.autotitleTimer = null + } + // start autotitle timer if note is new + if (this.isNewNote) { + this.autotitleTimer = setTimeout(() => { + this.autotitleTimer = null + if (this.isNewNote) { + autotitleNote(note.id) + } + }, config.interval.note.autotitle * 1000) + } } }, @@ -293,9 +309,8 @@ export default { onManualSave() { const note = { ...this.note, - autotitle: routeIsNewNote(this.$route), } - store.commit('add', note) + store.commit('updateNote', note) saveNoteManually(this.note.id) }, }, diff --git a/src/config.js b/src/config.js new file mode 100644 index 000000000..711ee31d1 --- /dev/null +++ b/src/config.js @@ -0,0 +1,9 @@ +export const config = { + interval: { + note: { + autosave: 1, + autotitle: 2, + refresh: 10, + }, + }, +} diff --git a/src/store/notes.js b/src/store/notes.js index 88393aa8b..621d9be85 100644 --- a/src/store/notes.js +++ b/src/store/notes.js @@ -83,7 +83,6 @@ const mutations = { // don't update meta-data over full data if (updated.content !== undefined || note.content === undefined) { note.content = updated.content - Vue.set(note, 'autotitle', updated.autotitle) Vue.set(note, 'unsaved', updated.unsaved) Vue.set(note, 'error', updated.error) Vue.set(note, 'errorMessage', updated.errorMessage)