FEATURE: Create an initial typeahead feature

This commit is contained in:
jason.wall 2018-04-19 11:05:23 -04:00
parent ed3d2da887
commit fa4ac84c57
18 changed files with 269 additions and 1015 deletions

File diff suppressed because one or more lines are too long

View File

@ -1828,7 +1828,6 @@
"requires": {
"anymatch": "1.3.2",
"async-each": "1.0.1",
"fsevents": "1.1.3",
"glob-parent": "2.0.0",
"inherits": "2.0.3",
"is-binary-path": "1.0.1",
@ -4227,795 +4226,6 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fsevents": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz",
"integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==",
"optional": true,
"requires": {
"nan": "2.8.0",
"node-pre-gyp": "0.6.39"
},
"dependencies": {
"abbrev": {
"version": "1.1.0",
"bundled": true,
"optional": true
},
"ajv": {
"version": "4.11.8",
"bundled": true,
"optional": true,
"requires": {
"co": "4.6.0",
"json-stable-stringify": "1.0.1"
}
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true
},
"aproba": {
"version": "1.1.1",
"bundled": true,
"optional": true
},
"are-we-there-yet": {
"version": "1.1.4",
"bundled": true,
"optional": true,
"requires": {
"delegates": "1.0.0",
"readable-stream": "2.2.9"
}
},
"asn1": {
"version": "0.2.3",
"bundled": true,
"optional": true
},
"assert-plus": {
"version": "0.2.0",
"bundled": true,
"optional": true
},
"asynckit": {
"version": "0.4.0",
"bundled": true,
"optional": true
},
"aws-sign2": {
"version": "0.6.0",
"bundled": true,
"optional": true
},
"aws4": {
"version": "1.6.0",
"bundled": true,
"optional": true
},
"balanced-match": {
"version": "0.4.2",
"bundled": true
},
"bcrypt-pbkdf": {
"version": "1.0.1",
"bundled": true,
"optional": true,
"requires": {
"tweetnacl": "0.14.5"
}
},
"block-stream": {
"version": "0.0.9",
"bundled": true,
"requires": {
"inherits": "2.0.3"
}
},
"boom": {
"version": "2.10.1",
"bundled": true,
"requires": {
"hoek": "2.16.3"
}
},
"brace-expansion": {
"version": "1.1.7",
"bundled": true,
"requires": {
"balanced-match": "0.4.2",
"concat-map": "0.0.1"
}
},
"buffer-shims": {
"version": "1.0.0",
"bundled": true
},
"caseless": {
"version": "0.12.0",
"bundled": true,
"optional": true
},
"co": {
"version": "4.6.0",
"bundled": true,
"optional": true
},
"code-point-at": {
"version": "1.1.0",
"bundled": true
},
"combined-stream": {
"version": "1.0.5",
"bundled": true,
"requires": {
"delayed-stream": "1.0.0"
}
},
"concat-map": {
"version": "0.0.1",
"bundled": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true
},
"core-util-is": {
"version": "1.0.2",
"bundled": true
},
"cryptiles": {
"version": "2.0.5",
"bundled": true,
"requires": {
"boom": "2.10.1"
}
},
"dashdash": {
"version": "1.14.1",
"bundled": true,
"optional": true,
"requires": {
"assert-plus": "1.0.0"
},
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"bundled": true,
"optional": true
}
}
},
"debug": {
"version": "2.6.8",
"bundled": true,
"optional": true,
"requires": {
"ms": "2.0.0"
}
},
"deep-extend": {
"version": "0.4.2",
"bundled": true,
"optional": true
},
"delayed-stream": {
"version": "1.0.0",
"bundled": true
},
"delegates": {
"version": "1.0.0",
"bundled": true,
"optional": true
},
"detect-libc": {
"version": "1.0.2",
"bundled": true,
"optional": true
},
"ecc-jsbn": {
"version": "0.1.1",
"bundled": true,
"optional": true,
"requires": {
"jsbn": "0.1.1"
}
},
"extend": {
"version": "3.0.1",
"bundled": true,
"optional": true
},
"extsprintf": {
"version": "1.0.2",
"bundled": true
},
"forever-agent": {
"version": "0.6.1",
"bundled": true,
"optional": true
},
"form-data": {
"version": "2.1.4",
"bundled": true,
"optional": true,
"requires": {
"asynckit": "0.4.0",
"combined-stream": "1.0.5",
"mime-types": "2.1.15"
}
},
"fs.realpath": {
"version": "1.0.0",
"bundled": true
},
"fstream": {
"version": "1.0.11",
"bundled": true,
"requires": {
"graceful-fs": "4.1.11",
"inherits": "2.0.3",
"mkdirp": "0.5.1",
"rimraf": "2.6.1"
}
},
"fstream-ignore": {
"version": "1.0.5",
"bundled": true,
"optional": true,
"requires": {
"fstream": "1.0.11",
"inherits": "2.0.3",
"minimatch": "3.0.4"
}
},
"gauge": {
"version": "2.7.4",
"bundled": true,
"optional": true,
"requires": {
"aproba": "1.1.1",
"console-control-strings": "1.1.0",
"has-unicode": "2.0.1",
"object-assign": "4.1.1",
"signal-exit": "3.0.2",
"string-width": "1.0.2",
"strip-ansi": "3.0.1",
"wide-align": "1.1.2"
}
},
"getpass": {
"version": "0.1.7",
"bundled": true,
"optional": true,
"requires": {
"assert-plus": "1.0.0"
},
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"bundled": true,
"optional": true
}
}
},
"glob": {
"version": "7.1.2",
"bundled": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
},
"graceful-fs": {
"version": "4.1.11",
"bundled": true
},
"har-schema": {
"version": "1.0.5",
"bundled": true,
"optional": true
},
"har-validator": {
"version": "4.2.1",
"bundled": true,
"optional": true,
"requires": {
"ajv": "4.11.8",
"har-schema": "1.0.5"
}
},
"has-unicode": {
"version": "2.0.1",
"bundled": true,
"optional": true
},
"hawk": {
"version": "3.1.3",
"bundled": true,
"requires": {
"boom": "2.10.1",
"cryptiles": "2.0.5",
"hoek": "2.16.3",
"sntp": "1.0.9"
}
},
"hoek": {
"version": "2.16.3",
"bundled": true
},
"http-signature": {
"version": "1.1.1",
"bundled": true,
"optional": true,
"requires": {
"assert-plus": "0.2.0",
"jsprim": "1.4.0",
"sshpk": "1.13.0"
}
},
"inflight": {
"version": "1.0.6",
"bundled": true,
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
}
},
"inherits": {
"version": "2.0.3",
"bundled": true
},
"ini": {
"version": "1.3.4",
"bundled": true,
"optional": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"requires": {
"number-is-nan": "1.0.1"
}
},
"is-typedarray": {
"version": "1.0.0",
"bundled": true,
"optional": true
},
"isarray": {
"version": "1.0.0",
"bundled": true
},
"isstream": {
"version": "0.1.2",
"bundled": true,
"optional": true
},
"jodid25519": {
"version": "1.0.2",
"bundled": true,
"optional": true,
"requires": {
"jsbn": "0.1.1"
}
},
"jsbn": {
"version": "0.1.1",
"bundled": true,
"optional": true
},
"json-schema": {
"version": "0.2.3",
"bundled": true,
"optional": true
},
"json-stable-stringify": {
"version": "1.0.1",
"bundled": true,
"optional": true,
"requires": {
"jsonify": "0.0.0"
}
},
"json-stringify-safe": {
"version": "5.0.1",
"bundled": true,
"optional": true
},
"jsonify": {
"version": "0.0.0",
"bundled": true,
"optional": true
},
"jsprim": {
"version": "1.4.0",
"bundled": true,
"optional": true,
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.0.2",
"json-schema": "0.2.3",
"verror": "1.3.6"
},
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"bundled": true,
"optional": true
}
}
},
"mime-db": {
"version": "1.27.0",
"bundled": true
},
"mime-types": {
"version": "2.1.15",
"bundled": true,
"requires": {
"mime-db": "1.27.0"
}
},
"minimatch": {
"version": "3.0.4",
"bundled": true,
"requires": {
"brace-expansion": "1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true
},
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"requires": {
"minimist": "0.0.8"
}
},
"ms": {
"version": "2.0.0",
"bundled": true,
"optional": true
},
"node-pre-gyp": {
"version": "0.6.39",
"bundled": true,
"optional": true,
"requires": {
"detect-libc": "1.0.2",
"hawk": "3.1.3",
"mkdirp": "0.5.1",
"nopt": "4.0.1",
"npmlog": "4.1.0",
"rc": "1.2.1",
"request": "2.81.0",
"rimraf": "2.6.1",
"semver": "5.3.0",
"tar": "2.2.1",
"tar-pack": "3.4.0"
}
},
"nopt": {
"version": "4.0.1",
"bundled": true,
"optional": true,
"requires": {
"abbrev": "1.1.0",
"osenv": "0.1.4"
}
},
"npmlog": {
"version": "4.1.0",
"bundled": true,
"optional": true,
"requires": {
"are-we-there-yet": "1.1.4",
"console-control-strings": "1.1.0",
"gauge": "2.7.4",
"set-blocking": "2.0.0"
}
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true
},
"oauth-sign": {
"version": "0.8.2",
"bundled": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
"bundled": true,
"optional": true
},
"once": {
"version": "1.4.0",
"bundled": true,
"requires": {
"wrappy": "1.0.2"
}
},
"os-homedir": {
"version": "1.0.2",
"bundled": true,
"optional": true
},
"os-tmpdir": {
"version": "1.0.2",
"bundled": true,
"optional": true
},
"osenv": {
"version": "0.1.4",
"bundled": true,
"optional": true,
"requires": {
"os-homedir": "1.0.2",
"os-tmpdir": "1.0.2"
}
},
"path-is-absolute": {
"version": "1.0.1",
"bundled": true
},
"performance-now": {
"version": "0.2.0",
"bundled": true,
"optional": true
},
"process-nextick-args": {
"version": "1.0.7",
"bundled": true
},
"punycode": {
"version": "1.4.1",
"bundled": true,
"optional": true
},
"qs": {
"version": "6.4.0",
"bundled": true,
"optional": true
},
"rc": {
"version": "1.2.1",
"bundled": true,
"optional": true,
"requires": {
"deep-extend": "0.4.2",
"ini": "1.3.4",
"minimist": "1.2.0",
"strip-json-comments": "2.0.1"
},
"dependencies": {
"minimist": {
"version": "1.2.0",
"bundled": true,
"optional": true
}
}
},
"readable-stream": {
"version": "2.2.9",
"bundled": true,
"requires": {
"buffer-shims": "1.0.0",
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "1.0.7",
"string_decoder": "1.0.1",
"util-deprecate": "1.0.2"
}
},
"request": {
"version": "2.81.0",
"bundled": true,
"optional": true,
"requires": {
"aws-sign2": "0.6.0",
"aws4": "1.6.0",
"caseless": "0.12.0",
"combined-stream": "1.0.5",
"extend": "3.0.1",
"forever-agent": "0.6.1",
"form-data": "2.1.4",
"har-validator": "4.2.1",
"hawk": "3.1.3",
"http-signature": "1.1.1",
"is-typedarray": "1.0.0",
"isstream": "0.1.2",
"json-stringify-safe": "5.0.1",
"mime-types": "2.1.15",
"oauth-sign": "0.8.2",
"performance-now": "0.2.0",
"qs": "6.4.0",
"safe-buffer": "5.0.1",
"stringstream": "0.0.5",
"tough-cookie": "2.3.2",
"tunnel-agent": "0.6.0",
"uuid": "3.0.1"
}
},
"rimraf": {
"version": "2.6.1",
"bundled": true,
"requires": {
"glob": "7.1.2"
}
},
"safe-buffer": {
"version": "5.0.1",
"bundled": true
},
"semver": {
"version": "5.3.0",
"bundled": true,
"optional": true
},
"set-blocking": {
"version": "2.0.0",
"bundled": true,
"optional": true
},
"signal-exit": {
"version": "3.0.2",
"bundled": true,
"optional": true
},
"sntp": {
"version": "1.0.9",
"bundled": true,
"requires": {
"hoek": "2.16.3"
}
},
"sshpk": {
"version": "1.13.0",
"bundled": true,
"optional": true,
"requires": {
"asn1": "0.2.3",
"assert-plus": "1.0.0",
"bcrypt-pbkdf": "1.0.1",
"dashdash": "1.14.1",
"ecc-jsbn": "0.1.1",
"getpass": "0.1.7",
"jodid25519": "1.0.2",
"jsbn": "0.1.1",
"tweetnacl": "0.14.5"
},
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"bundled": true,
"optional": true
}
}
},
"string-width": {
"version": "1.0.2",
"bundled": true,
"requires": {
"code-point-at": "1.1.0",
"is-fullwidth-code-point": "1.0.0",
"strip-ansi": "3.0.1"
}
},
"string_decoder": {
"version": "1.0.1",
"bundled": true,
"requires": {
"safe-buffer": "5.0.1"
}
},
"stringstream": {
"version": "0.0.5",
"bundled": true,
"optional": true
},
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"strip-json-comments": {
"version": "2.0.1",
"bundled": true,
"optional": true
},
"tar": {
"version": "2.2.1",
"bundled": true,
"requires": {
"block-stream": "0.0.9",
"fstream": "1.0.11",
"inherits": "2.0.3"
}
},
"tar-pack": {
"version": "3.4.0",
"bundled": true,
"optional": true,
"requires": {
"debug": "2.6.8",
"fstream": "1.0.11",
"fstream-ignore": "1.0.5",
"once": "1.4.0",
"readable-stream": "2.2.9",
"rimraf": "2.6.1",
"tar": "2.2.1",
"uid-number": "0.0.6"
}
},
"tough-cookie": {
"version": "2.3.2",
"bundled": true,
"optional": true,
"requires": {
"punycode": "1.4.1"
}
},
"tunnel-agent": {
"version": "0.6.0",
"bundled": true,
"optional": true,
"requires": {
"safe-buffer": "5.0.1"
}
},
"tweetnacl": {
"version": "0.14.5",
"bundled": true,
"optional": true
},
"uid-number": {
"version": "0.0.6",
"bundled": true,
"optional": true
},
"util-deprecate": {
"version": "1.0.2",
"bundled": true
},
"uuid": {
"version": "3.0.1",
"bundled": true,
"optional": true
},
"verror": {
"version": "1.3.6",
"bundled": true,
"optional": true,
"requires": {
"extsprintf": "1.0.2"
}
},
"wide-align": {
"version": "1.1.2",
"bundled": true,
"optional": true,
"requires": {
"string-width": "1.0.2"
}
},
"wrappy": {
"version": "1.0.2",
"bundled": true
}
}
},
"fstream": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
@ -5812,6 +5022,13 @@
}
}
},
"string_decoder": {
"version": "1.0.3",
"bundled": true,
"requires": {
"safe-buffer": "5.1.1"
}
},
"string-width": {
"version": "1.0.2",
"bundled": true,
@ -5821,13 +5038,6 @@
"strip-ansi": "3.0.1"
}
},
"string_decoder": {
"version": "1.0.3",
"bundled": true,
"requires": {
"safe-buffer": "5.1.1"
}
},
"stringstream": {
"version": "0.0.5",
"bundled": true
@ -6487,6 +5697,11 @@
"resolved": "https://registry.npmjs.org/ionic-plugin-keyboard/-/ionic-plugin-keyboard-2.2.1.tgz",
"integrity": "sha1-8qnhabvptVIkADR8n9bTRn7j+hI="
},
"ionic2-auto-complete": {
"version": "1.6.2-alpha",
"resolved": "https://registry.npmjs.org/ionic2-auto-complete/-/ionic2-auto-complete-1.6.2-alpha.tgz",
"integrity": "sha1-QHuEgTxRtgUbwBb8ZywLILlF50Q="
},
"ionicons": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-3.0.0.tgz",
@ -10903,6 +10118,14 @@
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
"dev": true
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"requires": {
"safe-buffer": "5.1.1"
}
},
"string-template": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz",
@ -10936,14 +10159,6 @@
}
}
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"requires": {
"safe-buffer": "5.1.1"
}
},
"stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",

View File

@ -48,6 +48,7 @@
"firebase": "^4.8.0",
"ionic-angular": "3.9.0",
"ionic-plugin-keyboard": "^2.2.1",
"ionic2-auto-complete": "^1.6.2-alpha",
"ionicons": "3.0.0",
"promise-polyfill": "^6.0.2",
"rxjs": "5.5.2",
@ -124,4 +125,4 @@
"android"
]
}
}
}

View File

@ -1,6 +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 { HttpModule } from '@angular/http';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
@ -28,6 +29,8 @@ import { AngularFireModule } from 'angularfire2';
import { AngularFireAuthModule } from 'angularfire2/auth';
import { AngularFireDatabaseModule } from 'angularfire2/database';
import { AutoCompleteModule } from 'ionic2-auto-complete';
export const firebaseConfig = {
apiKey: 'AIzaSyA3UV4s56CV2EumgvZmyJBTyU-vhv0xhc8',
authDomain: 'dynamicbible-7c6cf.firebaseapp.com',
@ -57,10 +60,12 @@ export const firebaseConfig = {
IonicModule.forRoot(MyApp),
IonicStorageModule.forRoot(),
BrowserModule,
HttpClientModule,
HttpModule,
AngularFireModule.initializeApp(firebaseConfig),
AngularFireAuthModule,
AngularFireDatabaseModule,
AutoCompleteModule
],
bootstrap: [IonicApp],
entryComponents: [

View File

@ -13,6 +13,7 @@
// To declare rules for a specific mode, create a child rule
// for the .md, .ios, or .wp mode classes. The mode class is
// automatically applied to the <body> element in the app.
@import "../../node_modules/ionic2-auto-complete/auto-complete";
.item {
padding: 0px !important;

View File

@ -1,4 +1,4 @@
<ion-item class="title strongs-title" padding (swipe)="close()">
<ion-item class="title strongs-title {{data.prefix}}" padding (swipe)="close()">
<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>
@ -43,4 +43,4 @@
<button ion-button item-left icon-start clear small (click)="close()">
<ion-icon name="close-circle"></ion-icon>
<div>Close</div>
</button>
</button>

View File

@ -2,10 +2,12 @@
color: #307e4b;
}
.strongs-title {
background-color: #c6efd4;
.heb-title {
background-color:#c6efd4;
}
.grk-title {
background-color:#a7eebe;
}
strongs {
font-family: var(--card-font);

View File

@ -21,38 +21,45 @@ export class Strongs implements AfterViewChecked, OnInit
data: StrongsResult;
constructor(private strongsService: StrongsService, private elementRef: ElementRef)
constructor(private strongsService: StrongsService, private elementRef: ElementRef)
{
}
@HostListener('window:resize', ['$event'])
onResize(evt)
onResize(evt)
{
$('strongs ion-scroll').each((i, el) =>
{
let len = $(el).find('.scroll-content .scroll-zoom-wrapper dl span').length;
len += $(el).find('.scroll-content .scroll-zoom-wrapper dl dd').length;
if (len < 20)
$(el).css('height', Math.ceil(len / 3) * 30 + 30);
});
$('strongs ion-scroll').each((i, el) =>
{
let len = $(el).find('.scroll-content .scroll-zoom-wrapper dl span').length;
len += $(el).find('.scroll-content .scroll-zoom-wrapper dl dd').length;
if (len < 20)
$(el).css('height', Math.ceil(len / 3) * 30 + 30);
});
}
ngAfterViewChecked(): void
{
this.onResize(null);
{
this.onResize(null);
}
ngOnInit(): void
{
this.strongsService.getResultAsPromise(parseInt(this.cardItem.qry), this.cardItem.dict)
.then(data =>
this.data = data
);
ngOnInit(): void
{
this.strongsService.getResultAsPromise(parseInt(this.cardItem.qry), this.cardItem.dict)
.then(data =>
{
this.data = data;
if (data.prefix.startsWith('H'))
document.querySelector('html').style.cssText = '--strongs-color: #87c99d';
if (data.prefix.startsWith('G'))
document.querySelector('html').style.cssText = '--strongs-color: #87c99d';
}
);
}
close()
{
{
const d = 275;
this.elementRef.nativeElement.parentElement.animate({
transform: ['none', 'translate3d(110%, 0, 0)']
@ -62,18 +69,18 @@ export class Strongs implements AfterViewChecked, OnInit
iterations: 1,
easing: 'ease-in-out'
});
setTimeout(() =>
setTimeout(() =>
{
this.onClose.emit(this.cardItem);
}, d);
}
openItem(p: string)
openItem(p: string)
{
this.onItemClicked.emit({ card: this.cardItem, qry: p, from_search_bar: false });
}
makePassage(p: string)
makePassage(p: string)
{
return Reference.bookName(parseInt(p.split(';')[0])).name + ' ' + p.split(';')[1] + ':' + p.split(';')[2];
}

View File

@ -60,10 +60,10 @@
}
}
@media screen and (max-width: 699px) and (min-width: 500px) {
@media screen and (min-width: 500px) {
words {
.passage-button {
width: 46%;
width: 30%;
}
ion-scroll {
@ -72,50 +72,4 @@
}
}
@media screen and (max-width: 799px) and (min-width: 700px) {
words {
.passage-button {
width: 31%;
}
ion-scroll {
height: 275px;
}
}
}
@media screen and (max-width: 899px) and (min-width: 800px) {
words {
.passage-button {
width: 23%;
}
ion-scroll {
height: 275px;
}
}
}
@media screen and (max-width: 1199px) and (min-width: 900px) {
words {
.passage-button {
width: 18%;
}
ion-scroll {
height: 300px;
}
}
}
@media screen and (min-width: 1200px) {
words {
.passage-button {
width: 13.5%;
}
ion-scroll {
height: 300px;
}
}
}

View File

@ -536,7 +536,7 @@ export class Reference
public static Books: Array<Book> = [
{
name: 'Unkown',
name: 'Unknown',
short_name: 'Unk',
long_name: 'Unknown',
book_number: 0,

View File

@ -101,7 +101,8 @@
<button ion-button icon-only menuToggle left>
<ion-icon name="menu" large></ion-icon>
</button>
<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-searchbar (search)="getQuery($event)" (input)="setQuery($event)" [showCancelButton]="true"></ion-searchbar>-->
<ion-buttons right>
<button ion-button icon-only secondary (click)="versePicker()">
<ion-icon name="albums" large></ion-icon>

View File

@ -1,3 +1,25 @@
.toolbar {
contain: inherit;
overflow: inherit;
}
.toolbar-content {
margin-right: .5em;
}
ion-auto-complete ul {
top: 4.2em;
left: 3.5em;
width: fit-content;
width: -webkit-fill-available;
margin-right: 8.5em;
}
ion-auto-complete {
width: 100%;
-webkit-box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
margin-right: .1em;
}
.search-card {
p {
margin: 1em 0;

View File

@ -1,4 +1,4 @@
import { Type, Component, OnInit } from '@angular/core';
import { Type, Component, OnInit, ViewChild } from '@angular/core';
import { Loading, LoadingController, ModalController, NavParams, AlertController, MenuController } from 'ionic-angular';
import { Storage } from '@ionic/storage';
@ -8,17 +8,23 @@ 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 { SearchAutoCompleteService } from '../../services/search-autocomplete-service';
@Component({
templateUrl: 'search.html'
templateUrl: 'search.html',
providers: [SearchAutoCompleteService]
})
export class SearchPage implements OnInit
{
export class SearchPage implements OnInit {
searchQuery = '';
last: CardItem;
loader: Loading;
title: string;
@ViewChild('searchbar')
searchbar: AutoCompleteComponent;
constructor(
private pagesService: PagesService
, private alertCtrl: AlertController
@ -27,54 +33,43 @@ export class SearchPage implements OnInit
, public modalCtrl: ModalController
, public profileService: ProfileService
, public params: NavParams
)
{
, public autocompleteService: SearchAutoCompleteService
) {
}
ngOnInit(): void
{
ngOnInit(): void {
if (this.profileService.localIsLoaded)
{
if (this.profileService.localIsLoaded) {
this.loader = this.loadingCtrl.create({ content: 'Loading Page...' });
this.loader.present().then(() =>
{
this.loader.present().then(() => {
let t = this.profileService.profile();
this.initializeItems(t);
this.loader.dismiss();
});
}
else
{
this.profileService.onLocalStorageLoaded.subscribe(t =>
{
else {
this.profileService.onLocalStorageLoaded.subscribe(t => {
// Check if there is a profile saved in local storage
this.loader = this.loadingCtrl.create({ content: 'Loading Page...' });
this.loader.present().then(() =>
{
this.loader.present().then(() => {
this.initializeItems(t);
this.loader.dismiss();
});
});
this.profileService.onSavedPagesChanged.subscribe(sp =>
{
this.profileService.onSavedPagesChanged.subscribe(sp => {
this.pagesService.initializePages(sp);
});
}
}
initializeItems(u: User)
{
initializeItems(u: User) {
// migrate old way of storing card items to the new.
let has_migrated = false;
for (let i in u.items)
{
if (u.items.hasOwnProperty(i))
{
for (let i in u.items) {
if (u.items.hasOwnProperty(i)) {
let ci = u.items[i];
if (ci['data'] !== undefined)
{
if (ci['data'] !== undefined) {
if (ci['data'].qry !== undefined)
u.items[i] = { qry: ci['data'].qry, dict: ci.dict, type: ci.type };
else if (ci['data'].ref !== undefined)
@ -93,15 +88,11 @@ export class SearchPage implements OnInit
}
}
for (let pg of u.saved_pages)
{
for (let i in pg.queries)
{
if (pg.queries.hasOwnProperty(i))
{
for (let pg of u.saved_pages) {
for (let i in pg.queries) {
if (pg.queries.hasOwnProperty(i)) {
let ci = pg.queries[i];
if (ci['data'] !== undefined)
{
if (ci['data'] !== undefined) {
if (ci['data'].qry !== undefined)
pg.queries[i] = { qry: ci['data'].qry, dict: ci.dict, type: ci.type };
else if (ci['data'].ref !== undefined)
@ -124,7 +115,7 @@ export class SearchPage implements OnInit
// initialize the pages.
this.pagesService.initializePages(u.saved_pages);
this.profileService.save(); // save the new items list
if (this.params.data.queries !== undefined)
this.profileService.profile().items = JSON.parse(JSON.stringify(this.params.data.queries));
@ -136,30 +127,25 @@ export class SearchPage implements OnInit
if (has_migrated)
this.profileService.save();
if (this.profileService.profile().items === undefined)
{
if (this.profileService.profile().items === undefined) {
this.profileService.profile().items = []; // sometimes, maybe because of all the weirdness with the remote syncing, this gets set to undefined, and it needs to be reset.
}
}
textSizeChanged()
{
textSizeChanged() {
this.profileService.textSizeChanged();
this.profileService.localSave();
}
fontFamilyChanged()
{
fontFamilyChanged() {
this.profileService.fontFamilyChanged();
this.profileService.localSave();
}
actionsMenu()
{
actionsMenu() {
this.menu.open('actions');
}
addPage()
{
addPage() {
const alert = this.alertCtrl.create({
title: 'Save Search as Page',
inputs: [
@ -172,15 +158,13 @@ export class SearchPage implements OnInit
{
text: 'Cancel',
role: 'cancel',
handler: (): void =>
{
handler: (): void => {
console.log('Cancel clicked');
}
},
{
text: 'Save',
handler: data =>
{
handler: data => {
const p = { queries: this.profileService.profile().items.slice(), title: data.title };
this.profileService.profile().saved_pages.push(p);
this.profileService.save();
@ -192,8 +176,7 @@ export class SearchPage implements OnInit
alert.present();
}
updatePage()
{
updatePage() {
const page = this.profileService.profile().saved_pages.find(
i =>
i.title === this.params.data.title
@ -202,40 +185,52 @@ export class SearchPage implements OnInit
this.profileService.save();
}
setQuery(searchbar)
{
itemSelected(autocomplete: string) {
let qry = autocomplete;
let idx = qry.lastIndexOf(';');
let prefix = '';
let words = [];
if (idx > -1) {
qry = autocomplete.substr(idx + 1).trim();
prefix = autocomplete.substr(0, idx).trim() + '; ';
}
if (qry.startsWith('Book:')) {
this.searchQuery = prefix + qry.substr(qry.indexOf('Book:')+5).trim();
autocomplete = this.searchQuery;
}
else {
this.searchQuery = autocomplete;
}
}
setQuery(searchbar) {
this.searchQuery = searchbar.target.value;
}
getQuery(searchbar)
{
getQuery(searchbar) {
this.updateUIwithItems(this.searchQuery, true);
}
isError(t: string)
{
isError(t: string) {
return t === 'Error';
}
isPassage(t: string)
{
isPassage(t: string) {
return t === 'Passage';
}
isStrongs(t: string)
{
isStrongs(t: string) {
return t === 'Strongs';
}
isWords(t: string)
{
isWords(t: string) {
return t === 'Words';
}
versePicker()
{
versePicker() {
const modal = this.modalCtrl.create(VersePickerModal, { onItemClicked: this });
modal.present();
}
removeItem(item)
{
removeItem(item) {
const idx = this.profileService.profile().items.indexOf(item);
this.profileService.profile().items.splice(idx, 1);
@ -243,21 +238,16 @@ export class SearchPage implements OnInit
this.profileService.save();
}
addItemToList(item: CardItem)
{
if (this.profileService.profile().append_to_bottom)
{
if (this.last != null && this.profileService.profile().insert_next_to_item)
{
addItemToList(item: CardItem) {
if (this.profileService.profile().append_to_bottom) {
if (this.last != null && this.profileService.profile().insert_next_to_item) {
const idx = this.profileService.profile().items.indexOf(this.last);
this.profileService.profile().items.splice(idx + 1, 0, item);
} else
this.profileService.profile().items.push(item);
}
else
{
if (this.last != null && this.profileService.profile().insert_next_to_item)
{
else {
if (this.last != null && this.profileService.profile().insert_next_to_item) {
const idx = this.profileService.profile().items.indexOf(this.last);
this.profileService.profile().items.splice(idx, 0, item);
} else
@ -265,33 +255,27 @@ export class SearchPage implements OnInit
}
this.last = null;
}
getItemsNextToCard(data: OpenData)
{
getItemsNextToCard(data: OpenData) {
this.last = data.card;
this.updateUIwithItems(data.qry, data.from_search_bar);
}
getItemList(search: string): Promise<CardItem[]>
{
return new Promise((resolve) =>
{
getItemList(search: string): Promise<CardItem[]> {
this.searchbar.hideItemList();
return new Promise((resolve) => {
const list: CardItem[] = [];
try
{
try {
const qs = search.split(';');
for (let x in qs)
{
if (qs.hasOwnProperty(x))
{
for (let x in qs) {
if (qs.hasOwnProperty(x)) {
let q = qs[x].trim();
if (q !== '')
{
if (q !== '') {
// its a search term.
if (q.search(/[0-9]/i) === -1)
list.push({ qry: q, dict: 'na', type: 'Words' });
else if (q.search(/(H|G)[0-9]/i) !== -1)
{
else if (q.search(/(H|G)[0-9]/i) !== -1) {
// its a strongs lookup
let dict = q.substring(0, 1);
@ -303,11 +287,9 @@ export class SearchPage implements OnInit
q = q.substring(1, q.length);
list.push({ qry: q, dict: dict, type: 'Strongs' });
}
else
{
else {
// its a verse reference.
if (q.trim() !== '')
{
if (q.trim() !== '') {
const myref = new Reference(q.trim());
list.push({ qry: myref.toString(), dict: myref.Section.start.book.book_number > 39 ? 'G' : 'H', type: 'Passage' });
}
@ -320,8 +302,7 @@ export class SearchPage implements OnInit
this.profileService.save();
}
catch (error)
{
catch (error) {
list.push({ qry: error, type: 'Error', dict: 'na' });
console.log(error);
}
@ -330,18 +311,13 @@ export class SearchPage implements OnInit
});
}
updateUIwithItems(search: string, from_search_bar: boolean)
{
this.getItemList(search).then(lst =>
{
updateUIwithItems(search: string, from_search_bar: boolean) {
this.getItemList(search).then(lst => {
this.loader = this.loadingCtrl.create({ content: 'Looking up Query...' });
this.loader.present().then(
() =>
{
for (let item of lst)
{
if (item.type === 'Strongs' && this.profileService.profile().strongs_modal && !from_search_bar)
{
() => {
for (let item of lst) {
if (item.type === 'Strongs' && this.profileService.profile().strongs_modal && !from_search_bar) {
const modal = this.modalCtrl.create(StrongsModal, { sn: parseInt(item.qry), dict: item.dict, onItemClicked: this });
modal.present();
} else
@ -358,8 +334,7 @@ export type OpenData = { card: CardItem, qry: string, from_search_bar: boolean }
export type CardItem = { qry: string, type: string, dict: string }
class Item
{
class Item {
id: number;
data: any;
type: Type<any>;

View File

@ -16,4 +16,4 @@ import 'core-js/es6/set';
import 'core-js/es6/reflect';
import 'core-js/es7/reflect';
import 'zone.js/dist/zone';
import 'zone.js/dist/zone';

View File

@ -1,7 +1,6 @@
/// <reference path="../../typings/globals/jquery/index.d.ts" />
/// <reference path="../../typings/globals/mathjs/index.d.ts" />
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Section, Reference } from '../libs/Reference';
@Injectable()
@ -13,7 +12,7 @@ export class BibleService
count = 0;
$: any;
constructor(private http: Http)
constructor()
{
this.getParagraphMarkersAsPromise()
}

View File

@ -0,0 +1,75 @@
import { AutoCompleteService } from 'ionic2-auto-complete';
import { HttpClient} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Reference } from '../libs/Reference';
@Injectable()
export class SearchAutoCompleteService implements AutoCompleteService {
public words: string[] = [];
constructor(private http: HttpClient) {
let self = this;
// getSearchRefs takes a url and uses ajax to retrieve the references and returns an array of references.
this.http.get('data/index/word_to_stem_idx.json', { responseType: 'json' }).subscribe(data => {
// find the right word
for (let i of data as WordToStem[]) {
self.words.push(i.w);
}
});
}
getResults(keyword: string) {
let qry = keyword;
let prefix = '';
let idx = qry.lastIndexOf(';');
let words = [];
if (idx > -1) {
qry = keyword.substr(idx + 1).trim();
prefix = keyword.substr(0, idx).trim() + '; ';
}
if (qry.search(/[0-9]/i) === -1) {
// its a word
for (let item of Reference.Books) {
if (
item.name !== 'Unknown' &&
(item.name.toLowerCase().indexOf(qry.toLowerCase()) > -1 || item.short_name.toLowerCase().indexOf(qry.toLowerCase()) > -1)
) {
words.push(prefix + item.name);
if (words.length > 2) {
break;
}
}
}
for (let item of this.words) {
if (item.toLowerCase().indexOf(qry.toLowerCase()) > -1) {
words.push(prefix + item);
if (words.length > 6) {
return words;
}
}
}
}
else if (qry.search(/(H|G)[0-9]/i) !== -1) {
// its a strongs lookup
if (qry.substr(0, 1).toUpperCase() === 'H') {
let num = parseInt(qry.substr(1));
for (let x = num; x < num + 10 && x < 8675; x++) {
words.push('H' + x)
}
return words;
}
if (qry.substr(0, 1).toUpperCase() === 'G') {
let num = parseInt(qry.substr(1));
for (let x = num; x < num + 10 && x < 5625; x++) {
words.push('G' + x)
}
return words;
}
}
return words;
}
}
type WordToStem = { w: string, s: string }

View File

@ -1,6 +1,5 @@
/// <reference path="../../typings/globals/jquery/index.d.ts" />
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
@Injectable()
export class StrongsService
@ -8,7 +7,7 @@ export class StrongsService
result: StrongsResult;
count = 0;
constructor(private http: Http)
constructor()
{
}
@ -193,4 +192,4 @@ type StrongsCrossReference =
type RMACDefinition = { id: string, d: string[] }
type RMACCrossReference = { i: string, r: string }
type RMACCrossReference = { i: string, r: string }

View File

@ -1,15 +1,13 @@
/// <reference path="../../typings/globals/jquery/index.d.ts" />
import { stemmer } from '../libs/Stemmer';
import { stemmer } from '../libs/Stemmer';
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
@Injectable()
export class WordService
{
wordToStem: Map<string> = {};
wordToStem: Map<string> = {};
constructor(private http: Http)
constructor()
{
this.getStemWordIndex();
}
@ -107,12 +105,12 @@ export class WordService
}
});
// find the right word
// find the right word
for (let i of r)
{
this.wordToStem[i.w] = i.s;
}
}
}
/**
* Gets the references a given word is found in.
@ -331,7 +329,7 @@ export class WordService
words.unshift('zalmonah');
words.unshift('zenan');
words.unshift('ziphim');
words.unshift('zuzim');
words.unshift('zuzim');
return words;
}
@ -436,8 +434,8 @@ export type WordLookupResult = {
type IndexResult = {
r: string[];
w: string;
}
}
type WordToStem = { w:string, s: string}
interface Map<T>
{