diff --git a/src/components/settings_modal/admin_tabs/rates_tab.js b/src/components/settings_modal/admin_tabs/rates_tab.js new file mode 100644 index 000000000..c602dcc8a --- /dev/null +++ b/src/components/settings_modal/admin_tabs/rates_tab.js @@ -0,0 +1,20 @@ +import RateSetting from '../helpers/rate_setting.vue' + +import SharedComputedObject from '../helpers/shared_computed_object.js' + +const RatesTab = { + provide () { + return { + defaultDraftMode: true, + defaultSource: 'admin' + } + }, + components: { + RateSetting, + }, + computed: { + ...SharedComputedObject() + } +} + +export default RatesTab diff --git a/src/components/settings_modal/admin_tabs/rates_tab.vue b/src/components/settings_modal/admin_tabs/rates_tab.vue new file mode 100644 index 000000000..dad5ad6e0 --- /dev/null +++ b/src/components/settings_modal/admin_tabs/rates_tab.vue @@ -0,0 +1,41 @@ + + + diff --git a/src/components/settings_modal/helpers/rate_setting.js b/src/components/settings_modal/helpers/rate_setting.js new file mode 100644 index 000000000..7425cdba3 --- /dev/null +++ b/src/components/settings_modal/helpers/rate_setting.js @@ -0,0 +1,53 @@ +import Checkbox from 'src/components/checkbox/checkbox.vue' +import Setting from './setting.js' + +export default { + ...Setting, + data () { + return { + newValue: '', + } + }, + components: { + ...Setting.components, + Checkbox + }, + props: { + ...Setting.props + }, + computed: { + ...Setting.computed, + isSeparate () { + // [[a1, b1], [a2, b2]] vs [a, b] + return Array.isArray(this.visibleState[0]) + }, + normalizedState () { + if (this.isSeparate) { + return this.visibleState.map(y => y.map(x => Number(x) || 0)) + } else { + return [this.visibleState.map(x => Number(x) || 0)] + } + } + }, + methods: { + ...Setting.methods, + getValue ({ event, side, index, eventType }) { + if (eventType === 'edit') { + const value = Number(event.target.value) + if (Number.isNaN(value)) return this.visibleState + + const newVal = [...this.normalizedState.map(x => [...x])] + newVal[side][index] = value + return newVal + } + + if (eventType === 'toggleMode') { + if (event === 'split') { + return [this.normalizedState[0], this.normalizedState[0]] + } else if (event === 'join') { + return [this.normalizedState[0]] + } + } + } + } +} diff --git a/src/components/settings_modal/helpers/rate_setting.vue b/src/components/settings_modal/helpers/rate_setting.vue new file mode 100644 index 000000000..a28ed13c2 --- /dev/null +++ b/src/components/settings_modal/helpers/rate_setting.vue @@ -0,0 +1,117 @@ + + + + diff --git a/src/components/settings_modal/settings_modal_admin_content.js b/src/components/settings_modal/settings_modal_admin_content.js index 4a05868d8..77a3d6b81 100644 --- a/src/components/settings_modal/settings_modal_admin_content.js +++ b/src/components/settings_modal/settings_modal_admin_content.js @@ -13,6 +13,7 @@ import RegistrationsTab from './admin_tabs/registrations_tab.vue' import AuthTab from './admin_tabs/auth_tab.vue' import HTTPTab from './admin_tabs/http_tab.vue' import OtherTab from './admin_tabs/other_tab.vue' +import RatesTab from './admin_tabs/rates_tab.vue' import PostsTab from './admin_tabs/posts_tab.vue' import FederationTab from './admin_tabs/federation_tab.vue' import JobQueuesTab from './admin_tabs/job_queues_tab.vue' @@ -34,7 +35,8 @@ import { faCircleNodes, faUpload, faMessage, - faEllipsis + faEllipsis, + faGauge } from '@fortawesome/free-solid-svg-icons' library.add( @@ -52,7 +54,8 @@ library.add( faCircleNodes, faUpload, faMessage, - faEllipsis + faEllipsis, + faGauge ) const SettingsModalAdminContent = { @@ -73,6 +76,7 @@ const SettingsModalAdminContent = { AuthTab, HTTPTab, MonitoringTab, + RatesTab, OtherTab, PostsTab }, diff --git a/src/components/settings_modal/settings_modal_admin_content.vue b/src/components/settings_modal/settings_modal_admin_content.vue index 80c82d84f..ef8e2793e 100644 --- a/src/components/settings_modal/settings_modal_admin_content.vue +++ b/src/components/settings_modal/settings_modal_admin_content.vue @@ -92,6 +92,15 @@ +
+ +
+
{ const path = [c.group, c.key] if (c.db) { @@ -94,16 +95,33 @@ const adminSettingsStorage = { // Using strings for modified paths for easier searching c.db.forEach(x => modifiedPaths.add([...path, x].join(' -> '))) } - const convert = (value) => { + + // we need to preserve tuples on second level only, possibly third + // but it's not a case right now. + const convert = (value, preserveTuples, preserveTuplesLv2) => { if (Array.isArray(value) && value.length > 0 && value[0].tuple) { - return value.reduce((acc, c) => { - return { ...acc, [c.tuple[0]]: convert(c.tuple[1]) } - }, {}) + if (!preserveTuples) { + return value.reduce((acc, c) => { + return { ...acc, [c.tuple[0]]: convert(c.tuple[1], preserveTuplesLv2) } + }, {}) + } else { + return value.map(x => x.tuple) + } } else { - return value + if (!preserveTuples) { + return value + } else { + return value.tuple + } } } - set(config, path, convert(c.value)) + // for most stuff we want maps since those are more convenient + // however this doesn't allow for multiple values per same key + // so for those cases we want to preserve tuples as-is + // right now it's made exclusively for :pleroma.:rate_limit + // so it might not work properly elsewhere + const preserveTuples = path.find(x => x === ':rate_limit') + set(config, path, convert(c.value, false, preserveTuples)) }) console.log('CONFIG', JSON.parse(JSON.stringify(config))) // patching http adapter config to be easier to handle