Merge branch 'sss-objects' into shigusegubu-themes3
This commit is contained in:
commit
55d29065f0
7 changed files with 95 additions and 38 deletions
1
changelog.d/mutes-sync.add
Normal file
1
changelog.d/mutes-sync.add
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Synchronized mutes, advanced mute control (regexp, expiry, naming)
|
|
@ -1,4 +1,4 @@
|
||||||
import { throttle } from 'lodash'
|
import { throttle, cloneDeep } from 'lodash'
|
||||||
import { mapState, mapActions } from 'pinia'
|
import { mapState, mapActions } from 'pinia'
|
||||||
import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
|
import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
@ -14,12 +14,19 @@ import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
|
|
||||||
const FilteringTab = {
|
const FilteringTab = {
|
||||||
data () {
|
data () {
|
||||||
|
console.log(cloneDeep(useServerSideStorageStore().prefsStorage.simple.muteFilters))
|
||||||
return {
|
return {
|
||||||
replyVisibilityOptions: ['all', 'following', 'self'].map(mode => ({
|
replyVisibilityOptions: ['all', 'following', 'self'].map(mode => ({
|
||||||
key: mode,
|
key: mode,
|
||||||
value: mode,
|
value: mode,
|
||||||
label: this.$t(`settings.reply_visibility_${mode}`)
|
label: this.$t(`settings.reply_visibility_${mode}`)
|
||||||
}))
|
})),
|
||||||
|
muteFiltersDraftObject: cloneDeep(useServerSideStorageStore().prefsStorage.simple.muteFilters),
|
||||||
|
muteFiltersDraftDirty: Object.fromEntries(
|
||||||
|
Object.entries(
|
||||||
|
useServerSideStorageStore().prefsStorage.simple.muteFilters
|
||||||
|
).map(([k]) => [k, false])
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -38,12 +45,13 @@ const FilteringTab = {
|
||||||
muteFilters: store => Object.entries(store.prefsStorage.simple.muteFilters),
|
muteFilters: store => Object.entries(store.prefsStorage.simple.muteFilters),
|
||||||
muteFiltersObject: store => store.prefsStorage.simple.muteFilters
|
muteFiltersObject: store => store.prefsStorage.simple.muteFilters
|
||||||
}
|
}
|
||||||
)
|
),
|
||||||
|
muteFiltersDraft () {
|
||||||
|
return Object.entries(this.muteFiltersDraftObject)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useServerSideStorageStore, ['unsetPreference']),
|
...mapActions(useServerSideStorageStore, ['setPreference', 'unsetPreference', 'pushServerSideStorage']),
|
||||||
pushServerSideStorage: throttle(() => useServerSideStorageStore().pushServerSideStorage(), 500),
|
|
||||||
setPreference: throttle(x => useServerSideStorageStore().setPreference(x), 500),
|
|
||||||
getDatetimeLocal (timestamp) {
|
getDatetimeLocal (timestamp) {
|
||||||
const date = new Date(timestamp)
|
const date = new Date(timestamp)
|
||||||
const datetime = [
|
const datetime = [
|
||||||
|
@ -84,22 +92,25 @@ const FilteringTab = {
|
||||||
}
|
}
|
||||||
const newId = uuidv4()
|
const newId = uuidv4()
|
||||||
|
|
||||||
|
this.muteFiltersDraftObject[newId] = filter
|
||||||
this.setPreference({ path: 'simple.muteFilters.' + newId , value: filter })
|
this.setPreference({ path: 'simple.muteFilters.' + newId , value: filter })
|
||||||
this.pushServerSideStorage()
|
this.pushServerSideStorage()
|
||||||
},
|
},
|
||||||
copyFilter (id) {
|
copyFilter (id) {
|
||||||
const filter = { ...this.muteFiltersObject[id] }
|
const filter = { ...this.muteFiltersDraftObject[id] }
|
||||||
const newId = uuidv4()
|
const newId = uuidv4()
|
||||||
|
|
||||||
|
this.muteFiltersDraftObject[newId] = filter
|
||||||
this.setPreference({ path: 'simple.muteFilters.' + newId , value: filter })
|
this.setPreference({ path: 'simple.muteFilters.' + newId , value: filter })
|
||||||
this.pushServerSideStorage()
|
this.pushServerSideStorage()
|
||||||
},
|
},
|
||||||
deleteFilter (id) {
|
deleteFilter (id) {
|
||||||
|
delete this.muteFiltersDraftObject[id]
|
||||||
this.unsetPreference({ path: 'simple.muteFilters.' + id , value: null })
|
this.unsetPreference({ path: 'simple.muteFilters.' + id , value: null })
|
||||||
this.pushServerSideStorage()
|
this.pushServerSideStorage()
|
||||||
},
|
},
|
||||||
updateFilter(id, field, value) {
|
updateFilter(id, field, value) {
|
||||||
const filter = { ...this.muteFiltersObject[id] }
|
const filter = { ...this.muteFiltersDraftObject[id] }
|
||||||
if (field === 'expires-never') {
|
if (field === 'expires-never') {
|
||||||
// filter[field] = value
|
// filter[field] = value
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
@ -115,8 +126,15 @@ const FilteringTab = {
|
||||||
} else {
|
} else {
|
||||||
filter[field] = value
|
filter[field] = value
|
||||||
}
|
}
|
||||||
this.setPreference({ path: 'simple.muteFilters.' + id , value: filter })
|
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.pushServerSideStorage()
|
||||||
|
this.muteFiltersDraftDirty[id] = false
|
||||||
|
console.log(this.muteFiltersDraftDirty)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Updating nested properties
|
// Updating nested properties
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
<div
|
<div
|
||||||
class="mute-filter"
|
class="mute-filter"
|
||||||
:style="{ order: filter[1].order }"
|
:style="{ order: filter[1].order }"
|
||||||
v-for="filter in muteFilters"
|
v-for="filter in muteFiltersDraft"
|
||||||
:key="filter[0]"
|
:key="filter[0]"
|
||||||
>
|
>
|
||||||
<div class="filter-name">
|
<div class="filter-name">
|
||||||
|
@ -201,6 +201,16 @@
|
||||||
>
|
>
|
||||||
{{ $t('settings.filter.delete') }}
|
{{ $t('settings.filter.delete') }}
|
||||||
</button>
|
</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>
|
</div>
|
||||||
<div class="mute-filter">
|
<div class="mute-filter">
|
||||||
|
|
|
@ -422,6 +422,7 @@
|
||||||
"expires": "Expires",
|
"expires": "Expires",
|
||||||
"expired": "Expired",
|
"expired": "Expired",
|
||||||
"copy": "Copy filter",
|
"copy": "Copy filter",
|
||||||
|
"save": "Save filter",
|
||||||
"delete": "Remove filter",
|
"delete": "Remove filter",
|
||||||
"new": "Create filter",
|
"new": "Create filter",
|
||||||
"regexp_error": "Invalid Regular Expression",
|
"regexp_error": "Invalid Regular Expression",
|
||||||
|
|
41
src/modules/config_declaration.js
Normal file
41
src/modules/config_declaration.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
export const CONFIG_MIGRATION = 1
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
|
// for future use
|
||||||
|
/*
|
||||||
|
const simpleDeclaration = {
|
||||||
|
store: 'server-side',
|
||||||
|
migration(serverside, rootState) {
|
||||||
|
serverside.setPreference({ path: 'simple.' + field, value: rootState.config[oldField ?? field] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const declarations = [
|
||||||
|
{
|
||||||
|
field: 'muteFilters',
|
||||||
|
store: 'server-side',
|
||||||
|
migrationFlag: 'configMigration',
|
||||||
|
migrationNum: 1,
|
||||||
|
description: 'Mute filters, wordfilter/regexp/etc',
|
||||||
|
valueType: 'complex',
|
||||||
|
migration (serverside, rootState) {
|
||||||
|
rootState.config.muteWords.forEach((word, order) => {
|
||||||
|
const uniqueId = uuidv4()
|
||||||
|
|
||||||
|
serverside.setPreference({
|
||||||
|
path: 'simple.muteFilters.' + uniqueId,
|
||||||
|
value: {
|
||||||
|
type: 'word',
|
||||||
|
value: word,
|
||||||
|
name: word,
|
||||||
|
enabled: true,
|
||||||
|
expires: null,
|
||||||
|
hide: false,
|
||||||
|
order
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
|
@ -1,5 +1,4 @@
|
||||||
import { compact, map, each, mergeWith, last, concat, uniq, isArray } from 'lodash'
|
import { compact, map, each, mergeWith, last, concat, uniq, isArray } from 'lodash'
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
|
|
||||||
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
|
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
|
||||||
import { windowWidth, windowHeight } from '../services/window_utils/window_utils'
|
import { windowWidth, windowHeight } from '../services/window_utils/window_utils'
|
||||||
|
@ -9,7 +8,9 @@ import { registerPushNotifications, unregisterPushNotifications } from '../servi
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import { useOAuthStore } from 'src/stores/oauth.js'
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
import { useServerSideStorageStore, CONFIG_MIGRATION } from 'src/stores/serverSideStorage'
|
import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
|
||||||
|
|
||||||
|
import { declarations } from 'src/modules/config_declaration'
|
||||||
|
|
||||||
// TODO: Unify with mergeOrAdd in statuses.js
|
// TODO: Unify with mergeOrAdd in statuses.js
|
||||||
export const mergeOrAdd = (arr, obj, item) => {
|
export const mergeOrAdd = (arr, obj, item) => {
|
||||||
|
@ -637,33 +638,17 @@ const users = {
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
const { configMigration } = useServerSideStorageStore().flagStorage
|
const { configMigration } = useServerSideStorageStore().flagStorage
|
||||||
|
declarations
|
||||||
// Wordfilter migration
|
.filter(x => {
|
||||||
if (configMigration < 1) {
|
return x.store === 'server-side' &&
|
||||||
// Convert existing wordfilter into synced one
|
(x.migrationNum ?? x.migrationNum > configMigration)
|
||||||
store.rootState.config.muteWords.forEach((word, order) => {
|
})
|
||||||
const uniqueId = uuidv4()
|
.toSorted((a, b) => a.configMigration - b.configMigration)
|
||||||
|
.forEach(value => {
|
||||||
useServerSideStorageStore().setPreference({
|
value.migration(useServerSideStorageStore(), store.rootState)
|
||||||
path: 'simple.muteFilters.' + uniqueId,
|
useServerSideStorageStore().setFlag({ flag: 'configMigration', value: value.migrationNum })
|
||||||
value: {
|
useServerSideStorageStore().pushServerSideStorage()
|
||||||
type: 'word',
|
|
||||||
value: word,
|
|
||||||
name: word,
|
|
||||||
enabled: true,
|
|
||||||
expires: null,
|
|
||||||
hide: false,
|
|
||||||
order
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
if (configMigration < CONFIG_MIGRATION) {
|
|
||||||
// Update the flag
|
|
||||||
useServerSideStorageStore().setFlag({ flag: 'configMigration', value: CONFIG_MIGRATION })
|
|
||||||
useServerSideStorageStore().pushServerSideStorage()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.token) {
|
if (user.token) {
|
||||||
dispatch('setWsToken', user.token)
|
dispatch('setWsToken', user.token)
|
||||||
|
|
|
@ -5,6 +5,7 @@ export const muteFilterHits = (muteFilters, status) => {
|
||||||
return muteFilters.toSorted((a,b) => b.order - a.order).map(filter => {
|
return muteFilters.toSorted((a,b) => b.order - a.order).map(filter => {
|
||||||
const { hide, expires, name, value, type, enabled} = filter
|
const { hide, expires, name, value, type, enabled} = filter
|
||||||
if (!enabled) return false
|
if (!enabled) return false
|
||||||
|
if (value === '') return false
|
||||||
if (expires !== null && expires < Date.now()) return false
|
if (expires !== null && expires < Date.now()) return false
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'word': {
|
case 'word': {
|
||||||
|
|
Loading…
Add table
Reference in a new issue