export/import
This commit is contained in:
parent
45e6e03a03
commit
bfd271a69f
5 changed files with 294 additions and 225 deletions
|
|
@ -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: {
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@
|
|||
max-width: 100%;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.total {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -73,232 +73,245 @@
|
|||
<ul class="setting-list">
|
||||
<h2>{{ $t('settings.filter.mute_filter') }}</h2>
|
||||
<li>
|
||||
<li>
|
||||
<BooleanSetting path="hideFilteredStatuses">
|
||||
{{ $t('settings.hide_muted_statuses') }}
|
||||
</BooleanSetting>
|
||||
<ul class="setting-list suboptions">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
parent-path="hideFilteredStatuses"
|
||||
:parent-invert="true"
|
||||
path="hideWordFilteredPosts"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.hide_filtered_statuses') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
v-if="user"
|
||||
parent-path="hideFilteredStatuses"
|
||||
:parent-invert="true"
|
||||
path="hideMutedThreads"
|
||||
>
|
||||
{{ $t('settings.hide_muted_threads') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
v-if="user"
|
||||
parent-path="hideFilteredStatuses"
|
||||
:parent-invert="true"
|
||||
path="hideMutedPosts"
|
||||
>
|
||||
{{ $t('settings.hide_muted_posts') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="muteBotStatuses">
|
||||
{{ $t('settings.mute_bot_posts') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="muteSensitiveStatuses">
|
||||
{{ $t('settings.mute_sensitive_posts') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<div class="muteFilterContainer">
|
||||
<div
|
||||
v-for="filter in muteFiltersDraft"
|
||||
:key="filter[0]"
|
||||
class="mute-filter"
|
||||
:style="{ order: filter[1].order }"
|
||||
>
|
||||
<div class="filter-name">
|
||||
<label
|
||||
:for="'filterName' + filter[0]"
|
||||
>
|
||||
{{ $t('settings.filter.name') }}
|
||||
</label>
|
||||
{{ ' ' }}
|
||||
<BooleanSetting path="hideFilteredStatuses">
|
||||
{{ $t('settings.hide_muted_statuses') }}
|
||||
</BooleanSetting>
|
||||
<ul class="setting-list suboptions">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
parent-path="hideFilteredStatuses"
|
||||
:parent-invert="true"
|
||||
path="hideWordFilteredPosts"
|
||||
expert="1"
|
||||
>
|
||||
{{ $t('settings.hide_filtered_statuses') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
v-if="user"
|
||||
parent-path="hideFilteredStatuses"
|
||||
:parent-invert="true"
|
||||
path="hideMutedThreads"
|
||||
>
|
||||
{{ $t('settings.hide_muted_threads') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
v-if="user"
|
||||
parent-path="hideFilteredStatuses"
|
||||
:parent-invert="true"
|
||||
path="hideMutedPosts"
|
||||
>
|
||||
{{ $t('settings.hide_muted_posts') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="muteBotStatuses">
|
||||
{{ $t('settings.mute_bot_posts') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="muteSensitiveStatuses">
|
||||
{{ $t('settings.mute_sensitive_posts') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<div class="muteFilterContainer">
|
||||
<div
|
||||
v-for="filter in muteFiltersDraft"
|
||||
:key="filter[0]"
|
||||
class="mute-filter"
|
||||
:style="{ order: filter[1].order }"
|
||||
>
|
||||
<div class="filter-name">
|
||||
<label
|
||||
:for="'filterName' + filter[0]"
|
||||
>
|
||||
{{ $t('settings.filter.name') }}
|
||||
</label>
|
||||
{{ ' ' }}
|
||||
<input
|
||||
:id="'filterName' + filter[0]"
|
||||
class="input"
|
||||
:value="filter[1].name"
|
||||
@input="updateFilter(filter[0], 'name', $event.target.value)"
|
||||
>
|
||||
</div>
|
||||
<div class="filter-enabled">
|
||||
<Checkbox
|
||||
:id="'filterHide' + filter[0]"
|
||||
:model-value="filter[1].hide"
|
||||
:name="'filterHide' + filter[0]"
|
||||
@update:model-value="updateFilter(filter[0], 'hide', $event)"
|
||||
>
|
||||
{{ $t('settings.filter.hide') }}
|
||||
</Checkbox>
|
||||
{{ ' ' }}
|
||||
<Checkbox
|
||||
:id="'filterEnabled' + filter[0]"
|
||||
:model-value="filter[1].enabled"
|
||||
:name="'filterEnabled' + filter[0]"
|
||||
@update:model-value="updateFilter(filter[0], 'enabled', $event)"
|
||||
>
|
||||
{{ $t('settings.enabled') }}
|
||||
</Checkbox>
|
||||
</div>
|
||||
<div class="filter-type filter-field">
|
||||
<label :for="'filterType' + filter[0]">
|
||||
<HelpIndicator>
|
||||
<p>
|
||||
{{ $t('settings.filter.help.word') }}
|
||||
</p>
|
||||
<p>
|
||||
{{ $t('settings.filter.help.user') }}
|
||||
</p>
|
||||
<i18n-t
|
||||
keypath="settings.filter.help.regexp"
|
||||
tag="p"
|
||||
>
|
||||
<template #link>
|
||||
<a
|
||||
:href="$t('settings.filter.help.regexp_url')"
|
||||
target="_blank"
|
||||
>
|
||||
{{ $t('settings.filter.help.regexp_link') }}
|
||||
</a>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</HelpIndicator>
|
||||
{{ $t('settings.filter.type') }}
|
||||
</label>
|
||||
<Select
|
||||
:id="'filterType' + filter[0]"
|
||||
class="filter-field-value"
|
||||
:model-value="filter[1].type"
|
||||
@update:model-value="updateFilter(filter[0], 'type', $event)"
|
||||
>
|
||||
<option value="word">
|
||||
{{ $t('settings.filter.plain') }}
|
||||
</option>
|
||||
<option value="regexp">
|
||||
{{ $t('settings.filter.regexp') }}
|
||||
</option>
|
||||
<option value="user">
|
||||
{{ $t('settings.filter.user') }}
|
||||
</option>
|
||||
<option value="user_regexp">
|
||||
{{ $t('settings.filter.user_regexp') }}
|
||||
</option>
|
||||
</Select>
|
||||
</div>
|
||||
<div class="filter-value filter-field">
|
||||
<label
|
||||
:for="'filterValue' + filter[0]"
|
||||
>
|
||||
{{ $t('settings.filter.value') }}
|
||||
</label>
|
||||
{{ ' ' }}
|
||||
<input
|
||||
:id="'filterValue' + filter[0]"
|
||||
class="input filter-field-value"
|
||||
:value="filter[1].value"
|
||||
@input="updateFilter(filter[0], 'value', $event.target.value)"
|
||||
>
|
||||
</div>
|
||||
<div class="filter-expires filter-field">
|
||||
<label
|
||||
:for="'filterExpires' + filter[0]"
|
||||
>
|
||||
{{ $t('settings.filter.expires') }}
|
||||
</label>
|
||||
{{ ' ' }}
|
||||
<div class="filter-field-value">
|
||||
<input
|
||||
:id="'filterName' + filter[0]"
|
||||
:id="'filterExpires' + filter[0]"
|
||||
class="input"
|
||||
:value="filter[1].name"
|
||||
@input="updateFilter(filter[0], 'name', $event.target.value)"
|
||||
:class="{ disabled: filter[1].expires === null }"
|
||||
type="datetime-local"
|
||||
:disabled="filter[1].expires === null"
|
||||
:value="filter[1].expires ? getDatetimeLocal(filter[1].expires) : null"
|
||||
@input="updateFilter(filter[0], 'expires', $event.target.value)"
|
||||
>
|
||||
</div>
|
||||
<div class="filter-enabled">
|
||||
<Checkbox
|
||||
:id="'filterHide' + filter[0]"
|
||||
:model-value="filter[1].hide"
|
||||
:name="'filterHide' + filter[0]"
|
||||
@update:model-value="updateFilter(filter[0], 'hide', $event)"
|
||||
>
|
||||
{{ $t('settings.filter.hide') }}
|
||||
</Checkbox>
|
||||
{{ ' ' }}
|
||||
<Checkbox
|
||||
:id="'filterEnabled' + filter[0]"
|
||||
:model-value="filter[1].enabled"
|
||||
:name="'filterEnabled' + filter[0]"
|
||||
@update:model-value="updateFilter(filter[0], 'enabled', $event)"
|
||||
:id="'filterExpiresNever' + filter[0]"
|
||||
:model-value="filter[1].expires === null"
|
||||
:name="'filterExpiresNever' + filter[0]"
|
||||
class="input-inset input-boolean"
|
||||
@update:model-value="updateFilter(filter[0], 'expires-never', $event)"
|
||||
>
|
||||
{{ $t('settings.enabled') }}
|
||||
{{ $t('settings.filter.never_expires') }}
|
||||
</Checkbox>
|
||||
</div>
|
||||
<div class="filter-type filter-field">
|
||||
<label :for="'filterType' + filter[0]">
|
||||
<HelpIndicator>
|
||||
<p>
|
||||
{{ $t('settings.filter.help.word') }}
|
||||
</p>
|
||||
<p>
|
||||
{{ $t('settings.filter.help.user') }}
|
||||
</p>
|
||||
<i18n-t
|
||||
keypath="settings.filter.help.regexp"
|
||||
tag="p"
|
||||
>
|
||||
<template #link>
|
||||
<a
|
||||
:href="$t('settings.filter.help.regexp_url')"
|
||||
target="_blank"
|
||||
>
|
||||
{{ $t('settings.filter.help.regexp_link') }}
|
||||
</a>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</HelpIndicator>
|
||||
{{ $t('settings.filter.type') }}
|
||||
</label>
|
||||
<Select
|
||||
:id="'filterType' + filter[0]"
|
||||
class="filter-field-value"
|
||||
:model-value="filter[1].type"
|
||||
@update:model-value="updateFilter(filter[0], 'type', $event)"
|
||||
>
|
||||
<option value="word">
|
||||
{{ $t('settings.filter.plain') }}
|
||||
</option>
|
||||
<option value="regexp">
|
||||
{{ $t('settings.filter.regexp') }}
|
||||
</option>
|
||||
<option value="user">
|
||||
{{ $t('settings.filter.user') }}
|
||||
</option>
|
||||
<option value="user_regexp">
|
||||
{{ $t('settings.filter.user_regexp') }}
|
||||
</option>
|
||||
</Select>
|
||||
</div>
|
||||
<div class="filter-value filter-field">
|
||||
<label
|
||||
:for="'filterValue' + filter[0]"
|
||||
>
|
||||
{{ $t('settings.filter.value') }}
|
||||
</label>
|
||||
{{ ' ' }}
|
||||
<input
|
||||
:id="'filterValue' + filter[0]"
|
||||
class="input filter-field-value"
|
||||
:value="filter[1].value"
|
||||
@input="updateFilter(filter[0], 'value', $event.target.value)"
|
||||
>
|
||||
</div>
|
||||
<div class="filter-expires filter-field">
|
||||
<label
|
||||
:for="'filterExpires' + filter[0]"
|
||||
>
|
||||
{{ $t('settings.filter.expires') }}
|
||||
</label>
|
||||
{{ ' ' }}
|
||||
<div class="filter-field-value">
|
||||
<input
|
||||
:id="'filterExpires' + filter[0]"
|
||||
class="input"
|
||||
:class="{ disabled: filter[1].expires === null }"
|
||||
type="datetime-local"
|
||||
:disabled="filter[1].expires === null"
|
||||
:value="filter[1].expires ? getDatetimeLocal(filter[1].expires) : null"
|
||||
@input="updateFilter(filter[0], 'expires', $event.target.value)"
|
||||
>
|
||||
{{ ' ' }}
|
||||
<Checkbox
|
||||
:id="'filterExpiresNever' + filter[0]"
|
||||
:model-value="filter[1].expires === null"
|
||||
:name="'filterExpiresNever' + filter[0]"
|
||||
class="input-inset input-boolean"
|
||||
@update:model-value="updateFilter(filter[0], 'expires-never', $event)"
|
||||
>
|
||||
{{ $t('settings.filter.never_expires') }}
|
||||
</Checkbox>
|
||||
<span
|
||||
v-if="filter[1].expires !== null && Date.now() > filter[1].expires"
|
||||
class="alert neutral"
|
||||
>
|
||||
{{ $t('settings.filter.expired') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-buttons">
|
||||
<span
|
||||
v-if="!checkRegexValid(filter[0])"
|
||||
class="alert error"
|
||||
v-if="filter[1].expires !== null && Date.now() > filter[1].expires"
|
||||
class="alert neutral"
|
||||
>
|
||||
{{ $t('settings.filter.regexp_error') }}
|
||||
{{ $t('settings.filter.expired') }}
|
||||
</span>
|
||||
<button
|
||||
class="copy-button button-default"
|
||||
type="button"
|
||||
@click="copyFilter(filter[0])"
|
||||
>
|
||||
{{ $t('settings.filter.copy') }}
|
||||
</button>
|
||||
{{ ' ' }}
|
||||
<button
|
||||
class="delete-button button-default -danger"
|
||||
type="button"
|
||||
@click="deleteFilter(filter[0])"
|
||||
>
|
||||
{{ $t('settings.filter.delete') }}
|
||||
</button>
|
||||
{{ ' ' }}
|
||||
<button
|
||||
class="save-button button-default"
|
||||
:class="{ disabled: !muteFiltersDraftDirty[filter[0]] }"
|
||||
:disabled="!muteFiltersDraftDirty[filter[0]]"
|
||||
type="button"
|
||||
@click="saveFilter(filter[0])"
|
||||
>
|
||||
{{ $t('settings.filter.save') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mute-filter">
|
||||
<div
|
||||
v-if="!checkRegexValid(filter[0])"
|
||||
class="alert error"
|
||||
>
|
||||
{{ $t('settings.filter.regexp_error') }}
|
||||
</div>
|
||||
<div class="filter-buttons">
|
||||
<button
|
||||
class="add-button button-default"
|
||||
class="delete-button button-default -danger"
|
||||
type="button"
|
||||
@click="createFilter()"
|
||||
@click="deleteFilter(filter[0])"
|
||||
>
|
||||
{{ $t('settings.filter.new') }}
|
||||
{{ $t('settings.filter.delete') }}
|
||||
</button>
|
||||
<button
|
||||
class="export-button button-default"
|
||||
type="button"
|
||||
@click="exportFilter(filter[0])"
|
||||
>
|
||||
{{ $t('settings.filter.export') }}
|
||||
</button>
|
||||
<button
|
||||
class="copy-button button-default"
|
||||
type="button"
|
||||
@click="copyFilter(filter[0])"
|
||||
>
|
||||
{{ $t('settings.filter.copy') }}
|
||||
</button>
|
||||
<button
|
||||
class="save-button button-default"
|
||||
:class="{ disabled: !muteFiltersDraftDirty[filter[0]] }"
|
||||
:disabled="!muteFiltersDraftDirty[filter[0]]"
|
||||
type="button"
|
||||
@click="saveFilter(filter[0])"
|
||||
>
|
||||
{{ $t('settings.filter.save') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<div class="mute-filter new-filter">
|
||||
<span class="total">
|
||||
{{ $t('settings.filter.count', { count: muteFiltersDraft.length }) }}
|
||||
</span>
|
||||
<button
|
||||
class="add-button button-default"
|
||||
type="button"
|
||||
@click="createFilter()"
|
||||
>
|
||||
{{ $t('settings.filter.new') }}
|
||||
</button>
|
||||
<button
|
||||
class="add-button button-default"
|
||||
type="button"
|
||||
@click="importFilter()"
|
||||
>
|
||||
{{ $t('settings.filter.import') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue