Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85804286
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
25 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
rPUFE pleroma-fe-upstream
Attached
Detach File
Event Timeline
Log In to Comment