add auto-refresh / split Vuex store into modules
This commit is contained in:
parent
57632ffe8c
commit
386a3ab502
|
@ -3,6 +3,7 @@
|
|||
namespace OCA\Notes\Controller;
|
||||
|
||||
use OCA\Notes\Service\NotesService;
|
||||
use OCA\Notes\Service\MetaService;
|
||||
use OCA\Notes\Service\SettingsService;
|
||||
|
||||
use OCP\AppFramework\Controller;
|
||||
|
@ -16,6 +17,8 @@ class NotesController extends Controller {
|
|||
|
||||
/** @var NotesService */
|
||||
private $notesService;
|
||||
/** @var MetaService */
|
||||
private $metaService;
|
||||
/** @var SettingsService */
|
||||
private $settingsService;
|
||||
/** @var Helper */
|
||||
|
@ -31,6 +34,7 @@ class NotesController extends Controller {
|
|||
string $AppName,
|
||||
IRequest $request,
|
||||
NotesService $notesService,
|
||||
MetaService $metaService,
|
||||
SettingsService $settingsService,
|
||||
Helper $helper,
|
||||
IConfig $settings,
|
||||
|
@ -39,6 +43,7 @@ class NotesController extends Controller {
|
|||
) {
|
||||
parent::__construct($AppName, $request);
|
||||
$this->notesService = $notesService;
|
||||
$this->metaService = $metaService;
|
||||
$this->settingsService = $settingsService;
|
||||
$this->helper = $helper;
|
||||
$this->settings = $settings;
|
||||
|
@ -50,8 +55,9 @@ class NotesController extends Controller {
|
|||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function index() : JSONResponse {
|
||||
return $this->helper->handleErrorResponse(function () {
|
||||
public function index(int $pruneBefore = 0) : JSONResponse {
|
||||
return $this->helper->handleErrorResponse(function () use ($pruneBefore) {
|
||||
$now = new \DateTime(); // this must be before loading notes if there are concurrent changes possible
|
||||
$settings = $this->settingsService->getAll($this->userId);
|
||||
|
||||
$errorMessage = null;
|
||||
|
@ -65,9 +71,15 @@ class NotesController extends Controller {
|
|||
$categories = null;
|
||||
try {
|
||||
$data = $this->notesService->getAll($this->userId);
|
||||
$metas = $this->metaService->updateAll($this->userId, $data['notes']);
|
||||
$categories = $data['categories'];
|
||||
$notesData = array_map(function ($note) {
|
||||
return $note->getData([ 'content' ]);
|
||||
$notesData = array_map(function ($note) use ($metas, $pruneBefore) {
|
||||
$lastUpdate = $metas[$note->getId()]->getLastUpdate();
|
||||
if ($pruneBefore && $lastUpdate<$pruneBefore) {
|
||||
return [ 'id' => $note->getId() ];
|
||||
} else {
|
||||
return $note->getData([ 'content' ]);
|
||||
}
|
||||
}, $data['notes']);
|
||||
if ($lastViewedNote) {
|
||||
// check if note exists
|
||||
|
@ -83,13 +95,18 @@ class NotesController extends Controller {
|
|||
$errorMessage = $this->l10n->t('The notes folder is not accessible: %s', $e->getMessage());
|
||||
}
|
||||
|
||||
return [
|
||||
$result = [
|
||||
'notes' => $notesData,
|
||||
'categories' => $categories,
|
||||
'settings' => $settings,
|
||||
'lastViewedNote' => $lastViewedNote,
|
||||
'errorMessage' => $errorMessage,
|
||||
];
|
||||
$etag = md5(json_encode($result));
|
||||
return (new JSONResponse($result))
|
||||
->setLastModified($now)
|
||||
->setETag($etag)
|
||||
;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,13 @@ class MetaService {
|
|||
$meta->setFileId($note->getId());
|
||||
$meta->setLastUpdate(time());
|
||||
$this->updateIfNeeded($meta, $note, true);
|
||||
$this->metaMapper->insert($meta);
|
||||
try {
|
||||
$this->metaMapper->insert($meta);
|
||||
/* @phan-suppress-next-line PhanUndeclaredClassCatch */
|
||||
} catch (\Doctrine\DBAL\Exception\UniqueConstraintViolationException $e) {
|
||||
// It's likely that a concurrent request created this entry, too.
|
||||
// We can ignore this, since the result should be the same.
|
||||
}
|
||||
return $meta;
|
||||
}
|
||||
|
||||
|
|
18
src/App.vue
18
src/App.vue
|
@ -67,7 +67,7 @@ export default {
|
|||
search: '',
|
||||
},
|
||||
loading: {
|
||||
notes: false,
|
||||
notes: true,
|
||||
create: false,
|
||||
},
|
||||
error: false,
|
||||
|
@ -79,7 +79,7 @@ export default {
|
|||
|
||||
computed: {
|
||||
notes() {
|
||||
return store.state.notes
|
||||
return store.state.notes.notes
|
||||
},
|
||||
|
||||
filteredNotes() {
|
||||
|
@ -129,9 +129,12 @@ export default {
|
|||
|
||||
methods: {
|
||||
loadNotes() {
|
||||
this.loading.notes = true
|
||||
fetchNotes()
|
||||
.then(data => {
|
||||
if (data === null) {
|
||||
// nothing changed
|
||||
return
|
||||
}
|
||||
if (data.notes !== null) {
|
||||
this.error = false
|
||||
this.routeDefault(data.lastViewedNote)
|
||||
|
@ -140,10 +143,14 @@ export default {
|
|||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.error = true
|
||||
// only show error state if not loading in background
|
||||
if (this.loading.notes) {
|
||||
this.error = true
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
this.loading.notes = false
|
||||
setTimeout(this.loadNotes, 25000)
|
||||
})
|
||||
},
|
||||
|
||||
|
@ -151,7 +158,8 @@ export default {
|
|||
if (this.$route.path !== '/') {
|
||||
this.$router.push('/')
|
||||
}
|
||||
store.commit('removeAll')
|
||||
store.commit('removeAllNotes')
|
||||
this.loading.notes = true
|
||||
this.loadNotes()
|
||||
},
|
||||
|
||||
|
|
|
@ -36,23 +36,39 @@ export const setSettings = settings => {
|
|||
}
|
||||
|
||||
export const fetchNotes = () => {
|
||||
const lastETag = store.state.sync.etag
|
||||
const lastModified = store.state.sync.lastModified
|
||||
const headers = {}
|
||||
if (lastETag) {
|
||||
headers['If-None-Match'] = lastETag
|
||||
}
|
||||
return axios
|
||||
.get(url('/notes'))
|
||||
.get(
|
||||
url('/notes' + (lastModified ? '?pruneBefore=' + lastModified : '')),
|
||||
{ headers }
|
||||
)
|
||||
.then(response => {
|
||||
store.commit('setSettings', response.data.settings)
|
||||
store.commit('setCategories', response.data.categories)
|
||||
if (response.data.notes !== null) {
|
||||
store.dispatch('addAll', response.data.notes)
|
||||
store.dispatch('updateNotes', response.data.notes)
|
||||
}
|
||||
if (response.data.errorMessage) {
|
||||
showError(response.data.errorMessage)
|
||||
}
|
||||
store.commit('setSyncETag', response.headers['etag'])
|
||||
store.commit('setSyncLastModified', response.headers['last-modified'])
|
||||
return response.data
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
handleSyncError(t('notes', 'Fetching notes has failed.'))
|
||||
throw err
|
||||
if (err.response && err.response.status === 304) {
|
||||
store.commit('setSyncLastModified', err.response.headers['last-modified'])
|
||||
return null
|
||||
} else {
|
||||
console.error(err)
|
||||
handleSyncError(t('notes', 'Fetching notes has failed.'))
|
||||
throw err
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -63,7 +79,7 @@ export const fetchNote = noteId => {
|
|||
const localNote = store.getters.getNote(parseInt(noteId))
|
||||
// only overwrite if there are no unsaved changes
|
||||
if (!localNote || !localNote.unsaved) {
|
||||
store.commit('add', response.data)
|
||||
store.commit('updateNote', response.data)
|
||||
}
|
||||
return response.data
|
||||
})
|
||||
|
@ -97,7 +113,7 @@ export const createNote = category => {
|
|||
return axios
|
||||
.post(url('/notes'), { category: category })
|
||||
.then(response => {
|
||||
store.commit('add', response.data)
|
||||
store.commit('updateNote', response.data)
|
||||
return response.data
|
||||
})
|
||||
.catch(err => {
|
||||
|
@ -122,7 +138,7 @@ function _updateNote(note) {
|
|||
if (updated.content === note.content) {
|
||||
note.unsaved = false
|
||||
}
|
||||
store.commit('add', note)
|
||||
store.commit('updateNote', note)
|
||||
return note
|
||||
})
|
||||
.catch(err => {
|
||||
|
@ -140,7 +156,7 @@ export const undoDeleteNote = (note) => {
|
|||
return axios
|
||||
.post(url('/notes/undo'), note)
|
||||
.then(response => {
|
||||
store.commit('add', response.data)
|
||||
store.commit('updateNote', response.data)
|
||||
return response.data
|
||||
})
|
||||
.catch(err => {
|
||||
|
@ -159,13 +175,13 @@ export const deleteNote = noteId => {
|
|||
return axios
|
||||
.delete(url('/notes/' + noteId))
|
||||
.then(() => {
|
||||
store.commit('remove', noteId)
|
||||
store.commit('removeNote', noteId)
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
handleSyncError(t('notes', 'Deleting note {id} has failed.', { id: noteId }))
|
||||
// remove note always since we don't know when the error happened
|
||||
store.commit('remove', noteId)
|
||||
store.commit('removeNote', noteId)
|
||||
throw err
|
||||
})
|
||||
.then(() => {
|
||||
|
@ -211,8 +227,8 @@ export const saveNote = (noteId, manualSave = false) => {
|
|||
}
|
||||
|
||||
function _saveNotes() {
|
||||
const unsavedNotes = Object.values(store.state.unsaved)
|
||||
if (store.state.isSaving || unsavedNotes.length === 0) {
|
||||
const unsavedNotes = Object.values(store.state.notes.unsaved)
|
||||
if (store.state.app.isSaving || unsavedNotes.length === 0) {
|
||||
return
|
||||
}
|
||||
store.commit('setSaving', true)
|
||||
|
@ -237,7 +253,7 @@ export const noteExists = (noteId) => {
|
|||
export const getCategories = (maxLevel, details) => {
|
||||
const categories = store.getters.getCategories(maxLevel, details)
|
||||
if (maxLevel === 0) {
|
||||
return [...new Set([...categories, ...store.state.categories])]
|
||||
return [...new Set([...categories, ...store.state.notes.categories])]
|
||||
} else {
|
||||
return categories
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ export default {
|
|||
|
||||
computed: {
|
||||
settings() {
|
||||
return store.state.settings
|
||||
return store.state.app.settings
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
@ -108,10 +108,10 @@ export default {
|
|||
return this.note ? this.note.title : ''
|
||||
},
|
||||
isManualSave() {
|
||||
return store.state.isManualSave
|
||||
return store.state.app.isManualSave
|
||||
},
|
||||
sidebarOpen() {
|
||||
return store.state.sidebarOpen
|
||||
return store.state.app.sidebarOpen
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -163,7 +163,7 @@ export default {
|
|||
},
|
||||
|
||||
onUpdateTitle(title) {
|
||||
const defaultTitle = store.state.documentTitle
|
||||
const defaultTitle = store.state.app.documentTitle
|
||||
if (title) {
|
||||
document.title = title + ' - ' + defaultTitle
|
||||
} else {
|
||||
|
@ -212,7 +212,7 @@ export default {
|
|||
},
|
||||
|
||||
onToggleSidebar() {
|
||||
store.commit('setSidebarOpen', !store.state.sidebarOpen)
|
||||
store.commit('setSidebarOpen', !store.state.app.sidebarOpen)
|
||||
this.actionsOpen = false
|
||||
},
|
||||
|
||||
|
@ -224,7 +224,7 @@ export default {
|
|||
unsaved: true,
|
||||
autotitle: routeIsNewNote(this.$route),
|
||||
}
|
||||
store.commit('add', note)
|
||||
store.commit('updateNote', note)
|
||||
if (this.autosaveTimer === null) {
|
||||
this.autosaveTimer = setTimeout(() => {
|
||||
this.autosaveTimer = null
|
||||
|
|
|
@ -138,7 +138,7 @@ export default {
|
|||
return [ '', ...getCategories(0, false) ]
|
||||
},
|
||||
sidebarOpen() {
|
||||
return store.state.sidebarOpen
|
||||
return store.state.app.sidebarOpen
|
||||
},
|
||||
},
|
||||
|
||||
|
|
166
src/store.js
166
src/store.js
|
@ -1,166 +1,16 @@
|
|||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
import app from './store/app'
|
||||
import notes from './store/notes'
|
||||
import sync from './store/sync'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
settings: {},
|
||||
categories: [],
|
||||
notes: [],
|
||||
notesIds: {},
|
||||
unsaved: {},
|
||||
isSaving: false,
|
||||
isManualSave: false,
|
||||
documentTitle: null,
|
||||
sidebarOpen: false,
|
||||
},
|
||||
|
||||
getters: {
|
||||
numNotes: (state) => () => {
|
||||
return state.notes.length
|
||||
},
|
||||
|
||||
noteExists: (state) => (id) => {
|
||||
return state.notesIds[id] !== undefined
|
||||
},
|
||||
|
||||
getNote: (state) => (id) => {
|
||||
if (state.notesIds[id] === undefined) {
|
||||
return null
|
||||
}
|
||||
return state.notesIds[id]
|
||||
},
|
||||
|
||||
getCategories: (state) => (maxLevel, details) => {
|
||||
function nthIndexOf(str, pattern, n) {
|
||||
let i = -1
|
||||
while (n-- && i++ < str.length) {
|
||||
i = str.indexOf(pattern, i)
|
||||
if (i < 0) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
// get categories from notes
|
||||
const categories = {}
|
||||
for (const note of state.notes) {
|
||||
let cat = note.category
|
||||
if (maxLevel > 0) {
|
||||
const index = nthIndexOf(cat, '/', maxLevel)
|
||||
if (index > 0) {
|
||||
cat = cat.substring(0, index)
|
||||
}
|
||||
}
|
||||
if (categories[cat] === undefined) {
|
||||
categories[cat] = 1
|
||||
} else {
|
||||
categories[cat] += 1
|
||||
}
|
||||
}
|
||||
// get structured result from categories
|
||||
const result = []
|
||||
for (const category in categories) {
|
||||
if (details) {
|
||||
result.push({
|
||||
name: category,
|
||||
count: categories[category],
|
||||
})
|
||||
} else if (category) {
|
||||
result.push(category)
|
||||
}
|
||||
}
|
||||
if (details) {
|
||||
result.sort((a, b) => a.name.localeCompare(b.name))
|
||||
} else {
|
||||
result.sort()
|
||||
}
|
||||
return result
|
||||
},
|
||||
},
|
||||
|
||||
mutations: {
|
||||
add(state, updated) {
|
||||
const note = state.notesIds[updated.id]
|
||||
if (note) {
|
||||
// don't update meta-data over full data
|
||||
if (updated.content !== undefined || note.content === undefined) {
|
||||
note.title = updated.title
|
||||
note.modified = updated.modified
|
||||
note.content = updated.content
|
||||
note.favorite = updated.favorite
|
||||
note.category = updated.category
|
||||
Vue.set(note, 'autotitle', updated.autotitle)
|
||||
Vue.set(note, 'unsaved', updated.unsaved)
|
||||
Vue.set(note, 'error', updated.error)
|
||||
Vue.set(note, 'errorMessage', updated.errorMessage)
|
||||
}
|
||||
} else {
|
||||
state.notes.push(updated)
|
||||
Vue.set(state.notesIds, updated.id, updated)
|
||||
}
|
||||
},
|
||||
|
||||
setNoteAttribute(state, params) {
|
||||
const note = state.notesIds[params.noteId]
|
||||
if (note) {
|
||||
Vue.set(note, params.attribute, params.value)
|
||||
}
|
||||
},
|
||||
|
||||
remove(state, id) {
|
||||
const index = state.notes.findIndex(note => note.id === id)
|
||||
if (index !== -1) {
|
||||
state.notes.splice(index, 1)
|
||||
delete state.notesIds[id]
|
||||
}
|
||||
},
|
||||
|
||||
removeAll(state) {
|
||||
state.notes = []
|
||||
state.notesIds = {}
|
||||
},
|
||||
|
||||
addUnsaved(state, id) {
|
||||
Vue.set(state.unsaved, id, state.notesIds[id])
|
||||
},
|
||||
|
||||
clearUnsaved(state) {
|
||||
state.unsaved = {}
|
||||
},
|
||||
|
||||
setSettings(state, settings) {
|
||||
state.settings = settings
|
||||
},
|
||||
|
||||
setCategories(state, categories) {
|
||||
state.categories = categories
|
||||
},
|
||||
|
||||
setSaving(state, isSaving) {
|
||||
state.isSaving = isSaving
|
||||
},
|
||||
|
||||
setManualSave(state, isManualSave) {
|
||||
state.isManualSave = isManualSave
|
||||
},
|
||||
|
||||
setDocumentTitle(state, title) {
|
||||
state.documentTitle = title
|
||||
},
|
||||
|
||||
setSidebarOpen(state, open) {
|
||||
state.sidebarOpen = open
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
addAll(context, notes) {
|
||||
for (const note of notes) {
|
||||
context.commit('add', note)
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
app,
|
||||
notes,
|
||||
sync,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
const state = {
|
||||
settings: {},
|
||||
isSaving: false,
|
||||
isManualSave: false,
|
||||
documentTitle: null,
|
||||
sidebarOpen: false,
|
||||
}
|
||||
|
||||
const getters = {
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
setSettings(state, settings) {
|
||||
state.settings = settings
|
||||
},
|
||||
|
||||
setSaving(state, isSaving) {
|
||||
state.isSaving = isSaving
|
||||
},
|
||||
|
||||
setManualSave(state, isManualSave) {
|
||||
state.isManualSave = isManualSave
|
||||
},
|
||||
|
||||
setDocumentTitle(state, title) {
|
||||
state.documentTitle = title
|
||||
},
|
||||
|
||||
setSidebarOpen(state, open) {
|
||||
state.sidebarOpen = open
|
||||
},
|
||||
}
|
||||
|
||||
const actions = {
|
||||
}
|
||||
|
||||
export default { state, getters, mutations, actions }
|
|
@ -0,0 +1,151 @@
|
|||
import Vue from 'vue'
|
||||
|
||||
const state = {
|
||||
categories: [],
|
||||
notes: [],
|
||||
notesIds: {},
|
||||
unsaved: {},
|
||||
}
|
||||
|
||||
const getters = {
|
||||
numNotes: (state) => () => {
|
||||
return state.notes.length
|
||||
},
|
||||
|
||||
noteExists: (state) => (id) => {
|
||||
return state.notesIds[id] !== undefined
|
||||
},
|
||||
|
||||
getNote: (state) => (id) => {
|
||||
if (state.notesIds[id] === undefined) {
|
||||
return null
|
||||
}
|
||||
return state.notesIds[id]
|
||||
},
|
||||
|
||||
getCategories: (state) => (maxLevel, details) => {
|
||||
function nthIndexOf(str, pattern, n) {
|
||||
let i = -1
|
||||
while (n-- && i++ < str.length) {
|
||||
i = str.indexOf(pattern, i)
|
||||
if (i < 0) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
// get categories from notes
|
||||
const categories = {}
|
||||
for (const note of state.notes) {
|
||||
let cat = note.category
|
||||
if (maxLevel > 0) {
|
||||
const index = nthIndexOf(cat, '/', maxLevel)
|
||||
if (index > 0) {
|
||||
cat = cat.substring(0, index)
|
||||
}
|
||||
}
|
||||
if (categories[cat] === undefined) {
|
||||
categories[cat] = 1
|
||||
} else {
|
||||
categories[cat] += 1
|
||||
}
|
||||
}
|
||||
// get structured result from categories
|
||||
const result = []
|
||||
for (const category in categories) {
|
||||
if (details) {
|
||||
result.push({
|
||||
name: category,
|
||||
count: categories[category],
|
||||
})
|
||||
} else if (category) {
|
||||
result.push(category)
|
||||
}
|
||||
}
|
||||
if (details) {
|
||||
result.sort((a, b) => a.name.localeCompare(b.name))
|
||||
} else {
|
||||
result.sort()
|
||||
}
|
||||
return result
|
||||
},
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
updateNote(state, updated) {
|
||||
const note = state.notesIds[updated.id]
|
||||
if (note) {
|
||||
// don't update meta-data over full data
|
||||
if (updated.content !== undefined || note.content === undefined) {
|
||||
note.title = updated.title
|
||||
note.modified = updated.modified
|
||||
note.content = updated.content
|
||||
note.favorite = updated.favorite
|
||||
note.category = updated.category
|
||||
Vue.set(note, 'autotitle', updated.autotitle)
|
||||
Vue.set(note, 'unsaved', updated.unsaved)
|
||||
Vue.set(note, 'error', updated.error)
|
||||
Vue.set(note, 'errorMessage', updated.errorMessage)
|
||||
}
|
||||
} else {
|
||||
state.notes.push(updated)
|
||||
Vue.set(state.notesIds, updated.id, updated)
|
||||
}
|
||||
},
|
||||
|
||||
setNoteAttribute(state, params) {
|
||||
const note = state.notesIds[params.noteId]
|
||||
if (note) {
|
||||
Vue.set(note, params.attribute, params.value)
|
||||
}
|
||||
},
|
||||
|
||||
removeNote(state, id) {
|
||||
const index = state.notes.findIndex(note => note.id === id)
|
||||
if (index !== -1) {
|
||||
state.notes.splice(index, 1)
|
||||
delete state.notesIds[id]
|
||||
}
|
||||
},
|
||||
|
||||
removeAllNotes(state) {
|
||||
state.notes = []
|
||||
state.notesIds = {}
|
||||
},
|
||||
|
||||
addUnsaved(state, id) {
|
||||
Vue.set(state.unsaved, id, state.notesIds[id])
|
||||
},
|
||||
|
||||
clearUnsaved(state) {
|
||||
state.unsaved = {}
|
||||
},
|
||||
|
||||
setCategories(state, categories) {
|
||||
state.categories = categories
|
||||
},
|
||||
}
|
||||
|
||||
const actions = {
|
||||
updateNotes(context, notes) {
|
||||
const noteIds = {}
|
||||
// add/update new notes
|
||||
for (const note of notes) {
|
||||
noteIds[note.id] = true
|
||||
// TODO check for parallel (local) changes!
|
||||
// only update, if note has changes (see API "purgeBefore")
|
||||
if (note.title !== undefined) {
|
||||
context.commit('updateNote', note)
|
||||
}
|
||||
}
|
||||
// remove deleted notes
|
||||
context.state.notes.forEach(note => {
|
||||
if (noteIds[note.id] === undefined) {
|
||||
context.commit('removeNote', note.id)
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
export default { state, getters, mutations, actions }
|
|
@ -0,0 +1,33 @@
|
|||
const state = {
|
||||
etag: null,
|
||||
lastModified: 0,
|
||||
active: false,
|
||||
// TODO add list of notes with changes during sync
|
||||
}
|
||||
|
||||
const getters = {
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
setSyncETag(state, etag) {
|
||||
if (etag) {
|
||||
state.etag = etag
|
||||
}
|
||||
},
|
||||
|
||||
setSyncLastModified(state, strLastModified) {
|
||||
const lastModified = Date.parse(strLastModified)
|
||||
if (lastModified) {
|
||||
state.lastModified = lastModified / 1000
|
||||
}
|
||||
},
|
||||
|
||||
setSyncActive(state, active) {
|
||||
state.active = active
|
||||
},
|
||||
}
|
||||
|
||||
const actions = {
|
||||
}
|
||||
|
||||
export default { state, getters, mutations, actions }
|
Loading…
Reference in New Issue