diff --git a/src/components/settings_modal/tabs/filtering_tab.js b/src/components/settings_modal/tabs/filtering_tab.js index 34ade4dfc..3345cb0c9 100644 --- a/src/components/settings_modal/tabs/filtering_tab.js +++ b/src/components/settings_modal/tabs/filtering_tab.js @@ -1,8 +1,15 @@ import { cloneDeep } from 'lodash' import { mapState, mapActions } from 'pinia' -import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { v4 as uuidv4 } from 'uuid'; +import { useServerSideStorageStore } from 'src/stores/serverSideStorage' +import { useInterfaceStore } from 'src/stores/interface' + +import { + newImporter, + newExporter +} from 'src/services/export_import/export_import.js' + import BooleanSetting from '../helpers/boolean_setting.vue' import ChoiceSetting from '../helpers/choice_setting.vue' import UnitSetting from '../helpers/unit_setting.vue' @@ -13,9 +20,10 @@ import Select from 'src/components/select/select.vue' import SharedComputedObject from '../helpers/shared_computed_object.js' +const SUPPORTED_TYPES = new Set(['word', 'regexp', 'user', 'user_regexp']) + const FilteringTab = { data () { - console.log(cloneDeep(useServerSideStorageStore().prefsStorage.simple.muteFilters)) return { replyVisibilityOptions: ['all', 'following', 'self'].map(mode => ({ key: mode, @@ -27,7 +35,44 @@ const FilteringTab = { Object.entries( useServerSideStorageStore().prefsStorage.simple.muteFilters ).map(([k]) => [k, false]) - ) + ), + exportedFilter: null, + filterImporter: newImporter({ + validator (parsed) { + if (Array.isArray(parsed)) return false + if (!SUPPORTED_TYPES.has(parsed.type)) return false + return true + }, + onImport: (data) => { + const { + enabled = true, + expires = null, + hide = false, + name = '', + value = '' + } = data + + this.createFilter({ + enabled, + expires, + hide, + name, + value + }) + }, + onImportFailure (result) { + console.error('Failure importing filter:', result) + useInterfaceStore() + .pushGlobalNotice({ + messageKey: 'settings.filter.import_failure', + level: 'error' + }) + } + }), + filterExporter: newExporter({ + filename: 'pleromafe_mute-filter', + getExportedObject: () => this.exportedFilter + }) } }, components: { @@ -83,22 +128,29 @@ const FilteringTab = { } return valid }, - createFilter () { - const filter = { - type: 'word', - value: '', - name: 'New Filter', - enabled: true, - expires: null, - hide: false, - order: this.muteFilters.length + 2 - } + createFilter (filter = { + type: 'word', + value: '', + name: 'New Filter', + enabled: true, + expires: null, + hide: false, + }) { const newId = uuidv4() + filter.order = this.muteFilters.length + 2 this.muteFiltersDraftObject[newId] = filter this.setPreference({ path: 'simple.muteFilters.' + newId , value: filter }) this.pushServerSideStorage() }, + exportFilter(id) { + this.exportedFilter = { ...this.muteFiltersDraftObject[id] } + delete this.exportedFilter.order + this.filterExporter.exportData() + }, + importFilter() { + this.filterImporter.importData() + }, copyFilter (id) { const filter = { ...this.muteFiltersDraftObject[id] } const newId = uuidv4() @@ -131,14 +183,12 @@ const FilteringTab = { } this.muteFiltersDraftObject[id] = filter this.muteFiltersDraftDirty[id] = true - console.log(this.muteFiltersDraftDirty) }, saveFilter(id) { this.setPreference({ path: 'simple.muteFilters.' + id , value: this.muteFiltersDraftObject[id] }) this.pushServerSideStorage() this.muteFiltersDraftDirty[id] = false - console.log(this.muteFiltersDraftDirty) - } + }, }, // Updating nested properties watch: { diff --git a/src/components/settings_modal/tabs/filtering_tab.scss b/src/components/settings_modal/tabs/filtering_tab.scss index 979096126..3f3fa3b58 100644 --- a/src/components/settings_modal/tabs/filtering_tab.scss +++ b/src/components/settings_modal/tabs/filtering_tab.scss @@ -62,6 +62,10 @@ max-width: 100%; justify-content: end; } + + .total { + text-align: center; + } } diff --git a/src/components/settings_modal/tabs/filtering_tab.vue b/src/components/settings_modal/tabs/filtering_tab.vue index f7754090b..968a7a0e7 100644 --- a/src/components/settings_modal/tabs/filtering_tab.vue +++ b/src/components/settings_modal/tabs/filtering_tab.vue @@ -73,232 +73,245 @@ diff --git a/src/components/settings_modal/tabs/style_tab/style_tab.js b/src/components/settings_modal/tabs/style_tab/style_tab.js index d2162c30c..8324263cd 100644 --- a/src/components/settings_modal/tabs/style_tab/style_tab.js +++ b/src/components/settings_modal/tabs/style_tab/style_tab.js @@ -643,7 +643,7 @@ export default { parser (string) { return deserialize(string) }, onImportFailure (result) { console.error('Failure importing style:', result) - this.$store.useInterfaceStore().pushGlobalNotice({ messageKey: 'settings.invalid_theme_imported', level: 'error' }) + useInterfaceStore().pushGlobalNotice({ messageKey: 'settings.invalid_theme_imported', level: 'error' }) }, onImport }) diff --git a/src/i18n/en.json b/src/i18n/en.json index 3695cb088..f5f451467 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -432,6 +432,8 @@ "export": "Export", "regexp_error": "Invalid Regular Expression", "never_expires": "Never", + "count": "{count} filter|{count} filters", + "import_failure": "The selected file is not a supported Pleroma filter.", "help": { "word": "Simple and RegExp filters test against post's content and subject.", "user": "User filter matches full user handle (user@domain) in the following: author, reply-to and mentions",