migrate drafts store to pinia as-is
This commit is contained in:
parent
c4442f595d
commit
148ce1eb99
8 changed files with 96 additions and 123 deletions
|
|
@ -7,6 +7,7 @@ import StatusContent from 'src/components/status_content/status_content.vue'
|
|||
|
||||
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||
import { useStatusesStore } from 'src/stores/statuses.js'
|
||||
import { useDraftsStore } from 'src/stores/drafts.js'
|
||||
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import { faPollH } from '@fortawesome/free-solid-svg-icons'
|
||||
|
|
@ -77,9 +78,9 @@ const Draft = {
|
|||
editing(newVal) {
|
||||
if (newVal) return
|
||||
if (this.safeToSave) {
|
||||
this.$store.dispatch('addOrSaveDraft', { draft: this.draft })
|
||||
useDraftsStore().addOrSaveDraft(this.draft)
|
||||
} else {
|
||||
this.$store.dispatch('addOrSaveDraft', { draft: this.referenceDraft })
|
||||
useDraftsStore().addOrSaveDraft(this.referenceDraft)
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
@ -91,7 +92,7 @@ const Draft = {
|
|||
this.showingConfirmDialog = true
|
||||
},
|
||||
doAbandon() {
|
||||
this.$store.dispatch('abandonDraft', { id: this.draft.id }).then(() => {
|
||||
useDraftsStore().abandonDraft(this.draft.id).then(() => {
|
||||
this.hideConfirmDialog()
|
||||
})
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { defineAsyncComponent } from 'vue'
|
||||
import { useDraftsStore } from 'src/stores/drafts.js'
|
||||
|
||||
import Draft from 'src/components/draft/draft.vue'
|
||||
import List from 'src/components/list/list.vue'
|
||||
|
|
@ -18,7 +19,7 @@ const Drafts = {
|
|||
},
|
||||
computed: {
|
||||
drafts() {
|
||||
return this.$store.getters.draftsArray
|
||||
return useDraftsStore().draftsArray
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -26,8 +27,7 @@ const Drafts = {
|
|||
this.showingConfirmDialog = true
|
||||
},
|
||||
doAbandonAll() {
|
||||
this.$store
|
||||
.dispatch('abandonAllDrafts')
|
||||
useDraftsStore().abandonAllDrafts()
|
||||
.then(() => this.hideConfirmDialog())
|
||||
},
|
||||
hideConfirmDialog() {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import { useMediaViewerStore } from 'src/stores/media_viewer.js'
|
|||
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
||||
import { useUsersStore } from 'src/stores/users.js'
|
||||
import { useDraftsStore } from 'src/stores/drafts.js'
|
||||
|
||||
import { pollFormToMasto } from 'src/services/poll/poll.service.js'
|
||||
|
||||
|
|
@ -985,13 +986,11 @@ const PostStatusForm = {
|
|||
saveDraft() {
|
||||
if (!this.disableDraft && !this.saveInhibited) {
|
||||
if (this.safeToSaveDraft) {
|
||||
return this.$store
|
||||
.dispatch('addOrSaveDraft', {
|
||||
draft: {
|
||||
type: this.statusType,
|
||||
refId: this.refId,
|
||||
...this.newStatus,
|
||||
},
|
||||
return useDraftsStore()
|
||||
.addOrSaveDraft({
|
||||
type: this.statusType,
|
||||
refId: this.refId,
|
||||
...this.newStatus,
|
||||
})
|
||||
.then((id) => {
|
||||
if (this.newStatus.id !== id) {
|
||||
|
|
@ -1024,14 +1023,14 @@ const PostStatusForm = {
|
|||
}
|
||||
},
|
||||
abandonDraft() {
|
||||
return this.$store.dispatch('abandonDraft', { id: this.draftId })
|
||||
return useDraftsStore().abandonDraft(this.draftId)
|
||||
},
|
||||
getDraft() {
|
||||
const maybeDraft = this.$store.state.drafts.drafts[this.draftId]
|
||||
const maybeDraft = useDraftsStore().drafts.get(this.draftId)
|
||||
if (this.draftId && maybeDraft) {
|
||||
return maybeDraft
|
||||
} else {
|
||||
const existingDrafts = this.$store.getters.draftsByTypeAndRefId(
|
||||
const existingDrafts = useDraftsStore().draftsByTypeAndRefId(
|
||||
this.statusType,
|
||||
this.refId,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { mapActions, mapState } from 'pinia'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
import { USERNAME_ROUTES } from 'src/components/navigation/navigation.js'
|
||||
import UserCard from 'src/components/user_card/user_card.vue'
|
||||
|
|
@ -15,6 +14,7 @@ import { useInterfaceStore } from 'src/stores/interface'
|
|||
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||
import { useShoutStore } from 'src/stores/shout'
|
||||
import { useUsersStore } from 'src/stores/users.js'
|
||||
import { useDraftsStore } from 'src/stores/drafts.js'
|
||||
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
|
|
@ -110,7 +110,7 @@ const SideDrawer = {
|
|||
hideSitename: (store) => store.instanceIdentity.hideSitename,
|
||||
}),
|
||||
...mapState(useChatsStore, ['unreadChatsCount']),
|
||||
...mapGetters(['draftCount']),
|
||||
...mapState(useDraftsStore, ['draftCount']),
|
||||
},
|
||||
methods: {
|
||||
toggleDrawer() {
|
||||
|
|
|
|||
|
|
@ -1,99 +0,0 @@
|
|||
import { storage } from 'src/lib/storage.js'
|
||||
|
||||
export const defaultState = {
|
||||
drafts: {},
|
||||
}
|
||||
|
||||
export const mutations = {
|
||||
addOrSaveDraft(state, { draft }) {
|
||||
state.drafts[draft.id] = draft
|
||||
},
|
||||
abandonDraft(state, { 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)) ||
|
||||
{
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
const saveDraftToStorage = async (draft) => {
|
||||
const currentData = await getStorageData()
|
||||
currentData[draft.id] = JSON.parse(JSON.stringify(draft))
|
||||
await storage.setItem(storageKey, currentData)
|
||||
}
|
||||
|
||||
const deleteDraftFromStorage = async (ids) => {
|
||||
const currentData = await getStorageData()
|
||||
ids.forEach((id) => {
|
||||
delete currentData[id]
|
||||
})
|
||||
await storage.setItem(storageKey, currentData)
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
async addOrSaveDraft(store, { draft }) {
|
||||
const id = draft.id || new Date().getTime().toString()
|
||||
const draftWithId = { ...draft, id }
|
||||
store.commit('addOrSaveDraft', { draft: draftWithId })
|
||||
await saveDraftToStorage(draftWithId)
|
||||
return id
|
||||
},
|
||||
async abandonDraft(store, { id }) {
|
||||
store.commit('abandonDraft', { id })
|
||||
await deleteDraftFromStorage([id])
|
||||
},
|
||||
async abandonAllDrafts(store) {
|
||||
const ids = Object.keys(store.state.drafts)
|
||||
ids.forEach((id) => store.commit('abandonDraft', { id }))
|
||||
await deleteDraftFromStorage(ids)
|
||||
},
|
||||
async loadDrafts(store) {
|
||||
const currentData = await getStorageData()
|
||||
store.commit('loadDrafts', currentData)
|
||||
},
|
||||
}
|
||||
|
||||
export const getters = {
|
||||
draftsByTypeAndRefId(state) {
|
||||
return (type, refId) => {
|
||||
return Object.values(state.drafts).filter(
|
||||
(draft) => draft.type === type && draft.refId === refId,
|
||||
)
|
||||
}
|
||||
},
|
||||
draftsArray(state) {
|
||||
return Object.values(state.drafts)
|
||||
},
|
||||
draftCount(state) {
|
||||
return Object.values(state.drafts).length
|
||||
},
|
||||
}
|
||||
|
||||
const drafts = {
|
||||
state: defaultState,
|
||||
mutations,
|
||||
getters,
|
||||
actions,
|
||||
}
|
||||
|
||||
export default drafts
|
||||
|
|
@ -1,5 +1 @@
|
|||
import drafts from './drafts.js'
|
||||
|
||||
export default {
|
||||
drafts,
|
||||
}
|
||||
export default {}
|
||||
|
|
|
|||
75
src/stores/drafts.js
Normal file
75
src/stores/drafts.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { defineStore } from 'pinia'
|
||||
import { storage } from 'src/lib/storage.js'
|
||||
|
||||
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 (ids) => {
|
||||
const currentData = await getStorageData() ?? {}
|
||||
ids.forEach((id) => {
|
||||
delete currentData[id]
|
||||
})
|
||||
await storage.setItem(storageKey, currentData)
|
||||
}
|
||||
|
||||
export const useDraftsStore = defineStore('drafts', {
|
||||
state: () => ({
|
||||
drafts: new Map()
|
||||
}),
|
||||
getters: {
|
||||
draftsByTypeAndRefId(state) {
|
||||
return (type, refId) => {
|
||||
return [...state.drafts.values()].filter(
|
||||
(draft) => draft.type === type && draft.refId === refId,
|
||||
)
|
||||
}
|
||||
},
|
||||
draftsArray(state) {
|
||||
return [...state.drafts.values()]
|
||||
},
|
||||
draftsCount(state) {
|
||||
return state.drafts.size
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async abandonDraft(id) {
|
||||
this.drafts.delete(id)
|
||||
await deleteDraftFromStorage([id])
|
||||
},
|
||||
async loadDrafts() {
|
||||
const currentData = await getStorageData()
|
||||
this.drafts = new Map(Object.entries(currentData))
|
||||
},
|
||||
async addOrSaveDraft(draft) {
|
||||
const id = draft.id ?? new Date().getTime().toString()
|
||||
const draftWithId = { ...draft, id }
|
||||
this.drafts.set(draft.id, draftWithId)
|
||||
await saveDraftToStorage(draftWithId)
|
||||
return id
|
||||
},
|
||||
async abandonAllDrafts(store) {
|
||||
const ids = this.drafts.keys()
|
||||
ids.forEach((id) => this.abandonDraft(id))
|
||||
await deleteDraftFromStorage(ids)
|
||||
},
|
||||
}
|
||||
})
|
||||
|
|
@ -21,6 +21,7 @@ import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|||
import { useProfileConfigStore } from 'src/stores/profile_config.js'
|
||||
import { useTimelinesStore } from 'src/stores/timelines.js'
|
||||
import { useUserHighlightStore } from 'src/stores/user_highlight.js'
|
||||
import { useDraftsStore } from 'src/stores/drafts.js'
|
||||
|
||||
import { revokeToken } from 'src/api/oauth.js'
|
||||
import {
|
||||
|
|
@ -700,7 +701,7 @@ export const useUsersStore = defineStore('users', {
|
|||
useAnnouncementsStore().startFetching()
|
||||
|
||||
this.fetchMutes()
|
||||
dispatch('loadDrafts')
|
||||
useDraftsStore().loadDrafts()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue