mirror of
https://gitlab.com/walljm/dynamicbible.git
synced 2025-07-24 16:00:11 -04:00
FEATURE: Move Help and Settings pages to modals
* fixed ton of bugs... apparently i didn't push up the work i did on the mac... and i don't have that anymore.
This commit is contained in:
parent
5e8d96f716
commit
e444a5fddf
File diff suppressed because one or more lines are too long
@ -1,17 +1,18 @@
|
||||
import { Component, ViewChild } from '@angular/core';
|
||||
import { Platform, MenuController, Nav } from 'ionic-angular';
|
||||
import { Platform, MenuController, Nav, ModalController } from 'ionic-angular';
|
||||
import { StatusBar } from '@ionic-native/status-bar';
|
||||
import { SplashScreen } from '@ionic-native/splash-screen';
|
||||
import { SearchPage } from '../pages/search/search';
|
||||
|
||||
import { PagesService } from '../services/pages-service';
|
||||
import { PagesService, Page } from '../services/pages-service';
|
||||
import { PageTitles } from '../libs/Constants';
|
||||
|
||||
|
||||
@Component({
|
||||
templateUrl: 'app.html',
|
||||
providers: [PagesService]
|
||||
})
|
||||
export class MyApp
|
||||
{
|
||||
export class MyApp {
|
||||
@ViewChild(Nav) nav: Nav;
|
||||
|
||||
rootPage: any = SearchPage;
|
||||
@ -19,32 +20,39 @@ export class MyApp
|
||||
constructor(
|
||||
public platform: Platform,
|
||||
public menu: MenuController,
|
||||
private statusBar: StatusBar,
|
||||
private splash: SplashScreen,
|
||||
private pagesSvc: PagesService
|
||||
)
|
||||
{
|
||||
public pagesSvc: PagesService,
|
||||
private _statusBar: StatusBar,
|
||||
private _splash: SplashScreen,
|
||||
private _modalCtrl: ModalController
|
||||
) {
|
||||
this.initializeApp();
|
||||
}
|
||||
|
||||
initializeApp()
|
||||
{
|
||||
this.platform.ready().then(() =>
|
||||
{
|
||||
initializeApp() {
|
||||
this.platform.ready().then(() => {
|
||||
// Okay, so the platform is ready and our plugins are available.
|
||||
// Here you can do any higher level native things you might need.
|
||||
this.statusBar.styleDefault();
|
||||
this.splash.hide();
|
||||
this._statusBar.styleDefault();
|
||||
this._splash.hide();
|
||||
});
|
||||
}
|
||||
|
||||
openPage(page)
|
||||
{
|
||||
openPage(page: Page) {
|
||||
if (page.title === PageTitles.Help || page.title === PageTitles.Settings)
|
||||
{
|
||||
this.menu.close(); // close the menu
|
||||
|
||||
// this is a modal.
|
||||
const modal = this._modalCtrl.create(page.component);
|
||||
modal.present();
|
||||
return;
|
||||
}
|
||||
|
||||
// close the menu when clicking a link from the menu
|
||||
this.menu.close('pages');
|
||||
|
||||
|
||||
// because the actions menu is on a Page component, and you swap the SearchPage out,
|
||||
// the menu get registered multiple times. to avoid some pages not opening the menu because
|
||||
// the menu gets registered multiple times. to avoid some pages not opening the menu because
|
||||
// multiple menus with the same id exist and the first one in the list is returned (which happens
|
||||
// be disabled when another of the same id is added) it won't show. because not enabled.
|
||||
// ---
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ProfileService } from './../services/profile-service';
|
||||
import { NgModule, ErrorHandler } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { HttpModule } from '@angular/http';
|
||||
|
||||
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
|
||||
@ -13,17 +13,17 @@ import { SplashScreen } from '@ionic-native/splash-screen';
|
||||
import { MyApp } from './app.component';
|
||||
|
||||
import { SearchPage } from '../pages/search/search';
|
||||
import { SettingsPage } from '../pages/settings/settings';
|
||||
import { HelpPage } from '../pages/help/help';
|
||||
|
||||
import { ComponentLoader } from '../components/component-loader/component-loader';
|
||||
import { Passage } from '../components/passage/passage';
|
||||
import { Strongs } from '../components/strongs/strongs';
|
||||
import { Words } from '../components/words/words';
|
||||
import { Error } from '../components/error/error';
|
||||
import { Settings } from '../components/settings/settings';
|
||||
import { StrongsModal } from '../components/strongs-modal/strongs-modal';
|
||||
import { ErrorMessage } from '../components/error-message/error-message';
|
||||
import { VersePickerModal } from '../components/verse-picker/verse-picker';
|
||||
import { AboutModal } from '../components/about-modal/about-modal';
|
||||
import { SettingsModal } from '../components/settings-modal/settings-modal';
|
||||
|
||||
import { AngularFireModule } from 'angularfire2';
|
||||
import { AngularFireAuthModule } from 'angularfire2/auth';
|
||||
@ -46,9 +46,9 @@ export const firebaseConfig = {
|
||||
declarations: [
|
||||
MyApp,
|
||||
SearchPage,
|
||||
SettingsPage,
|
||||
HelpPage,
|
||||
ComponentLoader,
|
||||
AboutModal,
|
||||
SettingsModal,
|
||||
Settings,
|
||||
Passage,
|
||||
Strongs,
|
||||
StrongsModal,
|
||||
@ -72,8 +72,9 @@ export const firebaseConfig = {
|
||||
entryComponents: [
|
||||
MyApp,
|
||||
SearchPage,
|
||||
SettingsPage,
|
||||
HelpPage,
|
||||
AboutModal,
|
||||
SettingsModal,
|
||||
Settings,
|
||||
Passage,
|
||||
Strongs,
|
||||
StrongsModal,
|
||||
|
122
DynamicBibleIonic/src/components/about-modal/about-modal.html
Normal file
122
DynamicBibleIonic/src/components/about-modal/about-modal.html
Normal file
@ -0,0 +1,122 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
<ion-icon name="help-circle" item-left></ion-icon> Dynamic Bible Help
|
||||
</ion-title>
|
||||
<ion-buttons start>
|
||||
<button ion-button (click)="dismiss()" large>
|
||||
<ion-icon name="md-close"></ion-icon>
|
||||
</button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<h2>How to search for a verse</h2>
|
||||
<p>
|
||||
To bring up a passage, just type in a reference, or use the verse picker in the top right corner. Dynamic Bible will recognize most abbreviations of books, and can handle ranges within a book. Here are a few examples to get you started:
|
||||
</p>
|
||||
<h3>Examples of Search Items:</h3>
|
||||
<ul>
|
||||
<li><b>John 1</b> (displays whole chapter)</li>
|
||||
<li><b>John 3:16</b> (displays single verse)</li>
|
||||
<li><b>Jn 3:16</b> (handles abbreviation of John)</li>
|
||||
<li><b>Jn 3:16-17</b> (displays verses starting with chapter 1 verse 3 through chapter 1 vs 5)</li>
|
||||
<li><b>John 3:16-4:4</b></li>
|
||||
<li><b>Jn 3-4</b> (displays both chapters)</li>
|
||||
<li><b>John 3 - John 4</b> (displays both chapters)</li>
|
||||
<li><b>Jn 3:1-*</b> (this will get all the verses in the chapter. the * char can be used in verse ranges, but not chapter ranges.)</li>
|
||||
<li><b>H1234</b> (displays the strongs definition for the Hebrew # 1234)</li>
|
||||
<li><b>G1234</b> (displays the strongs definition for the Greek # 1234)</li>
|
||||
<li><b>Jesus</b> (searches for "Jesus". all search terms assume boolean AND, i.e. "Jesus Christ" assumes "Jesus AND Christ". A word without a number is interpreted as search term).</li>
|
||||
</ul>
|
||||
|
||||
We currently don't support ranges that cross book boundaries. If you search for "John 12 - Romans 3" you will get an error. the second book name is ignored.
|
||||
|
||||
<h3>Further Notes:</h3>
|
||||
<ul>
|
||||
<li>Multiple lookups can be made using a semicolon as a seperator, i.e. "Ruth 1; g1234; spirit").</li>
|
||||
<li>All greek/hebrew cross references translations are taken from the 1933 Websters version and are sometimes not the same as the KJV translation.</li>
|
||||
<li>All source materials were taken from the <a href="http://sourceforge.net/projects/zefania-sharp/">Zefania XML Bible Project</a> on SourceForge.</li>
|
||||
<li>Any Errors and Omission you find would be appreciated. Please contact me via <a href='http://www.jasonwall.org/'>www.jasonwall.org</a>.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Visit Us Online</h3>
|
||||
<p>
|
||||
<a href="http://www.dynamicbible.com">www.dynamicbible.com</a> hosts the online version of the web app. We are currently available on the
|
||||
<a href="https://bitbucket.org/walljm/dynamicbible/downloads/DynamicBible-3.1.0.zip">Windows Platform</a> via the <a href="http://electron.atom.io/">Electron app from atom.io</a>
|
||||
and on the <a href="https://play.google.com/store/apps/details?id=walljm.dynamicbible">Google Android Play store</a>.
|
||||
|
||||
We are working on an IOS distribution and will be releasing that soon.
|
||||
</p>
|
||||
|
||||
<h3>Book Names and Accepted Abbreviations</h3>
|
||||
<ul>
|
||||
<li><b>Genesis</b>: gen, ge, gn</li>
|
||||
<li><b>Exodus</b>: ex, exo, exod, exd</li>
|
||||
<li><b>Leviticus</b>: lev, le, levi, lv</li>
|
||||
<li><b>Numbers</b>: num, nu, numb, number</li>
|
||||
<li><b>Deuteronomy</b>: deut, de, dt, deu</li>
|
||||
<li><b>Joshua</b>: josh, jos</li>
|
||||
<li><b>Judges</b>: jud, jdg, judg</li>
|
||||
<li><b>Ruth</b>: ru</li>
|
||||
<li><b>1 Samuel</b>: 1, i, 1st, first samuel, sa, sam, sml</li>
|
||||
<li><b>2 Samuel</b>: 2, ii, 2nd, second, sec samuel, sa, sam, sml</li>
|
||||
<li><b>1 Kings</b>: 1, i, 1st, first kings, king, kgs, kn, k, ki</li>
|
||||
<li><b>2 Kings</b>: 2, ii, 2nd, second, sec kings, king, kgs, kn, k, ki</li>
|
||||
<li><b>1 Chronicles</b>: 1, i, 1st, first chronicles, chron, ch, chr</li>
|
||||
<li><b>2 Chronicles</b>: 2, ii, 2nd, second, sec chronicles, chron, ch, chr</li>
|
||||
<li><b>Ezra</b>: ezr</li>
|
||||
<li><b>Nehemiah</b>: neh, ne, nehamiah</li>
|
||||
<li><b>Esther</b>: est, es, esth</li>
|
||||
<li><b>Job</b>: jo, jb</li>
|
||||
<li><b>Psalms</b>: ps, psa, psalm, psm</li>
|
||||
<li><b>Proverbs</b>: prov, pr, pro, proverb, prv, prvbs</li>
|
||||
<li><b>Ecclesiastes</b>: eccl, ecc, eccles, ec, ecl, ecclesiaste</li>
|
||||
<li><b>Song of Solomon</b>: , song of songs, sos, ss, son, so, song, songs</li>
|
||||
<li><b>Isaiah</b>: is, isah, isai, ia</li>
|
||||
<li><b>Jerimiah</b>: jeremiah, jer, je, jere</li>
|
||||
<li><b>Lamentations</b>: lam, la, lamentation</li>
|
||||
<li><b>Ezekiel</b>: eze, ezk, ezek</li>
|
||||
<li><b>Daniel</b>: dan, dn, dl, da</li>
|
||||
<li><b>Hosea</b>: hos, ho</li>
|
||||
<li><b>Joel</b>: joe, jl</li>
|
||||
<li><b>Amos</b>: am, amo</li>
|
||||
<li><b>Obadiah</b>: oba, ob, obad</li>
|
||||
<li><b>Jonah</b>: jnh, jon</li>
|
||||
<li><b>Micah</b>: mic, mi</li>
|
||||
<li><b>Nahum</b>: nah, na</li>
|
||||
<li><b>Habakkuk</b>: hab, ha, habakuk</li>
|
||||
<li><b>Zephaniah</b>: zeph, zep</li>
|
||||
<li><b>Haggia</b>: hag, hg, haggai</li>
|
||||
<li><b>Zechariah</b>: zech, zch, zec</li>
|
||||
<li><b>Malachi</b>: mal</li>
|
||||
<li><b>Matthew</b>: mt, matt, mat</li>
|
||||
<li><b>Mark</b>: mrk, mk, mr</li>
|
||||
<li><b>luke</b>: lu, lke, luk, lk</li>
|
||||
<li><b>John</b>: jn, jhn</li>
|
||||
<li><b>Acts</b>: ac, act</li>
|
||||
<li><b>Romans</b>: rom, ro, rm, roman</li>
|
||||
<li><b>1 Corinthians</b>: 1, i, 1st, first corinthian, cor, corinthians, corinth, corin, corth, corint</li>
|
||||
<li><b>2 Corinthians</b>: 2, ii, 2nd, second, sec corinthian, cor, corinthians, corinth, corin, corth, corint</li>
|
||||
<li><b>Galatians</b>: galatian, galations, gal, ga, gala, galation, galat</li>
|
||||
<li><b>Ephesians</b>: eph, ep, ephes, ephe, ephs</li>
|
||||
<li><b>Philippians</b>: phi, phil, ph, philip</li>
|
||||
<li><b>Colossians</b>: col, co, colossian, colos, coloss</li>
|
||||
<li><b>1 Thessalonians</b>: 1, i, 1st, first thessalonians, the, thessa, thessalonian, thes, thess, th</li>
|
||||
<li><b>2 Thessalonians</b>: 2, ii, 2nd, second, sec thessalonians, the, thessa, thessalonian, thes, thess, th</li>
|
||||
<li><b>1 Timothy</b>: 1, i, 1st, first timothy, tim, ti, timoth, tm</li>
|
||||
<li><b>2 Timothy</b>: 2, ii, 2nd, second, sec timothy, tim, timoth, tm</li>
|
||||
<li><b>Titus</b>: tit</li>
|
||||
<li><b>Philemon</b>: phlmn, phl, phm, phile, philem</li>
|
||||
<li><b>Hebrews</b>: heb, he, hebrew</li>
|
||||
<li><b>James</b>: jam, ja, jas, jms, jame, jm</li>
|
||||
<li><b>1 Peter</b>: 1, i, 1st, first peter, pe, pet, pete, pt, p</li>
|
||||
<li><b>2 Peter</b>: 2, ii, 2nd, second, sec peter, pe, pet, pete, pt, p</li>
|
||||
<li><b>1 John</b>: 1, i, 1st, first john, jn, jo</li>
|
||||
<li><b>2 John</b>: 2, ii, 2nd, second, sec john, jn, jo</li>
|
||||
<li><b>3 John</b>: 3, iii, 3rd, third john, jn, jo</li>
|
||||
<li><b>Jude</b>: ju</li>
|
||||
<li><b>Revelation</b>: rev, re, revelations, rv</li>
|
||||
</ul>
|
||||
</ion-content>
|
@ -0,0 +1,9 @@
|
||||
about-modal {
|
||||
ion-icon {
|
||||
float: left;
|
||||
}
|
||||
|
||||
ion-title {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
14
DynamicBibleIonic/src/components/about-modal/about-modal.ts
Normal file
14
DynamicBibleIonic/src/components/about-modal/about-modal.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ViewController } from 'ionic-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'about-modal',
|
||||
templateUrl: 'about-modal.html'
|
||||
})
|
||||
export class AboutModal {
|
||||
constructor(private _viewCtrl: ViewController) {}
|
||||
|
||||
dismiss() {
|
||||
this._viewCtrl.dismiss();
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
// our root app component
|
||||
import {Component, Compiler, ViewContainerRef, ViewChild, Input, ComponentRef, ComponentFactoryResolver, ChangeDetectorRef} from '@angular/core'
|
||||
|
||||
// Helper component to add dynamic components
|
||||
@Component({
|
||||
selector: 'component-loader',
|
||||
template: `<div #target></div>`
|
||||
})
|
||||
export class ComponentLoader {
|
||||
@ViewChild('target', { read: ViewContainerRef }) target;
|
||||
@Input() type;
|
||||
@Input() data;
|
||||
cmpRef: ComponentRef<any>;
|
||||
private isViewInitialized = false;
|
||||
|
||||
constructor(private componentFactoryResolver: ComponentFactoryResolver, private compiler: Compiler,
|
||||
private cdRef: ChangeDetectorRef) { }
|
||||
|
||||
updateComponent() {
|
||||
if (!this.isViewInitialized) {
|
||||
return;
|
||||
}
|
||||
if (this.cmpRef) {
|
||||
this.cmpRef.destroy();
|
||||
}
|
||||
|
||||
const factory = this.componentFactoryResolver.resolveComponentFactory(this.type);
|
||||
this.cmpRef = this.target.createComponent(factory);
|
||||
// to access the created instance use
|
||||
// this.compRef.instance.someProperty = 'someValue';
|
||||
// this.compRef.instance.someOutput.subscribe(val => doSomething());
|
||||
|
||||
this.cmpRef.instance.item = this.data;
|
||||
|
||||
this.cdRef.detectChanges();
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
this.updateComponent();
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.isViewInitialized = true;
|
||||
this.updateComponent();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.cmpRef) {
|
||||
this.cmpRef.destroy();
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,9 @@
|
||||
<br>
|
||||
<p>{{cardItem.qry}}</p>
|
||||
</ion-card-content>
|
||||
<button ion-button icon-start clear small (click)="close()">
|
||||
<ion-icon name="close-circle"></ion-icon>
|
||||
<div>Close</div>
|
||||
</button>
|
||||
|
||||
<div style="float: right">
|
||||
<button ion-button icon-center clear (click)="contextMenu()">
|
||||
<ion-icon name="more"></ion-icon>
|
||||
</button>
|
||||
</div>
|
@ -1,5 +1,9 @@
|
||||
import { EventEmitter, Component, Input, Output, ElementRef } from '@angular/core';
|
||||
import { CardItem } from '../../pages/search/search';
|
||||
import { ProfileService } from '../../services/profile-service';
|
||||
import { ActionSheetController, AlertController } from 'ionic-angular';
|
||||
import { PagesService } from '../../services/pages-service';
|
||||
import { cardContextMenu } from '../../libs/Common';
|
||||
|
||||
@Component({
|
||||
selector: 'error',
|
||||
@ -13,17 +17,25 @@ export class Error
|
||||
@Input()
|
||||
cardItem: CardItem;
|
||||
|
||||
constructor(private elementRef: ElementRef)
|
||||
constructor(
|
||||
private _elementRef: ElementRef,
|
||||
private _profileService: ProfileService,
|
||||
private _actionSheet: ActionSheetController,
|
||||
private _pagesSvc: PagesService,
|
||||
private _alertCtrl: AlertController)
|
||||
{
|
||||
}
|
||||
|
||||
contextMenu() {
|
||||
cardContextMenu(this._profileService, this._actionSheet, this._pagesSvc, this._alertCtrl, this.cardItem);
|
||||
}
|
||||
close(ev) {
|
||||
let translate = 'translate3d(110%, 0, 0)';
|
||||
if (ev != null && ev.direction === 2) {
|
||||
translate = 'translate3d(-110%, 0, 0)';
|
||||
}
|
||||
let d = 250;
|
||||
this.elementRef.nativeElement.parentElement.animate({
|
||||
this._elementRef.nativeElement.parentElement.animate({
|
||||
transform: ['none', translate]
|
||||
}, {
|
||||
fill: 'forwards',
|
||||
|
@ -6,42 +6,37 @@
|
||||
</ion-item>
|
||||
<ion-card-content *ngIf="data !== undefined && data.status === 0">
|
||||
<br>
|
||||
<ng-template [ngIf]="this.profileService.profile().show_paragraphs"><div class="passage-text" *ngFor="let ch of withParas">
|
||||
<ng-template [ngIf]="profileService.profile().show_paragraphs"><div class="passage-text" *ngFor="let ch of withParas">
|
||||
<h2 *ngIf="data.cs.length > 1">
|
||||
<b>Chapter {{ch.ch}}</b>
|
||||
</h2>
|
||||
<div *ngFor="let para of ch.paras">
|
||||
<h3 *ngIf="this.profileService.profile().show_paragraph_headings && hasHeader(para.p)">{{para.p.h}}</h3>
|
||||
<h3 *ngIf="profileService.profile().show_paragraph_headings && hasHeader(para.p)">{{para.p.h}}</h3>
|
||||
<p>
|
||||
<ng-template ngFor let-vs [ngForOf]="para.vss">
|
||||
<b *ngIf="this.profileService.profile().show_verse_numbers">{{vs.v}}.</b> <ng-template ngFor let-w [ngForOf]="vs.w">
|
||||
<b *ngIf="profileService.profile().show_verse_numbers">{{vs.v}}.</b> <ng-template ngFor let-w [ngForOf]="vs.w">
|
||||
<ng-template [ngIf]="!isPunct(w.t)"> </ng-template><a *ngIf="w.s != null" (click)="openStrongs(w.s)" (press)="openMenu(w.s)">{{w.t}}</a>
|
||||
<ng-template [ngIf]="w.s == null">{{w.t}}</ng-template>
|
||||
</ng-template><br *ngIf="this.profileService.profile().verses_on_new_line">
|
||||
</ng-template><br *ngIf="profileService.profile().verses_on_new_line">
|
||||
</ng-template>
|
||||
</p>
|
||||
</div>
|
||||
</div></ng-template>
|
||||
<ng-template [ngIf]="!this.profileService.profile().show_paragraphs"><div class="passage-text" *ngFor="let ch of data.cs">
|
||||
<ng-template [ngIf]="!profileService.profile().show_paragraphs"><div class="passage-text" *ngFor="let ch of data.cs">
|
||||
<h2 *ngIf="data.cs.length > 1">
|
||||
<b>Chapter {{ch.ch}}</b>
|
||||
</h2>
|
||||
<ng-template ngFor let-vs [ngForOf]="ch.vss">
|
||||
<b *ngIf="this.profileService.profile().show_verse_numbers">{{vs.v}}.</b> <ng-template ngFor let-w [ngForOf]="vs.w">
|
||||
<b *ngIf="profileService.profile().show_verse_numbers">{{vs.v}}.</b> <ng-template ngFor let-w [ngForOf]="vs.w">
|
||||
<ng-template [ngIf]="!isPunct(w.t)"> </ng-template><a *ngIf="w.s != null" (click)="openStrongs(w.s)" (press)="openMenu(w.s)">{{w.t}}</a>
|
||||
<ng-template [ngIf]="w.s == null">{{w.t}}</ng-template>
|
||||
</ng-template><br *ngIf="this.profileService.profile().verses_on_new_line">
|
||||
</ng-template><br *ngIf="profileService.profile().verses_on_new_line">
|
||||
</ng-template>
|
||||
</div></ng-template>
|
||||
</ion-card-content>
|
||||
<ion-card-content *ngIf="data !== undefined && data.status === -1">
|
||||
<error-message [msg]="data.msg"></error-message>
|
||||
</ion-card-content>
|
||||
<div style="float: left">
|
||||
<button ion-button icon-start clear (click)="close()">
|
||||
<ion-icon name="close-circle"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div style="float: right">
|
||||
<button ion-button icon-center clear (click)="prev()" *ngIf="ref !== undefined && ref.Section.start.chapter !== '1'">
|
||||
<ion-icon name="rewind"></ion-icon>
|
||||
@ -52,7 +47,6 @@
|
||||
<button ion-button icon-center clear (click)="next()" *ngIf="ref !== undefined && ref.Section.end.chapter !== ref.Section.end.book.last_chapter.toString()">
|
||||
<ion-icon name="fastforward"></ion-icon>
|
||||
</button>
|
||||
|
||||
<button ion-button icon-center clear (click)="contextMenu()">
|
||||
<ion-icon name="more"></ion-icon>
|
||||
</button>
|
||||
|
@ -5,6 +5,7 @@ passage {
|
||||
}
|
||||
|
||||
font-family: var(--card-font);
|
||||
|
||||
}
|
||||
|
||||
passage .button {
|
||||
@ -17,15 +18,17 @@ passage .button {
|
||||
|
||||
passage .passage-text {
|
||||
padding-bottom: 12px;
|
||||
|
||||
h3 {
|
||||
font-size: 1.6rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.passage-text + .passage-text {
|
||||
.passage-text+.passage-text {
|
||||
border-top: 1px dotted #808080;
|
||||
padding-top: 12px;
|
||||
}
|
||||
@ -46,4 +49,3 @@ passage .passage-text {
|
||||
// column-rule-width: 1px;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { Component, EventEmitter, Output, Input, OnInit, ElementRef } from '@angular/core';
|
||||
import { OpenData, CardItem } from '../../pages/search/search';
|
||||
import { BiblePassageResult, BibleService, BiblePassage, BibleVerse, HashTable, Paragraph } from '../../services/bible-service';
|
||||
import { BiblePassageResult, BibleService, BiblePassage, BibleVerse, Paragraph } from '../../services/bible-service';
|
||||
import { Reference } from '../../libs/Reference';
|
||||
import { ProfileService } from '../../services/profile-service';
|
||||
import { ActionSheetController, GestureController, GESTURE_ITEM_SWIPE, AlertController } from 'ionic-angular';
|
||||
import { ActionSheetController, AlertController } from 'ionic-angular';
|
||||
import { PagesService } from '../../services/pages-service';
|
||||
import { GESTURE_PRIORITY_SLIDING_ITEM } from 'ionic-angular/umd/gestures/gesture-controller';
|
||||
import { cardContextMenu } from '../../libs/Common';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'passage',
|
||||
@ -24,22 +25,21 @@ export class Passage implements OnInit {
|
||||
data: BiblePassageResult;
|
||||
withParas: BibleParaPassage[];
|
||||
ref: Reference;
|
||||
private gesture;
|
||||
|
||||
constructor(
|
||||
private bibleService: BibleService,
|
||||
private elementRef: ElementRef,
|
||||
private profileService: ProfileService,
|
||||
private actionSheet: ActionSheetController,
|
||||
private pagesSvc: PagesService,
|
||||
private alertCtrl: AlertController
|
||||
public profileService: ProfileService,
|
||||
private _elementRef: ElementRef,
|
||||
private _bibleService: BibleService,
|
||||
private _actionSheet: ActionSheetController,
|
||||
private _pagesSvc: PagesService,
|
||||
private _alertCtrl: AlertController
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
this.ref = new Reference(this.cardItem.qry);
|
||||
this.bibleService.getResultAsPromise(this.ref.Section).then(data => {
|
||||
this._bibleService.getResultAsPromise(this.ref.Section).then(data => {
|
||||
this.setData(data);
|
||||
});
|
||||
|
||||
@ -52,88 +52,7 @@ export class Passage implements OnInit {
|
||||
}
|
||||
|
||||
contextMenu() {
|
||||
const actions = this.actionSheet.create({
|
||||
title: 'Passage Actions',
|
||||
buttons: [
|
||||
{
|
||||
text: 'Add to a Saved Page',
|
||||
icon: 'add-circle',
|
||||
handler: () => {
|
||||
let btns = this.pagesSvc.getSavedPages().map(p => {
|
||||
return {
|
||||
text: p.title,
|
||||
icon: 'bookmark',
|
||||
handler: () => {
|
||||
const page = this.profileService.profile().saved_pages.find(
|
||||
i => i.title === p.title
|
||||
);
|
||||
page.queries.push(this.cardItem);
|
||||
this.profileService.save();
|
||||
}
|
||||
}
|
||||
});
|
||||
btns.push({
|
||||
text: 'Add to New Page',
|
||||
icon: 'create',
|
||||
handler: () => {
|
||||
const alert = this.alertCtrl.create({
|
||||
title: 'Save Passage as Page',
|
||||
inputs: [
|
||||
{
|
||||
name: 'title',
|
||||
placeholder: 'Page Title'
|
||||
}
|
||||
],
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel',
|
||||
handler: (): void => {
|
||||
console.log('Cancel clicked');
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Save',
|
||||
handler: data => {
|
||||
const p = { queries: this.profileService.profile().items.slice(), title: data.title };
|
||||
this.profileService.profile().saved_pages.push(p);
|
||||
this.profileService.save();
|
||||
this.pagesSvc.addPage(p);
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
alert.present();
|
||||
}
|
||||
});
|
||||
this.actionSheet.create({
|
||||
title: 'Saved Pages',
|
||||
buttons: btns
|
||||
}).present();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
if (this.profileService.isOnSearchPage()) {
|
||||
actions.addButton({
|
||||
text: 'Remove from ' + this.profileService.title,
|
||||
icon: 'remove-circle',
|
||||
handler: () => {
|
||||
const page = this.profileService.profile().saved_pages.find(
|
||||
i =>
|
||||
i.title === this.profileService.title
|
||||
);
|
||||
const idx = this.profileService.profile().items.indexOf(this.cardItem);
|
||||
this.profileService.profile().items.splice(idx, 1);
|
||||
|
||||
page.queries = this.profileService.profile().items.slice();
|
||||
this.profileService.save();
|
||||
this.pagesSvc.initializePages(this.profileService.profile().saved_pages);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
actions.present();
|
||||
cardContextMenu(this.profileService, this._actionSheet, this._pagesSvc, this._alertCtrl, this.cardItem);
|
||||
}
|
||||
|
||||
close(ev) {
|
||||
@ -142,7 +61,7 @@ export class Passage implements OnInit {
|
||||
translate = 'translate3d(-110%, 0, 0)';
|
||||
}
|
||||
let d = 250;
|
||||
this.elementRef.nativeElement.parentElement.animate({
|
||||
this._elementRef.nativeElement.parentElement.animate({
|
||||
transform: ['none', translate]
|
||||
}, {
|
||||
fill: 'forwards',
|
||||
@ -167,7 +86,7 @@ export class Passage implements OnInit {
|
||||
this.ref.Section.start.verse = '1';
|
||||
this.ref.Section.end.verse = '*';
|
||||
|
||||
this.bibleService.getResultAsPromise(this.ref.Section).then(data => {
|
||||
this._bibleService.getResultAsPromise(this.ref.Section).then(data => {
|
||||
this.setData(data);
|
||||
this.cardItem.qry = data.ref;
|
||||
this.ref = new Reference(data.ref);
|
||||
@ -184,7 +103,7 @@ export class Passage implements OnInit {
|
||||
this.ref.Section.start.verse = '1';
|
||||
this.ref.Section.end.verse = '*';
|
||||
|
||||
this.bibleService.getResultAsPromise(this.ref.Section).then(data => {
|
||||
this._bibleService.getResultAsPromise(this.ref.Section).then(data => {
|
||||
this.setData(data);
|
||||
this.cardItem.qry = data.ref;
|
||||
this.ref = new Reference(data.ref);
|
||||
@ -225,7 +144,7 @@ export class Passage implements OnInit {
|
||||
if (this.ref.Section.start.verse === '0')
|
||||
this.ref.Section.start.verse = '1';
|
||||
|
||||
this.bibleService.getResultAsPromise(this.ref.Section).then(data => {
|
||||
this._bibleService.getResultAsPromise(this.ref.Section).then(data => {
|
||||
this.setData(data);
|
||||
this.cardItem.qry = data.ref;
|
||||
this.ref = new Reference(data.ref);
|
||||
|
@ -0,0 +1,28 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
<ion-icon name='settings' item-left></ion-icon> Dynamic Bible Settings
|
||||
</ion-title>
|
||||
<ion-buttons start>
|
||||
<button ion-button (click)='dismiss()' large>
|
||||
<ion-icon name='md-close'></ion-icon>
|
||||
</button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<ng-template [ngIf]='_profileService.profile()'>
|
||||
<settings></settings>
|
||||
|
||||
<h4>Manage Pages</h4>
|
||||
<ion-list>
|
||||
<ion-item *ngFor='let p of _profileService.profile().saved_pages'>
|
||||
{{p.title}}
|
||||
<button ion-button item-end outline icon-end (click)='removePage(p)'>
|
||||
Delete Page <ion-icon name='trash'></ion-icon>
|
||||
</button>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ng-template>
|
||||
</ion-content>
|
@ -0,0 +1,17 @@
|
||||
settings-modal {
|
||||
.list-header {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.item-md .item-button {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
ion-icon {
|
||||
float: left;
|
||||
}
|
||||
|
||||
ion-title {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ViewController, AlertController } from 'ionic-angular';
|
||||
import { ProfileService, SavedPage } from '../../services/profile-service';
|
||||
|
||||
@Component({
|
||||
selector: 'settings-modal',
|
||||
templateUrl: 'settings-modal.html'
|
||||
})
|
||||
export class SettingsModal {
|
||||
constructor(
|
||||
private _alertCtrl: AlertController,
|
||||
private _viewCtrl: ViewController,
|
||||
private _profileService: ProfileService
|
||||
) {}
|
||||
|
||||
dismiss() {
|
||||
this._viewCtrl.dismiss();
|
||||
}
|
||||
|
||||
removePage(page: SavedPage) {
|
||||
let alert = this._alertCtrl.create({
|
||||
title: 'Confirm Delete',
|
||||
message: 'Do you want to delete the ' + page.title + ' page?',
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel',
|
||||
handler: () => {
|
||||
console.log('Cancel clicked');
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Ok',
|
||||
handler: () => {
|
||||
this._profileService.removePage(page);
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
alert.present();
|
||||
}
|
||||
}
|
89
DynamicBibleIonic/src/components/settings/settings.html
Normal file
89
DynamicBibleIonic/src/components/settings/settings.html
Normal file
@ -0,0 +1,89 @@
|
||||
<ion-list>
|
||||
<ion-list-header>
|
||||
<ion-icon name='search' item-left></ion-icon>Search Settings
|
||||
</ion-list-header>
|
||||
<ion-item>
|
||||
<ion-label>Show Strongs as Modal</ion-label>
|
||||
<ion-toggle color='dark' [(ngModel)]='profileService.profile().strongs_modal' (ionChange)='profileService.localSave()'></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Clear Search after Query</ion-label>
|
||||
<ion-toggle color='dark' [(ngModel)]='profileService.profile().clear_search_after_query' (ionChange)='profileService.localSave()'></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Append Results Below</ion-label>
|
||||
<ion-toggle color='dark' [(ngModel)]='profileService.profile().append_to_bottom' (ionChange)='profileService.localSave()'></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Insert Result Next to Item</ion-label>
|
||||
<ion-toggle color='dark' [(ngModel)]='profileService.profile().insert_next_to_item' (ionChange)='profileService.localSave()'></ion-toggle>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
<ion-list>
|
||||
<ion-list-header>
|
||||
<ion-icon name='browsers' item-left></ion-icon>Display Settings
|
||||
</ion-list-header>
|
||||
<ion-item>
|
||||
<ion-label>Each Verse on New Line</ion-label>
|
||||
<ion-toggle color='dark' [(ngModel)]='profileService.profile().verses_on_new_line' (ionChange)='profileService.localSave()'></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Show Verse #'s</ion-label>
|
||||
<ion-toggle color='dark' [(ngModel)]='profileService.profile().show_verse_numbers' (ionChange)='profileService.localSave()'></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Show Paragraphs</ion-label>
|
||||
<ion-toggle color='dark' [(ngModel)]='profileService.profile().show_paragraphs' (ionChange)='profileService.localSave()'></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Show Paragraph Headings</ion-label>
|
||||
<ion-toggle color='dark' [(ngModel)]='profileService.profile().show_paragraph_headings' (ionChange)='profileService.localSave()'></ion-toggle>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
<ion-list>
|
||||
<ion-list-header>
|
||||
<ion-icon name='sync' item-left></ion-icon>Profile Settings
|
||||
</ion-list-header>
|
||||
<ion-item>
|
||||
<ion-label>Sync Search Items</ion-label>
|
||||
<ion-toggle color='dark' [(ngModel)]='profileService.profile().sync_search_items' (ionChange)='profileService.localSave()'></ion-toggle>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
<ion-list>
|
||||
<ion-list-header>
|
||||
<ion-icon name='text' item-left></ion-icon>Adjust Text
|
||||
</ion-list-header>
|
||||
<ion-item>
|
||||
<ion-range min='6' max='20' step='1' snaps='true' [(ngModel)]='profileService.profile().font_size' (ionChange)='textSizeChanged()'>
|
||||
<ion-label range-left class='small-text'>a</ion-label>
|
||||
<ion-label range-right>A</ion-label>
|
||||
</ion-range>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Font Family</ion-label>
|
||||
<ion-select [(ngModel)]='profileService.profile().font_family' (ionChange)='fontFamilyChanged()'>
|
||||
<ion-option value='Roboto, Helvetica, Arial, sans-serif'>Sans Serif</ion-option>
|
||||
<ion-option value='"Times New Roman", serif'>Times</ion-option>
|
||||
<ion-option value='Georgia, serif'>Georgia</ion-option>
|
||||
<ion-option value='Merriweather, serif'>Merriweather</ion-option>
|
||||
<ion-option value='Consolas, monotype'>Monospaced</ion-option>
|
||||
<ion-option value='"PT Serif", serif'>PT Serif</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
<ion-list>
|
||||
<ion-list-header>
|
||||
<ion-icon name='log-in' item-left></ion-icon>Login/Logout
|
||||
</ion-list-header>
|
||||
|
||||
<ng-template [ngIf]='!profileService.currentUser()'>
|
||||
<ion-item center>
|
||||
<button ion-button block (click)='profileService.authenticate()'>Login With Google</button>
|
||||
</ion-item>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]='profileService.currentUser()'>
|
||||
<ion-item center>
|
||||
<button ion-button block (click)='profileService.logout()'>Logout</button>
|
||||
</ion-item>
|
||||
</ng-template>
|
||||
</ion-list>
|
3
DynamicBibleIonic/src/components/settings/settings.scss
Normal file
3
DynamicBibleIonic/src/components/settings/settings.scss
Normal file
@ -0,0 +1,3 @@
|
||||
settings {
|
||||
|
||||
}
|
30
DynamicBibleIonic/src/components/settings/settings.ts
Normal file
30
DynamicBibleIonic/src/components/settings/settings.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ProfileService } from '../../services/profile-service';
|
||||
|
||||
@Component({
|
||||
selector: 'settings',
|
||||
templateUrl: 'settings.html'
|
||||
})
|
||||
export class Settings {
|
||||
constructor(
|
||||
public profileService: ProfileService
|
||||
) {}
|
||||
|
||||
|
||||
textSizeChanged()
|
||||
{
|
||||
this.profileService.textSizeChanged();
|
||||
this.profileService.localSave();
|
||||
}
|
||||
|
||||
fontFamilyChanged()
|
||||
{
|
||||
this.profileService.fontFamilyChanged();
|
||||
this.profileService.localSave();
|
||||
}
|
||||
reset()
|
||||
{
|
||||
this.profileService.reset()
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { EventEmitter, Component, Output, OnInit } from '@angular/core';
|
||||
import { Platform, NavParams, ViewController } from 'ionic-angular';
|
||||
import { NavParams, ViewController } from 'ionic-angular';
|
||||
import { Reference } from '../../libs/Reference';
|
||||
import { StrongsResult, StrongsService } from '../../services/strongs-service';
|
||||
|
||||
@ -8,7 +8,7 @@ import { StrongsResult, StrongsService } from '../../services/strongs-service';
|
||||
templateUrl: 'strongs-modal.html',
|
||||
providers: [StrongsService]
|
||||
})
|
||||
export class StrongsModal implements OnInit
|
||||
export class StrongsModal implements OnInit
|
||||
{
|
||||
sn: number;
|
||||
dict: string;
|
||||
@ -17,43 +17,43 @@ export class StrongsModal implements OnInit
|
||||
@Output()
|
||||
onItemClicked = new EventEmitter<string>();
|
||||
|
||||
constructor(private strongsService: StrongsService,
|
||||
public platform: Platform,
|
||||
public params: NavParams,
|
||||
public viewCtrl: ViewController
|
||||
)
|
||||
constructor(
|
||||
private _strongsService: StrongsService,
|
||||
private _params: NavParams,
|
||||
private _viewCtrl: ViewController
|
||||
)
|
||||
{
|
||||
this.sn = this.params.get('sn') as number;
|
||||
this.dict = this.params.get('dict') as string;
|
||||
this.onItemClicked.subscribe(item =>
|
||||
this.sn = this._params.get('sn') as number;
|
||||
this.dict = this._params.get('dict') as string;
|
||||
this.onItemClicked.subscribe(item =>
|
||||
{
|
||||
let pg = this.params.get('onItemClicked');
|
||||
let pg = this._params.get('onItemClicked');
|
||||
pg.updateUIwithItems(item, false);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.strongsService.getResultAsPromise(this.sn, this.dict).then(data => this.item = data);
|
||||
}
|
||||
|
||||
dismiss()
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.viewCtrl.dismiss();
|
||||
this._strongsService.getResultAsPromise(this.sn, this.dict).then(data => this.item = data);
|
||||
}
|
||||
|
||||
openItem(p: string)
|
||||
|
||||
dismiss()
|
||||
{
|
||||
this._viewCtrl.dismiss();
|
||||
}
|
||||
|
||||
openItem(p: string)
|
||||
{
|
||||
this.onItemClicked.emit(p);
|
||||
this.dismiss();
|
||||
}
|
||||
|
||||
makePassage(p: string)
|
||||
makePassage(p: string)
|
||||
{
|
||||
return Reference.bookName(parseInt(p.split(';')[0])).name + ' ' + p.split(';')[1] + ':' + p.split(';')[2];
|
||||
}
|
||||
|
||||
openPassage(p: string)
|
||||
openPassage(p: string)
|
||||
{
|
||||
let ref = this.makePassage(p);
|
||||
this.onItemClicked.emit(ref);
|
||||
|
@ -1,4 +1,4 @@
|
||||
<ion-item class="title strongs-title {{data.prefix}}" padding (swipe)="close($event)">
|
||||
<ion-item class="title strongs-title" padding (swipe)="close($event)">
|
||||
<ion-icon name="paper" item-left></ion-icon> <span *ngIf="data !== undefined"><span *ngIf="data.status === -1">Error:</span> {{data.prefix}}{{data.sn}}</span>
|
||||
<button ion-button icon-only item-end large clear (click)="close()">
|
||||
<ion-icon name="close-circle"></ion-icon>
|
||||
@ -40,7 +40,9 @@
|
||||
<ion-card-content *ngIf="data !== undefined && data.status === -1">
|
||||
<error-message [msg]="data.msg"></error-message>
|
||||
</ion-card-content>
|
||||
<button ion-button item-left icon-start clear small (click)="close()">
|
||||
<ion-icon name="close-circle"></ion-icon>
|
||||
<div>Close</div>
|
||||
</button>
|
||||
|
||||
<div style="float: right">
|
||||
<button ion-button icon-center clear (click)="contextMenu()">
|
||||
<ion-icon name="more"></ion-icon>
|
||||
</button>
|
||||
</div>
|
@ -2,10 +2,7 @@
|
||||
color: #307e4b;
|
||||
}
|
||||
|
||||
.heb-title {
|
||||
background-color:#c6efd4;
|
||||
}
|
||||
.grk-title {
|
||||
.strongs-title {
|
||||
background-color:#a7eebe;
|
||||
}
|
||||
strongs {
|
||||
|
@ -2,6 +2,10 @@ import { HostListener, EventEmitter, Component, Input, Output, OnInit, AfterView
|
||||
import { Reference } from '../../libs/Reference';
|
||||
import { OpenData, CardItem } from '../../pages/search/search';
|
||||
import { StrongsResult, StrongsService } from '../../services/strongs-service';
|
||||
import { cardContextMenu } from '../../libs/Common';
|
||||
import { ProfileService } from '../../services/profile-service';
|
||||
import { ActionSheetController, AlertController } from 'ionic-angular';
|
||||
import { PagesService } from '../../services/pages-service';
|
||||
|
||||
@Component({
|
||||
selector: 'strongs',
|
||||
@ -21,10 +25,20 @@ export class Strongs implements AfterViewChecked, OnInit
|
||||
|
||||
data: StrongsResult;
|
||||
|
||||
constructor(private strongsService: StrongsService, private elementRef: ElementRef)
|
||||
constructor(
|
||||
private _elementRef: ElementRef,
|
||||
private _strongsService: StrongsService,
|
||||
private _profileService: ProfileService,
|
||||
private _actionSheet: ActionSheetController,
|
||||
private _pagesSvc: PagesService,
|
||||
private _alertCtrl: AlertController)
|
||||
{
|
||||
}
|
||||
|
||||
contextMenu() {
|
||||
cardContextMenu(this._profileService, this._actionSheet, this._pagesSvc, this._alertCtrl, this.cardItem);
|
||||
}
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(evt)
|
||||
{
|
||||
@ -45,7 +59,7 @@ export class Strongs implements AfterViewChecked, OnInit
|
||||
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.strongsService.getResultAsPromise(parseInt(this.cardItem.qry), this.cardItem.dict)
|
||||
this._strongsService.getResultAsPromise(parseInt(this.cardItem.qry), this.cardItem.dict)
|
||||
.then(data =>
|
||||
{
|
||||
this.data = data;
|
||||
@ -64,7 +78,7 @@ export class Strongs implements AfterViewChecked, OnInit
|
||||
translate = 'translate3d(-110%, 0, 0)';
|
||||
}
|
||||
let d = 250;
|
||||
this.elementRef.nativeElement.parentElement.animate({
|
||||
this._elementRef.nativeElement.parentElement.animate({
|
||||
transform: ['none', translate]
|
||||
}, {
|
||||
fill: 'forwards',
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { EventEmitter, Component, Output, OnInit } from '@angular/core';
|
||||
import { Platform, NavParams, ViewController } from 'ionic-angular';
|
||||
import { NavParams, ViewController } from 'ionic-angular';
|
||||
import { Book, Reference } from '../../libs/Reference';
|
||||
|
||||
@Component({
|
||||
@ -15,16 +15,15 @@ export class VersePickerModal
|
||||
book: Book;
|
||||
|
||||
constructor(
|
||||
public platform: Platform,
|
||||
public params: NavParams,
|
||||
public viewCtrl: ViewController
|
||||
private _params: NavParams,
|
||||
private _viewCtrl: ViewController
|
||||
)
|
||||
{
|
||||
this.hasBook = false;
|
||||
this.books = Reference.Books;
|
||||
this.onItemClicked.subscribe(item =>
|
||||
this.onItemClicked.subscribe(item =>
|
||||
{
|
||||
let pg = this.params.get('onItemClicked');
|
||||
let pg = this._params.get('onItemClicked');
|
||||
pg.updateUIwithItems(item, false);
|
||||
});
|
||||
}
|
||||
@ -37,7 +36,7 @@ export class VersePickerModal
|
||||
|
||||
dismiss()
|
||||
{
|
||||
this.viewCtrl.dismiss();
|
||||
this._viewCtrl.dismiss();
|
||||
}
|
||||
setBook(book: Book)
|
||||
{
|
||||
|
@ -12,7 +12,9 @@
|
||||
<ion-card-content *ngIf="data !== undefined && data.status === -1">
|
||||
<error-message [msg]="data.msg"></error-message>
|
||||
</ion-card-content>
|
||||
<button ion-button icon-start clear small (click)="close()">
|
||||
<ion-icon name="close-circle"></ion-icon>
|
||||
<div>Close</div>
|
||||
</button>
|
||||
|
||||
<div style="float: right">
|
||||
<button ion-button icon-center clear (click)="contextMenu()">
|
||||
<ion-icon name="more"></ion-icon>
|
||||
</button>
|
||||
</div>
|
@ -3,6 +3,10 @@ import { HostListener, EventEmitter, Component, Input, Output, AfterViewChecked,
|
||||
import { Reference } from '../../libs/Reference';
|
||||
import { OpenData, CardItem } from '../../pages/search/search';
|
||||
import { WordLookupResult, WordService } from '../../services/word-service';
|
||||
import { cardContextMenu } from '../../libs/Common';
|
||||
import { ProfileService } from '../../services/profile-service';
|
||||
import { ActionSheetController, AlertController } from 'ionic-angular';
|
||||
import { PagesService } from '../../services/pages-service';
|
||||
|
||||
@Component({
|
||||
selector: 'words',
|
||||
@ -24,10 +28,20 @@ export class Words implements AfterViewChecked, OnInit
|
||||
|
||||
data: WordLookupResult;
|
||||
|
||||
constructor(private wordService: WordService, private elementRef: ElementRef)
|
||||
constructor(
|
||||
private _elementRef: ElementRef,
|
||||
private _wordService: WordService,
|
||||
private _profileService: ProfileService,
|
||||
private _actionSheet: ActionSheetController,
|
||||
private _pagesSvc: PagesService,
|
||||
private _alertCtrl: AlertController)
|
||||
{
|
||||
}
|
||||
|
||||
contextMenu() {
|
||||
cardContextMenu(this._profileService, this._actionSheet, this._pagesSvc, this._alertCtrl, this.cardItem);
|
||||
}
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(evt)
|
||||
{
|
||||
@ -75,7 +89,7 @@ export class Words implements AfterViewChecked, OnInit
|
||||
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.wordService.getResultAsPromise(this.cardItem.qry).then(data =>
|
||||
this._wordService.getResultAsPromise(this.cardItem.qry).then(data =>
|
||||
this.data = data
|
||||
);
|
||||
}
|
||||
@ -86,7 +100,7 @@ export class Words implements AfterViewChecked, OnInit
|
||||
translate = 'translate3d(-110%, 0, 0)';
|
||||
}
|
||||
let d = 250;
|
||||
this.elementRef.nativeElement.parentElement.animate({
|
||||
this._elementRef.nativeElement.parentElement.animate({
|
||||
transform: ['none', translate]
|
||||
}, {
|
||||
fill: 'forwards',
|
||||
|
95
DynamicBibleIonic/src/libs/Common.ts
Normal file
95
DynamicBibleIonic/src/libs/Common.ts
Normal file
@ -0,0 +1,95 @@
|
||||
import { ProfileService } from "../services/profile-service";
|
||||
import { ActionSheetController, AlertController } from "ionic-angular";
|
||||
import { PagesService } from "../services/pages-service";
|
||||
import { CardItem } from "../pages/search/search";
|
||||
|
||||
export function cardContextMenu(
|
||||
profileService: ProfileService,
|
||||
actionSheet: ActionSheetController,
|
||||
pagesSvc: PagesService,
|
||||
alertCtrl: AlertController,
|
||||
cardItem: CardItem
|
||||
) {
|
||||
const actions = actionSheet.create({
|
||||
title: "Passage Actions",
|
||||
buttons: [
|
||||
{
|
||||
text: "Add to a Saved Page",
|
||||
icon: "add-circle",
|
||||
handler: () => {
|
||||
let btns = pagesSvc.getSavedPages().map(p => {
|
||||
return {
|
||||
text: p.title,
|
||||
icon: "bookmark",
|
||||
handler: () => {
|
||||
const page = profileService.profile().saved_pages.find(i => i.title === p.title);
|
||||
page.queries.push(cardItem);
|
||||
profileService.save();
|
||||
}
|
||||
};
|
||||
});
|
||||
btns.push({
|
||||
text: "Add to New Page",
|
||||
icon: "create",
|
||||
handler: () => {
|
||||
const alert = alertCtrl.create({
|
||||
title: "Save Passage as Page",
|
||||
inputs: [
|
||||
{
|
||||
name: "title",
|
||||
placeholder: "Page Title"
|
||||
}
|
||||
],
|
||||
buttons: [
|
||||
{
|
||||
text: "Cancel",
|
||||
role: "cancel",
|
||||
handler: (): void => {
|
||||
console.log("Cancel clicked");
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "Save",
|
||||
handler: data => {
|
||||
const p = {
|
||||
queries: profileService.profile().items.slice(),
|
||||
title: data.title
|
||||
};
|
||||
profileService.profile().saved_pages.push(p);
|
||||
profileService.save();
|
||||
pagesSvc.addPage(p);
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
alert.present();
|
||||
}
|
||||
});
|
||||
actionSheet
|
||||
.create({
|
||||
title: "Saved Pages",
|
||||
buttons: btns
|
||||
})
|
||||
.present();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
if (profileService.isOnSearchPage()) {
|
||||
actions.addButton({
|
||||
text: "Remove from " + profileService.title,
|
||||
icon: "remove-circle",
|
||||
handler: () => {
|
||||
const page = profileService.profile().saved_pages.find(i => i.title === profileService.title);
|
||||
const idx = profileService.profile().items.indexOf(cardItem);
|
||||
profileService.profile().items.splice(idx, 1);
|
||||
|
||||
page.queries = profileService.profile().items.slice();
|
||||
profileService.save();
|
||||
pagesSvc.initializePages(profileService.profile().saved_pages);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
actions.present();
|
||||
}
|
6
DynamicBibleIonic/src/libs/Constants.ts
Normal file
6
DynamicBibleIonic/src/libs/Constants.ts
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
export const PageTitles = {
|
||||
Search: 'Search',
|
||||
Help: 'Help',
|
||||
Settings: 'Settings'
|
||||
}
|
@ -1,117 +0,0 @@
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<button ion-button icon-only menuToggle left>
|
||||
<ion-icon name="menu"></ion-icon>
|
||||
</button>
|
||||
<ion-title>Help</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<h2>How to search for a verse</h2>
|
||||
<p>
|
||||
To bring up a passage, just type in a reference, or use the verse picker in the top right corner. Dynamic Bible will recognize most abbreviations of books, and can handle ranges within a book. Here are a few examples to get you started:
|
||||
</p>
|
||||
<h3>Examples of Search Items:</h3>
|
||||
<ul>
|
||||
<li><b>John 1</b> (displays whole chapter)</li>
|
||||
<li><b>John 3:16</b> (displays single verse)</li>
|
||||
<li><b>Jn 3:16</b> (handles abbreviation of John)</li>
|
||||
<li><b>Jn 3:16-17</b> (displays verses starting with chapter 1 verse 3 through chapter 1 vs 5)</li>
|
||||
<li><b>John 3:16-4:4</b></li>
|
||||
<li><b>Jn 3-4</b> (displays both chapters)</li>
|
||||
<li><b>John 3 - John 4</b> (displays both chapters)</li>
|
||||
<li><b>Jn 3:1-*</b> (this will get all the verses in the chapter. the * char can be used in verse ranges, but not chapter ranges.)</li>
|
||||
<li><b>H1234</b> (displays the strongs definition for the Hebrew # 1234)</li>
|
||||
<li><b>G1234</b> (displays the strongs definition for the Greek # 1234)</li>
|
||||
<li><b>Jesus</b> (searches for "Jesus". all search terms assume boolean AND, i.e. "Jesus Christ" assumes "Jesus AND Christ". A word without a number is interpreted as search term).</li>
|
||||
</ul>
|
||||
|
||||
We currently don't support ranges that cross book boundaries. If you search for "John 12 - Romans 3" you will get an error. the second book name is ignored.
|
||||
|
||||
<h3>Further Notes:</h3>
|
||||
<ul>
|
||||
<li>Multiple lookups can be made using a semicolon as a seperator, i.e. "Ruth 1; g1234; spirit").</li>
|
||||
<li>All greek/hebrew cross references translations are taken from the 1933 Websters version and are sometimes not the same as the KJV translation.</li>
|
||||
<li>All source materials were taken from the <a href="http://sourceforge.net/projects/zefania-sharp/">Zefania XML Bible Project</a> on SourceForge.</li>
|
||||
<li>Any Errors and Omission you find would be appreciated. Please contact me via <a href='http://www.jasonwall.org/'>www.jasonwall.org</a>.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Visit Us Online</h3>
|
||||
<p>
|
||||
<a href="http://www.dynamicbible.com">www.dynamicbible.com</a> hosts the online version of the web app. We are currently available on the
|
||||
<a href="https://bitbucket.org/walljm/dynamicbible/downloads/DynamicBible-3.1.0.zip">Windows Platform</a> via the <a href="http://electron.atom.io/">Electron app from atom.io</a>
|
||||
and on the <a href="https://play.google.com/store/apps/details?id=walljm.dynamicbible">Google Android Play store</a>.
|
||||
|
||||
We are working on an IOS distribution and will be releasing that soon.
|
||||
</p>
|
||||
|
||||
<h3>Book Names and Accepted Abbreviations</h3>
|
||||
<ul>
|
||||
<li><b>Genesis</b>: gen, ge, gn</li>
|
||||
<li><b>Exodus</b>: ex, exo, exod, exd</li>
|
||||
<li><b>Leviticus</b>: lev, le, levi, lv</li>
|
||||
<li><b>Numbers</b>: num, nu, numb, number</li>
|
||||
<li><b>Deuteronomy</b>: deut, de, dt, deu</li>
|
||||
<li><b>Joshua</b>: josh, jos</li>
|
||||
<li><b>Judges</b>: jud, jdg, judg</li>
|
||||
<li><b>Ruth</b>: ru</li>
|
||||
<li><b>1 Samuel</b>: 1, i, 1st, first samuel, sa, sam, sml</li>
|
||||
<li><b>2 Samuel</b>: 2, ii, 2nd, second, sec samuel, sa, sam, sml</li>
|
||||
<li><b>1 Kings</b>: 1, i, 1st, first kings, king, kgs, kn, k, ki</li>
|
||||
<li><b>2 Kings</b>: 2, ii, 2nd, second, sec kings, king, kgs, kn, k, ki</li>
|
||||
<li><b>1 Chronicles</b>: 1, i, 1st, first chronicles, chron, ch, chr</li>
|
||||
<li><b>2 Chronicles</b>: 2, ii, 2nd, second, sec chronicles, chron, ch, chr</li>
|
||||
<li><b>Ezra</b>: ezr</li>
|
||||
<li><b>Nehemiah</b>: neh, ne, nehamiah</li>
|
||||
<li><b>Esther</b>: est, es, esth</li>
|
||||
<li><b>Job</b>: jo, jb</li>
|
||||
<li><b>Psalms</b>: ps, psa, psalm, psm</li>
|
||||
<li><b>Proverbs</b>: prov, pr, pro, proverb, prv, prvbs</li>
|
||||
<li><b>Ecclesiastes</b>: eccl, ecc, eccles, ec, ecl, ecclesiaste</li>
|
||||
<li><b>Song of Solomon</b>: , song of songs, sos, ss, son, so, song, songs</li>
|
||||
<li><b>Isaiah</b>: is, isah, isai, ia</li>
|
||||
<li><b>Jerimiah</b>: jeremiah, jer, je, jere</li>
|
||||
<li><b>Lamentations</b>: lam, la, lamentation</li>
|
||||
<li><b>Ezekiel</b>: eze, ezk, ezek</li>
|
||||
<li><b>Daniel</b>: dan, dn, dl, da</li>
|
||||
<li><b>Hosea</b>: hos, ho</li>
|
||||
<li><b>Joel</b>: joe, jl</li>
|
||||
<li><b>Amos</b>: am, amo</li>
|
||||
<li><b>Obadiah</b>: oba, ob, obad</li>
|
||||
<li><b>Jonah</b>: jnh, jon</li>
|
||||
<li><b>Micah</b>: mic, mi</li>
|
||||
<li><b>Nahum</b>: nah, na</li>
|
||||
<li><b>Habakkuk</b>: hab, ha, habakuk</li>
|
||||
<li><b>Zephaniah</b>: zeph, zep</li>
|
||||
<li><b>Haggia</b>: hag, hg, haggai</li>
|
||||
<li><b>Zechariah</b>: zech, zch, zec</li>
|
||||
<li><b>Malachi</b>: mal</li>
|
||||
<li><b>Matthew</b>: mt, matt, mat</li>
|
||||
<li><b>Mark</b>: mrk, mk, mr</li>
|
||||
<li><b>luke</b>: lu, lke, luk, lk</li>
|
||||
<li><b>John</b>: jn, jhn</li>
|
||||
<li><b>Acts</b>: ac, act</li>
|
||||
<li><b>Romans</b>: rom, ro, rm, roman</li>
|
||||
<li><b>1 Corinthians</b>: 1, i, 1st, first corinthian, cor, corinthians, corinth, corin, corth, corint</li>
|
||||
<li><b>2 Corinthians</b>: 2, ii, 2nd, second, sec corinthian, cor, corinthians, corinth, corin, corth, corint</li>
|
||||
<li><b>Galatians</b>: galatian, galations, gal, ga, gala, galation, galat</li>
|
||||
<li><b>Ephesians</b>: eph, ep, ephes, ephe, ephs</li>
|
||||
<li><b>Philippians</b>: phi, phil, ph, philip</li>
|
||||
<li><b>Colossians</b>: col, co, colossian, colos, coloss</li>
|
||||
<li><b>1 Thessalonians</b>: 1, i, 1st, first thessalonians, the, thessa, thessalonian, thes, thess, th</li>
|
||||
<li><b>2 Thessalonians</b>: 2, ii, 2nd, second, sec thessalonians, the, thessa, thessalonian, thes, thess, th</li>
|
||||
<li><b>1 Timothy</b>: 1, i, 1st, first timothy, tim, ti, timoth, tm</li>
|
||||
<li><b>2 Timothy</b>: 2, ii, 2nd, second, sec timothy, tim, timoth, tm</li>
|
||||
<li><b>Titus</b>: tit</li>
|
||||
<li><b>Philemon</b>: phlmn, phl, phm, phile, philem</li>
|
||||
<li><b>Hebrews</b>: heb, he, hebrew</li>
|
||||
<li><b>James</b>: jam, ja, jas, jms, jame, jm</li>
|
||||
<li><b>1 Peter</b>: 1, i, 1st, first peter, pe, pet, pete, pt, p</li>
|
||||
<li><b>2 Peter</b>: 2, ii, 2nd, second, sec peter, pe, pet, pete, pt, p</li>
|
||||
<li><b>1 John</b>: 1, i, 1st, first john, jn, jo</li>
|
||||
<li><b>2 John</b>: 2, ii, 2nd, second, sec john, jn, jo</li>
|
||||
<li><b>3 John</b>: 3, iii, 3rd, third john, jn, jo</li>
|
||||
<li><b>Jude</b>: ju</li>
|
||||
<li><b>Revelation</b>: rev, re, revelations, rv</li>
|
||||
</ul>
|
||||
</ion-content>
|
@ -1,3 +0,0 @@
|
||||
page-settings {
|
||||
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'help',
|
||||
templateUrl: 'help.html'
|
||||
})
|
||||
export class HelpPage
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<ion-menu side="right" [content]="searchcontent" id="actions">
|
||||
<ion-menu side='right' [content]='searchcontent' id='actions'>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Actions</ion-title>
|
||||
@ -11,130 +11,43 @@
|
||||
</ion-list-header>
|
||||
|
||||
<ion-list>
|
||||
<button ion-item menuClose="actions" (click)="addPage()">
|
||||
<ion-icon name="bookmarks" item-left></ion-icon>Save Results as New Page
|
||||
<button ion-item menuClose='actions' (click)='addPage()'>
|
||||
<ion-icon name='bookmarks' item-left></ion-icon>Save Results as New Page
|
||||
</button>
|
||||
<button *ngIf="this.profileService.isOnSearchPage()" ion-item menuClose="actions" (click)="updatePage()">
|
||||
<ion-icon name="arrow-up" item-left></ion-icon>Update Page with Results
|
||||
<button *ngIf='this.profileService.isOnSearchPage()' ion-item menuClose='actions' (click)='updatePage()'>
|
||||
<ion-icon name='arrow-up' item-left></ion-icon>Update Page with Results
|
||||
</button>
|
||||
</ion-list>
|
||||
|
||||
<ion-list-header>
|
||||
<ion-icon name="search" item-left></ion-icon>Search Settings
|
||||
</ion-list-header>
|
||||
<ion-item>
|
||||
<ion-label>Show Strongs as Modal</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="this.profileService.profile().strongs_modal" (ionChange)="this.profileService.localSave()"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Clear Search after Query</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="this.profileService.profile().clear_search_after_query" (ionChange)="this.profileService.localSave()"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Append Results Below</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="this.profileService.profile().append_to_bottom" (ionChange)="this.profileService.localSave()"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Insert Result Next to Item</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="this.profileService.profile().insert_next_to_item" (ionChange)="this.profileService.localSave()"></ion-toggle>
|
||||
</ion-item>
|
||||
|
||||
<ion-list-header>
|
||||
<ion-icon name="browsers" item-left></ion-icon>Display Settings
|
||||
</ion-list-header>
|
||||
<ion-item>
|
||||
<ion-label>Each Verse on New Line</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="this.profileService.profile().verses_on_new_line" (ionChange)="this.profileService.localSave()"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Show Verse #'s</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="this.profileService.profile().show_verse_numbers" (ionChange)="this.profileService.localSave()"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Show Paragraphs</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="profileService.profile().show_paragraphs" (ionChange)="this.profileService.localSave()"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Show Paragraph Headings</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="profileService.profile().show_paragraph_headings" (ionChange)="this.profileService.localSave()"></ion-toggle>
|
||||
</ion-item>
|
||||
|
||||
<ion-list-header>
|
||||
<ion-icon name="sync" item-left></ion-icon>Profile Settings
|
||||
</ion-list-header>
|
||||
<ion-item>
|
||||
<ion-label>Sync Search Items</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="profileService.profile().sync_search_items" (ionChange)="this.profileService.localSave()"></ion-toggle>
|
||||
</ion-item>
|
||||
|
||||
<ion-list-header>
|
||||
<ion-icon name="text" item-left></ion-icon>Adjust Text
|
||||
</ion-list-header>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-range min="6" max="20" step="1" snaps="true" [(ngModel)]="this.profileService.profile().font_size"
|
||||
(ionChange)="textSizeChanged()">
|
||||
<ion-label range-left class="small-text">a</ion-label>
|
||||
<ion-label range-right>A</ion-label>
|
||||
</ion-range>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Font Family</ion-label>
|
||||
<ion-select [(ngModel)]="this.profileService.profile().font_family" (ionChange)="fontFamilyChanged()">
|
||||
<ion-option value="Roboto, Helvetica, Arial, sans-serif">Sans Serif</ion-option>
|
||||
<ion-option value="'Times New Roman', serif">Times</ion-option>
|
||||
<ion-option value="Georgia, serif">Georgia</ion-option>
|
||||
<ion-option value="Merriweather, serif">Merriweather</ion-option>
|
||||
<ion-option value="Consolas, monotype">Monospaced</ion-option>
|
||||
<ion-option value="'PT Serif'ß, serif">PT Serif</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<ion-list-header>
|
||||
<ion-icon name="log-in" item-left></ion-icon>Login/Logout
|
||||
</ion-list-header>
|
||||
|
||||
<ng-template [ngIf]="!profileService.currentUser()">
|
||||
<ion-item center>
|
||||
<button ion-button block (click)="profileService.authenticate()">Login With Google</button>
|
||||
</ion-item>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="profileService.currentUser()">
|
||||
<ion-item center>
|
||||
<button ion-button block (click)="profileService.logout()">Logout</button>
|
||||
</ion-item>
|
||||
</ng-template>
|
||||
<settings></settings>
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<button ion-button icon-only menuToggle left>
|
||||
<ion-icon name="menu" large></ion-icon>
|
||||
<ion-icon name='menu' large></ion-icon>
|
||||
</button>
|
||||
<ion-auto-complete [dataProvider]="autocompleteService" (search)="getQuery($event)" (input)="setQuery($event)"
|
||||
(itemSelected)="itemSelected($event)" [options]="{ showCancelButton : 'true' }" #searchbar></ion-auto-complete>
|
||||
<!--<ion-searchbar (search)="getQuery($event)" (input)="setQuery($event)" [showCancelButton]="true"></ion-searchbar>-->
|
||||
<ion-auto-complete [dataProvider]='autocompleteService' (search)='getQuery($event)' (input)='setQuery($event)'
|
||||
(itemSelected)='itemSelected($event)' [options]='{ showCancelButton : "true" }' #searchbar></ion-auto-complete>
|
||||
<ion-buttons right>
|
||||
<button ion-button icon-only secondary (click)="versePicker()">
|
||||
<ion-icon name="albums" large></ion-icon>
|
||||
<button ion-button icon-only secondary (click)='versePicker()'>
|
||||
<ion-icon name='albums' large></ion-icon>
|
||||
</button>
|
||||
<button ion-button icon-only secondary (click)="actionsMenu()">
|
||||
<ion-icon name="apps" large></ion-icon>
|
||||
<button ion-button icon-only secondary (click)='actionsMenu()'>
|
||||
<ion-icon name='apps' large></ion-icon>
|
||||
</button>
|
||||
</ion-buttons>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content #searchcontent padding class="search-card">
|
||||
<ion-card *ngFor="let item of this.profileService.profile().items">
|
||||
<passage *ngIf="isPassage(item.type)" [cardItem]="item" (onClose)="this.profileService.removeItem($event)"
|
||||
(onItemClicked)="getItemsNextToCard($event)"></passage>
|
||||
<strongs *ngIf="isStrongs(item.type)" [cardItem]="item" (onClose)="this.profileService.removeItem($event)"
|
||||
(onItemClicked)="getItemsNextToCard($event)"></strongs>
|
||||
<words *ngIf="isWords(item.type)" [cardItem]="item" (onClose)="this.profileService.removeItem($event)"
|
||||
(onItemClicked)="getItemsNextToCard($event)"></words>
|
||||
<error *ngIf="isError(item.type)" [cardItem]="item" (onClose)="this.profileService.removeItem($event)"></error>
|
||||
<ion-content #searchcontent padding class='search-card'>
|
||||
<ion-card *ngFor='let item of this.profileService.profile().items'>
|
||||
<passage *ngIf='isPassage(item.type)' [cardItem]='item' (onClose)='this.profileService.removeItem($event)'
|
||||
(onItemClicked)='getItemsNextToCard($event)'></passage>
|
||||
<strongs *ngIf='isStrongs(item.type)' [cardItem]='item' (onClose)='this.profileService.removeItem($event)'
|
||||
(onItemClicked)='getItemsNextToCard($event)'></strongs>
|
||||
<words *ngIf='isWords(item.type)' [cardItem]='item' (onClose)='this.profileService.removeItem($event)'
|
||||
(onItemClicked)='getItemsNextToCard($event)'></words>
|
||||
<error *ngIf='isError(item.type)' [cardItem]='item' (onClose)='this.profileService.removeItem($event)'></error>
|
||||
</ion-card>
|
||||
</ion-content>
|
@ -1,17 +1,18 @@
|
||||
import { Type, Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { Loading, LoadingController, ModalController, NavParams, AlertController, MenuController } from 'ionic-angular';
|
||||
import { Storage } from '@ionic/storage';
|
||||
|
||||
import { StrongsModal } from '../../components/strongs-modal/strongs-modal';
|
||||
import { PagesService } from '../../services/pages-service';
|
||||
|
||||
import { ProfileService, User } from './../../services/profile-service';
|
||||
import { Reference } from '../../libs/Reference';
|
||||
import { VersePickerModal } from '../../components/verse-picker/verse-picker';
|
||||
import { AutoCompleteComponent } from 'ionic2-auto-complete';
|
||||
|
||||
import { StrongsModal } from '../../components/strongs-modal/strongs-modal';
|
||||
import { VersePickerModal } from '../../components/verse-picker/verse-picker';
|
||||
import { Settings } from '../../components/settings/settings';
|
||||
|
||||
import { PagesService } from '../../services/pages-service';
|
||||
import { ProfileService, User } from './../../services/profile-service';
|
||||
import { SearchAutoCompleteService } from '../../services/search-autocomplete-service';
|
||||
|
||||
import { Reference } from '../../libs/Reference';
|
||||
|
||||
|
||||
@Component({
|
||||
templateUrl: 'search.html',
|
||||
providers: [SearchAutoCompleteService]
|
||||
|
@ -1,96 +0,0 @@
|
||||
<ion-header>
|
||||
<ion-navbar>
|
||||
<button ion-button icon-only menuToggle left>
|
||||
<ion-icon name="menu"></ion-icon>
|
||||
</button>
|
||||
<ion-title>Settings</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<ng-template [ngIf]="profileService.profile()">
|
||||
|
||||
<ion-list-header><ion-icon name="search" item-left></ion-icon>Search Settings</ion-list-header>
|
||||
<ion-item>
|
||||
<ion-label>Show Strongs as Modal</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="profileService.profile().strongs_modal" (ionChange)="save()"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Clear Search after Query</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="profileService.profile().clear_search_after_query" (ionChange)="save()"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Append Results Below</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="profileService.profile().append_to_bottom" (ionChange)="save()"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Insert Result Next to Item</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="profileService.profile().insert_next_to_item" (ionChange)="save()"></ion-toggle>
|
||||
</ion-item>
|
||||
|
||||
<ion-list-header><ion-icon name="browsers" item-left></ion-icon>Display Settings</ion-list-header>
|
||||
<ion-item>
|
||||
<ion-label>Each Verse on New Line</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="profileService.profile().verses_on_new_line" (ionChange)="save()"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Show Verse #'s</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="this.profileService.profile().show_verse_numbers" (ionChange)="save()"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Show Paragraphs</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="profileService.profile().show_paragraphs" (ionChange)="save()"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Show Paragraph Headings</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="profileService.profile().show_paragraph_headings" (ionChange)="save()"></ion-toggle>
|
||||
</ion-item>
|
||||
|
||||
<ion-list-header><ion-icon name="sync" item-left></ion-icon>Profile Settings</ion-list-header>
|
||||
<ion-item>
|
||||
<ion-label>Sync Search Items</ion-label>
|
||||
<ion-toggle color="dark" [(ngModel)]="profileService.profile().sync_search_items" (ionChange)="save()"></ion-toggle>
|
||||
</ion-item>
|
||||
|
||||
<ion-list-header><ion-icon name="text" item-left></ion-icon>Adjust Text</ion-list-header>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-range min="6" max="20" step="1" snaps="true" [(ngModel)]="this.profileService.profile().font_size" (ionChange)="textSizeChanged()">
|
||||
<ion-label range-left class="small-text">a</ion-label>
|
||||
<ion-label range-right>A</ion-label>
|
||||
</ion-range>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Font Family</ion-label>
|
||||
<ion-select [(ngModel)]="this.profileService.profile().font_family" (ionChange)="fontFamilyChanged()">
|
||||
<ion-option value="Roboto, Helvetica, Arial, sans-serif">Sans Serif</ion-option>
|
||||
<ion-option value="'Times New Roman', serif">Times</ion-option>
|
||||
<ion-option value="Georgia, serif">Georgia</ion-option>
|
||||
<ion-option value="Merriweather, serif">Merriweather</ion-option>
|
||||
<ion-option value="Consolas, monotype">Monospaced</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<ion-list-header><ion-icon name="log-in" item-left></ion-icon>Login/Logout</ion-list-header>
|
||||
<ng-template [ngIf]="!profileService.currentUser()">
|
||||
<ion-item>
|
||||
<button ion-button block (click)="profileService.authenticate()">Login With Google</button>
|
||||
</ion-item>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="profileService.currentUser()">
|
||||
<ion-item>
|
||||
<button ion-button block (click)="profileService.logout()">Logout</button>
|
||||
</ion-item>
|
||||
</ng-template>
|
||||
|
||||
<h4>Manage Pages</h4>
|
||||
<ion-list>
|
||||
<ion-item *ngFor="let p of profileService.profile().saved_pages">
|
||||
{{p.title}}
|
||||
<button ion-button item-end outline icon-end (click)="removePage(p)">
|
||||
Delete Page <ion-icon name="trash"></ion-icon>
|
||||
</button>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ng-template>
|
||||
</ion-content>
|
@ -1,6 +0,0 @@
|
||||
.list-header {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
.item-md .item-button {
|
||||
height: 40px;
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/// <reference path="../../../typings/globals/jquery/index.d.ts" />
|
||||
import { Component } from '@angular/core';
|
||||
import { NavController, AlertController } from 'ionic-angular';
|
||||
import { Storage } from '@ionic/storage';
|
||||
|
||||
import { ProfileService, SavedPage } from '../../services/profile-service';
|
||||
|
||||
@Component({
|
||||
selector: 'settings',
|
||||
templateUrl: 'settings.html',
|
||||
})
|
||||
export class SettingsPage
|
||||
{
|
||||
constructor(
|
||||
public navCtrl: NavController
|
||||
, private alertCtrl: AlertController
|
||||
, public profileService: ProfileService
|
||||
) {}
|
||||
|
||||
textSizeChanged()
|
||||
{
|
||||
this.profileService.textSizeChanged();
|
||||
this.profileService.localSave();
|
||||
}
|
||||
|
||||
fontFamilyChanged()
|
||||
{
|
||||
this.profileService.fontFamilyChanged();
|
||||
this.profileService.localSave();
|
||||
}
|
||||
reset()
|
||||
{
|
||||
this.profileService.reset()
|
||||
}
|
||||
|
||||
removePage(page: SavedPage)
|
||||
{
|
||||
let alert = this.alertCtrl.create({
|
||||
title: 'Confirm Delete',
|
||||
message: 'Do you want to delete the ' + page.title + ' page?',
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel',
|
||||
handler: () =>
|
||||
{
|
||||
console.log('Cancel clicked');
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Ok',
|
||||
handler: () =>
|
||||
{
|
||||
this.profileService.removePage(page);
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
alert.present();
|
||||
}
|
||||
}
|
@ -1,40 +1,45 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Storage } from '@ionic/storage';
|
||||
import { SearchPage } from '../pages/search/search';
|
||||
import { SettingsPage } from '../pages/settings/settings';
|
||||
import { HelpPage } from '../pages/help/help';
|
||||
|
||||
import { SavedPage } from './profile-service';
|
||||
import { PageTitles } from '../libs/Constants';
|
||||
import { SettingsModal } from '../components/settings-modal/settings-modal';
|
||||
import { AboutModal } from '../components/about-modal/about-modal';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class PagesService
|
||||
{
|
||||
pages: Array<{ title: string, component: any, params: any, icon: string }>;
|
||||
savedPages: Array<{ title: string, component: any, params: any }>;
|
||||
pages: Array<Page>;
|
||||
savedPages: Array<Page>;
|
||||
|
||||
constructor(public local: Storage)
|
||||
{
|
||||
this.pages = [
|
||||
{ title: 'Search', component: SearchPage, params: { queries: [], title: 'Search' }, icon: 'search' },
|
||||
{ title: 'Settings', component: SettingsPage, params: {}, icon: 'settings' },
|
||||
{ title: 'Help', component: HelpPage, params: {}, icon: 'help-circle' }
|
||||
{ title: PageTitles.Search, component: SearchPage, params: { queries: [], title: PageTitles.Search }, icon: 'search' },
|
||||
{ title: PageTitles.Settings, component: SettingsModal, params: {}, icon: 'settings' },
|
||||
{ title: PageTitles.Help, component: AboutModal, params: {}, icon: 'help-circle' }
|
||||
];
|
||||
this.savedPages = [];
|
||||
}
|
||||
|
||||
getMainPages(): Array<{ title: string, component: any }>
|
||||
getMainPages(): Array<Page>
|
||||
{
|
||||
return this.pages;
|
||||
}
|
||||
|
||||
getSavedPages(): Array<{ title: string, component: any }>
|
||||
getSavedPages(): Array<Page>
|
||||
{
|
||||
return this.savedPages;
|
||||
}
|
||||
|
||||
addPage(page: SavedPage)
|
||||
{
|
||||
this.savedPages.push({ title: page.title, component: SearchPage, params: { queries: page.queries, title: page.title } });
|
||||
this.savedPages.push({
|
||||
title: page.title,
|
||||
component: SearchPage,
|
||||
params: { queries: page.queries, title: page.title }
|
||||
});
|
||||
}
|
||||
|
||||
initializePages(page_array: SavedPage[])
|
||||
@ -43,7 +48,19 @@ export class PagesService
|
||||
|
||||
for (let p of page_array)
|
||||
{
|
||||
this.savedPages.push({ title: p.title, component: SearchPage, params: { queries: p.queries, title: p.title } });
|
||||
this.savedPages.push({
|
||||
title: p.title,
|
||||
component: SearchPage,
|
||||
params: { queries: p.queries, title: p.title }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class Page
|
||||
{
|
||||
title: string;
|
||||
component: any;
|
||||
params: any;
|
||||
icon?: string;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/// <reference path="../../typings/globals/jquery/index.d.ts" />
|
||||
/// <reference path='../../typings/globals/jquery/index.d.ts' />
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AngularFireDatabase, AngularFireObject } from 'angularfire2/database';
|
||||
import { AngularFireAuth } from 'angularfire2/auth';
|
||||
@ -16,10 +16,10 @@ import { Output, EventEmitter } from '@angular/core';
|
||||
export const DEFAULT_USER_NAME = 'john_doe';
|
||||
|
||||
@Injectable()
|
||||
export class ProfileService
|
||||
{
|
||||
export class ProfileService {
|
||||
@Output()
|
||||
onSavedPagesChanged = new EventEmitter<SavedPage[]>();
|
||||
|
||||
@Output()
|
||||
onLocalStorageLoaded = new EventEmitter<User>();
|
||||
|
||||
@ -34,32 +34,24 @@ export class ProfileService
|
||||
last: CardItem;
|
||||
title: string;
|
||||
|
||||
constructor(
|
||||
private local: Storage,
|
||||
private db: AngularFireDatabase,
|
||||
public firebaseAuth: AngularFireAuth
|
||||
)
|
||||
{
|
||||
constructor(private local: Storage, private db: AngularFireDatabase, public firebaseAuth: AngularFireAuth) {
|
||||
this.url = document.URL;
|
||||
this.isWeb = (document.URL.startsWith('http') && !document.URL.startsWith('http://localhost:8080'));
|
||||
this.isWeb = document.URL.startsWith('http') && !document.URL.startsWith('http://localhost:8080');
|
||||
this.localIsLoaded = false;
|
||||
|
||||
|
||||
// asyncrounosly kick off a poller that does the work of syncing remotely when the
|
||||
// profile needs to be synced.
|
||||
(function poll(self)
|
||||
{
|
||||
setTimeout(function ()
|
||||
{
|
||||
(function poll(self) {
|
||||
setTimeout(function() {
|
||||
// Setup the next poll recursively
|
||||
if (self.needsSync)
|
||||
{
|
||||
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...');
|
||||
// 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');
|
||||
console.log(' Finished saving remote profile. ' + self.elapsed(st, new Date()) + 'ms');
|
||||
}
|
||||
self.needsSync = false;
|
||||
}
|
||||
@ -68,12 +60,10 @@ export class ProfileService
|
||||
}, 2000);
|
||||
})(this);
|
||||
|
||||
this.local.get('profile').then(json_profile =>
|
||||
{
|
||||
this.local.get('profile').then(json_profile => {
|
||||
let t = this.profile();
|
||||
|
||||
if (json_profile !== null)
|
||||
t = JSON.parse(json_profile);
|
||||
if (json_profile !== null) t = JSON.parse(json_profile);
|
||||
|
||||
this.localProfile = t;
|
||||
this.localIsLoaded = true;
|
||||
@ -81,9 +71,9 @@ export class ProfileService
|
||||
});
|
||||
|
||||
this.firebaseAuth.authState.subscribe(state => this.subscribeToRemoteProfile(this.db, state));
|
||||
|
||||
}
|
||||
|
||||
//#region Profile
|
||||
|
||||
removeItem(item) {
|
||||
const idx = this.profile().items.indexOf(item);
|
||||
@ -98,42 +88,36 @@ export class ProfileService
|
||||
if (this.last != null && this.profile().insert_next_to_item) {
|
||||
const idx = this.profile().items.indexOf(this.last);
|
||||
this.profile().items.splice(idx + 1, 0, item);
|
||||
} else
|
||||
this.profile().items.push(item);
|
||||
}
|
||||
else {
|
||||
} else this.profile().items.push(item);
|
||||
} else {
|
||||
if (this.last != null && this.profile().insert_next_to_item) {
|
||||
const idx = this.profile().items.indexOf(this.last);
|
||||
this.profile().items.splice(idx, 0, item);
|
||||
} else
|
||||
this.profile().items.unshift(item);
|
||||
} else this.profile().items.unshift(item);
|
||||
}
|
||||
this.last = null;
|
||||
}
|
||||
|
||||
isOnSearchPage(){
|
||||
isOnSearchPage() {
|
||||
return this.title !== 'Search';
|
||||
}
|
||||
|
||||
profile(): User
|
||||
{
|
||||
if (!this.localProfile)
|
||||
{
|
||||
|
||||
profile(): User {
|
||||
if (!this.localProfile) {
|
||||
this.localProfile = ProfileService.createDefaultUser();
|
||||
}
|
||||
|
||||
return this.localProfile;
|
||||
}
|
||||
|
||||
subscribeToRemoteProfile(db: AngularFireDatabase, user: firebase.User)
|
||||
{
|
||||
subscribeToRemoteProfile(db: AngularFireDatabase, user: firebase.User) {
|
||||
console.log('subscribeToRemoteProfile');
|
||||
if (!user || this.firebaseUser) return;
|
||||
console.log('You got the firebase user.');
|
||||
let obj = db.object('/settings/' + user.uid);
|
||||
this.remoteProfile = {
|
||||
ref: obj as AngularFireObject<User>,
|
||||
stream: obj.valueChanges() as Observable<User>,
|
||||
stream: obj.valueChanges() as Observable<User>
|
||||
};
|
||||
this.firebaseUser = user;
|
||||
this.profile().username = user.displayName;
|
||||
@ -141,166 +125,132 @@ export class ProfileService
|
||||
|
||||
this.remoteProfile.stream.subscribe(
|
||||
user => this.handleRemotePreferenceChange(user),
|
||||
error => console.log(error));
|
||||
error => console.log(error)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
comparePage(a: SavedPage, b: SavedPage)
|
||||
{
|
||||
if (a.title > b.title)
|
||||
return 1;
|
||||
if (a.title === b.title)
|
||||
return 0;
|
||||
if (a.title < b.title)
|
||||
return -1;
|
||||
|
||||
comparePage(a: SavedPage, b: SavedPage) {
|
||||
if (a.title > b.title) return 1;
|
||||
if (a.title === b.title) return 0;
|
||||
if (a.title < b.title) return -1;
|
||||
}
|
||||
|
||||
handleRemotePreferenceChange(user: User)
|
||||
{
|
||||
handleRemotePreferenceChange(user: User) {
|
||||
console.log('handleRemotePreferenceChange');
|
||||
if (user)
|
||||
{
|
||||
if (user) {
|
||||
let changed = false;
|
||||
if (user.saved_pages !== undefined)
|
||||
{
|
||||
if (user.saved_pages !== undefined) {
|
||||
this.localProfile.saved_pages = user.saved_pages;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (this.profile().sync_search_items)
|
||||
{
|
||||
if (user === undefined || user.items === undefined)
|
||||
{
|
||||
if (this.profile().sync_search_items) {
|
||||
if (user === undefined || user.items === undefined) {
|
||||
this.localProfile.items = [];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this.localProfile.items = user.items;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// don't sync things that don't make sense.
|
||||
if (user.uid !== undefined && this.profile().uid !== user.uid)
|
||||
{
|
||||
if (user.uid !== undefined && this.profile().uid !== user.uid) {
|
||||
this.profile().uid = user.uid;
|
||||
changed = true;
|
||||
}
|
||||
if (user.username !== undefined && this.profile().username !== user.username)
|
||||
{
|
||||
if (user.username !== undefined && this.profile().username !== user.username) {
|
||||
this.profile().username = user.username;
|
||||
changed = true;
|
||||
}
|
||||
// We only save the local change here since this is an update from our remote profile.
|
||||
if (changed)
|
||||
{
|
||||
if (changed) {
|
||||
this.localSave();
|
||||
}
|
||||
this.onSavedPagesChanged.emit(user.saved_pages);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
|
||||
currentUser(): firebase.User
|
||||
{
|
||||
currentUser(): firebase.User {
|
||||
return this.firebaseAuth.auth.currentUser;
|
||||
}
|
||||
|
||||
authenticate()
|
||||
{
|
||||
authenticate() {
|
||||
console.log('Authenticating to remote...');
|
||||
|
||||
let self = this;
|
||||
let provider = new firebase.auth.GoogleAuthProvider();
|
||||
if (this.isWeb)
|
||||
{
|
||||
if (this.isWeb) {
|
||||
this.firebaseAuth.auth.signInWithPopup(provider);
|
||||
}
|
||||
else
|
||||
{
|
||||
firebase.auth().signInWithRedirect(provider).then(function ()
|
||||
{
|
||||
return firebase.auth().getRedirectResult();
|
||||
}).catch(function (error)
|
||||
{
|
||||
// Handle Errors here.
|
||||
console.log(error);
|
||||
});
|
||||
} else {
|
||||
firebase
|
||||
.auth()
|
||||
.signInWithRedirect(provider)
|
||||
.then(function() {
|
||||
return firebase.auth().getRedirectResult();
|
||||
})
|
||||
.catch(function(error) {
|
||||
// Handle Errors here.
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
this.firebaseAuth.authState.subscribe(state => this.subscribeToRemoteProfile(this.db, state));
|
||||
this.remoteLoggedIn = true;
|
||||
|
||||
}
|
||||
|
||||
refresh()
|
||||
{
|
||||
refresh() {
|
||||
console.log('refresh');
|
||||
this.logout();
|
||||
this.authenticate();
|
||||
}
|
||||
|
||||
logout()
|
||||
{
|
||||
logout() {
|
||||
console.log('logout');
|
||||
this.firebaseAuth.auth.signOut(); // sign out
|
||||
this.remoteProfile = null; // inform the profile service not to bother
|
||||
this.remoteLoggedIn = false;
|
||||
}
|
||||
|
||||
save()
|
||||
{
|
||||
save() {
|
||||
this.localSave();
|
||||
this.needsSync = true;
|
||||
}
|
||||
|
||||
localSave()
|
||||
{
|
||||
localSave() {
|
||||
console.log('saving local');
|
||||
this.local.set('profile', JSON.stringify(this.profile()));
|
||||
}
|
||||
|
||||
|
||||
private elapsed(start: Date, finish: Date)
|
||||
{
|
||||
private elapsed(start: Date, finish: Date) {
|
||||
let difference = new Date();
|
||||
difference.setTime(finish.getTime() - start.getTime());
|
||||
return difference.getMilliseconds();
|
||||
}
|
||||
|
||||
// this function updates a user object, in case new properties have been introduced
|
||||
// in a release.
|
||||
update(t: User): boolean
|
||||
{
|
||||
// in a release.
|
||||
update(t: User): boolean {
|
||||
let updated = false;
|
||||
let k;
|
||||
const user = this.profile();
|
||||
for (k in user)
|
||||
{
|
||||
if (user.hasOwnProperty(k))
|
||||
{
|
||||
if (t[k] === undefined)
|
||||
{
|
||||
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];
|
||||
for (k in user) if (user.hasOwnProperty(k)) user[k] = t[k];
|
||||
|
||||
this.textSizeChanged();
|
||||
this.fontFamilyChanged();
|
||||
return updated;
|
||||
}
|
||||
|
||||
private resetUser()
|
||||
{
|
||||
private resetUser() {
|
||||
this.profile().strongs_modal = true;
|
||||
this.profile().clear_search_after_query = false;
|
||||
this.profile().items = [];
|
||||
@ -315,15 +265,13 @@ export class ProfileService
|
||||
this.profile().sync_search_items = false;
|
||||
}
|
||||
|
||||
reset()
|
||||
{
|
||||
reset() {
|
||||
this.resetUser();
|
||||
this.remoteProfile.ref.set(this.profile())
|
||||
this.remoteProfile.ref.set(this.profile());
|
||||
this.save();
|
||||
}
|
||||
|
||||
removePage(page: SavedPage)
|
||||
{
|
||||
removePage(page: SavedPage) {
|
||||
let idx = this.profile().saved_pages.indexOf(page);
|
||||
this.profile().saved_pages.splice(idx, 1);
|
||||
this.onSavedPagesChanged.emit(this.localProfile.saved_pages);
|
||||
@ -333,19 +281,16 @@ export class ProfileService
|
||||
}
|
||||
|
||||
// TODO(jwall): This belongs somewhere else.
|
||||
textSizeChanged()
|
||||
{
|
||||
textSizeChanged() {
|
||||
$('html').css('font-size', this.profile().font_size + 'px');
|
||||
}
|
||||
|
||||
fontFamilyChanged()
|
||||
{
|
||||
document.querySelector('html').style.cssText = '--card-font: '+this.profile().font_family;
|
||||
fontFamilyChanged() {
|
||||
document.querySelector('html').style.cssText = '--card-font: ' + this.profile().font_family;
|
||||
this.textSizeChanged();
|
||||
}
|
||||
|
||||
static createDefaultUser(): User
|
||||
{
|
||||
static createDefaultUser(): User {
|
||||
return {
|
||||
username: DEFAULT_USER_NAME,
|
||||
uid: null,
|
||||
@ -365,34 +310,33 @@ export class ProfileService
|
||||
sync_search_items: false
|
||||
};
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
||||
|
||||
type fbObject<T> = {
|
||||
ref: AngularFireObject<T>,
|
||||
stream: Observable<T>,
|
||||
ref: AngularFireObject<T>;
|
||||
stream: Observable<T>;
|
||||
};
|
||||
|
||||
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,
|
||||
font_family: string,
|
||||
saved_pages: SavedPage[],
|
||||
verses_on_new_line: boolean,
|
||||
show_verse_numbers: boolean,
|
||||
show_paragraphs: boolean,
|
||||
show_paragraph_headings: boolean,
|
||||
sync_search_items: boolean
|
||||
}
|
||||
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;
|
||||
font_family: string;
|
||||
saved_pages: SavedPage[];
|
||||
verses_on_new_line: boolean;
|
||||
show_verse_numbers: boolean;
|
||||
show_paragraphs: boolean;
|
||||
show_paragraph_headings: boolean;
|
||||
sync_search_items: boolean;
|
||||
};
|
||||
|
||||
export type SavedPage = {
|
||||
queries: CardItem[],
|
||||
title: string,
|
||||
}
|
||||
queries: CardItem[];
|
||||
title: string;
|
||||
};
|
||||
|
@ -40,7 +40,7 @@
|
||||
"no-var-keyword": true,
|
||||
"object-literal-sort-keys": false,
|
||||
"quotemark": [
|
||||
true,
|
||||
false,
|
||||
"single"
|
||||
],
|
||||
"semicolon": [
|
||||
|
Loading…
x
Reference in New Issue
Block a user