first pass of migration - states and obvious replacements

This commit is contained in:
Henry Jameson 2026-01-29 00:49:26 +02:00
commit 24ce2dc0a5
66 changed files with 398 additions and 568 deletions

View file

@ -2,6 +2,7 @@ import { throttle } from 'lodash'
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { useInstanceStore } from 'src/stores/instance.js'
import DesktopNav from './components/desktop_nav/desktop_nav.vue' import DesktopNav from './components/desktop_nav/desktop_nav.vue'
import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue' import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue'
import FeaturesPanel from './components/features_panel/features_panel.vue' import FeaturesPanel from './components/features_panel/features_panel.vue'
@ -136,7 +137,7 @@ export default {
instanceBackground() { instanceBackground() {
return this.mergedConfig.hideInstanceWallpaper return this.mergedConfig.hideInstanceWallpaper
? null ? null
: this.$store.state.instance.background : useInstanceStore().background
}, },
background() { background() {
return this.userBackground || this.instanceBackground return this.userBackground || this.instanceBackground
@ -152,13 +153,13 @@ export default {
return useShoutStore().joined return useShoutStore().joined
}, },
suggestionsEnabled() { suggestionsEnabled() {
return this.$store.state.instance.suggestionsEnabled return useInstanceStore().suggestionsEnabled
}, },
showInstanceSpecificPanel() { showInstanceSpecificPanel() {
return ( return (
this.$store.state.instance.showInstanceSpecificPanel && useInstanceStore().showInstanceSpecificPanel &&
!this.$store.getters.mergedConfig.hideISP && !this.$store.getters.mergedConfig.hideISP &&
this.$store.state.instance.instanceSpecificPanelContent useInstanceStore().instanceSpecificPanelContent
) )
}, },
isChats() { isChats() {
@ -176,10 +177,10 @@ export default {
) )
}, },
showFeaturesPanel() { showFeaturesPanel() {
return this.$store.state.instance.showFeaturesPanel return useInstanceStore().showFeaturesPanel
}, },
editingAvailable() { editingAvailable() {
return this.$store.state.instance.editingAvailable return useInstanceStore().editingAvailable
}, },
shoutboxPosition() { shoutboxPosition() {
return this.$store.getters.mergedConfig.alwaysShowNewPostButton || false return this.$store.getters.mergedConfig.alwaysShowNewPostButton || false
@ -191,7 +192,7 @@ export default {
return useInterfaceStore().layoutType return useInterfaceStore().layoutType
}, },
privateMode() { privateMode() {
return this.$store.state.instance.private return useInstanceStore().private
}, },
reverseLayout() { reverseLayout() {
const { thirdColumnMode, sidebarRight: reverseSetting } = const { thirdColumnMode, sidebarRight: reverseSetting } =

View file

@ -28,6 +28,7 @@ import UserProfile from 'components/user_profile/user_profile.vue'
import WhoToFollow from 'components/who_to_follow/who_to_follow.vue' import WhoToFollow from 'components/who_to_follow/who_to_follow.vue'
import NavPanel from 'src/components/nav_panel/nav_panel.vue' import NavPanel from 'src/components/nav_panel/nav_panel.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import BookmarkFolderEdit from '../components/bookmark_folder_edit/bookmark_folder_edit.vue' import BookmarkFolderEdit from '../components/bookmark_folder_edit/bookmark_folder_edit.vue'
import BookmarkFolders from '../components/bookmark_folders/bookmark_folders.vue' import BookmarkFolders from '../components/bookmark_folders/bookmark_folders.vue'
import QuotesTimeline from '../components/quotes_timeline/quotes_timeline.vue' import QuotesTimeline from '../components/quotes_timeline/quotes_timeline.vue'
@ -37,7 +38,7 @@ export default (store) => {
if (store.state.users.currentUser) { if (store.state.users.currentUser) {
next() next()
} else { } else {
next(store.state.instance.redirectRootNoLogin || '/main/all') next(useInstanceStore().redirectRootNoLogin || '/main/all')
} }
} }
@ -48,8 +49,8 @@ export default (store) => {
redirect: () => { redirect: () => {
return ( return (
(store.state.users.currentUser (store.state.users.currentUser
? store.state.instance.redirectRootLogin ? useInstanceStore().redirectRootLogin
: store.state.instance.redirectRootNoLogin) || '/main/all' : useInstanceStore().redirectRootNoLogin) || '/main/all'
) )
}, },
}, },
@ -200,7 +201,7 @@ export default (store) => {
}, },
] ]
if (store.state.instance.pleromaChatMessagesAvailable) { if (useInstanceStore().pleromaChatMessagesAvailable) {
routes = routes.concat([ routes = routes.concat([
{ {
name: 'chat', name: 'chat',

View file

@ -1,3 +1,4 @@
import { useInstanceStore } from 'src/stores/instance.js'
import FeaturesPanel from '../features_panel/features_panel.vue' import FeaturesPanel from '../features_panel/features_panel.vue'
import InstanceSpecificPanel from '../instance_specific_panel/instance_specific_panel.vue' import InstanceSpecificPanel from '../instance_specific_panel/instance_specific_panel.vue'
import MRFTransparencyPanel from '../mrf_transparency_panel/mrf_transparency_panel.vue' import MRFTransparencyPanel from '../mrf_transparency_panel/mrf_transparency_panel.vue'
@ -14,13 +15,13 @@ const About = {
}, },
computed: { computed: {
showFeaturesPanel() { showFeaturesPanel() {
return this.$store.state.instance.showFeaturesPanel return useInstanceStore().showFeaturesPanel
}, },
showInstanceSpecificPanel() { showInstanceSpecificPanel() {
return ( return (
this.$store.state.instance.showInstanceSpecificPanel && useInstanceStore().showInstanceSpecificPanel &&
!this.$store.getters.mergedConfig.hideISP && !this.$store.getters.mergedConfig.hideISP &&
this.$store.state.instance.instanceSpecificPanelContent useInstanceStore().instanceSpecificPanelContent
) )
}, },
}, },

View file

@ -2,6 +2,7 @@ import { mapState } from 'vuex'
import UserListMenu from 'src/components/user_list_menu/user_list_menu.vue' import UserListMenu from 'src/components/user_list_menu/user_list_menu.vue'
import UserTimedFilterModal from 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue' import UserTimedFilterModal from 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useReportsStore } from 'src/stores/reports' import { useReportsStore } from 'src/stores/reports'
import ConfirmModal from '../confirm_modal/confirm_modal.vue' import ConfirmModal from '../confirm_modal/confirm_modal.vue'
import Popover from '../popover/popover.vue' import Popover from '../popover/popover.vue'
@ -93,9 +94,9 @@ const AccountActions = {
return this.$store.getters.mergedConfig.modalOnRemoveUserFromFollowers return this.$store.getters.mergedConfig.modalOnRemoveUserFromFollowers
}, },
...mapState({ ...mapState({
blockExpirationSupported: (state) => state.instance.blockExpiration, blockExpirationSupported: (state) => useInstanceStore().blockExpiration,
pleromaChatMessagesAvailable: (state) => pleromaChatMessagesAvailable: (state) =>
state.instance.pleromaChatMessagesAvailable, useInstanceStore().pleromaChatMessagesAvailable,
}), }),
}, },
} }

View file

@ -1,5 +1,6 @@
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { useInstanceStore } from 'src/stores/instance.js'
import { useMediaViewerStore } from 'src/stores/media_viewer' import { useMediaViewerStore } from 'src/stores/media_viewer'
import nsfwImage from '../../assets/nsfw.png' import nsfwImage from '../../assets/nsfw.png'
import fileTypeService from '../../services/file_type/file_type.service.js' import fileTypeService from '../../services/file_type/file_type.service.js'
@ -53,7 +54,7 @@ const Attachment = {
data() { data() {
return { return {
localDescription: this.description || this.attachment.description, localDescription: this.description || this.attachment.description,
nsfwImage: this.$store.state.instance.nsfwCensorImage || nsfwImage, nsfwImage: useInstanceStore().nsfwCensorImage || nsfwImage,
hideNsfwLocal: this.$store.getters.mergedConfig.hideNsfw, hideNsfwLocal: this.$store.getters.mergedConfig.hideNsfw,
preloadImage: this.$store.getters.mergedConfig.preloadImage, preloadImage: this.$store.getters.mergedConfig.preloadImage,
loading: false, loading: false,
@ -104,7 +105,7 @@ const Attachment = {
return 'file' return 'file'
}, },
referrerpolicy() { referrerpolicy() {
return this.$store.state.instance.mediaProxyAvailable ? '' : 'no-referrer' return useInstanceStore().mediaProxyAvailable ? '' : 'no-referrer'
}, },
type() { type() {
return fileTypeService.fileType(this.attachment.mimetype) return fileTypeService.fileType(this.attachment.mimetype)

View file

@ -1,4 +1,5 @@
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { useInstanceStore } from 'src/stores/instance.js'
import UserAvatar from '../user_avatar/user_avatar.vue' import UserAvatar from '../user_avatar/user_avatar.vue'
const AvatarList = { const AvatarList = {
@ -16,7 +17,7 @@ const AvatarList = {
return generateProfileLink( return generateProfileLink(
user.id, user.id,
user.screen_name, user.screen_name,
this.$store.state.instance.restrictedNicknames, useInstanceStore().restrictedNicknames,
) )
}, },
}, },

View file

@ -1,5 +1,6 @@
import RichContent from 'src/components/rich_content/rich_content.jsx' import RichContent from 'src/components/rich_content/rich_content.jsx'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { useInstanceStore } from 'src/stores/instance.js'
import UserAvatar from '../user_avatar/user_avatar.vue' import UserAvatar from '../user_avatar/user_avatar.vue'
import UserLink from '../user_link/user_link.vue' import UserLink from '../user_link/user_link.vue'
import UserPopover from '../user_popover/user_popover.vue' import UserPopover from '../user_popover/user_popover.vue'
@ -17,7 +18,7 @@ const BasicUserCard = {
return generateProfileLink( return generateProfileLink(
user.id, user.id,
user.screen_name, user.screen_name,
this.$store.state.instance.restrictedNicknames, useInstanceStore().restrictedNicknames,
) )
}, },
}, },

View file

@ -1,5 +1,6 @@
import { mapState } from 'vuex' import { mapState } from 'pinia'
import { useInstanceStore } from 'src/stores/instance.js'
import BasicUserCard from '../basic_user_card/basic_user_card.vue' import BasicUserCard from '../basic_user_card/basic_user_card.vue'
const BlockCard = { const BlockCard = {
@ -25,7 +26,7 @@ const BlockCard = {
]) ])
}, },
...mapState({ ...mapState({
blockExpirationSupported: (state) => state.instance.blockExpiration, blockExpirationSupported: (store) => store.blockExpiration,
}), }),
}, },
components: { components: {

View file

@ -2,6 +2,7 @@ import { mapState as mapPiniaState } from 'pinia'
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import { mapGetters, mapState } from 'vuex' import { mapGetters, mapState } from 'vuex'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
import Attachment from '../attachment/attachment.vue' import Attachment from '../attachment/attachment.vue'
import ChatMessageDate from '../chat_message_date/chat_message_date.vue' import ChatMessageDate from '../chat_message_date/chat_message_date.vue'
@ -74,7 +75,7 @@ const ChatMessage = {
}), }),
...mapState({ ...mapState({
currentUser: (state) => state.users.currentUser, currentUser: (state) => state.users.currentUser,
restrictedNicknames: (state) => state.instance.restrictedNicknames, restrictedNicknames: (state) => useInstanceStore().restrictedNicknames,
}), }),
popoverMarginStyle() { popoverMarginStyle() {
if (this.isCurrentUser) { if (this.isCurrentUser) {

View file

@ -1,5 +1,6 @@
import SearchBar from 'components/search_bar/search_bar.vue' import SearchBar from 'components/search_bar/search_bar.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
import ConfirmModal from '../confirm_modal/confirm_modal.vue' import ConfirmModal from '../confirm_modal/confirm_modal.vue'
@ -51,7 +52,7 @@ export default {
}), }),
computed: { computed: {
enableMask() { enableMask() {
return this.supportsMask && this.$store.state.instance.logoMask return this.supportsMask && useInstanceStore().logoMask
}, },
logoStyle() { logoStyle() {
return { return {
@ -61,7 +62,7 @@ export default {
logoMaskStyle() { logoMaskStyle() {
return this.enableMask return this.enableMask
? { ? {
'mask-image': `url(${this.$store.state.instance.logo})`, 'mask-image': `url(${useInstanceStore().logo})`,
} }
: { : {
'background-color': this.enableMask ? '' : 'transparent', 'background-color': this.enableMask ? '' : 'transparent',
@ -70,7 +71,7 @@ export default {
logoBgStyle() { logoBgStyle() {
return Object.assign( return Object.assign(
{ {
margin: `${this.$store.state.instance.logoMargin} 0`, margin: `${useInstanceStore().logoMargin} 0`,
opacity: this.searchBarHidden ? 1 : 0, opacity: this.searchBarHidden ? 1 : 0,
}, },
this.enableMask this.enableMask
@ -81,22 +82,22 @@ export default {
) )
}, },
logo() { logo() {
return this.$store.state.instance.logo return useInstanceStore().logo
}, },
sitename() { sitename() {
return this.$store.state.instance.name return useInstanceStore().name
}, },
hideSitename() { hideSitename() {
return this.$store.state.instance.hideSitename return useInstanceStore().hideSitename
}, },
logoLeft() { logoLeft() {
return this.$store.state.instance.logoLeft return useInstanceStore().logoLeft
}, },
currentUser() { currentUser() {
return this.$store.state.users.currentUser return this.$store.state.users.currentUser
}, },
privateMode() { privateMode() {
return this.$store.state.instance.private return useInstanceStore().private
}, },
shouldConfirmLogout() { shouldConfirmLogout() {
return this.$store.getters.mergedConfig.modalOnLogout return this.$store.getters.mergedConfig.modalOnLogout

View file

@ -2,6 +2,7 @@ import { chunk, debounce, trim } from 'lodash'
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import Popover from 'src/components/popover/popover.vue' import Popover from 'src/components/popover/popover.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { ensureFinalFallback } from '../../i18n/languages.js' import { ensureFinalFallback } from '../../i18n/languages.js'
import Checkbox from '../checkbox/checkbox.vue' import Checkbox from '../checkbox/checkbox.vue'
import StillImage from '../still-image/still-image.vue' import StillImage from '../still-image/still-image.vue'
@ -349,8 +350,8 @@ const EmojiPicker = {
return this.showingStickers ? '' : this.activeGroup return this.showingStickers ? '' : this.activeGroup
}, },
stickersAvailable() { stickersAvailable() {
if (this.$store.state.instance.stickers) { if (useInstanceStore().stickers) {
return this.$store.state.instance.stickers.length > 0 return useInstanceStore().stickers.length > 0
} }
return 0 return 0
}, },
@ -381,7 +382,7 @@ const EmojiPicker = {
.concat(this.unicodeEmojiGroups) .concat(this.unicodeEmojiGroups)
}, },
stickerPickerEnabled() { stickerPickerEnabled() {
return (this.$store.state.instance.stickers || []).length !== 0 return (useInstanceStore().stickers || []).length !== 0
}, },
debouncedHandleKeywordChange() { debouncedHandleKeywordChange() {
return debounce(() => { return debounce(() => {

View file

@ -1,31 +1,32 @@
import { useInstanceStore } from 'src/stores/instance.js'
import fileSizeFormatService from '../../services/file_size_format/file_size_format.js' import fileSizeFormatService from '../../services/file_size_format/file_size_format.js'
const FeaturesPanel = { const FeaturesPanel = {
computed: { computed: {
shout: function () { shout: function () {
return this.$store.state.instance.shoutAvailable return useInstanceStore().shoutAvailable
}, },
pleromaChatMessages: function () { pleromaChatMessages: function () {
return this.$store.state.instance.pleromaChatMessagesAvailable return useInstanceStore().pleromaChatMessagesAvailable
}, },
gopher: function () { gopher: function () {
return this.$store.state.instance.gopherAvailable return useInstanceStore().gopherAvailable
}, },
whoToFollow: function () { whoToFollow: function () {
return this.$store.state.instance.suggestionsEnabled return useInstanceStore().suggestionsEnabled
}, },
mediaProxy: function () { mediaProxy: function () {
return this.$store.state.instance.mediaProxyAvailable return useInstanceStore().mediaProxyAvailable
}, },
minimalScopesMode: function () { minimalScopesMode: function () {
return this.$store.state.instance.minimalScopesMode return useInstanceStore().minimalScopesMode
}, },
textlimit: function () { textlimit: function () {
return this.$store.state.instance.textlimit return useInstanceStore().textlimit
}, },
uploadlimit: function () { uploadlimit: function () {
return fileSizeFormatService.fileSizeFormat( return fileSizeFormatService.fileSizeFormat(
this.$store.state.instance.uploadlimit, useInstanceStore().uploadlimit,
) )
}, },
}, },

View file

@ -1,7 +1,9 @@
import { useInstanceStore } from 'src/stores/instance.js'
const InstanceSpecificPanel = { const InstanceSpecificPanel = {
computed: { computed: {
instanceSpecificPanelContent() { instanceSpecificPanelContent() {
return this.$store.state.instance.instanceSpecificPanelContent return useInstanceStore().instanceSpecificPanelContent
}, },
}, },
} }

View file

@ -3,6 +3,7 @@ import { mapState } from 'vuex'
import { getListEntries } from 'src/components/navigation/filter.js' import { getListEntries } from 'src/components/navigation/filter.js'
import NavigationEntry from 'src/components/navigation/navigation_entry.vue' import NavigationEntry from 'src/components/navigation/navigation_entry.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useListsStore } from 'src/stores/lists' import { useListsStore } from 'src/stores/lists'
export const ListsMenuContent = { export const ListsMenuContent = {
@ -16,8 +17,8 @@ export const ListsMenuContent = {
}), }),
...mapState({ ...mapState({
currentUser: (state) => state.users.currentUser, currentUser: (state) => state.users.currentUser,
privateMode: (state) => state.instance.private, privateMode: (state) => useInstanceStore().private,
federating: (state) => state.instance.federating, federating: (state) => useInstanceStore().federating,
}), }),
}, },
} }

View file

@ -2,6 +2,7 @@ import { mapActions, mapState as mapPiniaState, mapStores } from 'pinia'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import { useAuthFlowStore } from 'src/stores/auth_flow.js' import { useAuthFlowStore } from 'src/stores/auth_flow.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useOAuthStore } from 'src/stores/oauth.js' import { useOAuthStore } from 'src/stores/oauth.js'
import oauthApi from '../../services/new_api/oauth.js' import oauthApi from '../../services/new_api/oauth.js'
@ -24,8 +25,8 @@ const LoginForm = {
}, },
...mapStores(useOAuthStore), ...mapStores(useOAuthStore),
...mapState({ ...mapState({
registrationOpen: (state) => state.instance.registrationOpen, registrationOpen: (state) => useInstanceStore().registrationOpen,
instance: (state) => state.instance, instance: (state) => useInstanceStore(),
loggingIn: (state) => state.users.loggingIn, loggingIn: (state) => state.users.loggingIn,
}), }),
...mapPiniaState(useAuthFlowStore, [ ...mapPiniaState(useAuthFlowStore, [

View file

@ -1,8 +1,8 @@
/* eslint-env browser */
import fileSizeFormatService from '../../services/file_size_format/file_size_format.js' import fileSizeFormatService from '../../services/file_size_format/file_size_format.js'
import statusPosterService from '../../services/status_poster/status_poster.service.js' import statusPosterService from '../../services/status_poster/status_poster.service.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch, faUpload } from '@fortawesome/free-solid-svg-icons' import { faCircleNotch, faUpload } from '@fortawesome/free-solid-svg-icons'
@ -122,10 +122,10 @@ const mediaUpload = {
async uploadFile(file) { async uploadFile(file) {
const self = this const self = this
const store = this.$store const store = this.$store
if (file.size > store.state.instance.uploadlimit) { if (file.size > useInstanceStore().uploadlimit) {
const filesize = fileSizeFormatService.fileSizeFormat(file.size) const filesize = fileSizeFormatService.fileSizeFormat(file.size)
const allowedsize = fileSizeFormatService.fileSizeFormat( const allowedsize = fileSizeFormatService.fileSizeFormat(
store.state.instance.uploadlimit, useInstanceStore().uploadlimit,
) )
self.$emit('upload-failed', 'file_too_big', { self.$emit('upload-failed', 'file_too_big', {
filesize: filesize.num, filesize: filesize.num,

View file

@ -3,6 +3,7 @@ import { mapGetters } from 'vuex'
import NavigationPins from 'src/components/navigation/navigation_pins.vue' import NavigationPins from 'src/components/navigation/navigation_pins.vue'
import { useAnnouncementsStore } from 'src/stores/announcements' import { useAnnouncementsStore } from 'src/stores/announcements'
import { useInstanceStore } from 'src/stores/instance.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import GestureService from '../../services/gesture_service/gesture_service' import GestureService from '../../services/gesture_service/gesture_service'
import { import {
@ -64,10 +65,10 @@ const MobileNav = {
return `${this.unseenCount ? this.unseenCount : ''}` return `${this.unseenCount ? this.unseenCount : ''}`
}, },
hideSitename() { hideSitename() {
return this.$store.state.instance.hideSitename return useInstanceStore().hideSitename
}, },
sitename() { sitename() {
return this.$store.state.instance.name return useInstanceStore().name
}, },
isChat() { isChat() {
return this.$route.name === 'chat' return this.$route.name === 'chat'

View file

@ -1,3 +1,4 @@
import { useInstanceStore } from 'src/stores/instance.js'
import DialogModal from '../dialog_modal/dialog_modal.vue' import DialogModal from '../dialog_modal/dialog_modal.vue'
import Popover from '../popover/popover.vue' import Popover from '../popover/popover.vue'
@ -54,7 +55,7 @@ const ModerationTools = {
}, },
canUseTagPolicy() { canUseTagPolicy() {
return ( return (
this.$store.state.instance.tagPolicyAvailable && useInstanceStore().tagPolicyAvailable &&
this.privileged('users_manage_tags') this.privileged('users_manage_tags')
) )
}, },

View file

@ -9,6 +9,7 @@ import { ROOT_ITEMS, TIMELINES } from 'src/components/navigation/navigation.js'
import NavigationEntry from 'src/components/navigation/navigation_entry.vue' import NavigationEntry from 'src/components/navigation/navigation_entry.vue'
import NavigationPins from 'src/components/navigation/navigation_pins.vue' import NavigationPins from 'src/components/navigation/navigation_pins.vue'
import { useAnnouncementsStore } from 'src/stores/announcements' import { useAnnouncementsStore } from 'src/stores/announcements'
import { useInstanceStore } from 'src/stores/instance.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
@ -118,13 +119,14 @@ const NavPanel = {
...mapState({ ...mapState({
currentUser: (state) => state.users.currentUser, currentUser: (state) => state.users.currentUser,
followRequestCount: (state) => state.api.followRequests.length, followRequestCount: (state) => state.api.followRequests.length,
privateMode: (state) => state.instance.private, privateMode: (state) => useInstanceStore().private,
federating: (state) => state.instance.federating, federating: (state) => useInstanceStore().federating,
pleromaChatMessagesAvailable: (state) => pleromaChatMessagesAvailable: (state) =>
state.instance.pleromaChatMessagesAvailable, useInstanceStore().pleromaChatMessagesAvailable,
bookmarkFolders: (state) => bookmarkFolders: (state) =>
state.instance.pleromaBookmarkFoldersAvailable, useInstanceStore().pleromaBookmarkFoldersAvailable,
bubbleTimeline: (state) => state.instance.localBubbleInstances.length > 0, bubbleTimeline: (state) =>
useInstanceStore().localBubbleInstances.length > 0,
}), }),
timelinesItems() { timelinesItems() {
return filterNavigation( return filterNavigation(

View file

@ -14,6 +14,7 @@ import {
import StillImage from 'src/components/still-image/still-image.vue' import StillImage from 'src/components/still-image/still-image.vue'
import { useAnnouncementsStore } from 'src/stores/announcements' import { useAnnouncementsStore } from 'src/stores/announcements'
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders' import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
import { useInstanceStore } from 'src/stores/instance.js'
import { useListsStore } from 'src/stores/lists' import { useListsStore } from 'src/stores/lists'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
@ -74,11 +75,12 @@ const NavPanel = {
...mapState({ ...mapState({
currentUser: (state) => state.users.currentUser, currentUser: (state) => state.users.currentUser,
followRequestCount: (state) => state.api.followRequests.length, followRequestCount: (state) => state.api.followRequests.length,
privateMode: (state) => state.instance.private, privateMode: (state) => useInstanceStore().private,
federating: (state) => state.instance.federating, federating: (state) => useInstanceStore().federating,
pleromaChatMessagesAvailable: (state) => pleromaChatMessagesAvailable: (state) =>
state.instance.pleromaChatMessagesAvailable, useInstanceStore().pleromaChatMessagesAvailable,
bubbleTimeline: (state) => state.instance.localBubbleInstances.length > 0, bubbleTimeline: (state) =>
useInstanceStore().localBubbleInstances.length > 0,
}), }),
pinnedList() { pinnedList() {
if (!this.currentUser) { if (!this.currentUser) {

View file

@ -2,6 +2,7 @@ import { mapState } from 'vuex'
import RichContent from 'src/components/rich_content/rich_content.jsx' import RichContent from 'src/components/rich_content/rich_content.jsx'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { useInstanceStore } from 'src/stores/instance.js'
import { isStatusNotification } from '../../services/notification_utils/notification_utils.js' import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
import { import {
highlightClass, highlightClass,
@ -107,7 +108,7 @@ const Notification = {
return generateProfileLink( return generateProfileLink(
user.id, user.id,
user.screen_name, user.screen_name,
this.$store.state.instance.restrictedNicknames, useInstanceStore().restrictedNicknames,
) )
}, },
getUser(notification) { getUser(notification) {

View file

@ -1,3 +1,4 @@
import { useInstanceStore } from 'src/stores/instance.js'
import { useOAuthStore } from 'src/stores/oauth.js' import { useOAuthStore } from 'src/stores/oauth.js'
import oauth from '../../services/new_api/oauth.js' import oauth from '../../services/new_api/oauth.js'
@ -12,7 +13,7 @@ const oac = {
.getToken({ .getToken({
clientId, clientId,
clientSecret, clientSecret,
instance: this.$store.state.instance.server, instance: useInstanceStore().server,
code: this.code, code: this.code,
}) })
.then((result) => { .then((result) => {

View file

@ -1,5 +1,7 @@
import { mapState as mapPiniaState } from 'pinia'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import { useInstanceStore } from 'src/stores/instance.js'
import passwordResetApi from '../../services/new_api/password_reset.js' import passwordResetApi from '../../services/new_api/password_reset.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
@ -20,8 +22,8 @@ const passwordReset = {
computed: { computed: {
...mapState({ ...mapState({
signedIn: (state) => !!state.users.currentUser, signedIn: (state) => !!state.users.currentUser,
instance: (state) => state.instance,
}), }),
...mapPiniaState(useInstanceStore, ['server']),
mailerEnabled() { mailerEnabled() {
return this.instance.mailerEnabled return this.instance.mailerEnabled
}, },
@ -44,9 +46,9 @@ const passwordReset = {
submit() { submit() {
this.isPending = true this.isPending = true
const email = this.user.email const email = this.user.email
const instance = this.instance.server const server = this.server
passwordResetApi({ instance, email }) passwordResetApi({ server, email })
.then(({ status }) => { .then(({ status }) => {
this.isPending = false this.isPending = false
this.user.email = '' this.user.email = ''

View file

@ -1,5 +1,6 @@
import * as DateUtils from 'src/services/date_utils/date_utils.js' import * as DateUtils from 'src/services/date_utils/date_utils.js'
import { pollFallback } from 'src/services/poll/poll.service.js' import { pollFallback } from 'src/services/poll/poll.service.js'
import { useInstanceStore } from 'src/stores/instance.js'
import Select from '../select/select.vue' import Select from '../select/select.vue'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
@ -52,7 +53,7 @@ export default {
}, },
}, },
pollLimits() { pollLimits() {
return this.$store.state.instance.pollLimits return useInstanceStore().pollLimits
}, },
maxOptions() { maxOptions() {
return this.pollLimits.max_options return this.pollLimits.max_options

View file

@ -6,6 +6,7 @@ import DraftCloser from 'src/components/draft_closer/draft_closer.vue'
import Gallery from 'src/components/gallery/gallery.vue' import Gallery from 'src/components/gallery/gallery.vue'
import Popover from 'src/components/popover/popover.vue' import Popover from 'src/components/popover/popover.vue'
import { pollFormToMasto } from 'src/services/poll/poll.service.js' import { pollFormToMasto } from 'src/services/poll/poll.service.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface.js' import { useInterfaceStore } from 'src/stores/interface.js'
import { useMediaViewerStore } from 'src/stores/media_viewer.js' import { useMediaViewerStore } from 'src/stores/media_viewer.js'
import { propsToNative } from '../../services/attributes_helper/attributes_helper.service.js' import { propsToNative } from '../../services/attributes_helper/attributes_helper.service.js'
@ -259,7 +260,7 @@ const PostStatusForm = {
return suggestor({ return suggestor({
emoji: [ emoji: [
...this.$store.getters.standardEmojiList, ...this.$store.getters.standardEmojiList,
...this.$store.state.instance.customEmoji, ...useInstanceStore().customEmoji,
], ],
store: this.$store, store: this.$store,
}) })
@ -268,7 +269,7 @@ const PostStatusForm = {
return suggestor({ return suggestor({
emoji: [ emoji: [
...this.$store.getters.standardEmojiList, ...this.$store.getters.standardEmojiList,
...this.$store.state.instance.customEmoji, ...useInstanceStore().customEmoji,
], ],
}) })
}, },
@ -276,7 +277,7 @@ const PostStatusForm = {
return this.$store.getters.standardEmojiList || [] return this.$store.getters.standardEmojiList || []
}, },
customEmoji() { customEmoji() {
return this.$store.state.instance.customEmoji || [] return useInstanceStore().customEmoji || []
}, },
statusLength() { statusLength() {
return this.newStatus.status.length return this.newStatus.status.length
@ -285,7 +286,7 @@ const PostStatusForm = {
return this.newStatus.spoilerText.length return this.newStatus.spoilerText.length
}, },
statusLengthLimit() { statusLengthLimit() {
return this.$store.state.instance.textlimit return useInstanceStore().textlimit
}, },
hasStatusLengthLimit() { hasStatusLengthLimit() {
return this.statusLengthLimit > 0 return this.statusLengthLimit > 0
@ -299,21 +300,21 @@ const PostStatusForm = {
return this.hasStatusLengthLimit && this.charactersLeft < 0 return this.hasStatusLengthLimit && this.charactersLeft < 0
}, },
minimalScopesMode() { minimalScopesMode() {
return this.$store.state.instance.minimalScopesMode return useInstanceStore().minimalScopesMode
}, },
alwaysShowSubject() { alwaysShowSubject() {
return this.mergedConfig.alwaysShowSubjectInput return this.mergedConfig.alwaysShowSubjectInput
}, },
postFormats() { postFormats() {
return this.$store.state.instance.postFormats || [] return useInstanceStore().postFormats || []
}, },
safeDMEnabled() { safeDMEnabled() {
return this.$store.state.instance.safeDM return useInstanceStore().safeDM
}, },
pollsAvailable() { pollsAvailable() {
return ( return (
this.$store.state.instance.pollsAvailable && useInstanceStore().pollsAvailable &&
this.$store.state.instance.pollLimits.max_options >= 2 && useInstanceStore().pollLimits.max_options >= 2 &&
this.disablePolls !== true this.disablePolls !== true
) )
}, },
@ -342,7 +343,7 @@ const PostStatusForm = {
return typeof this.statusId !== 'undefined' && this.statusId.trim() !== '' return typeof this.statusId !== 'undefined' && this.statusId.trim() !== ''
}, },
quotable() { quotable() {
if (!this.$store.state.instance.quotingAvailable) { if (!useInstanceStore().quotingAvailable) {
return false return false
} }

View file

@ -1,8 +1,10 @@
import useVuelidate from '@vuelidate/core' import useVuelidate from '@vuelidate/core'
import { required, requiredIf, sameAs } from '@vuelidate/validators' import { required, requiredIf, sameAs } from '@vuelidate/validators'
import { mapState as mapPiniaState } from 'pinia'
import { mapActions, mapState } from 'vuex' import { mapActions, mapState } from 'vuex'
import { DAY } from 'src/services/date_utils/date_utils.js' import { DAY } from 'src/services/date_utils/date_utils.js'
import { useInstanceStore } from 'src/stores/instance.js'
import localeService from '../../services/locale/locale.service.js' import localeService from '../../services/locale/locale.service.js'
import InterfaceLanguageSwitcher from '../interface_language_switcher/interface_language_switcher.vue' import InterfaceLanguageSwitcher from '../interface_language_switcher/interface_language_switcher.vue'
import TermsOfServicePanel from '../terms_of_service_panel/terms_of_service_panel.vue' import TermsOfServicePanel from '../terms_of_service_panel/terms_of_service_panel.vue'
@ -96,21 +98,21 @@ const registration = {
) )
) )
}, },
...mapPiniaState(useInstanceStore, {
registrationOpen: (store) => store.registrationOpen,
embeddedToS: (store) => store.embeddedToS,
termsOfService: (store) => store.tos,
accountActivationRequired: (store) => store.accountActivationRequired,
accountApprovalRequired: (store) => store.accountApprovalRequired,
birthdayRequired: (store) => store.birthdayRequired,
birthdayMinAge: (store) => store.birthdayMinAge,
}),
...mapState({ ...mapState({
registrationOpen: (state) => state.instance.registrationOpen,
signedIn: (state) => !!state.users.currentUser, signedIn: (state) => !!state.users.currentUser,
isPending: (state) => state.users.signUpPending, isPending: (state) => state.users.signUpPending,
serverValidationErrors: (state) => state.users.signUpErrors, serverValidationErrors: (state) => state.users.signUpErrors,
signUpNotice: (state) => state.users.signUpNotice, signUpNotice: (state) => state.users.signUpNotice,
hasSignUpNotice: (state) => !!state.users.signUpNotice.message, hasSignUpNotice: (state) => !!state.users.signUpNotice.message,
termsOfService: (state) => state.instance.tos,
embeddedToS: (state) => state.instance.embeddedToS,
accountActivationRequired: (state) =>
state.instance.accountActivationRequired,
accountApprovalRequired: (state) =>
state.instance.accountApprovalRequired,
birthdayRequired: (state) => state.instance.birthdayRequired,
birthdayMinAge: (state) => state.instance.birthdayMinAge,
}), }),
}, },
methods: { methods: {

View file

@ -1,5 +1,6 @@
import RichContent from 'src/components/rich_content/rich_content.jsx' import RichContent from 'src/components/rich_content/rich_content.jsx'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { useInstanceStore } from 'src/stores/instance.js'
import { useReportsStore } from 'src/stores/reports' import { useReportsStore } from 'src/stores/reports'
import Select from '../select/select.vue' import Select from '../select/select.vue'
import StatusContent from '../status_content/status_content.vue' import StatusContent from '../status_content/status_content.vue'
@ -31,7 +32,7 @@ const Report = {
return generateProfileLink( return generateProfileLink(
user.id, user.id,
user.screen_name, user.screen_name,
this.$store.state.instance.restrictedNicknames, useInstanceStore().restrictedNicknames,
) )
}, },
setReportState(state) { setReportState(state) {

View file

@ -6,6 +6,7 @@ import StillImage from 'components/still-image/still-image.vue'
import { assign, clone } from 'lodash' import { assign, clone } from 'lodash'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
import EmojiEditingPopover from '../helpers/emoji_editing_popover.vue' import EmojiEditingPopover from '../helpers/emoji_editing_popover.vue'
import ModifiedIndicator from '../helpers/modified_indicator.vue' import ModifiedIndicator from '../helpers/modified_indicator.vue'
@ -102,7 +103,7 @@ const EmojiTab = {
// Remote pack // Remote pack
return `${this.pack.remote.instance}/emoji/${encodeURIComponent(this.pack.remote.baseName)}/${name}` return `${this.pack.remote.instance}/emoji/${encodeURIComponent(this.pack.remote.baseName)}/${name}`
} else { } else {
return `${this.$store.state.instance.server}/emoji/${encodeURIComponent(this.packName)}/${name}` return `${useInstanceStore().server}/emoji/${encodeURIComponent(this.packName)}/${name}`
} }
}, },

View file

@ -1,6 +1,7 @@
import Attachment from 'src/components/attachment/attachment.vue' import Attachment from 'src/components/attachment/attachment.vue'
import MediaUpload from 'src/components/media_upload/media_upload.vue' import MediaUpload from 'src/components/media_upload/media_upload.vue'
import { fileTypeExt } from 'src/services/file_type/file_type.service.js' import { fileTypeExt } from 'src/services/file_type/file_type.service.js'
import { useInstanceStore } from 'src/stores/instance.js'
import Setting from './setting.js' import Setting from './setting.js'
export default { export default {
@ -24,9 +25,7 @@ export default {
attachment() { attachment() {
const path = this.realDraftMode ? this.draft : this.state const path = this.realDraftMode ? this.draft : this.state
// The "server" part is primarily for local dev, but could be useful for alt-domain or multiuser usage. // The "server" part is primarily for local dev, but could be useful for alt-domain or multiuser usage.
const url = path.includes('://') const url = path.includes('://') ? path : useInstanceStore().server + path
? path
: this.$store.state.instance.server + path
return { return {
mimetype: fileTypeExt(url), mimetype: fileTypeExt(url),
url, url,

View file

@ -4,6 +4,7 @@ import Attachment from 'src/components/attachment/attachment.vue'
import MediaUpload from 'src/components/media_upload/media_upload.vue' import MediaUpload from 'src/components/media_upload/media_upload.vue'
import Select from 'src/components/select/select.vue' import Select from 'src/components/select/select.vue'
import { fileTypeExt } from 'src/services/file_type/file_type.service.js' import { fileTypeExt } from 'src/services/file_type/file_type.service.js'
import { useInstanceStore } from 'src/stores/instance.js'
import Setting from './setting.js' import Setting from './setting.js'
export default { export default {
@ -34,9 +35,7 @@ export default {
url: '', url: '',
} }
} }
const url = path.includes('://') const url = path.includes('://') ? path : useInstanceStore().server + path
? path
: this.$store.state.instance.server + path
return { return {
mimetype: fileTypeExt(url), mimetype: fileTypeExt(url),

View file

@ -11,6 +11,7 @@ import { getCssRules } from 'src/services/theme_data/css_utils.js'
import { deserialize } from 'src/services/theme_data/iss_deserializer.js' import { deserialize } from 'src/services/theme_data/iss_deserializer.js'
import { init } from 'src/services/theme_data/theme_data_3.service.js' import { init } from 'src/services/theme_data/theme_data_3.service.js'
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js' import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { normalizeThemeData, useInterfaceStore } from 'src/stores/interface' import { normalizeThemeData, useInterfaceStore } from 'src/stores/interface'
import BooleanSetting from '../helpers/boolean_setting.vue' import BooleanSetting from '../helpers/boolean_setting.vue'
import ChoiceSetting from '../helpers/choice_setting.vue' import ChoiceSetting from '../helpers/choice_setting.vue'
@ -83,7 +84,7 @@ const AppearanceTab = {
const updateIndex = (resource) => { const updateIndex = (resource) => {
const capitalizedResource = resource[0].toUpperCase() + resource.slice(1) const capitalizedResource = resource[0].toUpperCase() + resource.slice(1)
const currentIndex = this.$store.state.instance[`${resource}sIndex`] const currentIndex = useInstanceStore()[`${resource}sIndex`]
let promise let promise
if (currentIndex) { if (currentIndex) {
@ -273,11 +274,11 @@ const AppearanceTab = {
return !window.IntersectionObserver return !window.IntersectionObserver
}, },
instanceWallpaper() { instanceWallpaper() {
this.$store.state.instance.background useInstanceStore().background
}, },
instanceWallpaperUsed() { instanceWallpaperUsed() {
return ( return (
this.$store.state.instance.background && useInstanceStore().background &&
!this.$store.state.users.currentUser.background_image !this.$store.state.users.currentUser.background_image
) )
}, },
@ -332,20 +333,13 @@ const AppearanceTab = {
} }
}, },
isThemeActive(key) { isThemeActive(key) {
return ( return key === (this.mergedConfig.theme || useInstanceStore().theme)
key === (this.mergedConfig.theme || this.$store.state.instance.theme)
)
}, },
isStyleActive(key) { isStyleActive(key) {
return ( return key === (this.mergedConfig.style || useInstanceStore().style)
key === (this.mergedConfig.style || this.$store.state.instance.style)
)
}, },
isPaletteActive(key) { isPaletteActive(key) {
return ( return key === (this.mergedConfig.palette || useInstanceStore().palette)
key ===
(this.mergedConfig.palette || this.$store.state.instance.palette)
)
}, },
...mapActions(useInterfaceStore, ['setStyle', 'setTheme']), ...mapActions(useInterfaceStore, ['setStyle', 'setTheme']),
setPalette(name, data) { setPalette(name, data) {
@ -431,10 +425,10 @@ const AppearanceTab = {
if (!file) { if (!file) {
return return
} }
if (file.size > this.$store.state.instance[slot + 'limit']) { if (file.size > useInstanceStore()[slot + 'limit']) {
const filesize = fileSizeFormatService.fileSizeFormat(file.size) const filesize = fileSizeFormatService.fileSizeFormat(file.size)
const allowedsize = fileSizeFormatService.fileSizeFormat( const allowedsize = fileSizeFormatService.fileSizeFormat(
this.$store.state.instance[slot + 'limit'], useInstanceStore()[slot + 'limit'],
) )
useInterfaceStore().pushGlobalNotice({ useInterfaceStore().pushGlobalNotice({
messageKey: 'upload.error.message', messageKey: 'upload.error.message',

View file

@ -4,6 +4,7 @@ import { mapState as mapVuexState } from 'vuex'
import Checkbox from 'src/components/checkbox/checkbox.vue' import Checkbox from 'src/components/checkbox/checkbox.vue'
import Select from 'src/components/select/select.vue' import Select from 'src/components/select/select.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import BooleanSetting from '../helpers/boolean_setting.vue' import BooleanSetting from '../helpers/boolean_setting.vue'
import ChoiceSetting from '../helpers/choice_setting.vue' import ChoiceSetting from '../helpers/choice_setting.vue'
@ -24,7 +25,7 @@ const ClutterTab = {
}, },
computed: { computed: {
instanceSpecificPanelPresent() { instanceSpecificPanelPresent() {
return this.$store.state.instance.showInstanceSpecificPanel return useInstanceStore().showInstanceSpecificPanel
}, },
...SharedComputedObject(), ...SharedComputedObject(),
...mapState(useServerSideStorageStore, { ...mapState(useServerSideStorageStore, {
@ -33,7 +34,7 @@ const ClutterTab = {
muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters, muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters,
}), }),
...mapVuexState({ ...mapVuexState({
blockExpirationSupported: (state) => state.instance.blockExpiration, blockExpirationSupported: (state) => useInstanceStore().blockExpiration,
}), }),
onMuteDefaultActionLv1: { onMuteDefaultActionLv1: {
get() { get() {

View file

@ -6,6 +6,7 @@ import ScopeSelector from 'src/components/scope_selector/scope_selector.vue'
import Select from 'src/components/select/select.vue' import Select from 'src/components/select/select.vue'
import localeService from 'src/services/locale/locale.service.js' import localeService from 'src/services/locale/locale.service.js'
import { cacheKey, clearCache, emojiCacheKey } from 'src/services/sw/sw.js' import { cacheKey, clearCache, emojiCacheKey } from 'src/services/sw/sw.js'
import { useInstanceStore } from 'src/stores/instance.js'
import BooleanSetting from '../helpers/boolean_setting.vue' import BooleanSetting from '../helpers/boolean_setting.vue'
import ChoiceSetting from '../helpers/choice_setting.vue' import ChoiceSetting from '../helpers/choice_setting.vue'
import FloatSetting from '../helpers/float_setting.vue' import FloatSetting from '../helpers/float_setting.vue'
@ -108,7 +109,7 @@ const ComposingTab = {
}, },
computed: { computed: {
postFormats() { postFormats() {
return this.$store.state.instance.postFormats || [] return useInstanceStore().postFormats || []
}, },
postContentOptions() { postContentOptions() {
return this.postFormats.map((format) => ({ return this.postFormats.map((format) => ({
@ -130,7 +131,7 @@ const ComposingTab = {
}, },
...SharedComputedObject(), ...SharedComputedObject(),
...mapState({ ...mapState({
blockExpirationSupported: (state) => state.instance.blockExpiration, blockExpirationSupported: (state) => useInstanceStore().blockExpiration,
}), }),
}, },
methods: { methods: {

View file

@ -1,4 +1,5 @@
import { cacheKey, clearCache, emojiCacheKey } from 'src/services/sw/sw.js' import { cacheKey, clearCache, emojiCacheKey } from 'src/services/sw/sw.js'
import { useInstanceStore } from 'src/stores/instance.js'
import BooleanSetting from '../helpers/boolean_setting.vue' import BooleanSetting from '../helpers/boolean_setting.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js' import SharedComputedObject from '../helpers/shared_computed_object.js'
@ -7,7 +8,7 @@ const pleromaFeCommitUrl =
const VersionTab = { const VersionTab = {
data() { data() {
const instance = this.$store.state.instance const instance = useInstanceStore()
return { return {
backendVersion: instance.backendVersion, backendVersion: instance.backendVersion,
backendRepository: instance.backendRepository, backendRepository: instance.backendRepository,

View file

@ -9,6 +9,7 @@ import {
newExporter, newExporter,
newImporter, newImporter,
} from 'src/services/export_import/export_import.js' } from 'src/services/export_import/export_import.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import BooleanSetting from '../helpers/boolean_setting.vue' import BooleanSetting from '../helpers/boolean_setting.vue'
@ -90,7 +91,7 @@ const FilteringTab = {
}, },
computed: { computed: {
instanceSpecificPanelPresent() { instanceSpecificPanelPresent() {
return this.$store.state.instance.showInstanceSpecificPanel return useInstanceStore().showInstanceSpecificPanel
}, },
...SharedComputedObject(), ...SharedComputedObject(),
...mapState(useServerSideStorageStore, { ...mapState(useServerSideStorageStore, {
@ -99,7 +100,7 @@ const FilteringTab = {
muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters, muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters,
}), }),
...mapVuexState({ ...mapVuexState({
blockExpirationSupported: (state) => state.instance.blockExpiration, blockExpirationSupported: (state) => useInstanceStore().blockExpiration,
}), }),
onMuteDefaultActionLv1: { onMuteDefaultActionLv1: {
get() { get() {

View file

@ -3,6 +3,7 @@ import { mapState } from 'vuex'
import FontControl from 'src/components/font_control/font_control.vue' import FontControl from 'src/components/font_control/font_control.vue'
import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue' import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue'
import localeService from 'src/services/locale/locale.service.js' import localeService from 'src/services/locale/locale.service.js'
import { useInstanceStore } from 'src/stores/instance.js'
import BooleanSetting from '../helpers/boolean_setting.vue' import BooleanSetting from '../helpers/boolean_setting.vue'
import ChoiceSetting from '../helpers/choice_setting.vue' import ChoiceSetting from '../helpers/choice_setting.vue'
import FloatSetting from '../helpers/float_setting.vue' import FloatSetting from '../helpers/float_setting.vue'
@ -50,7 +51,7 @@ const GeneralTab = {
}, },
...SharedComputedObject(), ...SharedComputedObject(),
...mapState({ ...mapState({
blockExpirationSupported: (state) => state.instance.blockExpiration, blockExpirationSupported: (state) => useInstanceStore().blockExpiration,
}), }),
}, },
methods: { methods: {

View file

@ -1,3 +1,4 @@
import { useInstanceStore } from 'src/stores/instance.js'
import BooleanSetting from '../helpers/boolean_setting.vue' import BooleanSetting from '../helpers/boolean_setting.vue'
import ChoiceSetting from '../helpers/choice_setting.vue' import ChoiceSetting from '../helpers/choice_setting.vue'
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue' import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
@ -30,10 +31,10 @@ const GeneralTab = {
}, },
computed: { computed: {
postFormats() { postFormats() {
return this.$store.state.instance.postFormats || [] return useInstanceStore().postFormats || []
}, },
instanceShoutboxPresent() { instanceShoutboxPresent() {
return this.$store.state.instance.shoutAvailable return useInstanceStore().shoutAvailable
}, },
columns() { columns() {
const mode = this.$store.getters.mergedConfig.thirdColumnMode const mode = this.$store.getters.mergedConfig.thirdColumnMode

View file

@ -12,6 +12,7 @@ import MuteCard from 'src/components/mute_card/mute_card.vue'
import ProgressButton from 'src/components/progress_button/progress_button.vue' import ProgressButton from 'src/components/progress_button/progress_button.vue'
import SelectableList from 'src/components/selectable_list/selectable_list.vue' import SelectableList from 'src/components/selectable_list/selectable_list.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
import { useInstanceStore } from 'src/stores/instance.js'
import { useOAuthTokensStore } from 'src/stores/oauth_tokens' import { useOAuthTokensStore } from 'src/stores/oauth_tokens'
const BlockList = withLoadMore({ const BlockList = withLoadMore({
@ -64,7 +65,7 @@ const MutesAndBlocks = {
}, },
computed: { computed: {
knownDomains() { knownDomains() {
return this.$store.state.instance.knownDomains return useInstanceStore().knownDomains
}, },
user() { user() {
return this.$store.state.users.currentUser return this.$store.state.users.currentUser

View file

@ -41,6 +41,7 @@ import {
} from 'src/services/theme_data/theme_data.service.js' } from 'src/services/theme_data/theme_data.service.js'
import { init } from 'src/services/theme_data/theme_data_3.service.js' import { init } from 'src/services/theme_data/theme_data_3.service.js'
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js' import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
import Preview from './theme_preview.vue' import Preview from './theme_preview.vue'
@ -125,7 +126,7 @@ export default {
} }
}, },
created() { created() {
const currentIndex = this.$store.state.instance.themesIndex const currentIndex = useInstanceStore().themesIndex
let promise let promise
if (currentIndex) { if (currentIndex) {

View file

@ -1,6 +1,7 @@
import Checkbox from 'src/components/checkbox/checkbox.vue' import Checkbox from 'src/components/checkbox/checkbox.vue'
import ProgressButton from 'src/components/progress_button/progress_button.vue' import ProgressButton from 'src/components/progress_button/progress_button.vue'
import localeService from 'src/services/locale/locale.service.js' import localeService from 'src/services/locale/locale.service.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useOAuthTokensStore } from 'src/stores/oauth_tokens' import { useOAuthTokensStore } from 'src/stores/oauth_tokens'
import Mfa from './mfa.vue' import Mfa from './mfa.vue'
@ -42,7 +43,7 @@ const SecurityTab = {
return this.$store.state.users.currentUser return this.$store.state.users.currentUser
}, },
pleromaExtensionsAvailable() { pleromaExtensionsAvailable() {
return this.$store.state.instance.pleromaExtensionsAvailable return useInstanceStore().pleromaExtensionsAvailable
}, },
oauthTokens() { oauthTokens() {
return useOAuthTokensStore().tokens.map((oauthToken) => { return useOAuthTokensStore().tokens.map((oauthToken) => {

View file

@ -1,4 +1,5 @@
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { useInstanceStore } from 'src/stores/instance.js'
import { useShoutStore } from 'src/stores/shout' import { useShoutStore } from 'src/stores/shout'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
@ -32,7 +33,7 @@ const shoutPanel = {
return generateProfileLink( return generateProfileLink(
user.id, user.id,
user.username, user.username,
this.$store.state.instance.restrictedNicknames, useInstanceStore().restrictedNicknames,
) )
}, },
}, },

View file

@ -3,6 +3,7 @@ import { mapGetters, mapState } from 'vuex'
import { USERNAME_ROUTES } from 'src/components/navigation/navigation.js' import { USERNAME_ROUTES } from 'src/components/navigation/navigation.js'
import { useAnnouncementsStore } from 'src/stores/announcements' import { useAnnouncementsStore } from 'src/stores/announcements'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
import { useShoutStore } from 'src/stores/shout' import { useShoutStore } from 'src/stores/shout'
import GestureService from '../../services/gesture_service/gesture_service' import GestureService from '../../services/gesture_service/gesture_service'
@ -75,25 +76,25 @@ const SideDrawer = {
return this.unseenNotifications.length return this.unseenNotifications.length
}, },
suggestionsEnabled() { suggestionsEnabled() {
return this.$store.state.instance.suggestionsEnabled return useInstanceStore().suggestionsEnabled
}, },
logo() { logo() {
return this.$store.state.instance.logo return useInstanceStore().logo
}, },
hideSitename() { hideSitename() {
return this.$store.state.instance.hideSitename return useInstanceStore().hideSitename
}, },
sitename() { sitename() {
return this.$store.state.instance.name return useInstanceStore().name
}, },
followRequestCount() { followRequestCount() {
return this.$store.state.api.followRequests.length return this.$store.state.api.followRequests.length
}, },
privateMode() { privateMode() {
return this.$store.state.instance.private return useInstanceStore().private
}, },
federating() { federating() {
return this.$store.state.instance.federating return useInstanceStore().federating
}, },
timelinesRoute() { timelinesRoute() {
let name let name
@ -113,7 +114,7 @@ const SideDrawer = {
}), }),
...mapState({ ...mapState({
pleromaChatMessagesAvailable: (state) => pleromaChatMessagesAvailable: (state) =>
state.instance.pleromaChatMessagesAvailable, useInstanceStore().pleromaChatMessagesAvailable,
}), }),
...mapGetters(['unreadChatCount', 'draftCount']), ...mapGetters(['unreadChatCount', 'draftCount']),
}, },

View file

@ -2,11 +2,12 @@ import groupBy from 'lodash/groupBy'
import map from 'lodash/map' import map from 'lodash/map'
import { mapGetters, mapState } from 'vuex' import { mapGetters, mapState } from 'vuex'
import { useInstanceStore } from 'src/stores/instance.js'
import BasicUserCard from '../basic_user_card/basic_user_card.vue' import BasicUserCard from '../basic_user_card/basic_user_card.vue'
const StaffPanel = { const StaffPanel = {
created() { created() {
const nicknames = this.$store.state.instance.staffAccounts const nicknames = useInstanceStore().staffAccounts
nicknames.forEach((nickname) => nicknames.forEach((nickname) =>
this.$store.dispatch('fetchUserIfMissing', nickname), this.$store.dispatch('fetchUserIfMissing', nickname),
) )
@ -28,7 +29,7 @@ const StaffPanel = {
}, },
...mapGetters(['findUserByName']), ...mapGetters(['findUserByName']),
...mapState({ ...mapState({
staffAccounts: (state) => state.instance.staffAccounts, staffAccounts: (state) => useInstanceStore().staffAccounts,
}), }),
}, },
} }

View file

@ -5,6 +5,7 @@ import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
import RichContent from 'src/components/rich_content/rich_content.jsx' import RichContent from 'src/components/rich_content/rich_content.jsx'
import StatusActionButtons from 'src/components/status_action_buttons/status_action_buttons.vue' import StatusActionButtons from 'src/components/status_action_buttons/status_action_buttons.vue'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { useInstanceStore } from 'src/stores/instance.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import { muteFilterHits } from '../../services/status_parser/status_parser.js' import { muteFilterHits } from '../../services/status_parser/status_parser.js'
import { import {
@ -494,7 +495,7 @@ const Status = {
return this.status.edited_at !== null return this.status.edited_at !== null
}, },
editingAvailable() { editingAvailable() {
return this.$store.state.instance.editingAvailable return useInstanceStore().editingAvailable
}, },
hasVisibleQuote() { hasVisibleQuote() {
return this.status.quote_url && this.status.quote_visible return this.status.quote_url && this.status.quote_visible
@ -588,7 +589,7 @@ const Status = {
return generateProfileLink( return generateProfileLink(
id, id,
name, name,
this.$store.state.instance.restrictedNicknames, useInstanceStore().restrictedNicknames,
) )
}, },
addMediaPlaying(id) { addMediaPlaying(id) {

View file

@ -1,6 +1,7 @@
import EmojiPicker from 'src/components/emoji_picker/emoji_picker.vue' import EmojiPicker from 'src/components/emoji_picker/emoji_picker.vue'
import Popover from 'src/components/popover/popover.vue' import Popover from 'src/components/popover/popover.vue'
import StatusBookmarkFolderMenu from 'src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.vue' import StatusBookmarkFolderMenu from 'src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
@ -91,7 +92,7 @@ export default {
return this.status.thread_muted return this.status.thread_muted
}, },
hideCustomEmoji() { hideCustomEmoji() {
return !this.$store.state.instance.pleromaCustomEmojiReactionsAvailable return !useInstanceStore().pleromaCustomEmojiReactionsAvailable
}, },
buttonInnerClass() { buttonInnerClass() {
return [ return [

View file

@ -1,4 +1,5 @@
import { useEditStatusStore } from 'src/stores/editStatus.js' import { useEditStatusStore } from 'src/stores/editStatus.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useReportsStore } from 'src/stores/reports.js' import { useReportsStore } from 'src/stores/reports.js'
import { useStatusHistoryStore } from 'src/stores/statusHistory.js' import { useStatusHistoryStore } from 'src/stores/statusHistory.js'
@ -159,7 +160,7 @@ export const BUTTONS = [
icon: 'history', icon: 'history',
label: 'status.status_history', label: 'status.status_history',
if({ status, state }) { if({ status, state }) {
return state.instance.editingAvailable && status.edited_at !== null return useInstanceStore().editingAvailable && status.edited_at !== null
}, },
action({ status }) { action({ status }) {
const originalStatus = { ...status } const originalStatus = { ...status }
@ -189,7 +190,7 @@ export const BUTTONS = [
if({ status, loggedIn, currentUser, state }) { if({ status, loggedIn, currentUser, state }) {
return ( return (
loggedIn && loggedIn &&
state.instance.editingAvailable && useInstanceStore().editingAvailable &&
status.user.id === currentUser.id status.user.id === currentUser.id
) )
}, },
@ -243,7 +244,7 @@ export const BUTTONS = [
action({ state, status, router }) { action({ state, status, router }) {
navigator.clipboard.writeText( navigator.clipboard.writeText(
[ [
state.instance.server, useInstanceStore().server,
router.resolve({ name: 'conversation', params: { id: status.id } }) router.resolve({ name: 'conversation', params: { id: status.id } })
.href, .href,
].join(''), ].join(''),

View file

@ -1,4 +1,5 @@
/* eslint-env browser */ /* eslint-env browser */
import { useInstanceStore } from 'src/stores/instance.js'
import statusPosterService from '../../services/status_poster/status_poster.service.js' import statusPosterService from '../../services/status_poster/status_poster.service.js'
import TabSwitcher from '../tab_switcher/tab_switcher.jsx' import TabSwitcher from '../tab_switcher/tab_switcher.jsx'
@ -16,7 +17,7 @@ const StickerPicker = {
}, },
computed: { computed: {
pack() { pack() {
return this.$store.state.instance.stickers || [] return useInstanceStore().stickers || []
}, },
}, },
methods: { methods: {

View file

@ -60,6 +60,7 @@ import Popover from 'components/popover/popover.vue'
import SelectComponent from 'components/select/select.vue' import SelectComponent from 'components/select/select.vue'
import { assign } from 'lodash' import { assign } from 'lodash'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
import StillImage from './still-image.vue' import StillImage from './still-image.vue'
@ -125,7 +126,7 @@ export default {
const allPacks = {} const allPacks = {}
return listFunction({ return listFunction({
instance: this.$store.state.instance.server, instance: useInstanceStore().server,
page: 1, page: 1,
pageSize: 0, pageSize: 0,
}) })
@ -140,7 +141,7 @@ export default {
resultingPromise = resultingPromise resultingPromise = resultingPromise
.then(() => .then(() =>
listFunction({ listFunction({
instance: this.$store.state.instance.server, instance: useInstanceStore().server,
page: i, page: i,
pageSize, pageSize,
}), }),

View file

@ -1,10 +1,12 @@
import { useInstanceStore } from 'src/stores/instance.js'
const TermsOfServicePanel = { const TermsOfServicePanel = {
computed: { computed: {
content() { content() {
return this.$store.state.instance.tos return useInstanceStore().tos
}, },
embedded() { embedded() {
return this.$store.state.instance.embeddedToS return useInstanceStore().embeddedToS
}, },
}, },
} }

View file

@ -4,6 +4,7 @@ import { filterNavigation } from 'src/components/navigation/filter.js'
import { TIMELINES } from 'src/components/navigation/navigation.js' import { TIMELINES } from 'src/components/navigation/navigation.js'
import NavigationEntry from 'src/components/navigation/navigation_entry.vue' import NavigationEntry from 'src/components/navigation/navigation_entry.vue'
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders' import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
import { useListsStore } from 'src/stores/lists' import { useListsStore } from 'src/stores/lists'
import BookmarkFoldersMenuContent from '../bookmark_folders_menu/bookmark_folders_menu_content.vue' import BookmarkFoldersMenuContent from '../bookmark_folders_menu/bookmark_folders_menu_content.vue'
@ -60,11 +61,12 @@ const TimelineMenu = {
}, },
...mapState({ ...mapState({
currentUser: (state) => state.users.currentUser, currentUser: (state) => state.users.currentUser,
privateMode: (state) => state.instance.private, privateMode: (state) => useInstanceStore().private,
federating: (state) => state.instance.federating, federating: (state) => useInstanceStore().federating,
bookmarkFolders: (state) => bookmarkFolders: (state) =>
state.instance.pleromaBookmarkFoldersAvailable, useInstanceStore().pleromaBookmarkFoldersAvailable,
bubbleTimeline: (state) => state.instance.localBubbleInstances.length > 0, bubbleTimeline: (state) =>
useInstanceStore().localBubbleInstances.length > 0,
}), }),
timelinesList() { timelinesList() {
return filterNavigation( return filterNavigation(

View file

@ -1,6 +1,7 @@
import pleromaTanFoxMask from 'src/assets/pleromatan_apology_fox_mask.png' import pleromaTanFoxMask from 'src/assets/pleromatan_apology_fox_mask.png'
import pleromaTanMask from 'src/assets/pleromatan_apology_mask.png' import pleromaTanMask from 'src/assets/pleromatan_apology_mask.png'
import Modal from 'src/components/modal/modal.vue' import Modal from 'src/components/modal/modal.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
@ -36,7 +37,7 @@ const UpdateNotification = {
}, },
shouldShow() { shouldShow() {
return ( return (
!this.$store.state.instance.disableUpdateNotification && !useInstanceStore().disableUpdateNotification &&
this.$store.state.users.currentUser && this.$store.state.users.currentUser &&
useServerSideStorageStore().flagStorage.updateCounter < useServerSideStorageStore().flagStorage.updateCounter <
CURRENT_UPDATE_COUNTER && CURRENT_UPDATE_COUNTER &&

View file

@ -1,3 +1,4 @@
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
import StillImage from '../still-image/still-image.vue' import StillImage from '../still-image/still-image.vue'
@ -35,7 +36,7 @@ const UserAvatar = {
data() { data() {
return { return {
showPlaceholder: false, showPlaceholder: false,
defaultAvatar: `${this.$store.state.instance.server + this.$store.state.instance.defaultAvatar}`, defaultAvatar: `${useInstanceStore().server + useInstanceStore().defaultAvatar}`,
betterShadow: useInterfaceStore().browserSupport.cssFilter, betterShadow: useInterfaceStore().browserSupport.cssFilter,
} }
}, },

View file

@ -14,6 +14,7 @@ import UserTimedFilterModal from 'src/components/user_timed_filter_modal/user_ti
import { propsToNative } from 'src/services/attributes_helper/attributes_helper.service.js' import { propsToNative } from 'src/services/attributes_helper/attributes_helper.service.js'
import localeService from 'src/services/locale/locale.service.js' import localeService from 'src/services/locale/locale.service.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { useInstanceStore } from 'src/stores/instance.js'
import { usePostStatusStore } from 'src/stores/post_status' import { usePostStatusStore } from 'src/stores/post_status'
import { useInterfaceStore } from '../../stores/interface' import { useInterfaceStore } from '../../stores/interface'
import { useMediaViewerStore } from '../../stores/media_viewer' import { useMediaViewerStore } from '../../stores/media_viewer'
@ -176,7 +177,7 @@ export default {
return false return false
}, },
groupActorAvailable() { groupActorAvailable() {
return this.$store.state.instance.groupActorAvailable return useInstanceStore().groupActorAvailable
}, },
availableActorTypes() { availableActorTypes() {
return this.groupActorAvailable return this.groupActorAvailable
@ -209,7 +210,7 @@ export default {
return Math.round(this.user.statuses_count / days) return Math.round(this.user.statuses_count / days)
}, },
emoji() { emoji() {
return this.$store.state.instance.customEmoji.map((e) => ({ return useInstanceStore().customEmoji.map((e) => ({
shortcode: e.displayText, shortcode: e.displayText,
static_url: e.imageUrl, static_url: e.imageUrl,
url: e.imageUrl, url: e.imageUrl,
@ -335,19 +336,13 @@ export default {
return this.newBanner === null ? currentUrl : newUrl return this.newBanner === null ? currentUrl : newUrl
}, },
defaultAvatar() { defaultAvatar() {
return ( return useInstanceStore().server + useInstanceStore().defaultAvatar
this.$store.state.instance.server +
this.$store.state.instance.defaultAvatar
)
}, },
defaultBanner() { defaultBanner() {
return ( return useInstanceStore().server + useInstanceStore().defaultBanner
this.$store.state.instance.server +
this.$store.state.instance.defaultBanner
)
}, },
isDefaultAvatar() { isDefaultAvatar() {
const baseAvatar = this.$store.state.instance.defaultAvatar const baseAvatar = useInstanceStore().defaultAvatar
return ( return (
!this.$store.state.users.currentUser.profile_image_url || !this.$store.state.users.currentUser.profile_image_url ||
this.$store.state.users.currentUser.profile_image_url.includes( this.$store.state.users.currentUser.profile_image_url.includes(
@ -356,14 +351,14 @@ export default {
) )
}, },
isDefaultBanner() { isDefaultBanner() {
const baseBanner = this.$store.state.instance.defaultBanner const baseBanner = useInstanceStore().defaultBanner
return ( return (
!this.$store.state.users.currentUser.cover_photo || !this.$store.state.users.currentUser.cover_photo ||
this.$store.state.users.currentUser.cover_photo.includes(baseBanner) this.$store.state.users.currentUser.cover_photo.includes(baseBanner)
) )
}, },
fieldsLimits() { fieldsLimits() {
return this.$store.state.instance.fieldsLimits return useInstanceStore().fieldsLimits
}, },
maxFields() { maxFields() {
return this.fieldsLimits ? this.fieldsLimits.maxFields : 0 return this.fieldsLimits ? this.fieldsLimits.maxFields : 0
@ -372,7 +367,7 @@ export default {
return suggestor({ return suggestor({
emoji: [ emoji: [
...this.$store.getters.standardEmojiList, ...this.$store.getters.standardEmojiList,
...this.$store.state.instance.customEmoji, ...useInstanceStore().customEmoji,
], ],
store: this.$store, store: this.$store,
}) })
@ -381,7 +376,7 @@ export default {
return suggestor({ return suggestor({
emoji: [ emoji: [
...this.$store.getters.standardEmojiList, ...this.$store.getters.standardEmojiList,
...this.$store.state.instance.customEmoji, ...useInstanceStore().customEmoji,
], ],
}) })
}, },
@ -412,7 +407,7 @@ export default {
return generateProfileLink( return generateProfileLink(
user.id, user.id,
user.screen_name, user.screen_name,
this.$store.state.instance.restrictedNicknames, useInstanceStore().restrictedNicknames,
) )
}, },
openProfileTab() { openProfileTab() {

View file

@ -15,6 +15,7 @@
<script> <script>
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { useInstanceStore } from 'src/stores/instance.js'
import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue' import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
const UserLink = { const UserLink = {
@ -33,7 +34,7 @@ const UserLink = {
return generateProfileLink( return generateProfileLink(
user.id, user.id,
user.screen_name, user.screen_name,
this.$store.state.instance.restrictedNicknames, useInstanceStore().restrictedNicknames,
) )
}, },
}, },

View file

@ -2,6 +2,7 @@ import get from 'lodash/get'
import RichContent from 'src/components/rich_content/rich_content.jsx' import RichContent from 'src/components/rich_content/rich_content.jsx'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
import { useInstanceStore } from 'src/stores/instance.js'
import withLoadMore from '../../hocs/with_load_more/with_load_more' import withLoadMore from '../../hocs/with_load_more/with_load_more'
import Conversation from '../conversation/conversation.vue' import Conversation from '../conversation/conversation.vue'
import FollowCard from '../follow_card/follow_card.vue' import FollowCard from '../follow_card/follow_card.vue'
@ -87,7 +88,7 @@ const UserProfile = {
favoritesTabVisible() { favoritesTabVisible() {
return ( return (
this.isUs || this.isUs ||
(this.$store.state.instance.pleromaPublicFavouritesAvailable && (useInstanceStore().pleromaPublicFavouritesAvailable &&
!this.user.hide_favorites) !this.user.hide_favorites)
) )
}, },

View file

@ -1,6 +1,7 @@
import { shuffle } from 'lodash' import { shuffle } from 'lodash'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { useInstanceStore } from 'src/stores/instance.js'
import apiService from '../../services/api/api.service.js' import apiService from '../../services/api/api.service.js'
function showWhoToFollow(panel, reply) { function showWhoToFollow(panel, reply) {
@ -8,7 +9,7 @@ function showWhoToFollow(panel, reply) {
panel.usersToFollow.forEach((toFollow, index) => { panel.usersToFollow.forEach((toFollow, index) => {
const user = shuffled[index] const user = shuffled[index]
const img = user.avatar || this.$store.state.instance.defaultAvatar const img = user.avatar || useInstanceStore().defaultAvatar
const name = user.acct const name = user.acct
toFollow.img = img toFollow.img = img
@ -46,7 +47,7 @@ const WhoToFollowPanel = {
return this.$store.state.users.currentUser.screen_name return this.$store.state.users.currentUser.screen_name
}, },
suggestionsEnabled() { suggestionsEnabled() {
return this.$store.state.instance.suggestionsEnabled return useInstanceStore().suggestionsEnabled
}, },
}, },
methods: { methods: {
@ -54,7 +55,7 @@ const WhoToFollowPanel = {
return generateProfileLink( return generateProfileLink(
id, id,
name, name,
this.$store.state.instance.restrictedNicknames, useInstanceStore().restrictedNicknames,
) )
}, },
}, },
@ -67,7 +68,7 @@ const WhoToFollowPanel = {
}, },
mounted: function () { mounted: function () {
this.usersToFollow = new Array(3).fill().map(() => ({ this.usersToFollow = new Array(3).fill().map(() => ({
img: this.$store.state.instance.defaultAvatar, img: useInstanceStore().defaultAvatar,
name: '', name: '',
id: 0, id: 0,
})) }))

View file

@ -1,8 +1,9 @@
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
export default (store) => { export default (store) => {
store.subscribe((mutation, state) => { store.subscribe((mutation, state) => {
const vapidPublicKey = state.instance.vapidPublicKey const vapidPublicKey = useInstanceStore().vapidPublicKey
const webPushNotification = state.config.webPushNotifications const webPushNotification = state.config.webPushNotifications
const permission = useInterfaceStore().notificationPermission === 'granted' const permission = useInterfaceStore().notificationPermission === 'granted'
const user = state.users.currentUser const user = state.users.currentUser

View file

@ -1,5 +1,6 @@
import { Socket } from 'phoenix' import { Socket } from 'phoenix'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface.js' import { useInterfaceStore } from 'src/stores/interface.js'
import { useShoutStore } from 'src/stores/shout.js' import { useShoutStore } from 'src/stores/shout.js'
import { WSConnectionStatus } from '../services/api/api.service.js' import { WSConnectionStatus } from '../services/api/api.service.js'
@ -237,7 +238,7 @@ const api = {
) { ) {
if ( if (
timeline === 'favourites' && timeline === 'favourites' &&
!store.rootState.instance.pleromaPublicFavouritesAvailable !useInstanceStore().pleromaPublicFavouritesAvailable
) )
return return
if (store.state.fetchers[timeline]) return if (store.state.fetchers[timeline]) return
@ -322,7 +323,7 @@ const api = {
// Bookmark folders // Bookmark folders
startFetchingBookmarkFolders(store) { startFetchingBookmarkFolders(store) {
if (store.state.fetchers.bookmarkFolders) return if (store.state.fetchers.bookmarkFolders) return
if (!store.rootState.instance.pleromaBookmarkFoldersAvailable) return if (!useInstanceStore().pleromaBookmarkFoldersAvailable) return
const fetcher = const fetcher =
store.state.backendInteractor.startFetchingBookmarkFolders({ store }) store.state.backendInteractor.startFetchingBookmarkFolders({ store })
store.commit('addFetcher', { fetcherName: 'bookmarkFolders', fetcher }) store.commit('addFetcher', { fetcherName: 'bookmarkFolders', fetcher })
@ -341,7 +342,7 @@ const api = {
// Set up websocket connection // Set up websocket connection
const token = state.wsToken const token = state.wsToken
if ( if (
rootState.instance.shoutAvailable && useInstanceStore().shoutAvailable &&
typeof token !== 'undefined' && typeof token !== 'undefined' &&
state.socket === null state.socket === null
) { ) {

View file

@ -1,376 +0,0 @@
// See build/emojis_plugin for more details
import { useInterfaceStore } from 'src/stores/interface.js'
import { ensureFinalFallback } from '../i18n/languages.js'
import apiService from '../services/api/api.service.js'
import { instanceDefaultProperties } from './config.js'
import {
instanceDefaultConfig,
staticOrApiConfigDefault,
} from './default_config_state.js'
import { annotationsLoader } from 'virtual:pleroma-fe/emoji-annotations'
const SORTED_EMOJI_GROUP_IDS = [
'smileys-and-emotion',
'people-and-body',
'animals-and-nature',
'food-and-drink',
'travel-and-places',
'activities',
'objects',
'symbols',
'flags',
]
const REGIONAL_INDICATORS = (() => {
const start = 0x1f1e6
const end = 0x1f1ff
const A = 'A'.codePointAt(0)
const res = new Array(end - start + 1)
for (let i = start; i <= end; ++i) {
const letter = String.fromCodePoint(A + i - start)
res[i - start] = {
replacement: String.fromCodePoint(i),
imageUrl: false,
displayText: 'regional_indicator_' + letter,
displayTextI18n: {
key: 'emoji.regional_indicator',
args: { letter },
},
}
}
return res
})()
const REMOTE_INTERACTION_URL = '/main/ostatus'
const defaultState = {
// Stuff from apiConfig
name: 'Pleroma FE',
registrationOpen: true,
server: 'http://localhost:4040/',
textlimit: 5000,
themesIndex: undefined,
stylesIndex: undefined,
palettesIndex: undefined,
themeData: undefined, // used for theme editor v2
vapidPublicKey: undefined,
// Stuff from static/config.json
loginMethod: 'password',
disableUpdateNotification: false,
fontsOverride: {},
// Instance-wide configurations that should not be changed by individual users
...staticOrApiConfigDefault,
// Instance admins can override default settings for the whole instance
...instanceDefaultConfig,
// Nasty stuff
customEmoji: [],
customEmojiFetched: false,
emoji: {},
emojiFetched: false,
unicodeEmojiAnnotations: {},
pleromaExtensionsAvailable: true,
postFormats: [],
restrictedNicknames: [],
safeDM: true,
knownDomains: [],
birthdayRequired: false,
birthdayMinAge: 0,
// Feature-set, apparently, not everything here is reported...
shoutAvailable: false,
pleromaChatMessagesAvailable: false,
pleromaCustomEmojiReactionsAvailable: false,
pleromaBookmarkFoldersAvailable: false,
pleromaPublicFavouritesAvailable: true,
statusNotificationTypeAvailable: true,
gopherAvailable: false,
mediaProxyAvailable: false,
suggestionsEnabled: false,
suggestionsWeb: '',
quotingAvailable: false,
groupActorAvailable: false,
blockExpiration: false,
localBubbleInstances: [], // Akkoma
// Html stuff
instanceSpecificPanelContent: '',
tos: '',
// Version Information
backendVersion: '',
backendRepository: '',
frontendVersion: '',
pollsAvailable: false,
pollLimits: {
max_options: 4,
max_option_chars: 255,
min_expiration: 60,
max_expiration: 60 * 60 * 24,
},
}
const loadAnnotations = (lang) => {
return annotationsLoader[lang]().then((k) => k.default)
}
const injectAnnotations = (emoji, annotations) => {
const availableLangs = Object.keys(annotations)
return {
...emoji,
annotations: availableLangs.reduce((acc, cur) => {
acc[cur] = annotations[cur][emoji.replacement]
return acc
}, {}),
}
}
const injectRegionalIndicators = (groups) => {
groups.symbols.push(...REGIONAL_INDICATORS)
return groups
}
const instance = {
state: defaultState,
mutations: {
setInstanceOption(state, { name, value }) {
if (typeof value !== 'undefined') {
state[name] = value
}
},
setKnownDomains(state, domains) {
state.knownDomains = domains
},
setUnicodeEmojiAnnotations(state, { lang, annotations }) {
state.unicodeEmojiAnnotations[lang] = annotations
},
},
getters: {
instanceDefaultConfig(state) {
return instanceDefaultProperties
.map((key) => [key, state[key]])
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
},
groupedCustomEmojis(state) {
const packsOf = (emoji) => {
const packs = emoji.tags
.filter((k) => k.startsWith('pack:'))
.map((k) => {
const packName = k.slice(5) // remove 'pack:' prefix
return {
id: `custom-${packName}`,
text: packName,
}
})
if (!packs.length) {
return [
{
id: 'unpacked',
},
]
} else {
return packs
}
}
return state.customEmoji.reduce((res, emoji) => {
packsOf(emoji).forEach(({ id: packId, text: packName }) => {
if (!res[packId]) {
res[packId] = {
id: packId,
text: packName,
image: emoji.imageUrl,
emojis: [],
}
}
res[packId].emojis.push(emoji)
})
return res
}, {})
},
standardEmojiList(state) {
return SORTED_EMOJI_GROUP_IDS.map((groupId) =>
(state.emoji[groupId] || []).map((k) =>
injectAnnotations(k, state.unicodeEmojiAnnotations),
),
).reduce((a, b) => a.concat(b), [])
},
standardEmojiGroupList(state) {
return SORTED_EMOJI_GROUP_IDS.map((groupId) => ({
id: groupId,
emojis: (state.emoji[groupId] || []).map((k) =>
injectAnnotations(k, state.unicodeEmojiAnnotations),
),
}))
},
instanceDomain(state) {
return new URL(state.server).hostname
},
remoteInteractionLink(state) {
const server = state.server.endsWith('/')
? state.server.slice(0, -1)
: state.server
const link = server + REMOTE_INTERACTION_URL
return ({ statusId, nickname }) => {
if (statusId) {
return `${link}?status_id=${statusId}`
} else {
return `${link}?nickname=${nickname}`
}
}
},
},
actions: {
setInstanceOption({ commit, dispatch }, { name, value }) {
commit('setInstanceOption', { name, value })
switch (name) {
case 'name':
useInterfaceStore().setPageTitle()
break
case 'shoutAvailable':
if (value) {
dispatch('initializeSocket')
}
break
}
},
async getStaticEmoji({ commit }) {
try {
const values = (await import('/src/assets/emoji.json')).default
const emoji = Object.keys(values).reduce((res, groupId) => {
res[groupId] = values[groupId].map((e) => ({
displayText: e.slug,
imageUrl: false,
replacement: e.emoji,
}))
return res
}, {})
commit('setInstanceOption', {
name: 'emoji',
value: injectRegionalIndicators(emoji),
})
} catch (e) {
console.warn("Can't load static emoji\n", e)
}
},
loadUnicodeEmojiData({ commit, state }, language) {
const langList = ensureFinalFallback(language)
return Promise.all(
langList.map(async (lang) => {
if (!state.unicodeEmojiAnnotations[lang]) {
try {
const annotations = await loadAnnotations(lang)
commit('setUnicodeEmojiAnnotations', { lang, annotations })
} catch (e) {
console.warn(
`Error loading unicode emoji annotations for ${lang}: `,
e,
)
// ignore
}
}
}),
)
},
async getCustomEmoji({ commit, state }) {
try {
let res = await window.fetch('/api/v1/pleroma/emoji')
if (!res.ok) {
res = await window.fetch('/api/pleroma/emoji.json')
}
if (res.ok) {
const result = await res.json()
const values = Array.isArray(result)
? Object.assign({}, ...result)
: result
const caseInsensitiveStrCmp = (a, b) => {
const la = a.toLowerCase()
const lb = b.toLowerCase()
return la > lb ? 1 : la < lb ? -1 : 0
}
const noPackLast = (a, b) => {
const aNull = a === ''
const bNull = b === ''
if (aNull === bNull) {
return 0
} else if (aNull && !bNull) {
return 1
} else {
return -1
}
}
const byPackThenByName = (a, b) => {
const packOf = (emoji) =>
(emoji.tags.filter((k) => k.startsWith('pack:'))[0] || '').slice(
5,
)
const packOfA = packOf(a)
const packOfB = packOf(b)
return (
noPackLast(packOfA, packOfB) ||
caseInsensitiveStrCmp(packOfA, packOfB) ||
caseInsensitiveStrCmp(a.displayText, b.displayText)
)
}
const emoji = Object.entries(values)
.map(([key, value]) => {
const imageUrl = value.image_url
return {
displayText: key,
imageUrl: imageUrl ? state.server + imageUrl : value,
tags: imageUrl
? value.tags.sort((a, b) => (a > b ? 1 : 0))
: ['utf'],
replacement: `:${key}: `,
}
// Technically could use tags but those are kinda useless right now,
// should have been "pack" field, that would be more useful
})
.sort(byPackThenByName)
commit('setInstanceOption', { name: 'customEmoji', value: emoji })
} else {
throw res
}
} catch (e) {
console.warn("Can't load custom emojis\n", e)
}
},
fetchEmoji({ dispatch, state }) {
if (!state.customEmojiFetched) {
state.customEmojiFetched = true
dispatch('getCustomEmoji')
}
if (!state.emojiFetched) {
state.emojiFetched = true
dispatch('getStaticEmoji')
}
},
async getKnownDomains({ commit, rootState }) {
try {
const result = await apiService.fetchKnownDomains({
credentials: rootState.users.currentUser.credentials,
})
commit('setKnownDomains', result)
} catch (e) {
console.warn("Can't load known domains\n", e)
}
},
},
}
export default instance

View file

@ -10,6 +10,7 @@ import {
} from 'lodash' } from 'lodash'
import { declarations } from 'src/modules/config_declaration' import { declarations } from 'src/modules/config_declaration'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface.js' import { useInterfaceStore } from 'src/stores/interface.js'
import { useOAuthStore } from 'src/stores/oauth.js' import { useOAuthStore } from 'src/stores/oauth.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
@ -547,7 +548,7 @@ const users = {
}, },
registerPushNotifications(store) { registerPushNotifications(store) {
const token = store.state.currentUser.credentials const token = store.state.currentUser.credentials
const vapidPublicKey = store.rootState.instance.vapidPublicKey const vapidPublicKey = useInstanceStore().vapidPublicKey
const isEnabled = store.rootState.config.webPushNotifications const isEnabled = store.rootState.config.webPushNotifications
const notificationVisibility = const notificationVisibility =
store.rootState.config.notificationVisibility store.rootState.config.notificationVisibility
@ -685,7 +686,6 @@ const users = {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const commit = store.commit const commit = store.commit
const dispatch = store.dispatch const dispatch = store.dispatch
const rootState = store.rootState
commit('beginLogin') commit('beginLogin')
store.rootState.api.backendInteractor store.rootState.api.backendInteractor
.verifyCredentials(accessToken) .verifyCredentials(accessToken)
@ -763,7 +763,7 @@ const users = {
// Start fetching notifications // Start fetching notifications
dispatch('startFetchingNotifications') dispatch('startFetchingNotifications')
if (rootState.instance.pleromaChatMessagesAvailable) { if (useInstanceStore().pleromaChatMessagesAvailable) {
// Start fetching chats // Start fetching chats
dispatch('startFetchingChats') dispatch('startFetchingChats')
} }

View file

@ -1,3 +1,4 @@
import { useInstanceStore } from 'src/stores/instance.js'
import bookmarkFoldersFetcher from '../../services/bookmark_folders_fetcher/bookmark_folders_fetcher.service.js' import bookmarkFoldersFetcher from '../../services/bookmark_folders_fetcher/bookmark_folders_fetcher.service.js'
import followRequestFetcher from '../../services/follow_request_fetcher/follow_request_fetcher.service' import followRequestFetcher from '../../services/follow_request_fetcher/follow_request_fetcher.service'
import listsFetcher from '../../services/lists_fetcher/lists_fetcher.service.js' import listsFetcher from '../../services/lists_fetcher/lists_fetcher.service.js'
@ -55,7 +56,7 @@ const backendInteractorService = (credentials) => ({
}, },
startUserSocket({ store }) { startUserSocket({ store }) {
const serv = store.rootState.instance.server.replace('http', 'ws') const serv = useInstanceStore().server.replace('http', 'ws')
const url = getMastodonSocketURI({}, serv) const url = getMastodonSocketURI({}, serv)
return ProcessedWS({ url, id: 'Unified', credentials }) return ProcessedWS({ url, id: 'Unified', credentials })
}, },

View file

@ -1,3 +1,4 @@
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface.js' import { useInterfaceStore } from 'src/stores/interface.js'
import apiService from '../api/api.service.js' import apiService from '../api/api.service.js'
import { promiseInterval } from '../promise_interval/promise_interval.js' import { promiseInterval } from '../promise_interval/promise_interval.js'
@ -28,7 +29,7 @@ const fetchAndUpdate = ({ store, credentials, older = false, since }) => {
const timelineData = rootState.notifications const timelineData = rootState.notifications
const hideMutedPosts = getters.mergedConfig.hideMutedPosts const hideMutedPosts = getters.mergedConfig.hideMutedPosts
if (rootState.instance.pleromaChatMessagesAvailable) { if (useInstanceStore().pleromaChatMessagesAvailable) {
mastoApiNotificationTypes.add('pleroma:chat_mention') mastoApiNotificationTypes.add('pleroma:chat_mention')
} }

View file

@ -1,5 +1,6 @@
import { camelCase } from 'lodash' import { camelCase } from 'lodash'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface.js' import { useInterfaceStore } from 'src/stores/interface.js'
import apiService from '../api/api.service.js' import apiService from '../api/api.service.js'
import { promiseInterval } from '../promise_interval/promise_interval.js' import { promiseInterval } from '../promise_interval/promise_interval.js'
@ -76,7 +77,7 @@ const fetchAndUpdate = ({
.then((response) => { .then((response) => {
if (response.errors) { if (response.errors) {
if (timeline === 'favorites') { if (timeline === 'favorites') {
rootState.instance.pleromaPublicFavouritesAvailable = false useInstanceStore().pleromaPublicFavouritesAvailable = false
return return
} }
throw new Error(`${response.status} ${response.statusText}`) throw new Error(`${response.status} ${response.statusText}`)

157
src/stores/instance.js Normal file
View file

@ -0,0 +1,157 @@
import { get, set } from 'lodash'
import { defineStore } from 'pinia'
import { ensureFinalFallback } from 'src/i18n/languages.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { instanceDefaultProperties } from '../modules/config.js'
import {
instanceDefaultConfig,
staticOrApiConfigDefault,
} from '../modules/default_config_state.js'
import apiService from '../services/api/api.service.js'
const REMOTE_INTERACTION_URL = '/main/ostatus'
const defaultState = {
// Stuff from apiConfig
name: 'Pleroma FE',
registrationOpen: true,
server: 'http://localhost:4040/',
textlimit: 5000,
private: false,
federating: true,
federationPolicy: null,
themesIndex: null,
stylesIndex: null,
palettesIndex: null,
themeData: null, // used for theme editor v2
vapidPublicKey: null,
// Stuff from static/config.json
loginMethod: 'password',
disableUpdateNotification: false,
// Instance-wide configurations that should not be changed by individual users
instanceIdentity: {
...staticOrApiConfigDefault,
},
limits: {
bannerlimit: null,
avatarlimit: null,
backgroundlimit: null,
uploadlimit: null,
fieldsLimits: null,
pollLimits: {
max_options: 4,
max_option_chars: 255,
min_expiration: 60,
max_expiration: 60 * 60 * 24,
},
},
// Instance admins can override default settings for the whole instance
prefsStorage: {
...instanceDefaultConfig,
},
// Known domains list for user's domain-muting
knownDomains: [],
// Moderation stuff
staffAccounts: [],
accountActivationRequired: null,
accountApprovalRequired: null,
birthdayRequired: false,
birthdayMinAge: 0,
restrictedNicknames: [],
localBubbleInstances: [], // Akkoma
// Feature-set, apparently, not everything here is reported...
featureSet: {
postFormats: [],
mailerEnabled: false,
safeDM: true,
shoutAvailable: false,
pleromaExtensionsAvailable: true,
pleromaChatMessagesAvailable: false,
pleromaCustomEmojiReactionsAvailable: false,
pleromaBookmarkFoldersAvailable: false,
pleromaPublicFavouritesAvailable: true,
statusNotificationTypeAvailable: true,
gopherAvailable: false,
editingAvailable: false,
mediaProxyAvailable: false,
suggestionsEnabled: false,
suggestionsWeb: '',
quotingAvailable: false,
groupActorAvailable: false,
blockExpiration: false,
tagPolicyAvailable: false,
pollsAvailable: false,
localBubble: false, // Akkoma
},
// Html stuff
instanceSpecificPanelContent: '',
tos: '',
// Version Information
backendVersion: '',
backendRepository: '',
frontendVersion: '',
}
export const useInstanceStore = defineStore('instance', {
state: () => ({ ...defaultState }),
getters: {
instanceDefaultConfig(state) {
return instanceDefaultProperties
.map((key) => [key, state[key]])
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
},
instanceDomain(state) {
return new URL(this.server).hostname
},
remoteInteractionLink(state) {
const server = this.server.endsWith('/')
? this.server.slice(0, -1)
: this.server
const link = server + REMOTE_INTERACTION_URL
return ({ statusId, nickname }) => {
if (statusId) {
return `${link}?status_id=${statusId}`
} else {
return `${link}?nickname=${nickname}`
}
}
},
},
actions: {
set({ path, value }) {
if (get(defaultState, path) === undefined)
console.error(`Unknown instance option ${path}, value: ${value}`)
set(this, path, value)
switch (name) {
case 'name':
useInterfaceStore().setPageTitle()
break
case 'shoutAvailable':
if (value) {
window.vuex.dispatch('initializeSocket')
}
break
}
},
async getKnownDomains() {
try {
this.knownDomains = await apiService.fetchKnownDomains({
credentials: window.vuex.state.users.currentUser.credentials,
})
} catch (e) {
console.warn("Can't load known domains\n", e)
}
},
},
})

View file

@ -5,6 +5,7 @@ import {
generatePreset, generatePreset,
} from 'src/services/theme_data/theme_data.service.js' } from 'src/services/theme_data/theme_data.service.js'
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js' import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { import {
applyTheme, applyTheme,
getResourcesIndex, getResourcesIndex,
@ -86,7 +87,7 @@ export const useInterfaceStore = defineStore('interface', {
}, },
setPageTitle(option = '') { setPageTitle(option = '') {
try { try {
document.title = `${option} ${window.vuex.state.instance.name}` document.title = `${option} ${window.vuex.useInstanceStore().name}`
} catch (error) { } catch (error) {
console.error(`${error}`) console.error(`${error}`)
} }
@ -385,14 +386,14 @@ export const useInterfaceStore = defineStore('interface', {
} }
const { style: instanceStyleName, palette: instancePaletteName } = const { style: instanceStyleName, palette: instancePaletteName } =
window.vuex.state.instance window.vuex.useInstanceStore()
let { let {
theme: instanceThemeV2Name, theme: instanceThemeV2Name,
themesIndex, themesIndex,
stylesIndex, stylesIndex,
palettesIndex, palettesIndex,
} = window.vuex.state.instance } = window.vuex.useInstanceStore()
const { const {
style: userStyleName, style: userStyleName,

View file

@ -5,6 +5,7 @@ import {
getClientToken, getClientToken,
verifyAppToken, verifyAppToken,
} from 'src/services/new_api/oauth.js' } from 'src/services/new_api/oauth.js'
import { useInstanceStore } from 'src/stores/instance.js'
// status codes about verifyAppToken (GET /api/v1/apps/verify_credentials) // status codes about verifyAppToken (GET /api/v1/apps/verify_credentials)
const isAppTokenRejected = (error) => const isAppTokenRejected = (error) =>
@ -61,8 +62,7 @@ export const useOAuthStore = defineStore('oauth', {
this.userToken = false this.userToken = false
}, },
async createApp() { async createApp() {
const { state } = window.vuex const instance = useInstanceStore().server
const instance = state.instance.server
const app = await createApp(instance) const app = await createApp(instance)
this.setClientData(app) this.setClientData(app)
return app return app
@ -81,8 +81,7 @@ export const useOAuthStore = defineStore('oauth', {
} }
}, },
async getAppToken() { async getAppToken() {
const { state } = window.vuex const instance = useInstanceStore().server
const instance = state.instance.server
const res = await getClientToken({ const res = await getClientToken({
clientId: this.clientId, clientId: this.clientId,
clientSecret: this.clientSecret, clientSecret: this.clientSecret,
@ -94,11 +93,10 @@ export const useOAuthStore = defineStore('oauth', {
/// Use this if you want to ensure the app is still valid to use. /// Use this if you want to ensure the app is still valid to use.
/// @return {string} The access token to the app (not attached to any user) /// @return {string} The access token to the app (not attached to any user)
async ensureAppToken() { async ensureAppToken() {
const { state } = window.vuex
if (this.appToken) { if (this.appToken) {
try { try {
await verifyAppToken({ await verifyAppToken({
instance: state.instance.server, instance: useInstanceStore().server,
appToken: this.appToken, appToken: this.appToken,
}) })
return this.appToken return this.appToken