@@ -3,11 +3,21 @@ import moment, { Moment } from 'moment';
33import { getClient } from '~/util/awclient' ;
44import { Category , defaultCategories } from '~/util/classes' ;
55import { View , defaultViews } from '~/stores/views' ;
6+ import { isEqual } from 'lodash' ;
7+
8+ function jsonEq ( a : any , b : any ) {
9+ const jsonA = JSON . parse ( JSON . stringify ( a ) ) ;
10+ const jsonB = JSON . parse ( JSON . stringify ( b ) ) ;
11+ return isEqual ( jsonA , jsonB ) ;
12+ }
613
714// Backoffs for NewReleaseNotification
815export const SHORT_BACKOFF_PERIOD = 24 * 60 * 60 ;
916export const LONG_BACKOFF_PERIOD = 5 * 24 * 60 * 60 ;
1017
18+ // Initial wait period for UserSatisfactionPoll
19+ export const INITIAL_WAIT_PERIOD = 7 * 24 * 60 * 60 ;
20+
1121interface State {
1222 // Timestamp when user was first seen (first time webapp is run)
1323 initialTimestamp : Moment ;
@@ -20,7 +30,11 @@ interface State {
2030 theme : 'light' | 'dark' ;
2131
2232 newReleaseCheckData : Record < string , any > ;
23- userSatisfactionPollData : Record < string , any > ;
33+ userSatisfactionPollData : {
34+ isEnabled : boolean ;
35+ nextPollTime : Moment ;
36+ timesPollIsShown : number ;
37+ } ;
2438 always_active_pattern : string ;
2539 classes : Category [ ] ;
2640 views : View [ ] ;
@@ -53,7 +67,11 @@ export const useSettingsStore = defineStore('settings', {
5367 howOftenToCheck : SHORT_BACKOFF_PERIOD ,
5468 timesChecked : 0 ,
5569 } ,
56- userSatisfactionPollData : { } ,
70+ userSatisfactionPollData : {
71+ isEnabled : true ,
72+ nextPollTime : moment ( ) . add ( INITIAL_WAIT_PERIOD , 'seconds' ) ,
73+ timesPollIsShown : 0 ,
74+ } ,
5775
5876 always_active_pattern : '' ,
5977 classes : defaultCategories ,
@@ -110,8 +128,8 @@ export const useSettingsStore = defineStore('settings', {
110128 //const locstr = set_in_server ? '[server]' : '[localStorage]';
111129 //console.debug(`${locstr} ${key}:`, value);
112130
113- // Keys ending with 'Data' are JSON-serialized objects
114- if ( key . includes ( 'Data' ) && ! set_in_server ) {
131+ // Keys ending with 'Data' are JSON-serialized objects in localStorage
132+ if ( key . endsWith ( 'Data' ) && ! set_in_server ) {
115133 try {
116134 storage [ key ] = JSON . parse ( value ) ;
117135 } catch ( e ) {
@@ -134,31 +152,56 @@ export const useSettingsStore = defineStore('settings', {
134152 }
135153 } ,
136154 async save ( ) {
155+ // Important check, to avoid saving settings before they are loaded (potentially overwriting them with defaults)
156+ if ( ! this . loaded ) {
157+ console . error ( 'Settings not loaded, not saving' ) ;
158+ return ;
159+ }
137160 // We want to avoid saving to localStorage to not accidentally mess up pre-migration data
138161 // For example, if the user is using several browsers, and opened in their non-main browser on first run after upgrade.
139162 const saveToLocalStorage = false ;
140163
141164 // Save to localStorage and backend
142165 // NOTE: localStorage deprecated, will be removed in future
143166 const client = getClient ( ) ;
167+
168+ // Fetch current settings from server
169+ const server_settings = await client . get_settings ( ) ;
170+
171+ // Save settings
144172 for ( const key of Object . keys ( this . $state ) ) {
173+ // Skip keys starting with underscore, as they are local to the vuex store.
174+ if ( key . startsWith ( '_' ) ) {
175+ continue ;
176+ }
177+
145178 const value = this . $state [ key ] ;
146179
147180 // Save to localStorage
148- if ( saveToLocalStorage ) {
181+ // NOTE: we always save the theme and landingpage to localStorage, since they are used before the settings are loaded
182+ if ( saveToLocalStorage || key == 'theme' || key == 'landingpage' ) {
149183 if ( typeof value === 'object' ) {
150184 localStorage . setItem ( key , JSON . stringify ( value ) ) ;
151185 } else {
152186 localStorage . setItem ( key , value ) ;
153187 }
154188 }
155189
156- // Save to backend
157- await client . req . post ( '/0/settings/' + key , value , {
158- headers : {
159- 'Content-Type' : 'application/json' ,
160- } ,
161- } ) ;
190+ // Save changed settings to backend
191+ if ( server_settings [ key ] === undefined || ! jsonEq ( server_settings [ key ] , value ) ) {
192+ if ( server_settings [ key ] === undefined && value === false ) {
193+ // Skip saving settings that are set to false and not already saved on the server
194+ continue ;
195+ }
196+ console . log ( 'Saving' , { [ key ] : value } ) ;
197+ //console.log('Was:', server_settings[key]);
198+ //console.log('Now:', value);
199+ await client . req . post ( '/0/settings/' + key , value , {
200+ headers : {
201+ 'Content-Type' : 'application/json' ,
202+ } ,
203+ } ) ;
204+ }
162205 }
163206
164207 // After save, reload
0 commit comments