diff --git a/src/components/settings_modal/helpers/boolean_setting.js b/src/components/settings_modal/helpers/boolean_setting.js
index 5c52f697..353e551c 100644
--- a/src/components/settings_modal/helpers/boolean_setting.js
+++ b/src/components/settings_modal/helpers/boolean_setting.js
@@ -1,14 +1,17 @@
import { get, set } from 'lodash'
import Checkbox from 'src/components/checkbox/checkbox.vue'
import ModifiedIndicator from './modified_indicator.vue'
+import ServerSideIndicator from './server_side_indicator.vue'
export default {
components: {
Checkbox,
- ModifiedIndicator
+ ModifiedIndicator,
+ ServerSideIndicator
},
props: [
'path',
- 'disabled'
+ 'disabled',
+ 'expert'
],
computed: {
pathDefault () {
@@ -26,8 +29,14 @@ export default {
defaultState () {
return get(this.$parent, this.pathDefault)
},
+ isServerSide () {
+ return this.path.startsWith('serverSide_')
+ },
isChanged () {
- return this.state !== this.defaultState
+ return !this.path.startsWith('serverSide_') && this.state !== this.defaultState
+ },
+ matchesExpertLevel () {
+ return (this.expert || 0) <= this.$parent.expertLevel
}
},
methods: {
diff --git a/src/components/settings_modal/helpers/boolean_setting.vue b/src/components/settings_modal/helpers/boolean_setting.vue
index c3ee6583..e0d825f2 100644
--- a/src/components/settings_modal/helpers/boolean_setting.vue
+++ b/src/components/settings_modal/helpers/boolean_setting.vue
@@ -1,5 +1,6 @@
diff --git a/src/components/settings_modal/helpers/choice_setting.js b/src/components/settings_modal/helpers/choice_setting.js
index a15f6bac..4677d4c1 100644
--- a/src/components/settings_modal/helpers/choice_setting.js
+++ b/src/components/settings_modal/helpers/choice_setting.js
@@ -1,15 +1,18 @@
import { get, set } from 'lodash'
import Select from 'src/components/select/select.vue'
import ModifiedIndicator from './modified_indicator.vue'
+import ServerSideIndicator from './server_side_indicator.vue'
export default {
components: {
Select,
- ModifiedIndicator
+ ModifiedIndicator,
+ ServerSideIndicator
},
props: [
'path',
'disabled',
- 'options'
+ 'options',
+ 'expert'
],
computed: {
pathDefault () {
@@ -27,8 +30,14 @@ export default {
defaultState () {
return get(this.$parent, this.pathDefault)
},
+ isServerSide () {
+ return this.path.startsWith('serverSide_')
+ },
isChanged () {
- return this.state !== this.defaultState
+ return !this.path.startsWith('serverSide_') && this.state !== this.defaultState
+ },
+ matchesExpertLevel () {
+ return (this.expert || 0) <= this.$parent.expertLevel
}
},
methods: {
diff --git a/src/components/settings_modal/helpers/choice_setting.vue b/src/components/settings_modal/helpers/choice_setting.vue
index fa17661b..54f5d0a7 100644
--- a/src/components/settings_modal/helpers/choice_setting.vue
+++ b/src/components/settings_modal/helpers/choice_setting.vue
@@ -1,5 +1,6 @@
diff --git a/src/components/settings_modal/helpers/integer_setting.js b/src/components/settings_modal/helpers/integer_setting.js
index fa6569ab..4a19bd7c 100644
--- a/src/components/settings_modal/helpers/integer_setting.js
+++ b/src/components/settings_modal/helpers/integer_setting.js
@@ -7,7 +7,8 @@ export default {
props: {
path: String,
disabled: Boolean,
- min: Number
+ min: Number,
+ expert: Number
},
computed: {
pathDefault () {
@@ -27,6 +28,9 @@ export default {
},
isChanged () {
return this.state !== this.defaultState
+ },
+ matchesExpertLevel () {
+ return (this.expert || 0) <= this.$parent.expertLevel
}
},
methods: {
diff --git a/src/components/settings_modal/helpers/integer_setting.vue b/src/components/settings_modal/helpers/integer_setting.vue
index 8284abcc..408b0925 100644
--- a/src/components/settings_modal/helpers/integer_setting.vue
+++ b/src/components/settings_modal/helpers/integer_setting.vue
@@ -1,5 +1,8 @@
-
+
diff --git a/src/components/settings_modal/helpers/server_side_indicator.vue b/src/components/settings_modal/helpers/server_side_indicator.vue
new file mode 100644
index 00000000..143a86a1
--- /dev/null
+++ b/src/components/settings_modal/helpers/server_side_indicator.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+ {{ $t('settings.setting_server_side') }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/settings_modal/helpers/shared_computed_object.js b/src/components/settings_modal/helpers/shared_computed_object.js
index 2c833c0c..12431dca 100644
--- a/src/components/settings_modal/helpers/shared_computed_object.js
+++ b/src/components/settings_modal/helpers/shared_computed_object.js
@@ -1,4 +1,5 @@
import { defaultState as configDefaultState } from 'src/modules/config.js'
+import { defaultState as serverSideConfigDefaultState } from 'src/modules/serverSideConfig.js'
const SharedComputedObject = () => ({
user () {
@@ -22,6 +23,14 @@ const SharedComputedObject = () => ({
}
}])
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}),
+ ...Object.keys(serverSideConfigDefaultState)
+ .map(key => ['serverSide_' + key, {
+ get () { return this.$store.state.serverSideConfig[key] },
+ set (value) {
+ this.$store.dispatch('setServerSideOption', { name: key, value })
+ }
+ }])
+ .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}),
// Special cases (need to transform values or perform actions first)
useStreamingApi: {
get () { return this.$store.getters.mergedConfig.useStreamingApi },
diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js
index 04043483..82ea410e 100644
--- a/src/components/settings_modal/settings_modal.js
+++ b/src/components/settings_modal/settings_modal.js
@@ -3,6 +3,7 @@ import PanelLoading from 'src/components/panel_loading/panel_loading.vue'
import AsyncComponentError from 'src/components/async_component_error/async_component_error.vue'
import getResettableAsyncComponent from 'src/services/resettable_async_component.js'
import Popover from '../popover/popover.vue'
+import Checkbox from 'src/components/checkbox/checkbox.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { cloneDeep } from 'lodash'
import {
@@ -51,6 +52,7 @@ const SettingsModal = {
components: {
Modal,
Popover,
+ Checkbox,
SettingsModalContent: getResettableAsyncComponent(
() => import('./settings_modal_content.vue'),
{
@@ -159,6 +161,15 @@ const SettingsModal = {
},
modalPeeked () {
return this.$store.state.interface.settingsModalState === 'minimized'
+ },
+ expertLevel: {
+ get () {
+ return this.$store.state.config.expertLevel > 0
+ },
+ set (value) {
+ console.log(value)
+ this.$store.dispatch('setOption', { name: 'expertLevel', value: value ? 1 : 0 })
+ }
}
}
}
diff --git a/src/components/settings_modal/settings_modal.scss b/src/components/settings_modal/settings_modal.scss
index 90446b36..fb466f2f 100644
--- a/src/components/settings_modal/settings_modal.scss
+++ b/src/components/settings_modal/settings_modal.scss
@@ -48,4 +48,11 @@
}
}
}
+
+ .settings-footer {
+ display: flex;
+ >* {
+ margin-right: 0.5em;
+ }
+ }
}
diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue
index 583c2ecc..1805c77f 100644
--- a/src/components/settings_modal/settings_modal.vue
+++ b/src/components/settings_modal/settings_modal.vue
@@ -53,7 +53,7 @@
-
diff --git a/src/components/settings_modal/tabs/filtering_tab.vue b/src/components/settings_modal/tabs/filtering_tab.vue
index 0774c818..dc48902f 100644
--- a/src/components/settings_modal/tabs/filtering_tab.vue
+++ b/src/components/settings_modal/tabs/filtering_tab.vue
@@ -21,6 +21,7 @@
@@ -29,6 +30,7 @@
@@ -53,6 +55,7 @@
{{ $t('settings.filtering_explanation') }}
{{ $t('settings.attachments') }}
+
+
+
+
-
+
{{ $t('settings.user_profiles') }}
-
-
{{ $t('settings.notifications') }}
-
- -
- {{ $t('settings.notification_visibility') }}
-
- -
-
- {{ $t('settings.notification_visibility_likes') }}
-
-
- -
-
- {{ $t('settings.notification_visibility_repeats') }}
-
-
- -
-
- {{ $t('settings.notification_visibility_follows') }}
-
-
- -
-
- {{ $t('settings.notification_visibility_mentions') }}
-
-
- -
-
- {{ $t('settings.notification_visibility_moves') }}
-
-
- -
-
- {{ $t('settings.notification_visibility_emoji_reactions') }}
-
-
-
-
-
-
diff --git a/src/components/settings_modal/tabs/general_tab.js b/src/components/settings_modal/tabs/general_tab.js
index 03ca99fa..62d86176 100644
--- a/src/components/settings_modal/tabs/general_tab.js
+++ b/src/components/settings_modal/tabs/general_tab.js
@@ -1,9 +1,11 @@
import BooleanSetting from '../helpers/boolean_setting.vue'
import ChoiceSetting from '../helpers/choice_setting.vue'
+import ScopeSelector from 'src/components/scope_selector/scope_selector.vue'
import IntegerSetting from '../helpers/integer_setting.vue'
import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js'
+import ServerSideIndicator from '../helpers/server_side_indicator.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faGlobe
@@ -49,7 +51,9 @@ const GeneralTab = {
BooleanSetting,
ChoiceSetting,
IntegerSetting,
- InterfaceLanguageSwitcher
+ InterfaceLanguageSwitcher,
+ ScopeSelector,
+ ServerSideIndicator
},
computed: {
postFormats () {
@@ -69,6 +73,11 @@ const GeneralTab = {
},
instanceShoutboxPresent () { return this.$store.state.instance.shoutAvailable },
...SharedComputedObject()
+ },
+ methods: {
+ changeDefaultScope (value) {
+ this.$store.dispatch('setServerSideOption', { name: 'defaultScope', value })
+ }
}
}
diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue
index ba01fdeb..a2c6bffa 100644
--- a/src/components/settings_modal/tabs/general_tab.vue
+++ b/src/components/settings_modal/tabs/general_tab.vue
@@ -45,26 +45,42 @@
-
+
{{ $t('settings.useStreamingApi') }}
-
-
- {{ $t('settings.useStreamingApiWarning') }}
-
-
+
{{ $t('settings.virtual_scrolling') }}
-
+
+ {{ $t('settings.always_show_post_button') }}
+
+
+
+
{{ $t('settings.autohide_floating_post_button') }}
-
+
{{ $t('settings.hide_shoutbox') }}
@@ -73,85 +89,6 @@
{{ $t('settings.post_look_feel') }}
- -
-
- {{ $t('settings.collapse_subject') }}
-
-
- -
-
- {{ $t('settings.emoji_reactions_on_timeline') }}
-
-
- {{ $t('settings.attachments') }}
- -
-
- {{ $t('settings.use_contain_fit') }}
-
-
- -
-
- {{ $t('settings.nsfw_clickthrough') }}
-
-
-
- -
-
- {{ $t('settings.preload_images') }}
-
-
- -
-
- {{ $t('settings.use_one_click_nsfw') }}
-
-
-
- -
-
- {{ $t('settings.loop_video') }}
-
-
-
- -
-
- {{ $t('settings.play_videos_in_modal') }}
-
-
- {{ $t('settings.fun') }}
- -
-
- {{ $t('settings.greentext') }}
-
-
- -
-
- {{ $t('settings.show_yous') }}
-
-
-
-
-
+
{{ $t('settings.tree_fade_ancestors') }}
@@ -179,6 +119,7 @@
{{ $t('settings.max_depth_in_thread') }}
@@ -188,11 +129,105 @@
id="conversationOtherRepliesButton"
path="conversationOtherRepliesButton"
:options="conversationOtherRepliesButtonOptions"
+ :expert="1"
>
{{ $t('settings.conversation_other_replies_button') }}
+
+
+ {{ $t('settings.collapse_subject') }}
+
+
+
+
+ {{ $t('settings.emoji_reactions_on_timeline') }}
+
+
+
+
+ {{ $t('settings.no_rich_text_description') }}
+
+
+
{{ $t('settings.attachments') }}
+
+
+ {{ $t('settings.use_contain_fit') }}
+
+
+
+
+ {{ $t('settings.nsfw_clickthrough') }}
+
+
+
+ -
+
+ {{ $t('settings.preload_images') }}
+
+
+ -
+
+ {{ $t('settings.use_one_click_nsfw') }}
+
+
+
+
+
+ {{ $t('settings.loop_video') }}
+
+
+
+
+
+ {{ $t('settings.play_videos_in_modal') }}
+
+
+
{{ $t('settings.mention_links') }}
-
-
+
+
{{ $t('settings.mention_link_show_tooltip') }}
-
-
- {{ $t('settings.use_at_icon') }}
-
-
-
-
- {{ $t('settings.mention_link_show_avatar') }}
-
-
-
-
- {{ $t('settings.mention_link_fade_domain') }}
-
-
-
-
- {{ $t('settings.mention_link_bolden_you') }}
-
-
+
+
+ {{ $t('settings.use_at_icon') }}
+
+
+
+
+ {{ $t('settings.mention_link_show_avatar') }}
+
+
+
+
+ {{ $t('settings.mention_link_fade_domain') }}
+
+
+
+
+ {{ $t('settings.mention_link_bolden_you') }}
+
+
+
+ {{ $t('settings.fun') }}
+
+
+
+ {{ $t('settings.greentext') }}
+
+
+
+
+ {{ $t('settings.show_yous') }}
+
+
-
+
{{ $t('settings.composing') }}
-
-
+
+
+ -
+
+
+ {{ $t('settings.sensitive_by_default') }}
+
+
+ -
+
{{ $t('settings.scope_copy') }}
-
-
+
{{ $t('settings.subject_input_always_show') }}
@@ -254,6 +345,7 @@
id="subjectLineBehavior"
path="subjectLineBehavior"
:options="subjectLineOptions"
+ expert="1"
>
{{ $t('settings.subject_line_behavior') }}
@@ -268,43 +360,39 @@
-
-
+
{{ $t('settings.minimal_scopes_mode') }}
-
-
- {{ $t('settings.sensitive_by_default') }}
-
-
- -
-
+
{{ $t('settings.always_show_post_button') }}
-
-
+
{{ $t('settings.autohide_floating_post_button') }}
-
-
+
{{ $t('settings.pad_emoji') }}
-
-
-
{{ $t('settings.notifications') }}
-
- -
-
- {{ $t('settings.enable_web_push_notifications') }}
-
-
-
-
diff --git a/src/components/settings_modal/tabs/notifications_tab.js b/src/components/settings_modal/tabs/notifications_tab.js
index 3e44c95d..3c6ab87f 100644
--- a/src/components/settings_modal/tabs/notifications_tab.js
+++ b/src/components/settings_modal/tabs/notifications_tab.js
@@ -1,4 +1,5 @@
-import Checkbox from 'src/components/checkbox/checkbox.vue'
+import BooleanSetting from '../helpers/boolean_setting.vue'
+import SharedComputedObject from '../helpers/shared_computed_object.js'
const NotificationsTab = {
data () {
@@ -9,12 +10,13 @@ const NotificationsTab = {
}
},
components: {
- Checkbox
+ BooleanSetting
},
computed: {
user () {
return this.$store.state.users.currentUser
- }
+ },
+ ...SharedComputedObject()
},
methods: {
updateNotificationSettings () {
diff --git a/src/components/settings_modal/tabs/notifications_tab.vue b/src/components/settings_modal/tabs/notifications_tab.vue
index 7e0568ea..86be6095 100644
--- a/src/components/settings_modal/tabs/notifications_tab.vue
+++ b/src/components/settings_modal/tabs/notifications_tab.vue
@@ -2,30 +2,77 @@
{{ $t('settings.notification_setting_filters') }}
-
-
- {{ $t('settings.notification_setting_block_from_strangers') }}
-
-
+
+ -
+
+ {{ $t('settings.notification_setting_block_from_strangers') }}
+
+
+ -
+ {{ $t('settings.notification_visibility') }}
+
+ -
+
+ {{ $t('settings.notification_visibility_likes') }}
+
+
+ -
+
+ {{ $t('settings.notification_visibility_repeats') }}
+
+
+ -
+
+ {{ $t('settings.notification_visibility_follows') }}
+
+
+ -
+
+ {{ $t('settings.notification_visibility_mentions') }}
+
+
+ -
+
+ {{ $t('settings.notification_visibility_moves') }}
+
+
+ -
+
+ {{ $t('settings.notification_visibility_emoji_reactions') }}
+
+
+
+
+
-
+
{{ $t('settings.notification_setting_privacy') }}
-
-
- {{ $t('settings.notification_setting_hide_notification_contents') }}
-
-
+
+ -
+
+ {{ $t('settings.enable_web_push_notifications') }}
+
+
+ -
+
+ {{ $t('settings.notification_setting_hide_notification_contents') }}
+
+
+
{{ $t('settings.notification_mutes') }}
{{ $t('settings.notification_blocks') }}
-
diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js
index 64079fcd..bee8a7bb 100644
--- a/src/components/settings_modal/tabs/profile_tab.js
+++ b/src/components/settings_modal/tabs/profile_tab.js
@@ -8,6 +8,9 @@ import EmojiInput from 'src/components/emoji_input/emoji_input.vue'
import suggestor from 'src/components/emoji_input/suggestor.js'
import Autosuggest from 'src/components/autosuggest/autosuggest.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue'
+import BooleanSetting from '../helpers/boolean_setting.vue'
+import SharedComputedObject from '../helpers/shared_computed_object.js'
+
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faTimes,
@@ -27,18 +30,10 @@ const ProfileTab = {
newName: this.$store.state.users.currentUser.name_unescaped,
newBio: unescape(this.$store.state.users.currentUser.description),
newLocked: this.$store.state.users.currentUser.locked,
- newNoRichText: this.$store.state.users.currentUser.no_rich_text,
- newDefaultScope: this.$store.state.users.currentUser.default_scope,
newFields: this.$store.state.users.currentUser.fields.map(field => ({ name: field.name, value: field.value })),
- hideFollows: this.$store.state.users.currentUser.hide_follows,
- hideFollowers: this.$store.state.users.currentUser.hide_followers,
- hideFollowsCount: this.$store.state.users.currentUser.hide_follows_count,
- hideFollowersCount: this.$store.state.users.currentUser.hide_followers_count,
showRole: this.$store.state.users.currentUser.show_role,
role: this.$store.state.users.currentUser.role,
- discoverable: this.$store.state.users.currentUser.discoverable,
bot: this.$store.state.users.currentUser.bot,
- allowFollowingMove: this.$store.state.users.currentUser.allow_following_move,
pickAvatarBtnVisible: true,
bannerUploading: false,
backgroundUploading: false,
@@ -54,12 +49,14 @@ const ProfileTab = {
EmojiInput,
Autosuggest,
ProgressButton,
- Checkbox
+ Checkbox,
+ BooleanSetting
},
computed: {
user () {
return this.$store.state.users.currentUser
},
+ ...SharedComputedObject(),
emojiUserSuggestor () {
return suggestor({
emoji: [
@@ -123,15 +120,7 @@ const ProfileTab = {
/* eslint-disable camelcase */
display_name: this.newName,
fields_attributes: this.newFields.filter(el => el != null),
- default_scope: this.newDefaultScope,
- no_rich_text: this.newNoRichText,
- hide_follows: this.hideFollows,
- hide_followers: this.hideFollowers,
- discoverable: this.discoverable,
bot: this.bot,
- allow_following_move: this.allowFollowingMove,
- hide_follows_count: this.hideFollowsCount,
- hide_followers_count: this.hideFollowersCount,
show_role: this.showRole
/* eslint-enable camelcase */
} }).then((user) => {
diff --git a/src/components/settings_modal/tabs/profile_tab.vue b/src/components/settings_modal/tabs/profile_tab.vue
index bb3c301d..e00f6e5b 100644
--- a/src/components/settings_modal/tabs/profile_tab.vue
+++ b/src/components/settings_modal/tabs/profile_tab.vue
@@ -25,61 +25,6 @@
class="bio resize-height"
/>
-
-
- {{ $t('settings.lock_account_description') }}
-
-
-
-
-
-
-
-
-
-
- {{ $t('settings.no_rich_text_description') }}
-
-
-
-
- {{ $t('settings.hide_follows_description') }}
-
-
-
-
- {{ $t('settings.hide_follows_count_description') }}
-
-
-
-
- {{ $t('settings.hide_followers_description') }}
-
-
-
-
- {{ $t('settings.hide_followers_count_description') }}
-
-
-
-
- {{ $t('settings.allow_following_move') }}
-
-
@@ -90,11 +35,6 @@
-
-
- {{ $t('settings.discoverable') }}
-
-
{{ $t('settings.profile_fields.label') }}
+
+
{{ $t('settings.account_privacy') }}
+
+ -
+
+ {{ $t('settings.lock_account_description') }}
+
+
+ -
+
+ {{ $t('settings.discoverable') }}
+
+
+ -
+
+ {{ $t('settings.allow_following_move') }}
+
+
+ -
+
+ {{ $t('settings.hide_favorites_description') }}
+
+
+ -
+
+ {{ $t('settings.hide_followers_description') }}
+
+
+ -
+
+ {{ $t('settings.hide_followers_count_description') }}
+
+
+
+
+ -
+
+ {{ $t('settings.hide_follows_description') }}
+
+
+ -
+
+ {{ $t('settings.hide_follows_count_description') }}
+
+
+
+
+
+
diff --git a/src/components/still-image/still-image.vue b/src/components/still-image/still-image.vue
index 4ea21506..e939b532 100644
--- a/src/components/still-image/still-image.vue
+++ b/src/components/still-image/still-image.vue
@@ -19,7 +19,7 @@
@load="onLoad"
@error="onError"
>
-
+
diff --git a/src/components/user_avatar/user_avatar.vue b/src/components/user_avatar/user_avatar.vue
index 29e03bcb..847d654b 100644
--- a/src/components/user_avatar/user_avatar.vue
+++ b/src/components/user_avatar/user_avatar.vue
@@ -8,7 +8,11 @@
:class="{ 'avatar-compact': compact, 'better-shadow': betterShadow }"
:image-load-error="imageLoadError"
>
-
+
{
+ const params = {}
+ set(params, path, value)
+ return rootState
+ .api
+ .backendInteractor
+ .updateProfile({ params })
+ .then(result => {
+ commit('addNewUsers', [result])
+ commit('setCurrentUser', result)
+ })
+}
+
+const notificationsApi = ({ rootState, commit }, { path, value, oldValue }) => {
+ const settings = {}
+ set(settings, path, value)
+ return rootState
+ .api
+ .backendInteractor
+ .updateNotificationSettings({ settings })
+ .then(result => {
+ if (result.status === 'success') {
+ commit('confirmServerSideOption', { name, value })
+ } else {
+ commit('confirmServerSideOption', { name, value: oldValue })
+ }
+ })
+}
+
+/**
+ * Map that stores relation between path for reading (from user profile),
+ * for writing (into API) an what API to use.
+ *
+ * Shorthand - instead of { get, set, api? } object it's possible to use string
+ * in case default api is used and get = set
+ *
+ * If no api is specified, defaultApi is used (see above)
+ */
+export const settingsMap = {
+ 'defaultScope': 'source.privacy',
+ 'defaultNSFW': 'source.sensitive', // BROKEN: pleroma/pleroma#2837
+ 'stripRichContent': {
+ get: 'source.pleroma.no_rich_text',
+ set: 'no_rich_text'
+ },
+ // Privacy
+ 'locked': 'locked',
+ 'acceptChatMessages': {
+ get: 'pleroma.accepts_chat_messages',
+ set: 'accepts_chat_messages'
+ },
+ 'allowFollowingMove': {
+ get: 'pleroma.allow_following_move',
+ set: 'allow_following_move'
+ },
+ 'discoverable': 'source.discoverable',
+ 'hideFavorites': {
+ get: 'pleroma.hide_favorites',
+ set: 'hide_favorites'
+ },
+ 'hideFollowers': {
+ get: 'pleroma.hide_followers',
+ set: 'hide_followers'
+ },
+ 'hideFollows': {
+ get: 'pleroma.hide_follows',
+ set: 'hide_follows'
+ },
+ 'hideFollowersCount': {
+ get: 'pleroma.hide_followers_count',
+ set: 'hide_followers_count'
+ },
+ 'hideFollowsCount': {
+ get: 'pleroma.hide_follows_count',
+ set: 'hide_follows_count'
+ },
+ // NotificationSettingsAPIs
+ 'webPushHideContents': {
+ get: 'pleroma.notification_settings.hide_notification_contents',
+ set: 'hide_notification_contents',
+ api: notificationsApi
+ },
+ 'blockNotificationsFromStrangers': {
+ get: 'pleroma.notification_settings.block_from_strangers',
+ set: 'block_from_strangers',
+ api: notificationsApi
+ }
+}
+
+export const defaultState = Object.fromEntries(Object.keys(settingsMap).map(key => [key, null]))
+
+const serverSideConfig = {
+ state: { ...defaultState },
+ mutations: {
+ confirmServerSideOption (state, { name, value }) {
+ set(state, name, value)
+ },
+ wipeServerSideOption (state, { name }) {
+ set(state, name, null)
+ },
+ wipeAllServerSideOptions (state) {
+ Object.keys(settingsMap).forEach(key => {
+ set(state, key, null)
+ })
+ },
+ // Set the settings based on their path location
+ setCurrentUser (state, user) {
+ Object.entries(settingsMap).forEach((map) => {
+ const [name, value] = map
+ const { get: path = value } = value
+ set(state, name, get(user._original, path))
+ })
+ }
+ },
+ actions: {
+ setServerSideOption ({ rootState, state, commit, dispatch }, { name, value }) {
+ const oldValue = get(state, name)
+ const map = settingsMap[name]
+ if (!map) throw new Error('Invalid server-side setting')
+ const { set: path = map, api = defaultApi } = map
+ commit('wipeServerSideOption', { name })
+
+ api({ rootState, commit }, { path, value, oldValue })
+ .catch((e) => {
+ console.warn('Error setting server-side option:', e)
+ commit('confirmServerSideOption', { name, value: oldValue })
+ })
+ },
+ logout ({ commit }) {
+ commit('wipeAllServerSideOptions')
+ }
+ }
+}
+
+export default serverSideConfig
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 7025d803..f219c161 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -44,6 +44,7 @@ export const parseUser = (data) => {
const mastoShort = masto && !data.hasOwnProperty('avatar')
output.id = String(data.id)
+ output._original = data // used for server-side settings
if (masto) {
output.screen_name = data.acct