|
1 | 1 | import { defineStore } from 'pinia';
|
2 | 2 | import moment, { Moment } from 'moment';
|
| 3 | +import { getClient } from '~/util/awclient'; |
3 | 4 |
|
4 | 5 | // Backoffs for NewReleaseNotification
|
5 | 6 | export const SHORT_BACKOFF_PERIOD = 24 * 60 * 60;
|
@@ -74,63 +75,85 @@ export const useSettingsStore = defineStore('settings', {
|
74 | 75 | await this.load();
|
75 | 76 | }
|
76 | 77 | },
|
77 |
| - async load() { |
| 78 | + async load({ save }: { save?: boolean } = {}) { |
78 | 79 | if (typeof localStorage === 'undefined') {
|
79 | 80 | console.error('localStorage is not supported');
|
80 | 81 | return;
|
81 | 82 | }
|
82 |
| - // Fetch from localStorage first, if exists |
| 83 | + const client = getClient(); |
| 84 | + |
| 85 | + // Fetch from server, fall back to localStorage |
| 86 | + const server_settings = await client.get_settings(); |
| 87 | + |
| 88 | + const all_keys = [ |
| 89 | + ...Object.keys(localStorage).filter(key => { |
| 90 | + // Skip built-in properties like length, setItem, etc. |
| 91 | + return Object.prototype.hasOwnProperty.call(localStorage, key); |
| 92 | + }), |
| 93 | + ...Object.keys(server_settings), |
| 94 | + ].filter(key => { |
| 95 | + // Skip keys starting with underscore, as they are local to the vuex store. |
| 96 | + return !key.startsWith('_'); |
| 97 | + }); |
| 98 | + console.log('all_keys', all_keys); |
| 99 | + |
83 | 100 | const storage = {};
|
84 |
| - for (const key in localStorage) { |
85 |
| - // Skip built-in properties like length, setItem, etc. |
86 |
| - // Also skip keys starting with underscore, as they are local to the vuex store. |
87 |
| - if (Object.prototype.hasOwnProperty.call(localStorage, key) && !key.startsWith('_')) { |
88 |
| - const value = localStorage.getItem(key); |
89 |
| - //console.log(`${key}: ${value}`); |
90 |
| - |
91 |
| - // Keys ending with 'Data' are JSON-serialized objects |
92 |
| - if (key.includes('Data')) { |
93 |
| - try { |
94 |
| - storage[key] = JSON.parse(value); |
95 |
| - } catch (e) { |
96 |
| - console.error('failed to parse', key, value); |
97 |
| - } |
98 |
| - } else if (value === 'true' || value === 'false') { |
99 |
| - storage[key] = value === 'true'; |
100 |
| - } else { |
101 |
| - storage[key] = value; |
| 101 | + for (const key of all_keys) { |
| 102 | + // If key is set in server, use that value, otherwise use localStorage |
| 103 | + const set_in_server = server_settings[key] !== undefined; |
| 104 | + const value = set_in_server ? server_settings[key] : localStorage.getItem(key); |
| 105 | + const locstr = set_in_server ? '[server]' : '[localStorage]'; |
| 106 | + console.log(`${locstr} ${key}:`, value); |
| 107 | + |
| 108 | + // Keys ending with 'Data' are JSON-serialized objects |
| 109 | + if (key.includes('Data') && !set_in_server) { |
| 110 | + try { |
| 111 | + storage[key] = JSON.parse(value); |
| 112 | + } catch (e) { |
| 113 | + console.error('failed to parse', key, value); |
102 | 114 | }
|
| 115 | + } else if (value === 'true' || value === 'false') { |
| 116 | + storage[key] = value === 'true'; |
| 117 | + } else { |
| 118 | + storage[key] = value; |
103 | 119 | }
|
104 | 120 | }
|
105 | 121 | this.$patch({ ...storage, _loaded: true });
|
106 | 122 |
|
107 |
| - // TODO: Then fetch from server |
108 |
| - //const getSettingsFromServer = async () => { |
109 |
| - // const { data } = await this.$aw._get('/0/settings'); |
110 |
| - // return data; |
111 |
| - //}; |
| 123 | + if (save) { |
| 124 | + await this.save(); |
| 125 | + } |
112 | 126 | },
|
113 | 127 | async save() {
|
114 |
| - // First save to localStorage |
| 128 | + // We want to avoid saving to localStorage to not accidentally mess up pre-migration data |
| 129 | + // For example, if the user is using several browsers, and opened in their non-main browser on first run after upgrade. |
| 130 | + const saveToLocalStorage = false; |
| 131 | + |
| 132 | + // Save to localStorage and backend |
| 133 | + // NOTE: localStorage deprecated, will be removed in future |
| 134 | + const client = getClient(); |
115 | 135 | for (const key of Object.keys(this.$state)) {
|
116 | 136 | const value = this.$state[key];
|
117 |
| - if (typeof value === 'object') { |
118 |
| - localStorage.setItem(key, JSON.stringify(value)); |
119 |
| - } else { |
120 |
| - localStorage.setItem(key, value); |
| 137 | + |
| 138 | + // Save to localStorage |
| 139 | + if (saveToLocalStorage) { |
| 140 | + if (typeof value === 'object') { |
| 141 | + localStorage.setItem(key, JSON.stringify(value)); |
| 142 | + } else { |
| 143 | + localStorage.setItem(key, value); |
| 144 | + } |
121 | 145 | }
|
122 |
| - } |
123 | 146 |
|
124 |
| - // TODO: Save to backend |
125 |
| - //const updateSettingOnServer = async (key: string, value: string) => { |
126 |
| - // console.log({ key, value }); |
127 |
| - // const headers = { 'Content-Type': 'application/json' }; |
128 |
| - // const { data } = await this.$aw._post('/0/settings', { key, value }, headers); |
129 |
| - // return data; |
130 |
| - //}; |
| 147 | + // Save to backend |
| 148 | + await client.req.post('/0/settings/' + key, value, { |
| 149 | + headers: { |
| 150 | + 'Content-Type': 'application/json', |
| 151 | + }, |
| 152 | + }); |
| 153 | + } |
131 | 154 |
|
132 |
| - // After save, reload from localStorage |
133 |
| - await this.load(); |
| 155 | + // After save, reload |
| 156 | + await this.load({ save: false }); |
134 | 157 | },
|
135 | 158 | async update(new_state: Record<string, any>) {
|
136 | 159 | console.log('Updating state', new_state);
|
|
0 commit comments