/// import { Injectable } from '@angular/core'; import { AngularFireDatabase, AngularFireObject } from 'angularfire2/database'; import { AngularFireAuth } from 'angularfire2/auth'; import * as firebase from 'firebase/app'; import { Observable } from 'rxjs/Observable'; import { Catch } from 'rxjs/add/operator'; import { Storage } from '@ionic/storage'; import { CardItem } from '../pages/search/search'; type fbObject = { ref: AngularFireObject, stream: Observable, }; export const DEFAULT_USER_NAME = 'john_doe'; export type User = { username: string, uid: string|null, strongs_modal: boolean, clear_search_after_query: boolean, items: CardItem[], append_to_bottom: boolean, insert_next_to_item: boolean, font_size: number, saved_pages: SavedPage[], verses_on_new_line: boolean, } export type SavedPage = { queries: CardItem[], title: string, } @Injectable() export class ProfileService { localProfile: User; remoteProfile: fbObject | null; constructor( private local: Storage , private db: AngularFireDatabase , public fbAuth: AngularFireAuth ) { console.log('Setting up default user initially'); this.fbAuth.authState.subscribe(state => this.subscribeToRemoteProfile(db, state)); let localObserver = this.userObserver().subscribe( user => { this.update(user); this.localProfile = user; }, error => console.log(error)); } userObserver(): Observable { return Observable.fromPromise(this.local.get('profile')).map(json_profile => { let t = this.profile(); if (json_profile !== null) t = JSON.parse(json_profile); return t; }); } profile(): User { if (!this.localProfile) { console.log('Initializing default user'); this.localProfile = ProfileService.createDefaultUser(); } console.log('Returning Profile with user: ' + this.localProfile); return this.localProfile } subscribeToRemoteProfile(db: AngularFireDatabase, user: firebase.User) { if (!user) return; console.log('Subscribing to remote settings for user id%s', user.uid); let obj = db.object('/settings/' + user.uid); this.remoteProfile = { ref: obj as AngularFireObject, stream: obj.valueChanges() as Observable, }; this.profile().username = user.displayName; this.save(); this.remoteProfile.stream.subscribe( user => this.handleRemotePreferenceChange(user), error => console.log(error)); } handleRemotePreferenceChange(user: User) { if (user) { console.log('handling remote settings for user %s', user.username); if (!user.saved_pages) user.saved_pages = []; this.localProfile = user; console.log('Stashed remote changes locally'); // We only save the local change here since this is an update from our remote profile. this.localSave(); console.log('Saved remote changes locally'); } else { // No user is there so we should save our local to the remote. console.log('Saving local to remote for user %s', user.username); this.save() console.log('Saved remote for user %s', user.username); } } currentUser(): firebase.User { return this.fbAuth.auth.currentUser; } authenticate() { this.fbAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider()); } logout() { this.fbAuth.auth.signOut(); } private localSave() { 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 if (this.remoteProfile) { console.log('Saving remote settings profile for remote user id ' + this.profile().uid); this.remoteProfile.ref.set(this.profile()); } } public update(t: User): boolean { let updated = false; let k; const user = this.localProfile; for (k in user) { if (user.hasOwnProperty(k)) { if (t[k] === undefined) { t[k] = user[k]; updated = true; } } } for (k in user) if (user.hasOwnProperty(k)) user[k] = t[k]; this.textSizeChanged(); return updated; } private resetUser() { this.localProfile.strongs_modal = true; this.localProfile.clear_search_after_query = false; this.localProfile.items = []; this.localProfile.append_to_bottom = false; this.localProfile.insert_next_to_item = false; this.localProfile.font_size = 10; this.localProfile.saved_pages = []; this.localProfile.verses_on_new_line = true; } reset() { this.resetUser(); this.remoteProfile.ref.set(this.localProfile) this.save() } removePage(page: SavedPage) { let idx = this.localProfile.saved_pages.indexOf(page); this.localProfile.saved_pages.splice(idx, 1); // save the users settings. this.save(); } // TODO(jwall): This belongs somewhere else. public textSizeChanged() { $('html').css('font-size', this.localProfile.font_size + 'px'); } public static createDefaultUser(): User { return { username: DEFAULT_USER_NAME, uid: null, strongs_modal: true, clear_search_after_query: false, items: [], append_to_bottom: false, insert_next_to_item: false, font_size: 10, saved_pages: [], verses_on_new_line: true }; } }