Merge branch 'setttingssync' into shigusegubu-themes3
This commit is contained in:
commit
bb0656c505
7 changed files with 522 additions and 163 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
import { throttle } from 'lodash'
|
import { throttle } from 'lodash'
|
||||||
import { mapState } from 'pinia'
|
import { mapState } from 'pinia'
|
||||||
import { defineAsyncComponent } from 'vue'
|
import { defineAsyncComponent, toValue } from 'vue'
|
||||||
|
|
||||||
import DesktopNav from './components/desktop_nav/desktop_nav.vue'
|
import DesktopNav from './components/desktop_nav/desktop_nav.vue'
|
||||||
import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue'
|
import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue'
|
||||||
|
|
@ -32,6 +32,9 @@ import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
||||||
import messages from 'src/i18n/messages'
|
import messages from 'src/i18n/messages'
|
||||||
import localeService from 'src/services/locale/locale.service.js'
|
import localeService from 'src/services/locale/locale.service.js'
|
||||||
|
|
||||||
|
// Helper to unwrap reactive proxies
|
||||||
|
window.toValue = toValue
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@ import { useUserHighlightStore } from 'src/stores/user_highlight.js'
|
||||||
|
|
||||||
import VBodyScrollLock from 'src/directives/body_scroll_lock'
|
import VBodyScrollLock from 'src/directives/body_scroll_lock'
|
||||||
import {
|
import {
|
||||||
instanceDefaultConfig,
|
instanceDefaultConfigDefinitions,
|
||||||
staticOrApiConfigDefault,
|
instanceIdentityDefaultDefinitions,
|
||||||
} from 'src/modules/default_config_state.js'
|
} from 'src/modules/default_config_state.js'
|
||||||
|
|
||||||
let staticInitialResults = null
|
let staticInitialResults = null
|
||||||
|
|
@ -169,17 +169,21 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
|
||||||
config = Object.assign({}, staticConfig, apiConfig)
|
config = Object.assign({}, staticConfig, apiConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyInstanceOption = ({ source, destination }) => {
|
const copyInstanceOption = ({ source, definition = { required: true }, destination }) => {
|
||||||
if (typeof config[source] !== 'undefined') {
|
const value = config[source]
|
||||||
useInstanceStore().set({ path: destination, value: config[source] })
|
let { required, type, default: defaultValue } = definition
|
||||||
}
|
if (type == null && defaultValue != null) type = typeof defaultValue
|
||||||
|
if (required && value == null) return
|
||||||
|
if (type != null && typeof value !== type) return
|
||||||
|
|
||||||
|
useInstanceStore().set({ path: destination, value })
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(staticOrApiConfigDefault)
|
Object.entries(instanceIdentityDefaultDefinitions)
|
||||||
.map((k) => ({ source: k, destination: `instanceIdentity.${k}` }))
|
.map(([source, definition]) => ({ source, definition, destination: `instanceIdentity.${source}` }))
|
||||||
.forEach(copyInstanceOption)
|
.forEach(copyInstanceOption)
|
||||||
Object.keys(instanceDefaultConfig)
|
Object.keys(instanceDefaultConfigDefinitions)
|
||||||
.map((k) => ({ source: k, destination: `prefsStorage.${k}` }))
|
.map(([source, definition]) => ({ source, definition, destination: `prefsStorage.${source}` }))
|
||||||
.forEach(copyInstanceOption)
|
.forEach(copyInstanceOption)
|
||||||
|
|
||||||
useAuthFlowStore().setInitialStrategy(config.loginMethod)
|
useAuthFlowStore().setInitialStrategy(config.loginMethod)
|
||||||
|
|
|
||||||
|
|
@ -1,163 +1,514 @@
|
||||||
const browserLocale = (navigator.language || 'en').split('-')[0]
|
const browserLocale = (navigator.language || 'en').split('-')[0]
|
||||||
|
|
||||||
|
const convertDefinitions = definitions => Object.fromEntries(
|
||||||
|
Object.entries(definitions).map(([k, v]) => [
|
||||||
|
k,
|
||||||
|
v.default == null ? null : v.default,
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
|
||||||
/// Instance config entries provided by static config or pleroma api
|
/// Instance config entries provided by static config or pleroma api
|
||||||
/// Put settings here only if it does not make sense for a normal user
|
/// Put settings here only if it does not make sense for a normal user
|
||||||
/// to override it.
|
/// to override it.
|
||||||
export const staticOrApiConfigDefault = {
|
export const instanceIdentityDefaultDefinitions = {
|
||||||
name: 'PleromaFE',
|
style: {
|
||||||
theme: 'pleroma-dark',
|
description: 'Instance default style name',
|
||||||
palette: null,
|
type: 'string',
|
||||||
style: null,
|
required: false,
|
||||||
themeChecksum: undefined,
|
},
|
||||||
defaultAvatar: '/images/avi.png',
|
palette: {
|
||||||
defaultBanner: '/images/banner.png',
|
description: 'Instance default palette name',
|
||||||
background: '/static/aurora_borealis.jpg',
|
type: 'string',
|
||||||
embeddedToS: true,
|
required: false,
|
||||||
logo: '/static/logo.svg',
|
},
|
||||||
logoMargin: '.2em',
|
theme: {
|
||||||
logoMask: true,
|
description: 'Instance default theme name',
|
||||||
logoLeft: false,
|
type: 'string',
|
||||||
redirectRootLogin: '/main/friends',
|
required: false,
|
||||||
redirectRootNoLogin: '/main/all',
|
},
|
||||||
hideSitename: false,
|
defaultAvatar: {
|
||||||
nsfwCensorImage: null,
|
description: "Default avatar image to use when user doesn't have one set",
|
||||||
showFeaturesPanel: true,
|
type: 'string',
|
||||||
showInstanceSpecificPanel: false,
|
default: '/images/avi.png',
|
||||||
|
},
|
||||||
|
defaultBanner: {
|
||||||
|
description: "Default banner image to use when user doesn't have one set",
|
||||||
|
type: 'string',
|
||||||
|
default: '/images/banner.png',
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
description: 'Instance background/wallpaper',
|
||||||
|
type: 'string',
|
||||||
|
default: '/static/aurora_borealis.jpg',
|
||||||
|
},
|
||||||
|
embeddedToS: {
|
||||||
|
description: 'Whether to show Terms of Service title bar',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
logo: {
|
||||||
|
description: 'Instance logo',
|
||||||
|
type: 'string',
|
||||||
|
default: '/static/logo.svg',
|
||||||
|
},
|
||||||
|
logoMargin: {
|
||||||
|
description: 'Margin for logo (spacing above/below)',
|
||||||
|
type: 'string',
|
||||||
|
default: '.2em',
|
||||||
|
},
|
||||||
|
logoMask: {
|
||||||
|
description:
|
||||||
|
'Use logo as a mask (works well for monochrome/transparent logos)',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
logoLeft: {
|
||||||
|
description: 'Show logo on the left side of navbar',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
redirectRootLogin: {
|
||||||
|
description: 'Where to redirect user after login',
|
||||||
|
type: 'string',
|
||||||
|
default: '/main/friends',
|
||||||
|
},
|
||||||
|
redirectRootNoLogin: {
|
||||||
|
description: 'Where to redirect anonymous visitors',
|
||||||
|
type: 'string',
|
||||||
|
default: '/main/all',
|
||||||
|
},
|
||||||
|
hideSitename: {
|
||||||
|
description: 'Hide the instance name in navbar',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
nsfwCensorImage: {
|
||||||
|
description: 'Default NSFW censor image',
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
showFeaturesPanel: {
|
||||||
|
description: 'Show features panel to anonymous visitors',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
showInstanceSpecificPanel: {
|
||||||
|
description: 'Show instance-specific panel',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
// Html stuff
|
// Html stuff
|
||||||
instanceSpecificPanelContent: '',
|
instanceSpecificPanelContent: {
|
||||||
tos: '',
|
description: 'HTML of Instance-specific panel',
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
tos: {
|
||||||
|
description: 'HTML of Terms of Service panel',
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
export const instanceIdentityDefault = convertDefinitions(instanceIdentityDefaultDefinitions)
|
||||||
|
|
||||||
/// This object contains setting entries that makes sense
|
/// This object contains setting entries that makes sense
|
||||||
/// at the user level. The defaults can also be overriden by
|
/// at the user level. The defaults can also be overriden by
|
||||||
/// instance admins in the frontend_configuration endpoint or static config.
|
/// instance admins in the frontend_configuration endpoint or static config.
|
||||||
export const instanceDefaultConfig = {
|
export const instanceDefaultConfigDefinitions = {
|
||||||
expertLevel: 0, // used to track which settings to show and hide
|
expertLevel: {
|
||||||
hideISP: false,
|
description: 'Used to track which settings to show and hide in settings modal',
|
||||||
hideInstanceWallpaper: false,
|
type: 'number', // not a boolean so we could potentially make multiple levels of expert-ness
|
||||||
hideShoutbox: false,
|
default: 0,
|
||||||
// bad name: actually hides posts of muted USERS
|
},
|
||||||
hideMutedPosts: false,
|
hideISP: {
|
||||||
hideMutedThreads: true,
|
description: 'Hide Instance-specific panel',
|
||||||
hideWordFilteredPosts: false,
|
default: false,
|
||||||
muteBotStatuses: false,
|
},
|
||||||
muteSensitiveStatuses: false,
|
hideInstanceWallpaper: {
|
||||||
collapseMessageWithSubject: false,
|
description: 'Hide Instance default background',
|
||||||
padEmoji: true,
|
default: false,
|
||||||
hideAttachmentsInConv: false,
|
},
|
||||||
hideScrobbles: false,
|
hideShoutbox: {
|
||||||
hideScrobblesAfter: '2d',
|
description: 'Hide shoutbox if present',
|
||||||
maxThumbnails: 16,
|
default: false,
|
||||||
loopVideo: true,
|
},
|
||||||
loopVideoSilentOnly: true,
|
hideMutedPosts: { // bad name
|
||||||
|
description: 'Hide posts of muted users entirely',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
hideMutedThreads: {
|
||||||
|
description: 'Hide muted threads entirely',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
hideWordFilteredPosts: {
|
||||||
|
description: 'Hide wordfiltered posts entirely',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
muteBotStatuses: {
|
||||||
|
description: 'Mute posts made by bots',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
muteSensitiveStatuses: {
|
||||||
|
description: 'Mute posts marked as NSFW',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
collapseMessageWithSubject: {
|
||||||
|
description: 'Collapse posts with subject',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
padEmoji: {
|
||||||
|
description: 'Pad emoji with spaces when using emoji picker',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
hideAttachmentsInConv: {
|
||||||
|
description: 'Hide attachments',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
hideScrobbles: {
|
||||||
|
description: 'Hide scrobbles',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
hideScrobblesAfter: {
|
||||||
|
description: 'Hide scrobbles older than',
|
||||||
|
default: '2d',
|
||||||
|
},
|
||||||
|
maxThumbnails: {
|
||||||
|
description: 'Maximum attachments to show',
|
||||||
|
default: 16,
|
||||||
|
},
|
||||||
|
loopVideo: {
|
||||||
|
description: 'Loop videos',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
loopVideoSilentOnly: {
|
||||||
|
description: 'Loop only videos without sound',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
/// This is not the streaming API configuration, but rather an option
|
/// This is not the streaming API configuration, but rather an option
|
||||||
/// for automatically loading new posts into the timeline without
|
/// for automatically loading new posts into the timeline without
|
||||||
/// the user clicking the Show New button.
|
/// the user clicking the Show New button.
|
||||||
streaming: false,
|
streaming: {
|
||||||
emojiReactionsOnTimeline: true,
|
description: 'Automatically show new posts',
|
||||||
alwaysShowNewPostButton: false,
|
default: false,
|
||||||
autohideFloatingPostButton: false,
|
},
|
||||||
pauseOnUnfocused: true,
|
pauseOnUnfocused: {
|
||||||
stopGifs: true,
|
description: 'Pause showing new posts when tab is unfocused',
|
||||||
replyVisibility: 'all',
|
default: true,
|
||||||
thirdColumnMode: 'notifications',
|
},
|
||||||
|
emojiReactionsOnTimeline: {
|
||||||
|
description: 'Show emoji reactions on timeline',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
alwaysShowNewPostButton: {
|
||||||
|
description: 'Always show mobile "new post" button, even in desktop mode',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
autohideFloatingPostButton: {
|
||||||
|
description: 'Automatically hide mobile "new post" button when scrolling down',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
stopGifs: {
|
||||||
|
description: 'Play animated gifs on hover only',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
replyVisibility: {
|
||||||
|
description: 'Type of replies to show',
|
||||||
|
default: 'all',
|
||||||
|
},
|
||||||
|
thirdColumnMode: {
|
||||||
|
description: 'What to display in third column',
|
||||||
|
default: 'notifications',
|
||||||
|
},
|
||||||
notificationVisibility: {
|
notificationVisibility: {
|
||||||
follows: true,
|
description: 'What types of notifications to show',
|
||||||
mentions: true,
|
default: {
|
||||||
statuses: true,
|
follows: true,
|
||||||
likes: true,
|
mentions: true,
|
||||||
repeats: true,
|
statuses: true,
|
||||||
moves: true,
|
likes: true,
|
||||||
emojiReactions: true,
|
repeats: true,
|
||||||
followRequest: true,
|
moves: true,
|
||||||
reports: true,
|
emojiReactions: true,
|
||||||
chatMention: true,
|
followRequest: true,
|
||||||
polls: true,
|
reports: true,
|
||||||
|
chatMention: true,
|
||||||
|
polls: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
notificationNative: {
|
notificationNative: {
|
||||||
follows: true,
|
description: 'What type of notifications to show desktop notification for',
|
||||||
mentions: true,
|
default: {
|
||||||
statuses: true,
|
follows: true,
|
||||||
likes: false,
|
mentions: true,
|
||||||
repeats: false,
|
statuses: true,
|
||||||
moves: false,
|
likes: false,
|
||||||
emojiReactions: false,
|
repeats: false,
|
||||||
followRequest: true,
|
moves: false,
|
||||||
reports: true,
|
emojiReactions: false,
|
||||||
chatMention: true,
|
followRequest: true,
|
||||||
polls: true,
|
reports: true,
|
||||||
|
chatMention: true,
|
||||||
|
polls: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
webPushNotifications: {
|
||||||
|
description: 'Use WebPush',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
webPushAlwaysShowNotifications: {
|
||||||
|
description: 'Ignore filter when using WebPush',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
interfaceLanguage: {
|
||||||
|
description: 'UI language',
|
||||||
|
default: browserLocale,
|
||||||
|
},
|
||||||
|
hideScopeNotice: {
|
||||||
|
description: 'Hide scope notification',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
scopeCopy: {
|
||||||
|
description: 'Copy scope like mastodon does',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
subjectLineBehavior: {
|
||||||
|
description: 'How to treat subject line',
|
||||||
|
default: 'email',
|
||||||
|
},
|
||||||
|
alwaysShowSubjectInput: {
|
||||||
|
description: 'Always show subject line field',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
minimalScopesMode: {
|
||||||
|
description: 'Minimize amount of options shown in scope selector',
|
||||||
|
default: false,
|
||||||
},
|
},
|
||||||
webPushNotifications: false,
|
|
||||||
webPushAlwaysShowNotifications: false,
|
|
||||||
interfaceLanguage: browserLocale,
|
|
||||||
hideScopeNotice: false,
|
|
||||||
scopeCopy: true,
|
|
||||||
subjectLineBehavior: 'email',
|
|
||||||
alwaysShowSubjectInput: true,
|
|
||||||
minimalScopesMode: false,
|
|
||||||
|
|
||||||
// This hides statuses filtered via a word filter
|
// This hides statuses filtered via a word filter
|
||||||
hideFilteredStatuses: false,
|
hideFilteredStatuses: {
|
||||||
|
description: 'Hide wordfiltered entirely',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
// Confirmations
|
// Confirmations
|
||||||
modalOnRepeat: false,
|
modalOnRepeat: {
|
||||||
modalOnUnfollow: false,
|
description: 'Show confirmation modal for repeat',
|
||||||
modalOnBlock: true,
|
default: false,
|
||||||
modalOnMute: false,
|
},
|
||||||
modalOnMuteConversation: false,
|
modalOnUnfollow: {
|
||||||
modalOnMuteDomain: true,
|
description: 'Show confirmation modal for unfollow',
|
||||||
modalOnDelete: true,
|
default: false,
|
||||||
modalOnLogout: true,
|
},
|
||||||
modalOnApproveFollow: false,
|
modalOnBlock: {
|
||||||
modalOnDenyFollow: false,
|
description: 'Show confirmation modal for block',
|
||||||
modalOnRemoveUserFromFollowers: false,
|
default: true,
|
||||||
|
},
|
||||||
|
modalOnMute: {
|
||||||
|
description: 'Show confirmation modal for mute',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
modalOnMuteConversation: {
|
||||||
|
description: 'Show confirmation modal for mute conversation',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
modalOnMuteDomain: {
|
||||||
|
description: 'Show confirmation modal for mute domain',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
modalOnDelete: {
|
||||||
|
description: 'Show confirmation modal for delete',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
modalOnLogout: {
|
||||||
|
description: 'Show confirmation modal for logout',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
modalOnApproveFollow: {
|
||||||
|
description: 'Show confirmation modal for approve follow',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
modalOnDenyFollow: {
|
||||||
|
description: 'Show confirmation modal for deny follow',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
modalOnRemoveUserFromFollowers: {
|
||||||
|
description: 'Show confirmation modal for follower removal',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
// Expiry confirmations/default actions
|
// Expiry confirmations/default actions
|
||||||
onMuteDefaultAction: 'ask',
|
onMuteDefaultAction: {
|
||||||
onBlockDefaultAction: 'ask',
|
description: 'Default action when muting user',
|
||||||
|
default: 'ask',
|
||||||
|
},
|
||||||
|
onBlockDefaultAction: {
|
||||||
|
description: 'Default action when blocking user',
|
||||||
|
default: 'ask',
|
||||||
|
},
|
||||||
|
|
||||||
modalMobileCenter: false,
|
modalMobileCenter: {
|
||||||
playVideosInModal: false,
|
description: 'Center mobile dialogs vertically',
|
||||||
useContainFit: true,
|
default: false,
|
||||||
disableStickyHeaders: false,
|
},
|
||||||
showScrollbars: false,
|
playVideosInModal: {
|
||||||
userPopoverAvatarAction: 'open',
|
description: 'Play videos in gallery view',
|
||||||
userPopoverOverlay: false,
|
default: false,
|
||||||
userCardLeftJustify: false,
|
},
|
||||||
userCardHidePersonalMarks: false,
|
useContainFit: {
|
||||||
forcedRoundness: -1,
|
description: 'Use object-fit: contain for attachments',
|
||||||
greentext: false,
|
default: true,
|
||||||
mentionLinkShowTooltip: true,
|
},
|
||||||
mentionLinkShowAvatar: false,
|
disableStickyHeaders: {
|
||||||
mentionLinkFadeDomain: true,
|
description: 'Disable sticky headers',
|
||||||
mentionLinkShowYous: false,
|
default: false,
|
||||||
mentionLinkBoldenYou: true,
|
},
|
||||||
hidePostStats: false,
|
showScrollbars: {
|
||||||
hideBotIndication: false,
|
description: 'Always show scrollbars',
|
||||||
hideUserStats: false,
|
default: false,
|
||||||
virtualScrolling: true,
|
},
|
||||||
sensitiveByDefault: false,
|
userPopoverAvatarAction: {
|
||||||
conversationDisplay: 'linear',
|
description: 'What to do when clicking popover avatar',
|
||||||
conversationTreeAdvanced: false,
|
default: 'open',
|
||||||
conversationOtherRepliesButton: 'below',
|
},
|
||||||
conversationTreeFadeAncestors: false,
|
userPopoverOverlay: {
|
||||||
showExtraNotifications: true,
|
description: 'Overlay user popover with centering on avatar',
|
||||||
showExtraNotificationsTip: true,
|
default: false,
|
||||||
showChatsInExtraNotifications: true,
|
},
|
||||||
showAnnouncementsInExtraNotifications: true,
|
userCardLeftJustify: {
|
||||||
showFollowRequestsInExtraNotifications: true,
|
description: 'Justify user bio to the left',
|
||||||
maxDepthInThread: 6,
|
default: false,
|
||||||
autocompleteSelect: false,
|
},
|
||||||
closingDrawerMarksAsSeen: true,
|
userCardHidePersonalMarks: {
|
||||||
unseenAtTop: false,
|
description: 'Hide highlight/personal note in user view',
|
||||||
ignoreInactionableSeen: false,
|
default: false,
|
||||||
unsavedPostAction: 'confirm',
|
},
|
||||||
autoSaveDraft: false,
|
forcedRoundness: {
|
||||||
useAbsoluteTimeFormat: false,
|
description: 'Force roundness of the theme',
|
||||||
absoluteTimeFormatMinAge: '0d',
|
default: -1,
|
||||||
absoluteTime12h: '24h',
|
},
|
||||||
|
greentext: {
|
||||||
|
description: 'Highlight plaintext >quotes',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
mentionLinkShowTooltip: {
|
||||||
|
description: 'Show tooltips for mention links',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
mentionLinkShowAvatar: {
|
||||||
|
description: 'Show avatar next to mention link',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
mentionLinkFadeDomain: {
|
||||||
|
description: 'Mute (fade) domain name in mention links if configured to show it',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
mentionLinkShowYous: {
|
||||||
|
description: 'Show (you)s when you are mentioned',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
mentionLinkBoldenYou: {
|
||||||
|
description: 'Boldern mentionlink of you',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
hidePostStats: {
|
||||||
|
description: 'Hide post stats (rt, favs)',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
hideBotIndication: {
|
||||||
|
description: 'Hide bot indicator',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
hideUserStats: {
|
||||||
|
description: 'Hide user stats (followers etc)',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
virtualScrolling: {
|
||||||
|
description: 'Timeline virtual scrolling',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
sensitiveByDefault: {
|
||||||
|
description: 'Assume attachments are NSFW by default',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
conversationDisplay: {
|
||||||
|
description: 'Style of conversation display',
|
||||||
|
default: 'linear',
|
||||||
|
},
|
||||||
|
conversationTreeAdvanced: {
|
||||||
|
description: 'Advanced features of tree view conversation',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
conversationOtherRepliesButton: {
|
||||||
|
description: 'Where to show "other replies" in tree conversation view',
|
||||||
|
default: 'below',
|
||||||
|
},
|
||||||
|
conversationTreeFadeAncestors: {
|
||||||
|
description: 'Fade ancestors in tree conversation view',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
showExtraNotifications: {
|
||||||
|
description: 'Show extra notifications (chats, announcements etc) in notification panel',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
showExtraNotificationsTip: {
|
||||||
|
description: 'Show tip for extra notifications (that user can remove them)',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
showChatsInExtraNotifications: {
|
||||||
|
description: 'Show chat messages in notifications',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
showAnnouncementsInExtraNotifications: {
|
||||||
|
description: 'Show announcements in notifications',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
showFollowRequestsInExtraNotifications: {
|
||||||
|
description: 'Show follow requests in notifications',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
maxDepthInThread: {
|
||||||
|
description: 'Maximum depth in tree conversation view',
|
||||||
|
default: 6,
|
||||||
|
},
|
||||||
|
autocompleteSelect: {
|
||||||
|
description: '',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
closingDrawerMarksAsSeen: {
|
||||||
|
description: 'Closing mobile notification pane marks everything as seen',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
unseenAtTop: {
|
||||||
|
description: 'Show unseen notifications above others',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
ignoreInactionableSeen: {
|
||||||
|
description: 'Treat inactionable (fav, rt etc) notifications as "seen"',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
unsavedPostAction: {
|
||||||
|
description: 'What to do if post is aborted',
|
||||||
|
default: 'confirm',
|
||||||
|
},
|
||||||
|
autoSaveDraft: {
|
||||||
|
description: 'Save drafts automatically',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
useAbsoluteTimeFormat: {
|
||||||
|
description: 'Use absolute time format',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
absoluteTimeFormatMinAge: {
|
||||||
|
description: 'Show absolute time format only after this post age',
|
||||||
|
default: '0d',
|
||||||
|
},
|
||||||
|
absoluteTime12h: {
|
||||||
|
description: 'Use 24h time format',
|
||||||
|
default: '24h',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
export const instanceDefaultConfig = convertDefinitions(instanceDefaultConfigDefinitions)
|
||||||
|
|
||||||
export const defaultConfigLocal = {
|
export const defaultConfigLocal = {
|
||||||
hideAttachments: false,
|
hideAttachments: false,
|
||||||
|
|
@ -189,6 +540,7 @@ export const defaultConfigLocal = {
|
||||||
themeDebug: false, // debug mode that uses computed backgrounds instead of real ones to debug contrast functions
|
themeDebug: false, // debug mode that uses computed backgrounds instead of real ones to debug contrast functions
|
||||||
forceThemeRecompilation: false, // flag that forces recompilation on boot even if cache exists
|
forceThemeRecompilation: false, // flag that forces recompilation on boot even if cache exists
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LOCAL_ONLY_KEYS = new Set(Object.keys(defaultConfigLocal))
|
export const LOCAL_ONLY_KEYS = new Set(Object.keys(defaultConfigLocal))
|
||||||
|
|
||||||
export const makeUndefined = (c) =>
|
export const makeUndefined = (c) =>
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ import { defineStore } from 'pinia'
|
||||||
|
|
||||||
import { instanceDefaultProperties } from '../modules/config.js'
|
import { instanceDefaultProperties } from '../modules/config.js'
|
||||||
import {
|
import {
|
||||||
instanceDefaultConfig,
|
|
||||||
defaultConfigLocal,
|
defaultConfigLocal,
|
||||||
staticOrApiConfigDefault,
|
instanceDefaultConfig,
|
||||||
|
instanceIdentityDefault,
|
||||||
} from '../modules/default_config_state.js'
|
} from '../modules/default_config_state.js'
|
||||||
import apiService from '../services/api/api.service.js'
|
import apiService from '../services/api/api.service.js'
|
||||||
|
|
||||||
|
|
@ -16,7 +16,6 @@ import { ensureFinalFallback } from 'src/i18n/languages.js'
|
||||||
const REMOTE_INTERACTION_URL = '/main/ostatus'
|
const REMOTE_INTERACTION_URL = '/main/ostatus'
|
||||||
|
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
// Stuff from apiConfig
|
|
||||||
name: 'Pleroma FE',
|
name: 'Pleroma FE',
|
||||||
registrationOpen: true,
|
registrationOpen: true,
|
||||||
server: 'http://localhost:4040/',
|
server: 'http://localhost:4040/',
|
||||||
|
|
@ -36,7 +35,7 @@ const defaultState = {
|
||||||
|
|
||||||
// Instance-wide configurations that should not be changed by individual users
|
// Instance-wide configurations that should not be changed by individual users
|
||||||
instanceIdentity: {
|
instanceIdentity: {
|
||||||
...staticOrApiConfigDefault,
|
...instanceIdentityDefault,
|
||||||
},
|
},
|
||||||
|
|
||||||
limits: {
|
limits: {
|
||||||
|
|
|
||||||
|
|
@ -412,15 +412,13 @@ export const useInterfaceStore = defineStore('interface', {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const { style: instanceStyleName, palette: instancePaletteName } =
|
|
||||||
useInstanceStore()
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
theme: instanceThemeV2Name,
|
theme: instanceThemeName,
|
||||||
themesIndex,
|
style: instanceStyleName,
|
||||||
stylesIndex,
|
palette: instancePaletteName,
|
||||||
palettesIndex,
|
} = useInstanceStore().instanceIdentity
|
||||||
} = useInstanceStore()
|
|
||||||
|
let { themesIndex, stylesIndex, palettesIndex } = useInstanceStore()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
style: userStyleName,
|
style: userStyleName,
|
||||||
|
|
@ -447,7 +445,7 @@ export const useInterfaceStore = defineStore('interface', {
|
||||||
console.debug(
|
console.debug(
|
||||||
`Instance V3 palette: ${instancePaletteName}, style: ${instanceStyleName}`,
|
`Instance V3 palette: ${instancePaletteName}, style: ${instanceStyleName}`,
|
||||||
)
|
)
|
||||||
console.debug('Instance V2 theme: ' + instanceThemeV2Name)
|
console.debug('Instance V2 theme: ' + instanceThemeName)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
userPaletteName ||
|
userPaletteName ||
|
||||||
|
|
@ -456,11 +454,11 @@ export const useInterfaceStore = defineStore('interface', {
|
||||||
userStyleCustomData ||
|
userStyleCustomData ||
|
||||||
// User V2 overrides instance V3
|
// User V2 overrides instance V3
|
||||||
((instancePaletteName || instanceStyleName) &&
|
((instancePaletteName || instanceStyleName) &&
|
||||||
instanceThemeV2Name == null &&
|
instanceThemeName == null &&
|
||||||
userThemeV2Name == null)
|
userThemeV2Name == null)
|
||||||
) {
|
) {
|
||||||
// Palette and/or style overrides V2 themes
|
// Palette and/or style overrides V2 themes
|
||||||
instanceThemeV2Name = null
|
instanceThemeName = null
|
||||||
userThemeV2Name = null
|
userThemeV2Name = null
|
||||||
userThemeV2Source = null
|
userThemeV2Source = null
|
||||||
userThemeV2Snapshot = null
|
userThemeV2Snapshot = null
|
||||||
|
|
@ -470,7 +468,7 @@ export const useInterfaceStore = defineStore('interface', {
|
||||||
userThemeV2Name ||
|
userThemeV2Name ||
|
||||||
userThemeV2Snapshot ||
|
userThemeV2Snapshot ||
|
||||||
userThemeV2Source ||
|
userThemeV2Source ||
|
||||||
instanceThemeV2Name
|
instanceThemeName
|
||||||
) {
|
) {
|
||||||
majorVersionUsed = 'v2'
|
majorVersionUsed = 'v2'
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -588,7 +586,7 @@ export const useInterfaceStore = defineStore('interface', {
|
||||||
'theme',
|
'theme',
|
||||||
themesIndex,
|
themesIndex,
|
||||||
userThemeV2Source || userThemeV2Snapshot,
|
userThemeV2Source || userThemeV2Snapshot,
|
||||||
userThemeV2Name || instanceThemeV2Name,
|
userThemeV2Name || instanceThemeName,
|
||||||
)
|
)
|
||||||
this.themeNameUsed = theme.nameUsed
|
this.themeNameUsed = theme.nameUsed
|
||||||
this.themeDataUsed = theme.dataUsed
|
this.themeDataUsed = theme.dataUsed
|
||||||
|
|
|
||||||
|
|
@ -643,7 +643,9 @@ export const useSyncConfigStore = defineStore('sync_config', {
|
||||||
vuexState.config = vuexState.config ?? {}
|
vuexState.config = vuexState.config ?? {}
|
||||||
|
|
||||||
const migratedEntries = new Set(vuexState.config._syncMigration ?? [])
|
const migratedEntries = new Set(vuexState.config._syncMigration ?? [])
|
||||||
console.debug(`Already migrated Values: ${[...migratedEntries].join() || '[none]'}`)
|
console.debug(
|
||||||
|
`Already migrated Values: ${[...migratedEntries].join() || '[none]'}`,
|
||||||
|
)
|
||||||
|
|
||||||
Object.entries(oldDefaultConfigSync).forEach(([key, value]) => {
|
Object.entries(oldDefaultConfigSync).forEach(([key, value]) => {
|
||||||
const oldValue = vuexState.config[key]
|
const oldValue = vuexState.config[key]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
import { createPinia, setActivePinia } from 'pinia'
|
import { createPinia, setActivePinia } from 'pinia'
|
||||||
|
|
||||||
|
import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
_getAllFlags,
|
_getAllFlags,
|
||||||
_getRecentData,
|
_getRecentData,
|
||||||
|
|
@ -15,7 +17,6 @@ import {
|
||||||
useSyncConfigStore,
|
useSyncConfigStore,
|
||||||
VERSION,
|
VERSION,
|
||||||
} from 'src/stores/sync_config.js'
|
} from 'src/stores/sync_config.js'
|
||||||
import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js'
|
|
||||||
|
|
||||||
describe('The SyncConfig store', () => {
|
describe('The SyncConfig store', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue