diff --git a/ionic.config.json b/ionic.config.json index a84a217..6d0f784 100644 --- a/ionic.config.json +++ b/ionic.config.json @@ -1,6 +1,6 @@ { "name": "ionic2-reddit-reader", "app_id": "", - "v2": true, - "typescript": true + "type": "ionic-angular", + "integrations": {} } diff --git a/package.json b/package.json index f4a0b6b..f072c82 100644 --- a/package.json +++ b/package.json @@ -4,31 +4,35 @@ "version": "1.0.0", "private": false, "scripts": { + "clean": "ionic-app-scripts clean", + "build": "ionic-app-scripts build", + "lint": "ionic-app-scripts lint", "ionic:build": "ionic-app-scripts build", "ionic:serve": "ionic-app-scripts serve" }, "dependencies": { - "@angular/common": "2.1.1", - "@angular/compiler": "2.1.1", - "@angular/compiler-cli": "2.1.1", - "@angular/core": "2.1.1", - "@angular/forms": "2.1.1", - "@angular/http": "2.1.1", - "@angular/platform-browser": "2.1.1", - "@angular/platform-browser-dynamic": "2.1.1", - "@angular/platform-server": "2.1.1", - "@ionic/storage": "1.1.6", - "angular2-moment": "^1.0.0-beta.rc.1", - "ionic-angular": "2.0.0-rc.3", - "ionic-native": "2.2.3", + "@angular/common": "5.1.0", + "@angular/compiler": "5.1.0", + "@angular/compiler-cli": "5.1.0", + "@angular/core": "5.1.0", + "@angular/forms": "5.1.0", + "@angular/http": "5.1.0", + "@angular/platform-browser": "5.1.0", + "@angular/platform-browser-dynamic": "5.1.0", + "@ionic-native/core": "4.5.0", + "@ionic-native/splash-screen": "4.5.0", + "@ionic-native/status-bar": "4.5.0", + "@ionic/storage": "2.1.3", + "angular2-moment": "^1.7.0", + "ionic-angular": "3.9.2", "ionicons": "3.0.0", - "rxjs": "5.0.0-beta.12", - "sw-toolbox": "3.4.0", - "zone.js": "0.6.26" + "rxjs": "5.5.5", + "sw-toolbox": "3.6.0", + "zone.js": "0.8.18" }, "devDependencies": { - "@ionic/app-scripts": "1.0.0", - "typescript": "2.0.9" + "@ionic/app-scripts": "3.1.5", + "typescript": "2.6.2" }, "cordovaPlugins": [ "cordova-plugin-whitelist", diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 7198436..9f82001 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,22 +1,23 @@ import { Component } from '@angular/core'; import { Platform } from 'ionic-angular'; -import { StatusBar, Splashscreen } from 'ionic-native'; +import { StatusBar } from '@ionic-native/status-bar'; +import { SplashScreen } from '@ionic-native/splash-screen'; import { PostsPage } from '../pages/posts/posts'; @Component({ - template: `` + templateUrl: 'app.html' }) export class RedditReaderApp { rootPage = PostsPage; - constructor(platform: Platform) { + constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) { platform.ready().then(() => { // Okay, so the platform is ready and our plugins are available. // Here you can do any higher level native things you might need. - StatusBar.styleDefault(); - Splashscreen.hide(); + statusBar.styleDefault(); + splashScreen.hide(); }); } } diff --git a/src/app/app.html b/src/app/app.html new file mode 100644 index 0000000..7b88c96 --- /dev/null +++ b/src/app/app.html @@ -0,0 +1 @@ + diff --git a/src/app/app.module.ts b/src/app/app.module.ts index e0416b9..68df563 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -5,6 +5,11 @@ import { RedditReaderApp } from './app.component'; import { PostsPage } from '../pages/posts/posts'; import { CommentsPage } from '../pages/comments/comments' import { CommentsList } from '../pages/comments/commentsList/commentsList' +import { RedditApiService } from "../providers/reddit-api-service"; +import { SplashScreen } from '@ionic-native/splash-screen'; +import { StatusBar } from '@ionic-native/status-bar'; +import { BrowserModule } from "@angular/platform-browser"; +import {HttpClientModule} from "@angular/common/http"; @NgModule({ declarations: [ @@ -14,6 +19,8 @@ import { CommentsList } from '../pages/comments/commentsList/commentsList' CommentsList ], imports: [ + BrowserModule, + HttpClientModule, IonicModule.forRoot(RedditReaderApp), MomentModule ], @@ -23,6 +30,10 @@ import { CommentsList } from '../pages/comments/commentsList/commentsList' PostsPage, CommentsPage ], - providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}] + providers: [ + RedditApiService, + StatusBar, + SplashScreen, + {provide: ErrorHandler, useClass: IonicErrorHandler}] }) export class AppModule {} diff --git a/src/app/app.scss b/src/app/app.scss index a967d6f..1392a6e 100644 --- a/src/app/app.scss +++ b/src/app/app.scss @@ -1,4 +1,4 @@ -// http://ionicframework.com/docs/v2/theming/ +// http://ionicframework.com/docs/theming/ // App Global Sass diff --git a/src/declarations.d.ts b/src/declarations.d.ts deleted file mode 100644 index 423e2f1..0000000 --- a/src/declarations.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - Declaration files are how the Typescript compiler knows about the type information(or shape) of an object. - They're what make intellisense work and make Typescript know all about your code. - - A wildcard module is declared below to allow third party libraries to be used in an app even if they don't - provide their own type declarations. - - To learn more about using third party libraries in an Ionic app, check out the docs here: - http://ionicframework.com/docs/v2/resources/third-party-libs/ - - For more info on type definition files, check out the Typescript docs here: - https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html -*/ -declare module '*'; \ No newline at end of file diff --git a/src/index.html b/src/index.html index ce6c3c6..e254871 100644 --- a/src/index.html +++ b/src/index.html @@ -3,16 +3,19 @@ Ionic App - + - - + + + + + @@ -35,7 +38,11 @@ - + + + + diff --git a/src/pages/comments/comments.html b/src/pages/comments/comments.html index 4d12bbb..0e76147 100644 --- a/src/pages/comments/comments.html +++ b/src/pages/comments/comments.html @@ -1,9 +1,3 @@ - diff --git a/src/pages/comments/comments.ts b/src/pages/comments/comments.ts index 5196694..066216f 100644 --- a/src/pages/comments/comments.ts +++ b/src/pages/comments/comments.ts @@ -1,26 +1,20 @@ import { Component } from '@angular/core'; -import { NavController, NavParams } from 'ionic-angular'; +import { NavParams } from 'ionic-angular'; import { RedditApiService } from '../../providers/reddit-api-service'; -/* - Generated class for the Comments page. - - See http://ionicframework.com/docs/v2/components/#navigation for more info on - Ionic pages and navigation. -*/ @Component({ selector: 'page-comments', - templateUrl: 'comments.html', - providers: [RedditApiService], + templateUrl: 'comments.html' }) export class CommentsPage { post; comments; loadCompleted: boolean = false; - constructor(public navCtrl: NavController, public redditApi: RedditApiService, public params: NavParams) { - this.post = this.params.get('post'); + constructor(private redditApi: RedditApiService, + params: NavParams) { + this.post = params.get('post'); this.load(); } @@ -29,7 +23,6 @@ export class CommentsPage { // comments.sort((a,b) => b.score - a.score); this.comments = comments; this.loadCompleted = true; - console.log(this.comments) }) } } diff --git a/src/pages/comments/commentsList/commentsList.ts b/src/pages/comments/commentsList/commentsList.ts index eba4c40..e8a573a 100644 --- a/src/pages/comments/commentsList/commentsList.ts +++ b/src/pages/comments/commentsList/commentsList.ts @@ -2,8 +2,7 @@ import { Component, Input } from '@angular/core'; @Component({ selector: 'comments-list', - templateUrl: 'commentsList.html', - providers: [], + templateUrl: 'commentsList.html' }) export class CommentsList { @Input() comments; diff --git a/src/pages/posts/posts.ts b/src/pages/posts/posts.ts index efd13bb..2e95430 100644 --- a/src/pages/posts/posts.ts +++ b/src/pages/posts/posts.ts @@ -6,8 +6,7 @@ import { CommentsPage } from '../comments/comments' @Component({ selector: 'page-posts', - templateUrl: 'posts.html', - providers: [RedditApiService] + templateUrl: 'posts.html' }) export class PostsPage { loadCompleted: boolean = false; @@ -16,8 +15,10 @@ export class PostsPage { posts: Array; commentsPage = CommentsPage; - constructor(public navCtrl: NavController, public redditApi: RedditApiService, public navParams: NavParams) { - this.subreddit = this.navParams.get('subreddit'); + constructor(private navCtrl: NavController, + private redditApi: RedditApiService, + navParams: NavParams) { + this.subreddit = navParams.get('subreddit'); this.load(this.subreddit); } @@ -25,7 +26,6 @@ export class PostsPage { this.redditApi.fetch(url).subscribe((posts) => { this.posts = posts; this.loadCompleted = true; - console.log(posts) }) } diff --git a/src/providers/reddit-api-service.ts b/src/providers/reddit-api-service.ts index 8fd2817..26a4e85 100644 --- a/src/providers/reddit-api-service.ts +++ b/src/providers/reddit-api-service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; -import { Http } from '@angular/http'; -import 'rxjs/add/operator/map'; +import { map } from 'rxjs/operators/map'; +import {HttpClient} from "@angular/common/http"; const BASE_URL: string = 'https://www.reddit.com/'; const JSON_POSTFIX: string = '.json'; @@ -8,29 +8,31 @@ const JSON_POSTFIX: string = '.json'; @Injectable() export class RedditApiService { - constructor(public http: Http) {} + constructor(private http: HttpClient) {} fetch(url?: string) { return url ? this.http.get(BASE_URL + '/r/' + url + JSON_POSTFIX) - .map(this.redditCollectionToJson) : + .pipe(map(this.redditCollectionToJson)) : this.http.get(BASE_URL + JSON_POSTFIX) - .map(this.redditCollectionToJson) + .pipe(map(this.redditCollectionToJson)); } fetchNext(lastPostName: string, url?: string) { return url ? this.http.get(BASE_URL + '/r/' + url + JSON_POSTFIX + '?count=' + 25 + '&after=' + lastPostName) - .map(this.redditCollectionToJson) : + .pipe(map(this.redditCollectionToJson)) : this.http.get(BASE_URL + JSON_POSTFIX + '?count=' + 25 + '&after=' + lastPostName) - .map(this.redditCollectionToJson) + .pipe(map(this.redditCollectionToJson)); } fetchComments(post) { let url: string = BASE_URL + post.permalink + JSON_POSTFIX; return this.http.get(url) - .map(res => res.json()[1].data.children.map(c => c.data).filter(c => c.body)) - .map(this.beautifyReplies.bind(this)) + .pipe( + map(res => res[1].data.children.map(c => c.data).filter(c => c.body)), + map(this.beautifyReplies.bind(this))); + } beautifyReplies(comments) { @@ -42,6 +44,6 @@ export class RedditApiService { } redditCollectionToJson(response) { - return response.json().data.children.map(c => c.data) + return response.data.children.map(c => c.data) } } diff --git a/src/service-worker.js b/src/service-worker.js index 0928a8f..ffbbb06 100644 --- a/src/service-worker.js +++ b/src/service-worker.js @@ -1,80 +1,31 @@ -// tick this to make the cache invalidate and update -const CACHE_VERSION = 1; -const CURRENT_CACHES = { - 'read-through': 'read-through-cache-v' + CACHE_VERSION -}; - -self.addEventListener('activate', (event) => { - // Delete all caches that aren't named in CURRENT_CACHES. - // While there is only one cache in this example, the same logic will handle the case where - // there are multiple versioned caches. - const expectedCacheNames = Object.keys(CURRENT_CACHES).map((key) => { - return CURRENT_CACHES[key]; - }); - - event.waitUntil( - caches.keys().then((cacheNames) => { - return Promise.all( - cacheNames.map((cacheName) => { - if (expectedCacheNames.indexOf(cacheName) === -1) { - // If this cache name isn't present in the array of "expected" cache names, then delete it. - console.log('Deleting out of date cache:', cacheName); - return caches.delete(cacheName); - } - }) - ); - }) - ); -}); - -// This sample illustrates an aggressive approach to caching, in which every valid response is -// cached and every request is first checked against the cache. -// This may not be an appropriate approach if your web application makes requests for -// arbitrary URLs as part of its normal operation (e.g. a RSS client or a news aggregator), -// as the cache could end up containing large responses that might not end up ever being accessed. -// Other approaches, like selectively caching based on response headers or only caching -// responses served from a specific domain, might be more appropriate for those use cases. -self.addEventListener('fetch', (event) => { +/** + * Check out https://googlechromelabs.github.io/sw-toolbox/ for + * more info on how to use sw-toolbox to custom configure your service worker. + */ - event.respondWith( - caches.open(CURRENT_CACHES['read-through']).then((cache) => { - return cache.match(event.request).then((response) => { - if (response) { - // If there is an entry in the cache for event.request, then response will be defined - // and we can just return it. - return response; - } +'use strict'; +importScripts('./build/sw-toolbox.js'); - // Otherwise, if there is no entry in the cache for event.request, response will be - // undefined, and we need to fetch() the resource. - console.log(' No response for %s found in cache. ' + - 'About to fetch from network...', event.request.url); - - // We call .clone() on the request since we might use it in the call to cache.put() later on. - // Both fetch() and cache.put() "consume" the request, so we need to make a copy. - // (see https://fetch.spec.whatwg.org/#dom-request-clone) - return fetch(event.request.clone()).then((response) => { - - // Optional: add in extra conditions here, e.g. response.type == 'basic' to only cache - // responses from the same domain. See https://fetch.spec.whatwg.org/#concept-response-type - if (response.status < 400 && response.type === 'basic') { - // We need to call .clone() on the response object to save a copy of it to the cache. - // (https://fetch.spec.whatwg.org/#dom-request-clone) - cache.put(event.request, response.clone()); - } - - // Return the original response object, which will be used to fulfill the resource request. - return response; - }); - }).catch((error) => { - // This catch() will handle exceptions that arise from the match() or fetch() operations. - // Note that a HTTP error response (e.g. 404) will NOT trigger an exception. - // It will return a normal response object that has the appropriate error code set. - console.error(' Read-through caching failed:', error); +self.toolbox.options.cache = { + name: 'ionic-cache' +}; - throw error; - }); - }) - ); -}); \ No newline at end of file +// pre-cache our key assets +self.toolbox.precache( + [ + './build/main.js', + './build/vendor.js', + './build/main.css', + './build/polyfills.js', + 'index.html', + 'manifest.json' + ] +); + +// dynamically cache any other local assets +self.toolbox.router.any('/*', self.toolbox.fastest); + +// for any other requests go to the network, cache, +// and then only use that cached resource if your user goes offline +self.toolbox.router.default = self.toolbox.networkFirst; diff --git a/src/theme/variables.scss b/src/theme/variables.scss index ed0139a..d16b088 100644 --- a/src/theme/variables.scss +++ b/src/theme/variables.scss @@ -1,5 +1,17 @@ // Ionic Variables and Theming. For more info, please see: -// http://ionicframework.com/docs/v2/theming/ +// http://ionicframework.com/docs/theming/ + +// Font path is used to include ionicons, +// roboto, and noto sans fonts +$font-path: "../assets/fonts"; + + +// The app direction is used to include +// rtl styles in your app. For more info, please see: +// http://ionicframework.com/docs/theming/rtl-support/ +$app-direction: ltr; + + @import "ionic.globals"; @@ -8,10 +20,9 @@ // To customize the look and feel of this app, you can override // the Sass variables found in Ionic's source scss files. // To view all the possible Ionic variables, see: -// http://ionicframework.com/docs/v2/theming/overriding-ionic-variables/ +// http://ionicframework.com/docs/theming/overriding-ionic-variables/ + -$text-color: #000; -$background-color: #fff; // Named Color Variables @@ -30,6 +41,7 @@ $colors: ( dark: #222 ); + // App iOS Variables // -------------------------------------------------- // iOS only Sass variables can go here @@ -64,7 +76,13 @@ $colors: ( // Ionicons // -------------------------------------------------- // The premium icon font for Ionic. For more info, please see: -// http://ionicframework.com/docs/v2/ionicons/ +// http://ionicframework.com/docs/ionicons/ + +@import "ionic.ionicons"; + + +// Fonts +// -------------------------------------------------- -$ionicons-font-path: "../assets/fonts"; -@import "ionicons"; +@import "roboto"; +@import "noto-sans"; diff --git a/tsconfig.json b/tsconfig.json index bc1c921..2d2df92 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,8 +4,6 @@ "declaration": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "skipLibCheck": true, - "noImplicitAny": false, "lib": [ "dom", "es2015" @@ -13,13 +11,18 @@ "module": "es2015", "moduleResolution": "node", "sourceMap": true, - "target": "es5" + "target": "es5", + "typeRoots": [ + "../node_modules/@types" + ] }, "include": [ "src/**/*.ts" ], "exclude": [ - "node_modules" + "node_modules", + "src/**/*.spec.ts", + "src/**/__tests__/*.ts" ], "compileOnSave": false, "atom": {