├── www └── .gitignore ├── typings ├── webpack.d.ts ├── commonjs.d.ts └── .gitignore ├── resources ├── icon.psd ├── splash.png ├── gifs │ ├── ios.gif │ └── nexus.gif ├── screenshots │ ├── iphone │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ └── 6.png │ └── nexus │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ └── 6.png ├── ios │ └── splash │ │ ├── Default-667h.png │ │ ├── Default-736h.png │ │ ├── Default~iphone.png │ │ ├── Default@2x~iphone.png │ │ ├── Default-Portrait~ipad.png │ │ ├── Default-568h@2x~iphone.png │ │ ├── Default-Landscape-736h.png │ │ ├── Default-Landscape~ipad.png │ │ ├── Default-Portrait@2x~ipad.png │ │ └── Default-Landscape@2x~ipad.png └── android │ └── splash │ ├── drawable-land-hdpi-screen.png │ ├── drawable-land-ldpi-screen.png │ ├── drawable-land-mdpi-screen.png │ ├── drawable-port-hdpi-screen.png │ ├── drawable-port-ldpi-screen.png │ ├── drawable-port-mdpi-screen.png │ ├── drawable-land-xhdpi-screen.png │ ├── drawable-land-xxhdpi-screen.png │ ├── drawable-port-xhdpi-screen.png │ ├── drawable-port-xxhdpi-screen.png │ ├── drawable-land-xxxhdpi-screen.png │ └── drawable-port-xxxhdpi-screen.png ├── ionic.config.json ├── app ├── images │ ├── appicon.png │ ├── speakers │ │ ├── bear.jpg │ │ ├── duck.jpg │ │ ├── eagle.jpg │ │ ├── lion.jpg │ │ ├── mouse.jpg │ │ ├── puppy.jpg │ │ ├── cheetah.jpg │ │ ├── giraffe.jpg │ │ ├── iguana.jpg │ │ ├── kitten.jpg │ │ ├── rabbit.jpg │ │ ├── turtle.jpg │ │ └── elephant.jpg │ ├── ica-slidebox-img-1.png │ ├── ica-slidebox-img-2.png │ ├── ica-slidebox-img-3.png │ ├── ica-slidebox-img-4.png │ ├── appicon.svg │ └── ionic-logo-white.svg ├── pages │ ├── account │ │ ├── account.scss │ │ ├── account.html │ │ └── account.ts │ ├── speaker-detail │ │ ├── speaker-detail.scss │ │ ├── speaker-detail.ts │ │ └── speaker-detail.html │ ├── login │ │ ├── login.scss │ │ ├── login.ts │ │ └── login.html │ ├── map │ │ ├── map.scss │ │ ├── map.html │ │ └── map.ts │ ├── session-detail │ │ ├── session-detail.ts │ │ └── session-detail.html │ ├── schedule-filter │ │ ├── schedule-filter.scss │ │ ├── schedule-filter.html │ │ └── schedule-filter.ts │ ├── tabs │ │ ├── tabs.html │ │ └── tabs.ts │ ├── speaker-list │ │ ├── speaker-list.scss │ │ ├── speaker-list.html │ │ └── speaker-list.ts │ ├── tutorial │ │ ├── tutorial.scss │ │ ├── tutorial.html │ │ └── tutorial.ts │ ├── schedule │ │ ├── schedule.scss │ │ ├── schedule.html │ │ └── schedule.ts │ ├── signup │ │ ├── signup.ts │ │ └── signup.html │ └── about │ │ ├── about.scss │ │ ├── about.ts │ │ └── about.html ├── scss │ ├── index.scss │ └── _variables.scss ├── index.html ├── providers │ ├── user-data.ts │ ├── conference-data.ts │ └── data.json ├── app.html └── app.ts ├── typings.json ├── .editorconfig ├── tsconfig.json ├── .gitignore ├── README.md ├── webpack.config.js ├── package.json └── config.xml /www/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !README.md 3 | !.gitignore -------------------------------------------------------------------------------- /typings/webpack.d.ts: -------------------------------------------------------------------------------- 1 | declare let __DEV__: boolean; -------------------------------------------------------------------------------- /typings/commonjs.d.ts: -------------------------------------------------------------------------------- 1 | declare function require(string): any; -------------------------------------------------------------------------------- /typings/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !commonjs.d.ts 4 | !webpack.d.ts 5 | -------------------------------------------------------------------------------- /resources/icon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/icon.psd -------------------------------------------------------------------------------- /ionic.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic2-webpack-boilerplate", 3 | "app_id": "", 4 | "v2": true 5 | } 6 | -------------------------------------------------------------------------------- /resources/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/splash.png -------------------------------------------------------------------------------- /app/images/appicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/appicon.png -------------------------------------------------------------------------------- /resources/gifs/ios.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/gifs/ios.gif -------------------------------------------------------------------------------- /resources/gifs/nexus.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/gifs/nexus.gif -------------------------------------------------------------------------------- /app/images/speakers/bear.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/bear.jpg -------------------------------------------------------------------------------- /app/images/speakers/duck.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/duck.jpg -------------------------------------------------------------------------------- /app/images/speakers/eagle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/eagle.jpg -------------------------------------------------------------------------------- /app/images/speakers/lion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/lion.jpg -------------------------------------------------------------------------------- /app/images/speakers/mouse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/mouse.jpg -------------------------------------------------------------------------------- /app/images/speakers/puppy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/puppy.jpg -------------------------------------------------------------------------------- /app/images/speakers/cheetah.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/cheetah.jpg -------------------------------------------------------------------------------- /app/images/speakers/giraffe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/giraffe.jpg -------------------------------------------------------------------------------- /app/images/speakers/iguana.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/iguana.jpg -------------------------------------------------------------------------------- /app/images/speakers/kitten.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/kitten.jpg -------------------------------------------------------------------------------- /app/images/speakers/rabbit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/rabbit.jpg -------------------------------------------------------------------------------- /app/images/speakers/turtle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/turtle.jpg -------------------------------------------------------------------------------- /app/images/ica-slidebox-img-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/ica-slidebox-img-1.png -------------------------------------------------------------------------------- /app/images/ica-slidebox-img-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/ica-slidebox-img-2.png -------------------------------------------------------------------------------- /app/images/ica-slidebox-img-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/ica-slidebox-img-3.png -------------------------------------------------------------------------------- /app/images/ica-slidebox-img-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/ica-slidebox-img-4.png -------------------------------------------------------------------------------- /app/images/speakers/elephant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/app/images/speakers/elephant.jpg -------------------------------------------------------------------------------- /app/pages/account/account.scss: -------------------------------------------------------------------------------- 1 | 2 | .account-page { 3 | img { 4 | max-width: 140px; 5 | border-radius: 50%; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /resources/screenshots/iphone/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/screenshots/iphone/1.png -------------------------------------------------------------------------------- /resources/screenshots/iphone/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/screenshots/iphone/2.png -------------------------------------------------------------------------------- /resources/screenshots/iphone/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/screenshots/iphone/3.png -------------------------------------------------------------------------------- /resources/screenshots/iphone/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/screenshots/iphone/4.png -------------------------------------------------------------------------------- /resources/screenshots/iphone/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/screenshots/iphone/5.png -------------------------------------------------------------------------------- /resources/screenshots/iphone/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/screenshots/iphone/6.png -------------------------------------------------------------------------------- /resources/screenshots/nexus/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/screenshots/nexus/1.png -------------------------------------------------------------------------------- /resources/screenshots/nexus/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/screenshots/nexus/2.png -------------------------------------------------------------------------------- /resources/screenshots/nexus/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/screenshots/nexus/3.png -------------------------------------------------------------------------------- /resources/screenshots/nexus/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/screenshots/nexus/4.png -------------------------------------------------------------------------------- /resources/screenshots/nexus/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/screenshots/nexus/5.png -------------------------------------------------------------------------------- /resources/screenshots/nexus/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/screenshots/nexus/6.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-667h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/ios/splash/Default-667h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-736h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/ios/splash/Default-736h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/ios/splash/Default~iphone.png -------------------------------------------------------------------------------- /resources/ios/splash/Default@2x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/ios/splash/Default@2x~iphone.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Portrait~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/ios/splash/Default-Portrait~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-568h@2x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/ios/splash/Default-568h@2x~iphone.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape-736h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/ios/splash/Default-Landscape-736h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/ios/splash/Default-Landscape~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Portrait@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/ios/splash/Default-Portrait@2x~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/ios/splash/Default-Landscape@2x~ipad.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-hdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/android/splash/drawable-land-hdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-ldpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/android/splash/drawable-land-ldpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-mdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/android/splash/drawable-land-mdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-hdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/android/splash/drawable-port-hdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-ldpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/android/splash/drawable-port-ldpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-mdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/android/splash/drawable-port-mdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-xhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/android/splash/drawable-land-xhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-xxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/android/splash/drawable-land-xxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-xhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/android/splash/drawable-port-xhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-xxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/android/splash/drawable-port-xxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-xxxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/android/splash/drawable-land-xxxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-xxxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shprink/ionic2-webpack-boilerplate/HEAD/resources/android/splash/drawable-port-xxxhdpi-screen.png -------------------------------------------------------------------------------- /app/pages/speaker-detail/speaker-detail.scss: -------------------------------------------------------------------------------- 1 | 2 | .speaker-detail img { 3 | max-width: 140px; 4 | border-radius: 50%; 5 | } 6 | 7 | .speaker-detail p { 8 | color: #60646B; 9 | } 10 | -------------------------------------------------------------------------------- /app/pages/login/login.scss: -------------------------------------------------------------------------------- 1 | 2 | .login-page .logo { 3 | padding: 20px 0; 4 | min-height: 200px; 5 | text-align: center; 6 | } 7 | 8 | .login-page .logo img { 9 | max-width: 150px; 10 | } 11 | -------------------------------------------------------------------------------- /typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic2-webpack-boilerplate", 3 | "globalDependencies": { 4 | "core-js": "registry:dt/core-js#0.0.0+20160602141332", 5 | "googlemaps": "github:DefinitelyTyped/DefinitelyTyped/googlemaps/google.maps.d.ts" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /app/pages/map/map.scss: -------------------------------------------------------------------------------- 1 | 2 | .map-page ion-content { 3 | background: rgb(229, 227, 223); 4 | } 5 | 6 | .map-page #map { 7 | width: 100%; 8 | height: 100%; 9 | opacity: 0; 10 | transition: opacity 150ms ease-in 11 | } 12 | 13 | .map-page #map.show-map { 14 | opacity: 1; 15 | } 16 | -------------------------------------------------------------------------------- /app/pages/map/map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | Map 7 | 8 | 9 | 10 | 11 |
12 |
13 | -------------------------------------------------------------------------------- /app/pages/session-detail/session-detail.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { NavParams } from 'ionic-angular'; 4 | 5 | 6 | @Component({ 7 | templateUrl: 'session-detail.html' 8 | }) 9 | export class SessionDetailPage { 10 | session: any; 11 | 12 | constructor(private navParams: NavParams) { 13 | this.session = navParams.data; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/pages/schedule-filter/schedule-filter.scss: -------------------------------------------------------------------------------- 1 | 2 | .reset-filters { 3 | color: color($colors, danger); 4 | } 5 | 6 | @each $track, $value in auxiliary-categories() { 7 | 8 | ion-item[track=#{$track}] .dot { 9 | height: 10px; 10 | display: inline-block; 11 | width: 10px; 12 | background-color: $value; 13 | border-radius: 5px; 14 | margin-right: 10px; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /app/pages/tabs/tabs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/pages/speaker-list/speaker-list.scss: -------------------------------------------------------------------------------- 1 | 2 | .speaker-list { 3 | 4 | ion-card.speaker ion-card-header .item { 5 | padding: 12px; 6 | } 7 | 8 | ion-card.speaker ion-card-content .list { 9 | margin: 0; 10 | } 11 | 12 | ion-card.speaker ion-card-header, 13 | ion-card.speaker ion-card-content, 14 | ion-card.speaker ion-card-content .list ion-item-content, { 15 | padding: 0; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /app/pages/session-detail/session-detail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Session 4 | 5 | 6 | 7 | 8 |

{{session.name}}

9 | 10 |

11 | {{speaker.name}} 12 |

13 | 14 |

15 | {{session.timeStart}} - {{session.timeEnd}} 16 |

17 | 18 |

{{session.location}}

19 | 20 |

{{session.description}}

21 |
22 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | # Change these settings to your own preference 10 | indent_style = space 11 | indent_size = 2 12 | 13 | # We recommend you to keep these unchanged 14 | end_of_line = lf 15 | charset = utf-8 16 | trim_trailing_whitespace = true 17 | insert_final_newline = true 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /app/scss/index.scss: -------------------------------------------------------------------------------- 1 | @import 'variables'; 2 | @import '~ionic-angular/ionic'; 3 | @import '~ionicons/dist/scss/ionicons'; 4 | 5 | @import "../pages/about/about"; 6 | 7 | @import "../pages/account/account"; 8 | 9 | @import "../pages/login/login"; 10 | 11 | @import "../pages/map/map"; 12 | 13 | @import "../pages/schedule/schedule"; 14 | 15 | @import "../pages/schedule-filter/schedule-filter"; 16 | 17 | @import "../pages/speaker-detail/speaker-detail"; 18 | 19 | @import "../pages/speaker-list/speaker-list"; 20 | 21 | @import "../pages/tutorial/tutorial"; -------------------------------------------------------------------------------- /app/pages/tutorial/tutorial.scss: -------------------------------------------------------------------------------- 1 | 2 | .tutorial-page { 3 | .toolbar-background { 4 | background: #fff; 5 | border-color: transparent; 6 | } 7 | 8 | .slide-zoom { 9 | height: 100%; 10 | } 11 | 12 | .slide-title { 13 | margin-top: 2.8rem; 14 | } 15 | 16 | .slide-image { 17 | max-height: 50%; 18 | max-width: 60%; 19 | margin: 36px 0; 20 | } 21 | 22 | b { 23 | font-weight: 500; 24 | } 25 | 26 | p { 27 | padding: 0 40px; 28 | font-size: 14px; 29 | line-height: 1.5; 30 | color: #60646B; 31 | 32 | b { 33 | color: #000000; 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "removeComments": true, 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true 9 | }, 10 | "awesomeTypescriptLoaderOptions": { 11 | "useWebpackText": true //Allows loaders to be chained to awesome-typescript-loader. 12 | }, 13 | "files": [ 14 | "app/index.ts", 15 | "typings/index.d.ts", 16 | "typings/commonjs.d.ts", 17 | "typings/webpack.d.ts" 18 | ], 19 | "compileOnSave": false, 20 | "atom": { 21 | "rewriteTsconfig": false 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/pages/schedule/schedule.scss: -------------------------------------------------------------------------------- 1 | $categories: ( 2 | ionic: color($colors, primary), 3 | angular: #AC282B, 4 | communication: #8E8D93, 5 | tooling: #FE4C52, 6 | services: #FD8B2D, 7 | design: #FED035, 8 | workshop: #69BB7B, 9 | food: #3BC7C4, 10 | documentation: #B16BE3, 11 | navigation: #6600CC, 12 | ); 13 | 14 | @function auxiliary-categories() { 15 | @return map-remove($categories); 16 | } 17 | 18 | .schedule-page { 19 | @each $track, $value in auxiliary-categories() { 20 | ion-item-sliding[track=#{$track}] ion-label { 21 | border-left: 2px solid $value; 22 | padding-left: 10px; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/pages/speaker-detail/speaker-detail.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { NavController, NavParams, Page } from 'ionic-angular'; 4 | 5 | import { SessionDetailPage } from '../session-detail/session-detail'; 6 | 7 | 8 | @Component({ 9 | templateUrl: 'speaker-detail.html' 10 | }) 11 | export class SpeakerDetailPage { 12 | speaker: any; 13 | 14 | constructor( 15 | private nav: NavController, 16 | private navParams: NavParams 17 | ) { 18 | this.speaker = this.navParams.data; 19 | } 20 | 21 | goToSessionDetail(session) { 22 | this.nav.push(SessionDetailPage, session); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/pages/speaker-detail/speaker-detail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{speaker.name}} 4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 | 12 | 13 | 14 | 15 |
16 | 17 |

{{speaker.about}}

18 | 19 |
20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | platforms 29 | plugins -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This project is a Fork of that uses Webpack and TypeScript. 2 | 3 | It is the perfect Boilerplate to start an app in no time. 4 | 5 | ## Prerequisites 6 | 7 | * Ionic CLI `npm - ionic@beta --global` 8 | * Cordova CLI 9 | * Typings CLI 10 | 11 | ## Installation 12 | 13 | ``` 14 | npm install && ionic state restore 15 | ``` 16 | 17 | ## Project public API 18 | 19 | ``` 20 | # Dev server 21 | npm start 22 | 23 | # Dump files in www 24 | npm run dumpdev 25 | npm run dumpprod 26 | 27 | # Run Cordova 28 | npm run android 29 | npm run ios 30 | npm run iosEmulator 31 | 32 | # Webpack bundle analyser 33 | npm run analyze 34 | ``` 35 | -------------------------------------------------------------------------------- /app/pages/signup/signup.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { NavController } from 'ionic-angular'; 4 | 5 | import { TabsPage } from '../tabs/tabs'; 6 | import { UserData } from '../../providers/user-data'; 7 | 8 | 9 | @Component({ 10 | templateUrl: 'signup.html' 11 | }) 12 | export class SignupPage { 13 | signup: { username?: string, password?: string } = {}; 14 | submitted = false; 15 | 16 | constructor( 17 | private nav: NavController, 18 | private userData: UserData 19 | ) { } 20 | 21 | onSignup(form) { 22 | this.submitted = true; 23 | 24 | if (form.valid) { 25 | this.userData.signup(this.signup.username); 26 | this.nav.push(TabsPage); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/pages/about/about.scss: -------------------------------------------------------------------------------- 1 | .about-header { 2 | background-color: #434954; 3 | padding: 16px; 4 | width: 100%; 5 | min-height: 150px; 6 | text-align: center; 7 | } 8 | 9 | .about-header img { 10 | max-width: 200px; 11 | min-height: 115px; 12 | margin-left: -15px; 13 | padding: 25px 0 20px 0; 14 | } 15 | 16 | .about-info p { 17 | color: #697072; 18 | text-align: left; 19 | } 20 | 21 | .about-info ion-icon { 22 | color: color($colors, primary); 23 | width: 20px; 24 | } 25 | 26 | .md, 27 | .wp { 28 | .about-info [text-right] { 29 | margin-right: 0; 30 | } 31 | } 32 | 33 | .ios .about-info { 34 | text-align: center; 35 | } 36 | 37 | .ios .about-info ion-icon { 38 | width: auto; 39 | margin-right: 10px; 40 | } 41 | -------------------------------------------------------------------------------- /app/pages/tabs/tabs.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { NavParams } from 'ionic-angular'; 4 | 5 | import { AboutPage } from '../about/about'; 6 | import { MapPage } from '../map/map'; 7 | import { SchedulePage } from '../schedule/schedule'; 8 | import { SpeakerListPage } from '../speaker-list/speaker-list'; 9 | 10 | 11 | @Component({ 12 | templateUrl: 'tabs.html' 13 | }) 14 | export class TabsPage { 15 | // set the root pages for each tab 16 | tab1Root: any = SchedulePage; 17 | tab2Root: any = SpeakerListPage; 18 | tab3Root: any = MapPage; 19 | tab4Root: any = AboutPage; 20 | mySelectedIndex: number; 21 | 22 | constructor(navParams: NavParams) { 23 | this.mySelectedIndex = navParams.data.tabIndex || 0; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/pages/account/account.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | Account 7 | 8 | 9 | 10 | 11 |
12 | 13 |

{{username}}

14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |
23 | -------------------------------------------------------------------------------- /app/pages/login/login.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { NavController } from 'ionic-angular'; 4 | 5 | import { SignupPage } from '../signup/signup'; 6 | import { TabsPage } from '../tabs/tabs'; 7 | import { UserData } from '../../providers/user-data'; 8 | 9 | 10 | @Component({ 11 | templateUrl: 'login.html' 12 | }) 13 | export class LoginPage { 14 | login: { username?: string, password?: string } = {}; 15 | submitted = false; 16 | 17 | constructor( 18 | private nav: NavController, 19 | private userData: UserData 20 | ) { } 21 | 22 | onLogin(form) { 23 | this.submitted = true; 24 | 25 | if (form.valid) { 26 | this.userData.login(this.login.username); 27 | this.nav.push(TabsPage); 28 | } 29 | } 30 | 31 | onSignup() { 32 | this.nav.push(SignupPage); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/pages/tutorial/tutorial.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

14 |

15 |
16 | 17 | 18 |

Ready to Play?

19 | 23 |
24 |
25 |
26 | -------------------------------------------------------------------------------- /app/pages/schedule-filter/schedule-filter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Filter Sessions 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Tracks 21 | 22 | 23 | 24 | {{track.name}} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/pages/about/about.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { PopoverController, ViewController } from 'ionic-angular'; 4 | 5 | 6 | @Component({ 7 | template: ` 8 | 9 | 10 | 11 | 12 | 13 | 14 | ` 15 | }) 16 | class PopoverPage { 17 | 18 | constructor(private viewCtrl: ViewController) { 19 | 20 | } 21 | 22 | close() { 23 | this.viewCtrl.dismiss(); 24 | } 25 | } 26 | 27 | 28 | @Component({ 29 | templateUrl: 'about.html' 30 | }) 31 | export class AboutPage { 32 | conferenceDate = '2047-05-17'; 33 | 34 | constructor( 35 | private popoverCtrl: PopoverController 36 | ) { } 37 | 38 | presentPopover(event) { 39 | let popover = this.popoverCtrl.create(PopoverPage); 40 | popover.present({ ev: event }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ionic Conference 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/scss/_variables.scss: -------------------------------------------------------------------------------- 1 | // http://ionicframework.com/docs/v2/theming/ 2 | 3 | // Ionic Shared Functions 4 | // -------------------------------------------------- 5 | // Makes Ionic Sass functions available to your App 6 | 7 | // @import 'globals.core'; 8 | 9 | 10 | // App Shared Color Variables 11 | // -------------------------------------------------- 12 | // It's highly recommended to change the default colors 13 | // to match your app's branding. Ionic uses a Sass map of 14 | // colors so you can add, rename and remove colors as needed. 15 | // The "primary" color is the only required color in the map. 16 | // Both iOS and MD colors can be further customized if colors 17 | // are different per mode. 18 | 19 | $colors: ( 20 | primary: #387ef5, 21 | secondary: #32db64, 22 | danger: #f53d3d, 23 | light: #f4f4f4, 24 | dark: #222, 25 | favorite: #69BB7B, 26 | twitter: #53ACEB, 27 | github: #000000, 28 | instagram: #235D8D 29 | ); 30 | // $ionicons: false; 31 | $font-path: '~ionic-angular/fonts'; 32 | $ionicons-font-path: '~ionicons/dist/fonts'; -------------------------------------------------------------------------------- /app/images/appicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 11 | 12 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/pages/map/map.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { Page } from 'ionic-angular'; 4 | 5 | import { ConferenceData } from '../../providers/conference-data'; 6 | 7 | 8 | @Component({ 9 | templateUrl: 'map.html' 10 | }) 11 | export class MapPage { 12 | constructor(private confData: ConferenceData) {} 13 | 14 | ionViewLoaded() { 15 | this.confData.getMap().then(mapData => { 16 | let mapEle = document.getElementById('map'); 17 | 18 | let map = new google.maps.Map(mapEle, { 19 | center: mapData.find(d => d.center), 20 | zoom: 16 21 | }); 22 | 23 | mapData.forEach(markerData => { 24 | let infoWindow = new google.maps.InfoWindow({ 25 | content: `
${markerData.name}
` 26 | }); 27 | 28 | let marker = new google.maps.Marker({ 29 | position: markerData, 30 | map: map, 31 | title: markerData.name 32 | }); 33 | 34 | marker.addListener('click', () => { 35 | infoWindow.open(map, marker); 36 | }); 37 | }); 38 | 39 | google.maps.event.addListenerOnce(map, 'idle', () => { 40 | mapEle.classList.add('show-map'); 41 | }); 42 | 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/pages/signup/signup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | Signup 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 |
18 | 19 | Username 20 | 21 | 22 | 23 |

24 | Username is required 25 |

26 | 27 | 28 | Password 29 | 30 | 31 | 32 |

33 | Password is required 34 |

35 | 36 |
37 | 38 |
39 |
40 |
41 | 42 |
43 | -------------------------------------------------------------------------------- /app/pages/speaker-list/speaker-list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | Speakers 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | {{speaker.name}} 19 | 20 | 21 | 22 | 23 | 24 | 27 | 30 | 31 | 32 | 33 | 34 | 38 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/pages/login/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | Login 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 |
18 | 19 | Username 20 | 21 | 22 | 23 |

24 | Username is required 25 |

26 | 27 | 28 | Password 29 | 30 | 31 | 32 |

33 | Password is required 34 |

35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 |
46 | 47 |
48 | -------------------------------------------------------------------------------- /app/pages/schedule-filter/schedule-filter.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { NavParams, ViewController } from 'ionic-angular'; 4 | 5 | import { ConferenceData } from '../../providers/conference-data'; 6 | 7 | 8 | @Component({ 9 | templateUrl: 'schedule-filter.html' 10 | }) 11 | export class ScheduleFilterPage { 12 | tracks: Array<{name: string, isChecked: boolean}> = []; 13 | 14 | constructor( 15 | private confData: ConferenceData, 16 | private navParams: NavParams, 17 | private viewCtrl: ViewController 18 | ) { 19 | // passed in array of track names that should be excluded (unchecked) 20 | let excludedTrackNames = this.navParams.data; 21 | 22 | this.confData.getTracks().then((trackNames: string[]) => { 23 | 24 | trackNames.forEach(trackName => { 25 | this.tracks.push({ 26 | name: trackName, 27 | isChecked: (excludedTrackNames.indexOf(trackName) === -1) 28 | }); 29 | }); 30 | 31 | }); 32 | } 33 | 34 | resetFilters() { 35 | // reset all of the toggles to be checked 36 | this.tracks.forEach(track => { 37 | track.isChecked = true; 38 | }); 39 | } 40 | 41 | applyFilters() { 42 | // Pass back a new array of track names to exclude 43 | let excludedTrackNames = this.tracks.filter(c => !c.isChecked).map(c => c.name); 44 | this.dismiss(excludedTrackNames); 45 | } 46 | 47 | dismiss(data) { 48 | // using the injected ViewController this page 49 | // can "dismiss" itself and pass back data 50 | this.viewCtrl.dismiss(data); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/pages/about/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | About 7 | 8 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 |
19 |
20 |

Ionic Conference

21 | 22 | 23 | 24 | 25 | Date 26 | 27 | 28 | 29 | 30 | 31 | Location 32 | Madison, WI 33 | 34 | 35 | 36 |

37 | The Ionic Conference is a one-day conference featuring talks from the 38 | Ionic team. It is focused on Ionic applications being built with 39 | Ionic 2. This includes migrating apps from Ionic 1 to Ionic 2, 40 | Angular concepts, Webpack, Sass, and many other technologies used 41 | in Ionic 2. Tickets are completely sold out, and we’re expecting 42 | more than 1000 developers – making this the largest Ionic 43 | conference ever! 44 |

45 |
46 |
47 | -------------------------------------------------------------------------------- /app/providers/user-data.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { Events, LocalStorage, Storage } from 'ionic-angular'; 4 | 5 | 6 | @Injectable() 7 | export class UserData { 8 | _favorites = []; 9 | HAS_LOGGED_IN = 'hasLoggedIn'; 10 | storage = new Storage(LocalStorage); 11 | 12 | constructor(private events: Events) {} 13 | 14 | hasFavorite(sessionName) { 15 | return (this._favorites.indexOf(sessionName) > -1); 16 | } 17 | 18 | addFavorite(sessionName) { 19 | this._favorites.push(sessionName); 20 | } 21 | 22 | removeFavorite(sessionName) { 23 | let index = this._favorites.indexOf(sessionName); 24 | if (index > -1) { 25 | this._favorites.splice(index, 1); 26 | } 27 | } 28 | 29 | login(username) { 30 | this.storage.set(this.HAS_LOGGED_IN, true); 31 | this.setUsername(username); 32 | this.events.publish('user:login'); 33 | } 34 | 35 | signup(username) { 36 | this.storage.set(this.HAS_LOGGED_IN, true); 37 | this.setUsername(username); 38 | this.events.publish('user:signup'); 39 | } 40 | 41 | logout() { 42 | this.storage.remove(this.HAS_LOGGED_IN); 43 | this.storage.remove('username'); 44 | this.events.publish('user:logout'); 45 | } 46 | 47 | setUsername(username) { 48 | this.storage.set('username', username); 49 | } 50 | 51 | getUsername() { 52 | return this.storage.get('username').then((value) => { 53 | return value; 54 | }); 55 | } 56 | 57 | // return a promise 58 | hasLoggedIn() { 59 | return this.storage.get(this.HAS_LOGGED_IN).then((value) => { 60 | return value; 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/pages/account/account.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { AlertController, NavController } from 'ionic-angular'; 4 | 5 | import { LoginPage } from '../login/login'; 6 | import { UserData } from '../../providers/user-data'; 7 | 8 | 9 | @Component({ 10 | templateUrl: 'account.html', 11 | }) 12 | export class AccountPage { 13 | username: string; 14 | 15 | constructor( 16 | public nav: NavController, 17 | public alertCtrl: AlertController, 18 | private userData: UserData 19 | ) { } 20 | 21 | ngAfterViewInit() { 22 | this.getUsername(); 23 | } 24 | 25 | updatePicture() { 26 | console.log('Clicked to update picture'); 27 | } 28 | 29 | // Present an alert with the current username populated 30 | // clicking OK will update the username and display it 31 | // clicking Cancel will close the alert and do nothing 32 | changeUsername() { 33 | let alert = this.alertCtrl.create({ 34 | title: 'Change Username', 35 | buttons: [ 36 | 'Cancel' 37 | ] 38 | }); 39 | alert.addInput({ 40 | name: 'username', 41 | value: this.username, 42 | placeholder: 'username' 43 | }); 44 | alert.addButton({ 45 | text: 'Ok', 46 | handler: data => { 47 | this.userData.setUsername(data.username); 48 | this.getUsername(); 49 | } 50 | }); 51 | 52 | alert.present(); 53 | } 54 | 55 | getUsername() { 56 | this.userData.getUsername().then((username) => { 57 | this.username = username; 58 | }); 59 | } 60 | 61 | changePassword() { 62 | console.log('Clicked to change password'); 63 | } 64 | 65 | logout() { 66 | this.userData.logout(); 67 | this.nav.setRoot(LoginPage); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Menu 7 | 8 | 9 | 10 | 11 | 12 | 13 | Navigate 14 | 15 | 19 | 20 | 21 | 22 | 23 | Account 24 | 25 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Menu 39 | 40 | 41 | 42 | 43 | 44 | 45 | Navigate 46 | 47 | 51 | 52 | 53 | 54 | 55 | Account 56 | 57 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /app/pages/tutorial/tutorial.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { MenuController, NavController } from 'ionic-angular'; 4 | 5 | import { SignupPage } from '../signup/signup'; 6 | import { TabsPage } from '../tabs/tabs'; 7 | 8 | interface Slide { 9 | title: string; 10 | description: string; 11 | image: string; 12 | } 13 | 14 | @Component({ 15 | templateUrl: 'tutorial.html' 16 | }) 17 | export class TutorialPage { 18 | slides: Slide[]; 19 | showSkip = true; 20 | 21 | constructor( 22 | private nav: NavController, 23 | private menu: MenuController 24 | ) { 25 | this.slides = [ 26 | { 27 | title: 'Welcome to ICA', 28 | description: 'The Ionic Conference App is a practical preview of the Ionic Framework in action, and a demonstration of proper code use.', 29 | image: require('../../images/ica-slidebox-img-1.png'), 30 | }, 31 | { 32 | title: 'What is Ionic?', 33 | description: 'Ionic Framework is an open source SDK that enables developers to build high quality mobile apps with web technologies like HTML, CSS, and JavaScript.', 34 | image: require('../../images/ica-slidebox-img-2.png'), 35 | }, 36 | { 37 | title: 'What is Ionic Platform?', 38 | description: 'The Ionic Platform is a cloud platform for managing and scaling Ionic apps with integrated services like push notifications, native builds, user auth, and live updating.', 39 | image: require('../../images/ica-slidebox-img-3.png'), 40 | } 41 | ]; 42 | } 43 | 44 | startApp() { 45 | this.nav.push(TabsPage); 46 | } 47 | 48 | onSlideChangeStart(slider) { 49 | this.showSkip = !slider.isEnd; 50 | } 51 | 52 | ionViewDidEnter() { 53 | // the root left menu should be disabled on the tutorial page 54 | this.menu.enable(false); 55 | } 56 | 57 | ionViewWillLeave() { 58 | // enable the root left menu when leaving the tutorial page 59 | this.menu.enable(true); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /app/pages/speaker-list/speaker-list.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { ActionSheetController, NavController, Page } from 'ionic-angular'; 4 | 5 | import { ConferenceData } from '../../providers/conference-data'; 6 | import { SessionDetailPage } from '../session-detail/session-detail'; 7 | import { SpeakerDetailPage } from '../speaker-detail/speaker-detail'; 8 | 9 | 10 | @Component({ 11 | templateUrl: 'speaker-list.html' 12 | }) 13 | export class SpeakerListPage { 14 | speakers = []; 15 | 16 | constructor( 17 | private nav: NavController, 18 | private actionSheetCtrl: ActionSheetController, 19 | confData: ConferenceData 20 | ) { 21 | confData.getSpeakers().then(speakers => { 22 | this.speakers = speakers; 23 | }); 24 | } 25 | 26 | goToSessionDetail(session) { 27 | this.nav.push(SessionDetailPage, session); 28 | } 29 | 30 | goToSpeakerDetail(speakerName: string) { 31 | this.nav.push(SpeakerDetailPage, speakerName); 32 | } 33 | 34 | goToSpeakerTwitter(speaker) { 35 | window.open(`https://twitter.com/${speaker.twitter}`); 36 | } 37 | 38 | openSpeakerShare(speaker) { 39 | let actionSheet = this.actionSheetCtrl.create({ 40 | title: 'Share ' + speaker.name, 41 | buttons: [ 42 | { 43 | text: 'Copy Link', 44 | handler: () => { 45 | console.log('Copy link clicked on https://twitter.com/' + speaker.twitter); 46 | if (window['cordova'] && window['cordova'].plugins.clipboard) { 47 | window['cordova'].plugins.clipboard.copy('https://twitter.com/' + speaker.twitter); 48 | } 49 | } 50 | }, 51 | { 52 | text: 'Share via ...', 53 | handler: () => { 54 | console.log('Share via clicked'); 55 | } 56 | }, 57 | { 58 | text: 'Cancel', 59 | role: 'cancel', 60 | handler: () => { 61 | console.log('Cancel clicked'); 62 | } 63 | } 64 | ] 65 | }); 66 | 67 | actionSheet.present(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/pages/schedule/schedule.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | All 10 | 11 | 12 | Favorites 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | {{group.time}} 39 | 40 | 41 | 42 | 43 | 51 | 52 | 53 | 56 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | No Sessions Found 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /app/images/ionic-logo-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 13 | 16 | 17 | 21 | 22 | 23 | 24 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let path = require('path'), 4 | webpack = require('webpack'), 5 | pkg = require('./package.json'), 6 | ExtractTextPlugin = require("extract-text-webpack-plugin"), 7 | HtmlWebpackPlugin = require('html-webpack-plugin'); 8 | 9 | 10 | let paths = { 11 | www: path.join(__dirname, 'www'), 12 | src: path.join(__dirname, 'app') 13 | } 14 | let devtool = '#cheap-eval-source-map'; 15 | let appEntries = []; 16 | let baseAppEntries = [ 17 | path.join(paths.src, 'app') 18 | ]; 19 | 20 | let devAppEntries = [ 21 | 'webpack-dev-server/client', 22 | 'webpack/hot/only-dev-server' 23 | ]; 24 | 25 | let plugins = []; 26 | let basePlugins = [ 27 | new webpack.optimize.OccurrenceOrderPlugin(), 28 | new webpack.DefinePlugin({ 29 | __DEV__: process.env.NODE_ENV !== 'production', 30 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) 31 | }), 32 | new HtmlWebpackPlugin({ 33 | template: path.join(paths.src, 'index.html'), 34 | inject: 'body' 35 | }), 36 | new ExtractTextPlugin("styles.[hash].css") 37 | ]; 38 | 39 | let devPlugins = [ 40 | new webpack.HotModuleReplacementPlugin(), 41 | new webpack.NoErrorsPlugin(), 42 | ]; 43 | 44 | let prodPlugins = [ 45 | new webpack.optimize.UglifyJsPlugin({ 46 | sourceMap: false, 47 | compress: { 48 | warnings: false 49 | } 50 | }) 51 | ]; 52 | 53 | if (process.env.NODE_ENV === 'production') { 54 | plugins = basePlugins.concat(prodPlugins); 55 | appEntries = baseAppEntries.concat([]); 56 | devtool = '#source-map'; 57 | } else { // dev or rest 58 | plugins = basePlugins.concat(devPlugins); 59 | appEntries = baseAppEntries.concat(devAppEntries); 60 | } 61 | 62 | module.exports = { 63 | entry: { 64 | app: appEntries, 65 | polyfills: [ 66 | 'core-js', 67 | 'reflect-metadata', 68 | 'zone.js' 69 | ], 70 | vendors: [ 71 | '@angular/core', 72 | 'rxjs' 73 | ], 74 | style: path.join(paths.src, 'scss', 'index.scss') 75 | }, 76 | output: { 77 | path: paths.www, 78 | filename: '[name].[hash].js' 79 | }, 80 | devtool: devtool, 81 | resolve: { 82 | extensions: ['', '.ts', '.js', '.html', '.scss', '.png'], 83 | moduleDirectories: [ 84 | 'node_modules', 85 | 'node_modules/ionic-angular', 86 | 'node_modules/ionicons/dist/scss/' 87 | ] 88 | }, 89 | plugins: plugins, 90 | module: { 91 | preLoaders: [ 92 | // loaders.tslint, 93 | ], 94 | loaders: [ 95 | { 96 | test: /\.ts$/, 97 | exclude: /(node_modules)/, 98 | loaders: ['awesome-typescript-loader', 'angular2-template-loader'], 99 | include: paths.src 100 | }, { 101 | test: /\.json$/, 102 | loader: "json" 103 | }, { 104 | test: /\.(png|jpg|svg)$/, 105 | loader: 'file?name=img/[ext]/[name].[ext]' 106 | }, { 107 | test: /\.scss$/, 108 | loader: ExtractTextPlugin.extract(["css", "autoprefixer", "sass"]) 109 | }, { 110 | test: /\.html$/, 111 | loader: 'html' 112 | }, { 113 | test: [/ionicons\.svg/, /ionicons\.eot/, /ionicons\.ttf/, /ionicons\.woff/, /roboto-bold\.woff/, /roboto-medium\.woff/, /roboto-light\.woff/, /roboto-regular\.woff/, /roboto-bold\.ttf/, /roboto-medium\.ttf/, /roboto-light\.ttf/, /roboto-regular\.ttf/, /noto-sans-bold\.ttf/, /noto-sans-regular\.ttf/], 114 | loader: 'file?name=fonts/[name].[ext]' 115 | } 116 | ] 117 | }, 118 | sassLoader: { 119 | includePaths: [ 120 | "node_modules/ionic-angular", 121 | "node_modules/ionicons/dist/scss" 122 | ] 123 | } 124 | }; 125 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic2-webpack-boilerplate", 3 | "version": "1.0.0", 4 | "description": "TypeScript and Webpack port of driftyco/ionic-conference-app conference app", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "better-npm-run start", 8 | "analyze": "better-npm-run analyze", 9 | "dumpprod": "better-npm-run dumpprod", 10 | "dumpdev": "better-npm-run dumpdev", 11 | "restore": "ionic state restore", 12 | "postinstall": "typings install", 13 | "android": "npm run dumpdev && cordova run android", 14 | "iosEmulator": "npm run dumpdev && cordova run ios", 15 | "ios": "npm run dumpdev && cordova run ios --device" 16 | }, 17 | "betterScripts": { 18 | "start": { 19 | "command": "webpack-dev-server -d --hot --progress", 20 | "env": { 21 | "NODE_ENV": "development" 22 | } 23 | }, 24 | "webpack": { 25 | "command": "rm -rf www/* && webpack --progress" 26 | }, 27 | "dumpdev": { 28 | "command": "better-npm-run webpack", 29 | "env": { 30 | "NODE_ENV": "development" 31 | } 32 | }, 33 | "dumpprod": { 34 | "command": "better-npm-run webpack", 35 | "env": { 36 | "NODE_ENV": "production" 37 | } 38 | }, 39 | "analyze": { 40 | "command": "rm -rf www/* && webpack --progress --json | webpack-bundle-size-analyzer", 41 | "env": { 42 | "NODE_ENV": "development" 43 | } 44 | } 45 | }, 46 | "repository": { 47 | "type": "git", 48 | "url": "git+ssh://git@github.com/shprink/ionic2-webpack-boilerplate.git" 49 | }, 50 | "keywords": [ 51 | "ionic", 52 | "ionic2", 53 | "webpack", 54 | "es6", 55 | "es2015", 56 | "typescript" 57 | ], 58 | "author": "shprink (http://julienrenaux.fr/)", 59 | "license": "MIT", 60 | "bugs": { 61 | "url": "https://github.com/shprink/ionic2-webpack-boilerplate/issues" 62 | }, 63 | "homepage": "https://github.com/shprink/ionic2-webpack-boilerplate#readme", 64 | "devDependencies": { 65 | "angular2-template-loader": "^0.4.0", 66 | "autoprefixer-loader": "^3.2.0", 67 | "awesome-typescript-loader": "^0.17.0-rc.5", 68 | "better-npm-run": "0.0.8", 69 | "css-loader": "^0.23.1", 70 | "extract-text-webpack-plugin": "^1.0.1", 71 | "file-loader": "^0.8.5", 72 | "html-loader": "^0.4.3", 73 | "html-webpack-plugin": "^2.15.0", 74 | "json-loader": "^0.5.4", 75 | "node-sass": "^3.4.2", 76 | "path": "^0.12.7", 77 | "sass-loader": "^3.2.0", 78 | "style-loader": "^0.13.1", 79 | "typescript": "^1.8.10", 80 | "webpack": "^1.13.1", 81 | "webpack-bundle-size-analyzer": "^2.0.1", 82 | "webpack-dev-server": "^1.14.1" 83 | }, 84 | "dependencies": { 85 | "@angular/common": "2.0.0-rc.4", 86 | "@angular/compiler": "2.0.0-rc.4", 87 | "@angular/core": "2.0.0-rc.4", 88 | "@angular/forms": "0.2.0", 89 | "@angular/http": "2.0.0-rc.4", 90 | "@angular/platform-browser": "2.0.0-rc.4", 91 | "@angular/platform-browser-dynamic": "2.0.0-rc.4", 92 | "@angular/router": "^2.0.0-rc.2", 93 | "core-js": "^2.4.1", 94 | "es5-shim": "^4.5.8", 95 | "es6-promise": "^3.1.2", 96 | "es6-shim": "^0.35.0", 97 | "ionic-angular": "2.0.0-beta.11", 98 | "ionic-native": "^1.1.1", 99 | "ionicons": "^3.0.0", 100 | "reflect-metadata": "^0.1.3", 101 | "rxjs": "5.0.0-beta.6", 102 | "zone.js": "0.6.12" 103 | }, 104 | "cordovaPlugins": [ 105 | "cordova-plugin-whitelist", 106 | { 107 | "locator": "https://github.com/VersoSolutions/CordovaClipboard", 108 | "id": "com.verso.cordova.clipboard" 109 | } 110 | ], 111 | "cordovaPlatforms": [ 112 | "ios", 113 | "android" 114 | ] 115 | } 116 | -------------------------------------------------------------------------------- /app/app.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewChild } from '@angular/core'; 2 | 3 | import { Events, ionicBootstrap, MenuController, Nav, Platform } from 'ionic-angular'; 4 | import { Splashscreen, StatusBar } from 'ionic-native'; 5 | 6 | import { AccountPage } from './pages/account/account'; 7 | import { ConferenceData } from './providers/conference-data'; 8 | import { LoginPage } from './pages/login/login'; 9 | import { SignupPage } from './pages/signup/signup'; 10 | import { TabsPage } from './pages/tabs/tabs'; 11 | import { TutorialPage } from './pages/tutorial/tutorial'; 12 | import { UserData } from './providers/user-data'; 13 | 14 | interface PageObj { 15 | title: string; 16 | component: any; 17 | icon: string; 18 | index?: number; 19 | } 20 | 21 | @Component({ 22 | templateUrl: 'app.html' 23 | }) 24 | class ConferenceApp { 25 | // the root nav is a child of the root app component 26 | // @ViewChild(Nav) gets a reference to the app's root nav 27 | @ViewChild(Nav) nav: Nav; 28 | 29 | // List of pages that can be navigated to from the left menu 30 | // the left menu only works after login 31 | // the login page disables the left menu 32 | appPages: PageObj[] = [ 33 | { title: 'Schedule', component: TabsPage, icon: 'calendar' }, 34 | { title: 'Speakers', component: TabsPage, index: 1, icon: 'contacts' }, 35 | { title: 'Map', component: TabsPage, index: 2, icon: 'map' }, 36 | { title: 'About', component: TabsPage, index: 3, icon: 'information-circle' }, 37 | ]; 38 | loggedInPages: PageObj[] = [ 39 | { title: 'Account', component: AccountPage, icon: 'person' }, 40 | { title: 'Logout', component: TabsPage, icon: 'log-out' } 41 | ]; 42 | loggedOutPages: PageObj[] = [ 43 | { title: 'Login', component: LoginPage, icon: 'log-in' }, 44 | { title: 'Signup', component: SignupPage, icon: 'person-add' } 45 | ]; 46 | rootPage: any = TutorialPage; 47 | 48 | constructor( 49 | private events: Events, 50 | private userData: UserData, 51 | private menu: MenuController, 52 | platform: Platform, 53 | confData: ConferenceData 54 | ) { 55 | // Call any initial plugins when ready 56 | platform.ready().then(() => { 57 | StatusBar.styleDefault(); 58 | Splashscreen.hide(); 59 | }); 60 | 61 | // load the conference data 62 | confData.load(); 63 | 64 | // decide which menu items should be hidden by current login status stored in local storage 65 | this.userData.hasLoggedIn().then((hasLoggedIn) => { 66 | this.enableMenu(hasLoggedIn === 'true'); 67 | }); 68 | 69 | this.listenToLoginEvents(); 70 | } 71 | 72 | openPage(page: PageObj) { 73 | // the nav component was found using @ViewChild(Nav) 74 | // reset the nav to remove previous pages and only have this page 75 | // we wouldn't want the back button to show in this scenario 76 | if (page.index) { 77 | this.nav.setRoot(page.component, {tabIndex: page.index}); 78 | 79 | } else { 80 | this.nav.setRoot(page.component); 81 | } 82 | 83 | if (page.title === 'Logout') { 84 | // Give the menu time to close before changing to logged out 85 | setTimeout(() => { 86 | this.userData.logout(); 87 | }, 1000); 88 | } 89 | } 90 | 91 | listenToLoginEvents() { 92 | this.events.subscribe('user:login', () => { 93 | this.enableMenu(true); 94 | }); 95 | 96 | this.events.subscribe('user:signup', () => { 97 | this.enableMenu(true); 98 | }); 99 | 100 | this.events.subscribe('user:logout', () => { 101 | this.enableMenu(false); 102 | }); 103 | } 104 | 105 | enableMenu(loggedIn) { 106 | this.menu.enable(loggedIn, 'loggedInMenu'); 107 | this.menu.enable(!loggedIn, 'loggedOutMenu'); 108 | } 109 | } 110 | 111 | 112 | // Pass the main App component as the first argument 113 | // Pass any providers for your app in the second argument 114 | // Set any config for your app as the third argument, see the docs for 115 | // more ways to configure your app: 116 | // http://ionicframework.com/docs/v2/api/config/Config/ 117 | // Place the tabs on the bottom for all platforms 118 | // See the theming docs for the default values: 119 | // http://ionicframework.com/docs/v2/theming/platform-specific-styles/ 120 | 121 | ionicBootstrap(ConferenceApp, [ConferenceData, UserData], { 122 | tabbarPlacement: 'bottom' 123 | }); 124 | -------------------------------------------------------------------------------- /app/pages/schedule/schedule.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewChild } from '@angular/core'; 2 | 3 | import { 4 | AlertController, 5 | App, 6 | ItemSliding, 7 | List, 8 | ModalController, 9 | NavController, 10 | Page 11 | } from 'ionic-angular'; 12 | 13 | import { ConferenceData } from '../../providers/conference-data'; 14 | import { ScheduleFilterPage } from '../schedule-filter/schedule-filter'; 15 | import { SessionDetailPage } from '../session-detail/session-detail'; 16 | import { UserData } from '../../providers/user-data'; 17 | 18 | 19 | @Component({ 20 | templateUrl: 'schedule.html' 21 | }) 22 | export class SchedulePage { 23 | // the list is a child of the schedule page 24 | // @ViewChild('scheduleList') gets a reference to the list 25 | // with the variable #scheduleList, `read: List` tells it to return 26 | // the List and not a reference to the element 27 | @ViewChild('scheduleList', { read: List }) scheduleList: List; 28 | 29 | dayIndex = 0; 30 | queryText = ''; 31 | segment = 'all'; 32 | excludeTracks = []; 33 | shownSessions = []; 34 | groups = []; 35 | 36 | constructor( 37 | private app: App, 38 | private nav: NavController, 39 | public alertCtrl: AlertController, 40 | private confData: ConferenceData, 41 | private user: UserData, 42 | private modalCtrl: ModalController 43 | ) { 44 | 45 | } 46 | 47 | ionViewDidEnter() { 48 | this.app.setTitle('Schedule'); 49 | } 50 | 51 | ngAfterViewInit() { 52 | this.updateSchedule(); 53 | } 54 | 55 | updateSchedule() { 56 | // Close any open sliding items when the schedule updates 57 | this.scheduleList && this.scheduleList.closeSlidingItems(); 58 | 59 | this.confData.getTimeline(this.dayIndex, this.queryText, this.excludeTracks, this.segment).then(data => { 60 | this.shownSessions = data.shownSessions; 61 | this.groups = data.groups; 62 | }); 63 | } 64 | 65 | presentFilter() { 66 | let modal = this.modalCtrl.create(ScheduleFilterPage, this.excludeTracks); 67 | modal.present(); 68 | modal.onDidDismiss((data: any[]) => { 69 | if (data) { 70 | this.excludeTracks = data; 71 | this.updateSchedule(); 72 | } 73 | }); 74 | } 75 | 76 | goToSessionDetail(sessionData) { 77 | // go to the session detail page 78 | // and pass in the session data 79 | this.nav.push(SessionDetailPage, sessionData); 80 | } 81 | 82 | addFavorite(slidingItem: ItemSliding, sessionData) { 83 | 84 | if (this.user.hasFavorite(sessionData.name)) { 85 | // woops, they already favorited it! What shall we do!? 86 | // prompt them to remove it 87 | this.removeFavorite(slidingItem, sessionData, 'Favorite already added'); 88 | } else { 89 | // remember this session as a user favorite 90 | this.user.addFavorite(sessionData.name); 91 | 92 | // create an alert instance 93 | let alert = this.alertCtrl.create({ 94 | title: 'Favorite Added', 95 | buttons: [{ 96 | text: 'OK', 97 | handler: () => { 98 | // close the sliding item 99 | slidingItem.close(); 100 | } 101 | }] 102 | }); 103 | // now present the alert on top of all other content 104 | alert.present(); 105 | } 106 | 107 | } 108 | 109 | removeFavorite(slidingItem: ItemSliding, sessionData, title) { 110 | let alert = this.alertCtrl.create({ 111 | title: title, 112 | message: 'Would you like to remove this session from your favorites?', 113 | buttons: [ 114 | { 115 | text: 'Cancel', 116 | handler: () => { 117 | // they clicked the cancel button, do not remove the session 118 | // close the sliding item and hide the option buttons 119 | slidingItem.close(); 120 | } 121 | }, 122 | { 123 | text: 'Remove', 124 | handler: () => { 125 | // they want to remove this session from their favorites 126 | this.user.removeFavorite(sessionData.name); 127 | this.updateSchedule(); 128 | 129 | // close the sliding item and hide the option buttons 130 | slidingItem.close(); 131 | } 132 | } 133 | ] 134 | }); 135 | // now present the alert on top of all other content 136 | alert.present(); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Ionic Conference 4 | 5 | An Ionic Framework application for the Ionic Conference. 6 | 7 | 8 | Ionic Framework Team 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /app/providers/conference-data.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { Http } from '@angular/http'; 4 | 5 | import { UserData } from './user-data'; 6 | 7 | 8 | @Injectable() 9 | export class ConferenceData { 10 | data: any; 11 | 12 | constructor(private http: Http, private user: UserData) { } 13 | 14 | load() { 15 | if (this.data) { 16 | // already loaded data 17 | return Promise.resolve(this.data); 18 | } 19 | // don't have the data yet 20 | return Promise.resolve(require('./data.json')); 21 | } 22 | 23 | processData(data) { 24 | // just some good 'ol JS fun with objects and arrays 25 | // build up the data by linking speakers to sessions 26 | 27 | data.tracks = []; 28 | 29 | // loop through each day in the schedule 30 | data.schedule.forEach(day => { 31 | // loop through each timeline group in the day 32 | day.groups.forEach(group => { 33 | // loop through each session in the timeline group 34 | group.sessions.forEach(session => { 35 | this.processSession(data, session); 36 | }); 37 | }); 38 | }); 39 | 40 | return data; 41 | } 42 | 43 | processSession(data, session) { 44 | // loop through each speaker and load the speaker data 45 | // using the speaker name as the key 46 | session.speakers = []; 47 | if (session.speakerNames) { 48 | session.speakerNames.forEach(speakerName => { 49 | let speaker = data.speakers.find(s => s.name === speakerName); 50 | if (speaker) { 51 | session.speakers.push(speaker); 52 | speaker.sessions = speaker.sessions || []; 53 | speaker.sessions.push(session); 54 | } 55 | }); 56 | } 57 | 58 | if (session.tracks) { 59 | session.tracks.forEach(track => { 60 | if (data.tracks.indexOf(track) < 0) { 61 | data.tracks.push(track); 62 | } 63 | }); 64 | } 65 | } 66 | 67 | getTimeline(dayIndex, queryText = '', excludeTracks = [], segment = 'all') { 68 | return this.load().then(data => { 69 | console.log('data', data) 70 | let day = data.schedule[dayIndex]; 71 | day.shownSessions = 0; 72 | 73 | queryText = queryText.toLowerCase().replace(/,|\.|-/g, ' '); 74 | let queryWords = queryText.split(' ').filter(w => !!w.trim().length); 75 | 76 | day.groups.forEach(group => { 77 | group.hide = true; 78 | 79 | group.sessions.forEach(session => { 80 | // check if this session should show or not 81 | this.filterSession(session, queryWords, excludeTracks, segment); 82 | 83 | if (!session.hide) { 84 | // if this session is not hidden then this group should show 85 | group.hide = false; 86 | day.shownSessions++; 87 | } 88 | }); 89 | 90 | }); 91 | 92 | return day; 93 | }); 94 | } 95 | 96 | filterSession(session, queryWords, excludeTracks, segment) { 97 | 98 | let matchesQueryText = false; 99 | if (queryWords.length) { 100 | // of any query word is in the session name than it passes the query test 101 | queryWords.forEach(queryWord => { 102 | if (session.name.toLowerCase().indexOf(queryWord) > -1) { 103 | matchesQueryText = true; 104 | } 105 | }); 106 | } else { 107 | // if there are no query words then this session passes the query test 108 | matchesQueryText = true; 109 | } 110 | 111 | // if any of the sessions tracks are not in the 112 | // exclude tracks then this session passes the track test 113 | let matchesTracks = false; 114 | session.tracks.forEach(trackName => { 115 | if (excludeTracks.indexOf(trackName) === -1) { 116 | matchesTracks = true; 117 | } 118 | }); 119 | 120 | // if the segement is 'favorites', but session is not a user favorite 121 | // then this session does not pass the segment test 122 | let matchesSegment = false; 123 | if (segment === 'favorites') { 124 | if (this.user.hasFavorite(session.name)) { 125 | matchesSegment = true; 126 | } 127 | } else { 128 | matchesSegment = true; 129 | } 130 | 131 | // all tests must be true if it should not be hidden 132 | session.hide = !(matchesQueryText && matchesTracks && matchesSegment); 133 | } 134 | 135 | getSpeakers() { 136 | return this.load().then(data => { 137 | return data.speakers.sort((a, b) => { 138 | let aName = a.name.split(' ').pop(); 139 | let bName = b.name.split(' ').pop(); 140 | return aName.localeCompare(bName); 141 | }); 142 | }); 143 | } 144 | 145 | getTracks() { 146 | return this.load().then(data => { 147 | return data.tracks.sort(); 148 | }); 149 | } 150 | 151 | getMap() { 152 | return this.load().then(data => { 153 | return data.map; 154 | }); 155 | } 156 | 157 | } 158 | -------------------------------------------------------------------------------- /app/providers/data.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "schedule": [ 4 | { 5 | "date": "2047-05-17", 6 | "groups": [ 7 | { 8 | "time": "8:00 am", 9 | "sessions": [ 10 | { 11 | "name": "Breakfast", 12 | "timeStart": "8:00 am", 13 | "timeEnd": "9:00 am", 14 | "location": "Main hallway", 15 | "tracks": ["Food"] 16 | } 17 | ] 18 | }, 19 | { 20 | "time": "9:00 am", 21 | "sessions": [ 22 | { 23 | "name": "Introduction to Appcamp.io", 24 | "location": "Room 2203", 25 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 26 | "speakerNames": ["Ellie Elephant"], 27 | "timeStart": "9:00 am", 28 | "timeEnd": "9:30 am", 29 | "tracks": ["Ionic"] 30 | }, 31 | { 32 | "name": "Getting started with Ionic", 33 | "location": "Room 2202", 34 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 35 | "speakerNames": ["Ted Turtle"], 36 | "timeStart": "9:30 am", 37 | "timeEnd": "9:45 am", 38 | "tracks": ["Ionic"] 39 | }, 40 | { 41 | "name": "Tooling for Ionic", 42 | "location": "Room 2201", 43 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 44 | "speakerNames": ["Rachel Rabbit"], 45 | "timeStart": "9:45 am", 46 | "timeEnd": "10:00 am", 47 | "tracks": ["Tooling"] 48 | } 49 | ] 50 | }, 51 | { 52 | "time": "10:00 am", 53 | "sessions": [ 54 | { 55 | "name": "Migrating to Ionic2", 56 | "location": "Room 2201", 57 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 58 | "speakerNames": ["Eva Eagle", "Lionel Lion"], 59 | "timeStart": "10:00 am", 60 | "timeEnd": "10:15 am", 61 | "tracks": ["Ionic"] 62 | }, 63 | { 64 | "name": "The evolution of Ionicons", 65 | "location": "Room 2202", 66 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 67 | "speakerNames": ["Isabella Iguana", "Eva Eagle"], 68 | "timeStart": "10:15 am", 69 | "timeEnd": "10:30 am", 70 | "tracks": ["Design"] 71 | }, 72 | { 73 | "name": "Ionic.io Services", 74 | "location": "Room 2202", 75 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 76 | "speakerNames": ["Charlie Cheetah"], 77 | "timeStart": "10:30 am", 78 | "timeEnd": "11:00 am", 79 | "tracks": ["Services"] 80 | } 81 | ] 82 | }, 83 | { 84 | "time": "11:00 am", 85 | "sessions": [ 86 | { 87 | "name": "Ionic Workshop", 88 | "location": "Room 2201", 89 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 90 | "speakerNames": ["Karl Kitten", "Lionel Lion"], 91 | "timeStart": "11:00 am", 92 | "timeEnd": "11:45 am", 93 | "tracks": ["Workshop"] 94 | }, 95 | { 96 | "name": "Community Interaction", 97 | "location": "Room 2203", 98 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 99 | "speakerNames": ["Lionel Lion", "Gino Giraffe"], 100 | "timeStart": "11:30 am", 101 | "timeEnd": "11:50 am", 102 | "tracks": ["Communication"] 103 | }, 104 | { 105 | "name": "Navigation in Ionic", 106 | "location": "Room 2203", 107 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 108 | "speakerNames": ["Rachel Rabbit", "Eva Eagle"], 109 | "timeStart": "11:30 am", 110 | "timeEnd": "12:00 pm", 111 | "tracks": ["Navigation"] 112 | } 113 | ] 114 | }, 115 | { 116 | "time": "12:00 pm", 117 | "sessions": [ 118 | { 119 | "name": "Lunch", 120 | "location": "Auditorium", 121 | "description": "Come grab lunch with all the Ionic fanatics and talk all things Ionic", 122 | "timeStart": "12:00 pm", 123 | "timeEnd": "1:00 pm", 124 | "tracks": ["Food"] 125 | } 126 | ] 127 | }, 128 | { 129 | "time": "1:00 pm", 130 | "sessions": [ 131 | { 132 | "name": "Ionic in the Enterprise", 133 | "location": "Room 2201", 134 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 135 | "speakerNames": ["Paul Puppy"], 136 | "timeStart": "1:00 pm", 137 | "timeEnd": "1:15 pm", 138 | "tracks": ["Communication"] 139 | }, 140 | { 141 | "name": "Ionic Worldwide", 142 | "location": "Room 2201", 143 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 144 | "speakerNames": ["Gino Giraffe"], 145 | "timeStart": "1:15 pm", 146 | "timeEnd": "1:30 pm", 147 | "tracks": ["Communication"] 148 | }, 149 | { 150 | "name": "The Ionic package service", 151 | "location": "Room 2203", 152 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 153 | "speakerNames": ["Molly Mouse", "Burt Bear"], 154 | "timeStart": "1:30 pm", 155 | "timeEnd": "2:00 pm", 156 | "tracks": ["Services"] 157 | } 158 | ] 159 | }, 160 | { 161 | "time": "2:00 pm", 162 | "sessions": [ 163 | { 164 | "name": "Push Notifications in Ionic", 165 | "location": "Room 2202", 166 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 167 | "speakerNames": ["Burt Bear", "Charlie Cheetah"], 168 | "timeStart": "2:00 pm", 169 | "timeEnd": "2:30 pm", 170 | "tracks": ["Services"] 171 | }, 172 | { 173 | "name": "Ionic Documentation", 174 | "location": "Room 2202", 175 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 176 | "speakerNames": ["Donald Duck"], 177 | "timeStart": "2:30 pm", 178 | "timeEnd": "2:45 pm", 179 | "tracks": ["Documentation"] 180 | }, 181 | { 182 | "name": "UX planning in Ionic", 183 | "location": "Room 2203", 184 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 185 | "speakerNames": ["Isabella Iguana", "Ellie Elephant"], 186 | "timeStart": "2:45 pm", 187 | "timeEnd": "3:00 pm", 188 | "tracks": ["Design"] 189 | } 190 | ] 191 | }, 192 | { 193 | "time": "3:00", 194 | "sessions": [ 195 | { 196 | "name": "Directives in Ionic", 197 | "location": "Room 2201", 198 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 199 | "speakerNames": ["Ted Turtle"], 200 | "timeStart": "3:00 pm", 201 | "timeEnd": "3:30 pm", 202 | "tracks": ["Angular"] 203 | }, 204 | { 205 | "name": "Mobile States", 206 | "location": "Room 2202", 207 | "description": "Mobile devices and browsers are now advanced enough that developers can build native-quality mobile apps using open web technologies like HTML5, Javascript, and CSS. In this talk, we’ll provide background on why and how we created Ionic, the design decisions made as we integrated Ionic with Angular, and the performance considerations for mobile platforms that our team had to overcome. We’ll also review new and upcoming Ionic features, and talk about the hidden powers and benefits of combining mobile app development and Angular.", 208 | "speakerNames": ["Rachel Rabbit"], 209 | "timeStart": "3:30 pm", 210 | "timeEnd": "3:45 pm", 211 | "tracks": ["Navigation"] 212 | } 213 | ] 214 | } 215 | ] 216 | } 217 | ], 218 | 219 | 220 | "speakers": [ 221 | { 222 | "name": "Burt Bear", 223 | "profilePic": "img/speakers/bear.jpg", 224 | "twitter": "ionicframework", 225 | "about": "Burt is a Bear.", 226 | "location": "Everywhere" 227 | }, 228 | { 229 | "name": "Charlie Cheetah", 230 | "profilePic": "img/speakers/cheetah.jpg", 231 | "twitter": "ionicframework", 232 | "about": "Charlie is a Cheetah.", 233 | "location": "Everywhere" 234 | }, 235 | { 236 | "name": "Donald Duck", 237 | "profilePic": "img/speakers/duck.jpg", 238 | "twitter": "ionicframework", 239 | "about": "Donald is a Duck.", 240 | "location": "Everywhere" 241 | }, 242 | { 243 | "name": "Eva Eagle", 244 | "profilePic": "img/speakers/eagle.jpg", 245 | "twitter": "ionicframework", 246 | "about": "Eva is an Eagle.", 247 | "location": "Everywhere" 248 | }, 249 | { 250 | "name": "Ellie Elephant", 251 | "profilePic": "img/speakers/elephant.jpg", 252 | "twitter": "ionicframework", 253 | "about": "Ellie is an Elephant.", 254 | "location": "Everywhere" 255 | }, 256 | { 257 | "name": "Gino Giraffe", 258 | "profilePic": "img/speakers/giraffe.jpg", 259 | "twitter": "ionicframework", 260 | "about": "Gino is a Giraffe.", 261 | "location": "Everywhere" 262 | }, 263 | { 264 | "name": "Isabella Iguana", 265 | "profilePic": "img/speakers/iguana.jpg", 266 | "twitter": "ionicframework", 267 | "about": "Isabella is an Iguana.", 268 | "location": "Everywhere" 269 | }, 270 | { 271 | "name": "Karl Kitten", 272 | "profilePic": "img/speakers/kitten.jpg", 273 | "twitter": "ionicframework", 274 | "about": "Karl is a Kitten.", 275 | "location": "Everywhere" 276 | }, 277 | { 278 | "name": "Lionel Lion", 279 | "profilePic": "img/speakers/lion.jpg", 280 | "twitter": "ionicframework", 281 | "about": "Lionel is a Lion.", 282 | "location": "Everywhere" 283 | }, 284 | { 285 | "name": "Molly Mouse", 286 | "profilePic": "img/speakers/mouse.jpg", 287 | "twitter": "ionicframework", 288 | "about": "Molly is a Mouse.", 289 | "location": "Everywhere" 290 | }, 291 | { 292 | "name": "Paul Puppy", 293 | "profilePic": "img/speakers/puppy.jpg", 294 | "twitter": "ionicframework", 295 | "about": "Paul is a Puppy.", 296 | "location": "Everywhere" 297 | }, 298 | { 299 | "name": "Rachel Rabbit", 300 | "profilePic": "img/speakers/rabbit.jpg", 301 | "twitter": "ionicframework", 302 | "about": "Rachel is a Rabbit.", 303 | "location": "Everywhere" 304 | }, 305 | { 306 | "name": "Ted Turtle", 307 | "profilePic": "img/speakers/turtle.jpg", 308 | "twitter": "ionicframework", 309 | "about": "Ted is a Turtle.", 310 | "location": "Everywhere" 311 | } 312 | ], 313 | 314 | 315 | "map": [ 316 | { 317 | "name": "Monona Terrace Convention Center", 318 | "lat": 43.071584, 319 | "lng": -89.380120, 320 | "center": true 321 | }, 322 | { 323 | "name": "Ionic HQ", 324 | "lat": 43.074395, 325 | "lng": -89.381056 326 | }, 327 | { 328 | "name": "Afterparty - Brocach Irish Pub", 329 | "lat": 43.07336, 330 | "lng": -89.38335 331 | } 332 | ] 333 | 334 | } 335 | --------------------------------------------------------------------------------