FIX: Fixed perf issues with remote syncing

* added longer timeout, in case older devices are unable to load the index.html file quickly enough
This commit is contained in:
walljm 2018-01-19 21:17:52 -05:00
parent 5b621dda80
commit f38d8c1b21
5 changed files with 79 additions and 45 deletions

File diff suppressed because one or more lines are too long

View File

@ -63,6 +63,7 @@
<preference name="AutoHideSplashScreen" value="false" /> <preference name="AutoHideSplashScreen" value="false" />
<preference name="SplashShowOnlyFirstTime" value="false" /> <preference name="SplashShowOnlyFirstTime" value="false" />
<preference name="FadeSplashScreen" value="false" /> <preference name="FadeSplashScreen" value="false" />
<preference name="loadUrlTimeoutValue" value="60000" />
<feature name="SplashScreen"> <feature name="SplashScreen">
<param name="android-package" value="org.apache.cordova.splashscreen.SplashScreen" /> <param name="android-package" value="org.apache.cordova.splashscreen.SplashScreen" />
</feature> </feature>

View File

@ -1,6 +1,6 @@
{ {
"name": "dynamicbible", "name": "dynamicbible",
"version": "3.0.3", "version": "3.1.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -2,6 +2,7 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module'; import { AppModule } from './app.module';
import {enableProdMode} from '@angular/core'; import {enableProdMode} from '@angular/core';
enableProdMode(); enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule); platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -9,6 +9,7 @@ import { Storage } from '@ionic/storage';
import { CardItem } from '../pages/search/search'; import { CardItem } from '../pages/search/search';
import { Promise } from 'q'; import { Promise } from 'q';
import { setTimeout } from 'timers';
type fbObject<T> = { type fbObject<T> = {
ref: AngularFireObject<T>, ref: AngularFireObject<T>,
@ -42,15 +43,35 @@ export class ProfileService
remoteProfile: fbObject<User> | null; remoteProfile: fbObject<User> | null;
remoteLoggedIn: boolean; remoteLoggedIn: boolean;
isWeb: boolean; isWeb: boolean;
needsSync = false;
constructor( constructor(private local: Storage, private db: AngularFireDatabase, public firebaseAuth: AngularFireAuth)
private local: Storage
, private db: AngularFireDatabase
, public firebaseAuth: AngularFireAuth
)
{ {
this.isWeb = (document.URL.startsWith('http') || !document.URL.startsWith('http://localhost:8080')); this.isWeb = (document.URL.startsWith('http') || !document.URL.startsWith('http://localhost:8080'));
// asyncrounosly kick off a poller that does the work of syncing remotely when the
// profile needs to be synced.
(function poll(self)
{
setTimeout(function ()
{
// Setup the next poll recursively
if (self.needsSync)
{
// do the sync here.
// If we have a remote profile then save it there too
if (self.remoteProfile && self.localProfile.uid)
{
let st = new Date(); console.log('Saving the remote profile...');
self.remoteProfile.ref.set(self.localProfile);
console.log('Finished saving remote profile. ' + self.elapsed(st, new Date) + 'ms');
}
self.needsSync = false;
}
poll(self);
}, 3000);
})(this);
let localObserver = this.userObserver().subscribe( let localObserver = this.userObserver().subscribe(
user => user =>
{ {
@ -88,12 +109,15 @@ export class ProfileService
subscribeToRemoteProfile(db: AngularFireDatabase, user: firebase.User) subscribeToRemoteProfile(db: AngularFireDatabase, user: firebase.User)
{ {
if (!user) return; if (!user) return;
let obj = db.object('/settings/' + user.uid); let obj = db.object('/settings/' + user.uid);
this.remoteProfile = { this.remoteProfile = {
ref: obj as AngularFireObject<User>, ref: obj as AngularFireObject<User>,
stream: obj.valueChanges() as Observable<User>, stream: obj.valueChanges() as Observable<User>,
}; };
this.profile().username = user.displayName; this.profile().username = user.displayName;
this.profile().uid = user.uid;
this.save(); this.save();
this.remoteProfile.stream.subscribe( this.remoteProfile.stream.subscribe(
user => this.handleRemotePreferenceChange(user), user => this.handleRemotePreferenceChange(user),
@ -107,21 +131,26 @@ export class ProfileService
if (!user.saved_pages) user.saved_pages = []; if (!user.saved_pages) user.saved_pages = [];
if (!user.items) user.items = []; if (!user.items) user.items = [];
// merge the items and the saved_pages, so they don't loose anything. // merge the items so you don't loose anything.
if (this.localProfile.items.length > 0) if (this.profile().items.length > 0)
user.items.concat(this.localProfile.items); user.items.concat(this.localProfile.items);
if (this.localProfile.saved_pages.length > 0) // merge the saved pages so you don't loose those either
if (this.profile().saved_pages.length > 0)
user.saved_pages.concat(this.localProfile.saved_pages); user.saved_pages.concat(this.localProfile.saved_pages);
this.localProfile = user; // don't sync things that don't make sense.
this.profile().uid = user.uid;
this.profile().username = user.username;
// We only save the local change here since this is an update from our remote profile. // We only save the local change here since this is an update from our remote profile.
this.localSave(); this.localSave();
} }
else else
{ {
// No user is there so we should save our local to the remote. // No user is there so we should save our local to the remote.
this.save()
this.save();
} }
} }
@ -154,7 +183,7 @@ export class ProfileService
} }
Refresh() refresh()
{ {
this.logout(); this.logout();
this.authenticate(); this.authenticate();
@ -167,28 +196,32 @@ export class ProfileService
this.remoteLoggedIn = false; this.remoteLoggedIn = false;
} }
save()
{
this.localSave();
this.needsSync = true;
}
private localSave() private localSave()
{ {
this.local.set('profile', JSON.stringify(this.profile())); this.local.set('profile', JSON.stringify(this.profile()));
} }
save()
{
// First we save our local copy of the settings.
this.localSave();
// If we have a remote profile then save it there too private elapsed(start: Date, finish: Date)
if (this.remoteProfile) {
{ let difference = new Date();
this.remoteProfile.ref.set(this.profile()); difference.setTime(finish.getTime() - start.getTime());
} return difference.getMilliseconds();
} }
public update(t: User): boolean // this function updates a user object, in case new properties have been introduced
// in a release.
update(t: User): boolean
{ {
let updated = false; let updated = false;
let k; let k;
const user = this.localProfile; const user = this.profile();
for (k in user) for (k in user)
{ {
if (user.hasOwnProperty(k)) if (user.hasOwnProperty(k))
@ -209,43 +242,42 @@ export class ProfileService
return updated; return updated;
} }
private resetUser() private resetUser()
{ {
this.localProfile.strongs_modal = true; this.profile().strongs_modal = true;
this.localProfile.clear_search_after_query = false; this.profile().clear_search_after_query = false;
this.localProfile.items = []; this.profile().items = [];
this.localProfile.append_to_bottom = false; this.profile().append_to_bottom = false;
this.localProfile.insert_next_to_item = false; this.profile().insert_next_to_item = false;
this.localProfile.font_size = 10; this.profile().font_size = 10;
this.localProfile.saved_pages = []; this.profile().saved_pages = [];
this.localProfile.verses_on_new_line = true; this.profile().verses_on_new_line = true;
this.localProfile.show_verse_numbers = true; this.profile().show_verse_numbers = true;
} }
reset() reset()
{ {
this.resetUser(); this.resetUser();
this.remoteProfile.ref.set(this.localProfile) this.remoteProfile.ref.set(this.profile())
this.save() this.save();
} }
removePage(page: SavedPage) removePage(page: SavedPage)
{ {
let idx = this.localProfile.saved_pages.indexOf(page); let idx = this.profile().saved_pages.indexOf(page);
this.localProfile.saved_pages.splice(idx, 1); this.profile().saved_pages.splice(idx, 1);
// save the users settings. // Sync with remote
this.save(); this.save();
} }
// TODO(jwall): This belongs somewhere else. // TODO(jwall): This belongs somewhere else.
public textSizeChanged() textSizeChanged()
{ {
$('html').css('font-size', this.localProfile.font_size + 'px'); $('html').css('font-size', this.profile().font_size + 'px');
} }
public static createDefaultUser(): User static createDefaultUser(): User
{ {
return { return {
username: DEFAULT_USER_NAME, username: DEFAULT_USER_NAME,