components

This commit is contained in:
Henry Jameson 2026-02-13 14:26:39 +02:00
commit dbc9bd9c46
46 changed files with 247 additions and 160 deletions

View file

@ -5,6 +5,7 @@ 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: {
@ -21,7 +22,7 @@ const About = {
showInstanceSpecificPanel() { showInstanceSpecificPanel() {
return ( return (
useInstanceStore().instanceIdentity.showInstanceSpecificPanel && useInstanceStore().instanceIdentity.showInstanceSpecificPanel &&
!this.$store.getters.mergedConfig.hideISP && !useSyncConfigStore().mergedConfig.hideISP &&
useInstanceStore().instanceIdentity.instanceSpecificPanelContent useInstanceStore().instanceIdentity.instanceSpecificPanelContent
) )
}, },

View file

@ -8,6 +8,7 @@ import ProgressButton from '../progress_button/progress_button.vue'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' 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'
@ -89,10 +90,10 @@ const AccountActions = {
}, },
computed: { computed: {
shouldConfirmBlock() { shouldConfirmBlock() {
return this.$store.getters.mergedConfig.modalOnBlock return useSyncConfigStore().mergedConfig.modalOnBlock
}, },
shouldConfirmRemoveUserFromFollowers() { shouldConfirmRemoveUserFromFollowers() {
return this.$store.getters.mergedConfig.modalOnRemoveUserFromFollowers return useSyncConfigStore().mergedConfig.modalOnRemoveUserFromFollowers
}, },
...mapState(useInstanceCapabilitiesStore, [ ...mapState(useInstanceCapabilitiesStore, [
'blockExpiration', 'blockExpiration',

View file

@ -9,6 +9,7 @@ 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 { 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 {
@ -58,8 +59,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: this.$store.getters.mergedConfig.hideNsfw, hideNsfwLocal: useSyncConfigStore().mergedConfig.hideNsfw,
preloadImage: this.$store.getters.mergedConfig.preloadImage, preloadImage: useSyncConfigStore().mergedConfig.preloadImage,
loading: false, loading: false,
img: img:
fileTypeService.fileType(this.attachment.mimetype) === 'image' && fileTypeService.fileType(this.attachment.mimetype) === 'image' &&
@ -93,7 +94,7 @@ const Attachment = {
return this.size === 'hide' return this.size === 'hide'
}, },
useContainFit() { useContainFit() {
return this.$store.getters.mergedConfig.useContainFit return useSyncConfigStore().mergedConfig.useContainFit
}, },
placeholderName() { placeholderName() {
if (this.attachment.description === '' || !this.attachment.description) { if (this.attachment.description === '' || !this.attachment.description) {

View file

@ -1,8 +1,10 @@
import { mapGetters } from 'vuex' import { mapState } from 'pinia'
import Select from 'src/components/select/select.vue' import Select from 'src/components/select/select.vue'
import ConfirmModal from './confirm_modal.vue' import ConfirmModal from './confirm_modal.vue'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
export default { export default {
props: ['type', 'user', 'status'], props: ['type', 'user', 'status'],
emits: ['hide', 'show', 'muted'], emits: ['hide', 'show', 'muted'],
@ -43,7 +45,7 @@ export default {
} }
} }
}, },
...mapGetters(['mergedConfig']), ...mapState(useSyncConfigStore, ['mergedConfig']),
}, },
methods: { methods: {
optionallyPrompt() { optionallyPrompt() {

View file

@ -9,6 +9,7 @@ import Status from '../status/status.vue'
import ThreadTree from '../thread_tree/thread_tree.vue' import ThreadTree from '../thread_tree/thread_tree.vue'
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 {
@ -81,7 +82,7 @@ const conversation = {
// maxDepthInThread = max number of depths that is *visible* // maxDepthInThread = max number of depths that is *visible*
// since our depth starts with 0 and "showing" means "showing children" // since our depth starts with 0 and "showing" means "showing children"
// there is a -2 here // there is a -2 here
const maxDepth = this.$store.getters.mergedConfig.maxDepthInThread - 2 const maxDepth = useSyncConfigStore().mergedConfig.maxDepthInThread - 2
return maxDepth >= 1 ? maxDepth : 1 return maxDepth >= 1 ? maxDepth : 1
}, },
streamingEnabled() { streamingEnabled() {
@ -91,22 +92,22 @@ const conversation = {
) )
}, },
displayStyle() { displayStyle() {
return this.$store.getters.mergedConfig.conversationDisplay return useSyncConfigStore().mergedConfig.conversationDisplay
}, },
isTreeView() { isTreeView() {
return !this.isLinearView return !this.isLinearView
}, },
treeViewIsSimple() { treeViewIsSimple() {
return !this.$store.getters.mergedConfig.conversationTreeAdvanced return !useSyncConfigStore().mergedConfig.conversationTreeAdvanced
}, },
isLinearView() { isLinearView() {
return this.displayStyle === 'linear' return this.displayStyle === 'linear'
}, },
shouldFadeAncestors() { shouldFadeAncestors() {
return this.$store.getters.mergedConfig.conversationTreeFadeAncestors return useSyncConfigStore().mergedConfig.conversationTreeFadeAncestors
}, },
otherRepliesButtonPosition() { otherRepliesButtonPosition() {
return this.$store.getters.mergedConfig.conversationOtherRepliesButton return useSyncConfigStore().mergedConfig.conversationOtherRepliesButton
}, },
showOtherRepliesButtonBelowStatus() { showOtherRepliesButtonBelowStatus() {
return this.otherRepliesButtonPosition === 'below' return this.otherRepliesButtonPosition === 'below'

View file

@ -5,6 +5,7 @@ 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' 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 {
@ -96,7 +97,7 @@ export default {
return this.$store.state.users.currentUser return this.$store.state.users.currentUser
}, },
shouldConfirmLogout() { shouldConfirmLogout() {
return this.$store.getters.mergedConfig.modalOnLogout return useSyncConfigStore().mergedConfig.modalOnLogout
}, },
}, },
methods: { methods: {

View file

@ -1,3 +1,5 @@
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const DialogModal = { const DialogModal = {
props: { props: {
darkOverlay: { darkOverlay: {
@ -13,7 +15,7 @@ const DialogModal = {
}, },
computed: { computed: {
mobileCenter() { mobileCenter() {
return this.$store.getters.mergedConfig.modalMobileCenter return useSyncConfigStore().mergedConfig.modalMobileCenter
}, },
}, },
} }

View file

@ -6,6 +6,8 @@ import Gallery from 'src/components/gallery/gallery.vue'
import PostStatusForm from 'src/components/post_status_form/post_status_form.vue' import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
import StatusContent from 'src/components/status_content/status_content.vue' import StatusContent from 'src/components/status_content/status_content.vue'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { faPollH } from '@fortawesome/free-solid-svg-icons' import { faPollH } from '@fortawesome/free-solid-svg-icons'
@ -57,7 +59,7 @@ const Draft = {
: undefined : undefined
}, },
localCollapseSubjectDefault() { localCollapseSubjectDefault() {
return this.$store.getters.mergedConfig.collapseMessageWithSubject return useSyncConfigStore().mergedConfig.collapseMessageWithSubject
}, },
nsfwClickthrough() { nsfwClickthrough() {
if (!this.draft.nsfw) { if (!this.draft.nsfw) {

View file

@ -1,5 +1,7 @@
import DialogModal from 'src/components/dialog_modal/dialog_modal.vue' import DialogModal from 'src/components/dialog_modal/dialog_modal.vue'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const DraftCloser = { const DraftCloser = {
data() { data() {
return { return {
@ -12,10 +14,10 @@ const DraftCloser = {
emits: ['save', 'discard'], emits: ['save', 'discard'],
computed: { computed: {
action() { action() {
if (this.$store.getters.mergedConfig.autoSaveDraft) { if (useSyncConfigStore().mergedConfig.autoSaveDraft) {
return 'save' return 'save'
} else { } else {
return this.$store.getters.mergedConfig.unsavedPostAction return useSyncConfigStore().mergedConfig.unsavedPostAction
} }
}, },
shouldConfirm() { shouldConfirm() {

View file

@ -9,6 +9,8 @@ import genRandomSeed from '../../services/random_seed/random_seed.service.js'
import EmojiPicker from '../emoji_picker/emoji_picker.vue' import EmojiPicker from '../emoji_picker/emoji_picker.vue'
import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue' import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { faSmileBeam } from '@fortawesome/free-regular-svg-icons' import { faSmileBeam } from '@fortawesome/free-regular-svg-icons'
@ -131,7 +133,7 @@ const EmojiInput = {
}, },
computed: { computed: {
padEmoji() { padEmoji() {
return this.$store.getters.mergedConfig.padEmoji return useSyncConfigStore().mergedConfig.padEmoji
}, },
defaultCandidateIndex() { defaultCandidateIndex() {
return this.$store.getters.mergedConfig.autocompleteSelect ? 0 : -1 return this.$store.getters.mergedConfig.autocompleteSelect ? 0 : -1

View file

@ -1,3 +1,5 @@
import { useEmojiStore } from 'src/stores/emoji.js'
/** /**
* suggest - generates a suggestor function to be used by emoji-input * suggest - generates a suggestor function to be used by emoji-input
* data: object providing source information for specific types of suggestions: * data: object providing source information for specific types of suggestions:

View file

@ -8,6 +8,7 @@ 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 { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
@ -340,7 +341,7 @@ const EmojiPicker = {
this.$nextTick(() => { this.$nextTick(() => {
this.updateEmojiSize() this.updateEmojiSize()
}) })
return this.$store.getters.mergedConfig.fontSize return useSyncConfigStore().mergedConfig.fontSize
}, },
emojiHeight() { emojiHeight() {
return this.emojiSize return this.emojiSize
@ -405,7 +406,7 @@ const EmojiPicker = {
}, },
languages() { languages() {
return ensureFinalFallback( return ensureFinalFallback(
this.$store.getters.mergedConfig.interfaceLanguage, useSyncConfigStore().mergedConfig.interfaceLanguage,
) )
}, },
maybeLocalizedEmojiName() { maybeLocalizedEmojiName() {

View file

@ -3,6 +3,8 @@ import {
requestUnfollow, requestUnfollow,
} from '../../services/follow_manipulate/follow_manipulate' } from '../../services/follow_manipulate/follow_manipulate'
import ConfirmModal from '../confirm_modal/confirm_modal.vue' import ConfirmModal from '../confirm_modal/confirm_modal.vue'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
export default { export default {
props: ['relationship', 'user', 'labelFollowing', 'buttonClass'], props: ['relationship', 'user', 'labelFollowing', 'buttonClass'],
components: { components: {
@ -16,7 +18,7 @@ export default {
}, },
computed: { computed: {
shouldConfirmUnfollow() { shouldConfirmUnfollow() {
return this.$store.getters.mergedConfig.modalOnUnfollow return useSyncConfigStore().mergedConfig.modalOnUnfollow
}, },
isPressed() { isPressed() {
return this.inProgress || this.relationship.following return this.inProgress || this.relationship.following

View file

@ -2,6 +2,8 @@ import { notificationsFromStore } from '../../services/notification_utils/notifi
import BasicUserCard from '../basic_user_card/basic_user_card.vue' import BasicUserCard from '../basic_user_card/basic_user_card.vue'
import ConfirmModal from '../confirm_modal/confirm_modal.vue' import ConfirmModal from '../confirm_modal/confirm_modal.vue'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const FollowRequestCard = { const FollowRequestCard = {
props: ['user'], props: ['user'],
components: { components: {
@ -76,7 +78,7 @@ const FollowRequestCard = {
}, },
computed: { computed: {
mergedConfig() { mergedConfig() {
return this.$store.getters.mergedConfig return useSyncConfigStore().mergedConfig
}, },
shouldConfirmApprove() { shouldConfirmApprove() {
return this.mergedConfig.modalOnApproveFollow return this.mergedConfig.modalOnApproveFollow

View file

@ -1,4 +1,6 @@
import { mapGetters } from 'vuex' import { mapState } from 'pinia'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const LinkPreview = { const LinkPreview = {
name: 'LinkPreview', name: 'LinkPreview',
@ -24,7 +26,7 @@ const LinkPreview = {
hideNsfwConfig() { hideNsfwConfig() {
return this.mergedConfig.hideNsfw return this.mergedConfig.hideNsfw
}, },
...mapGetters(['mergedConfig']), ...mapState(useSyncConfigStore, ['mergedConfig']),
}, },
created() { created() {
if (this.useImage) { if (this.useImage) {

View file

@ -2,6 +2,7 @@ import fileSizeFormatService from '../../services/file_size_format/file_size_for
import statusPosterService from '../../services/status_poster/status_poster.service.js' import statusPosterService from '../../services/status_poster/status_poster.service.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useSyncConfigStore } from 'src/stores/sync_config.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 +34,7 @@ const mediaUpload = {
} }
// Skip if image compression is disabled // Skip if image compression is disabled
if (!this.$store.getters.mergedConfig.imageCompression) { if (!useSyncConfigStore().mergedConfig.imageCompression) {
return file return file
} }
@ -78,7 +79,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 =
!this.$store.getters.mergedConfig.alwaysUseJpeg && supportsWebP !useSyncConfigStore().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'

View file

@ -1,7 +1,9 @@
import { mapGetters } from 'vuex' 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 { useSyncConfigStore } from 'src/stores/sync_config.js'
export const MENTIONS_LIMIT = 5 export const MENTIONS_LIMIT = 5
const MentionsLine = { const MentionsLine = {
@ -26,7 +28,7 @@ const MentionsLine = {
manyMentions() { manyMentions() {
return this.extraMentions.length > 0 return this.extraMentions.length > 0
}, },
...mapGetters(['mergedConfig']), ...mapState(useSyncConfigStore, ['mergedConfig']),
}, },
methods: { methods: {
toggleShowMore() { toggleShowMore() {

View file

@ -1,6 +1,7 @@
import { debounce } from 'lodash' import { debounce } from 'lodash'
import { usePostStatusStore } from 'src/stores/post_status.js' 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'
@ -45,10 +46,10 @@ const MobilePostStatusButton = {
) )
}, },
isPersistent() { isPersistent() {
return !!this.$store.getters.mergedConfig.alwaysShowNewPostButton return !!useSyncConfigStore().mergedConfig.alwaysShowNewPostButton
}, },
autohideFloatingPostButton() { autohideFloatingPostButton() {
return !!this.$store.getters.mergedConfig.autohideFloatingPostButton return !!useSyncConfigStore().mergedConfig.autohideFloatingPostButton
}, },
}, },
watch: { watch: {

View file

@ -17,6 +17,7 @@ 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'
@ -181,7 +182,7 @@ const Notification = {
return highlightClass(this.notification.from_profile) return highlightClass(this.notification.from_profile)
}, },
userStyle() { userStyle() {
const highlight = this.$store.getters.mergedConfig.highlight const highlight = useSyncConfigStore().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])
}, },
@ -209,7 +210,7 @@ const Notification = {
return isStatusNotification(this.notification.type) return isStatusNotification(this.notification.type)
}, },
mergedConfig() { mergedConfig() {
return this.$store.getters.mergedConfig return useSyncConfigStore().mergedConfig
}, },
shouldConfirmApprove() { shouldConfirmApprove() {
return this.mergedConfig.modalOnApproveFollow return this.mergedConfig.modalOnApproveFollow

View file

@ -108,6 +108,8 @@
<script> <script>
import Popover from '../popover/popover.vue' import Popover from '../popover/popover.vue'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { faFilter } from '@fortawesome/free-solid-svg-icons' import { faFilter } from '@fortawesome/free-solid-svg-icons'
@ -117,7 +119,7 @@ export default {
components: { Popover }, components: { Popover },
computed: { computed: {
filters() { filters() {
return this.$store.getters.mergedConfig.notificationVisibility return useSyncConfigStore().mergedConfig.notificationVisibility
}, },
}, },
methods: { methods: {

View file

@ -17,6 +17,7 @@ import NotificationFilters from './notification_filters.vue'
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 {
@ -98,7 +99,7 @@ const Notifications = {
return this.unseenNotifications.length return this.unseenNotifications.length
}, },
ignoreInactionableSeen() { ignoreInactionableSeen() {
return this.$store.getters.mergedConfig.ignoreInactionableSeen return useSyncConfigStore().mergedConfig.ignoreInactionableSeen
}, },
extraNotificationsCount() { extraNotificationsCount() {
return countExtraNotifications(this.$store) return countExtraNotifications(this.$store)
@ -136,10 +137,10 @@ const Notifications = {
) )
}, },
noSticky() { noSticky() {
return this.$store.getters.mergedConfig.disableStickyHeaders return useSyncConfigStore().mergedConfig.disableStickyHeaders
}, },
unseenAtTop() { unseenAtTop() {
return this.$store.getters.mergedConfig.unseenAtTop return useSyncConfigStore().mergedConfig.unseenAtTop
}, },
showExtraNotifications() { showExtraNotifications() {
return !this.noExtra return !this.noExtra

View file

@ -5,6 +5,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.js' import { usePollsStore } from 'src/stores/polls.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
export default { export default {
name: 'Poll', name: 'Poll',
@ -48,7 +49,7 @@ export default {
return (this.poll && this.poll.expired) || false return (this.poll && this.poll.expired) || false
}, },
expirationLabel() { expirationLabel() {
if (this.$store.getters.mergedConfig.useAbsoluteTimeFormat) { if (useSyncConfigStore().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'

View file

@ -25,6 +25,7 @@ import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.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,7 +164,7 @@ 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 { scopeCopy } = useSyncConfigStore().mergedConfig
const [statusType, refId] = typeAndRefId({ const [statusType, refId] = typeAndRefId({
replyTo: this.replyTo, replyTo: this.replyTo,
@ -193,7 +194,7 @@ const PostStatusForm = {
: this.$store.state.users.currentUser.default_scope : this.$store.state.users.currentUser.default_scope
const { postContentType: contentType, sensitiveByDefault } = const { postContentType: contentType, sensitiveByDefault } =
this.$store.getters.mergedConfig useSyncConfigStore().mergedConfig
statusParams = { statusParams = {
type: statusType, type: statusType,
@ -324,7 +325,7 @@ const PostStatusForm = {
}, },
hideScopeNotice() { hideScopeNotice() {
return ( return (
this.disableNotice || this.$store.getters.mergedConfig.hideScopeNotice this.disableNotice || useSyncConfigStore().mergedConfig.hideScopeNotice
) )
}, },
pollContentError() { pollContentError() {
@ -380,7 +381,7 @@ const PostStatusForm = {
return this.newStatus.hasPoll return this.newStatus.hasPoll
}, },
shouldAutoSaveDraft() { shouldAutoSaveDraft() {
return this.$store.getters.mergedConfig.autoSaveDraft return useSyncConfigStore().mergedConfig.autoSaveDraft
}, },
autoSaveState() { autoSaveState() {
if (this.saveable) { if (this.saveable) {

View file

@ -1,5 +1,7 @@
import ConfirmModal from '../confirm_modal/confirm_modal.vue' import ConfirmModal from '../confirm_modal/confirm_modal.vue'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
export default { export default {
props: ['user', 'relationship'], props: ['user', 'relationship'],
data() { data() {
@ -20,7 +22,7 @@ export default {
} }
}, },
shouldConfirmRemoveUserFromFollowers() { shouldConfirmRemoveUserFromFollowers() {
return this.$store.getters.mergedConfig.modalOnRemoveUserFromFollowers return useSyncConfigStore().mergedConfig.modalOnRemoveUserFromFollowers
}, },
}, },
methods: { methods: {

View file

@ -4,6 +4,10 @@ import DraftButtons from './draft_buttons.vue'
import ModifiedIndicator from './modified_indicator.vue' import ModifiedIndicator from './modified_indicator.vue'
import ProfileSettingIndicator from './profile_setting_indicator.vue' import ProfileSettingIndicator from './profile_setting_indicator.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
export default { export default {
components: { components: {
ModifiedIndicator, ModifiedIndicator,
@ -235,13 +239,14 @@ export default {
case 'admin': case 'admin':
return this.$store.state.adminSettings.config return this.$store.state.adminSettings.config
default: default:
return this.$store.getters.mergedConfig return useSyncConfigStore().mergedConfig
} }
}, },
configSink() { configSink() {
if (this.path == null) { if (this.path == null) {
return (k, v) => this.$emit('update:modelValue', v) return (k, v) => this.$emit('update:modelValue', v)
} }
switch (this.realSource) { switch (this.realSource) {
case 'profile': case 'profile':
return (k, v) => return (k, v) =>
@ -250,15 +255,37 @@ export default {
return (k, v) => return (k, v) =>
this.$store.dispatch('pushAdminSetting', { path: k, value: v }) this.$store.dispatch('pushAdminSetting', { path: k, value: v })
default: default:
if (this.timedApplyMode) { return (readPath, value) => {
return (k, v) => const writePath = `simple.${readPath}`
this.$store.dispatch('setOptionTemporarily', {
name: k, if (!this.timedApplyMode) {
value: v, useSyncConfigStore().setPreference({ path: writePath, value })
}) useSyncConfigStore().pushSyncConfig()
} else { } else {
return (k, v) => if (useInterfaceStore().temporaryChangesTimeoutId !== null) {
this.$store.dispatch('setOption', { name: k, value: v }) console.error("Can't track more than one temporary change")
return
}
const oldValue = get(this.configSource, readPath)
useSyncConfigStore().setPreference({ path: writePath, value })
const confirm = () => {
useSyncConfigStore().pushSyncConfig()
useInterfaceStore().clearTemporaryChanges()
}
const revert = () => {
useSyncConfigStore().setPreference({
path: writePath,
value: oldValue,
})
useInterfaceStore().clearTemporaryChanges()
}
useInterfaceStore().setTemporaryChanges({ confirm, revert })
}
} }
} }
}, },
@ -267,7 +294,7 @@ export default {
case 'profile': case 'profile':
return {} return {}
default: default:
return get(this.$store.getters.defaultConfig, this.path) return get(useInstanceStore().prefsStorage, this.path)
} }
}, },
isProfileSetting() { isProfileSetting() {
@ -318,7 +345,8 @@ export default {
}, },
matchesExpertLevel() { matchesExpertLevel() {
const settingExpertLevel = this.expert || 0 const settingExpertLevel = this.expert || 0
const userToggleExpert = this.$store.state.config.expertLevel || 0 const userToggleExpert =
useSyncConfigStore().mergedConfig.expertLevel || 0
return settingExpertLevel <= userToggleExpert return settingExpertLevel <= userToggleExpert
}, },
@ -344,7 +372,7 @@ export default {
this.draft = cloneDeep(this.state) this.draft = cloneDeep(this.state)
} else { } else {
set( set(
this.$store.getters.mergedConfig, useSyncConfigStore().mergedConfig,
this.path, this.path,
cloneDeep(this.defaultState), cloneDeep(this.defaultState),
) )

View file

@ -1,19 +1,18 @@
import { mapState as mapPiniaState } from 'pinia'
import { mapState } from 'vuex'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const SharedComputedObject = () => ({ const SharedComputedObject = () => ({
user() { ...mapPiniaState(useSyncConfigStore, ['mergedConfig']),
return this.$store.state.users.currentUser ...mapPiniaState(useSyncConfigStore, {
}, expertLevel: (store) => store.mergedConfig.expertLevel,
expertLevel() { }),
return this.$store.getters.mergedConfig.expertLevel > 0 ...mapState({
}, adminConfig: (state) => state.adminSettings.config,
mergedConfig() { adminDraft: (state) => state.adminSettings.draft,
return this.$store.getters.mergedConfig user: (state) => state.users.currentUser,
}, }),
adminConfig() {
return this.$store.state.adminSettings.config
},
adminDraft() {
return this.$store.state.adminSettings.draft
},
}) })
export default SharedComputedObject export default SharedComputedObject

View file

@ -9,6 +9,7 @@ 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.js' import { useInterfaceStore } from 'src/stores/interface.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { import {
newExporter, newExporter,
@ -191,11 +192,11 @@ const SettingsModal = {
}), }),
expertLevel: { expertLevel: {
get() { get() {
return this.$store.state.config.expertLevel > 0 return useSyncConfigStore().mergedConfig.expertLevel > 0
}, },
set(value) { set(value) {
this.$store.dispatch('setOption', { useSyncConfigStore().setPreference({
name: 'expertLevel', path: 'simple.expertLevel',
value: value ? 1 : 0, value: value ? 1 : 0,
}) })
}, },

View file

@ -54,7 +54,7 @@
:key="style.key" :key="style.key"
:data-theme-key="style.key" :data-theme-key="style.key"
class="button-default theme-preview" class="button-default theme-preview"
:class="{ toggled: isThemeActive(style.key), disabled: switchInProgress }" :class="{ toggled: isStyleActive(style.key), disabled: switchInProgress }"
:disabled="switchInProgress" :disabled="switchInProgress"
@click="style.version === 'v2' ? setTheme(style.key) : setStyle(style.key)" @click="style.version === 'v2' ? setTheme(style.key) : setStyle(style.key)"
> >
@ -90,7 +90,7 @@
class="btn button-default palette-entry" class="btn button-default palette-entry"
:class="{ toggled: isPaletteActive(p.key), disabled: switchInProgress }" :class="{ toggled: isPaletteActive(p.key), disabled: switchInProgress }"
:disabled="switchInProgress" :disabled="switchInProgress"
@click="() => setPalette(p.key, p)" @click="() => setLocalPalette(p.key, p)"
> >
<div class="palette-label"> <div class="palette-label">
<label> <label>
@ -113,7 +113,7 @@
class="btn button-default palette-entry" class="btn button-default palette-entry"
:class="{ toggled: isPaletteActive(p.key), disabled: switchInProgress }" :class="{ toggled: isPaletteActive(p.key), disabled: switchInProgress }"
:disabled="switchInProgress" :disabled="switchInProgress"
@click="() => setPalette(p.key, p)" @click="() => setLocalPalette(p.key, p)"
> >
<div class="palette-label"> <div class="palette-label">
<label> <label>
@ -143,7 +143,7 @@
:compact="true" :compact="true"
:apply="true" :apply="true"
:disabled="switchInProgress" :disabled="switchInProgress"
@apply-palette="data => setPaletteCustom(data)" @apply-palette="data => setLocalPaletteCustom(data)"
/> />
</template> </template>
<template v-else-if="customThemeVersion === 'v2'"> <template v-else-if="customThemeVersion === 'v2'">

View file

@ -19,9 +19,7 @@
</BooleanSetting> </BooleanSetting>
</li> </li>
<li> <li>
<BooleanSetting <BooleanSetting path="hideUserStats">
path="hideUserStats"
>
{{ $t('settings.hide_user_stats') }} {{ $t('settings.hide_user_stats') }}
</BooleanSetting> </BooleanSetting>
</li> </li>

View file

@ -13,6 +13,7 @@ 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'
@ -116,7 +117,7 @@ const ComposingTab = {
}, },
language: { language: {
get: function () { get: function () {
return this.$store.getters.mergedConfig.interfaceLanguage return useSyncConfigStore().mergedConfig.interfaceLanguage
}, },
set: function (val) { set: function (val) {
this.$store.dispatch('setOption', { this.$store.dispatch('setOption', {

View file

@ -11,6 +11,7 @@ import UnitSetting from '../helpers/unit_setting.vue'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.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'
@ -37,7 +38,7 @@ const GeneralTab = {
computed: { computed: {
language: { language: {
get: function () { get: function () {
return this.$store.getters.mergedConfig.interfaceLanguage return useSyncConfigStore().mergedConfig.interfaceLanguage
}, },
set: function (val) { set: function (val) {
this.$store.dispatch('setOption', { this.$store.dispatch('setOption', {
@ -48,6 +49,9 @@ const GeneralTab = {
}, },
...SharedComputedObject(), ...SharedComputedObject(),
...mapState(useInstanceCapabilitiesStore, ['blockExpiration']), ...mapState(useInstanceCapabilitiesStore, ['blockExpiration']),
...mapState(useSyncConfigStore, {
theme3hacks: (store) => store.mergedConfig.theme3hacks,
}),
}, },
methods: { methods: {
updateProfile() { updateProfile() {

View file

@ -68,7 +68,7 @@
</li> </li>
<li> <li>
<FontControl <FontControl
:model-value="mergedConfig.theme3hacks.fonts.interface" :model-value="theme3hacks.fonts.interface"
name="ui" name="ui"
:label="$t('settings.style.fonts.components_inline.interface')" :label="$t('settings.style.fonts.components_inline.interface')"
:fallback="{ family: 'sans-serif' }" :fallback="{ family: 'sans-serif' }"
@ -78,7 +78,7 @@
</li> </li>
<li> <li>
<FontControl <FontControl
:model-value="mergedConfig.theme3hacks.fonts.input" :model-value="theme3hacks.fonts.input"
name="input" name="input"
:fallback="{ family: 'inherit' }" :fallback="{ family: 'inherit' }"
:label="$t('settings.style.fonts.components_inline.input')" :label="$t('settings.style.fonts.components_inline.input')"

View file

@ -7,6 +7,7 @@ import SharedComputedObject from '../helpers/shared_computed_object.js'
import UnitSetting from '../helpers/unit_setting.vue' import UnitSetting from '../helpers/unit_setting.vue'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const GeneralTab = { const GeneralTab = {
data() { data() {
@ -32,12 +33,12 @@ const GeneralTab = {
'suggestionsEnabled', 'suggestionsEnabled',
]), ]),
columns() { columns() {
const mode = this.$store.getters.mergedConfig.thirdColumnMode const mode = useSyncConfigStore().mergedConfig.thirdColumnMode
const notif = mode === 'none' ? [] : ['notifs'] const notif = mode === 'none' ? [] : ['notifs']
if ( if (
this.$store.getters.mergedConfig.sidebarRight || useSyncConfigStore().mergedConfig.sidebarRight ||
mode === 'postform' mode === 'postform'
) { ) {
return [...notif, 'content', 'sidebar'] return [...notif, 'content', 'sidebar']

View file

@ -11,6 +11,7 @@ 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.js' import { useInterfaceStore } from 'src/stores/interface.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { import {
getContrastRatioLayers, getContrastRatioLayers,
@ -81,7 +82,7 @@ export default {
}), }),
availableStyles: [], availableStyles: [],
selected: '', selected: '',
selectedTheme: this.$store.getters.mergedConfig.theme, selectedTheme: useSyncConfigStore().mergedConfig.theme,
themeWarning: undefined, themeWarning: undefined,
tempImportFile: undefined, tempImportFile: undefined,
engineVersion: 0, engineVersion: 0,

View file

@ -478,7 +478,7 @@ const Status = {
return this.$store.state.users.currentUser return this.$store.state.users.currentUser
}, },
mergedConfig() { mergedConfig() {
return this.$store.getters.mergedConfig return useSyncConfigStore().mergedConfig
}, },
isSuspendable() { isSuspendable() {
return !this.replying && this.mediaPlaying.length === 0 return !this.replying && this.mediaPlaying.length === 0

View file

@ -7,6 +7,7 @@ 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.js' 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 {
@ -74,7 +75,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:
!this.$store.getters.mergedConfig.collapseMessageWithSubject, !useSyncConfigStore().mergedConfig.collapseMessageWithSubject,
} }
}, },
computed: { computed: {

View file

@ -1,3 +1,5 @@
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const StillImage = { const StillImage = {
props: [ props: [
'src', 'src',
@ -15,7 +17,7 @@ const StillImage = {
return { return {
// for lazy loading, see loadLazy() // for lazy loading, see loadLazy()
realSrc: this.src, realSrc: this.src,
stopGifs: this.$store.getters.mergedConfig.stopGifs, stopGifs: useSyncConfigStore().mergedConfig.stopGifs,
} }
}, },
computed: { computed: {

View file

@ -9,6 +9,7 @@ import Status from '../status/status.vue'
import TimelineMenu from '../timeline_menu/timeline_menu.vue' import TimelineMenu from '../timeline_menu/timeline_menu.vue'
import { useInterfaceStore } from 'src/stores/interface.js' import { useInterfaceStore } from 'src/stores/interface.js'
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'
@ -125,7 +126,7 @@ const Timeline = {
return this.timeline.visibleStatuses.slice(min, max).map((_) => _.id) return this.timeline.visibleStatuses.slice(min, max).map((_) => _.id)
}, },
virtualScrollingEnabled() { virtualScrollingEnabled() {
return this.$store.getters.mergedConfig.virtualScrolling return useSyncConfigStore().mergedConfig.virtualScrolling
}, },
...mapState(useInterfaceStore, { ...mapState(useInterfaceStore, {
mobileLayout: (store) => store.layoutType === 'mobile', mobileLayout: (store) => store.layoutType === 'mobile',
@ -313,7 +314,7 @@ const Timeline = {
}, },
watch: { watch: {
newStatusCount(count) { newStatusCount(count) {
if (!this.$store.getters.mergedConfig.streaming) { if (!useSyncConfigStore().mergedConfig.streaming) {
return return
} }
if (count > 0) { if (count > 0) {
@ -323,7 +324,9 @@ 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 {

View file

@ -27,6 +27,7 @@ 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 { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { usePostStatusStore } from 'src/stores/post_status' import { usePostStatusStore } from 'src/stores/post_status'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { propsToNative } from 'src/services/attributes_helper/attributes_helper.service.js' import { propsToNative } from 'src/services/attributes_helper/attributes_helper.service.js'
import localeService from 'src/services/locale/locale.service.js' import localeService from 'src/services/locale/locale.service.js'
@ -223,12 +224,12 @@ export default {
userHighlightType: { userHighlightType: {
get() { get() {
const data = const data =
this.$store.getters.mergedConfig.highlight[this.user.screen_name] useSyncConfigStore().mergedConfig.highlight[this.user.screen_name]
return (data && data.type) || 'disabled' return (data && data.type) || 'disabled'
}, },
set(type) { set(type) {
const data = const data =
this.$store.getters.mergedConfig.highlight[this.user.screen_name] useSyncConfigStore().mergedConfig.highlight[this.user.screen_name]
if (type !== 'disabled') { if (type !== 'disabled') {
this.$store.dispatch('setHighlight', { this.$store.dispatch('setHighlight', {
user: this.user.screen_name, user: this.user.screen_name,
@ -247,7 +248,7 @@ export default {
userHighlightColor: { userHighlightColor: {
get() { get() {
const data = const data =
this.$store.getters.mergedConfig.highlight[this.user.screen_name] useSyncConfigStore().mergedConfig.highlight[this.user.screen_name]
return data && data.color return data && data.color
}, },
set(color) { set(color) {

View file

@ -293,7 +293,7 @@
</div> </div>
</div> </div>
<div <div
v-if="!editable && loggedIn && isOtherUser && (hasNote || !hideBio) && !mergedConfig.userCardHidePersonalMarks" v-if="!editable && loggedIn && isOtherUser && (hasNote || !hideBio) && !userCardHidePersonalMarks"
class="personal-marks" class="personal-marks"
> >
<UserNote <UserNote
@ -357,7 +357,7 @@
<RichContent <RichContent
v-if="!hideBio" v-if="!hideBio"
class="user-card-bio" class="user-card-bio"
:class="{ '-justify-left': mergedConfig.userCardLeftJustify }" :class="{ '-justify-left': userCardLeftJustify }"
:html="editable ? newBio.replace(/\n/g, '<br>') : user.description_html" :html="editable ? newBio.replace(/\n/g, '<br>') : user.description_html"
:emoji="editable ? emoji : user.emoji" :emoji="editable ? emoji : user.emoji"
:handle-links="true" :handle-links="true"
@ -368,7 +368,7 @@
v-model="newBio" v-model="newBio"
enable-emoji-picker enable-emoji-picker
class="user-card-bio" class="user-card-bio"
:class="{ '-justify-left': mergedConfig.userCardLeftJustify }" :class="{ '-justify-left': userCardLeftJustify }"
:suggest="emojiUserSuggestor" :suggest="emojiUserSuggestor"
> >
<template #default="inputProps"> <template #default="inputProps">
@ -505,11 +505,11 @@
class="user-extras" class="user-extras"
> >
<span <span
v-if="!editable && !mergedConfig.hideUserStats" v-if="!editable && !hideUserStats"
class="user-stats" class="user-stats"
> >
<dl <dl
v-if="!mergedConfig.hideUserStats && !hideBio" v-if="!hideUserStats && !hideBio"
class="user-count" class="user-count"
> >
<dd>{{ user.statuses_count }}</dd> <dd>{{ user.statuses_count }}</dd>

View file

@ -1,7 +1,10 @@
import { mapState } from 'pinia'
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import UserCard from '../user_card/user_card.vue' import UserCard from '../user_card/user_card.vue'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const UserPopover = { const UserPopover = {
name: 'UserPopover', name: 'UserPopover',
props: ['userId', 'overlayCenters', 'disabled', 'overlayCentersSelector'], props: ['userId', 'overlayCenters', 'disabled', 'overlayCentersSelector'],
@ -9,14 +12,11 @@ const UserPopover = {
UserCard, UserCard,
Popover: defineAsyncComponent(() => import('../popover/popover.vue')), Popover: defineAsyncComponent(() => import('../popover/popover.vue')),
}, },
computed: { computed: mapState(useSyncConfigStore, {
userPopoverAvatarAction() { userPopoverAvatarAction: (state) =>
return this.$store.getters.mergedConfig.userPopoverAvatarAction state.mergedConfig.userPopoverAvatarAction,
}, userPopoverOverlay: (state) => state.mergedConfig.userPopoverOverlay,
userPopoverOverlay() { }),
return this.$store.getters.mergedConfig.userPopoverOverlay
},
},
} }
export default UserPopover export default UserPopover

View file

@ -2,13 +2,15 @@ import Checkbox from 'src/components/checkbox/checkbox.vue'
import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue' import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
import Select from 'src/components/select/select.vue' import Select from 'src/components/select/select.vue'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { durationStrToMs } from 'src/services/date_utils/date_utils.js' import { durationStrToMs } from 'src/services/date_utils/date_utils.js'
const UserTimedFilterModal = { const UserTimedFilterModal = {
data() { data() {
const action = this.isMute const action = this.isMute
? this.$store.getters.mergedConfig.onMuteDefaultAction ? useSyncConfigStore().mergedConfig.onMuteDefaultAction
: this.$store.getters.mergedConfig.onBlockDefaultAction : useSyncConfigStore().mergedConfig.onBlockDefaultAction
const doAsk = action === 'ask' const doAsk = action === 'ask'
const defaultValues = {} const defaultValues = {}
@ -44,9 +46,9 @@ const UserTimedFilterModal = {
computed: { computed: {
shouldConfirm() { shouldConfirm() {
if (this.isMute) { if (this.isMute) {
return this.$store.getters.mergedConfig.onMuteDefaultAction === 'ask' return useSyncConfigStore().mergedConfig.onMuteDefaultAction === 'ask'
} else { } else {
return this.$store.getters.mergedConfig.onBlockDefaultAction === 'ask' return useSyncConfigStore().mergedConfig.onBlockDefaultAction === 'ask'
} }
}, },
expiryString() { expiryString() {

View file

@ -1,3 +1,5 @@
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const VideoAttachment = { const VideoAttachment = {
props: ['attachment', 'controls'], props: ['attachment', 'controls'],
data() { data() {
@ -9,10 +11,10 @@ const VideoAttachment = {
}, },
computed: { computed: {
loopVideo() { loopVideo() {
if (this.$store.getters.mergedConfig.loopVideoSilentOnly) { if (useSyncConfigStore().mergedConfig.loopVideoSilentOnly) {
return !this.hasAudio return !this.hasAudio
} }
return this.$store.getters.mergedConfig.loopVideo return useSyncConfigStore().mergedConfig.loopVideo
}, },
}, },
methods: { methods: {

View file

@ -1,6 +1,8 @@
import apiService from '../../services/api/api.service.js' import apiService from '../../services/api/api.service.js'
import FollowCard from '../follow_card/follow_card.vue' import FollowCard from '../follow_card/follow_card.vue'
import { useInstanceStore } from 'src/stores/instance.js'
const WhoToFollow = { const WhoToFollow = {
components: { components: {
FollowCard, FollowCard,

View file

@ -1,10 +1,13 @@
import { createTestingPinia } from '@pinia/testing' import { createTestingPinia } from '@pinia/testing'
import { flushPromises, mount } from '@vue/test-utils' import { flushPromises, mount } from '@vue/test-utils'
import { setActivePinia } from 'pinia'
import { nextTick } from 'vue' import { nextTick } from 'vue'
import PostStatusForm from 'src/components/post_status_form/post_status_form.vue' import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
import { $t, mountOpts, waitForEvent } from '../../../fixtures/setup_test' import { $t, mountOpts, waitForEvent } from '../../../fixtures/setup_test'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const autoSaveOrNot = (caseFn, caseTitle, runFn) => { const autoSaveOrNot = (caseFn, caseTitle, runFn) => {
caseFn(`${caseTitle} with auto-save`, function () { caseFn(`${caseTitle} with auto-save`, function () {
return runFn.bind(this)(true) return runFn.bind(this)(true)
@ -36,17 +39,19 @@ afterEach(() => {
}) })
describe('Draft saving', () => { describe('Draft saving', () => {
createTestingPinia() beforeEach(() => {
setActivePinia(createTestingPinia())
})
autoSaveOrNot( autoSaveOrNot(
it, it,
'should save when the button is clicked', 'should save when the button is clicked',
async (autoSave) => { async (autoSave) => {
const wrapper = mount(PostStatusForm, mountOpts()) const wrapper = mount(PostStatusForm, mountOpts())
await wrapper.vm.$store.dispatch('setOption', { const store = useSyncConfigStore()
name: 'autoSaveDraft', store.mergedConfig = {
value: autoSave, autoSaveDraft: autoSave,
}) }
expect(wrapper.vm.$store.getters.draftCount).to.equal(0) expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
const textarea = wrapper.get('textarea') const textarea = wrapper.get('textarea')
@ -63,10 +68,10 @@ describe('Draft saving', () => {
it('should auto-save if it is enabled', async function () { it('should auto-save if it is enabled', async function () {
vi.useFakeTimers() vi.useFakeTimers()
const wrapper = mount(PostStatusForm, mountOpts()) const wrapper = mount(PostStatusForm, mountOpts())
await wrapper.vm.$store.dispatch('setOption', { const store = useSyncConfigStore()
name: 'autoSaveDraft', store.mergedConfig = {
value: true, autoSaveDraft: true,
}) }
expect(wrapper.vm.$store.getters.draftCount).to.equal(0) expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
const textarea = wrapper.get('textarea') const textarea = wrapper.get('textarea')
await textarea.setValue('mew mew') await textarea.setValue('mew mew')
@ -86,10 +91,10 @@ describe('Draft saving', () => {
}, },
}), }),
) )
await wrapper.vm.$store.dispatch('setOption', { const store = useSyncConfigStore()
name: 'autoSaveDraft', store.mergedConfig = {
value: true, autoSaveDraft: true,
}) }
expect(wrapper.vm.$store.getters.draftCount).to.equal(0) expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
const textarea = wrapper.get('textarea') const textarea = wrapper.get('textarea')
await textarea.setValue('mew mew') await textarea.setValue('mew mew')
@ -107,14 +112,11 @@ describe('Draft saving', () => {
}, },
}), }),
) )
await wrapper.vm.$store.dispatch('setOption', { const store = useSyncConfigStore()
name: 'autoSaveDraft', store.mergedConfig = {
value: false, autoSaveDraft: false,
}) unsavedPostAction: 'save',
await wrapper.vm.$store.dispatch('setOption', { }
name: 'unsavedPostAction',
value: 'save',
})
expect(wrapper.vm.$store.getters.draftCount).to.equal(0) expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
const textarea = wrapper.get('textarea') const textarea = wrapper.get('textarea')
await textarea.setValue('mew mew') await textarea.setValue('mew mew')
@ -132,14 +134,11 @@ describe('Draft saving', () => {
}, },
}), }),
) )
await wrapper.vm.$store.dispatch('setOption', { const store = useSyncConfigStore()
name: 'autoSaveDraft', store.mergedConfig = {
value: false, autoSaveDraft: false,
}) unsavedPostAction: 'discard',
await wrapper.vm.$store.dispatch('setOption', { }
name: 'unsavedPostAction',
value: 'discard',
})
expect(wrapper.vm.$store.getters.draftCount).to.equal(0) expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
const textarea = wrapper.get('textarea') const textarea = wrapper.get('textarea')
await textarea.setValue('mew mew') await textarea.setValue('mew mew')
@ -157,14 +156,11 @@ describe('Draft saving', () => {
}, },
}), }),
) )
await wrapper.vm.$store.dispatch('setOption', { const store = useSyncConfigStore(createTestingPinia())
name: 'autoSaveDraft', store.mergedConfig = {
value: false, autoSaveDraft: false,
}) unsavedPostAction: 'confirm',
await wrapper.vm.$store.dispatch('setOption', { }
name: 'unsavedPostAction',
value: 'confirm',
})
expect(wrapper.vm.$store.getters.draftCount).to.equal(0) expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
const textarea = wrapper.get('textarea') const textarea = wrapper.get('textarea')
await textarea.setValue('mew mew') await textarea.setValue('mew mew')

View file

@ -7,18 +7,13 @@ createTestingPinia()
import EmojiInput from 'src/components/emoji_input/emoji_input.vue' import EmojiInput from 'src/components/emoji_input/emoji_input.vue'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const generateInput = (value, padEmoji = true) => { const generateInput = (value, padEmoji = true) => {
const wrapper = shallowMount(EmojiInput, { const wrapper = shallowMount(EmojiInput, {
global: { global: {
renderStubDefaultSlot: true, renderStubDefaultSlot: true,
mocks: { mocks: {
$store: {
getters: {
mergedConfig: {
padEmoji,
},
},
},
$t: (msg) => msg, $t: (msg) => msg,
}, },
stubs: { stubs: {
@ -49,6 +44,12 @@ const generateInput = (value, padEmoji = true) => {
} }
describe('EmojiInput', () => { describe('EmojiInput', () => {
beforeEach(() => {
const store = useSyncConfigStore(createTestingPinia())
store.mergedConfig = {
padEmoji: true,
}
})
describe('insertion mechanism', () => { describe('insertion mechanism', () => {
it('inserts string at the end with trailing space', () => { it('inserts string at the end with trailing space', () => {
const initialString = 'Testing' const initialString = 'Testing'
@ -112,6 +113,10 @@ describe('EmojiInput', () => {
it('inserts string without any padding if padEmoji setting is set to false', () => { it('inserts string without any padding if padEmoji setting is set to false', () => {
const initialString = 'Eat some spam!' const initialString = 'Eat some spam!'
const wrapper = generateInput(initialString, false) const wrapper = generateInput(initialString, false)
const store = useSyncConfigStore(createTestingPinia())
store.mergedConfig = {
padEmoji: false,
}
const input = wrapper.find('input') const input = wrapper.find('input')
input.setValue(initialString) input.setValue(initialString)
wrapper.setData({ caret: initialString.length, keepOpen: false }) wrapper.setData({ caret: initialString.length, keepOpen: false })
@ -147,6 +152,10 @@ describe('EmojiInput', () => {
it('correctly sets caret after insertion if padEmoji setting is set to false', async () => { it('correctly sets caret after insertion if padEmoji setting is set to false', async () => {
const initialString = '1234' const initialString = '1234'
const wrapper = generateInput(initialString, false) const wrapper = generateInput(initialString, false)
const store = useSyncConfigStore(createTestingPinia())
store.mergedConfig = {
padEmoji: false,
}
const input = wrapper.find('input') const input = wrapper.find('input')
input.setValue(initialString) input.setValue(initialString)
wrapper.setData({ caret: initialString.length }) wrapper.setData({ caret: initialString.length })