Page MenuHomePhorge

No OneTemporary

Size
25 KB
Referenced Files
None
Subscribers
None
diff --git a/changelog.d/migrate-bookmark-folders-store-pinia.skip b/changelog.d/migrate-bookmark-folders-store-pinia.skip
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/components/bookmark_folder_edit/bookmark_folder_edit.js b/src/components/bookmark_folder_edit/bookmark_folder_edit.js
index 4ed440eb7b..bb96585bfe 100644
--- a/src/components/bookmark_folder_edit/bookmark_folder_edit.js
+++ b/src/components/bookmark_folder_edit/bookmark_folder_edit.js
@@ -1,80 +1,82 @@
import EmojiPicker from '../emoji_picker/emoji_picker.vue'
import apiService from '../../services/api/api.service'
+import { useInterfaceStore } from 'src/stores/interface'
+import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
const BookmarkFolderEdit = {
data () {
return {
name: '',
nameDraft: '',
emoji: '',
emojiUrl: null,
emojiDraft: '',
emojiUrlDraft: null,
emojiPickerExpanded: false,
reallyDelete: false
}
},
components: {
EmojiPicker
},
created () {
if (!this.id) return
const credentials = this.$store.state.users.currentUser.credentials
apiService.fetchBookmarkFolders({ credentials })
.then((folders) => {
const folder = folders.find(folder => folder.id === this.id)
if (!folder) return
this.nameDraft = this.name = folder.name
this.emojiDraft = this.emoji = folder.emoji
this.emojiUrlDraft = this.emojiUrl = folder.emoji_url
})
},
computed: {
id () {
return this.$route.params.id
}
},
methods: {
selectEmoji (event) {
this.emojiDraft = event.insertion
this.emojiUrlDraft = event.insertionUrl
},
showEmojiPicker () {
if (!this.emojiPickerExpanded) {
this.$refs.picker.showPicker()
}
},
onShowPicker () {
this.emojiPickerExpanded = true
},
onClosePicker () {
this.emojiPickerExpanded = false
},
updateFolder () {
- this.$store.dispatch('setBookmarkFolder', { folderId: this.id, name: this.nameDraft, emoji: this.emojiDraft })
+ useBookmarkFoldersStore().updateBookmarkFolder({ folderId: this.id, name: this.nameDraft, emoji: this.emojiDraft })
.then(() => {
this.$router.push({ name: 'bookmark-folders' })
})
},
createFolder () {
- this.$store.dispatch('createBookmarkFolder', { name: this.nameDraft, emoji: this.emojiDraft })
+ useBookmarkFoldersStore().createBookmarkFolder({ name: this.nameDraft, emoji: this.emojiDraft })
.then(() => {
this.$router.push({ name: 'bookmark-folders' })
})
.catch((e) => {
- this.$store.useInterfaceStore().pushGlobalNotice({
+ useInterfaceStore().pushGlobalNotice({
messageKey: 'bookmark_folders.error',
messageArgs: [e.message],
level: 'error'
})
})
},
deleteFolder () {
- this.$store.dispatch('deleteBookmarkFolder', { folderId: this.id })
+ useBookmarkFoldersStore().deleteBookmarkFolder({ folderId: this.id })
this.$router.push({ name: 'bookmark-folders' })
}
}
}
export default BookmarkFolderEdit
diff --git a/src/components/bookmark_folders/bookmark_folders.js b/src/components/bookmark_folders/bookmark_folders.js
index 9f1f1fed07..096f3769d5 100644
--- a/src/components/bookmark_folders/bookmark_folders.js
+++ b/src/components/bookmark_folders/bookmark_folders.js
@@ -1,27 +1,28 @@
import BookmarkFolderCard from '../bookmark_folder_card/bookmark_folder_card.vue'
+import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
const BookmarkFolders = {
data () {
return {
isNew: false
}
},
components: {
BookmarkFolderCard
},
computed: {
bookmarkFolders () {
- return this.$store.state.bookmarkFolders.allFolders
+ return useBookmarkFoldersStore().allFolders
}
},
methods: {
cancelNewFolder () {
this.isNew = false
},
newFolder () {
this.isNew = true
}
}
}
export default BookmarkFolders
diff --git a/src/components/bookmark_folders_menu/bookmark_folders_menu_content.js b/src/components/bookmark_folders_menu/bookmark_folders_menu_content.js
index 43db7df323..dc46b91b34 100644
--- a/src/components/bookmark_folders_menu/bookmark_folders_menu_content.js
+++ b/src/components/bookmark_folders_menu/bookmark_folders_menu_content.js
@@ -1,19 +1,20 @@
-import { mapState } from 'vuex'
+import { mapState } from 'pinia'
import NavigationEntry from 'src/components/navigation/navigation_entry.vue'
import { getBookmarkFolderEntries } from 'src/components/navigation/filter.js'
+import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
export const BookmarkFoldersMenuContent = {
props: [
'showPin'
],
components: {
NavigationEntry
},
computed: {
- ...mapState({
+ ...mapState(useBookmarkFoldersStore, {
folders: getBookmarkFolderEntries
})
}
}
export default BookmarkFoldersMenuContent
diff --git a/src/components/navigation/filter.js b/src/components/navigation/filter.js
index 0974bc1e39..12ab9266e4 100644
--- a/src/components/navigation/filter.js
+++ b/src/components/navigation/filter.js
@@ -1,29 +1,29 @@
export const filterNavigation = (list = [], { hasChats, hasAnnouncements, isFederating, isPrivate, currentUser, supportsBookmarkFolders }) => {
return list.filter(({ criteria, anon, anonRoute }) => {
const set = new Set(criteria || [])
if (!isFederating && set.has('federating')) return false
if (!currentUser && isPrivate && set.has('!private')) return false
if (!currentUser && !(anon || anonRoute)) return false
if ((!currentUser || !currentUser.locked) && set.has('lockedUser')) return false
if (!hasChats && set.has('chats')) return false
if (!hasAnnouncements && set.has('announcements')) return false
if (supportsBookmarkFolders && set.has('!supportsBookmarkFolders')) return false
return true
})
}
export const getListEntries = store => store.allLists.map(list => ({
name: 'list-' + list.id,
routeObject: { name: 'lists-timeline', params: { id: list.id } },
labelRaw: list.title,
iconLetter: list.title[0]
}))
-export const getBookmarkFolderEntries = state => state.bookmarkFolders.allFolders.map(folder => ({
+export const getBookmarkFolderEntries = store => store.allFolders.map(folder => ({
name: 'bookmark-folder-' + folder.id,
routeObject: { name: 'bookmark-folder', params: { id: folder.id } },
labelRaw: folder.name,
iconEmoji: folder.emoji,
iconEmojiUrl: folder.emoji_url,
iconLetter: folder.name[0]
}))
diff --git a/src/components/navigation/navigation_pins.js b/src/components/navigation/navigation_pins.js
index e657e94a02..f9cdef71b1 100644
--- a/src/components/navigation/navigation_pins.js
+++ b/src/components/navigation/navigation_pins.js
@@ -1,104 +1,107 @@
import { mapState } from 'vuex'
import { mapState as mapPiniaState } from 'pinia'
import { TIMELINES, ROOT_ITEMS, routeTo } from 'src/components/navigation/navigation.js'
import { getBookmarkFolderEntries, getListEntries, filterNavigation } from 'src/components/navigation/filter.js'
import StillImage from 'src/components/still-image/still-image.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faUsers,
faGlobe,
faBookmark,
faEnvelope,
faComments,
faBell,
faInfoCircle,
faStream,
faList
} from '@fortawesome/free-solid-svg-icons'
import { useListsStore } from 'src/stores/lists'
import { useAnnouncementsStore } from 'src/stores/announcements'
+import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
library.add(
faUsers,
faGlobe,
faBookmark,
faEnvelope,
faComments,
faBell,
faInfoCircle,
faStream,
faList
)
const NavPanel = {
props: ['limit'],
methods: {
getRouteTo (item) {
return routeTo(item, this.currentUser)
}
},
components: {
StillImage
},
computed: {
getters () {
return this.$store.getters
},
...mapPiniaState(useListsStore, {
lists: getListEntries
}),
...mapPiniaState(useAnnouncementsStore, {
supportsAnnouncements: store => store.supportsAnnouncements
}),
+ ...mapPiniaState(useBookmarkFoldersStore, {
+ bookmarks: getBookmarkFolderEntries
+ }),
...mapState({
- bookmarks: getBookmarkFolderEntries,
currentUser: state => state.users.currentUser,
followRequestCount: state => state.api.followRequests.length,
privateMode: state => state.instance.private,
federating: state => state.instance.federating,
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable,
pinnedItems: state => new Set(state.serverSideStorage.prefsStorage.collections.pinnedNavItems)
}),
pinnedList () {
if (!this.currentUser) {
return filterNavigation([
{ ...TIMELINES.public, name: 'public' },
{ ...TIMELINES.twkn, name: 'twkn' },
{ ...ROOT_ITEMS.about, name: 'about' }
],
{
hasChats: this.pleromaChatMessagesAvailable,
hasAnnouncements: this.supportsAnnouncements,
isFederating: this.federating,
isPrivate: this.privateMode,
currentUser: this.currentUser
})
}
return filterNavigation(
[
...Object
.entries({ ...TIMELINES })
.filter(([k]) => this.pinnedItems.has(k))
.map(([k, v]) => ({ ...v, name: k })),
...this.lists.filter((k) => this.pinnedItems.has(k.name)),
...this.bookmarks.filter((k) => this.pinnedItems.has(k.name)),
...Object
.entries({ ...ROOT_ITEMS })
.filter(([k]) => this.pinnedItems.has(k))
.map(([k, v]) => ({ ...v, name: k }))
],
{
hasChats: this.pleromaChatMessagesAvailable,
hasAnnouncements: this.supportsAnnouncements,
isFederating: this.federating,
isPrivate: this.privateMode,
currentUser: this.currentUser
}
).slice(0, this.limit)
}
}
}
export default NavPanel
diff --git a/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.js b/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.js
index 573134909d..72d4f6fda8 100644
--- a/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.js
+++ b/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.js
@@ -1,41 +1,42 @@
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronRight, faFolder } from '@fortawesome/free-solid-svg-icons'
-import { mapState } from 'vuex'
+import { mapState } from 'pinia'
+import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
import Popover from 'src/components/popover/popover.vue'
import StillImage from 'src/components/still-image/still-image.vue'
library.add(faChevronRight, faFolder)
const StatusBookmarkFolderMenu = {
props: [
'status',
'close'
],
data () {
return {}
},
components: {
Popover,
StillImage
},
computed: {
- ...mapState({
- folders: state => state.bookmarkFolders.allFolders
+ ...mapState(useBookmarkFoldersStore, {
+ folders: store => store.allFolders
}),
folderId () {
return this.status.bookmark_folder_id
}
},
methods: {
toggleFolder (id) {
const value = id === this.folderId ? null : id
this.$store.dispatch('bookmark', { id: this.status.id, bookmark_folder_id: value })
.then(() => this.$emit('onSuccess'))
.catch(err => this.$emit('onError', err.error.error))
}
}
}
export default StatusBookmarkFolderMenu
diff --git a/src/components/timeline_menu/timeline_menu.js b/src/components/timeline_menu/timeline_menu.js
index 985efe81b4..700ab3a4ce 100644
--- a/src/components/timeline_menu/timeline_menu.js
+++ b/src/components/timeline_menu/timeline_menu.js
@@ -1,111 +1,112 @@
import Popover from '../popover/popover.vue'
import NavigationEntry from 'src/components/navigation/navigation_entry.vue'
import { mapState } from 'vuex'
import { ListsMenuContent } from '../lists_menu/lists_menu_content.vue'
import { BookmarkFoldersMenuContent } from '../bookmark_folders_menu/bookmark_folders_menu_content.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { TIMELINES } from 'src/components/navigation/navigation.js'
import { filterNavigation } from 'src/components/navigation/filter.js'
import {
faChevronDown
} from '@fortawesome/free-solid-svg-icons'
import { useInterfaceStore } from 'src/stores/interface'
import { useListsStore } from 'src/stores/lists'
+import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
library.add(faChevronDown)
// Route -> i18n key mapping, exported and not in the computed
// because nav panel benefits from the same information.
export const timelineNames = (supportsBookmarkFolders) => {
return {
friends: 'nav.home_timeline',
bookmarks: supportsBookmarkFolders ? 'nav.all_bookmarks' : 'nav.bookmarks',
dms: 'nav.dms',
'public-timeline': 'nav.public_tl',
'public-external-timeline': 'nav.twkn',
quotes: 'nav.quotes'
}
}
const TimelineMenu = {
components: {
Popover,
NavigationEntry,
ListsMenuContent,
BookmarkFoldersMenuContent
},
data () {
return {
isOpen: false
}
},
created () {
if (timelineNames(this.bookmarkFolders)[this.$route.name]) {
useInterfaceStore().setLastTimeline(this.$route.name)
}
},
computed: {
useListsMenu () {
const route = this.$route.name
return route === 'lists-timeline'
},
useBookmarkFoldersMenu () {
const route = this.$route.name
return this.bookmarkFolders && (route === 'bookmark-folder' || route === 'bookmarks')
},
...mapState({
currentUser: state => state.users.currentUser,
privateMode: state => state.instance.private,
federating: state => state.instance.federating,
bookmarkFolders: state => state.instance.pleromaBookmarkFoldersAvailable
}),
timelinesList () {
return filterNavigation(
Object.entries(TIMELINES).map(([k, v]) => ({ ...v, name: k })),
{
hasChats: this.pleromaChatMessagesAvailable,
isFederating: this.federating,
isPrivate: this.privateMode,
currentUser: this.currentUser,
supportsBookmarkFolders: this.bookmarkFolders
}
)
}
},
methods: {
openMenu () {
// $nextTick is too fast, animation won't play back but
// instead starts in fully open position. Low values
// like 1-5 work on fast machines but not on mobile, 25
// seems like a good compromise that plays without significant
// added lag.
setTimeout(() => {
this.isOpen = true
}, 25)
},
blockOpen (event) {
// For the blank area inside the button element.
// Just setting @click.stop="" makes unintuitive behavior when
// menu is open and clicking on the blank area doesn't close it.
if (!this.isOpen) {
event.stopPropagation()
}
},
timelineName () {
const route = this.$route.name
if (route === 'tag-timeline') {
return '#' + this.$route.params.tag
}
if (route === 'lists-timeline') {
return useListsStore().findListTitle(this.$route.params.id)
}
if (route === 'bookmark-folder') {
- return this.$store.getters.findBookmarkFolderName(this.$route.params.id)
+ return useBookmarkFoldersStore().findBookmarkFolderName(this.$route.params.id)
}
const i18nkey = timelineNames(this.bookmarkFolders)[this.$route.name]
return i18nkey ? this.$t(i18nkey) : route
}
}
}
export default TimelineMenu
diff --git a/src/main.js b/src/main.js
index 985bc4c2bd..a7571578a7 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,130 +1,128 @@
/* global process */
import { createStore } from 'vuex'
import { createPinia } from 'pinia'
import 'custom-event-polyfill'
import './lib/event_target_polyfill.js'
import instanceModule from './modules/instance.js'
import statusesModule from './modules/statuses.js'
import notificationsModule from './modules/notifications.js'
import usersModule from './modules/users.js'
import apiModule from './modules/api.js'
import configModule from './modules/config.js'
import profileConfigModule from './modules/profileConfig.js'
import serverSideStorageModule from './modules/serverSideStorage.js'
import adminSettingsModule from './modules/adminSettings.js'
import oauthModule from './modules/oauth.js'
import authFlowModule from './modules/auth_flow.js'
import oauthTokensModule from './modules/oauth_tokens.js'
import draftsModule from './modules/drafts.js'
import chatsModule from './modules/chats.js'
-import bookmarkFoldersModule from './modules/bookmark_folders.js'
import { createI18n } from 'vue-i18n'
import createPersistedState from './lib/persisted_state.js'
import pushNotifications from './lib/push_notifications_plugin.js'
import messages from './i18n/messages.js'
import afterStoreSetup from './boot/after_store.js'
const currentLocale = (window.navigator.language || 'en').split('-')[0]
const i18n = createI18n({
// By default, use the browser locale, we will update it if neccessary
locale: 'en',
fallbackLocale: 'en',
messages: messages.default
})
messages.setLanguage(i18n.global, currentLocale)
const persistedStateOptions = {
paths: [
'serverSideStorage.cache',
'config',
'users.lastLoginName',
'oauth'
]
};
(async () => {
const isFox = Math.floor(Math.random() * 2) > 0 ? '_fox' : ''
const splashError = (i18n, e) => {
const throbber = document.querySelector('#throbber')
throbber.addEventListener('animationend', () => {
document.querySelector('#mascot').src = `/static/pleromatan_orz${isFox}.png`
})
throbber.classList.add('dead')
document.querySelector('#status').textContent = i18n.global.t('splash.error')
console.error('PleromaFE failed to initialize: ', e)
document.querySelector('#statusError').textContent = e
document.querySelector('#statusStack').textContent = e.stack
document.querySelector('#statusError').style = 'display: block'
document.querySelector('#statusStack').style = 'display: block'
}
window.splashError = e => splashError(i18n, e)
window.splashUpdate = key => {
if (document.querySelector('#status')) {
document.querySelector('#status').textContent = i18n.global.t(key)
}
}
try {
let storageError
const plugins = [pushNotifications]
const pinia = createPinia()
try {
const persistedState = await createPersistedState(persistedStateOptions)
plugins.push(persistedState)
} catch (e) {
console.error('Storage error', e)
storageError = e
}
document.querySelector('#mascot').src = `/static/pleromatan_apology${isFox}_small.webp`
document.querySelector('#status').removeAttribute('class')
document.querySelector('#status').textContent = i18n.global.t('splash.loading')
document.querySelector('#splash-credit').textContent = i18n.global.t('update.art_by', { linkToArtist: 'pipivovott' })
const store = createStore({
modules: {
instance: instanceModule,
// TODO refactor users/statuses modules, they depend on each other
users: usersModule,
statuses: statusesModule,
notifications: notificationsModule,
api: apiModule,
config: configModule,
profileConfig: profileConfigModule,
serverSideStorage: serverSideStorageModule,
adminSettings: adminSettingsModule,
oauth: oauthModule,
authFlow: authFlowModule,
oauthTokens: oauthTokensModule,
drafts: draftsModule,
- chats: chatsModule,
- bookmarkFolders: bookmarkFoldersModule
+ chats: chatsModule
},
plugins,
options: {
devtools: process.env.NODE_ENV !== 'production'
},
strict: false // Socket modifies itself, let's ignore this for now.
// strict: process.env.NODE_ENV !== 'production'
})
window.vuex = store
// Temporarily passing pinia and vuex stores along with storageError result until migration is fully complete.
return await afterStoreSetup({ pinia, store, storageError, i18n })
} catch (e) {
splashError(i18n, e)
}
})()
// These are inlined by webpack's DefinePlugin
/* eslint-disable */
window.___pleromafe_mode = process.env
window.___pleromafe_commit_hash = COMMIT_HASH
window.___pleromafe_dev_overrides = DEV_OVERRIDES
diff --git a/src/modules/bookmark_folders.js b/src/modules/bookmark_folders.js
deleted file mode 100644
index c276adf4b0..0000000000
--- a/src/modules/bookmark_folders.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import { remove, find } from 'lodash'
-
-export const defaultState = {
- allFolders: []
-}
-
-export const mutations = {
- setBookmarkFolders (state, value) {
- state.allFolders = value
- },
- setBookmarkFolder (state, { id, name, emoji, emoji_url: emojiUrl }) {
- const entry = find(state.allFolders, { id })
- if (!entry) {
- state.allFolders.push({ id, name, emoji, emoji_url: emojiUrl })
- } else {
- entry.name = name
- entry.emoji = emoji
- entry.emoji_url = emojiUrl
- }
- },
- deleteBookmarkFolder (state, { folderId }) {
- remove(state.allFolders, folder => folder.id === folderId)
- }
-}
-
-const actions = {
- setBookmarkFolders ({ commit }, value) {
- commit('setBookmarkFolders', value)
- },
- createBookmarkFolder ({ rootState, commit }, { name, emoji }) {
- return rootState.api.backendInteractor.createBookmarkFolder({ name, emoji })
- .then((folder) => {
- commit('setBookmarkFolder', folder)
- return folder
- })
- },
- setBookmarkFolder ({ rootState, commit }, { folderId, name, emoji }) {
- return rootState.api.backendInteractor.updateBookmarkFolder({ folderId, name, emoji })
- .then((folder) => {
- commit('setBookmarkFolder', folder)
- return folder
- })
- },
- deleteBookmarkFolder ({ rootState, commit }, { folderId }) {
- rootState.api.backendInteractor.deleteBookmarkFolder({ folderId })
- commit('deleteBookmarkFolder', { folderId })
- }
-}
-
-export const getters = {
- findBookmarkFolderName: state => id => {
- const folder = state.allFolders.find(folder => folder.id === id)
-
- if (!folder) return
- return folder.name
- }
-}
-
-const bookmarkFolders = {
- state: defaultState,
- mutations,
- actions,
- getters
-}
-
-export default bookmarkFolders
diff --git a/src/services/bookmark_folders_fetcher/bookmark_folders_fetcher.service.js b/src/services/bookmark_folders_fetcher/bookmark_folders_fetcher.service.js
index 2181ab67bf..ac83311cae 100644
--- a/src/services/bookmark_folders_fetcher/bookmark_folders_fetcher.service.js
+++ b/src/services/bookmark_folders_fetcher/bookmark_folders_fetcher.service.js
@@ -1,22 +1,23 @@
import apiService from '../api/api.service.js'
import { promiseInterval } from '../promise_interval/promise_interval.js'
+import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
-const fetchAndUpdate = ({ store, credentials }) => {
+const fetchAndUpdate = ({ credentials }) => {
return apiService.fetchBookmarkFolders({ credentials })
.then(bookmarkFolders => {
- store.commit('setBookmarkFolders', bookmarkFolders)
+ useBookmarkFoldersStore().setBookmarkFolders(bookmarkFolders)
}, () => {})
.catch(() => {})
}
const startFetching = ({ credentials, store }) => {
const boundFetchAndUpdate = () => fetchAndUpdate({ credentials, store })
boundFetchAndUpdate()
return promiseInterval(boundFetchAndUpdate, 240000)
}
const bookmarkFoldersFetcher = {
startFetching
}
export default bookmarkFoldersFetcher
diff --git a/src/stores/bookmark_folders.js b/src/stores/bookmark_folders.js
new file mode 100644
index 0000000000..79f373b0ad
--- /dev/null
+++ b/src/stores/bookmark_folders.js
@@ -0,0 +1,51 @@
+import { remove, find } from 'lodash'
+import { defineStore } from 'pinia'
+
+export const useBookmarkFoldersStore = defineStore('bookmarkFolders', {
+ state: () => ({
+ allFolders: []
+ }),
+ getters: {
+ findBookmarkFolderName () {
+ return (id) => {
+ const folder = this.allFolders.find(folder => folder.id === id)
+
+ if (!folder) return
+ return folder.name
+ }
+ }
+ },
+ actions: {
+ setBookmarkFolders (value) {
+ this.allFolders = value
+ },
+ setBookmarkFolder ({ id, name, emoji, emoji_url: emojiUrl }) {
+ const entry = find(this.allFolders, { id })
+ if (!entry) {
+ this.allFolders.push({ id, name, emoji, emoji_url: emojiUrl })
+ } else {
+ entry.name = name
+ entry.emoji = emoji
+ entry.emoji_url = emojiUrl
+ }
+ },
+ createBookmarkFolder ({ name, emoji }) {
+ return window.vuex.state.api.backendInteractor.createBookmarkFolder({ name, emoji })
+ .then((folder) => {
+ this.setBookmarkFolder(folder)
+ return folder
+ })
+ },
+ updateBookmarkFolder ({ folderId, name, emoji }) {
+ return window.vuex.state.api.backendInteractor.updateBookmarkFolder({ folderId, name, emoji })
+ .then((folder) => {
+ this.setBookmarkFolder(folder)
+ return folder
+ })
+ },
+ deleteBookmarkFolder ({ folderId }) {
+ window.vuex.state.api.backendInteractor.deleteBookmarkFolder({ folderId })
+ remove(this.allFolders, folder => folder.id === folderId)
+ }
+ }
+})

File Metadata

Mime Type
text/x-diff
Expires
Sat, Oct 10, 1:40 AM (1 d, 15 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1784985
Default Alt Text
(25 KB)

Event Timeline