From 971e90507dcf43194950e8078294d37dc48c4c64 Mon Sep 17 00:00:00 2001 From: Jordan Matthiesen Date: Thu, 15 Sep 2016 17:05:39 -0700 Subject: [PATCH] Update to the latest Beta11 release of Ionic! --- app/app.ts | 10 +- app/pages/about/about.html | 7 +- app/pages/about/about.ts | 23 +++-- app/pages/account/account.ts | 8 +- app/pages/login/login.ts | 10 +- app/pages/map/map.ts | 4 +- app/pages/schedule-filter/schedule-filter.ts | 6 +- app/pages/schedule/schedule.ts | 28 +++--- app/pages/session-detail/session-detail.ts | 2 +- app/pages/signup/signup.html | 4 +- app/pages/signup/signup.ts | 4 +- app/pages/speaker-detail/speaker-detail.ts | 6 +- app/pages/speaker-list/speaker-list.html | 3 + app/pages/speaker-list/speaker-list.ts | 39 ++++++-- app/providers/conference-data.ts | 2 +- app/providers/user-data.ts | 2 +- app/theme/app.core.scss | 2 +- app/theme/app.md.scss | 6 +- config.xml | 10 +- gulpfile.js | 1 + package.json | 21 +++-- www/data/data.json | 52 ++++++++--- www/index.html | 12 +++ www/manifest.json | 13 +++ www/service-worker.js | 97 ++++++++++++++++++++ 25 files changed, 281 insertions(+), 91 deletions(-) create mode 100644 www/manifest.json create mode 100644 www/service-worker.js diff --git a/app/app.ts b/app/app.ts index fad27d9e..8fef1a0b 100644 --- a/app/app.ts +++ b/app/app.ts @@ -45,9 +45,9 @@ class ConferenceApp { rootPage: any = TabsPage; constructor( - private events: Events, - private userData: UserData, - private menu: MenuController, + public events: Events, + public userData: UserData, + public menu: MenuController, platform: Platform, private confData: ConferenceData ) { @@ -121,6 +121,4 @@ class ConferenceApp { // See the theming docs for the default values: // http://ionicframework.com/docs/v2/theming/platform-specific-styles/ -ionicBootstrap(ConferenceApp, [ConferenceData, UserData], { - tabbarPlacement: 'bottom' -}); +ionicBootstrap(ConferenceApp, [ConferenceData, UserData], { }); diff --git a/app/pages/about/about.html b/app/pages/about/about.html index 8698e590..4f03fedc 100644 --- a/app/pages/about/about.html +++ b/app/pages/about/about.html @@ -29,7 +29,12 @@

Ionic Conference

Location - Madison, WI + + Madison, WI + Austin, TX + Chicago, IL + Seattle, WA + diff --git a/app/pages/about/about.ts b/app/pages/about/about.ts index caf332e5..589c4184 100644 --- a/app/pages/about/about.ts +++ b/app/pages/about/about.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import { NavController, Popover, ViewController, Alert } from 'ionic-angular'; +import { PopoverController, ViewController, AlertController } from 'ionic-angular'; import {CodePushUpdate} from '../../providers/codepush-update'; @@ -15,9 +15,7 @@ import {CodePushUpdate} from '../../providers/codepush-update'; }) class PopoverPage { - constructor(private viewCtrl: ViewController) { - - } + constructor(public viewCtrl: ViewController) { } close() { this.viewCtrl.dismiss(); @@ -35,28 +33,29 @@ export class AboutPage { isWindows: boolean; constructor( - private nav: NavController, - private updater: CodePushUpdate) { + public popoverCtrl: PopoverController, + public alertCtrl: AlertController, + public updater: CodePushUpdate) { this.isWindows = window.cordova.platformId === 'windows'; } presentPopover(event) { - let popover = Popover.create(PopoverPage); - this.nav.present(popover, { ev: event }); + let popover = this.popoverCtrl.create(PopoverPage); + popover.present({ ev: event }); } checkAndInstallUpdates() { this.updater.checkForUpdate().then((remotePackage) => { if (!remotePackage) { - let alert = Alert.create({ + let alert = this.alertCtrl.create({ title: 'No update available!', subTitle: 'We could not find any update.', buttons: ['Ok'] }); - this.nav.present(alert); + alert.present(); } else { console.log('update available: ' + remotePackage.appVersion); - let alert = Alert.create({ + let alert = this.alertCtrl.create({ title: 'Update ' + remotePackage.appVersion + ' available', message: 'Would you like to update your app?', buttons: [ @@ -74,7 +73,7 @@ export class AboutPage { } ] }); - this.nav.present(alert); + alert.present(); } }); } diff --git a/app/pages/account/account.ts b/app/pages/account/account.ts index 6d2b126c..6680711b 100644 --- a/app/pages/account/account.ts +++ b/app/pages/account/account.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; -import { Alert, NavController } from 'ionic-angular'; +import { AlertController, NavController } from 'ionic-angular'; import { LoginPage } from '../login/login'; import { UserData } from '../../providers/user-data'; @@ -12,7 +12,7 @@ import { UserData } from '../../providers/user-data'; export class AccountPage { username: string; - constructor(private nav: NavController, private userData: UserData) { + constructor(public alertCtrl: AlertController, public nav: NavController, public userData: UserData) { } @@ -28,7 +28,7 @@ export class AccountPage { // clicking OK will update the username and display it // clicking Cancel will close the alert and do nothing changeUsername() { - let alert = Alert.create({ + let alert = this.alertCtrl.create({ title: 'Change Username', buttons: [ 'Cancel' @@ -47,7 +47,7 @@ export class AccountPage { } }); - this.nav.present(alert); + alert.present(); } getUsername() { diff --git a/app/pages/login/login.ts b/app/pages/login/login.ts index 3eb9036d..54500b56 100644 --- a/app/pages/login/login.ts +++ b/app/pages/login/login.ts @@ -14,10 +14,14 @@ export class LoginPage { login: {username?: string, password?: string} = {}; submitted = false; - constructor(private nav: NavController, private userData: UserData) {} + constructor(public navCtrl: NavController, public userData: UserData) { } - doLogin(provider: string) { + onLogin(provider: string) { this.userData.login(provider); - this.nav.push(TabsPage); + this.navCtrl.push(TabsPage); + } + + onSignup() { + this.navCtrl.push(SignupPage); } } diff --git a/app/pages/map/map.ts b/app/pages/map/map.ts index eda3d642..0cb80eea 100644 --- a/app/pages/map/map.ts +++ b/app/pages/map/map.ts @@ -1,7 +1,5 @@ import { Component } from '@angular/core'; -import { Page } from 'ionic-angular'; - import { ConferenceData } from '../../providers/conference-data'; @@ -9,7 +7,7 @@ import { ConferenceData } from '../../providers/conference-data'; templateUrl: 'build/pages/map/map.html' }) export class MapPage { - constructor(private confData: ConferenceData) {} + constructor(public confData: ConferenceData) {} ionViewLoaded() { this.confData.getMap().then(mapData => { diff --git a/app/pages/schedule-filter/schedule-filter.ts b/app/pages/schedule-filter/schedule-filter.ts index 0923e9d5..965d87c1 100644 --- a/app/pages/schedule-filter/schedule-filter.ts +++ b/app/pages/schedule-filter/schedule-filter.ts @@ -12,9 +12,9 @@ export class ScheduleFilterPage { tracks: Array<{name: string, isChecked: boolean}> = []; constructor( - private confData: ConferenceData, - private navParams: NavParams, - private viewCtrl: ViewController + public confData: ConferenceData, + public navParams: NavParams, + public viewCtrl: ViewController ) { // passed in array of track names that should be excluded (unchecked) let excludedTrackNames = this.navParams.data; diff --git a/app/pages/schedule/schedule.ts b/app/pages/schedule/schedule.ts index c58d1413..96480020 100644 --- a/app/pages/schedule/schedule.ts +++ b/app/pages/schedule/schedule.ts @@ -1,6 +1,6 @@ import { Component, ViewChild } from '@angular/core'; -import { Alert, App, ItemSliding, List, Modal, NavController, Page } from 'ionic-angular'; +import { AlertController, App, ItemSliding, List, ModalController, NavController } from 'ionic-angular'; import { ConferenceData } from '../../providers/conference-data'; import { ScheduleFilterPage } from '../schedule-filter/schedule-filter'; @@ -26,10 +26,12 @@ export class SchedulePage { groups = []; constructor( - private app: App, - private nav: NavController, - private confData: ConferenceData, - private user: UserData + public alertCtrl: AlertController, + public app: App, + public modalCtrl: ModalController, + public navCtrl: NavController, + public confData: ConferenceData, + public user: UserData ) { } @@ -64,10 +66,10 @@ export class SchedulePage { } presentFilter() { - let modal = Modal.create(ScheduleFilterPage, this.excludeTracks); - this.nav.present(modal); + let modal = this.modalCtrl.create(ScheduleFilterPage, this.excludeTracks); + modal.present(); - modal.onDismiss((data: any[]) => { + modal.onDidDismiss((data: any[]) => { if (data) { this.excludeTracks = data; this.updateSchedule(); @@ -79,7 +81,7 @@ export class SchedulePage { goToSessionDetail(sessionData) { // go to the session detail page // and pass in the session data - this.nav.push(SessionDetailPage, sessionData); + this.navCtrl.push(SessionDetailPage, sessionData); } addFavorite(slidingItem: ItemSliding, sessionData) { @@ -93,7 +95,7 @@ export class SchedulePage { this.user.addFavorite(sessionData.name); // create an alert instance - let alert = Alert.create({ + let alert = this.alertCtrl.create({ title: 'Favorite Added', buttons: [{ text: 'OK', @@ -104,14 +106,14 @@ export class SchedulePage { }] }); // now present the alert on top of all other content - this.nav.present(alert); + alert.present(); } } removeFavorite(slidingItem: ItemSliding, sessionData, title) { sessionData.favorite = false; - let alert = Alert.create({ + let alert = this.alertCtrl.create({ title: title, message: 'Would you like to remove this session from your favorites?', buttons: [ @@ -137,6 +139,6 @@ export class SchedulePage { ] }); // now present the alert on top of all other content - this.nav.present(alert); + alert.present(); } } diff --git a/app/pages/session-detail/session-detail.ts b/app/pages/session-detail/session-detail.ts index c054dd31..3d70c22b 100644 --- a/app/pages/session-detail/session-detail.ts +++ b/app/pages/session-detail/session-detail.ts @@ -9,7 +9,7 @@ import { NavParams } from 'ionic-angular'; export class SessionDetailPage { session: any; - constructor(private navParams: NavParams) { + constructor(public navParams: NavParams) { this.session = navParams.data; } } diff --git a/app/pages/signup/signup.html b/app/pages/signup/signup.html index 512b9637..e1c4f9b9 100644 --- a/app/pages/signup/signup.html +++ b/app/pages/signup/signup.html @@ -17,7 +17,7 @@
Username - +

@@ -26,7 +26,7 @@ Password - +

diff --git a/app/pages/signup/signup.ts b/app/pages/signup/signup.ts index 36fd20d1..61fdee50 100644 --- a/app/pages/signup/signup.ts +++ b/app/pages/signup/signup.ts @@ -13,14 +13,14 @@ export class SignupPage { signup: {username?: string, password?: string} = {}; submitted = false; - constructor(private nav: NavController, private userData: UserData) {} + constructor(public navCtrl: NavController, public userData: UserData) {} onSignup(form) { this.submitted = true; if (form.valid) { this.userData.signup(this.signup.username); - this.nav.push(TabsPage); + this.navCtrl.push(TabsPage); } } } diff --git a/app/pages/speaker-detail/speaker-detail.ts b/app/pages/speaker-detail/speaker-detail.ts index 41fccd11..0b3b76af 100644 --- a/app/pages/speaker-detail/speaker-detail.ts +++ b/app/pages/speaker-detail/speaker-detail.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; -import { NavController, NavParams, Page } from 'ionic-angular'; +import { NavController, NavParams } from 'ionic-angular'; import { SessionDetailPage } from '../session-detail/session-detail'; @@ -11,11 +11,11 @@ import { SessionDetailPage } from '../session-detail/session-detail'; export class SpeakerDetailPage { speaker: any; - constructor(private nav: NavController, private navParams: NavParams) { + constructor(public navCtrl: NavController, public navParams: NavParams) { this.speaker = this.navParams.data; } goToSessionDetail(session) { - this.nav.push(SessionDetailPage, session); + this.navCtrl.push(SessionDetailPage, session); } } diff --git a/app/pages/speaker-list/speaker-list.html b/app/pages/speaker-list/speaker-list.html index 284a8d51..0a73dee6 100644 --- a/app/pages/speaker-list/speaker-list.html +++ b/app/pages/speaker-list/speaker-list.html @@ -16,6 +16,9 @@ {{speaker.name}} + diff --git a/app/pages/speaker-list/speaker-list.ts b/app/pages/speaker-list/speaker-list.ts index b774b1c0..c477f948 100644 --- a/app/pages/speaker-list/speaker-list.ts +++ b/app/pages/speaker-list/speaker-list.ts @@ -1,6 +1,7 @@ import { Component } from '@angular/core'; -import { ActionSheet, NavController, Page } from 'ionic-angular'; +import { ActionSheet, ActionSheetController, NavController } from 'ionic-angular'; +import { InAppBrowser } from 'ionic-native'; import { ConferenceData } from '../../providers/conference-data'; import { SessionDetailPage } from '../session-detail/session-detail'; @@ -14,26 +15,26 @@ export class SpeakerListPage { actionSheet: ActionSheet; speakers = []; - constructor(private nav: NavController, confData: ConferenceData) { + constructor(public actionSheetCtrl: ActionSheetController, public navCtrl: NavController, confData: ConferenceData) { confData.getSpeakers().then(speakers => { this.speakers = speakers; }); } goToSessionDetail(session) { - this.nav.push(SessionDetailPage, session); + this.navCtrl.push(SessionDetailPage, session); } goToSpeakerDetail(speakerName: string) { - this.nav.push(SpeakerDetailPage, speakerName); + this.navCtrl.push(SpeakerDetailPage, speakerName); } goToSpeakerTwitter(speaker) { - window.open(`https://twitter.com/${speaker.twitter}`); + new InAppBrowser(`https://twitter.com/${speaker.twitter}`, '_system'); } openSpeakerShare(speaker) { - let actionSheet = ActionSheet.create({ + let actionSheet = this.actionSheetCtrl.create({ title: 'Share ' + speaker.name, buttons: [ { @@ -61,6 +62,30 @@ export class SpeakerListPage { ] }); - this.nav.present(actionSheet); + actionSheet.present(); + } + + openContact(speaker) { + let actionSheet = this.actionSheetCtrl.create({ + title: 'Contact with ' + speaker.name, + buttons: [ + { + text: `Email ( ${speaker.email} )`, + icon: 'mail', + handler: () => { + window.open('mailto:' + speaker.email); + } + }, + { + text: `Call ( ${speaker.phone} )`, + icon: 'call', + handler: () => { + window.open('tel:' + speaker.phone); + } + } + ] + }); + + actionSheet.present(); } } diff --git a/app/providers/conference-data.ts b/app/providers/conference-data.ts index ad2746a4..8604ebef 100644 --- a/app/providers/conference-data.ts +++ b/app/providers/conference-data.ts @@ -9,7 +9,7 @@ import { UserData } from './user-data'; export class ConferenceData { data: any; - constructor(private http: Http, private user: UserData) {} + constructor(public http: Http, public user: UserData) {} load() { if (this.data) { diff --git a/app/providers/user-data.ts b/app/providers/user-data.ts index 540df381..f497a52f 100644 --- a/app/providers/user-data.ts +++ b/app/providers/user-data.ts @@ -14,7 +14,7 @@ export class UserData { remoteFavsTable: WindowsAzure.MobileServiceTable; loggedIn: boolean = false; - constructor(private events: Events) {} + constructor(public events: Events) {} hasFavorite(sessionName) { return (this._favorites.indexOf(sessionName) > -1); diff --git a/app/theme/app.core.scss b/app/theme/app.core.scss index 27bb4b81..601a1bfe 100644 --- a/app/theme/app.core.scss +++ b/app/theme/app.core.scss @@ -26,4 +26,4 @@ @import "../pages/speaker-detail/speaker-detail"; -@import "../pages/speaker-list/speaker-list"; +@import "../pages/speaker-list/speaker-list"; \ No newline at end of file diff --git a/app/theme/app.md.scss b/app/theme/app.md.scss index 116abed4..cde8fbb8 100644 --- a/app/theme/app.md.scss +++ b/app/theme/app.md.scss @@ -15,11 +15,11 @@ $toolbar-md-background: color($colors, primary); // Use the default background for the tabbar since it inherits from toolbar -$tabbar-md-background: #f8f8f8; +$tabs-md-background: #f8f8f8; // Change the color of the tabs text -$tab-button-md-active-color: color($colors, primary); -$tab-button-md-inactive-color: #8c8c8c; +$tabs-md-tab-color-active: color($colors, primary); +$tabs-md-tab-color: rgba(#8c8c8c, 0.7); // Change the color of the segment button text $toolbar-md-active-color: #fff; diff --git a/config.xml b/config.xml index 7b38eb81..d6876052 100644 --- a/config.xml +++ b/config.xml @@ -16,6 +16,8 @@ + + @@ -99,9 +101,12 @@ + + + + - @@ -120,7 +125,8 @@ - + + diff --git a/gulpfile.js b/gulpfile.js index c43f47c4..84283439 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -41,6 +41,7 @@ gulp.task('watch', ['clean'], function(done){ function(){ gulpWatch('app/**/*.scss', function(){ gulp.start('sass'); }); gulpWatch('app/**/*.html', function(){ gulp.start('html'); }); + gulpWatch('app/**/*.ts', function(){ gulp.start('lint'); }); buildBrowserify({ watch: true }).on('end', done); } ); diff --git a/package.json b/package.json index 2ba202ef..47c3aae9 100644 --- a/package.json +++ b/package.json @@ -7,16 +7,17 @@ "url": "https://github.com/driftyco/ionic-conference-app.git" }, "dependencies": { - "@angular/common": "2.0.0-rc.3", - "@angular/compiler": "2.0.0-rc.3", - "@angular/core": "2.0.0-rc.3", - "@angular/http": "2.0.0-rc.3", - "@angular/platform-browser": "2.0.0-rc.3", - "@angular/platform-browser-dynamic": "2.0.0-rc.3", - "@angular/router": "2.0.0-rc.2", + "@angular/common": "2.0.0-rc.4", + "@angular/compiler": "2.0.0-rc.4", + "@angular/core": "2.0.0-rc.4", + "@angular/forms": "0.2.0", + "@angular/http": "2.0.0-rc.4", + "@angular/platform-browser": "2.0.0-rc.4", + "@angular/platform-browser-dynamic": "2.0.0-rc.4", + "@angular/router": "^2.0.0-rc.2", "es6-shim": "0.35.0", - "ionic-angular": "2.0.0-beta.10", - "ionic-native": "1.1.0", + "ionic-angular": "2.0.0-beta.11", + "ionic-native": "^1.3.10", "ionicons": "3.0.0", "reflect-metadata": "0.1.3", "rxjs": "5.0.0-beta.6", @@ -35,7 +36,7 @@ "ionic-gulp-tslint": "^1.0.0", "run-sequence": "1.1.5", "tslint": "^3.10.1", - "tslint-ionic-rules": "^0.0.3" + "tslint-ionic-rules": "0.0.5" }, "cordovaPlugins": [ "cordova-plugin-whitelist", diff --git a/www/data/data.json b/www/data/data.json index 91c6aa0d..496e8827 100644 --- a/www/data/data.json +++ b/www/data/data.json @@ -223,91 +223,117 @@ "profilePic": "img/speakers/bear.jpg", "twitter": "ionicframework", "about": "Burt is a Bear.", - "location": "Everywhere" + "location": "Everywhere", + "email": "burt@example.com", + "phone": "+1-541-754-3010" }, { "name": "Charlie Cheetah", "profilePic": "img/speakers/cheetah.jpg", "twitter": "ionicframework", "about": "Charlie is a Cheetah.", - "location": "Everywhere" + "location": "Everywhere", + "email": "charlie@example.com", + "phone": "+1-541-754-3010" }, { "name": "Donald Duck", "profilePic": "img/speakers/duck.jpg", "twitter": "ionicframework", "about": "Donald is a Duck.", - "location": "Everywhere" + "location": "Everywhere", + "email": "donald@example.com", + "phone": "+1-541-754-3010" }, { "name": "Eva Eagle", "profilePic": "img/speakers/eagle.jpg", "twitter": "ionicframework", "about": "Eva is an Eagle.", - "location": "Everywhere" + "location": "Everywhere", + "email": "eva@example.com", + "phone": "+1-541-754-3010" }, { "name": "Ellie Elephant", "profilePic": "img/speakers/elephant.jpg", "twitter": "ionicframework", "about": "Ellie is an Elephant.", - "location": "Everywhere" + "location": "Everywhere", + "email": "ellie@example.com", + "phone": "+1-541-754-3010" }, { "name": "Gino Giraffe", "profilePic": "img/speakers/giraffe.jpg", "twitter": "ionicframework", "about": "Gino is a Giraffe.", - "location": "Everywhere" + "location": "Everywhere", + "email": "gino@example.com", + "phone": "+1-541-754-3010" }, { "name": "Isabella Iguana", "profilePic": "img/speakers/iguana.jpg", "twitter": "ionicframework", "about": "Isabella is an Iguana.", - "location": "Everywhere" + "location": "Everywhere", + "email": "isabella@example.com", + "phone": "+1-541-754-3010" }, { "name": "Karl Kitten", "profilePic": "img/speakers/kitten.jpg", "twitter": "ionicframework", "about": "Karl is a Kitten.", - "location": "Everywhere" + "location": "Everywhere", + "email": "karl@example.com", + "phone": "+1-541-754-3010" }, { "name": "Lionel Lion", "profilePic": "img/speakers/lion.jpg", "twitter": "ionicframework", "about": "Lionel is a Lion.", - "location": "Everywhere" + "location": "Everywhere", + "email": "lionel@example.com", + "phone": "+1-541-754-3010" }, { "name": "Molly Mouse", "profilePic": "img/speakers/mouse.jpg", "twitter": "ionicframework", "about": "Molly is a Mouse.", - "location": "Everywhere" + "location": "Everywhere", + "email": "molly@example.com", + "phone": "+1-541-754-3010" }, { "name": "Paul Puppy", "profilePic": "img/speakers/puppy.jpg", "twitter": "ionicframework", "about": "Paul is a Puppy.", - "location": "Everywhere" + "location": "Everywhere", + "email": "paul@example.com", + "phone": "+1-541-754-3010" }, { "name": "Rachel Rabbit", "profilePic": "img/speakers/rabbit.jpg", "twitter": "ionicframework", "about": "Rachel is a Rabbit.", - "location": "Everywhere" + "location": "Everywhere", + "email": "rachel@example.com", + "phone": "+1-541-754-3010" }, { "name": "Ted Turtle", "profilePic": "img/speakers/turtle.jpg", "twitter": "ionicframework", "about": "Ted is a Turtle.", - "location": "Everywhere" + "location": "Everywhere", + "email": "ted@example.com", + "phone": "+1-541-754-3010" } ], diff --git a/www/index.html b/www/index.html index c2caa7ec..65b44431 100644 --- a/www/index.html +++ b/www/index.html @@ -9,6 +9,18 @@ + + + + + diff --git a/www/manifest.json b/www/manifest.json new file mode 100644 index 00000000..ed5411da --- /dev/null +++ b/www/manifest.json @@ -0,0 +1,13 @@ +{ + "name": "Ionic", + "short_name": "Ionic", + "start_url": "index.html", + "display": "standalone", + "icons": [{ + "src": "img/appicon.png", + "sizes": "512x512", + "type": "image/png" + }], + "background_color": "#4e8ef7", + "theme_color": "#4e8ef7" +} \ No newline at end of file diff --git a/www/service-worker.js b/www/service-worker.js new file mode 100644 index 00000000..bbc8ef00 --- /dev/null +++ b/www/service-worker.js @@ -0,0 +1,97 @@ +/* + Copyright 2014 Google Inc. All Rights Reserved. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// While overkill for this specific sample in which there is only one cache, +// this is one best practice that can be followed in general to keep track of +// multiple caches used by a given service worker, and keep them all versioned. +// It maps a shorthand identifier for a cache to a specific, versioned cache name. + +// Note that since global state is discarded in between service worker restarts, these +// variables will be reinitialized each time the service worker handles an event, and you +// should not attempt to change their values inside an event handler. (Treat them as constants.) + +// If at any point you want to force pages that use this service worker to start using a fresh +// cache, then increment the CACHE_VERSION value. It will kick off the service worker update +// flow and the old cache(s) will be purged as part of the activate event handler when the +// updated service worker is activated. +var CACHE_VERSION = 2; +var CURRENT_CACHES = { + 'read-through': 'read-through-cache-v' + CACHE_VERSION +}; + +self.addEventListener('activate', function (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. + var expectedCacheNames = Object.keys(CURRENT_CACHES).map(function (key) { + return CURRENT_CACHES[key]; + }); + + event.waitUntil( + caches.keys().then(function (cacheNames) { + return Promise.all( + cacheNames.map(function (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) { + + event.respondWith( + caches.open(CURRENT_CACHES['read-through']).then(function (cache) { + return cache.match(event.request).then(function (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(function (response) { + + // Modified here, added check for response.type == 'basic' to only cache local assets + 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(function (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; + }); + }) + ); +}); \ No newline at end of file