mirror of
https://gitlab.com/walljm/dynamicbible.git
synced 2025-07-27 01:19:52 -04:00
MAID: Updated to Ionic2 RC3, fixed errors, implemented strongs
This commit is contained in:
parent
1ff43d7dc0
commit
293c47a71c
30
DynamicBibleIonic/.gitignore
vendored
30
DynamicBibleIonic/.gitignore
vendored
@ -1,10 +1,34 @@
|
|||||||
# Specifies files to intentionally ignore when using Git
|
# Specifies intentionally untracked files to ignore when using Git
|
||||||
# http://git-scm.com/docs/gitignore
|
# http://git-scm.com/docs/gitignore
|
||||||
|
|
||||||
|
*~
|
||||||
|
*.sw[mnpcod]
|
||||||
|
*.log
|
||||||
|
*.tmp
|
||||||
|
*.tmp.*
|
||||||
|
log.txt
|
||||||
|
*.sublime-project
|
||||||
|
*.sublime-workspace
|
||||||
|
.vscode/
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
.sass-cache/
|
||||||
|
.tmp/
|
||||||
|
.versions/
|
||||||
|
coverage/
|
||||||
|
dist/
|
||||||
node_modules/
|
node_modules/
|
||||||
www/build/
|
tmp/
|
||||||
|
temp/
|
||||||
|
hooks/
|
||||||
platforms/
|
platforms/
|
||||||
plugins/
|
plugins/
|
||||||
*.swp
|
plugins/android.json
|
||||||
|
plugins/ios.json
|
||||||
|
www/
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
UserInterfaceState.xcuserstate
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
<ion-menu [content]="content">
|
|
||||||
|
|
||||||
<ion-toolbar>
|
|
||||||
<ion-title>Settings</ion-title>
|
|
||||||
</ion-toolbar>
|
|
||||||
|
|
||||||
<ion-content>
|
|
||||||
|
|
||||||
</ion-content>
|
|
||||||
|
|
||||||
</ion-menu>
|
|
||||||
|
|
||||||
<ion-nav id="nav" [root]="rootPage" #content swipe-back-enabled="false"></ion-nav>
|
|
@ -1,54 +0,0 @@
|
|||||||
import {ComponentFactory, Component, ComponentRef, Input, ViewContainerRef, ComponentResolver, ViewChild} from "@angular/core"
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "dcl-wrapper",
|
|
||||||
template: `<div #target></div>`
|
|
||||||
})
|
|
||||||
export class DclWrapper
|
|
||||||
{
|
|
||||||
@ViewChild("target", { read: ViewContainerRef }) target;
|
|
||||||
@Input() type;
|
|
||||||
@Input() data;
|
|
||||||
cmpRef: ComponentRef<any>;
|
|
||||||
private isViewInitialized: boolean = false;
|
|
||||||
|
|
||||||
constructor(private resolver: ComponentResolver) { }
|
|
||||||
|
|
||||||
updateComponent()
|
|
||||||
{
|
|
||||||
if (!this.isViewInitialized)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.cmpRef)
|
|
||||||
{
|
|
||||||
this.cmpRef.destroy();
|
|
||||||
}
|
|
||||||
this.resolver.resolveComponent(this.type).then((factory: ComponentFactory<any>) =>
|
|
||||||
{
|
|
||||||
this.cmpRef = this.target.createComponent(factory);
|
|
||||||
//to access the created instance use
|
|
||||||
this.cmpRef.instance.item = this.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnChanges()
|
|
||||||
{
|
|
||||||
this.updateComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterViewInit()
|
|
||||||
{
|
|
||||||
this.isViewInitialized = true;
|
|
||||||
this.updateComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy()
|
|
||||||
{
|
|
||||||
if (this.cmpRef)
|
|
||||||
{
|
|
||||||
this.cmpRef.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
<ion-card-title class="title" padding>{{item.ref}}</ion-card-title>
|
|
||||||
<ion-card-content>
|
|
||||||
<div *ngFor="let ch of item.cs">
|
|
||||||
<br>
|
|
||||||
<h2 *ngIf="item.cs.length > 1"><b>Chapter {{ch.ch}}</b></h2>
|
|
||||||
<span *ngFor="let vs of ch.vss"><b>{{vs.v}}.</b> <span *ngFor="let w of vs.w">{{w.t}}</span><br></span>
|
|
||||||
</div>
|
|
||||||
</ion-card-content>
|
|
@ -1,10 +0,0 @@
|
|||||||
import { Component } from "@angular/core";
|
|
||||||
@Component({
|
|
||||||
selector: "passage",
|
|
||||||
templateUrl: "build/components/passage/passage.html"
|
|
||||||
})
|
|
||||||
export class Passage {
|
|
||||||
private item: BiblePassageResult;
|
|
||||||
constructor() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
<ion-card-title class="title" padding>{{item.prefix}}{{item.sn}}</ion-card-title>
|
|
||||||
<ion-card-content>
|
|
||||||
<b>{{item.def.tr}} ({{item.def.sn}})</b> - {{item.def.p}} - {{item.def.lemma}} - <span [innerHTML]="item.def.de"></span><br />
|
|
||||||
</ion-card-content>
|
|
@ -1,13 +0,0 @@
|
|||||||
import { Component } from "@angular/core";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "strongs",
|
|
||||||
templateUrl: "build/components/strongs/strongs.html"
|
|
||||||
})
|
|
||||||
export class Strongs {
|
|
||||||
|
|
||||||
private item: StrongsResult;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
<ion-header>
|
|
||||||
<ion-navbar>
|
|
||||||
<button menuToggle>
|
|
||||||
<ion-icon name="menu"></ion-icon>
|
|
||||||
</button>
|
|
||||||
<ion-searchbar [(ngmodel)]="searchQuery" (search)="getItems($event)" (input)="setQuery($event)"></ion-searchbar>
|
|
||||||
</ion-navbar>
|
|
||||||
</ion-header>
|
|
||||||
<ion-content padding class="search-card">
|
|
||||||
<ion-card *ngFor="let item of items" (swipe)="removeItem(item)">
|
|
||||||
<dcl-wrapper [data]="item.data" [type]="item.type"></dcl-wrapper>
|
|
||||||
<ion-item>
|
|
||||||
<button primary clear item-left (click)="removeItem(item)">
|
|
||||||
<ion-icon name="close-circle"></ion-icon>
|
|
||||||
<div>Close</div>
|
|
||||||
</button>
|
|
||||||
<button primary clear item-left>
|
|
||||||
<ion-icon name="text"></ion-icon>
|
|
||||||
<div>4 Comments</div>
|
|
||||||
</button>
|
|
||||||
</ion-item>
|
|
||||||
</ion-card>
|
|
||||||
</ion-content>
|
|
@ -1,10 +0,0 @@
|
|||||||
// http://ionicframework.com/docs/v2/theming/
|
|
||||||
|
|
||||||
|
|
||||||
// App Shared Imports
|
|
||||||
// --------------------------------------------------
|
|
||||||
// These are the imports which make up the design of this app.
|
|
||||||
// By default each design mode includes these shared imports.
|
|
||||||
// App Shared Sass variables belong in app.variables.scss.
|
|
||||||
|
|
||||||
@import "../pages/search/search";
|
|
@ -1,31 +0,0 @@
|
|||||||
// http://ionicframework.com/docs/v2/theming/
|
|
||||||
|
|
||||||
|
|
||||||
// App Shared Variables
|
|
||||||
// --------------------------------------------------
|
|
||||||
// Shared Sass variables go in the app.variables.scss file
|
|
||||||
@import 'app.variables';
|
|
||||||
|
|
||||||
|
|
||||||
// App iOS Variables
|
|
||||||
// --------------------------------------------------
|
|
||||||
// iOS only Sass variables can go here
|
|
||||||
|
|
||||||
|
|
||||||
// Ionic iOS Sass
|
|
||||||
// --------------------------------------------------
|
|
||||||
// Custom App variables must be declared before importing Ionic.
|
|
||||||
// Ionic will use its default values when a custom variable isn't provided.
|
|
||||||
@import "ionic.ios";
|
|
||||||
|
|
||||||
|
|
||||||
// App Shared Sass
|
|
||||||
// --------------------------------------------------
|
|
||||||
// All Sass files that make up this app goes into the app.core.scss file.
|
|
||||||
// For simpler CSS overrides, custom app CSS must come after Ionic's CSS.
|
|
||||||
@import 'app.core';
|
|
||||||
|
|
||||||
|
|
||||||
// App iOS Only Sass
|
|
||||||
// --------------------------------------------------
|
|
||||||
// CSS that should only apply to the iOS app
|
|
@ -1,31 +0,0 @@
|
|||||||
// http://ionicframework.com/docs/v2/theming/
|
|
||||||
|
|
||||||
|
|
||||||
// App Shared Variables
|
|
||||||
// --------------------------------------------------
|
|
||||||
// Shared Sass variables go in the app.variables.scss file
|
|
||||||
@import 'app.variables';
|
|
||||||
|
|
||||||
|
|
||||||
// App Material Design Variables
|
|
||||||
// --------------------------------------------------
|
|
||||||
// Material Design only Sass variables can go here
|
|
||||||
|
|
||||||
|
|
||||||
// Ionic Material Design Sass
|
|
||||||
// --------------------------------------------------
|
|
||||||
// Custom App variables must be declared before importing Ionic.
|
|
||||||
// Ionic will use its default values when a custom variable isn't provided.
|
|
||||||
@import "ionic.md";
|
|
||||||
|
|
||||||
|
|
||||||
// App Shared Sass
|
|
||||||
// --------------------------------------------------
|
|
||||||
// All Sass files that make up this app goes into the app.core.scss file.
|
|
||||||
// For simpler CSS overrides, custom app CSS must come after Ionic's CSS.
|
|
||||||
@import 'app.core';
|
|
||||||
|
|
||||||
|
|
||||||
// App Material Design Only Sass
|
|
||||||
// --------------------------------------------------
|
|
||||||
// CSS that should only apply to the Material Design app
|
|
@ -1,35 +0,0 @@
|
|||||||
// http://ionicframework.com/docs/v2/theming/
|
|
||||||
|
|
||||||
// Ionic Shared Functions
|
|
||||||
// --------------------------------------------------
|
|
||||||
// Makes Ionic Sass functions available to your App
|
|
||||||
|
|
||||||
@import 'globals.core';
|
|
||||||
|
|
||||||
// App Shared Variables
|
|
||||||
// --------------------------------------------------
|
|
||||||
// To customize the look and feel of this app, you can override
|
|
||||||
// the Sass variables found in Ionic's source scss files. Setting
|
|
||||||
// variables before Ionic's Sass will use these variables rather than
|
|
||||||
// Ionic's default Sass variable values. App Shared Sass imports belong
|
|
||||||
// in the app.core.scss file and not this file. Sass variables specific
|
|
||||||
// to the mode belong in either the app.ios.scss or app.md.scss files.
|
|
||||||
|
|
||||||
|
|
||||||
// App Shared Color Variables
|
|
||||||
// --------------------------------------------------
|
|
||||||
// It's highly recommended to change the default colors
|
|
||||||
// to match your app's branding. Ionic uses a Sass map of
|
|
||||||
// colors so you can add, rename and remove colors as needed.
|
|
||||||
// The "primary" color is the only required color in the map.
|
|
||||||
// Both iOS and MD colors can be further customized if colors
|
|
||||||
// are different per mode.
|
|
||||||
|
|
||||||
$colors: (
|
|
||||||
primary: #387ef5,
|
|
||||||
secondary: #32db64,
|
|
||||||
danger: #f53d3d,
|
|
||||||
light: #f4f4f4,
|
|
||||||
dark: #222,
|
|
||||||
favorite: #69BB7B
|
|
||||||
);
|
|
@ -1,31 +0,0 @@
|
|||||||
// http://ionicframework.com/docs/v2/theming/
|
|
||||||
|
|
||||||
|
|
||||||
// App Shared Variables
|
|
||||||
// --------------------------------------------------
|
|
||||||
// Shared Sass variables go in the app.variables.scss file
|
|
||||||
@import 'app.variables';
|
|
||||||
|
|
||||||
|
|
||||||
// App Windows Variables
|
|
||||||
// --------------------------------------------------
|
|
||||||
// Windows only Sass variables can go here
|
|
||||||
|
|
||||||
|
|
||||||
// Ionic Windows Sass
|
|
||||||
// --------------------------------------------------
|
|
||||||
// Custom App variables must be declared before importing Ionic.
|
|
||||||
// Ionic will use its default values when a custom variable isn't provided.
|
|
||||||
@import "ionic.wp";
|
|
||||||
|
|
||||||
|
|
||||||
// App Shared Sass
|
|
||||||
// --------------------------------------------------
|
|
||||||
// All Sass files that make up this app goes into the app.core.scss file.
|
|
||||||
// For simpler CSS overrides, custom app CSS must come after Ionic's CSS.
|
|
||||||
@import 'app.core';
|
|
||||||
|
|
||||||
|
|
||||||
// App Windows Only Sass
|
|
||||||
// --------------------------------------------------
|
|
||||||
// CSS that should only apply to the Windows app
|
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<widget id="com.ionicframework.test117969" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
<widget id="com.ionicframework.db572483" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
||||||
<name>test</name>
|
<name>db</name>
|
||||||
<description>An Ionic Framework and Cordova project.</description>
|
<description>An awesome Ionic/Cordova app.</description>
|
||||||
<author email="hi@ionicframework" href="http://ionicframework.com/">Ionic Framework Team</author>
|
<author email="hi@ionicframework" href="http://ionicframework.com/">Ionic Framework Team</author>
|
||||||
<content src="index.html"/>
|
<content src="index.html"/>
|
||||||
<access origin="*"/>
|
<access origin="*"/>
|
||||||
@ -23,15 +23,9 @@
|
|||||||
<preference name="DisallowOverscroll" value="true"/>
|
<preference name="DisallowOverscroll" value="true"/>
|
||||||
<preference name="android-minSdkVersion" value="16"/>
|
<preference name="android-minSdkVersion" value="16"/>
|
||||||
<preference name="BackupWebStorage" value="none"/>
|
<preference name="BackupWebStorage" value="none"/>
|
||||||
<preference name="SplashScreenDelay" value="2000"/>
|
<preference name="SplashMaintainAspectRatio" value="true"/>
|
||||||
<preference name="FadeSplashScreenDuration" value="2000"/>
|
<preference name="FadeSplashScreenDuration" value="300"/>
|
||||||
<feature name="StatusBar">
|
<feature name="StatusBar">
|
||||||
<param name="ios-package" onload="true" value="CDVStatusBar"/>
|
<param name="ios-package" onload="true" value="CDVStatusBar"/>
|
||||||
</feature>
|
</feature>
|
||||||
<plugin name="cordova-plugin-device" spec="~1.1.2"/>
|
|
||||||
<plugin name="cordova-plugin-console" spec="~1.0.3"/>
|
|
||||||
<plugin name="cordova-plugin-whitelist" spec="~1.2.2"/>
|
|
||||||
<plugin name="cordova-plugin-splashscreen" spec="~3.2.2"/>
|
|
||||||
<plugin name="cordova-plugin-statusbar" spec="~2.1.3"/>
|
|
||||||
<plugin name="ionic-plugin-keyboard" spec="~2.2.1"/>
|
|
||||||
</widget>
|
</widget>
|
@ -1,74 +0,0 @@
|
|||||||
var gulp = require('gulp'),
|
|
||||||
gulpWatch = require('gulp-watch'),
|
|
||||||
del = require('del'),
|
|
||||||
runSequence = require('run-sequence'),
|
|
||||||
argv = process.argv;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ionic hooks
|
|
||||||
* Add ':before' or ':after' to any Ionic project command name to run the specified
|
|
||||||
* tasks before or after the command.
|
|
||||||
*/
|
|
||||||
gulp.task('serve:before', ['watch']);
|
|
||||||
gulp.task('emulate:before', ['build']);
|
|
||||||
gulp.task('deploy:before', ['build']);
|
|
||||||
gulp.task('build:before', ['build']);
|
|
||||||
|
|
||||||
// we want to 'watch' when livereloading
|
|
||||||
var shouldWatch = argv.indexOf('-l') > -1 || argv.indexOf('--livereload') > -1;
|
|
||||||
gulp.task('run:before', [shouldWatch ? 'watch' : 'build']);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ionic Gulp tasks, for more information on each see
|
|
||||||
* https://github.com/driftyco/ionic-gulp-tasks
|
|
||||||
*
|
|
||||||
* Using these will allow you to stay up to date if the default Ionic 2 build
|
|
||||||
* changes, but you are of course welcome (and encouraged) to customize your
|
|
||||||
* build however you see fit.
|
|
||||||
*/
|
|
||||||
var buildBrowserify = require('ionic-gulp-browserify-typescript');
|
|
||||||
var buildSass = require('ionic-gulp-sass-build');
|
|
||||||
var copyHTML = require('ionic-gulp-html-copy');
|
|
||||||
var copyFonts = require('ionic-gulp-fonts-copy');
|
|
||||||
var copyScripts = require('ionic-gulp-scripts-copy');
|
|
||||||
var tslint = require('ionic-gulp-tslint');
|
|
||||||
|
|
||||||
var isRelease = argv.indexOf('--release') > -1;
|
|
||||||
|
|
||||||
gulp.task('watch', ['clean'], function(done){
|
|
||||||
runSequence(
|
|
||||||
['sass', 'html', 'fonts', 'scripts'],
|
|
||||||
function(){
|
|
||||||
gulpWatch('app/**/*.scss', function(){ gulp.start('sass'); });
|
|
||||||
gulpWatch('app/**/*.html', function(){ gulp.start('html'); });
|
|
||||||
buildBrowserify({ watch: true }).on('end', done);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('build', ['clean'], function(done){
|
|
||||||
runSequence(
|
|
||||||
['sass', 'html', 'fonts', 'scripts'],
|
|
||||||
function(){
|
|
||||||
buildBrowserify({
|
|
||||||
minify: isRelease,
|
|
||||||
browserifyOptions: {
|
|
||||||
debug: !isRelease
|
|
||||||
},
|
|
||||||
uglifyOptions: {
|
|
||||||
mangle: false
|
|
||||||
}
|
|
||||||
}).on('end', done);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('sass', buildSass);
|
|
||||||
gulp.task('html', copyHTML);
|
|
||||||
gulp.task('fonts', copyFonts);
|
|
||||||
gulp.task('scripts', copyScripts);
|
|
||||||
gulp.task('clean', function(){
|
|
||||||
return del('www/build');
|
|
||||||
});
|
|
||||||
gulp.task('lint', tslint);
|
|
@ -1,94 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
// Add Platform Class
|
|
||||||
// v1.0
|
|
||||||
// Automatically adds the platform class to the body tag
|
|
||||||
// after the `prepare` command. By placing the platform CSS classes
|
|
||||||
// directly in the HTML built for the platform, it speeds up
|
|
||||||
// rendering the correct layout/style for the specific platform
|
|
||||||
// instead of waiting for the JS to figure out the correct classes.
|
|
||||||
|
|
||||||
var fs = require('fs');
|
|
||||||
var path = require('path');
|
|
||||||
|
|
||||||
var rootdir = process.argv[2];
|
|
||||||
|
|
||||||
function addPlatformBodyTag(indexPath, platform) {
|
|
||||||
// add the platform class to the body tag
|
|
||||||
try {
|
|
||||||
var platformClass = 'platform-' + platform;
|
|
||||||
var cordovaClass = 'platform-cordova platform-webview';
|
|
||||||
|
|
||||||
var html = fs.readFileSync(indexPath, 'utf8');
|
|
||||||
|
|
||||||
var bodyTag = findBodyTag(html);
|
|
||||||
if(!bodyTag) return; // no opening body tag, something's wrong
|
|
||||||
|
|
||||||
if(bodyTag.indexOf(platformClass) > -1) return; // already added
|
|
||||||
|
|
||||||
var newBodyTag = bodyTag;
|
|
||||||
|
|
||||||
var classAttr = findClassAttr(bodyTag);
|
|
||||||
if(classAttr) {
|
|
||||||
// body tag has existing class attribute, add the classname
|
|
||||||
var endingQuote = classAttr.substring(classAttr.length-1);
|
|
||||||
var newClassAttr = classAttr.substring(0, classAttr.length-1);
|
|
||||||
newClassAttr += ' ' + platformClass + ' ' + cordovaClass + endingQuote;
|
|
||||||
newBodyTag = bodyTag.replace(classAttr, newClassAttr);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// add class attribute to the body tag
|
|
||||||
newBodyTag = bodyTag.replace('>', ' class="' + platformClass + ' ' + cordovaClass + '">');
|
|
||||||
}
|
|
||||||
|
|
||||||
html = html.replace(bodyTag, newBodyTag);
|
|
||||||
|
|
||||||
fs.writeFileSync(indexPath, html, 'utf8');
|
|
||||||
|
|
||||||
process.stdout.write('add to body class: ' + platformClass + '\n');
|
|
||||||
} catch(e) {
|
|
||||||
process.stdout.write(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function findBodyTag(html) {
|
|
||||||
// get the body tag
|
|
||||||
try{
|
|
||||||
return html.match(/<body(?=[\s>])(.*?)>/gi)[0];
|
|
||||||
}catch(e){}
|
|
||||||
}
|
|
||||||
|
|
||||||
function findClassAttr(bodyTag) {
|
|
||||||
// get the body tag's class attribute
|
|
||||||
try{
|
|
||||||
return bodyTag.match(/ class=["|'](.*?)["|']/gi)[0];
|
|
||||||
}catch(e){}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rootdir) {
|
|
||||||
|
|
||||||
// go through each of the platform directories that have been prepared
|
|
||||||
var platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []);
|
|
||||||
|
|
||||||
for(var x=0; x<platforms.length; x++) {
|
|
||||||
// open up the index.html file at the www root
|
|
||||||
try {
|
|
||||||
var platform = platforms[x].trim().toLowerCase();
|
|
||||||
var indexPath;
|
|
||||||
|
|
||||||
if(platform == 'android') {
|
|
||||||
indexPath = path.join('platforms', platform, 'assets', 'www', 'index.html');
|
|
||||||
} else {
|
|
||||||
indexPath = path.join('platforms', platform, 'www', 'index.html');
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fs.existsSync(indexPath)) {
|
|
||||||
addPlatformBodyTag(indexPath, platform);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch(e) {
|
|
||||||
process.stdout.write(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,9 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "test",
|
"name": "db",
|
||||||
"app_id": "",
|
"app_id": "",
|
||||||
"v2": true,
|
"v2": true,
|
||||||
"watchPatterns": [
|
"typescript": true
|
||||||
"www/**",
|
|
||||||
"!www/data/**"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@ -1,42 +1,42 @@
|
|||||||
{
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"name": "dynamicbible",
|
||||||
|
"author": "Jason Wall",
|
||||||
|
"homepage": "http://dynamicbible.com/",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"ionic:build": "ionic-app-scripts build",
|
||||||
|
"ionic:serve": "ionic-app-scripts serve"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/common": "2.0.0-rc.4",
|
"@angular/common": "2.1.1",
|
||||||
"@angular/compiler": "2.0.0-rc.4",
|
"@angular/compiler": "2.1.1",
|
||||||
"@angular/core": "2.0.0-rc.4",
|
"@angular/compiler-cli": "2.1.1",
|
||||||
"@angular/platform-browser": "2.0.0-rc.4",
|
"@angular/core": "2.1.1",
|
||||||
"@angular/platform-browser-dynamic": "2.0.0-rc.4",
|
"@angular/forms": "2.1.1",
|
||||||
"@angular/http": "2.0.0-rc.4",
|
"@angular/http": "2.1.1",
|
||||||
"@angular/forms": "0.2.0",
|
"@angular/platform-browser": "2.1.1",
|
||||||
"es6-shim": "0.35.1",
|
"@angular/platform-browser-dynamic": "2.1.1",
|
||||||
"ionic-angular": "2.0.0-beta.11",
|
"@angular/platform-server": "2.1.1",
|
||||||
"ionic-native": "1.3.10",
|
"@ionic/storage": "1.1.6",
|
||||||
|
"ionic-angular": "2.0.0-rc.3",
|
||||||
|
"ionic-native": "2.2.3",
|
||||||
"ionicons": "3.0.0",
|
"ionicons": "3.0.0",
|
||||||
"reflect-metadata": "0.1.8",
|
"rxjs": "5.0.0-beta.12",
|
||||||
"rxjs": "5.0.0-beta.6",
|
"zone.js": "0.6.26"
|
||||||
"zone.js": "0.6.12"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"del": "2.2.0",
|
"@ionic/app-scripts": "0.0.45",
|
||||||
"gulp": "3.9.1",
|
"typescript": "2.0.6"
|
||||||
"gulp-watch": "4.3.5",
|
|
||||||
"ionic-gulp-browserify-typescript": "2.0.0",
|
|
||||||
"ionic-gulp-fonts-copy": "^1.0.0",
|
|
||||||
"ionic-gulp-html-copy": "^1.0.0",
|
|
||||||
"ionic-gulp-sass-build": "^1.0.0",
|
|
||||||
"ionic-gulp-scripts-copy": "^2.0.0",
|
|
||||||
"ionic-gulp-tslint": "^1.0.0",
|
|
||||||
"tslint-ionic-rules": "0.0.4",
|
|
||||||
"run-sequence": "1.1.5"
|
|
||||||
},
|
},
|
||||||
"name": "test",
|
|
||||||
"description": "test: An Ionic project",
|
|
||||||
"cordovaPlugins": [
|
"cordovaPlugins": [
|
||||||
"cordova-plugin-device",
|
|
||||||
"cordova-plugin-console",
|
|
||||||
"cordova-plugin-whitelist",
|
"cordova-plugin-whitelist",
|
||||||
"cordova-plugin-splashscreen",
|
"cordova-plugin-console",
|
||||||
"cordova-plugin-statusbar",
|
"cordova-plugin-statusbar",
|
||||||
"ionic-plugin-keyboard"
|
"cordova-plugin-device",
|
||||||
|
"ionic-plugin-keyboard",
|
||||||
|
"cordova-plugin-splashscreen"
|
||||||
],
|
],
|
||||||
"cordovaPlatforms": []
|
"cordovaPlatforms": [],
|
||||||
|
"description": "Dynamic Bible: A bible made for studying scripture"
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import {Component, ViewChild} from "@angular/core";
|
import { Component, ViewChild } from '@angular/core';
|
||||||
import {ionicBootstrap, Platform, MenuController, Nav} from "ionic-angular";
|
|
||||||
import {StatusBar} from "ionic-native";
|
|
||||||
import {SearchPage} from "./pages/search/search";
|
|
||||||
|
|
||||||
|
import { Platform, MenuController, Nav } from 'ionic-angular';
|
||||||
|
|
||||||
|
import { StatusBar, Splashscreen } from 'ionic-native';
|
||||||
|
|
||||||
|
import {SearchPage} from "../pages/search/search";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "build/app.html"
|
templateUrl: 'app.html'
|
||||||
})
|
})
|
||||||
class MyApp
|
export class MyApp {
|
||||||
{
|
|
||||||
@ViewChild(Nav) nav: Nav;
|
@ViewChild(Nav) nav: Nav;
|
||||||
|
|
||||||
// make HelloIonicPage the root (or first) page
|
// make HelloIonicPage the root (or first) page
|
||||||
@ -18,31 +19,28 @@ class MyApp
|
|||||||
constructor(
|
constructor(
|
||||||
public platform: Platform,
|
public platform: Platform,
|
||||||
public menu: MenuController
|
public menu: MenuController
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
this.initializeApp();
|
this.initializeApp();
|
||||||
|
|
||||||
// set our app's pages
|
// set our app's pages
|
||||||
this.pages = [];
|
this.pages = [
|
||||||
|
{ title: 'Dynamic Bible', component: SearchPage }
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeApp()
|
initializeApp() {
|
||||||
{
|
this.platform.ready().then(() => {
|
||||||
this.platform.ready().then(() =>
|
|
||||||
{
|
|
||||||
// Okay, so the platform is ready and our plugins are available.
|
// Okay, so the platform is ready and our plugins are available.
|
||||||
// Here you can do any higher level native things you might need.
|
// Here you can do any higher level native things you might need.
|
||||||
StatusBar.styleDefault();
|
StatusBar.styleDefault();
|
||||||
|
Splashscreen.hide();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openPage(page)
|
openPage(page) {
|
||||||
{
|
|
||||||
// close the menu when clicking a link from the menu
|
// close the menu when clicking a link from the menu
|
||||||
this.menu.close();
|
this.menu.close();
|
||||||
// navigate to the new page if it is not the current page
|
// navigate to the new page if it is not the current page
|
||||||
this.nav.setRoot(page.component);
|
this.nav.setRoot(page.component);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ionicBootstrap(MyApp);
|
|
19
DynamicBibleIonic/src/app/app.html
Normal file
19
DynamicBibleIonic/src/app/app.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<ion-menu [content]="content">
|
||||||
|
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Pages</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content>
|
||||||
|
<ion-list>
|
||||||
|
<button ion-item *ngFor="let p of pages" (click)="openPage(p)">
|
||||||
|
{{p.title}}
|
||||||
|
</button>
|
||||||
|
</ion-list>
|
||||||
|
</ion-content>
|
||||||
|
|
||||||
|
</ion-menu>
|
||||||
|
|
||||||
|
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
|
32
DynamicBibleIonic/src/app/app.module.ts
Normal file
32
DynamicBibleIonic/src/app/app.module.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { NgModule, ErrorHandler } from '@angular/core';
|
||||||
|
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
|
||||||
|
import { MyApp } from './app.component';
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
import {SearchPage} from "../pages/search/search";
|
||||||
|
import {ComponentLoader} from "../components/component-loader/component-loader.ts";
|
||||||
|
import {Passage} from "../components/passage/passage.ts";
|
||||||
|
import {Strongs} from "../components/strongs/strongs.ts";
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
MyApp,
|
||||||
|
SearchPage,
|
||||||
|
ComponentLoader,
|
||||||
|
Passage,
|
||||||
|
Strongs,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
IonicModule.forRoot(MyApp),
|
||||||
|
BrowserModule,
|
||||||
|
],
|
||||||
|
bootstrap: [IonicApp],
|
||||||
|
entryComponents: [
|
||||||
|
MyApp,
|
||||||
|
SearchPage,
|
||||||
|
Passage,
|
||||||
|
Strongs,
|
||||||
|
],
|
||||||
|
providers: [{ provide: ErrorHandler, useClass: IonicErrorHandler }]
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
16
DynamicBibleIonic/src/app/app.scss
Normal file
16
DynamicBibleIonic/src/app/app.scss
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// http://ionicframework.com/docs/v2/theming/
|
||||||
|
|
||||||
|
|
||||||
|
// App Global Sass
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Put style rules here that you want to apply globally. These
|
||||||
|
// styles are for the entire app and not just one component.
|
||||||
|
// Additionally, this file can be also used as an entry point
|
||||||
|
// to import other Sass files to be included in the output CSS.
|
||||||
|
//
|
||||||
|
// Shared Sass variables, which can be used to adjust Ionic's
|
||||||
|
// default Sass variables, belong in "theme/variables.scss".
|
||||||
|
//
|
||||||
|
// 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.
|
5
DynamicBibleIonic/src/app/main.dev.ts
Normal file
5
DynamicBibleIonic/src/app/main.dev.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
|
import { AppModule } from './app.module';
|
||||||
|
|
||||||
|
platformBrowserDynamic().bootstrapModule(AppModule);
|
5
DynamicBibleIonic/src/app/main.prod.ts
Normal file
5
DynamicBibleIonic/src/app/main.prod.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
|
import { AppModule } from './app.module';
|
||||||
|
|
||||||
|
platformBrowserDynamic().bootstrapModule(AppModule);
|
BIN
DynamicBibleIonic/src/assets/icon/favicon.ico
Normal file
BIN
DynamicBibleIonic/src/assets/icon/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
@ -1,8 +1,7 @@
|
|||||||
/// <reference path="../typings/browser/ambient/jquery/index.d.ts" />
|
/// <reference path="../typings/browser/ambient/jquery/index.d.ts" />
|
||||||
/// <reference path="types.ts" />
|
/// <reference path="types.ts" />
|
||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
import { Observable } from "rxjs/Observable";
|
import { Http } from "@angular/http";
|
||||||
import { Http, Response } from "@angular/http";
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class BibleService
|
export class BibleService
|
||||||
@ -92,6 +91,7 @@ export class BibleService
|
|||||||
if (section.start.book >= 40)
|
if (section.start.book >= 40)
|
||||||
{
|
{
|
||||||
this.result.testament = "new";
|
this.result.testament = "new";
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
this.result.testament = "old";
|
this.result.testament = "old";
|
@ -0,0 +1,52 @@
|
|||||||
|
//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: boolean = false;
|
||||||
|
|
||||||
|
constructor(private componentFactoryResolver: ComponentFactoryResolver, private compiler: Compiler,
|
||||||
|
private cdRef: ChangeDetectorRef) { }
|
||||||
|
|
||||||
|
updateComponent() {
|
||||||
|
if (!this.isViewInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.cmpRef) {
|
||||||
|
this.cmpRef.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
let 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
DynamicBibleIonic/src/components/passage/passage.html
Normal file
13
DynamicBibleIonic/src/components/passage/passage.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<ion-item class="title" padding>
|
||||||
|
{{item.ref}}
|
||||||
|
<button ion-button icon-only item-right large clear (click)="close()">
|
||||||
|
<ion-icon name="close-circle"></ion-icon>
|
||||||
|
</button>
|
||||||
|
</ion-item>
|
||||||
|
<ion-card-content>
|
||||||
|
<div *ngFor="let ch of item.cs">
|
||||||
|
<br>
|
||||||
|
<h2 *ngIf="item.cs.length > 1"><b>Chapter {{ch.ch}}</b></h2>
|
||||||
|
<span *ngFor="let vs of ch.vss"><b>{{vs.v}}.</b> <span *ngFor="let w of vs.w"><a (click)="openStrongs(w.s)">{{w.t}}</a></span><br></span>
|
||||||
|
</div>
|
||||||
|
</ion-card-content>
|
27
DynamicBibleIonic/src/components/passage/passage.ts
Normal file
27
DynamicBibleIonic/src/components/passage/passage.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { Component, EventEmitter, Output, Input} from "@angular/core";
|
||||||
|
@Component({
|
||||||
|
selector: "passage",
|
||||||
|
templateUrl: "passage.html"
|
||||||
|
})
|
||||||
|
export class Passage {
|
||||||
|
@Output()
|
||||||
|
onStrongs = new EventEmitter<string>();
|
||||||
|
@Output()
|
||||||
|
onClose = new EventEmitter<BiblePassageResult>();
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
item: BiblePassageResult;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
dict: string;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.onClose.emit(this.item);
|
||||||
|
}
|
||||||
|
openStrongs(strongs: string) {
|
||||||
|
this.onStrongs.emit(this.dict+strongs);
|
||||||
|
}
|
||||||
|
}
|
11
DynamicBibleIonic/src/components/strongs/strongs.html
Normal file
11
DynamicBibleIonic/src/components/strongs/strongs.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<ion-item class="title" padding>
|
||||||
|
{{item.prefix}}{{item.sn}}
|
||||||
|
<button ion-button icon-only item-right large clear (click)="close()">
|
||||||
|
<ion-icon name="close-circle"></ion-icon>
|
||||||
|
</button>
|
||||||
|
</ion-item>
|
||||||
|
<ion-card-content>
|
||||||
|
<p>
|
||||||
|
<b>{{item.def.tr}} ({{item.def.sn}})</b> - {{item.def.p}} - {{item.def.lemma}} - <span [innerHTML]="item.def.de"></span><br />
|
||||||
|
</p>
|
||||||
|
</ion-card-content>
|
20
DynamicBibleIonic/src/components/strongs/strongs.ts
Normal file
20
DynamicBibleIonic/src/components/strongs/strongs.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import {EventEmitter, Component, Input, Output} from "@angular/core";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "strongs",
|
||||||
|
templateUrl: "strongs.html"
|
||||||
|
})
|
||||||
|
export class Strongs {
|
||||||
|
@Output()
|
||||||
|
onClose = new EventEmitter<StrongsResult>();
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
item: StrongsResult;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.onClose.emit(this.item);
|
||||||
|
}
|
||||||
|
}
|
14
DynamicBibleIonic/src/declarations.d.ts
vendored
Normal file
14
DynamicBibleIonic/src/declarations.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
Declaration files are how the Typescript compiler knows about the type information(or shape) of an object.
|
||||||
|
They're what make intellisense work and make Typescript know all about your code.
|
||||||
|
|
||||||
|
A wildcard module is declared below to allow third party libraries to be used in an app even if they don't
|
||||||
|
provide their own type declarations.
|
||||||
|
|
||||||
|
To learn more about using third party libraries in an Ionic app, check out the docs here:
|
||||||
|
http://ionicframework.com/docs/v2/resources/third-party-libs/
|
||||||
|
|
||||||
|
For more info on type definition files, check out the Typescript docs here:
|
||||||
|
https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html
|
||||||
|
*/
|
||||||
|
declare module '*';
|
41
DynamicBibleIonic/src/index.html
Normal file
41
DynamicBibleIonic/src/index.html
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Dynamic Bible</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<meta name="msapplication-tap-highlight" content="no">
|
||||||
|
|
||||||
|
<link rel="icon" type="image/x-icon" href="assets/icon/favicon.ico">
|
||||||
|
<link rel="manifest" href="manifest.json">
|
||||||
|
<meta name="theme-color" content="#4e8ef7">
|
||||||
|
|
||||||
|
<!-- cordova.js required for cordova apps -->
|
||||||
|
<script src="cordova.js"></script>
|
||||||
|
|
||||||
|
<!-- un-comment this code to enable service worker
|
||||||
|
<script>
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
navigator.serviceWorker.register('service-worker.js')
|
||||||
|
.then(() => console.log('service worker installed'))
|
||||||
|
.catch(err => console.log('Error', err));
|
||||||
|
}
|
||||||
|
</script>-->
|
||||||
|
|
||||||
|
<link href="build/main.css" rel="stylesheet">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- Ionic's root component and where the app will load -->
|
||||||
|
<ion-app></ion-app>
|
||||||
|
|
||||||
|
<!-- The polyfills js is generated during the build process -->
|
||||||
|
<script src="build/polyfills.js"></script>
|
||||||
|
|
||||||
|
<!-- The bundle js is generated during the build process -->
|
||||||
|
<script src="build/main.js"></script>
|
||||||
|
<script src="lib/jquery.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
13
DynamicBibleIonic/src/manifest.json
Normal file
13
DynamicBibleIonic/src/manifest.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "Ionic",
|
||||||
|
"short_name": "Ionic",
|
||||||
|
"start_url": "index.html",
|
||||||
|
"display": "standalone",
|
||||||
|
"icons": [{
|
||||||
|
"src": "assets/imgs/logo.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}],
|
||||||
|
"background_color": "#4e8ef7",
|
||||||
|
"theme_color": "#4e8ef7"
|
||||||
|
}
|
26
DynamicBibleIonic/src/pages/search/search.html
Normal file
26
DynamicBibleIonic/src/pages/search/search.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<ion-header>
|
||||||
|
<ion-navbar>
|
||||||
|
<button menuToggle>
|
||||||
|
<ion-icon name="menu"></ion-icon>
|
||||||
|
</button>
|
||||||
|
<ion-searchbar (search)="getQuery($event)" (input)="setQuery($event)"></ion-searchbar>
|
||||||
|
</ion-navbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content padding class="search-card">
|
||||||
|
<ion-card *ngFor="let item of items" (swipe)="removeItem(item)">
|
||||||
|
<passage *ngIf="isPassage(item.type)" [item]="item.data" [dict]="item.dict" (onStrongs)="getItems($event)" (onClose)="removeItem($event)"></passage>
|
||||||
|
<strongs *ngIf="isStrongs(item.type)" [item]="item.data" (onClose)="removeItem($event)"></strongs>
|
||||||
|
<button ion-button icon-left clear small (click)="removeItem(item)">
|
||||||
|
<ion-icon name="close-circle"></ion-icon>
|
||||||
|
<div>Close</div>
|
||||||
|
</button>
|
||||||
|
<button ion-button icon-left clear small>
|
||||||
|
<ion-icon name="text"></ion-icon>
|
||||||
|
<div>4 Notes</div>
|
||||||
|
</button>
|
||||||
|
<button ion-button icon-left clear small>
|
||||||
|
<ion-icon name="text"></ion-icon>
|
||||||
|
<div>8 Tags</div>
|
||||||
|
</button>
|
||||||
|
</ion-card>
|
||||||
|
</ion-content>
|
@ -10,4 +10,5 @@
|
|||||||
|
|
||||||
.title{
|
.title{
|
||||||
background-color:gainsboro;
|
background-color:gainsboro;
|
||||||
|
font-size: 2em;
|
||||||
}
|
}
|
@ -1,64 +1,66 @@
|
|||||||
/// <reference path="../../types.ts" />
|
/// <reference path="../../types.ts" />
|
||||||
import {Injectable, Type} from "@angular/core";
|
import {Type, Component} from "@angular/core";
|
||||||
import {Reference} from "../../Reference";
|
import {Reference} from "../../Reference";
|
||||||
import {BibleService} from "../../bible-service";
|
import {BibleService} from "../../bible-service";
|
||||||
import {Component} from "@angular/core";
|
|
||||||
import {LoadingController} from "ionic-angular";
|
import {LoadingController} from "ionic-angular";
|
||||||
import {Passage} from "../../components/passage/passage.ts";
|
|
||||||
import {DclWrapper} from "../../components/dcl-wrapper/dcl-wrapper.ts";
|
|
||||||
import {StrongsService} from "../../strongs-service";
|
import {StrongsService} from "../../strongs-service";
|
||||||
import {Strongs} from "../../components/strongs/strongs";
|
import {Strongs} from "../../components/strongs/strongs";
|
||||||
import {ReversePipe} from "../../pipes/reverse-pipe.ts";
|
import {Passage} from "../../components/passage/passage.ts";
|
||||||
|
import {ComponentLoader} from "../../components/component-loader/component-loader.ts";
|
||||||
|
|
||||||
class Item
|
|
||||||
{
|
class Item {
|
||||||
id: number;
|
id: number;
|
||||||
data: any;
|
data: any;
|
||||||
type: Type;
|
type: Type<any>;
|
||||||
|
dict: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "build/pages/search/search.html",
|
templateUrl: "search.html",
|
||||||
providers: [BibleService, StrongsService],
|
providers: [BibleService, StrongsService],
|
||||||
directives: [DclWrapper],
|
|
||||||
pipes: [ReversePipe]
|
|
||||||
})
|
})
|
||||||
export class SearchPage
|
export class SearchPage {
|
||||||
{
|
|
||||||
searchQuery: string = "";
|
searchQuery: string = "";
|
||||||
items: any[];
|
items: any[];
|
||||||
last: number;
|
last: number;
|
||||||
|
|
||||||
constructor(private strongsService: StrongsService, private bibleService: BibleService, public loadingCtrl: LoadingController)
|
constructor(private strongsService: StrongsService, private bibleService: BibleService, public loadingCtrl: LoadingController) {
|
||||||
{
|
|
||||||
this.initializeItems();
|
this.initializeItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeItems()
|
initializeItems() {
|
||||||
{
|
|
||||||
this.items = [];
|
this.items = [];
|
||||||
this.last = 0;
|
this.last = 0;
|
||||||
}
|
}
|
||||||
setQuery(searchbar)
|
setQuery(searchbar) {
|
||||||
{
|
|
||||||
this.searchQuery = searchbar.target.value;
|
this.searchQuery = searchbar.target.value;
|
||||||
}
|
}
|
||||||
removeItem(item)
|
getQuery(searchbar) {
|
||||||
{
|
this.getItems(this.searchQuery);
|
||||||
|
}
|
||||||
|
removeItem(item) {
|
||||||
let idx = this.items.indexOf(item);
|
let idx = this.items.indexOf(item);
|
||||||
this.items.splice(idx, 1);
|
this.items.splice(idx, 1);
|
||||||
}
|
}
|
||||||
getItems(searchbar)
|
|
||||||
{
|
isPassage(t: Type<any>) {
|
||||||
try
|
return t == Passage;
|
||||||
{
|
}
|
||||||
|
|
||||||
|
isStrongs(t: Type<any>) {
|
||||||
|
return t == Strongs;
|
||||||
|
}
|
||||||
|
|
||||||
|
getItems(search) {
|
||||||
|
try {
|
||||||
let loader = this.loadingCtrl.create({
|
let loader = this.loadingCtrl.create({
|
||||||
content: "Retrieving passage...",
|
content: "Retrieving passage...",
|
||||||
dismissOnPageChange: true
|
dismissOnPageChange: true
|
||||||
});
|
});
|
||||||
loader.present();
|
loader.present();
|
||||||
|
|
||||||
let qs = this.searchQuery.split(";");
|
let qs = search.split(";");
|
||||||
for (let x in qs) {
|
for (let x in qs) {
|
||||||
if (qs.hasOwnProperty(x)) {
|
if (qs.hasOwnProperty(x)) {
|
||||||
let q = qs[x].trim();
|
let q = qs[x].trim();
|
||||||
@ -86,7 +88,7 @@ export class SearchPage
|
|||||||
let myref = new Reference(q.trim());
|
let myref = new Reference(q.trim());
|
||||||
let r = this.bibleService.getPassage(myref.Section);
|
let r = this.bibleService.getPassage(myref.Section);
|
||||||
r.ref = myref.toString();
|
r.ref = myref.toString();
|
||||||
this.items.unshift({ id: this.last++, data: r, type: Passage });
|
this.items.unshift({ id: this.last++, data: r, type: Passage, dict: r.testament == 'new' ? "G":"H" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,8 +98,7 @@ export class SearchPage
|
|||||||
|
|
||||||
//Settings.SaveResults();
|
//Settings.SaveResults();
|
||||||
}
|
}
|
||||||
catch (err)
|
catch (err) {
|
||||||
{
|
|
||||||
//Util.HandleError(err);
|
//Util.HandleError(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
80
DynamicBibleIonic/src/service-worker.js
Normal file
80
DynamicBibleIonic/src/service-worker.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// tick this to make the cache invalidate and update
|
||||||
|
const CACHE_VERSION = 1;
|
||||||
|
const CURRENT_CACHES = {
|
||||||
|
'read-through': 'read-through-cache-v' + CACHE_VERSION
|
||||||
|
};
|
||||||
|
|
||||||
|
self.addEventListener('activate', (event) => {
|
||||||
|
// Delete all caches that aren't named in CURRENT_CACHES.
|
||||||
|
// While there is only one cache in this example, the same logic will handle the case where
|
||||||
|
// there are multiple versioned caches.
|
||||||
|
const expectedCacheNames = Object.keys(CURRENT_CACHES).map((key) => {
|
||||||
|
return CURRENT_CACHES[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
event.waitUntil(
|
||||||
|
caches.keys().then((cacheNames) => {
|
||||||
|
return Promise.all(
|
||||||
|
cacheNames.map((cacheName) => {
|
||||||
|
if (expectedCacheNames.indexOf(cacheName) === -1) {
|
||||||
|
// If this cache name isn't present in the array of "expected" cache names, then delete it.
|
||||||
|
console.log('Deleting out of date cache:', cacheName);
|
||||||
|
return caches.delete(cacheName);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// This sample illustrates an aggressive approach to caching, in which every valid response is
|
||||||
|
// cached and every request is first checked against the cache.
|
||||||
|
// This may not be an appropriate approach if your web application makes requests for
|
||||||
|
// arbitrary URLs as part of its normal operation (e.g. a RSS client or a news aggregator),
|
||||||
|
// as the cache could end up containing large responses that might not end up ever being accessed.
|
||||||
|
// Other approaches, like selectively caching based on response headers or only caching
|
||||||
|
// responses served from a specific domain, might be more appropriate for those use cases.
|
||||||
|
self.addEventListener('fetch', (event) => {
|
||||||
|
|
||||||
|
event.respondWith(
|
||||||
|
caches.open(CURRENT_CACHES['read-through']).then((cache) => {
|
||||||
|
return cache.match(event.request).then((response) => {
|
||||||
|
if (response) {
|
||||||
|
// If there is an entry in the cache for event.request, then response will be defined
|
||||||
|
// and we can just return it.
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, if there is no entry in the cache for event.request, response will be
|
||||||
|
// undefined, and we need to fetch() the resource.
|
||||||
|
console.log(' No response for %s found in cache. ' +
|
||||||
|
'About to fetch from network...', event.request.url);
|
||||||
|
|
||||||
|
// We call .clone() on the request since we might use it in the call to cache.put() later on.
|
||||||
|
// Both fetch() and cache.put() "consume" the request, so we need to make a copy.
|
||||||
|
// (see https://fetch.spec.whatwg.org/#dom-request-clone)
|
||||||
|
return fetch(event.request.clone()).then((response) => {
|
||||||
|
|
||||||
|
// Optional: add in extra conditions here, e.g. response.type == 'basic' to only cache
|
||||||
|
// responses from the same domain. See https://fetch.spec.whatwg.org/#concept-response-type
|
||||||
|
if (response.status < 400 && response.type === 'basic') {
|
||||||
|
// We need to call .clone() on the response object to save a copy of it to the cache.
|
||||||
|
// (https://fetch.spec.whatwg.org/#dom-request-clone)
|
||||||
|
cache.put(event.request, response.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the original response object, which will be used to fulfill the resource request.
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
}).catch((error) => {
|
||||||
|
// This catch() will handle exceptions that arise from the match() or fetch() operations.
|
||||||
|
// Note that a HTTP error response (e.g. 404) will NOT trigger an exception.
|
||||||
|
// It will return a normal response object that has the appropriate error code set.
|
||||||
|
console.error(' Read-through caching failed:', error);
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
@ -1,8 +1,7 @@
|
|||||||
/// <reference path="../typings/browser/ambient/jquery/index.d.ts" />
|
/// <reference path="../typings/browser/ambient/jquery/index.d.ts" />
|
||||||
/// <reference path="types.ts" />
|
/// <reference path="types.ts" />
|
||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
import { Observable } from "rxjs/Observable";
|
import { Http } from "@angular/http";
|
||||||
import { Http, Response } from "@angular/http";
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class StrongsService
|
export class StrongsService
|
71
DynamicBibleIonic/src/theme/variables.scss
Normal file
71
DynamicBibleIonic/src/theme/variables.scss
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Ionic Variables and Theming. For more info, please see:
|
||||||
|
// http://ionicframework.com/docs/v2/theming/
|
||||||
|
@import "ionic.globals";
|
||||||
|
|
||||||
|
|
||||||
|
// Shared Variables
|
||||||
|
// --------------------------------------------------
|
||||||
|
// To customize the look and feel of this app, you can override
|
||||||
|
// the Sass variables found in Ionic's source scss files.
|
||||||
|
// To view all the possible Ionic variables, see:
|
||||||
|
// http://ionicframework.com/docs/v2/theming/overriding-ionic-variables/
|
||||||
|
|
||||||
|
$text-color: #000;
|
||||||
|
$background-color: #fff;
|
||||||
|
|
||||||
|
|
||||||
|
// Named Color Variables
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Named colors makes it easy to reuse colors on various components.
|
||||||
|
// It's highly recommended to change the default colors
|
||||||
|
// to match your app's branding. Ionic uses a Sass map of
|
||||||
|
// colors so you can add, rename and remove colors as needed.
|
||||||
|
// The "primary" color is the only required color in the map.
|
||||||
|
|
||||||
|
$colors: (
|
||||||
|
primary: #387ef5,
|
||||||
|
secondary: #32db64,
|
||||||
|
danger: #f53d3d,
|
||||||
|
light: #f4f4f4,
|
||||||
|
dark: #222
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// App iOS Variables
|
||||||
|
// --------------------------------------------------
|
||||||
|
// iOS only Sass variables can go here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// App Material Design Variables
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Material Design only Sass variables can go here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// App Windows Variables
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Windows only Sass variables can go here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// App Theme
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Ionic apps can have different themes applied, which can
|
||||||
|
// then be future customized. This import comes last
|
||||||
|
// so that the above variables are used and Ionic's
|
||||||
|
// default are overridden.
|
||||||
|
|
||||||
|
@import "ionic.theme.default";
|
||||||
|
|
||||||
|
|
||||||
|
// Ionicons
|
||||||
|
// --------------------------------------------------
|
||||||
|
// The premium icon font for Ionic. For more info, please see:
|
||||||
|
// http://ionicframework.com/docs/v2/ionicons/
|
||||||
|
|
||||||
|
$ionicons-font-path: "../assets/fonts";
|
||||||
|
@import "ionicons";
|
@ -1,18 +1,24 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"allowSyntheticDefaultImports": true,
|
||||||
"module": "commonjs",
|
"declaration": false,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"experimentalDecorators": true
|
"experimentalDecorators": true,
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"es2015"
|
||||||
|
],
|
||||||
|
"module": "es2015",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"sourceMap": true,
|
||||||
|
"target": "es5"
|
||||||
},
|
},
|
||||||
"filesGlob": [
|
"include": [
|
||||||
"**/*.ts",
|
"src/**/*.ts"
|
||||||
"!node_modules/**/*"
|
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
"typings/global",
|
".tmp"
|
||||||
"typings/global.d.ts"
|
|
||||||
],
|
],
|
||||||
"compileOnSave": false,
|
"compileOnSave": false,
|
||||||
"atom": {
|
"atom": {
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
{
|
{
|
||||||
"extends": "tslint-ionic-rules",
|
"rules": {
|
||||||
"rules" : {
|
"no-duplicate-variable": true,
|
||||||
|
"no-unused-variable": [
|
||||||
}
|
true
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rulesDirectory": [
|
||||||
|
"node_modules/tslint-eslint-rules/dist/rules"
|
||||||
|
]
|
||||||
}
|
}
|
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"dependencies": {},
|
|
||||||
"devDependencies": {},
|
|
||||||
"globalDependencies": {
|
|
||||||
"es6-shim": "registry:dt/es6-shim#0.31.2+20160602141504"
|
|
||||||
}
|
|
||||||
}
|
|
BIN
DynamicBibleIonic/www/assets/fonts/ionicons.eot
Normal file
BIN
DynamicBibleIonic/www/assets/fonts/ionicons.eot
Normal file
Binary file not shown.
2630
DynamicBibleIonic/www/assets/fonts/ionicons.svg
Normal file
2630
DynamicBibleIonic/www/assets/fonts/ionicons.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 391 KiB |
BIN
DynamicBibleIonic/www/assets/fonts/ionicons.ttf
Normal file
BIN
DynamicBibleIonic/www/assets/fonts/ionicons.ttf
Normal file
Binary file not shown.
BIN
DynamicBibleIonic/www/assets/fonts/ionicons.woff
Normal file
BIN
DynamicBibleIonic/www/assets/fonts/ionicons.woff
Normal file
Binary file not shown.
BIN
DynamicBibleIonic/www/assets/fonts/ionicons.woff2
Normal file
BIN
DynamicBibleIonic/www/assets/fonts/ionicons.woff2
Normal file
Binary file not shown.
BIN
DynamicBibleIonic/www/assets/icon/favicon.ico
Normal file
BIN
DynamicBibleIonic/www/assets/icon/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
@ -1,38 +1,41 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" dir="ltr">
|
||||||
<head>
|
<head>
|
||||||
<title>Ionic</title>
|
<meta charset="UTF-8">
|
||||||
<meta charset="UTF-8">
|
<title>Dynamic Bible</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<meta name="msapplication-tap-highlight" content="no">
|
||||||
|
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="icon" type="image/x-icon" href="assets/icon/favicon.ico">
|
||||||
|
<link rel="manifest" href="manifest.json">
|
||||||
|
<meta name="theme-color" content="#4e8ef7">
|
||||||
|
|
||||||
<!-- un-comment this code to enable service worker
|
<!-- cordova.js required for cordova apps -->
|
||||||
<script>
|
<script src="cordova.js"></script>
|
||||||
if ('serviceWorker' in navigator) {
|
|
||||||
navigator.serviceWorker.register('service-worker.js')
|
<!-- un-comment this code to enable service worker
|
||||||
.then(() => console.log('service worker installed'))
|
<script>
|
||||||
.catch(err => console.log('Error', err));
|
if ('serviceWorker' in navigator) {
|
||||||
}
|
navigator.serviceWorker.register('service-worker.js')
|
||||||
</script>-->
|
.then(() => console.log('service worker installed'))
|
||||||
|
.catch(err => console.log('Error', err));
|
||||||
|
}
|
||||||
|
</script>-->
|
||||||
|
|
||||||
|
<link href="build/main.css" rel="stylesheet">
|
||||||
|
|
||||||
<link ios-href="build/css/app.ios.css" rel="stylesheet">
|
|
||||||
<link md-href="build/css/app.md.css" rel="stylesheet">
|
|
||||||
<link wp-href="build/css/app.wp.css" rel="stylesheet">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<ion-app></ion-app>
|
<!-- Ionic's root component and where the app will load -->
|
||||||
|
<ion-app></ion-app>
|
||||||
|
|
||||||
<!-- cordova.js required for cordova apps -->
|
<!-- The polyfills js is generated during the build process -->
|
||||||
<script src="cordova.js"></script>
|
<script src="build/polyfills.js"></script>
|
||||||
<!-- Polyfill needed for platforms without Promise and Collection support -->
|
|
||||||
<script src="build/js/es6-shim.min.js"></script>
|
<!-- The bundle js is generated during the build process -->
|
||||||
<!-- Zone.js and Reflect-metadata -->
|
<script src="build/main.js"></script>
|
||||||
<script src="build/js/Reflect.js"></script>
|
<script src="lib/jquery.min.js"></script>
|
||||||
<script src="build/js/zone.js"></script>
|
|
||||||
<!-- the bundle which is built from the app's source code -->
|
|
||||||
<script src="build/js/app.bundle.js"></script>
|
|
||||||
<script src="lib/jquery.min.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -1,11 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "My Ionic App",
|
"name": "Ionic",
|
||||||
"short_name": "My Ionic App",
|
"short_name": "Ionic",
|
||||||
"start_url": "index.html",
|
"start_url": "index.html",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"icons": [{
|
"icons": [{
|
||||||
"src": "icon.png",
|
"src": "assets/imgs/logo.png",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
}]
|
}],
|
||||||
|
"background_color": "#4e8ef7",
|
||||||
|
"theme_color": "#4e8ef7"
|
||||||
}
|
}
|
@ -1,11 +1,80 @@
|
|||||||
self.addEventListener('activate', function (event) {
|
// tick this to make the cache invalidate and update
|
||||||
|
const CACHE_VERSION = 1;
|
||||||
|
const CURRENT_CACHES = {
|
||||||
|
'read-through': 'read-through-cache-v' + CACHE_VERSION
|
||||||
|
};
|
||||||
|
|
||||||
|
self.addEventListener('activate', (event) => {
|
||||||
|
// Delete all caches that aren't named in CURRENT_CACHES.
|
||||||
|
// While there is only one cache in this example, the same logic will handle the case where
|
||||||
|
// there are multiple versioned caches.
|
||||||
|
const expectedCacheNames = Object.keys(CURRENT_CACHES).map((key) => {
|
||||||
|
return CURRENT_CACHES[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
event.waitUntil(
|
||||||
|
caches.keys().then((cacheNames) => {
|
||||||
|
return Promise.all(
|
||||||
|
cacheNames.map((cacheName) => {
|
||||||
|
if (expectedCacheNames.indexOf(cacheName) === -1) {
|
||||||
|
// If this cache name isn't present in the array of "expected" cache names, then delete it.
|
||||||
|
console.log('Deleting out of date cache:', cacheName);
|
||||||
|
return caches.delete(cacheName);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.addEventListener('fetch', function (event) {
|
// This sample illustrates an aggressive approach to caching, in which every valid response is
|
||||||
|
// cached and every request is first checked against the cache.
|
||||||
});
|
// This may not be an appropriate approach if your web application makes requests for
|
||||||
|
// arbitrary URLs as part of its normal operation (e.g. a RSS client or a news aggregator),
|
||||||
self.addEventListener('push', function (event) {
|
// as the cache could end up containing large responses that might not end up ever being accessed.
|
||||||
|
// Other approaches, like selectively caching based on response headers or only caching
|
||||||
|
// responses served from a specific domain, might be more appropriate for those use cases.
|
||||||
|
self.addEventListener('fetch', (event) => {
|
||||||
|
|
||||||
|
event.respondWith(
|
||||||
|
caches.open(CURRENT_CACHES['read-through']).then((cache) => {
|
||||||
|
return cache.match(event.request).then((response) => {
|
||||||
|
if (response) {
|
||||||
|
// If there is an entry in the cache for event.request, then response will be defined
|
||||||
|
// and we can just return it.
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, if there is no entry in the cache for event.request, response will be
|
||||||
|
// undefined, and we need to fetch() the resource.
|
||||||
|
console.log(' No response for %s found in cache. ' +
|
||||||
|
'About to fetch from network...', event.request.url);
|
||||||
|
|
||||||
|
// We call .clone() on the request since we might use it in the call to cache.put() later on.
|
||||||
|
// Both fetch() and cache.put() "consume" the request, so we need to make a copy.
|
||||||
|
// (see https://fetch.spec.whatwg.org/#dom-request-clone)
|
||||||
|
return fetch(event.request.clone()).then((response) => {
|
||||||
|
|
||||||
|
// Optional: add in extra conditions here, e.g. response.type == 'basic' to only cache
|
||||||
|
// responses from the same domain. See https://fetch.spec.whatwg.org/#concept-response-type
|
||||||
|
if (response.status < 400 && response.type === 'basic') {
|
||||||
|
// We need to call .clone() on the response object to save a copy of it to the cache.
|
||||||
|
// (https://fetch.spec.whatwg.org/#dom-request-clone)
|
||||||
|
cache.put(event.request, response.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the original response object, which will be used to fulfill the resource request.
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
}).catch((error) => {
|
||||||
|
// This catch() will handle exceptions that arise from the match() or fetch() operations.
|
||||||
|
// Note that a HTTP error response (e.g. 404) will NOT trigger an exception.
|
||||||
|
// It will return a normal response object that has the appropriate error code set.
|
||||||
|
console.error(' Read-through caching failed:', error);
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
});
|
});
|
Loading…
x
Reference in New Issue
Block a user