您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
simple state manager based on Vue3.reactive and localStorage
当前为
- // ==UserScript==
- // @name persistent-state
- // @description simple state manager based on Vue3.reactive and localStorage
- // @namespace http://tampermonkey.net/
- // @author smartacephale
- // @license MIT
- // @version 1.3
- // @match *://*/*
- // ==/UserScript==
- /* globals reactive watch parseIntegerOr */
- class PersistentState {
- constructor(state, key = "state_acephale") {
- this.key = key;
- this.state = reactive(state);
- this.sync();
- this.watchPersistence();
- }
- sync() {
- this.trySetFromLocalStorage();
- window.addEventListener('focus', this.trySetFromLocalStorage);
- }
- watchPersistence() {
- watch(this.state, (value) => {
- this.saveToLocalStorage(this.key, value);
- });
- }
- saveToLocalStorage(key, value) {
- localStorage.setItem(key, JSON.stringify(value));
- }
- trySetFromLocalStorage = () => {
- const localStorageValue = localStorage.getItem(this.key);
- if (localStorageValue !== null) {
- const prevState = JSON.parse(localStorageValue);
- for (const prop of Object.keys(prevState)) {
- this.state[prop] = prevState[prop];
- }
- }
- }
- }
- class DefaultState {
- DEFAULT_STATE = {
- filterExcludeWords: "",
- filterExclude: false,
- filterIncludeWords: "",
- filterInclude: false,
- infiniteScrollEnabled: true,
- uiEnabled: true,
- };
- OPTIONAL_FILTERS = {
- DURATION_FILTER: {
- filterDurationFrom: 0,
- filterDurationTo: 600,
- filterDuration: false
- },
- PRIVACY_FILTER: {
- filterPrivate: false,
- filterPublic: false
- }
- }
- DEFAULT_OPTIONS = {
- PRIVACY_FILTER: false,
- DURATION_FILTER: true
- }
- constructor(options = this.DEFAULT_OPTIONS, custom = {}) {
- const opted = Object.assign(this.DEFAULT_OPTIONS, options);
- Object.keys(opted).forEach(key => {
- if (opted[key]) {
- Object.assign(this.DEFAULT_STATE, this.OPTIONAL_FILTERS[key]);
- }
- });
- Object.assign(this.DEFAULT_STATE, { custom });
- const { state } = new PersistentState(this.DEFAULT_STATE);
- this.state = state;
- this.stateLocale = reactive({
- pagIndexLast: 1,
- pagIndexCur: 1,
- filterOptions: opted
- });
- }
- setWatchers(applyFilter) {
- const { state, stateLocale } = this;
- if (stateLocale.filterOptions.PRIVACY_FILTER) {
- watch(() => state.filterPrivate, () => applyFilter({ filterPrivate: true }));
- watch(() => state.filterPublic, () => applyFilter({ filterPublic: true }));
- }
- if (stateLocale.filterOptions.DURATION_FILTER) {
- watch([() => state.filterDurationFrom, () => state.filterDurationTo], (a, b) => {
- state.filterDurationFrom = parseIntegerOr(a[0], b[0]);
- state.filterDurationTo = parseIntegerOr(a[1], b[1]);
- if (state.filterDuration) applyFilter({ filterDuration: true });
- });
- watch(() => state.filterDuration, () => applyFilter({ filterDuration: true }));
- }
- watch(() => state.filterExclude, () => applyFilter({ filterExclude: true }));
- watch(() => state.filterExcludeWords, () => {
- if (state.filterExclude) applyFilter({ filterExclude: true });
- }, { deep: true });
- watch(() => state.filterInclude, () => applyFilter({ filterInclude: true }));
- watch(() => state.filterIncludeWords, () => {
- if (state.filterInclude) applyFilter({ filterInclude: true });
- }, { deep: true });
- }
- }