Save drafts permanently in local storage
This commit is contained in:
parent
39b42da724
commit
0256ff5f63
|
@ -377,6 +377,8 @@ const afterStoreSetup = async ({ store, i18n }) => {
|
||||||
getInstanceConfig({ store })
|
getInstanceConfig({ store })
|
||||||
])
|
])
|
||||||
|
|
||||||
|
await store.dispatch('loadDrafts')
|
||||||
|
|
||||||
// Start fetching things that don't need to block the UI
|
// Start fetching things that don't need to block the UI
|
||||||
store.dispatch('fetchMutes')
|
store.dispatch('fetchMutes')
|
||||||
store.dispatch('startFetchingAnnouncements')
|
store.dispatch('startFetchingAnnouncements')
|
||||||
|
|
|
@ -31,12 +31,12 @@
|
||||||
class="faint-link"
|
class="faint-link"
|
||||||
:to="{ name: 'conversation', params: { id: draft.refId } }"
|
:to="{ name: 'conversation', params: { id: draft.refId } }"
|
||||||
>
|
>
|
||||||
{{ refStatus.external_url }}
|
{{ refStatus ? refStatus.external_url : $t('drafts.unavailable') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
<StatusContent
|
<StatusContent
|
||||||
v-if="draft.refId"
|
v-if="draft.refId && refStatus"
|
||||||
class="status-content"
|
class="status-content"
|
||||||
:status="refStatus"
|
:status="refStatus"
|
||||||
:compact="true"
|
:compact="true"
|
||||||
|
|
|
@ -1165,6 +1165,7 @@
|
||||||
"abandon_confirm_accept_button": "Abandon",
|
"abandon_confirm_accept_button": "Abandon",
|
||||||
"abandon_confirm_cancel_button": "Keep",
|
"abandon_confirm_cancel_button": "Keep",
|
||||||
"replying": "Replying to {statusLink}",
|
"replying": "Replying to {statusLink}",
|
||||||
"editing": "Editing {statusLink}"
|
"editing": "Editing {statusLink}",
|
||||||
|
"unavailable": "(unavailable)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import merge from 'lodash.merge'
|
import merge from 'lodash.merge'
|
||||||
import localforage from 'localforage'
|
|
||||||
import { each, get, set, cloneDeep } from 'lodash'
|
import { each, get, set, cloneDeep } from 'lodash'
|
||||||
|
import { storage } from './storage.js'
|
||||||
|
|
||||||
let loaded = false
|
let loaded = false
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ const saveImmedeatelyActions = [
|
||||||
]
|
]
|
||||||
|
|
||||||
const defaultStorage = (() => {
|
const defaultStorage = (() => {
|
||||||
return localforage
|
return storage
|
||||||
})()
|
})()
|
||||||
|
|
||||||
export default function createPersistedState ({
|
export default function createPersistedState ({
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
import localforage from 'localforage'
|
||||||
|
|
||||||
|
export const storage = localforage
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { storage } from 'src/lib/storage.js'
|
||||||
|
|
||||||
export const defaultState = {
|
export const defaultState = {
|
||||||
drafts: {}
|
drafts: {}
|
||||||
|
@ -9,17 +10,55 @@ export const mutations = {
|
||||||
},
|
},
|
||||||
abandonDraft (state, { id }) {
|
abandonDraft (state, { id }) {
|
||||||
delete state.drafts[id]
|
delete state.drafts[id]
|
||||||
|
},
|
||||||
|
loadDrafts (state, data) {
|
||||||
|
state.drafts = data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const storageKey = 'pleroma-fe-drafts'
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: we do not use the persist state plugin because
|
||||||
|
* it is not impossible for a user to have two windows at
|
||||||
|
* the same time. The persist state plugin is just overriding
|
||||||
|
* everything with the current state. This isn't good because
|
||||||
|
* if a draft is created in one window and another draft is
|
||||||
|
* created in another, the draft in the first window will just
|
||||||
|
* be overriden.
|
||||||
|
* Here, we can't guarantee 100% atomicity unless one uses
|
||||||
|
* different keys, which will just pollute the whole storage.
|
||||||
|
* It is indeed best to have backend support for this.
|
||||||
|
*/
|
||||||
|
const getStorageData = async () => ((await storage.getItem(storageKey)) || {})
|
||||||
|
|
||||||
|
const saveDraftToStorage = async (draft) => {
|
||||||
|
const currentData = await getStorageData()
|
||||||
|
currentData[draft.id] = JSON.parse(JSON.stringify(draft))
|
||||||
|
await storage.setItem(storageKey, currentData)
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteDraftFromStorage = async (id) => {
|
||||||
|
const currentData = await getStorageData()
|
||||||
|
delete currentData[id]
|
||||||
|
await storage.setItem(storageKey, currentData)
|
||||||
|
}
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
addOrSaveDraft (store, { draft }) {
|
async addOrSaveDraft (store, { draft }) {
|
||||||
const id = draft.id || (new Date().getTime()).toString()
|
const id = draft.id || (new Date().getTime()).toString()
|
||||||
store.commit('addOrSaveDraft', { draft: { ...draft, id } })
|
const draftWithId = { ...draft, id }
|
||||||
|
store.commit('addOrSaveDraft', { draft: draftWithId })
|
||||||
|
await saveDraftToStorage(draftWithId)
|
||||||
return id
|
return id
|
||||||
},
|
},
|
||||||
abandonDraft (store, { id }) {
|
async abandonDraft (store, { id }) {
|
||||||
store.commit('abandonDraft', { id })
|
store.commit('abandonDraft', { id })
|
||||||
|
await deleteDraftFromStorage(id)
|
||||||
|
},
|
||||||
|
async loadDrafts (store) {
|
||||||
|
const currentData = await getStorageData()
|
||||||
|
store.commit('loadDrafts', currentData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* eslint-env serviceworker */
|
/* eslint-env serviceworker */
|
||||||
|
|
||||||
import localForage from 'localforage'
|
import { storage } from 'src/lib/storage.js'
|
||||||
import { parseNotification } from './services/entity_normalizer/entity_normalizer.service.js'
|
import { parseNotification } from './services/entity_normalizer/entity_normalizer.service.js'
|
||||||
import { prepareNotificationObject } from './services/notification_utils/notification_utils.js'
|
import { prepareNotificationObject } from './services/notification_utils/notification_utils.js'
|
||||||
import { createI18n } from 'vue-i18n'
|
import { createI18n } from 'vue-i18n'
|
||||||
|
@ -14,7 +14,7 @@ const i18n = createI18n({
|
||||||
})
|
})
|
||||||
|
|
||||||
function isEnabled () {
|
function isEnabled () {
|
||||||
return localForage.getItem('vuex-lz')
|
return storage.getItem('vuex-lz')
|
||||||
.then(data => data.config.webPushNotifications)
|
.then(data => data.config.webPushNotifications)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ function getWindowClients () {
|
||||||
}
|
}
|
||||||
|
|
||||||
const setLocale = async () => {
|
const setLocale = async () => {
|
||||||
const state = await localForage.getItem('vuex-lz')
|
const state = await storage.getItem('vuex-lz')
|
||||||
const locale = state.config.interfaceLanguage || 'en'
|
const locale = state.config.interfaceLanguage || 'en'
|
||||||
i18n.locale = locale
|
i18n.locale = locale
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue