Merge branch 'develop' into setttingssync
This commit is contained in:
commit
3530830b07
134 changed files with 1411 additions and 1299 deletions
0
changelog.d/instance-store-migration.skip
Normal file
0
changelog.d/instance-store-migration.skip
Normal file
145
src/App.js
145
src/App.js
|
|
@ -1,36 +1,31 @@
|
||||||
import { throttle } from 'lodash'
|
import { throttle } from 'lodash'
|
||||||
import { mapActions, mapState } from 'pinia'
|
import { mapState } from 'pinia'
|
||||||
import { defineAsyncComponent } from 'vue'
|
import { defineAsyncComponent } from 'vue'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
import DesktopNav from 'src/components/desktop_nav/desktop_nav.vue'
|
import DesktopNav from './components/desktop_nav/desktop_nav.vue'
|
||||||
import EditStatusModal from 'src/components/edit_status_modal/edit_status_modal.vue'
|
import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue'
|
||||||
import FeaturesPanel from 'src/components/features_panel/features_panel.vue'
|
import FeaturesPanel from './components/features_panel/features_panel.vue'
|
||||||
import GlobalNoticeList from 'src/components/global_notice_list/global_notice_list.vue'
|
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
|
||||||
import InstanceSpecificPanel from 'src/components/instance_specific_panel/instance_specific_panel.vue'
|
import InstanceSpecificPanel from './components/instance_specific_panel/instance_specific_panel.vue'
|
||||||
import MediaModal from 'src/components/media_modal/media_modal.vue'
|
import MediaModal from './components/media_modal/media_modal.vue'
|
||||||
import MobileNav from 'src/components/mobile_nav/mobile_nav.vue'
|
import MobileNav from './components/mobile_nav/mobile_nav.vue'
|
||||||
import MobilePostStatusButton from 'src/components/mobile_post_status_button/mobile_post_status_button.vue'
|
import MobilePostStatusButton from './components/mobile_post_status_button/mobile_post_status_button.vue'
|
||||||
import NavPanel from 'src/components/nav_panel/nav_panel.vue'
|
import NavPanel from './components/nav_panel/nav_panel.vue'
|
||||||
import PostStatusModal from 'src/components/post_status_modal/post_status_modal.vue'
|
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
|
||||||
import ShoutPanel from 'src/components/shout_panel/shout_panel.vue'
|
import ShoutPanel from './components/shout_panel/shout_panel.vue'
|
||||||
import SideDrawer from 'src/components/side_drawer/side_drawer.vue'
|
import SideDrawer from './components/side_drawer/side_drawer.vue'
|
||||||
import StatusHistoryModal from 'src/components/status_history_modal/status_history_modal.vue'
|
import StatusHistoryModal from './components/status_history_modal/status_history_modal.vue'
|
||||||
import UserPanel from 'src/components/user_panel/user_panel.vue'
|
import UserPanel from './components/user_panel/user_panel.vue'
|
||||||
import UserReportingModal from 'src/components/user_reporting_modal/user_reporting_modal.vue'
|
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
|
||||||
import WhoToFollowPanel from 'src/components/who_to_follow_panel/who_to_follow_panel.vue'
|
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
|
||||||
|
import { getOrCreateServiceWorker } from './services/sw/sw'
|
||||||
|
import { windowHeight, windowWidth } from './services/window_utils/window_utils'
|
||||||
|
|
||||||
import { useI18nStore } from 'src/stores/i18n.js'
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.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 { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { applyStyleConfig } from 'src/services/style_setter/style_setter.js'
|
|
||||||
import { getOrCreateServiceWorker } from 'src/services/sw/sw'
|
|
||||||
import {
|
|
||||||
windowHeight,
|
|
||||||
windowWidth,
|
|
||||||
} from 'src/services/window_utils/window_utils'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
|
|
@ -76,11 +71,11 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
// Load the locale from the storage
|
||||||
|
const val = this.$store.getters.mergedConfig.interfaceLanguage
|
||||||
|
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
|
||||||
document.getElementById('modal').classList = ['-' + this.layoutType]
|
document.getElementById('modal').classList = ['-' + this.layoutType]
|
||||||
|
|
||||||
useI18nStore().setLanguage()
|
|
||||||
applyStyleConfig(useSyncConfigStore().mergedConfig)
|
|
||||||
|
|
||||||
// Create bound handlers
|
// Create bound handlers
|
||||||
this.updateScrollState = throttle(this.scrollHandler, 200)
|
this.updateScrollState = throttle(this.scrollHandler, 200)
|
||||||
this.updateMobileState = throttle(this.resizeHandler, 200)
|
this.updateMobileState = throttle(this.resizeHandler, 200)
|
||||||
|
|
@ -89,7 +84,7 @@ export default {
|
||||||
window.addEventListener('resize', this.updateMobileState)
|
window.addEventListener('resize', this.updateMobileState)
|
||||||
this.scrollParent.addEventListener('scroll', this.updateScrollState)
|
this.scrollParent.addEventListener('scroll', this.updateScrollState)
|
||||||
|
|
||||||
if (useInterfaceStore().themeApplied) {
|
if (this.themeApplied) {
|
||||||
this.setThemeBodyClass()
|
this.setThemeBodyClass()
|
||||||
this.removeSplash()
|
this.removeSplash()
|
||||||
}
|
}
|
||||||
|
|
@ -100,12 +95,9 @@ export default {
|
||||||
this.scrollParent.removeEventListener('scroll', this.updateScrollState)
|
this.scrollParent.removeEventListener('scroll', this.updateScrollState)
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
themeApplied() {
|
|
||||||
return useInterfaceStore().themeApplied
|
|
||||||
},
|
|
||||||
currentTheme() {
|
currentTheme() {
|
||||||
if (useInterfaceStore().styleDataUsed) {
|
if (this.styleDataUsed) {
|
||||||
const styleMeta = useInterfaceStore().styleDataUsed.find(
|
const styleMeta = this.styleDataUsed.find(
|
||||||
(x) => x.component === '@meta',
|
(x) => x.component === '@meta',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -130,7 +122,7 @@ export default {
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
navClasses() {
|
navClasses() {
|
||||||
const { navbarColumnStretch } = useSyncConfigStore().mergedConfig
|
const { navbarColumnStretch } = this.$store.getters.mergedConfig
|
||||||
return [
|
return [
|
||||||
'-' + this.layoutType,
|
'-' + this.layoutType,
|
||||||
...(navbarColumnStretch ? ['-column-stretch'] : []),
|
...(navbarColumnStretch ? ['-column-stretch'] : []),
|
||||||
|
|
@ -142,6 +134,9 @@ export default {
|
||||||
userBackground() {
|
userBackground() {
|
||||||
return this.currentUser.background_image
|
return this.currentUser.background_image
|
||||||
},
|
},
|
||||||
|
instanceBackground() {
|
||||||
|
return this.mergedConfig.hideInstanceWallpaper ? null : this.background
|
||||||
|
},
|
||||||
background() {
|
background() {
|
||||||
return this.userBackground || this.instanceBackground
|
return this.userBackground || this.instanceBackground
|
||||||
},
|
},
|
||||||
|
|
@ -164,11 +159,20 @@ export default {
|
||||||
newPostButtonShown() {
|
newPostButtonShown() {
|
||||||
if (this.isChats) return false
|
if (this.isChats) return false
|
||||||
if (this.isListEdit) return false
|
if (this.isListEdit) return false
|
||||||
return this.alwaysShowNewPostButton || this.layoutType === 'mobile'
|
return (
|
||||||
|
this.$store.getters.mergedConfig.alwaysShowNewPostButton ||
|
||||||
|
this.layoutType === 'mobile'
|
||||||
|
)
|
||||||
|
},
|
||||||
|
shoutboxPosition() {
|
||||||
|
return this.$store.getters.mergedConfig.alwaysShowNewPostButton || false
|
||||||
|
},
|
||||||
|
hideShoutbox() {
|
||||||
|
return this.$store.getters.mergedConfig.hideShoutbox
|
||||||
},
|
},
|
||||||
reverseLayout() {
|
reverseLayout() {
|
||||||
const { thirdColumnMode, sidebarRight: reverseSetting } =
|
const { thirdColumnMode, sidebarRight: reverseSetting } =
|
||||||
useSyncConfigStore().mergedConfig
|
this.$store.getters.mergedConfig
|
||||||
if (this.layoutType !== 'wide') {
|
if (this.layoutType !== 'wide') {
|
||||||
return reverseSetting
|
return reverseSetting
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -177,46 +181,44 @@ export default {
|
||||||
: !reverseSetting
|
: !reverseSetting
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
noSticky() {
|
||||||
|
return this.$store.getters.mergedConfig.disableStickyHeaders
|
||||||
|
},
|
||||||
|
showScrollbars() {
|
||||||
|
return this.$store.getters.mergedConfig.showScrollbars
|
||||||
|
},
|
||||||
scrollParent() {
|
scrollParent() {
|
||||||
return window /* this.$refs.appContentRef */
|
return window /* this.$refs.appContentRef */
|
||||||
},
|
},
|
||||||
|
showInstanceSpecificPanel() {
|
||||||
...mapState(useSyncConfigStore, {
|
return (
|
||||||
shoutboxPosition: (store) =>
|
this.instanceSpecificPanelPresent &&
|
||||||
store.mergedConfig.alwaysShowSubjectInput || false,
|
!this.$store.getters.mergedConfig.hideISP
|
||||||
alwaysShowSubjectInput: (store) =>
|
)
|
||||||
store.mergedConfig.alwaysShowSubjectInput,
|
},
|
||||||
}),
|
...mapGetters(['mergedConfig']),
|
||||||
|
...mapState(useInterfaceStore, [
|
||||||
...mapState(useInterfaceStore, ['layoutType']),
|
'themeApplied',
|
||||||
|
'styleDataUsed',
|
||||||
...mapState(useSyncConfigStore, {
|
'layoutType',
|
||||||
hideShoutbox: (store) => store.mergedConfig.hideShoutbox,
|
|
||||||
noSticky: (store) => store.mergedConfig.disableStickyHeaders,
|
|
||||||
showScrollbars: (store) => store.mergedConfig.showScrollbars,
|
|
||||||
}),
|
|
||||||
|
|
||||||
...mapState(useInstanceStore, {
|
|
||||||
instanceBackground: (store) =>
|
|
||||||
useSyncConfigStore().mergedConfig.hideInstanceWallpaper
|
|
||||||
? null
|
|
||||||
: store.background,
|
|
||||||
showInstanceSpecificPanel: (store) =>
|
|
||||||
store.showInstanceSpecificPanel &&
|
|
||||||
!useSyncConfigStore().mergedConfig.hideISP &&
|
|
||||||
store.instanceSpecificPanelContent,
|
|
||||||
}),
|
|
||||||
...mapState(useInstanceStore, [
|
|
||||||
'editingAvailable',
|
|
||||||
'showFeaturesPanel',
|
|
||||||
'private',
|
|
||||||
'suggestionsEnabled',
|
|
||||||
]),
|
]),
|
||||||
|
...mapState(useInstanceStore, ['styleDataUsed']),
|
||||||
|
...mapState(useInstanceCapabilitiesStore, [
|
||||||
|
'suggestionsEnabled',
|
||||||
|
'editingAvailable',
|
||||||
|
]),
|
||||||
|
...mapState(useInstanceStore, {
|
||||||
|
background: (store) => store.instanceIdentity.background,
|
||||||
|
showFeaturesPanel: (store) => store.instanceIdentity.showFeaturesPanel,
|
||||||
|
instanceSpecificPanelPresent: (store) =>
|
||||||
|
store.instanceIdentity.showInstanceSpecificPanel &&
|
||||||
|
store.instanceIdentity.instanceSpecificPanelContent,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resizeHandler() {
|
resizeHandler() {
|
||||||
this.setLayoutWidth(windowWidth())
|
useInterfaceStore().setLayoutWidth(windowWidth())
|
||||||
this.setLayoutHeight(windowHeight())
|
useInterfaceStore().setLayoutHeight(windowHeight())
|
||||||
},
|
},
|
||||||
scrollHandler() {
|
scrollHandler() {
|
||||||
const scrollPosition =
|
const scrollPosition =
|
||||||
|
|
@ -263,6 +265,5 @@ export default {
|
||||||
splashscreenRoot.classList.add('hidden')
|
splashscreenRoot.classList.add('hidden')
|
||||||
document.querySelector('#app').classList.remove('hidden')
|
document.querySelector('#app').classList.remove('hidden')
|
||||||
},
|
},
|
||||||
...mapActions(useInterfaceStore, ['setLayoutWidth', 'setLayoutHeight']),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
/* global process */
|
/* global process */
|
||||||
|
|
||||||
import vClickOutside from 'click-outside-vue3'
|
import vClickOutside from 'click-outside-vue3'
|
||||||
import { get, set } from 'lodash'
|
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import VueVirtualScroller from 'vue-virtual-scroller'
|
import VueVirtualScroller from 'vue-virtual-scroller'
|
||||||
|
|
@ -18,7 +17,7 @@ config.autoAddCss = false
|
||||||
import App from '../App.vue'
|
import App from '../App.vue'
|
||||||
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
|
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
|
||||||
import FaviconService from '../services/favicon_service/favicon_service.js'
|
import FaviconService from '../services/favicon_service/favicon_service.js'
|
||||||
import { applyStyleConfig } from '../services/style_setter/style_setter.js'
|
import { applyConfig } from '../services/style_setter/style_setter.js'
|
||||||
import { initServiceWorker, updateFocus } from '../services/sw/sw.js'
|
import { initServiceWorker, updateFocus } from '../services/sw/sw.js'
|
||||||
import {
|
import {
|
||||||
windowHeight,
|
windowHeight,
|
||||||
|
|
@ -26,13 +25,14 @@ import {
|
||||||
} from '../services/window_utils/window_utils'
|
} from '../services/window_utils/window_utils'
|
||||||
import routes from './routes'
|
import routes from './routes'
|
||||||
|
|
||||||
import { useAnnouncementsStore } from 'src/stores/announcements.js'
|
import { useAnnouncementsStore } from 'src/stores/announcements'
|
||||||
import { useAuthFlowStore } from 'src/stores/auth_flow.js'
|
import { useAuthFlowStore } from 'src/stores/auth_flow'
|
||||||
import { useI18nStore } from 'src/stores/i18n.js'
|
import { useEmojiStore } from 'src/stores/emoji.js'
|
||||||
|
import { useI18nStore } from 'src/stores/i18n'
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.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'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import VBodyScrollLock from 'src/directives/body_scroll_lock'
|
import VBodyScrollLock from 'src/directives/body_scroll_lock'
|
||||||
import {
|
import {
|
||||||
|
|
@ -83,30 +83,30 @@ const getInstanceConfig = async ({ store }) => {
|
||||||
const textlimit = data.max_toot_chars
|
const textlimit = data.max_toot_chars
|
||||||
const vapidPublicKey = data.pleroma.vapid_public_key
|
const vapidPublicKey = data.pleroma.vapid_public_key
|
||||||
|
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'pleromaExtensionsAvailable',
|
||||||
|
data.pleroma,
|
||||||
|
)
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'featureSet.pleromaExtensionsAvailable',
|
name: 'textlimit',
|
||||||
value: data.pleroma,
|
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'textlimit',
|
|
||||||
value: textlimit,
|
value: textlimit,
|
||||||
})
|
})
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'accountApprovalRequired',
|
name: 'accountApprovalRequired',
|
||||||
value: data.approval_required,
|
value: data.approval_required,
|
||||||
})
|
})
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'birthdayRequired',
|
name: 'birthdayRequired',
|
||||||
value: !!data.pleroma?.metadata.birthday_required,
|
value: !!data.pleroma?.metadata.birthday_required,
|
||||||
})
|
})
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'birthdayMinAge',
|
name: 'birthdayMinAge',
|
||||||
value: data.pleroma?.metadata.birthday_min_age || 0,
|
value: data.pleroma?.metadata.birthday_min_age || 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (vapidPublicKey) {
|
if (vapidPublicKey) {
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'vapidPublicKey',
|
name: 'vapidPublicKey',
|
||||||
value: vapidPublicKey,
|
value: vapidPublicKey,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -161,31 +161,23 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
|
||||||
let config = {}
|
let config = {}
|
||||||
if (overrides.staticConfigPreference && env === 'development') {
|
if (overrides.staticConfigPreference && env === 'development') {
|
||||||
console.warn('OVERRIDING API CONFIG WITH STATIC CONFIG')
|
console.warn('OVERRIDING API CONFIG WITH STATIC CONFIG')
|
||||||
config = { ...apiConfig, ...staticConfig }
|
config = Object.assign({}, apiConfig, staticConfig)
|
||||||
} else {
|
} else {
|
||||||
config = { ...staticConfig, ...apiConfig }
|
config = Object.assign({}, staticConfig, apiConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyInstanceIdentityOption = (path) => {
|
const copyInstanceOption = ({ source, destination }) => {
|
||||||
if (get(config, path) !== undefined) {
|
if (typeof config[source] !== 'undefined') {
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({ path: destination, value: config[source] })
|
||||||
path: `instanceIdentity.${path}`,
|
|
||||||
value: get(config, path),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyInstancePrefOption = (path) => {
|
Object.keys(staticOrApiConfigDefault)
|
||||||
if (get(config, path) !== undefined) {
|
.map((k) => ({ source: k, destination: `instanceIdentity.${k}` }))
|
||||||
useInstanceStore().set({
|
.forEach(copyInstanceOption)
|
||||||
path: `prefsStorage.${path}`,
|
Object.keys(instanceDefaultConfig)
|
||||||
value: get(config, path),
|
.map((k) => ({ source: k, destination: `prefsStorage.${k}` }))
|
||||||
})
|
.forEach(copyInstanceOption)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.keys(staticOrApiConfigDefault).forEach(copyInstanceIdentityOption)
|
|
||||||
Object.keys(instanceDefaultConfig).forEach(copyInstancePrefOption)
|
|
||||||
|
|
||||||
useAuthFlowStore().setInitialStrategy(config.loginMethod)
|
useAuthFlowStore().setInitialStrategy(config.loginMethod)
|
||||||
}
|
}
|
||||||
|
|
@ -195,7 +187,7 @@ const getTOS = async ({ store }) => {
|
||||||
const res = await window.fetch('/static/terms-of-service.html')
|
const res = await window.fetch('/static/terms-of-service.html')
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const html = await res.text()
|
const html = await res.text()
|
||||||
useInstanceStore().set({ path: 'tos', value: html })
|
useInstanceStore().set({ name: 'instanceIdentity.tos', value: html })
|
||||||
} else {
|
} else {
|
||||||
throw res
|
throw res
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +202,7 @@ const getInstancePanel = async ({ store }) => {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const html = await res.text()
|
const html = await res.text()
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'instanceSpecificPanelContent',
|
path: 'instanceIdentity.instanceSpecificPanelContent',
|
||||||
value: html,
|
value: html,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -244,7 +236,7 @@ const getStickers = async ({ store }) => {
|
||||||
).sort((a, b) => {
|
).sort((a, b) => {
|
||||||
return a.meta.title.localeCompare(b.meta.title)
|
return a.meta.title.localeCompare(b.meta.title)
|
||||||
})
|
})
|
||||||
useInstanceStore().set({ path: 'stickers', value: stickers })
|
useEmojiStore().setStickers(stickers)
|
||||||
} else {
|
} else {
|
||||||
throw res
|
throw res
|
||||||
}
|
}
|
||||||
|
|
@ -266,7 +258,7 @@ const getAppSecret = async ({ store }) => {
|
||||||
const resolveStaffAccounts = ({ store, accounts }) => {
|
const resolveStaffAccounts = ({ store, accounts }) => {
|
||||||
const nicknames = accounts.map((uri) => uri.split('/').pop())
|
const nicknames = accounts.map((uri) => uri.split('/').pop())
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'staffAccounts',
|
name: 'staffAccounts',
|
||||||
value: nicknames,
|
value: nicknames,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -279,85 +271,81 @@ const getNodeInfo = async ({ store }) => {
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
const metadata = data.metadata
|
const metadata = data.metadata
|
||||||
const features = metadata.features
|
const features = metadata.features
|
||||||
|
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'localBubbleInstances',
|
path: 'name',
|
||||||
value: metadata.localBubbleInstances ?? [],
|
|
||||||
})
|
|
||||||
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'instanceIdentity.name',
|
|
||||||
value: metadata.nodeName,
|
value: metadata.nodeName,
|
||||||
})
|
})
|
||||||
|
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'registrationOpen',
|
path: 'registrationOpen',
|
||||||
value: data.openRegistrations,
|
value: data.openRegistrations,
|
||||||
})
|
})
|
||||||
useInstanceStore().set({
|
useInstanceCapabilitiesStore().set(
|
||||||
path: 'restrictedNicknames',
|
'mediaProxyAvailable',
|
||||||
value: metadata.restrictedNicknames,
|
features.includes('media_proxy'),
|
||||||
})
|
)
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'safeDM',
|
||||||
|
features.includes('safe_dm_mentions'),
|
||||||
|
)
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'shoutAvailable',
|
||||||
|
features.includes('chat'),
|
||||||
|
)
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'pleromaChatMessagesAvailable',
|
||||||
|
features.includes('pleroma_chat_messages'),
|
||||||
|
)
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'pleromaCustomEmojiReactionsAvailable',
|
||||||
|
|
||||||
useInstanceStore().set({
|
features.includes('pleroma_custom_emoji_reactions') ||
|
||||||
path: 'featureSet.mediaProxyAvailable',
|
|
||||||
value: features.includes('media_proxy'),
|
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.safeDM',
|
|
||||||
value: features.includes('safe_dm_mentions'),
|
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.shoutAvailable',
|
|
||||||
value: features.includes('chat'),
|
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.pleromaChatMessagesAvailable',
|
|
||||||
value: features.includes('pleroma_chat_messages'),
|
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.pleromaCustomEmojiReactionsAvailable',
|
|
||||||
value:
|
|
||||||
features.includes('pleroma_custom_emoji_reactions') ||
|
|
||||||
features.includes('custom_emoji_reactions'),
|
features.includes('custom_emoji_reactions'),
|
||||||
})
|
)
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'pleromaBookmarkFoldersAvailable',
|
||||||
|
features.includes('pleroma:bookmark_folders'),
|
||||||
|
)
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'gopherAvailable',
|
||||||
|
features.includes('gopher'),
|
||||||
|
)
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'pollsAvailable',
|
||||||
|
features.includes('polls'),
|
||||||
|
)
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'editingAvailable',
|
||||||
|
features.includes('editing'),
|
||||||
|
)
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'mailerEnabled',
|
||||||
|
metadata.mailerEnabled,
|
||||||
|
)
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'quotingAvailable',
|
||||||
|
features.includes('quote_posting'),
|
||||||
|
)
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'groupActorAvailable',
|
||||||
|
features.includes('pleroma:group_actors'),
|
||||||
|
)
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'blockExpiration',
|
||||||
|
features.includes('pleroma:block_expiration'),
|
||||||
|
)
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'featureSet.pleromaBookmarkFoldersAvailable',
|
path: 'localBubbleInstances',
|
||||||
value: features.includes('pleroma:bookmark_folders'),
|
value: metadata.localBubbleInstances ?? [],
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.gopherAvailable',
|
|
||||||
value: features.includes('gopher'),
|
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.pollsAvailable',
|
|
||||||
value: features.includes('polls'),
|
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.editingAvailable',
|
|
||||||
value: features.includes('editing'),
|
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.mailerEnabled',
|
|
||||||
value: metadata.mailerEnabled,
|
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.quotingAvailable',
|
|
||||||
value: features.includes('quote_posting'),
|
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.groupActorAvailable',
|
|
||||||
value: features.includes('pleroma:group_actors'),
|
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.blockExpiration',
|
|
||||||
value: features.includes('pleroma:block_expiration'),
|
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.localBubble',
|
|
||||||
value: Array.isArray(metadata.localBubbleInstances),
|
|
||||||
})
|
})
|
||||||
|
useInstanceCapabilitiesStore().set(
|
||||||
|
'localBubble',
|
||||||
|
(metadata.localBubbleInstances ?? []).length > 0,
|
||||||
|
)
|
||||||
|
|
||||||
|
useInstanceStore().set({
|
||||||
|
path: 'limits.pollLimits',
|
||||||
|
value: metadata.pollLimits,
|
||||||
|
})
|
||||||
const uploadLimits = metadata.uploadLimits
|
const uploadLimits = metadata.uploadLimits
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'limits.uploadlimit',
|
path: 'limits.uploadlimit',
|
||||||
|
|
@ -379,60 +367,53 @@ const getNodeInfo = async ({ store }) => {
|
||||||
path: 'limits.fieldsLimits',
|
path: 'limits.fieldsLimits',
|
||||||
value: metadata.fieldsLimits,
|
value: metadata.fieldsLimits,
|
||||||
})
|
})
|
||||||
|
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'limits.pollLimits',
|
path: 'restrictedNicknames',
|
||||||
value: metadata.pollLimits,
|
value: metadata.restrictedNicknames,
|
||||||
})
|
|
||||||
useInstanceStore().set({
|
|
||||||
path: 'featureSet.postFormats',
|
|
||||||
value: metadata.postFormats,
|
|
||||||
})
|
})
|
||||||
|
useInstanceCapabilitiesStore().set('postFormats', metadata.postFormats)
|
||||||
|
|
||||||
const suggestions = metadata.suggestions
|
const suggestions = metadata.suggestions
|
||||||
useInstanceStore().set({
|
useInstanceCapabilitiesStore().set(
|
||||||
path: 'featureSet.suggestionsEnabled',
|
'suggestionsEnabled',
|
||||||
value: suggestions.enabled,
|
suggestions.enabled,
|
||||||
})
|
)
|
||||||
useInstanceStore().set({
|
// this is unused, why?
|
||||||
path: 'featureSet.suggestionsWeb',
|
useInstanceCapabilitiesStore().set('suggestionsWeb', suggestions.web)
|
||||||
value: suggestions.web,
|
|
||||||
})
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
const software = data.software
|
const software = data.software
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'backendVersion',
|
name: 'backendVersion',
|
||||||
value: software.version,
|
value: software.version,
|
||||||
})
|
})
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'backendRepository',
|
name: 'backendRepository',
|
||||||
value: software.repository,
|
value: software.repository,
|
||||||
})
|
})
|
||||||
|
|
||||||
useInstanceStore().set({ path: 'private', value: metadata.private })
|
const priv = metadata.private
|
||||||
|
useInstanceStore().set({ name: 'privateMode', value: priv })
|
||||||
|
|
||||||
const frontendVersion = window.___pleromafe_commit_hash
|
const frontendVersion = window.___pleromafe_commit_hash
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'frontendVersion',
|
name: 'frontendVersion',
|
||||||
value: frontendVersion,
|
value: frontendVersion,
|
||||||
})
|
})
|
||||||
|
|
||||||
const federation = metadata.federation
|
const federation = metadata.federation
|
||||||
|
|
||||||
useInstanceStore().set({
|
useInstanceCapabilitiesStore().set(
|
||||||
path: 'featureSet.tagPolicyAvailable',
|
'tagPolicyAvailable',
|
||||||
value:
|
typeof federation.mrf_policies === 'undefined'
|
||||||
typeof federation.mrf_policies === 'undefined'
|
? false
|
||||||
? false
|
: metadata.federation.mrf_policies.includes('TagPolicy'),
|
||||||
: metadata.federation.mrf_policies.includes('TagPolicy'),
|
)
|
||||||
})
|
|
||||||
|
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'federationPolicy',
|
path: 'federationPolicy',
|
||||||
value: federation,
|
value: federation,
|
||||||
})
|
})
|
||||||
|
|
||||||
useInstanceStore().set({
|
useInstanceStore().set({
|
||||||
path: 'federating',
|
path: 'federating',
|
||||||
value:
|
value:
|
||||||
|
|
@ -471,8 +452,8 @@ const setConfig = async ({ store }) => {
|
||||||
|
|
||||||
const checkOAuthToken = async ({ store }) => {
|
const checkOAuthToken = async ({ store }) => {
|
||||||
const oauth = useOAuthStore()
|
const oauth = useOAuthStore()
|
||||||
if (oauth.userToken) {
|
if (oauth.getUserToken) {
|
||||||
return store.dispatch('loginUser', oauth.userToken)
|
return store.dispatch('loginUser', oauth.getUserToken)
|
||||||
}
|
}
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
|
|
@ -552,7 +533,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
||||||
typeof overrides.target !== 'undefined'
|
typeof overrides.target !== 'undefined'
|
||||||
? overrides.target
|
? overrides.target
|
||||||
: window.location.origin
|
: window.location.origin
|
||||||
useInstanceStore().set({ path: 'server', value: server })
|
useInstanceStore().set({ name: 'server', value: server })
|
||||||
|
|
||||||
await setConfig({ store })
|
await setConfig({ store })
|
||||||
try {
|
try {
|
||||||
|
|
@ -566,7 +547,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
||||||
return Promise.reject(e)
|
return Promise.reject(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
applyStyleConfig(useSyncConfigStore().mergedConfig)
|
applyConfig(store.state.config, i18n.global)
|
||||||
|
|
||||||
// Now we can try getting the server settings and logging in
|
// Now we can try getting the server settings and logging in
|
||||||
// Most of these are preloaded into the index.html so blocking is minimized
|
// Most of these are preloaded into the index.html so blocking is minimized
|
||||||
|
|
|
||||||
|
|
@ -33,13 +33,16 @@ 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'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
|
|
||||||
export default (store) => {
|
export default (store) => {
|
||||||
const validateAuthenticatedRoute = (to, from, next) => {
|
const validateAuthenticatedRoute = (to, from, next) => {
|
||||||
if (store.state.users.currentUser) {
|
if (store.state.users.currentUser) {
|
||||||
next()
|
next()
|
||||||
} else {
|
} else {
|
||||||
next(useInstanceStore().redirectRootNoLogin || '/main/all')
|
next(
|
||||||
|
useInstanceStore().instanceIdentity.redirectRootNoLogin || '/main/all',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,8 +53,9 @@ export default (store) => {
|
||||||
redirect: () => {
|
redirect: () => {
|
||||||
return (
|
return (
|
||||||
(store.state.users.currentUser
|
(store.state.users.currentUser
|
||||||
? useInstanceStore().redirectRootLogin
|
? useInstanceStore().instanceIdentity.redirectRootLogin
|
||||||
: useInstanceStore().redirectRootNoLogin) || '/main/all'
|
: useInstanceStore().instanceIdentity.redirectRootNoLogin) ||
|
||||||
|
'/main/all'
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -202,7 +206,7 @@ export default (store) => {
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
if (useInstanceStore().featureSet.pleromaChatMessagesAvailable) {
|
if (useInstanceCapabilitiesStore().pleromaChatMessagesAvailable) {
|
||||||
routes = routes.concat([
|
routes = routes.concat([
|
||||||
{
|
{
|
||||||
name: 'chat',
|
name: 'chat',
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import StaffPanel from '../staff_panel/staff_panel.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'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
const About = {
|
const About = {
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -17,13 +16,13 @@ const About = {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
showFeaturesPanel() {
|
showFeaturesPanel() {
|
||||||
return useInstanceStore().showFeaturesPanel
|
return useInstanceStore().instanceIdentity.showFeaturesPanel
|
||||||
},
|
},
|
||||||
showInstanceSpecificPanel() {
|
showInstanceSpecificPanel() {
|
||||||
return (
|
return (
|
||||||
useInstanceStore().showInstanceSpecificPanel &&
|
useInstanceStore().instanceIdentity.showInstanceSpecificPanel &&
|
||||||
!useSyncConfigStore().mergedConfig.hideISP &&
|
!this.$store.getters.mergedConfig.hideISP &&
|
||||||
useInstanceStore().instanceSpecificPanelContent
|
useInstanceStore().instanceIdentity.instanceSpecificPanelContent
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { mapState as mapPiniaState } from 'pinia'
|
import { mapState } from 'pinia'
|
||||||
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'
|
||||||
|
|
@ -7,9 +6,8 @@ import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
import Popover from '../popover/popover.vue'
|
import Popover from '../popover/popover.vue'
|
||||||
import ProgressButton from '../progress_button/progress_button.vue'
|
import ProgressButton from '../progress_button/progress_button.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance'
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
import { useReportsStore } from 'src/stores/reports'
|
import { useReportsStore } from 'src/stores/reports'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faEllipsisV } from '@fortawesome/free-solid-svg-icons'
|
import { faEllipsisV } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
@ -91,18 +89,15 @@ const AccountActions = {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
shouldConfirmBlock() {
|
shouldConfirmBlock() {
|
||||||
return useSyncConfigStore().mergedConfig.modalOnBlock
|
return this.$store.getters.mergedConfig.modalOnBlock
|
||||||
},
|
},
|
||||||
shouldConfirmRemoveUserFromFollowers() {
|
shouldConfirmRemoveUserFromFollowers() {
|
||||||
return useSyncConfigStore().mergedConfig.modalOnRemoveUserFromFollowers
|
return this.$store.getters.mergedConfig.modalOnRemoveUserFromFollowers
|
||||||
},
|
},
|
||||||
...mapPiniaState(useInstanceStore, (store) => ({
|
...mapState(useInstanceCapabilitiesStore, [
|
||||||
blockExpirationSupported: (store) => store.featureSet.blockExpiration,
|
'blockExpiration',
|
||||||
})),
|
'pleromaChatMessagesAvailable',
|
||||||
...mapState({
|
]),
|
||||||
pleromaChatMessagesAvailable: (state) =>
|
|
||||||
state.instance.pleromaChatMessagesAvailable,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@
|
||||||
</Popover>
|
</Popover>
|
||||||
<teleport to="#modal">
|
<teleport to="#modal">
|
||||||
<confirm-modal
|
<confirm-modal
|
||||||
v-if="showingConfirmBlock && !blockExpirationSupported"
|
v-if="showingConfirmBlock && !blockExpiration"
|
||||||
ref="blockDialog"
|
ref="blockDialog"
|
||||||
:title="$t('user_card.block_confirm_title')"
|
:title="$t('user_card.block_confirm_title')"
|
||||||
:confirm-text="$t('user_card.block_confirm_accept_button')"
|
:confirm-text="$t('user_card.block_confirm_accept_button')"
|
||||||
|
|
@ -138,7 +138,7 @@
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
</confirm-modal>
|
</confirm-modal>
|
||||||
<UserTimedFilterModal
|
<UserTimedFilterModal
|
||||||
v-if="blockExpirationSupported"
|
v-if="blockExpiration"
|
||||||
ref="timedBlockDialog"
|
ref="timedBlockDialog"
|
||||||
:is-mute="false"
|
:is-mute="false"
|
||||||
:user="user"
|
:user="user"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import localeService from '../../services/locale/locale.service.js'
|
||||||
import AnnouncementEditor from '../announcement_editor/announcement_editor.vue'
|
import AnnouncementEditor from '../announcement_editor/announcement_editor.vue'
|
||||||
import RichContent from '../rich_content/rich_content.jsx'
|
import RichContent from '../rich_content/rich_content.jsx'
|
||||||
|
|
||||||
import { useAnnouncementsStore } from 'src/stores/announcements'
|
import { useAnnouncementsStore } from 'src/stores/announcements.js'
|
||||||
|
|
||||||
const Announcement = {
|
const Announcement = {
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { mapState } from 'vuex'
|
||||||
import Announcement from '../announcement/announcement.vue'
|
import Announcement from '../announcement/announcement.vue'
|
||||||
import AnnouncementEditor from '../announcement_editor/announcement_editor.vue'
|
import AnnouncementEditor from '../announcement_editor/announcement_editor.vue'
|
||||||
|
|
||||||
import { useAnnouncementsStore } from 'src/stores/announcements'
|
import { useAnnouncementsStore } from 'src/stores/announcements.js'
|
||||||
|
|
||||||
const AnnouncementsPage = {
|
const AnnouncementsPage = {
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { mapState } from 'pinia'
|
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
import nsfwImage from '../../assets/nsfw.png'
|
import nsfwImage from '../../assets/nsfw.png'
|
||||||
|
|
@ -8,8 +7,8 @@ import StillImage from '../still-image/still-image.vue'
|
||||||
import VideoAttachment from '../video_attachment/video_attachment.vue'
|
import VideoAttachment from '../video_attachment/video_attachment.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
import { useMediaViewerStore } from 'src/stores/media_viewer'
|
import { useMediaViewerStore } from 'src/stores/media_viewer'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -59,8 +58,8 @@ const Attachment = {
|
||||||
localDescription: this.description || this.attachment.description,
|
localDescription: this.description || this.attachment.description,
|
||||||
nsfwImage:
|
nsfwImage:
|
||||||
useInstanceStore().instanceIdentity.nsfwCensorImage || nsfwImage,
|
useInstanceStore().instanceIdentity.nsfwCensorImage || nsfwImage,
|
||||||
hideNsfwLocal: useSyncConfigStore().mergedConfig.hideNsfw,
|
hideNsfwLocal: this.$store.getters.mergedConfig.hideNsfw,
|
||||||
preloadImage: useSyncConfigStore().mergedConfig.preloadImage,
|
preloadImage: this.$store.getters.mergedConfig.preloadImage,
|
||||||
loading: false,
|
loading: false,
|
||||||
img:
|
img:
|
||||||
fileTypeService.fileType(this.attachment.mimetype) === 'image' &&
|
fileTypeService.fileType(this.attachment.mimetype) === 'image' &&
|
||||||
|
|
@ -93,6 +92,9 @@ const Attachment = {
|
||||||
usePlaceholder() {
|
usePlaceholder() {
|
||||||
return this.size === 'hide'
|
return this.size === 'hide'
|
||||||
},
|
},
|
||||||
|
useContainFit() {
|
||||||
|
return this.$store.getters.mergedConfig.useContainFit
|
||||||
|
},
|
||||||
placeholderName() {
|
placeholderName() {
|
||||||
if (this.attachment.description === '' || !this.attachment.description) {
|
if (this.attachment.description === '' || !this.attachment.description) {
|
||||||
return this.type.toUpperCase()
|
return this.type.toUpperCase()
|
||||||
|
|
@ -106,7 +108,9 @@ const Attachment = {
|
||||||
return 'file'
|
return 'file'
|
||||||
},
|
},
|
||||||
referrerpolicy() {
|
referrerpolicy() {
|
||||||
return useInstanceStore().mediaProxyAvailable ? '' : 'no-referrer'
|
return useInstanceCapabilitiesStore().mediaProxyAvailable
|
||||||
|
? ''
|
||||||
|
: 'no-referrer'
|
||||||
},
|
},
|
||||||
type() {
|
type() {
|
||||||
return fileTypeService.fileType(this.attachment.mimetype)
|
return fileTypeService.fileType(this.attachment.mimetype)
|
||||||
|
|
@ -125,7 +129,7 @@ const Attachment = {
|
||||||
modalTypes = ['image', 'video', 'audio', 'flash']
|
modalTypes = ['image', 'video', 'audio', 'flash']
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
modalTypes = this.playVideosInModal
|
modalTypes = this.mergedConfig.playVideosInModal
|
||||||
? ['image', 'video', 'flash']
|
? ['image', 'video', 'flash']
|
||||||
: ['image']
|
: ['image']
|
||||||
break
|
break
|
||||||
|
|
@ -135,11 +139,7 @@ const Attachment = {
|
||||||
videoTag() {
|
videoTag() {
|
||||||
return this.useModal ? 'button' : 'span'
|
return this.useModal ? 'button' : 'span'
|
||||||
},
|
},
|
||||||
...mapState(useSyncConfigStore, {
|
...mapGetters(['mergedConfig']),
|
||||||
useContainFit: (state) => state.mergedConfig.useContainFit,
|
|
||||||
playVideosInModal: (state) => state.mergedConfig.playVideosInModal,
|
|
||||||
useOneClickNsfw: (state) => state.mergedConfig.useOneClickNsfw,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'attachment.description'(newVal) {
|
'attachment.description'(newVal) {
|
||||||
|
|
@ -190,9 +190,9 @@ const Attachment = {
|
||||||
},
|
},
|
||||||
toggleHidden(event) {
|
toggleHidden(event) {
|
||||||
if (
|
if (
|
||||||
this.useOneClickNsfw &&
|
this.mergedConfig.useOneClickNsfw &&
|
||||||
!this.showHidden &&
|
!this.showHidden &&
|
||||||
(this.type !== 'video' || this.playVideosInModal)
|
(this.type !== 'video' || this.mergedConfig.playVideosInModal)
|
||||||
) {
|
) {
|
||||||
this.openModal(event)
|
this.openModal(event)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import LoginForm from '../login_form/login_form.vue'
|
||||||
import MFARecoveryForm from '../mfa_form/recovery_form.vue'
|
import MFARecoveryForm from '../mfa_form/recovery_form.vue'
|
||||||
import MFATOTPForm from '../mfa_form/totp_form.vue'
|
import MFATOTPForm from '../mfa_form/totp_form.vue'
|
||||||
|
|
||||||
import { useAuthFlowStore } from 'src/stores/auth_flow'
|
import { useAuthFlowStore } from 'src/stores/auth_flow.js'
|
||||||
|
|
||||||
const AuthForm = {
|
const AuthForm = {
|
||||||
name: 'AuthForm',
|
name: 'AuthForm',
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'pinia'
|
||||||
|
|
||||||
|
import UserTimedFilterModal from 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
|
||||||
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
|
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
|
||||||
|
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
|
|
||||||
const BlockCard = {
|
const BlockCard = {
|
||||||
props: ['userId'],
|
props: ['userId'],
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -24,19 +27,18 @@ const BlockCard = {
|
||||||
new Date(this.user.mute_expires_at).toLocaleString(),
|
new Date(this.user.mute_expires_at).toLocaleString(),
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
...mapState({
|
...mapState(useInstanceCapabilitiesStore, ['blockExpiration']),
|
||||||
blockExpirationSupported: (state) => state.instance.blockExpiration,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
BasicUserCard,
|
BasicUserCard,
|
||||||
|
UserTimedFilterModal,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
unblockUser() {
|
unblockUser() {
|
||||||
this.$store.dispatch('unblockUser', this.user.id)
|
this.$store.dispatch('unblockUser', this.user.id)
|
||||||
},
|
},
|
||||||
blockUser() {
|
blockUser() {
|
||||||
if (this.blockExpirationSupported) {
|
if (this.blockExpiration) {
|
||||||
this.$refs.timedBlockDialog.optionallyPrompt()
|
this.$refs.timedBlockDialog.optionallyPrompt()
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('blockUser', { id: this.user.id })
|
this.$store.dispatch('blockUser', { id: this.user.id })
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import apiService from '../../services/api/api.service'
|
import apiService from '../../services/api/api.service'
|
||||||
import EmojiPicker from '../emoji_picker/emoji_picker.vue'
|
import EmojiPicker from '../emoji_picker/emoji_picker.vue'
|
||||||
|
|
||||||
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
|
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
|
||||||
const BookmarkFolderEdit = {
|
const BookmarkFolderEdit = {
|
||||||
data() {
|
data() {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import BookmarkFolderCard from '../bookmark_folder_card/bookmark_folder_card.vue'
|
import BookmarkFolderCard from '../bookmark_folder_card/bookmark_folder_card.vue'
|
||||||
|
|
||||||
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
|
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
|
||||||
|
|
||||||
const BookmarkFolders = {
|
const BookmarkFolders = {
|
||||||
data() {
|
data() {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { mapState } from 'pinia'
|
||||||
import { getBookmarkFolderEntries } from 'src/components/navigation/filter.js'
|
import { getBookmarkFolderEntries } 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 { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
|
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
|
||||||
|
|
||||||
export const BookmarkFoldersMenuContent = {
|
export const BookmarkFoldersMenuContent = {
|
||||||
props: ['showPin'],
|
props: ['showPin'],
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import {
|
||||||
} from './chat_layout_utils.js'
|
} from './chat_layout_utils.js'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faChevronDown, faChevronLeft } from '@fortawesome/free-solid-svg-icons'
|
import { faChevronDown, faChevronLeft } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
@ -110,11 +109,11 @@ const Chat = {
|
||||||
'currentChat',
|
'currentChat',
|
||||||
'currentChatMessageService',
|
'currentChatMessageService',
|
||||||
'findOpenedChatByRecipientId',
|
'findOpenedChatByRecipientId',
|
||||||
|
'mergedConfig',
|
||||||
]),
|
]),
|
||||||
...mapPiniaState(useInterfaceStore, {
|
...mapPiniaState(useInterfaceStore, {
|
||||||
mobileLayout: (store) => store.layoutType === 'mobile',
|
mobileLayout: (store) => store.layoutType === 'mobile',
|
||||||
}),
|
}),
|
||||||
...mapPiniaState(useSyncConfigStore, ['mergedConfig']),
|
|
||||||
...mapState({
|
...mapState({
|
||||||
backendInteractor: (state) => state.api.backendInteractor,
|
backendInteractor: (state) => state.api.backendInteractor,
|
||||||
mastoUserSocketStatus: (state) => state.api.mastoUserSocketStatus,
|
mastoUserSocketStatus: (state) => state.api.mastoUserSocketStatus,
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ import Popover from '../popover/popover.vue'
|
||||||
import StatusContent from '../status_content/status_content.vue'
|
import StatusContent from '../status_content/status_content.vue'
|
||||||
import UserAvatar from '../user_avatar/user_avatar.vue'
|
import UserAvatar from '../user_avatar/user_avatar.vue'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faEllipsisH, faTimes } from '@fortawesome/free-solid-svg-icons'
|
import { faEllipsisH, faTimes } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
@ -76,7 +76,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) {
|
||||||
|
|
@ -85,8 +85,7 @@ const ChatMessage = {
|
||||||
return { left: 50 }
|
return { left: 50 }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
...mapGetters(['findUser']),
|
...mapGetters(['mergedConfig', 'findUser']),
|
||||||
...mapPiniaState(useSyncConfigStore, ['mergedConfig']),
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,7 @@ import QuickViewSettings from '../quick_view_settings/quick_view_settings.vue'
|
||||||
import Status from '../status/status.vue'
|
import Status from '../status/status.vue'
|
||||||
import ThreadTree from '../thread_tree/thread_tree.vue'
|
import ThreadTree from '../thread_tree/thread_tree.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -79,12 +77,37 @@ const conversation = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
maxDepthToShowByDefault() {
|
||||||
|
// maxDepthInThread = max number of depths that is *visible*
|
||||||
|
// since our depth starts with 0 and "showing" means "showing children"
|
||||||
|
// there is a -2 here
|
||||||
|
const maxDepth = this.$store.getters.mergedConfig.maxDepthInThread - 2
|
||||||
|
return maxDepth >= 1 ? maxDepth : 1
|
||||||
|
},
|
||||||
|
streamingEnabled() {
|
||||||
|
return (
|
||||||
|
this.mergedConfig.useStreamingApi &&
|
||||||
|
this.mastoUserSocketStatus === WSConnectionStatus.JOINED
|
||||||
|
)
|
||||||
|
},
|
||||||
|
displayStyle() {
|
||||||
|
return this.$store.getters.mergedConfig.conversationDisplay
|
||||||
|
},
|
||||||
isTreeView() {
|
isTreeView() {
|
||||||
return !this.isLinearView
|
return !this.isLinearView
|
||||||
},
|
},
|
||||||
|
treeViewIsSimple() {
|
||||||
|
return !this.$store.getters.mergedConfig.conversationTreeAdvanced
|
||||||
|
},
|
||||||
isLinearView() {
|
isLinearView() {
|
||||||
return this.displayStyle === 'linear'
|
return this.displayStyle === 'linear'
|
||||||
},
|
},
|
||||||
|
shouldFadeAncestors() {
|
||||||
|
return this.$store.getters.mergedConfig.conversationTreeFadeAncestors
|
||||||
|
},
|
||||||
|
otherRepliesButtonPosition() {
|
||||||
|
return this.$store.getters.mergedConfig.conversationOtherRepliesButton
|
||||||
|
},
|
||||||
showOtherRepliesButtonBelowStatus() {
|
showOtherRepliesButtonBelowStatus() {
|
||||||
return this.otherRepliesButtonPosition === 'below'
|
return this.otherRepliesButtonPosition === 'below'
|
||||||
},
|
},
|
||||||
|
|
@ -369,28 +392,7 @@ const conversation = {
|
||||||
maybeHighlight() {
|
maybeHighlight() {
|
||||||
return this.isExpanded ? this.highlight : null
|
return this.isExpanded ? this.highlight : null
|
||||||
},
|
},
|
||||||
...mapPiniaState(useSyncConfigStore, ['mergedConfig']),
|
...mapGetters(['mergedConfig']),
|
||||||
...mapPiniaState(useSyncConfigStore, {
|
|
||||||
maxDepthToShowByDefault: (store) => {
|
|
||||||
// maxDepthInThread = max number of depths that is *visible*
|
|
||||||
// since our depth starts with 0 and "showing" means "showing children"
|
|
||||||
// there is a -2 here
|
|
||||||
const maxDepth = store.mergedConfig.maxDepthInThread - 2
|
|
||||||
return maxDepth >= 1 ? maxDepth : 1
|
|
||||||
},
|
|
||||||
streamingEnabled: (store) => {
|
|
||||||
return (
|
|
||||||
store.mergedConfig.useStreamingApi &&
|
|
||||||
this.mastoUserSocketStatus === WSConnectionStatus.JOINED
|
|
||||||
)
|
|
||||||
},
|
|
||||||
displayStyle: (store) => store.mergedConfig.conversationDisplay,
|
|
||||||
treeViewIsSimple: (store) => !store.mergedConfig.conversationTreeAdvanced,
|
|
||||||
shouldFadeAncestors: (store) =>
|
|
||||||
store.mergedConfig.conversationTreeFadeAncestors,
|
|
||||||
otherRepliesButtonPosition: (store) =>
|
|
||||||
store.mergedConfig.conversationOtherRepliesButton,
|
|
||||||
}),
|
|
||||||
...mapState({
|
...mapState({
|
||||||
mastoUserSocketStatus: (state) => state.api.mastoUserSocketStatus,
|
mastoUserSocketStatus: (state) => state.api.mastoUserSocketStatus,
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
import SearchBar from 'components/search_bar/search_bar.vue'
|
import SearchBar from 'components/search_bar/search_bar.vue'
|
||||||
import { mapState } from 'pinia'
|
import { mapActions, mapState } from 'pinia'
|
||||||
|
|
||||||
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -35,14 +34,6 @@ library.add(
|
||||||
faCog,
|
faCog,
|
||||||
faInfoCircle,
|
faInfoCircle,
|
||||||
)
|
)
|
||||||
const supportsMask =
|
|
||||||
window.CSS &&
|
|
||||||
window.CSS.supports &&
|
|
||||||
(window.CSS.supports('mask-size', 'contain') ||
|
|
||||||
window.CSS.supports('-webkit-mask-size', 'contain') ||
|
|
||||||
window.CSS.supports('-moz-mask-size', 'contain') ||
|
|
||||||
window.CSS.supports('-ms-mask-size', 'contain') ||
|
|
||||||
window.CSS.supports('-o-mask-size', 'contain'))
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -51,21 +42,32 @@ export default {
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
searchBarHidden: true,
|
searchBarHidden: true,
|
||||||
|
supportsMask:
|
||||||
|
window.CSS &&
|
||||||
|
window.CSS.supports &&
|
||||||
|
(window.CSS.supports('mask-size', 'contain') ||
|
||||||
|
window.CSS.supports('-webkit-mask-size', 'contain') ||
|
||||||
|
window.CSS.supports('-moz-mask-size', 'contain') ||
|
||||||
|
window.CSS.supports('-ms-mask-size', 'contain') ||
|
||||||
|
window.CSS.supports('-o-mask-size', 'contain')),
|
||||||
showingConfirmLogout: false,
|
showingConfirmLogout: false,
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
|
enableMask() {
|
||||||
|
return this.supportsMask && this.logoMask
|
||||||
|
},
|
||||||
logoStyle() {
|
logoStyle() {
|
||||||
return {
|
return {
|
||||||
visibility: this.logoMask ? 'hidden' : 'visible',
|
visibility: this.enableMask ? 'hidden' : 'visible',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
logoMaskStyle() {
|
logoMaskStyle() {
|
||||||
return this.logoMask
|
return this.enableMask
|
||||||
? {
|
? {
|
||||||
'mask-image': `url(${this.logo})`,
|
'mask-image': `url(${this.logo})`,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
'background-color': this.logoMask ? '' : 'transparent',
|
'background-color': this.enableMask ? '' : 'transparent',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
logoBgStyle() {
|
logoBgStyle() {
|
||||||
|
|
@ -74,28 +76,28 @@ export default {
|
||||||
margin: `${this.logoMargin} 0`,
|
margin: `${this.logoMargin} 0`,
|
||||||
opacity: this.searchBarHidden ? 1 : 0,
|
opacity: this.searchBarHidden ? 1 : 0,
|
||||||
},
|
},
|
||||||
this.logoMask
|
this.enableMask
|
||||||
? {}
|
? {}
|
||||||
: {
|
: {
|
||||||
'background-color': this.logoMask ? '' : 'transparent',
|
'background-color': this.enableMask ? '' : 'transparent',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
...mapState(useInstanceStore, ['privateMode']),
|
||||||
|
...mapState(useInstanceStore, {
|
||||||
|
logoMask: (store) => store.instanceIdentity.logoMask,
|
||||||
|
logo: (store) => store.instanceIdentity.logo,
|
||||||
|
logoLeft: (store) => store.instanceIdentity.logoLeft,
|
||||||
|
logoMargin: (store) => store.instanceIdentity.logoMargin,
|
||||||
|
sitename: (store) => store.instanceIdentity.name,
|
||||||
|
hideSitename: (store) => store.instanceIdentity.hideSitename,
|
||||||
|
}),
|
||||||
currentUser() {
|
currentUser() {
|
||||||
return this.$store.state.users.currentUser
|
return this.$store.state.users.currentUser
|
||||||
},
|
},
|
||||||
shouldConfirmLogout() {
|
shouldConfirmLogout() {
|
||||||
return useSyncConfigStore().mergedConfig.modalOnLogout
|
return this.$store.getters.mergedConfig.modalOnLogout
|
||||||
},
|
},
|
||||||
...mapState(useInstanceStore, {
|
|
||||||
logo: (state) => state.instanceIdentity.logo,
|
|
||||||
logoMask: (state) => supportsMask && state.instanceIdentity.logoMask,
|
|
||||||
logoLeft: (state) => state.instanceIdentity.logoLeft,
|
|
||||||
logoMargin: (state) => state.instanceIdentity.logoMargin,
|
|
||||||
sitename: (state) => state.instanceIdentity.name,
|
|
||||||
privateMode: (state) => state.private,
|
|
||||||
hideSitename: (state) => state.instanceIdentity.hideSitename,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
scrollToTop() {
|
scrollToTop() {
|
||||||
|
|
@ -122,11 +124,6 @@ export default {
|
||||||
onSearchBarToggled(hidden) {
|
onSearchBarToggled(hidden) {
|
||||||
this.searchBarHidden = hidden
|
this.searchBarHidden = hidden
|
||||||
},
|
},
|
||||||
openSettingsModal() {
|
...mapActions(useInterfaceStore, ['openSettingsModal']),
|
||||||
useInterfaceStore().openSettingsModal('user')
|
|
||||||
},
|
|
||||||
openAdminModal() {
|
|
||||||
useInterfaceStore().openSettingsModal('admin')
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
<button
|
<button
|
||||||
class="button-unstyled nav-icon"
|
class="button-unstyled nav-icon"
|
||||||
:title="$t('nav.preferences')"
|
:title="$t('nav.preferences')"
|
||||||
@click.stop="openSettingsModal"
|
@click.stop="openSettingsModal('user')"
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
class="button-unstyled nav-icon"
|
class="button-unstyled nav-icon"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
:title="$t('nav.administration')"
|
:title="$t('nav.administration')"
|
||||||
@click.stop="openAdminModal"
|
@click.stop="openSettingsModal('admin')"
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import get from 'lodash/get'
|
||||||
import EditStatusForm from '../edit_status_form/edit_status_form.vue'
|
import EditStatusForm from '../edit_status_form/edit_status_form.vue'
|
||||||
import Modal from '../modal/modal.vue'
|
import Modal from '../modal/modal.vue'
|
||||||
|
|
||||||
import { useEditStatusStore } from 'src/stores/editStatus'
|
import { useEditStatusStore } from 'src/stores/editStatus.js'
|
||||||
|
|
||||||
const EditStatusModal = {
|
const EditStatusModal = {
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,12 @@ 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 { 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'
|
||||||
|
|
||||||
import { useEmojiStore } from 'src/stores/emoji.js'
|
import { useEmojiStore } from 'src/stores/emoji.js'
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { ensureFinalFallback } from 'src/i18n/languages.js'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -342,7 +340,7 @@ const EmojiPicker = {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.updateEmojiSize()
|
this.updateEmojiSize()
|
||||||
})
|
})
|
||||||
return useSyncConfigStore().mergedConfig.fontSize
|
return this.$store.getters.mergedConfig.fontSize
|
||||||
},
|
},
|
||||||
emojiHeight() {
|
emojiHeight() {
|
||||||
return this.emojiSize
|
return this.emojiSize
|
||||||
|
|
@ -354,8 +352,8 @@ const EmojiPicker = {
|
||||||
return this.showingStickers ? '' : this.activeGroup
|
return this.showingStickers ? '' : this.activeGroup
|
||||||
},
|
},
|
||||||
stickersAvailable() {
|
stickersAvailable() {
|
||||||
if (useInstanceStore().stickers) {
|
if (useEmojiStore().stickers) {
|
||||||
return useInstanceStore().stickers.length > 0
|
return useEmojiStore().stickers.length > 0
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
},
|
},
|
||||||
|
|
@ -386,7 +384,7 @@ const EmojiPicker = {
|
||||||
.concat(this.unicodeEmojiGroups)
|
.concat(this.unicodeEmojiGroups)
|
||||||
},
|
},
|
||||||
stickerPickerEnabled() {
|
stickerPickerEnabled() {
|
||||||
return (useInstanceStore().stickers || []).length !== 0
|
return (useEmojiStore().stickers || []).length !== 0
|
||||||
},
|
},
|
||||||
debouncedHandleKeywordChange() {
|
debouncedHandleKeywordChange() {
|
||||||
return debounce(() => {
|
return debounce(() => {
|
||||||
|
|
@ -407,7 +405,7 @@ const EmojiPicker = {
|
||||||
},
|
},
|
||||||
languages() {
|
languages() {
|
||||||
return ensureFinalFallback(
|
return ensureFinalFallback(
|
||||||
useSyncConfigStore().mergedConfig.interfaceLanguage,
|
this.$store.getters.mergedConfig.interfaceLanguage,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
maybeLocalizedEmojiName() {
|
maybeLocalizedEmojiName() {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import { mapState } from 'pinia'
|
import { mapState as mapPiniaState } from 'pinia'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
import { useAnnouncementsStore } from 'src/stores/announcements.js'
|
import { useAnnouncementsStore } from 'src/stores/announcements.js'
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -52,11 +51,10 @@ const ExtraNotifications = {
|
||||||
currentUser() {
|
currentUser() {
|
||||||
return this.$store.state.users.currentUser
|
return this.$store.state.users.currentUser
|
||||||
},
|
},
|
||||||
...mapGetters(['unreadChatCount', 'followRequestCount']),
|
...mapGetters(['unreadChatCount', 'followRequestCount', 'mergedConfig']),
|
||||||
...mapState(useAnnouncementsStore, {
|
...mapPiniaState(useAnnouncementsStore, {
|
||||||
unreadAnnouncementCount: 'unreadAnnouncementCount',
|
unreadAnnouncementCount: 'unreadAnnouncementCount',
|
||||||
}),
|
}),
|
||||||
...mapState(useSyncConfigStore, ['mergedConfig']),
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openNotificationSettings() {
|
openNotificationSettings() {
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,24 @@
|
||||||
|
import { mapState } from 'pinia'
|
||||||
|
|
||||||
import fileSizeFormatService from '../../services/file_size_format/file_size_format.js'
|
import fileSizeFormatService from '../../services/file_size_format/file_size_format.js'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
|
|
||||||
const FeaturesPanel = {
|
const FeaturesPanel = {
|
||||||
computed: {
|
computed: {
|
||||||
shout: function () {
|
...mapState(useInstanceCapabilitiesStore, [
|
||||||
return useInstanceStore().shoutAvailable
|
'shoutAvailable',
|
||||||
},
|
'pleromaChatMessagesAvailable',
|
||||||
pleromaChatMessages: function () {
|
'gopherAvailable',
|
||||||
return useInstanceStore().pleromaChatMessagesAvailable
|
'suggestionsEnabled',
|
||||||
},
|
'mediaProxyAvailable',
|
||||||
gopher: function () {
|
]),
|
||||||
return useInstanceStore().gopherAvailable
|
...mapState(useInstanceStore, {
|
||||||
},
|
textlimit: (store) => store.limits.textlimit,
|
||||||
whoToFollow: function () {
|
uploadlimit: (store) =>
|
||||||
return useInstanceStore().suggestionsEnabled
|
fileSizeFormatService.fileSizeFormat(store.limits.uploadlimit),
|
||||||
},
|
}),
|
||||||
mediaProxy: function () {
|
|
||||||
return useInstanceStore().mediaProxyAvailable
|
|
||||||
},
|
|
||||||
minimalScopesMode: function () {
|
|
||||||
return useInstanceStore().minimalScopesMode
|
|
||||||
},
|
|
||||||
textlimit: function () {
|
|
||||||
return useInstanceStore().textlimit
|
|
||||||
},
|
|
||||||
uploadlimit: function () {
|
|
||||||
return fileSizeFormatService.fileSizeFormat(
|
|
||||||
useInstanceStore().uploadlimit,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,19 +8,19 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-if="shout">
|
<li v-if="shoutAvailable">
|
||||||
{{ $t('features_panel.shout') }}
|
{{ $t('features_panel.shout') }}
|
||||||
</li>
|
</li>
|
||||||
<li v-if="pleromaChatMessages">
|
<li v-if="pleromaChatMessagesAvailable">
|
||||||
{{ $t('features_panel.pleroma_chat_messages') }}
|
{{ $t('features_panel.pleroma_chat_messages') }}
|
||||||
</li>
|
</li>
|
||||||
<li v-if="gopher">
|
<li v-if="gopherAvailable">
|
||||||
{{ $t('features_panel.gopher') }}
|
{{ $t('features_panel.gopher') }}
|
||||||
</li>
|
</li>
|
||||||
<li v-if="whoToFollow">
|
<li v-if="suggestionsEnabled">
|
||||||
{{ $t('features_panel.who_to_follow') }}
|
{{ $t('features_panel.who_to_follow') }}
|
||||||
</li>
|
</li>
|
||||||
<li v-if="mediaProxy">
|
<li v-if="mediaProxyAvailable">
|
||||||
{{ $t('features_panel.media_proxy') }}
|
{{ $t('features_panel.media_proxy') }}
|
||||||
</li>
|
</li>
|
||||||
<li>{{ $t('features_panel.scope_options') }}</li>
|
<li>{{ $t('features_panel.scope_options') }}</li>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import Checkbox from 'src/components/checkbox/checkbox.vue'
|
||||||
import Popover from 'src/components/popover/popover.vue'
|
import Popover from 'src/components/popover/popover.vue'
|
||||||
import Select from '../select/select.vue'
|
import Select from '../select/select.vue'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { set, sumBy } from 'lodash'
|
||||||
|
|
||||||
import Attachment from '../attachment/attachment.vue'
|
import Attachment from '../attachment/attachment.vue'
|
||||||
|
|
||||||
import { useMediaViewerStore } from 'src/stores/media_viewer'
|
import { useMediaViewerStore } from 'src/stores/media_viewer.js'
|
||||||
|
|
||||||
const Gallery = {
|
const Gallery = {
|
||||||
props: [
|
props: [
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faTimes } from '@fortawesome/free-solid-svg-icons'
|
import { faTimes } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
const InstanceSpecificPanel = {
|
const InstanceSpecificPanel = {
|
||||||
computed: {
|
computed: {
|
||||||
instanceSpecificPanelContent() {
|
instanceSpecificPanelContent() {
|
||||||
return useInstanceStore().instanceSpecificPanelContent
|
return useInstanceStore().instanceIdentity.instanceSpecificPanelContent
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import ListsCard from '../lists_card/lists_card.vue'
|
import ListsCard from '../lists_card/lists_card.vue'
|
||||||
|
|
||||||
import { useListsStore } from 'src/stores/lists'
|
import { useListsStore } from 'src/stores/lists.js'
|
||||||
|
|
||||||
const Lists = {
|
const Lists = {
|
||||||
data() {
|
data() {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ import BasicUserCard from '../basic_user_card/basic_user_card.vue'
|
||||||
import ListsUserSearch from '../lists_user_search/lists_user_search.vue'
|
import ListsUserSearch from '../lists_user_search/lists_user_search.vue'
|
||||||
import UserAvatar from '../user_avatar/user_avatar.vue'
|
import UserAvatar from '../user_avatar/user_avatar.vue'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import { useListsStore } from 'src/stores/lists'
|
import { useListsStore } from 'src/stores/lists.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faChevronLeft, faSearch } from '@fortawesome/free-solid-svg-icons'
|
import { faChevronLeft, faSearch } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ 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 { useListsStore } from 'src/stores/lists'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useListsStore } from 'src/stores/lists.js'
|
||||||
|
|
||||||
export const ListsMenuContent = {
|
export const ListsMenuContent = {
|
||||||
props: ['showPin'],
|
props: ['showPin'],
|
||||||
|
|
@ -17,8 +18,6 @@ export const ListsMenuContent = {
|
||||||
}),
|
}),
|
||||||
...mapState({
|
...mapState({
|
||||||
currentUser: (state) => state.users.currentUser,
|
currentUser: (state) => state.users.currentUser,
|
||||||
privateMode: (state) => state.instance.private,
|
|
||||||
federating: (state) => state.instance.federating,
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Timeline from '../timeline/timeline.vue'
|
import Timeline from '../timeline/timeline.vue'
|
||||||
|
|
||||||
import { useListsStore } from 'src/stores/lists'
|
import { useListsStore } from 'src/stores/lists.js'
|
||||||
|
|
||||||
const ListsTimeline = {
|
const ListsTimeline = {
|
||||||
data() {
|
data() {
|
||||||
|
|
|
||||||
|
|
@ -18,25 +18,19 @@ const LoginForm = {
|
||||||
error: false,
|
error: false,
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
isPasswordAuth() {
|
|
||||||
return this.requiredPassword
|
|
||||||
},
|
|
||||||
isTokenAuth() {
|
|
||||||
return this.requiredToken
|
|
||||||
},
|
|
||||||
...mapStores(useOAuthStore),
|
|
||||||
...mapState({
|
...mapState({
|
||||||
loggingIn: (state) => state.users.loggingIn,
|
loggingIn: (state) => state.users.loggingIn,
|
||||||
}),
|
}),
|
||||||
...mapPiniaState(useAuthFlowStore, [
|
...mapPiniaState(useOAuthStore, ['clientId', 'clientSecret']),
|
||||||
'requiredPassword',
|
...mapPiniaState(useInstanceStore, ['server', 'registrationOpen']),
|
||||||
'requiredToken',
|
...mapPiniaState(useAuthFlowStore, {
|
||||||
'requiredMFA',
|
isTokenAuth: (store) => store.requiredToken,
|
||||||
]),
|
isPasswordAuth: (store) => !store.requiredToken,
|
||||||
...mapPiniaState(useInstanceStore, ['registrationOpen', 'server']),
|
}),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useAuthFlowStore, ['requireMFA', 'login']),
|
...mapActions(useAuthFlowStore, ['requireMFA', 'login']),
|
||||||
|
...mapActions(useOAuthStore, ['ensureAppToken']),
|
||||||
submit() {
|
submit() {
|
||||||
this.isTokenAuth ? this.submitToken() : this.submitPassword()
|
this.isTokenAuth ? this.submitToken() : this.submitPassword()
|
||||||
},
|
},
|
||||||
|
|
@ -48,10 +42,10 @@ const LoginForm = {
|
||||||
|
|
||||||
// NOTE: we do not really need the app token, but obtaining a token and
|
// NOTE: we do not really need the app token, but obtaining a token and
|
||||||
// calling verify_credentials is the only way to ensure the app still works.
|
// calling verify_credentials is the only way to ensure the app still works.
|
||||||
this.oauthStore.ensureAppToken().then(() => {
|
this.ensureAppToken().then(() => {
|
||||||
const app = {
|
const app = {
|
||||||
clientId: this.oauthStore.clientId,
|
clientId: this.clientId,
|
||||||
clientSecret: this.oauthStore.clientSecret,
|
clientSecret: this.clientSecret,
|
||||||
}
|
}
|
||||||
oauthApi.login({ ...app, ...data })
|
oauthApi.login({ ...app, ...data })
|
||||||
})
|
})
|
||||||
|
|
@ -61,10 +55,10 @@ const LoginForm = {
|
||||||
|
|
||||||
// NOTE: we do not really need the app token, but obtaining a token and
|
// NOTE: we do not really need the app token, but obtaining a token and
|
||||||
// calling verify_credentials is the only way to ensure the app still works.
|
// calling verify_credentials is the only way to ensure the app still works.
|
||||||
this.oauthStore.ensureAppToken().then(() => {
|
this.ensureAppToken().then(() => {
|
||||||
const app = {
|
const app = {
|
||||||
clientId: this.oauthStore.clientId,
|
clientId: this.clientId,
|
||||||
clientSecret: this.oauthStore.clientSecret,
|
clientSecret: this.clientSecret,
|
||||||
}
|
}
|
||||||
|
|
||||||
oauthApi
|
oauthApi
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import StillImage from '../still-image/still-image.vue'
|
||||||
import SwipeClick from '../swipe_click/swipe_click.vue'
|
import SwipeClick from '../swipe_click/swipe_click.vue'
|
||||||
import VideoAttachment from '../video_attachment/video_attachment.vue'
|
import VideoAttachment from '../video_attachment/video_attachment.vue'
|
||||||
|
|
||||||
import { useMediaViewerStore } from 'src/stores/media_viewer'
|
import { useMediaViewerStore } from 'src/stores/media_viewer.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
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 { useSyncConfigStore } from 'src/stores/sync_config.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'
|
||||||
|
|
@ -33,7 +33,7 @@ const mediaUpload = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip if image compression is disabled
|
// Skip if image compression is disabled
|
||||||
if (!useSyncConfigStore().mergedConfig.imageCompression) {
|
if (!this.$store.getters.mergedConfig.imageCompression) {
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +78,7 @@ const mediaUpload = {
|
||||||
|
|
||||||
// Convert to WebP if supported and alwaysUseJpeg is false, otherwise JPEG
|
// Convert to WebP if supported and alwaysUseJpeg is false, otherwise JPEG
|
||||||
const type =
|
const type =
|
||||||
!useSyncConfigStore().mergedConfig.alwaysUseJpeg && supportsWebP
|
!this.$store.getters.mergedConfig.alwaysUseJpeg && supportsWebP
|
||||||
? 'image/webp'
|
? 'image/webp'
|
||||||
: 'image/jpeg'
|
: 'image/jpeg'
|
||||||
const extension = type === 'image/webp' ? '.webp' : '.jpg'
|
const extension = type === 'image/webp' ? '.webp' : '.jpg'
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { mapState as mapPiniaState } from 'pinia'
|
|
||||||
import { defineAsyncComponent } from 'vue'
|
import { defineAsyncComponent } from 'vue'
|
||||||
import { mapState } from 'vuex'
|
import { mapGetters, mapState } from 'vuex'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
highlightClass,
|
highlightClass,
|
||||||
|
|
@ -9,8 +8,6 @@ import {
|
||||||
import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
|
import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
|
||||||
import UserAvatar from '../user_avatar/user_avatar.vue'
|
import UserAvatar from '../user_avatar/user_avatar.vue'
|
||||||
|
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.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 { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
|
@ -101,10 +98,7 @@ const MentionLink = {
|
||||||
return this.user && this.user.screen_name_ui
|
return this.user && this.user.screen_name_ui
|
||||||
},
|
},
|
||||||
highlight() {
|
highlight() {
|
||||||
return (
|
return this.user && this.mergedConfig.highlight[this.user.screen_name]
|
||||||
this.user &&
|
|
||||||
useSyncConfigStore().mergedConfig.highlight[this.user.screen_name]
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
highlightType() {
|
highlightType() {
|
||||||
return this.highlight && '-' + this.highlight.type
|
return this.highlight && '-' + this.highlight.type
|
||||||
|
|
@ -137,7 +131,7 @@ const MentionLink = {
|
||||||
return this.userName !== this.userNameFull
|
return this.userName !== this.userNameFull
|
||||||
},
|
},
|
||||||
shouldShowFullUserName() {
|
shouldShowFullUserName() {
|
||||||
const conf = useSyncConfigStore().mergedConfig.mentionLinkDisplay
|
const conf = this.mergedConfig.mentionLinkDisplay
|
||||||
if (conf === 'short') {
|
if (conf === 'short') {
|
||||||
return false
|
return false
|
||||||
} else if (conf === 'full') {
|
} else if (conf === 'full') {
|
||||||
|
|
@ -147,16 +141,25 @@ const MentionLink = {
|
||||||
return this.isRemote
|
return this.isRemote
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
shouldShowTooltip() {
|
||||||
|
return this.mergedConfig.mentionLinkShowTooltip
|
||||||
|
},
|
||||||
|
shouldShowAvatar() {
|
||||||
|
return this.mergedConfig.mentionLinkShowAvatar
|
||||||
|
},
|
||||||
|
shouldShowYous() {
|
||||||
|
return this.mergedConfig.mentionLinkShowYous
|
||||||
|
},
|
||||||
|
shouldBoldenYou() {
|
||||||
|
return this.mergedConfig.mentionLinkBoldenYou
|
||||||
|
},
|
||||||
|
shouldFadeDomain() {
|
||||||
|
return this.mergedConfig.mentionLinkFadeDomain
|
||||||
|
},
|
||||||
|
...mapGetters(['mergedConfig']),
|
||||||
...mapState({
|
...mapState({
|
||||||
currentUser: (state) => state.users.currentUser,
|
currentUser: (state) => state.users.currentUser,
|
||||||
}),
|
}),
|
||||||
...mapPiniaState(useSyncConfigStore, {
|
|
||||||
shouldShowTooltip: (state) => state.mergedConfig.mentionLinkShowTooltip,
|
|
||||||
shouldShowAvatar: (state) => state.mergedConfig.mentionLinkShowAvatar,
|
|
||||||
shouldShowYous: (state) => state.mergedConfig.mentionLinkShowYous,
|
|
||||||
shouldBoldenYou: (state) => state.mergedConfig.mentionLinkBoldenYou,
|
|
||||||
shouldFadeDomain: (state) => state.mergedConfig.mentionLinkFadeDomain,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
import { mapActions, mapState as mapPiniaState, mapStores } from 'pinia'
|
import { mapActions, mapState, mapStores } from 'pinia'
|
||||||
import { mapState } from 'vuex'
|
|
||||||
|
import mfaApi from '../../services/new_api/mfa.js'
|
||||||
|
|
||||||
import mfaApi from '../../services/new_api/mfa.js'
|
import mfaApi from '../../services/new_api/mfa.js'
|
||||||
|
|
||||||
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 { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
|
@ -17,13 +19,10 @@ export default {
|
||||||
error: false,
|
error: false,
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
...mapPiniaState(useAuthFlowStore, {
|
|
||||||
authSettings: (store) => store.settings,
|
|
||||||
}),
|
|
||||||
...mapStores(useOAuthStore),
|
...mapStores(useOAuthStore),
|
||||||
...mapState({
|
...mapState(useOAuthStore, ['clientId', 'clientSecret']),
|
||||||
instance: 'instance',
|
...mapState(useAuthFlowStore, ['settings']),
|
||||||
}),
|
...mapState(useInstanceStore, ['server']),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useAuthFlowStore, ['requireTOTP', 'abortMFA', 'login']),
|
...mapActions(useAuthFlowStore, ['requireTOTP', 'abortMFA', 'login']),
|
||||||
|
|
@ -38,13 +37,11 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
submit() {
|
submit() {
|
||||||
const { clientId, clientSecret } = this.oauthStore
|
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
clientId,
|
clientId: this.clientId,
|
||||||
clientSecret,
|
clientSecret: this.clientSecret,
|
||||||
instance: this.instance.server,
|
instance: this.server,
|
||||||
mfaToken: this.authSettings.mfa_token,
|
mfaToken: this.settings.mfa_token,
|
||||||
code: this.code,
|
code: this.code,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
import Notifications from '../notifications/notifications.vue'
|
import Notifications from '../notifications/notifications.vue'
|
||||||
import SideDrawer from '../side_drawer/side_drawer.vue'
|
import SideDrawer from '../side_drawer/side_drawer.vue'
|
||||||
|
|
||||||
import { useAnnouncementsStore } from 'src/stores/announcements'
|
import { useAnnouncementsStore } from 'src/stores/announcements.js'
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
import { useServerSideStorageStore } from 'src/stores/serverSideStorage.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -75,15 +75,15 @@ const MobileNav = {
|
||||||
return this.$route.name === 'chat'
|
return this.$route.name === 'chat'
|
||||||
},
|
},
|
||||||
...mapState(useAnnouncementsStore, ['unreadAnnouncementCount']),
|
...mapState(useAnnouncementsStore, ['unreadAnnouncementCount']),
|
||||||
...mapState(useSyncConfigStore, {
|
...mapState(useServerSideStorageStore, {
|
||||||
pinnedItems: (store) =>
|
pinnedItems: (store) =>
|
||||||
new Set(store.prefsStorage.collections.pinnedNavItems).has('chats'),
|
new Set(store.prefsStorage.collections.pinnedNavItems).has('chats'),
|
||||||
}),
|
}),
|
||||||
shouldConfirmLogout() {
|
shouldConfirmLogout() {
|
||||||
return useSyncConfigStore().mergedConfig.modalOnLogout
|
return this.$store.getters.mergedConfig.modalOnLogout
|
||||||
},
|
},
|
||||||
closingDrawerMarksAsSeen() {
|
closingDrawerMarksAsSeen() {
|
||||||
return useSyncConfigStore().mergedConfig.closingDrawerMarksAsSeen
|
return this.$store.getters.mergedConfig.closingDrawerMarksAsSeen
|
||||||
},
|
},
|
||||||
...mapGetters(['unreadChatCount']),
|
...mapGetters(['unreadChatCount']),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { debounce } from 'lodash'
|
import { debounce } from 'lodash'
|
||||||
|
|
||||||
import { usePostStatusStore } from 'src/stores/post_status'
|
import { usePostStatusStore } from 'src/stores/post_status.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faPen } from '@fortawesome/free-solid-svg-icons'
|
import { faPen } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
@ -46,10 +45,10 @@ const MobilePostStatusButton = {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
isPersistent() {
|
isPersistent() {
|
||||||
return !!useSyncConfigStore().mergedConfig.alwaysShowNewPostButton
|
return !!this.$store.getters.mergedConfig.alwaysShowNewPostButton
|
||||||
},
|
},
|
||||||
autohideFloatingPostButton() {
|
autohideFloatingPostButton() {
|
||||||
return !!useSyncConfigStore().mergedConfig.autohideFloatingPostButton
|
return !!this.$store.getters.mergedConfig.autohideFloatingPostButton
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import DialogModal from '../dialog_modal/dialog_modal.vue'
|
||||||
import Popover from '../popover/popover.vue'
|
import Popover from '../popover/popover.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faChevronDown } from '@fortawesome/free-solid-svg-icons'
|
import { faChevronDown } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
@ -56,7 +57,7 @@ const ModerationTools = {
|
||||||
},
|
},
|
||||||
canUseTagPolicy() {
|
canUseTagPolicy() {
|
||||||
return (
|
return (
|
||||||
useInstanceStore().tagPolicyAvailable &&
|
useInstanceCapabilitiesStore().tagPolicyAvailable &&
|
||||||
this.privileged('users_manage_tags')
|
this.privileged('users_manage_tags')
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,10 @@ 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.js'
|
import { useAnnouncementsStore } from 'src/stores/announcements'
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
|
import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -83,28 +84,28 @@ const NavPanel = {
|
||||||
this.editMode = !this.editMode
|
this.editMode = !this.editMode
|
||||||
},
|
},
|
||||||
toggleCollapse() {
|
toggleCollapse() {
|
||||||
useSyncConfigStore().setPreference({
|
useServerSideStorageStore().setPreference({
|
||||||
path: 'simple.collapseNav',
|
path: 'simple.collapseNav',
|
||||||
value: !this.collapsed,
|
value: !this.collapsed,
|
||||||
})
|
})
|
||||||
useSyncConfigStore().pushSyncConfig()
|
useServerSideStorageStore().pushServerSideStorage()
|
||||||
},
|
},
|
||||||
isPinned(item) {
|
isPinned(item) {
|
||||||
return this.pinnedItems.has(item)
|
return this.pinnedItems.has(item)
|
||||||
},
|
},
|
||||||
togglePin(item) {
|
togglePin(item) {
|
||||||
if (this.isPinned(item)) {
|
if (this.isPinned(item)) {
|
||||||
useSyncConfigStore().removeCollectionPreference({
|
useServerSideStorageStore().removeCollectionPreference({
|
||||||
path: 'collections.pinnedNavItems',
|
path: 'collections.pinnedNavItems',
|
||||||
value: item,
|
value: item,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
useSyncConfigStore().addCollectionPreference({
|
useServerSideStorageStore().addCollectionPreference({
|
||||||
path: 'collections.pinnedNavItems',
|
path: 'collections.pinnedNavItems',
|
||||||
value: item,
|
value: item,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
useSyncConfigStore().pushSyncConfig()
|
useServerSideStorageStore().pushServerSideStorage()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -112,20 +113,20 @@ const NavPanel = {
|
||||||
unreadAnnouncementCount: 'unreadAnnouncementCount',
|
unreadAnnouncementCount: 'unreadAnnouncementCount',
|
||||||
supportsAnnouncements: (store) => store.supportsAnnouncements,
|
supportsAnnouncements: (store) => store.supportsAnnouncements,
|
||||||
}),
|
}),
|
||||||
...mapPiniaState(useSyncConfigStore, {
|
...mapPiniaState(useInstanceCapabilitiesStore, [
|
||||||
|
'pleromaChatMessagesAvailable',
|
||||||
|
'pleromaBookmarkFoldersAvailable',
|
||||||
|
'localBubble',
|
||||||
|
]),
|
||||||
|
...mapPiniaState(useInstanceStore, ['federating']),
|
||||||
|
...mapPiniaState(useInstanceStore, {
|
||||||
|
privateMode: (store) => store.private,
|
||||||
|
}),
|
||||||
|
...mapPiniaState(useServerSideStorageStore, {
|
||||||
collapsed: (store) => store.prefsStorage.simple.collapseNav,
|
collapsed: (store) => store.prefsStorage.simple.collapseNav,
|
||||||
pinnedItems: (store) =>
|
pinnedItems: (store) =>
|
||||||
new Set(store.prefsStorage.collections.pinnedNavItems),
|
new Set(store.prefsStorage.collections.pinnedNavItems),
|
||||||
}),
|
}),
|
||||||
...mapPiniaState(useInstanceStore, {
|
|
||||||
bubbleTimeline: (store) => store.featureSet.localBubble,
|
|
||||||
pleromaChatMessagesAvailable: (store) =>
|
|
||||||
store.featureSet.pleromaChatMessagesAvailable,
|
|
||||||
bookmarkFolders: (store) =>
|
|
||||||
store.featureSet.pleromaBookmarkFoldersAvailable,
|
|
||||||
privateMode: (state) => state.private,
|
|
||||||
federating: (state) => state.federating,
|
|
||||||
}),
|
|
||||||
...mapState({
|
...mapState({
|
||||||
currentUser: (state) => state.users.currentUser,
|
currentUser: (state) => state.users.currentUser,
|
||||||
followRequestCount: (state) => state.api.followRequests.length,
|
followRequestCount: (state) => state.api.followRequests.length,
|
||||||
|
|
@ -142,8 +143,8 @@ const NavPanel = {
|
||||||
isFederating: this.federating,
|
isFederating: this.federating,
|
||||||
isPrivate: this.privateMode,
|
isPrivate: this.privateMode,
|
||||||
currentUser: this.currentUser,
|
currentUser: this.currentUser,
|
||||||
supportsBubbleTimeline: this.bubbleTimeline,
|
supportsBubbleTimeline: this.localBubble,
|
||||||
supportsBookmarkFolders: this.bookmarkFolders,
|
supportsBookmarkFolders: this.pleromaBookmarkFoldersAvailable,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -156,8 +157,8 @@ const NavPanel = {
|
||||||
isFederating: this.federating,
|
isFederating: this.federating,
|
||||||
isPrivate: this.privateMode,
|
isPrivate: this.privateMode,
|
||||||
currentUser: this.currentUser,
|
currentUser: this.currentUser,
|
||||||
supportsBubbleTimeline: this.bubbleTimeline,
|
supportsBubbleTimeline: this.localBubble,
|
||||||
supportsBookmarkFolders: this.bookmarkFolders,
|
supportsBookmarkFolders: this.pleromaBookmarkFoldersAvailable,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<NavigationEntry
|
<NavigationEntry
|
||||||
v-if="currentUser && bookmarkFolders"
|
v-if="currentUser && pleromaBookmarkFoldersAvailable"
|
||||||
:show-pin="false"
|
:show-pin="false"
|
||||||
:item="{ icon: 'bookmark', label: 'nav.bookmarks' }"
|
:item="{ icon: 'bookmark', label: 'nav.bookmarks' }"
|
||||||
:aria-expanded="showBookmarkFolders ? 'true' : 'false'"
|
:aria-expanded="showBookmarkFolders ? 'true' : 'false'"
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import { mapState } from 'vuex'
|
||||||
import { routeTo } from 'src/components/navigation/navigation.js'
|
import { routeTo } from 'src/components/navigation/navigation.js'
|
||||||
import OptionalRouterLink from 'src/components/optional_router_link/optional_router_link.vue'
|
import OptionalRouterLink from 'src/components/optional_router_link/optional_router_link.vue'
|
||||||
|
|
||||||
import { useAnnouncementsStore } from 'src/stores/announcements'
|
import { useAnnouncementsStore } from 'src/stores/announcements.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
import { useServerSideStorageStore } from 'src/stores/serverSideStorage.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faThumbtack } from '@fortawesome/free-solid-svg-icons'
|
import { faThumbtack } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
@ -23,17 +23,17 @@ const NavigationEntry = {
|
||||||
},
|
},
|
||||||
togglePin(value) {
|
togglePin(value) {
|
||||||
if (this.isPinned(value)) {
|
if (this.isPinned(value)) {
|
||||||
useSyncConfigStore().removeCollectionPreference({
|
useServerSideStorageStore().removeCollectionPreference({
|
||||||
path: 'collections.pinnedNavItems',
|
path: 'collections.pinnedNavItems',
|
||||||
value,
|
value,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
useSyncConfigStore().addCollectionPreference({
|
useServerSideStorageStore().addCollectionPreference({
|
||||||
path: 'collections.pinnedNavItems',
|
path: 'collections.pinnedNavItems',
|
||||||
value,
|
value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
useSyncConfigStore().pushSyncConfig()
|
useServerSideStorageStore().pushServerSideStorage()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -47,7 +47,7 @@ const NavigationEntry = {
|
||||||
...mapState({
|
...mapState({
|
||||||
currentUser: (state) => state.users.currentUser,
|
currentUser: (state) => state.users.currentUser,
|
||||||
}),
|
}),
|
||||||
...mapPiniaState(useSyncConfigStore, {
|
...mapPiniaState(useServerSideStorageStore, {
|
||||||
pinnedItems: (store) =>
|
pinnedItems: (store) =>
|
||||||
new Set(store.prefsStorage.collections.pinnedNavItems),
|
new Set(store.prefsStorage.collections.pinnedNavItems),
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,10 @@ 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'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
import { useListsStore } from 'src/stores/lists'
|
import { useListsStore } from 'src/stores/lists'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -69,17 +70,15 @@ const NavPanel = {
|
||||||
...mapPiniaState(useBookmarkFoldersStore, {
|
...mapPiniaState(useBookmarkFoldersStore, {
|
||||||
bookmarks: getBookmarkFolderEntries,
|
bookmarks: getBookmarkFolderEntries,
|
||||||
}),
|
}),
|
||||||
...mapPiniaState(useSyncConfigStore, {
|
...mapPiniaState(useServerSideStorageStore, {
|
||||||
pinnedItems: (store) =>
|
pinnedItems: (store) =>
|
||||||
new Set(store.prefsStorage.collections.pinnedNavItems),
|
new Set(store.prefsStorage.collections.pinnedNavItems),
|
||||||
}),
|
}),
|
||||||
...mapPiniaState(useInstanceStore, {
|
...mapPiniaState(useInstanceStore, ['privateMode', 'federating']),
|
||||||
privateMode: (store) => store.featureSet.private,
|
...mapPiniaState(useInstanceCapabilitiesStore, [
|
||||||
federating: (store) => store.featureSet.federating,
|
'pleromaChatMessagesAvailable',
|
||||||
pleromaChatMessagesAvailable: (store) =>
|
'localBubble',
|
||||||
store.featureSet.pleromaChatMessagesAvailable,
|
]),
|
||||||
bubbleTimelinesSupported: (store) => store.featureSet.localBubble,
|
|
||||||
}),
|
|
||||||
...mapState({
|
...mapState({
|
||||||
currentUser: (state) => state.users.currentUser,
|
currentUser: (state) => state.users.currentUser,
|
||||||
followRequestCount: (state) => state.api.followRequests.length,
|
followRequestCount: (state) => state.api.followRequests.length,
|
||||||
|
|
@ -98,7 +97,7 @@ const NavPanel = {
|
||||||
isFederating: this.federating,
|
isFederating: this.federating,
|
||||||
isPrivate: this.privateMode,
|
isPrivate: this.privateMode,
|
||||||
currentUser: this.currentUser,
|
currentUser: this.currentUser,
|
||||||
supportsBubbleTimeline: this.bubbleTimelinesSupported,
|
supportsBubbleTimeline: this.localBubble,
|
||||||
supportsBookmarkFolders: this.bookmarks,
|
supportsBookmarkFolders: this.bookmarks,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -117,7 +116,7 @@ const NavPanel = {
|
||||||
{
|
{
|
||||||
hasChats: this.pleromaChatMessagesAvailable,
|
hasChats: this.pleromaChatMessagesAvailable,
|
||||||
hasAnnouncements: this.supportsAnnouncements,
|
hasAnnouncements: this.supportsAnnouncements,
|
||||||
supportsBubbleTimeline: this.bubbleTimelinesSupported,
|
supportsBubbleTimeline: this.localBubble,
|
||||||
supportsBookmarkFolders: this.bookmarks,
|
supportsBookmarkFolders: this.bookmarks,
|
||||||
isFederating: this.federating,
|
isFederating: this.federating,
|
||||||
isPrivate: this.privateMode,
|
isPrivate: this.privateMode,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import UserLink from '../user_link/user_link.vue'
|
||||||
import UserPopover from '../user_popover/user_popover.vue'
|
import UserPopover from '../user_popover/user_popover.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.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'
|
||||||
|
|
||||||
|
|
@ -182,7 +181,7 @@ const Notification = {
|
||||||
return highlightClass(this.notification.from_profile)
|
return highlightClass(this.notification.from_profile)
|
||||||
},
|
},
|
||||||
userStyle() {
|
userStyle() {
|
||||||
const highlight = useSyncConfigStore().mergedConfig.highlight
|
const highlight = this.$store.getters.mergedConfig.highlight
|
||||||
const user = this.notification.from_profile
|
const user = this.notification.from_profile
|
||||||
return highlightStyle(highlight[user.screen_name])
|
return highlightStyle(highlight[user.screen_name])
|
||||||
},
|
},
|
||||||
|
|
@ -210,7 +209,7 @@ const Notification = {
|
||||||
return isStatusNotification(this.notification.type)
|
return isStatusNotification(this.notification.type)
|
||||||
},
|
},
|
||||||
mergedConfig() {
|
mergedConfig() {
|
||||||
return useSyncConfigStore().mergedConfig
|
return this.$store.getters.mergedConfig
|
||||||
},
|
},
|
||||||
shouldConfirmApprove() {
|
shouldConfirmApprove() {
|
||||||
return this.mergedConfig.modalOnApproveFollow
|
return this.mergedConfig.modalOnApproveFollow
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,7 @@ import Notification from '../notification/notification.vue'
|
||||||
import NotificationFilters from './notification_filters.vue'
|
import NotificationFilters from './notification_filters.vue'
|
||||||
|
|
||||||
import { useAnnouncementsStore } from 'src/stores/announcements.js'
|
import { useAnnouncementsStore } from 'src/stores/announcements.js'
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -100,7 +98,7 @@ const Notifications = {
|
||||||
return this.unseenNotifications.length
|
return this.unseenNotifications.length
|
||||||
},
|
},
|
||||||
ignoreInactionableSeen() {
|
ignoreInactionableSeen() {
|
||||||
return useSyncConfigStore().mergedConfig.ignoreInactionableSeen
|
return this.$store.getters.mergedConfig.ignoreInactionableSeen
|
||||||
},
|
},
|
||||||
extraNotificationsCount() {
|
extraNotificationsCount() {
|
||||||
return countExtraNotifications(this.$store)
|
return countExtraNotifications(this.$store)
|
||||||
|
|
@ -138,10 +136,10 @@ const Notifications = {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
noSticky() {
|
noSticky() {
|
||||||
return useSyncConfigStore().mergedConfig.disableStickyHeaders
|
return this.$store.getters.mergedConfig.disableStickyHeaders
|
||||||
},
|
},
|
||||||
unseenAtTop() {
|
unseenAtTop() {
|
||||||
return useSyncConfigStore().mergedConfig.unseenAtTop
|
return this.$store.getters.mergedConfig.unseenAtTop
|
||||||
},
|
},
|
||||||
showExtraNotifications() {
|
showExtraNotifications() {
|
||||||
return !this.noExtra
|
return !this.noExtra
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ import { computed } from 'vue'
|
||||||
|
|
||||||
import ColorInput from 'src/components/color_input/color_input.vue'
|
import ColorInput from 'src/components/color_input/color_input.vue'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
newExporter,
|
newExporter,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
|
import { mapState as mapPiniaState } from 'pinia'
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
import passwordResetApi from '../../services/new_api/password_reset.js'
|
import passwordResetApi from '../../services/new_api/password_reset.js'
|
||||||
|
|
||||||
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faTimes } from '@fortawesome/free-solid-svg-icons'
|
import { faTimes } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
|
|
@ -20,11 +23,8 @@ const passwordReset = {
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
signedIn: (state) => !!state.users.currentUser,
|
signedIn: (state) => !!state.users.currentUser,
|
||||||
instance: (state) => state.instance,
|
|
||||||
}),
|
}),
|
||||||
mailerEnabled() {
|
...mapPiniaState(useInstanceStore, ['server', 'mailerEnabled']),
|
||||||
return this.instance.mailerEnabled
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (this.signedIn) {
|
if (this.signedIn) {
|
||||||
|
|
@ -44,9 +44,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 = ''
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@ import Timeago from 'components/timeago/timeago.vue'
|
||||||
|
|
||||||
import genRandomSeed from '../../services/random_seed/random_seed.service.js'
|
import genRandomSeed from '../../services/random_seed/random_seed.service.js'
|
||||||
|
|
||||||
import { usePollsStore } from 'src/stores/polls'
|
import { usePollsStore } from 'src/stores/polls.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Poll',
|
name: 'Poll',
|
||||||
|
|
@ -49,7 +48,7 @@ export default {
|
||||||
return (this.poll && this.poll.expired) || false
|
return (this.poll && this.poll.expired) || false
|
||||||
},
|
},
|
||||||
expirationLabel() {
|
expirationLabel() {
|
||||||
if (useSyncConfigStore().mergedConfig.useAbsoluteTimeFormat) {
|
if (this.$store.getters.mergedConfig.useAbsoluteTimeFormat) {
|
||||||
return this.expired ? 'polls.expired_at' : 'polls.expires_at'
|
return this.expired ? 'polls.expired_at' : 'polls.expires_at'
|
||||||
} else {
|
} else {
|
||||||
return this.expired ? 'polls.expired' : 'polls.expires_in'
|
return this.expired ? 'polls.expired' : 'polls.expires_in'
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pollLimits() {
|
pollLimits() {
|
||||||
return useInstanceStore().pollLimits
|
return useInstanceStore().limits.pollLimits
|
||||||
},
|
},
|
||||||
maxOptions() {
|
maxOptions() {
|
||||||
return this.pollLimits.max_options
|
return this.pollLimits.max_options
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ import StatusContent from '../status_content/status_content.vue'
|
||||||
|
|
||||||
import { useEmojiStore } from 'src/stores/emoji.js'
|
import { useEmojiStore } from 'src/stores/emoji.js'
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.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 { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { pollFormToMasto } from 'src/services/poll/poll.service.js'
|
import { pollFormToMasto } from 'src/services/poll/poll.service.js'
|
||||||
|
|
||||||
|
|
@ -163,6 +163,8 @@ const PostStatusForm = {
|
||||||
const preset = this.$route.query.message
|
const preset = this.$route.query.message
|
||||||
let statusText = preset || ''
|
let statusText = preset || ''
|
||||||
|
|
||||||
|
const { scopeCopy } = this.$store.getters.mergedConfig
|
||||||
|
|
||||||
const [statusType, refId] = typeAndRefId({
|
const [statusType, refId] = typeAndRefId({
|
||||||
replyTo: this.replyTo,
|
replyTo: this.replyTo,
|
||||||
profileMention: this.profileMention && this.repliedUser?.id,
|
profileMention: this.profileMention && this.repliedUser?.id,
|
||||||
|
|
@ -185,34 +187,37 @@ const PostStatusForm = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const scope =
|
const scope =
|
||||||
(this.copyMessageScope && this.scopeCopy) ||
|
(this.copyMessageScope && scopeCopy) ||
|
||||||
this.copyMessageScope === 'direct'
|
this.copyMessageScope === 'direct'
|
||||||
? this.copyMessageScope
|
? this.copyMessageScope
|
||||||
: this.$store.state.users.currentUser.default_scope
|
: this.$store.state.users.currentUser.default_scope
|
||||||
|
|
||||||
|
const { postContentType: contentType, sensitiveByDefault } =
|
||||||
|
this.$store.getters.mergedConfig
|
||||||
|
|
||||||
statusParams = {
|
statusParams = {
|
||||||
type: statusType,
|
type: statusType,
|
||||||
refId,
|
refId,
|
||||||
spoilerText: this.subject || '',
|
spoilerText: this.subject || '',
|
||||||
status: statusText,
|
status: statusText,
|
||||||
nsfw: !!this.sensitiveByDefault,
|
nsfw: !!sensitiveByDefault,
|
||||||
files: [],
|
files: [],
|
||||||
poll: {},
|
poll: {},
|
||||||
hasPoll: false,
|
hasPoll: false,
|
||||||
mediaDescriptions: {},
|
mediaDescriptions: {},
|
||||||
visibility: scope,
|
visibility: scope,
|
||||||
contentType: this.contentType,
|
contentType,
|
||||||
quoting: false,
|
quoting: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statusType === 'edit') {
|
if (statusType === 'edit') {
|
||||||
const statusContentType = this.statusContentType || this.contentType
|
const statusContentType = this.statusContentType || contentType
|
||||||
statusParams = {
|
statusParams = {
|
||||||
type: statusType,
|
type: statusType,
|
||||||
refId,
|
refId,
|
||||||
spoilerText: this.subject || '',
|
spoilerText: this.subject || '',
|
||||||
status: this.statusText || '',
|
status: this.statusText || '',
|
||||||
nsfw: this.statusIsSensitive || !!this.sensitiveByDefault,
|
nsfw: this.statusIsSensitive || !!sensitiveByDefault,
|
||||||
files: this.statusFiles || [],
|
files: this.statusFiles || [],
|
||||||
poll: this.statusPoll || {},
|
poll: this.statusPoll || {},
|
||||||
hasPoll: false,
|
hasPoll: false,
|
||||||
|
|
@ -249,6 +254,9 @@ const PostStatusForm = {
|
||||||
userDefaultScope() {
|
userDefaultScope() {
|
||||||
return this.$store.state.users.currentUser.default_scope
|
return this.$store.state.users.currentUser.default_scope
|
||||||
},
|
},
|
||||||
|
showAllScopes() {
|
||||||
|
return !this.mergedConfig.minimalScopesMode
|
||||||
|
},
|
||||||
hideExtraActions() {
|
hideExtraActions() {
|
||||||
return this.disableDraft || this.hideDraft
|
return this.disableDraft || this.hideDraft
|
||||||
},
|
},
|
||||||
|
|
@ -295,22 +303,28 @@ const PostStatusForm = {
|
||||||
isOverLengthLimit() {
|
isOverLengthLimit() {
|
||||||
return this.hasStatusLengthLimit && this.charactersLeft < 0
|
return this.hasStatusLengthLimit && this.charactersLeft < 0
|
||||||
},
|
},
|
||||||
|
minimalScopesMode() {
|
||||||
|
return useInstanceStore().minimalScopesMode
|
||||||
|
},
|
||||||
|
alwaysShowSubject() {
|
||||||
|
return this.mergedConfig.alwaysShowSubjectInput
|
||||||
|
},
|
||||||
postFormats() {
|
postFormats() {
|
||||||
return useInstanceStore().postFormats || []
|
return useInstanceCapabilitiesStore().postFormats || []
|
||||||
},
|
},
|
||||||
safeDMEnabled() {
|
safeDMEnabled() {
|
||||||
return useInstanceStore().safeDM
|
return useInstanceCapabilitiesStore().safeDM
|
||||||
},
|
},
|
||||||
pollsAvailable() {
|
pollsAvailable() {
|
||||||
return (
|
return (
|
||||||
useInstanceStore().pollsAvailable &&
|
useInstanceCapabilitiesStore().pollsAvailable &&
|
||||||
useInstanceStore().pollLimits.max_options >= 2 &&
|
useInstanceStore().limits.pollLimits.max_options >= 2 &&
|
||||||
this.disablePolls !== true
|
this.disablePolls !== true
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
hideScopeNotice() {
|
hideScopeNotice() {
|
||||||
return (
|
return (
|
||||||
this.disableNotice || useSyncConfigStore().mergedConfig.hideScopeNotice
|
this.disableNotice || this.$store.getters.mergedConfig.hideScopeNotice
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
pollContentError() {
|
pollContentError() {
|
||||||
|
|
@ -333,7 +347,7 @@ const PostStatusForm = {
|
||||||
return typeof this.statusId !== 'undefined' && this.statusId.trim() !== ''
|
return typeof this.statusId !== 'undefined' && this.statusId.trim() !== ''
|
||||||
},
|
},
|
||||||
quotable() {
|
quotable() {
|
||||||
if (!useInstanceStore().quotingAvailable) {
|
if (!useInstanceCapabilitiesStore().quotingAvailable) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -365,6 +379,9 @@ const PostStatusForm = {
|
||||||
pollFormVisible() {
|
pollFormVisible() {
|
||||||
return this.newStatus.hasPoll
|
return this.newStatus.hasPoll
|
||||||
},
|
},
|
||||||
|
shouldAutoSaveDraft() {
|
||||||
|
return this.$store.getters.mergedConfig.autoSaveDraft
|
||||||
|
},
|
||||||
autoSaveState() {
|
autoSaveState() {
|
||||||
if (this.saveable) {
|
if (this.saveable) {
|
||||||
return this.$t('post_status.auto_save_saving')
|
return this.$t('post_status.auto_save_saving')
|
||||||
|
|
@ -394,17 +411,10 @@ const PostStatusForm = {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
...mapGetters(['mergedConfig']),
|
||||||
...mapState(useInterfaceStore, {
|
...mapState(useInterfaceStore, {
|
||||||
mobileLayout: (store) => store.mobileLayout,
|
mobileLayout: (store) => store.mobileLayout,
|
||||||
}),
|
}),
|
||||||
...mapState(useSyncConfigStore, {
|
|
||||||
scopeCopy: (store) => store.mergedConfig.scopeCopy,
|
|
||||||
shouldAutoSaveDraft: (store) => store.mergedConfig.autoSaveDraft,
|
|
||||||
showAllScopes: (store) => !store.mergedConfig.minimalScopesMode,
|
|
||||||
alwaysShowSubject: (store) => store.mergedConfig.alwaysShowSubjectInput,
|
|
||||||
contentType: (store) => store.mergedConfig.postContentType,
|
|
||||||
sensitiveByDefaultType: (store) => store.mergedConfig.sensitiveByDefault,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
newStatus: {
|
newStatus: {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import get from 'lodash/get'
|
||||||
import Modal from '../modal/modal.vue'
|
import Modal from '../modal/modal.vue'
|
||||||
import PostStatusForm from '../post_status_form/post_status_form.vue'
|
import PostStatusForm from '../post_status_form/post_status_form.vue'
|
||||||
|
|
||||||
import { usePostStatusStore } from 'src/stores/post_status'
|
import { usePostStatusStore } from 'src/stores/post_status.js'
|
||||||
|
|
||||||
const PostStatusModal = {
|
const PostStatusModal = {
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { mapState } from 'pinia'
|
import { mapState } from 'pinia'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
import Popover from '../popover/popover.vue'
|
import Popover from '../popover/popover.vue'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faFilter, faFont, faWrench } from '@fortawesome/free-solid-svg-icons'
|
import { faFilter, faFont, faWrench } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
@ -31,7 +31,7 @@ const QuickFilterSettings = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useSyncConfigStore, ['mergedConfig']),
|
...mapGetters(['mergedConfig']),
|
||||||
...mapState(useInterfaceStore, {
|
...mapState(useInterfaceStore, {
|
||||||
mobileLayout: (state) => state.layoutType === 'mobile',
|
mobileLayout: (state) => state.layoutType === 'mobile',
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@ import { mapGetters } from 'vuex'
|
||||||
import Popover from 'src/components/popover/popover.vue'
|
import Popover from 'src/components/popover/popover.vue'
|
||||||
import QuickFilterSettings from 'src/components/quick_filter_settings/quick_filter_settings.vue'
|
import QuickFilterSettings from 'src/components/quick_filter_settings/quick_filter_settings.vue'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -37,7 +36,7 @@ const QuickViewSettings = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useSyncConfigStore, ['mergedConfig']),
|
...mapGetters(['mergedConfig']),
|
||||||
...mapState(useInterfaceStore, {
|
...mapState(useInterfaceStore, {
|
||||||
mobileLayout: (state) => state.layoutType === 'mobile',
|
mobileLayout: (state) => state.layoutType === 'mobile',
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
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 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'
|
||||||
|
|
||||||
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
|
||||||
import { DAY } from 'src/services/date_utils/date_utils.js'
|
import { DAY } from 'src/services/date_utils/date_utils.js'
|
||||||
|
|
||||||
const registration = {
|
const registration = {
|
||||||
|
|
@ -97,21 +100,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: {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import StatusContent from '../status_content/status_content.vue'
|
||||||
import Timeago from '../timeago/timeago.vue'
|
import Timeago from '../timeago/timeago.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useReportsStore } from 'src/stores/reports'
|
import { useReportsStore } from 'src/stores/reports.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'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
import StringSetting from '../helpers/string_setting.vue'
|
import StringSetting from '../helpers/string_setting.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import IntegerSetting from '../helpers/integer_setting.vue'
|
||||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
import StringSetting from '../helpers/string_setting.vue'
|
import StringSetting from '../helpers/string_setting.vue'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faGlobe } from '@fortawesome/free-solid-svg-icons'
|
import { faGlobe } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,10 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
path: {
|
path: {
|
||||||
type: [String, Array],
|
type: [String, Array],
|
||||||
required: false,
|
required: false,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
|
||||||
|
|
||||||
import './vertical_tab_switcher.scss'
|
import './vertical_tab_switcher.scss'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
|
||||||
const findFirstUsable = (slots) => slots.findIndex((_) => _.props)
|
const findFirstUsable = (slots) => slots.findIndex((_) => _.props)
|
||||||
|
|
||||||
|
|
@ -35,11 +35,6 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
parentCollapsed: {
|
|
||||||
required: false,
|
|
||||||
type: Boolean,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -202,7 +197,7 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
class={'contents' + (this.scrollableTabs ? ' scrollable-tabs' : '')}
|
class="contents"
|
||||||
v-body-scroll-lock={this.bodyScrollLock}
|
v-body-scroll-lock={this.bodyScrollLock}
|
||||||
ref="contents"
|
ref="contents"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -63,10 +63,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-content-wrapper {
|
.tab-content-wrapper {
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
&.-hidden {
|
&.-hidden {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import Modal from 'src/components/modal/modal.vue'
|
||||||
import PanelLoading from 'src/components/panel_loading/panel_loading.vue'
|
import PanelLoading from 'src/components/panel_loading/panel_loading.vue'
|
||||||
import Popover from '../popover/popover.vue'
|
import Popover from '../popover/popover.vue'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
newExporter,
|
newExporter,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import RegistrationsTab from './admin_tabs/registrations_tab.vue'
|
||||||
import UploadsTab from './admin_tabs/uploads_tab.vue'
|
import UploadsTab from './admin_tabs/uploads_tab.vue'
|
||||||
import VerticalTabSwitcher from './helpers/vertical_tab_switcher.jsx'
|
import VerticalTabSwitcher from './helpers/vertical_tab_switcher.jsx'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import ProfileTab from './tabs/profile_tab.vue'
|
||||||
import SecurityTab from './tabs/security_tab/security_tab.vue'
|
import SecurityTab from './tabs/security_tab/security_tab.vue'
|
||||||
import StyleTab from './tabs/style_tab/style_tab.vue'
|
import StyleTab from './tabs/style_tab/style_tab.vue'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
ref="tabSwitcher"
|
ref="tabSwitcher"
|
||||||
class="settings_tab-switcher"
|
class="settings_tab-switcher"
|
||||||
:scrollable-tabs="true"
|
:scrollable-tabs="true"
|
||||||
:child-collapsed="childCollapsed"
|
|
||||||
:body-scroll-lock="bodyLock"
|
:body-scroll-lock="bodyLock"
|
||||||
:hide-header="navHideHeader"
|
:hide-header="navHideHeader"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@ import UnitSetting from '../helpers/unit_setting.vue'
|
||||||
import Preview from './old_theme_tab/theme_preview.vue'
|
import Preview from './old_theme_tab/theme_preview.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { normalizeThemeData, useInterfaceStore } from 'src/stores/interface'
|
import { normalizeThemeData, useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { newImporter } from 'src/services/export_import/export_import.js'
|
import { newImporter } from 'src/services/export_import/export_import.js'
|
||||||
import {
|
import {
|
||||||
|
|
@ -277,11 +276,11 @@ const AppearanceTab = {
|
||||||
return !window.IntersectionObserver
|
return !window.IntersectionObserver
|
||||||
},
|
},
|
||||||
instanceWallpaper() {
|
instanceWallpaper() {
|
||||||
useInstanceStore().background
|
useInstanceStore().instanceIdentity.background
|
||||||
},
|
},
|
||||||
instanceWallpaperUsed() {
|
instanceWallpaperUsed() {
|
||||||
return (
|
return (
|
||||||
this.instanceWallpaper &&
|
useInstanceStore().instanceIdentity.background &&
|
||||||
!this.$store.state.users.currentUser.background_image
|
!this.$store.state.users.currentUser.background_image
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -312,9 +311,9 @@ const AppearanceTab = {
|
||||||
},
|
},
|
||||||
onImport(parsed, filename) {
|
onImport(parsed, filename) {
|
||||||
if (filename.endsWith('.json')) {
|
if (filename.endsWith('.json')) {
|
||||||
this.setThemeCustom(parsed.source || parsed.theme)
|
useInterfaceStore().setThemeCustom(parsed.source || parsed.theme)
|
||||||
} else if (filename.endsWith('.iss')) {
|
} else if (filename.endsWith('.iss')) {
|
||||||
this.setStyleCustom(parsed)
|
useInterfaceStore().setStyleCustom(parsed)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onImportFailure(result) {
|
onImportFailure(result) {
|
||||||
|
|
@ -336,36 +335,35 @@ const AppearanceTab = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isThemeActive(key) {
|
isThemeActive(key) {
|
||||||
return key === useSyncConfigStore().mergedConfig.theme
|
return (
|
||||||
|
key ===
|
||||||
|
(this.mergedConfig.theme || useInstanceStore().instanceIdentity.theme)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
isStyleActive(key) {
|
isStyleActive(key) {
|
||||||
return key === useSyncConfigStore().mergedConfig.style
|
return (
|
||||||
|
key ===
|
||||||
|
(this.mergedConfig.style || useInstanceStore().instanceIdentity.style)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
isPaletteActive(key) {
|
isPaletteActive(key) {
|
||||||
return (
|
return (
|
||||||
key ===
|
key ===
|
||||||
(useSyncConfigStore().mergedConfig.palette ||
|
(this.mergedConfig.palette ||
|
||||||
useInstanceStore().palette)
|
useInstanceStore().instanceIdentity.palette)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
...mapActions(useInterfaceStore, [
|
...mapActions(useInterfaceStore, ['setStyle', 'setTheme']),
|
||||||
'setStyle',
|
setPalette(name, data) {
|
||||||
'setStyleCustom',
|
useInterfaceStore().setPalette(name)
|
||||||
'setPalette',
|
|
||||||
'setPaletteCustom',
|
|
||||||
'setTheme',
|
|
||||||
'setThemeCustom',
|
|
||||||
]),
|
|
||||||
setLocalPalette(name, data) {
|
|
||||||
this.setPalette(name)
|
|
||||||
this.userPalette = data
|
this.userPalette = data
|
||||||
},
|
},
|
||||||
setLocalPaletteCustom(data) {
|
setPaletteCustom(data) {
|
||||||
this.setPaletteCustom(data)
|
useInterfaceStore().setPaletteCustom(data)
|
||||||
this.userPalette = data
|
this.userPalette = data
|
||||||
},
|
},
|
||||||
resetTheming() {
|
resetTheming() {
|
||||||
this.setStyle('stock')
|
useInterfaceStore().setStyle('stock')
|
||||||
},
|
},
|
||||||
previewTheme(key, version, input) {
|
previewTheme(key, version, input) {
|
||||||
let theme3
|
let theme3
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { mapActions, mapState } from 'pinia'
|
import { mapActions, mapState } from 'pinia'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
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'
|
||||||
|
|
@ -12,7 +11,8 @@ import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
import UnitSetting from '../helpers/unit_setting.vue'
|
import UnitSetting from '../helpers/unit_setting.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
|
import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
|
||||||
|
|
||||||
const ClutterTab = {
|
const ClutterTab = {
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -25,18 +25,19 @@ const ClutterTab = {
|
||||||
HelpIndicator,
|
HelpIndicator,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
instanceSpecificPanelPresent() {
|
|
||||||
return useInstanceStore().showInstanceSpecificPanel
|
|
||||||
},
|
|
||||||
...SharedComputedObject(),
|
...SharedComputedObject(),
|
||||||
...mapState(useSyncConfigStore, {
|
...mapState(useInstanceCapabilitiesStore, ['shoutAvailable']),
|
||||||
|
...mapState(useInstanceStore, {
|
||||||
|
showFeaturesPanel: (store) => store.instanceIdentity.showFeaturesPanel,
|
||||||
|
instanceSpecificPanelPresent: (store) =>
|
||||||
|
store.instanceIdentity.showInstanceSpecificPanel &&
|
||||||
|
store.instanceIdentity.instanceSpecificPanelContent,
|
||||||
|
}),
|
||||||
|
...mapState(useServerSideStorageStore, {
|
||||||
muteFilters: (store) =>
|
muteFilters: (store) =>
|
||||||
Object.entries(store.prefsStorage.simple.muteFilters),
|
Object.entries(store.prefsStorage.simple.muteFilters),
|
||||||
muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters,
|
muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters,
|
||||||
}),
|
}),
|
||||||
...mapVuexState({
|
|
||||||
blockExpirationSupported: (state) => state.instance.blockExpiration,
|
|
||||||
}),
|
|
||||||
onMuteDefaultActionLv1: {
|
onMuteDefaultActionLv1: {
|
||||||
get() {
|
get() {
|
||||||
const value = this.$store.state.config.onMuteDefaultAction
|
const value = this.$store.state.config.onMuteDefaultAction
|
||||||
|
|
@ -88,10 +89,10 @@ const ClutterTab = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useSyncConfigStore, [
|
...mapActions(useServerSideStorageStore, [
|
||||||
'setPreference',
|
'setPreference',
|
||||||
'unsetPreference',
|
'unsetPreference',
|
||||||
'pushSyncConfig',
|
'pushServerSideStorage',
|
||||||
]),
|
]),
|
||||||
getDatetimeLocal(timestamp) {
|
getDatetimeLocal(timestamp) {
|
||||||
const date = new Date(timestamp)
|
const date = new Date(timestamp)
|
||||||
|
|
@ -138,7 +139,7 @@ const ClutterTab = {
|
||||||
filter.order = this.muteFilters.length + 2
|
filter.order = this.muteFilters.length + 2
|
||||||
this.muteFiltersDraftObject[newId] = filter
|
this.muteFiltersDraftObject[newId] = filter
|
||||||
this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter })
|
this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter })
|
||||||
this.pushSyncConfig()
|
this.pushServerSideStorage()
|
||||||
},
|
},
|
||||||
exportFilter(id) {
|
exportFilter(id) {
|
||||||
this.exportedFilter = { ...this.muteFiltersDraftObject[id] }
|
this.exportedFilter = { ...this.muteFiltersDraftObject[id] }
|
||||||
|
|
@ -154,19 +155,19 @@ const ClutterTab = {
|
||||||
|
|
||||||
this.muteFiltersDraftObject[newId] = filter
|
this.muteFiltersDraftObject[newId] = filter
|
||||||
this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter })
|
this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter })
|
||||||
this.pushSyncConfig()
|
this.pushServerSideStorage()
|
||||||
},
|
},
|
||||||
deleteFilter(id) {
|
deleteFilter(id) {
|
||||||
delete this.muteFiltersDraftObject[id]
|
delete this.muteFiltersDraftObject[id]
|
||||||
this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null })
|
this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null })
|
||||||
this.pushSyncConfig()
|
this.pushServerSideStorage()
|
||||||
},
|
},
|
||||||
purgeExpiredFilters() {
|
purgeExpiredFilters() {
|
||||||
this.muteFiltersExpired.forEach(([id]) => {
|
this.muteFiltersExpired.forEach(([id]) => {
|
||||||
delete this.muteFiltersDraftObject[id]
|
delete this.muteFiltersDraftObject[id]
|
||||||
this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null })
|
this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null })
|
||||||
})
|
})
|
||||||
this.pushSyncConfig()
|
this.pushServerSideStorage()
|
||||||
},
|
},
|
||||||
updateFilter(id, field, value) {
|
updateFilter(id, field, value) {
|
||||||
const filter = { ...this.muteFiltersDraftObject[id] }
|
const filter = { ...this.muteFiltersDraftObject[id] }
|
||||||
|
|
@ -192,7 +193,7 @@ const ClutterTab = {
|
||||||
path: 'simple.muteFilters.' + id,
|
path: 'simple.muteFilters.' + id,
|
||||||
value: this.muteFiltersDraftObject[id],
|
value: this.muteFiltersDraftObject[id],
|
||||||
})
|
})
|
||||||
this.pushSyncConfig()
|
this.pushServerSideStorage()
|
||||||
this.muteFiltersDraftDirty[id] = false
|
this.muteFiltersDraftDirty[id] = false
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,11 @@
|
||||||
{{ $t('settings.hide_scrobbles_after') }}
|
{{ $t('settings.hide_scrobbles_after') }}
|
||||||
</UnitSetting>
|
</UnitSetting>
|
||||||
</li>
|
</li>
|
||||||
|
<li v-if="instanceSpecificPanelPresent">
|
||||||
|
<BooleanSetting path="hideISP">
|
||||||
|
{{ $t('settings.hide_isp') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -71,7 +76,7 @@
|
||||||
{{ $t('settings.user_card_hide_personal_marks') }}
|
{{ $t('settings.user_card_hide_personal_marks') }}
|
||||||
</BooleanSetting>
|
</BooleanSetting>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="instanceShoutboxPresent">
|
<li v-if="shoutAvailable">
|
||||||
<BooleanSetting
|
<BooleanSetting
|
||||||
path="hideShoutbox"
|
path="hideShoutbox"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'pinia'
|
||||||
|
|
||||||
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'
|
||||||
|
|
@ -13,7 +13,6 @@ import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
import UnitSetting from '../helpers/unit_setting.vue'
|
import UnitSetting from '../helpers/unit_setting.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
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'
|
||||||
|
|
@ -30,12 +29,6 @@ import {
|
||||||
library.add(faGlobe, faMessage, faPenAlt, faDatabase, faSliders)
|
library.add(faGlobe, faMessage, faPenAlt, faDatabase, faSliders)
|
||||||
|
|
||||||
const ComposingTab = {
|
const ComposingTab = {
|
||||||
props: {
|
|
||||||
parentCollapsed: {
|
|
||||||
required: true,
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
subjectLineOptions: ['email', 'noop', 'masto'].map((mode) => ({
|
subjectLineOptions: ['email', 'noop', 'masto'].map((mode) => ({
|
||||||
|
|
@ -123,7 +116,7 @@ const ComposingTab = {
|
||||||
},
|
},
|
||||||
language: {
|
language: {
|
||||||
get: function () {
|
get: function () {
|
||||||
return useSyncConfigStore().mergedConfig.interfaceLanguage
|
return this.$store.getters.mergedConfig.interfaceLanguage
|
||||||
},
|
},
|
||||||
set: function (val) {
|
set: function (val) {
|
||||||
this.$store.dispatch('setOption', {
|
this.$store.dispatch('setOption', {
|
||||||
|
|
@ -133,9 +126,7 @@ const ComposingTab = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
...SharedComputedObject(),
|
...SharedComputedObject(),
|
||||||
...mapState({
|
...mapState(useInstanceStore, ['blockExpiration']),
|
||||||
blockExpirationSupported: (state) => state.instance.blockExpiration,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeDefaultScope(value) {
|
changeDefaultScope(value) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import Checkbox from 'src/components/checkbox/checkbox.vue'
|
||||||
import Exporter from 'src/components/exporter/exporter.vue'
|
import Exporter from 'src/components/exporter/exporter.vue'
|
||||||
import Importer from 'src/components/importer/importer.vue'
|
import Importer from 'src/components/importer/importer.vue'
|
||||||
|
|
||||||
import { useOAuthTokensStore } from 'src/stores/oauth_tokens'
|
import { useOAuthTokensStore } from 'src/stores/oauth_tokens.js'
|
||||||
|
|
||||||
const DataImportExportTab = {
|
const DataImportExportTab = {
|
||||||
data() {
|
data() {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
import { mapState } from 'pinia'
|
|
||||||
|
|
||||||
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'
|
||||||
|
|
||||||
|
|
@ -11,6 +9,14 @@ const pleromaFeCommitUrl =
|
||||||
'https://git.pleroma.social/pleroma/pleroma-fe/commit/'
|
'https://git.pleroma.social/pleroma/pleroma-fe/commit/'
|
||||||
|
|
||||||
const VersionTab = {
|
const VersionTab = {
|
||||||
|
data() {
|
||||||
|
const instance = useInstanceStore()
|
||||||
|
return {
|
||||||
|
backendVersion: instance.backendVersion,
|
||||||
|
backendRepository: instance.backendRepository,
|
||||||
|
frontendVersion: instance.frontendVersion,
|
||||||
|
}
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
BooleanSetting,
|
BooleanSetting,
|
||||||
},
|
},
|
||||||
|
|
@ -19,11 +25,6 @@ const VersionTab = {
|
||||||
return pleromaFeCommitUrl + this.frontendVersion
|
return pleromaFeCommitUrl + this.frontendVersion
|
||||||
},
|
},
|
||||||
...SharedComputedObject(),
|
...SharedComputedObject(),
|
||||||
...mapState(useInstanceStore, [
|
|
||||||
'backendVersion',
|
|
||||||
'backendRepository',
|
|
||||||
'frontendVersion',
|
|
||||||
]),
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
clearAssetCache() {
|
clearAssetCache() {
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ import IntegerSetting from '../helpers/integer_setting.vue'
|
||||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
import UnitSetting from '../helpers/unit_setting.vue'
|
import UnitSetting from '../helpers/unit_setting.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
newExporter,
|
newExporter,
|
||||||
|
|
@ -36,11 +36,11 @@ const FilteringTab = {
|
||||||
label: this.$t(`user_card.mute_block_${mode}`),
|
label: this.$t(`user_card.mute_block_${mode}`),
|
||||||
})),
|
})),
|
||||||
muteFiltersDraftObject: cloneDeep(
|
muteFiltersDraftObject: cloneDeep(
|
||||||
useSyncConfigStore().prefsStorage.simple.muteFilters,
|
useServerSideStorageStore().prefsStorage.simple.muteFilters,
|
||||||
),
|
),
|
||||||
muteFiltersDraftDirty: Object.fromEntries(
|
muteFiltersDraftDirty: Object.fromEntries(
|
||||||
Object.entries(
|
Object.entries(
|
||||||
useSyncConfigStore().prefsStorage.simple.muteFilters,
|
useServerSideStorageStore().prefsStorage.simple.muteFilters,
|
||||||
).map(([k]) => [k, false]),
|
).map(([k]) => [k, false]),
|
||||||
),
|
),
|
||||||
exportedFilter: null,
|
exportedFilter: null,
|
||||||
|
|
@ -91,6 +91,13 @@ const FilteringTab = {
|
||||||
HelpIndicator,
|
HelpIndicator,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
...SharedComputedObject(),
|
||||||
|
...mapState(useServerSideStorageStore, {
|
||||||
|
muteFilters: (store) =>
|
||||||
|
Object.entries(store.prefsStorage.simple.muteFilters),
|
||||||
|
muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters,
|
||||||
|
}),
|
||||||
|
...mapState(useInstanceCapabilitiesStore, ['blockExpiration']),
|
||||||
onMuteDefaultActionLv1: {
|
onMuteDefaultActionLv1: {
|
||||||
get() {
|
get() {
|
||||||
const value = this.$store.state.config.onMuteDefaultAction
|
const value = this.$store.state.config.onMuteDefaultAction
|
||||||
|
|
@ -140,22 +147,12 @@ const FilteringTab = {
|
||||||
([, { expires }]) => expires != null && expires <= now,
|
([, { expires }]) => expires != null && expires <= now,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
...mapState(useInstanceStore, {
|
|
||||||
instanceSpecificPanelPresent: (store) => store.showInstanceSpecificPanel,
|
|
||||||
blockExpirationSupported: (store) => store.featureSet.blockExpiration,
|
|
||||||
}),
|
|
||||||
...SharedComputedObject(),
|
|
||||||
...mapState(useSyncConfigStore, {
|
|
||||||
muteFilters: (store) =>
|
|
||||||
Object.entries(store.prefsStorage.simple.muteFilters),
|
|
||||||
muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useSyncConfigStore, [
|
...mapActions(useServerSideStorageStore, [
|
||||||
'setPreference',
|
'setPreference',
|
||||||
'unsetPreference',
|
'unsetPreference',
|
||||||
'pushSyncConfig',
|
'pushServerSideStorage',
|
||||||
]),
|
]),
|
||||||
getDatetimeLocal(timestamp) {
|
getDatetimeLocal(timestamp) {
|
||||||
const date = new Date(timestamp)
|
const date = new Date(timestamp)
|
||||||
|
|
@ -202,7 +199,7 @@ const FilteringTab = {
|
||||||
filter.order = this.muteFilters.length + 2
|
filter.order = this.muteFilters.length + 2
|
||||||
this.muteFiltersDraftObject[newId] = filter
|
this.muteFiltersDraftObject[newId] = filter
|
||||||
this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter })
|
this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter })
|
||||||
this.pushSyncConfig()
|
this.pushServerSideStorage()
|
||||||
},
|
},
|
||||||
exportFilter(id) {
|
exportFilter(id) {
|
||||||
this.exportedFilter = { ...this.muteFiltersDraftObject[id] }
|
this.exportedFilter = { ...this.muteFiltersDraftObject[id] }
|
||||||
|
|
@ -218,19 +215,19 @@ const FilteringTab = {
|
||||||
|
|
||||||
this.muteFiltersDraftObject[newId] = filter
|
this.muteFiltersDraftObject[newId] = filter
|
||||||
this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter })
|
this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter })
|
||||||
this.pushSyncConfig()
|
this.pushServerSideStorage()
|
||||||
},
|
},
|
||||||
deleteFilter(id) {
|
deleteFilter(id) {
|
||||||
delete this.muteFiltersDraftObject[id]
|
delete this.muteFiltersDraftObject[id]
|
||||||
this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null })
|
this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null })
|
||||||
this.pushSyncConfig()
|
this.pushServerSideStorage()
|
||||||
},
|
},
|
||||||
purgeExpiredFilters() {
|
purgeExpiredFilters() {
|
||||||
this.muteFiltersExpired.forEach(([id]) => {
|
this.muteFiltersExpired.forEach(([id]) => {
|
||||||
delete this.muteFiltersDraftObject[id]
|
delete this.muteFiltersDraftObject[id]
|
||||||
this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null })
|
this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null })
|
||||||
})
|
})
|
||||||
this.pushSyncConfig()
|
this.pushServerSideStorage()
|
||||||
},
|
},
|
||||||
updateFilter(id, field, value) {
|
updateFilter(id, field, value) {
|
||||||
const filter = { ...this.muteFiltersDraftObject[id] }
|
const filter = { ...this.muteFiltersDraftObject[id] }
|
||||||
|
|
@ -256,7 +253,7 @@ const FilteringTab = {
|
||||||
path: 'simple.muteFilters.' + id,
|
path: 'simple.muteFilters.' + id,
|
||||||
value: this.muteFiltersDraftObject[id],
|
value: this.muteFiltersDraftObject[id],
|
||||||
})
|
})
|
||||||
this.pushSyncConfig()
|
this.pushServerSideStorage()
|
||||||
this.muteFiltersDraftDirty[id] = false
|
this.muteFiltersDraftDirty[id] = false
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="blockExpirationSupported">
|
<li v-if="blockExpiration">
|
||||||
<span class="setting-item">
|
<span class="setting-item">
|
||||||
<span class="setting-label">
|
<span class="setting-label">
|
||||||
{{ $t('user_card.default_block_expiration') }}
|
{{ $t('user_card.default_block_expiration') }}
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,11 @@ import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
import UnitSetting from '../helpers/unit_setting.vue'
|
import UnitSetting from '../helpers/unit_setting.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
|
|
||||||
import localeService from 'src/services/locale/locale.service.js'
|
import localeService from 'src/services/locale/locale.service.js'
|
||||||
|
|
||||||
const GeneralTab = {
|
const GeneralTab = {
|
||||||
props: {
|
|
||||||
parentCollapsed: {
|
|
||||||
required: true,
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
absoluteTime12hOptions: ['24h', '12h'].map((mode) => ({
|
absoluteTime12hOptions: ['24h', '12h'].map((mode) => ({
|
||||||
|
|
@ -43,23 +37,17 @@ const GeneralTab = {
|
||||||
computed: {
|
computed: {
|
||||||
language: {
|
language: {
|
||||||
get: function () {
|
get: function () {
|
||||||
return useSyncConfigStore().mergedConfig.interfaceLanguage
|
return this.$store.getters.mergedConfig.interfaceLanguage
|
||||||
},
|
},
|
||||||
set: function (val) {
|
set: function (val) {
|
||||||
useSyncConfigStore().setPreference({
|
this.$store.dispatch('setOption', {
|
||||||
path: 'simple.interfaceLanguage',
|
name: 'interfaceLanguage',
|
||||||
value: val,
|
value: val,
|
||||||
})
|
})
|
||||||
useSyncConfigStore().pushSyncConfig()
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
...SharedComputedObject(),
|
...SharedComputedObject(),
|
||||||
...mapState(useSyncConfigStore, {
|
...mapState(useInstanceCapabilitiesStore, ['blockExpiration']),
|
||||||
theme3hacks: (store) => store.mergedConfig.theme3hacks,
|
|
||||||
}),
|
|
||||||
...mapState(useInstanceStore, {
|
|
||||||
blockExpirationSupported: (store) => store.featureSet.blockExpiration,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateProfile() {
|
updateProfile() {
|
||||||
|
|
@ -77,9 +65,15 @@ const GeneralTab = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
updateFont(key, value) {
|
updateFont(key, value) {
|
||||||
useSyncConfigStore().setPreference({
|
this.$store.dispatch('setOption', {
|
||||||
path: `simple.theme3hacks.fonts.${key}`,
|
name: 'theme3hacks',
|
||||||
value,
|
value: {
|
||||||
|
...this.mergedConfig.theme3hacks,
|
||||||
|
fonts: {
|
||||||
|
...this.mergedConfig.theme3hacks.fonts,
|
||||||
|
[key]: value,
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@
|
||||||
</BooleanSetting>
|
</BooleanSetting>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
v-if="!blockExpirationSupported"
|
v-if="!blockExpiration"
|
||||||
>
|
>
|
||||||
<BooleanSetting
|
<BooleanSetting
|
||||||
path="modalOnBlock"
|
path="modalOnBlock"
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,14 @@
|
||||||
|
import { mapState } from 'pinia'
|
||||||
|
|
||||||
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'
|
||||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
import UnitSetting from '../helpers/unit_setting.vue'
|
import UnitSetting from '../helpers/unit_setting.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
const GeneralTab = {
|
const GeneralTab = {
|
||||||
props: {
|
|
||||||
parentCollapsed: {
|
|
||||||
required: true,
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
thirdColumnModeOptions: ['none', 'notifications', 'postform'].map(
|
thirdColumnModeOptions: ['none', 'notifications', 'postform'].map(
|
||||||
|
|
@ -32,19 +27,17 @@ const GeneralTab = {
|
||||||
ProfileSettingIndicator,
|
ProfileSettingIndicator,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
postFormats() {
|
...mapState(useInstanceCapabilitiesStore, [
|
||||||
return useInstanceStore().postFormats || []
|
'postFormats',
|
||||||
},
|
'suggestionsEnabled',
|
||||||
instanceShoutboxPresent() {
|
]),
|
||||||
return useInstanceStore().shoutAvailable
|
|
||||||
},
|
|
||||||
columns() {
|
columns() {
|
||||||
const mode = useSyncConfigStore().mergedConfig.thirdColumnMode
|
const mode = this.$store.getters.mergedConfig.thirdColumnMode
|
||||||
|
|
||||||
const notif = mode === 'none' ? [] : ['notifs']
|
const notif = mode === 'none' ? [] : ['notifs']
|
||||||
|
|
||||||
if (
|
if (
|
||||||
useSyncConfigStore().mergedConfig.sidebarRight ||
|
this.$store.getters.mergedConfig.sidebarRight ||
|
||||||
mode === 'postform'
|
mode === 'postform'
|
||||||
) {
|
) {
|
||||||
return [...notif, 'content', 'sidebar']
|
return [...notif, 'content', 'sidebar']
|
||||||
|
|
|
||||||
|
|
@ -69,11 +69,6 @@
|
||||||
{{ $t('settings.show_scrollbars') }}
|
{{ $t('settings.show_scrollbars') }}
|
||||||
</BooleanSetting>
|
</BooleanSetting>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="instanceSpecificPanelPresent">
|
|
||||||
<BooleanSetting path="hideISP">
|
|
||||||
{{ $t('settings.hide_isp') }}
|
|
||||||
</BooleanSetting>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<UnitSetting
|
<UnitSetting
|
||||||
path="panelHeaderSize"
|
path="panelHeaderSize"
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,7 @@ 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 { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useOAuthTokensStore } from 'src/stores/oauth_tokens'
|
import { useOAuthTokensStore } from 'src/stores/oauth_tokens.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
const BlockList = withLoadMore({
|
const BlockList = withLoadMore({
|
||||||
fetch: (props, $store) => $store.dispatch('fetchBlocks'),
|
fetch: (props, $store) => $store.dispatch('fetchBlocks'),
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@ import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
|
||||||
import Preview from './theme_preview.vue'
|
import Preview from './theme_preview.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getContrastRatioLayers,
|
getContrastRatioLayers,
|
||||||
|
|
@ -82,7 +81,7 @@ export default {
|
||||||
}),
|
}),
|
||||||
availableStyles: [],
|
availableStyles: [],
|
||||||
selected: '',
|
selected: '',
|
||||||
selectedTheme: useSyncConfigStore().mergedConfig.theme,
|
selectedTheme: this.$store.getters.mergedConfig.theme,
|
||||||
themeWarning: undefined,
|
themeWarning: undefined,
|
||||||
tempImportFile: undefined,
|
tempImportFile: undefined,
|
||||||
engineVersion: 0,
|
engineVersion: 0,
|
||||||
|
|
@ -129,7 +128,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
const currentIndex = useInstanceStore().instanceThemesIndex
|
const currentIndex = useInstanceStore().themesIndex
|
||||||
|
|
||||||
let promise
|
let promise
|
||||||
if (currentIndex) {
|
if (currentIndex) {
|
||||||
|
|
@ -138,8 +137,8 @@ export default {
|
||||||
promise = useInterfaceStore().fetchThemesIndex()
|
promise = useInterfaceStore().fetchThemesIndex()
|
||||||
}
|
}
|
||||||
|
|
||||||
promise.then((instanceThemesIndex) => {
|
promise.then((themesIndex) => {
|
||||||
Object.values(instanceThemesIndex).forEach((themeFunc) => {
|
Object.values(themesIndex).forEach((themeFunc) => {
|
||||||
themeFunc().then(
|
themeFunc().then(
|
||||||
(themeData) => themeData && this.availableStyles.push(themeData),
|
(themeData) => themeData && this.availableStyles.push(themeData),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,6 @@ import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
|
||||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
|
|
||||||
const GeneralTab = {
|
const GeneralTab = {
|
||||||
props: {
|
|
||||||
parentCollapsed: {
|
|
||||||
required: true,
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
conversationDisplayOptions: ['tree', 'linear'].map((mode) => ({
|
conversationDisplayOptions: ['tree', 'linear'].map((mode) => ({
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import ProgressButton from 'src/components/progress_button/progress_button.vue'
|
||||||
import Mfa from './mfa.vue'
|
import Mfa from './mfa.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
import { useOAuthTokensStore } from 'src/stores/oauth_tokens'
|
import { useOAuthTokensStore } from 'src/stores/oauth_tokens'
|
||||||
|
|
||||||
import localeService from 'src/services/locale/locale.service.js'
|
import localeService from 'src/services/locale/locale.service.js'
|
||||||
|
|
@ -45,7 +46,7 @@ const SecurityTab = {
|
||||||
return this.$store.state.users.currentUser
|
return this.$store.state.users.currentUser
|
||||||
},
|
},
|
||||||
pleromaExtensionsAvailable() {
|
pleromaExtensionsAvailable() {
|
||||||
return useInstanceStore().pleromaExtensionsAvailable
|
return useInstanceCapabilitiesStore().pleromaExtensionsAvailable
|
||||||
},
|
},
|
||||||
oauthTokens() {
|
oauthTokens() {
|
||||||
return useOAuthTokensStore().tokens.map((oauthToken) => {
|
return useOAuthTokensStore().tokens.map((oauthToken) => {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import Preview from '../old_theme_tab/theme_preview.vue'
|
||||||
import VirtualDirectivesTab from './virtual_directives_tab.vue'
|
import VirtualDirectivesTab from './virtual_directives_tab.vue'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config'
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getContrastRatio,
|
getContrastRatio,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useShoutStore } from 'src/stores/shout'
|
import { useShoutStore } from 'src/stores/shout.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'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { mapState as mapPiniaState } from 'pinia'
|
import { mapActions, mapState } from 'pinia'
|
||||||
import { mapGetters, mapState } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
import { USERNAME_ROUTES } from 'src/components/navigation/navigation.js'
|
import { USERNAME_ROUTES } from 'src/components/navigation/navigation.js'
|
||||||
import GestureService from '../../services/gesture_service/gesture_service'
|
import GestureService from '../../services/gesture_service/gesture_service'
|
||||||
|
|
@ -8,6 +8,7 @@ import UserCard from '../user_card/user_card.vue'
|
||||||
|
|
||||||
import { useAnnouncementsStore } from 'src/stores/announcements'
|
import { useAnnouncementsStore } from 'src/stores/announcements'
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.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'
|
||||||
|
|
||||||
|
|
@ -76,27 +77,9 @@ const SideDrawer = {
|
||||||
unseenNotificationsCount() {
|
unseenNotificationsCount() {
|
||||||
return this.unseenNotifications.length
|
return this.unseenNotifications.length
|
||||||
},
|
},
|
||||||
suggestionsEnabled() {
|
|
||||||
return useInstanceStore().suggestionsEnabled
|
|
||||||
},
|
|
||||||
logo() {
|
|
||||||
return useInstanceStore().logo
|
|
||||||
},
|
|
||||||
hideSitename() {
|
|
||||||
return useInstanceStore().hideSitename
|
|
||||||
},
|
|
||||||
sitename() {
|
|
||||||
return useInstanceStore().name
|
|
||||||
},
|
|
||||||
followRequestCount() {
|
followRequestCount() {
|
||||||
return this.$store.state.api.followRequests.length
|
return this.$store.state.api.followRequests.length
|
||||||
},
|
},
|
||||||
privateMode() {
|
|
||||||
return useInstanceStore().private
|
|
||||||
},
|
|
||||||
federating() {
|
|
||||||
return useInstanceStore().federating
|
|
||||||
},
|
|
||||||
timelinesRoute() {
|
timelinesRoute() {
|
||||||
let name
|
let name
|
||||||
if (useInterfaceStore().lastTimeline) {
|
if (useInterfaceStore().lastTimeline) {
|
||||||
|
|
@ -109,13 +92,19 @@ const SideDrawer = {
|
||||||
return { name }
|
return { name }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
...mapPiniaState(useAnnouncementsStore, {
|
...mapState(useAnnouncementsStore, [
|
||||||
supportsAnnouncements: (store) => store.supportsAnnouncements,
|
'supportsAnnouncements',
|
||||||
unreadAnnouncementCount: 'unreadAnnouncementCount',
|
'unreadAnnouncementCount',
|
||||||
}),
|
]),
|
||||||
...mapState({
|
...mapState(useInstanceCapabilitiesStore, [
|
||||||
pleromaChatMessagesAvailable: (state) =>
|
'pleromaChatMessagesAvailable',
|
||||||
state.instance.pleromaChatMessagesAvailable,
|
'suggestionsEnabled',
|
||||||
|
]),
|
||||||
|
...mapState(useInstanceStore, ['privateMode', 'federating']),
|
||||||
|
...mapState(useInstanceStore, {
|
||||||
|
logo: (store) => store.instanceIdentity.logo,
|
||||||
|
sitename: (store) => store.instanceIdentity.name,
|
||||||
|
hideSitename: (store) => store.instanceIdentity.hideSitename,
|
||||||
}),
|
}),
|
||||||
...mapGetters(['unreadChatCount', 'draftCount']),
|
...mapGetters(['unreadChatCount', 'draftCount']),
|
||||||
},
|
},
|
||||||
|
|
@ -133,12 +122,7 @@ const SideDrawer = {
|
||||||
touchMove(e) {
|
touchMove(e) {
|
||||||
GestureService.updateSwipe(e, this.closeGesture)
|
GestureService.updateSwipe(e, this.closeGesture)
|
||||||
},
|
},
|
||||||
openSettingsModal() {
|
...mapActions(useInterfaceStore, ['openSettingsModal']),
|
||||||
useInterfaceStore().openSettingsModal('user')
|
|
||||||
},
|
|
||||||
openAdminModal() {
|
|
||||||
useInterfaceStore().openSettingsModal('admin')
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,7 @@
|
||||||
<li @click="toggleDrawer">
|
<li @click="toggleDrawer">
|
||||||
<button
|
<button
|
||||||
class="menu-item"
|
class="menu-item"
|
||||||
@click="openSettingsModal"
|
@click="openSettingsModal('user')"
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
|
|
@ -225,7 +225,7 @@
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="menu-item"
|
class="menu-item"
|
||||||
@click.stop="openAdminModal"
|
@click.stop="openSettingsModal('admin')"
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ const StaffPanel = {
|
||||||
},
|
},
|
||||||
...mapGetters(['findUserByName']),
|
...mapGetters(['findUserByName']),
|
||||||
...mapState({
|
...mapState({
|
||||||
staffAccounts: (state) => state.instance.staffAccounts,
|
staffAccounts: (state) => useInstanceStore().staffAccounts,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { unescape as ldUnescape, uniqBy } from 'lodash'
|
import { unescape as ldUnescape, uniqBy } from 'lodash'
|
||||||
import { mapState } from 'pinia'
|
|
||||||
|
|
||||||
import MentionLink from 'src/components/mention_link/mention_link.vue'
|
import MentionLink from 'src/components/mention_link/mention_link.vue'
|
||||||
import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
|
import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
|
||||||
|
|
@ -22,7 +21,8 @@ import UserListPopover from '../user_list_popover/user_list_popover.vue'
|
||||||
import UserPopover from '../user_popover/user_popover.vue'
|
import UserPopover from '../user_popover/user_popover.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
|
import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
|
||||||
|
|
||||||
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'
|
||||||
|
|
||||||
|
|
@ -258,7 +258,12 @@ const Status = {
|
||||||
return !!this.currentUser
|
return !!this.currentUser
|
||||||
},
|
},
|
||||||
muteFilterHits() {
|
muteFilterHits() {
|
||||||
return muteFilterHits(Object.values(this.muteFilters), this.status)
|
return muteFilterHits(
|
||||||
|
Object.values(
|
||||||
|
useServerSideStorageStore().prefsStorage.simple.muteFilters,
|
||||||
|
),
|
||||||
|
this.status,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
botStatus() {
|
botStatus() {
|
||||||
return this.status.user.actor_type === 'Service'
|
return this.status.user.actor_type === 'Service'
|
||||||
|
|
@ -451,6 +456,9 @@ const Status = {
|
||||||
.map((tagObj) => tagObj.name)
|
.map((tagObj) => tagObj.name)
|
||||||
.join(' ')
|
.join(' ')
|
||||||
},
|
},
|
||||||
|
hidePostStats() {
|
||||||
|
return this.mergedConfig.hidePostStats
|
||||||
|
},
|
||||||
shouldDisplayFavsAndRepeats() {
|
shouldDisplayFavsAndRepeats() {
|
||||||
return (
|
return (
|
||||||
!this.hidePostStats &&
|
!this.hidePostStats &&
|
||||||
|
|
@ -472,7 +480,7 @@ const Status = {
|
||||||
return this.$store.state.users.currentUser
|
return this.$store.state.users.currentUser
|
||||||
},
|
},
|
||||||
mergedConfig() {
|
mergedConfig() {
|
||||||
return useSyncConfigStore().mergedConfig
|
return this.$store.getters.mergedConfig
|
||||||
},
|
},
|
||||||
isSuspendable() {
|
isSuspendable() {
|
||||||
return !this.replying && this.mediaPlaying.length === 0
|
return !this.replying && this.mediaPlaying.length === 0
|
||||||
|
|
@ -490,7 +498,7 @@ const Status = {
|
||||||
return this.status.edited_at !== null
|
return this.status.edited_at !== null
|
||||||
},
|
},
|
||||||
editingAvailable() {
|
editingAvailable() {
|
||||||
return useInstanceStore().editingAvailable
|
return useInstanceCapabilitiesStore().editingAvailable
|
||||||
},
|
},
|
||||||
hasVisibleQuote() {
|
hasVisibleQuote() {
|
||||||
return this.status.quote_url && this.status.quote_visible
|
return this.status.quote_url && this.status.quote_visible
|
||||||
|
|
@ -507,10 +515,10 @@ const Status = {
|
||||||
return this.quotedStatus && this.displayQuote
|
return this.quotedStatus && this.displayQuote
|
||||||
},
|
},
|
||||||
scrobblePresent() {
|
scrobblePresent() {
|
||||||
if (this.hideScrobbles) return false
|
if (this.mergedConfig.hideScrobbles) return false
|
||||||
if (!this.status.user?.latestScrobble) return false
|
if (!this.status.user?.latestScrobble) return false
|
||||||
const value = this.hideScrobblesAfter.match(/\d+/gs)[0]
|
const value = this.mergedConfig.hideScrobblesAfter.match(/\d+/gs)[0]
|
||||||
const unit = this.hideScrobblesAfter.match(/\D+/gs)[0]
|
const unit = this.mergedConfig.hideScrobblesAfter.match(/\D+/gs)[0]
|
||||||
let multiplier = 60 * 1000 // minutes is smallest unit
|
let multiplier = 60 * 1000 // minutes is smallest unit
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
case 'm':
|
case 'm':
|
||||||
|
|
@ -532,13 +540,6 @@ const Status = {
|
||||||
scrobble() {
|
scrobble() {
|
||||||
return this.status.user?.latestScrobble
|
return this.status.user?.latestScrobble
|
||||||
},
|
},
|
||||||
...mapState(useSyncConfigStore, {
|
|
||||||
muteFilters: (store) => store.prefsStorage.simple.muteFilters,
|
|
||||||
hideBotIndicatior: (store) => store.prefsStorage.simple.hideBotIndicator,
|
|
||||||
hidePostStats: (store) => store.mergedConfig.hidePostStats,
|
|
||||||
hideScrobbles: (store) => store.mergedConfig.hideScrobbles,
|
|
||||||
hideScrobblesAfter: (store) => store.mergedConfig.hideScrobblesAfter,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
visibilityIcon(visibility) {
|
visibilityIcon(visibility) {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ 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 { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -93,7 +94,8 @@ export default {
|
||||||
return this.status.thread_muted
|
return this.status.thread_muted
|
||||||
},
|
},
|
||||||
hideCustomEmoji() {
|
hideCustomEmoji() {
|
||||||
return !useInstanceStore().pleromaCustomEmojiReactionsAvailable
|
return !useInstanceCapabilitiesStore()
|
||||||
|
.pleromaCustomEmojiReactionsAvailable
|
||||||
},
|
},
|
||||||
buttonInnerClass() {
|
buttonInnerClass() {
|
||||||
return [
|
return [
|
||||||
|
|
@ -109,7 +111,7 @@ export default {
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
remoteInteractionLink() {
|
remoteInteractionLink() {
|
||||||
return this.$store.getters.remoteInteractionLink({
|
return useInstanceStore().getRemoteInteractionLink({
|
||||||
statusId: this.status.id,
|
statusId: this.status.id,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import { useEditStatusStore } from 'src/stores/editStatus.js'
|
import { useEditStatusStore } from 'src/stores/editStatus.js'
|
||||||
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.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'
|
||||||
|
|
||||||
|
|
@ -49,8 +51,8 @@ export const BUTTONS = [
|
||||||
(currentUser.id === status.user.id ||
|
(currentUser.id === status.user.id ||
|
||||||
!PRIVATE_SCOPES.has(status.visibility)),
|
!PRIVATE_SCOPES.has(status.visibility)),
|
||||||
toggleable: true,
|
toggleable: true,
|
||||||
confirm: ({ status, mergedConfig }) =>
|
confirm: ({ status, getters }) =>
|
||||||
!status.repeated && mergedConfig.modalOnRepeat,
|
!status.repeated && getters.mergedConfig.modalOnRepeat,
|
||||||
confirmStrings: {
|
confirmStrings: {
|
||||||
title: 'status.repeat_confirm_title',
|
title: 'status.repeat_confirm_title',
|
||||||
body: 'status.repeat_confirm',
|
body: 'status.repeat_confirm',
|
||||||
|
|
@ -158,8 +160,11 @@ export const BUTTONS = [
|
||||||
name: 'editHistory',
|
name: 'editHistory',
|
||||||
icon: 'history',
|
icon: 'history',
|
||||||
label: 'status.status_history',
|
label: 'status.status_history',
|
||||||
if({ status, instance }) {
|
if({ status, state }) {
|
||||||
return instance.featureSet.editingAvailable && status.edited_at !== null
|
return (
|
||||||
|
useInstanceCapabilitiesStore().editingAvailable &&
|
||||||
|
status.edited_at !== null
|
||||||
|
)
|
||||||
},
|
},
|
||||||
action({ status }) {
|
action({ status }) {
|
||||||
const originalStatus = { ...status }
|
const originalStatus = { ...status }
|
||||||
|
|
@ -186,10 +191,10 @@ export const BUTTONS = [
|
||||||
name: 'edit',
|
name: 'edit',
|
||||||
icon: 'pen',
|
icon: 'pen',
|
||||||
label: 'status.edit',
|
label: 'status.edit',
|
||||||
if({ status, loggedIn, currentUser, instance }) {
|
if({ status, loggedIn, currentUser, state }) {
|
||||||
return (
|
return (
|
||||||
loggedIn &&
|
loggedIn &&
|
||||||
instance.featureSet.editingAvailable &&
|
useInstanceCapabilitiesStore().editingAvailable &&
|
||||||
status.user.id === currentUser.id
|
status.user.id === currentUser.id
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -222,7 +227,7 @@ export const BUTTONS = [
|
||||||
currentUser.privileges.includes('messages_delete'))
|
currentUser.privileges.includes('messages_delete'))
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
confirm: ({ mergedConfig }) => mergedConfig.modalOnDelete,
|
confirm: ({ getters }) => getters.mergedConfig.modalOnDelete,
|
||||||
confirmStrings: {
|
confirmStrings: {
|
||||||
title: 'status.delete_confirm_title',
|
title: 'status.delete_confirm_title',
|
||||||
body: 'status.delete_confirm',
|
body: 'status.delete_confirm',
|
||||||
|
|
@ -240,10 +245,10 @@ export const BUTTONS = [
|
||||||
name: 'share',
|
name: 'share',
|
||||||
icon: 'share-alt',
|
icon: 'share-alt',
|
||||||
label: 'status.copy_link',
|
label: 'status.copy_link',
|
||||||
action({ instance, status, router }) {
|
action({ state, status, router }) {
|
||||||
navigator.clipboard.writeText(
|
navigator.clipboard.writeText(
|
||||||
[
|
[
|
||||||
instance.server,
|
useInstanceStore().server,
|
||||||
router.resolve({ name: 'conversation', params: { id: status.id } })
|
router.resolve({ name: 'conversation', params: { id: status.id } })
|
||||||
.href,
|
.href,
|
||||||
].join(''),
|
].join(''),
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ import Popover from 'src/components/popover/popover.vue'
|
||||||
import ActionButtonContainer from './action_button_container.vue'
|
import ActionButtonContainer from './action_button_container.vue'
|
||||||
import { BUTTONS } from './buttons_definitions.js'
|
import { BUTTONS } from './buttons_definitions.js'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useServerSideStorageStore } from 'src/stores/serverSideStorage.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import genRandomSeed from 'src/services/random_seed/random_seed.service.js'
|
import genRandomSeed from 'src/services/random_seed/random_seed.service.js'
|
||||||
|
|
||||||
|
|
@ -37,7 +36,7 @@ const StatusActionButtons = {
|
||||||
ActionButtonContainer,
|
ActionButtonContainer,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useSyncConfigStore, {
|
...mapState(useServerSideStorageStore, {
|
||||||
pinnedItems: (store) =>
|
pinnedItems: (store) =>
|
||||||
new Set(store.prefsStorage.collections.pinnedStatusActions),
|
new Set(store.prefsStorage.collections.pinnedStatusActions),
|
||||||
}),
|
}),
|
||||||
|
|
@ -59,8 +58,8 @@ const StatusActionButtons = {
|
||||||
replying: this.replying,
|
replying: this.replying,
|
||||||
emit: this.$emit,
|
emit: this.$emit,
|
||||||
dispatch: this.$store.dispatch,
|
dispatch: this.$store.dispatch,
|
||||||
instance: useInstanceStore(),
|
state: this.$store.state,
|
||||||
mergedConfig: useSyncConfigStore().mergedConfig,
|
getters: this.$store.getters,
|
||||||
router: this.$router,
|
router: this.$router,
|
||||||
currentUser: this.currentUser,
|
currentUser: this.currentUser,
|
||||||
loggedIn: !!this.currentUser,
|
loggedIn: !!this.currentUser,
|
||||||
|
|
@ -112,18 +111,18 @@ const StatusActionButtons = {
|
||||||
return this.pinnedItems.has(button.name)
|
return this.pinnedItems.has(button.name)
|
||||||
},
|
},
|
||||||
unpin(button) {
|
unpin(button) {
|
||||||
useSyncConfigStore().removeCollectionPreference({
|
useServerSideStorageStore().removeCollectionPreference({
|
||||||
path: 'collections.pinnedStatusActions',
|
path: 'collections.pinnedStatusActions',
|
||||||
value: button.name,
|
value: button.name,
|
||||||
})
|
})
|
||||||
useSyncConfigStore().pushSyncConfig()
|
useServerSideStorageStore().pushServerSideStorage()
|
||||||
},
|
},
|
||||||
pin(button) {
|
pin(button) {
|
||||||
useSyncConfigStore().addCollectionPreference({
|
useServerSideStorageStore().addCollectionPreference({
|
||||||
path: 'collections.pinnedStatusActions',
|
path: 'collections.pinnedStatusActions',
|
||||||
value: button.name,
|
value: button.name,
|
||||||
})
|
})
|
||||||
useSyncConfigStore().pushSyncConfig()
|
useServerSideStorageStore().pushServerSideStorage()
|
||||||
},
|
},
|
||||||
getComponent(button) {
|
getComponent(button) {
|
||||||
if (!this.$store.state.users.currentUser && button.anonLink) {
|
if (!this.$store.state.users.currentUser && button.anonLink) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import { mapState } from 'pinia'
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
||||||
|
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import fileType from 'src/services/file_type/file_type.service'
|
import fileType from 'src/services/file_type/file_type.service'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
|
@ -112,7 +110,7 @@ const StatusBody = {
|
||||||
collapsedStatus() {
|
collapsedStatus() {
|
||||||
return this.status.raw_html.replace(/(\n|<br\s?\/?>)/g, ' ')
|
return this.status.raw_html.replace(/(\n|<br\s?\/?>)/g, ' ')
|
||||||
},
|
},
|
||||||
...mapState(useSyncConfigStore, ['mergedConfig']),
|
...mapGetters(['mergedConfig']),
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
RichContent,
|
RichContent,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { mapState } from 'pinia'
|
||||||
import Popover from 'src/components/popover/popover.vue'
|
import Popover from 'src/components/popover/popover.vue'
|
||||||
import StillImage from 'src/components/still-image/still-image.vue'
|
import StillImage from 'src/components/still-image/still-image.vue'
|
||||||
|
|
||||||
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
|
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faChevronRight, faFolder } from '@fortawesome/free-solid-svg-icons'
|
import { faChevronRight, faFolder } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { mapState as mapPiniaState } from 'pinia'
|
|
||||||
import { mapGetters, mapState } from 'vuex'
|
import { mapGetters, mapState } from 'vuex'
|
||||||
|
|
||||||
import StatusBody from 'src/components/status_body/status_body.vue'
|
import StatusBody from 'src/components/status_body/status_body.vue'
|
||||||
|
|
@ -7,8 +6,7 @@ import Gallery from '../gallery/gallery.vue'
|
||||||
import LinkPreview from '../link-preview/link-preview.vue'
|
import LinkPreview from '../link-preview/link-preview.vue'
|
||||||
import Poll from '../poll/poll.vue'
|
import Poll from '../poll/poll.vue'
|
||||||
|
|
||||||
import { useMediaViewerStore } from 'src/stores/media_viewer'
|
import { useMediaViewerStore } from 'src/stores/media_viewer.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -76,7 +74,7 @@ const StatusContent = {
|
||||||
uncontrolledShowingLongSubject: false,
|
uncontrolledShowingLongSubject: false,
|
||||||
// not as computed because it sets the initial state which will be changed later
|
// not as computed because it sets the initial state which will be changed later
|
||||||
uncontrolledExpandingSubject:
|
uncontrolledExpandingSubject:
|
||||||
!useSyncConfigStore().mergedConfig.collapseMessageWithSubject,
|
!this.$store.getters.mergedConfig.collapseMessageWithSubject,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -93,8 +91,8 @@ const StatusContent = {
|
||||||
},
|
},
|
||||||
hideAttachments() {
|
hideAttachments() {
|
||||||
return (
|
return (
|
||||||
(this.hideAttachments && !this.inConversation) ||
|
(this.mergedConfig.hideAttachments && !this.inConversation) ||
|
||||||
(this.hideAttachmentsInConv && this.inConversation)
|
(this.mergedConfig.hideAttachmentsInConv && this.inConversation)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
nsfwClickthrough() {
|
nsfwClickthrough() {
|
||||||
|
|
@ -106,29 +104,28 @@ const StatusContent = {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
|
localCollapseSubjectDefault() {
|
||||||
|
return this.mergedConfig.collapseMessageWithSubject
|
||||||
|
},
|
||||||
attachmentSize() {
|
attachmentSize() {
|
||||||
if (this.compact) {
|
if (this.compact) {
|
||||||
return 'small'
|
return 'small'
|
||||||
} else if (
|
} else if (
|
||||||
(this.hideAttachments && !this.inConversation) ||
|
(this.mergedConfig.hideAttachments && !this.inConversation) ||
|
||||||
(this.hideAttachmentsInConv && this.inConversation) ||
|
(this.mergedConfig.hideAttachmentsInConv && this.inConversation) ||
|
||||||
this.status.attachments.length > this.maxThumbnails
|
this.status.attachments.length > this.maxThumbnails
|
||||||
) {
|
) {
|
||||||
return 'hide'
|
return 'hide'
|
||||||
}
|
}
|
||||||
return 'normal'
|
return 'normal'
|
||||||
},
|
},
|
||||||
|
maxThumbnails() {
|
||||||
|
return this.mergedConfig.maxThumbnails
|
||||||
|
},
|
||||||
|
...mapGetters(['mergedConfig']),
|
||||||
...mapState({
|
...mapState({
|
||||||
currentUser: (state) => state.users.currentUser,
|
currentUser: (state) => state.users.currentUser,
|
||||||
}),
|
}),
|
||||||
...mapPiniaState(useSyncConfigStore, {
|
|
||||||
localCollapseSubjectDefault: (store) =>
|
|
||||||
store.mergedConfig.collapseMessageWithSubject,
|
|
||||||
maxThumbnails: (store) => store.mergedConfig.maxThumbnails,
|
|
||||||
hideAttachments: (store) => store.mergedConfig.hideAttachments,
|
|
||||||
hideAttachmentsInConv: (store) =>
|
|
||||||
store.prefsStorage.simple.hideAttachmentsInConv,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Attachment,
|
Attachment,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { get } from 'lodash'
|
||||||
import Modal from '../modal/modal.vue'
|
import Modal from '../modal/modal.vue'
|
||||||
import Status from '../status/status.vue'
|
import Status from '../status/status.vue'
|
||||||
|
|
||||||
import { useStatusHistoryStore } from 'src/stores/statusHistory'
|
import { useStatusHistoryStore } from 'src/stores/statusHistory.js'
|
||||||
|
|
||||||
const StatusHistoryModal = {
|
const StatusHistoryModal = {
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
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'
|
||||||
|
|
||||||
|
import { useEmojiStore } from 'src/stores/emoji.js'
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
|
||||||
const StickerPicker = {
|
const StickerPicker = {
|
||||||
|
|
@ -19,7 +20,7 @@ const StickerPicker = {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
pack() {
|
pack() {
|
||||||
return useInstanceStore().stickers || []
|
return useEmojiStore().stickers || []
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,135 @@
|
||||||
</Popover>
|
</Popover>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./still-image-emoji-popover.js" />
|
<script>
|
||||||
|
import Popover from 'components/popover/popover.vue'
|
||||||
|
import SelectComponent from 'components/select/select.vue'
|
||||||
|
import { assign } from 'lodash'
|
||||||
|
|
||||||
|
import StillImage from './still-image.vue'
|
||||||
|
|
||||||
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { StillImage, Popover, SelectComponent },
|
||||||
|
props: {
|
||||||
|
shortcode: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
isLocal: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
knownLocalPacks: {},
|
||||||
|
packName: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isUserAdmin() {
|
||||||
|
return this.$store.state.users.currentUser.rights.admin
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
displayError(msg) {
|
||||||
|
useInterfaceStore().pushGlobalNotice({
|
||||||
|
messageKey: 'admin_dash.emoji.error',
|
||||||
|
messageArgs: [msg],
|
||||||
|
level: 'error',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
copyToLocalPack() {
|
||||||
|
this.$store.state.api.backendInteractor
|
||||||
|
.addNewEmojiFile({
|
||||||
|
packName: this.packName,
|
||||||
|
file: this.$attrs.src,
|
||||||
|
shortcode: this.shortcode,
|
||||||
|
filename: '',
|
||||||
|
})
|
||||||
|
.then((resp) => resp.json())
|
||||||
|
.then((resp) => {
|
||||||
|
if (resp.error !== undefined) {
|
||||||
|
this.displayError(resp.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
useInterfaceStore().pushGlobalNotice({
|
||||||
|
messageKey: 'admin_dash.emoji.copied_successfully',
|
||||||
|
messageArgs: [this.shortcode, this.packName],
|
||||||
|
level: 'success',
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$refs.emojiPopover.hidePopover()
|
||||||
|
this.packName = ''
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// Copied from emoji_tab.js
|
||||||
|
loadPacksPaginated(listFunction) {
|
||||||
|
const pageSize = 25
|
||||||
|
const allPacks = {}
|
||||||
|
|
||||||
|
return listFunction({
|
||||||
|
instance: useInstanceStore().server,
|
||||||
|
page: 1,
|
||||||
|
pageSize: 0,
|
||||||
|
})
|
||||||
|
.then((data) => data.json())
|
||||||
|
.then((data) => {
|
||||||
|
if (data.error !== undefined) {
|
||||||
|
return Promise.reject(data.error)
|
||||||
|
}
|
||||||
|
|
||||||
|
let resultingPromise = Promise.resolve({})
|
||||||
|
for (let i = 0; i < Math.ceil(data.count / pageSize); i++) {
|
||||||
|
resultingPromise = resultingPromise
|
||||||
|
.then(() =>
|
||||||
|
listFunction({
|
||||||
|
instance: useInstanceStore().server,
|
||||||
|
page: i,
|
||||||
|
pageSize,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.then((data) => data.json())
|
||||||
|
.then((pageData) => {
|
||||||
|
if (pageData.error !== undefined) {
|
||||||
|
return Promise.reject(pageData.error)
|
||||||
|
}
|
||||||
|
|
||||||
|
assign(allPacks, pageData.packs)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultingPromise
|
||||||
|
})
|
||||||
|
.then(() => allPacks)
|
||||||
|
.catch((data) => {
|
||||||
|
this.displayError(data)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
fetchEmojiPacksIfAdmin() {
|
||||||
|
if (!this.isUserAdmin) return
|
||||||
|
|
||||||
|
this.loadPacksPaginated(
|
||||||
|
this.$store.state.api.backendInteractor.listEmojiPacks,
|
||||||
|
).then((allPacks) => {
|
||||||
|
// Sort by key
|
||||||
|
const sorted = Object.keys(allPacks)
|
||||||
|
.sort()
|
||||||
|
.reduce((acc, key) => {
|
||||||
|
if (key.length === 0) return acc
|
||||||
|
acc[key] = allPacks[key]
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
this.knownLocalPacks = sorted
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.emoji-popover {
|
.emoji-popover {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
|
||||||
|
|
||||||
import './tab_switcher.scss'
|
import './tab_switcher.scss'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
|
||||||
const findFirstUsable = (slots) => slots.findIndex((_) => _.props)
|
const findFirstUsable = (slots) => slots.findIndex((_) => _.props)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
|
|
||||||
const TermsOfServicePanel = {
|
const TermsOfServicePanel = {
|
||||||
computed: mapState(useInstanceStore, {
|
computed: mapState(useInstanceStore, {
|
||||||
content: (state) => state.tos,
|
content: (store) => store.instanceIdentity.tos,
|
||||||
embedded: (state) => state.embeddedToS,
|
embedded: (store) => store.instanceIdentity.embeddedToS,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,7 @@ import ScrollTopButton from '../scroll_top_button/scroll_top_button.vue'
|
||||||
import Status from '../status/status.vue'
|
import Status from '../status/status.vue'
|
||||||
import TimelineMenu from '../timeline_menu/timeline_menu.vue'
|
import TimelineMenu from '../timeline_menu/timeline_menu.vue'
|
||||||
|
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
|
||||||
|
|
||||||
import timelineFetcher from 'src/services/timeline_fetcher/timeline_fetcher.service.js'
|
import timelineFetcher from 'src/services/timeline_fetcher/timeline_fetcher.service.js'
|
||||||
|
|
||||||
|
|
@ -127,7 +125,7 @@ const Timeline = {
|
||||||
return this.timeline.visibleStatuses.slice(min, max).map((_) => _.id)
|
return this.timeline.visibleStatuses.slice(min, max).map((_) => _.id)
|
||||||
},
|
},
|
||||||
virtualScrollingEnabled() {
|
virtualScrollingEnabled() {
|
||||||
return useSyncConfigStore().mergedConfig.virtualScrolling
|
return this.$store.getters.mergedConfig.virtualScrolling
|
||||||
},
|
},
|
||||||
...mapState(useInterfaceStore, {
|
...mapState(useInterfaceStore, {
|
||||||
mobileLayout: (store) => store.layoutType === 'mobile',
|
mobileLayout: (store) => store.layoutType === 'mobile',
|
||||||
|
|
@ -315,7 +313,7 @@ const Timeline = {
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
newStatusCount(count) {
|
newStatusCount(count) {
|
||||||
if (!useSyncConfigStore().mergedConfig.streaming) {
|
if (!this.$store.getters.mergedConfig.streaming) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
|
|
@ -325,9 +323,7 @@ const Timeline = {
|
||||||
if (
|
if (
|
||||||
top < 15 &&
|
top < 15 &&
|
||||||
!this.paused &&
|
!this.paused &&
|
||||||
!(
|
!(this.unfocused && this.$store.getters.mergedConfig.pauseOnUnfocused)
|
||||||
this.unfocused && useSyncConfigStore().mergedConfig.pauseOnUnfocused
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
this.showNewStatuses()
|
this.showNewStatuses()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue