├── src
├── pages
│ ├── user
│ │ ├── user.scss
│ │ ├── user.module.ts
│ │ ├── user.ts
│ │ └── user.html
│ ├── page1
│ │ ├── page1.scss
│ │ ├── page1.ts
│ │ └── page1.html
│ ├── page2
│ │ ├── page2.scss
│ │ ├── page2.html
│ │ └── page2.ts
│ ├── topic
│ │ ├── topic.scss
│ │ ├── topic.module.ts
│ │ ├── topic.ts
│ │ └── topic.html
│ ├── message
│ │ ├── message.scss
│ │ ├── message.module.ts
│ │ ├── message.ts
│ │ └── message.html
│ ├── new-topic-modal
│ │ ├── new-topic-modal.scss
│ │ ├── new-topic-modal.module.ts
│ │ ├── new-topic-modal.html
│ │ └── new-topic-modal.ts
│ └── topics
│ │ ├── topics.module.ts
│ │ ├── topics.scss
│ │ ├── topics.html
│ │ └── topics.ts
├── classes
│ ├── tab.ts
│ ├── topic.ts
│ ├── message.ts
│ └── user.ts
├── assets
│ └── icon
│ │ └── favicon.ico
├── app
│ ├── main.ts
│ ├── app.html
│ ├── app.module.ts
│ ├── app.scss
│ └── app.component.ts
├── manifest.json
├── providers
│ ├── storage-service.ts
│ ├── config-service.ts
│ ├── tabs-service.ts
│ ├── message-service.ts
│ ├── user-service.ts
│ └── topic-service.ts
├── declarations.d.ts
├── service-worker.js
├── index.html
└── theme
│ └── variables.scss
├── resources
├── icon.png
├── splash.png
├── ios
│ ├── icon
│ │ ├── icon.png
│ │ ├── icon-40.png
│ │ ├── icon-50.png
│ │ ├── icon-60.png
│ │ ├── icon-72.png
│ │ ├── icon-76.png
│ │ ├── icon@2x.png
│ │ ├── icon-40@2x.png
│ │ ├── icon-40@3x.png
│ │ ├── icon-50@2x.png
│ │ ├── icon-60@2x.png
│ │ ├── icon-60@3x.png
│ │ ├── icon-72@2x.png
│ │ ├── icon-76@2x.png
│ │ ├── icon-83.5@2x.png
│ │ ├── icon-small.png
│ │ ├── icon-small@2x.png
│ │ └── icon-small@3x.png
│ └── splash
│ │ ├── Default-667h.png
│ │ ├── Default-736h.png
│ │ ├── Default~iphone.png
│ │ ├── Default@2x~iphone.png
│ │ ├── Default-568h@2x~iphone.png
│ │ ├── Default-Landscape-736h.png
│ │ ├── Default-Landscape~ipad.png
│ │ ├── Default-Portrait~ipad.png
│ │ ├── Default-Landscape@2x~ipad.png
│ │ └── Default-Portrait@2x~ipad.png
└── android
│ ├── icon
│ ├── drawable-hdpi-icon.png
│ ├── drawable-ldpi-icon.png
│ ├── drawable-mdpi-icon.png
│ ├── drawable-xhdpi-icon.png
│ ├── drawable-xxhdpi-icon.png
│ └── drawable-xxxhdpi-icon.png
│ └── splash
│ ├── drawable-land-hdpi-screen.png
│ ├── drawable-land-ldpi-screen.png
│ ├── drawable-land-mdpi-screen.png
│ ├── drawable-land-xhdpi-screen.png
│ ├── drawable-port-hdpi-screen.png
│ ├── drawable-port-ldpi-screen.png
│ ├── drawable-port-mdpi-screen.png
│ ├── drawable-port-xhdpi-screen.png
│ ├── drawable-land-xxhdpi-screen.png
│ ├── drawable-land-xxxhdpi-screen.png
│ ├── drawable-port-xxhdpi-screen.png
│ └── drawable-port-xxxhdpi-screen.png
├── ionic.config.json
├── config
├── webpack.common.js
└── webpack.config.js
├── tslint.json
├── .editorconfig
├── .gitignore
├── tsconfig.json
├── package.json
└── config.xml
/src/pages/user/user.scss:
--------------------------------------------------------------------------------
1 | page-user {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/page1/page1.scss:
--------------------------------------------------------------------------------
1 | page-page1 {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/page2/page2.scss:
--------------------------------------------------------------------------------
1 | page-page2 {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/topic/topic.scss:
--------------------------------------------------------------------------------
1 | page-topic {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/message/message.scss:
--------------------------------------------------------------------------------
1 | page-message {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/new-topic-modal/new-topic-modal.scss:
--------------------------------------------------------------------------------
1 | page-new-topic-modal {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/resources/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/icon.png
--------------------------------------------------------------------------------
/resources/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/splash.png
--------------------------------------------------------------------------------
/src/classes/tab.ts:
--------------------------------------------------------------------------------
1 | export class Tab {
2 | value: string;
3 | label: string;
4 | }
5 |
6 |
7 |
--------------------------------------------------------------------------------
/resources/ios/icon/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon.png
--------------------------------------------------------------------------------
/src/assets/icon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/src/assets/icon/favicon.ico
--------------------------------------------------------------------------------
/src/classes/topic.ts:
--------------------------------------------------------------------------------
1 | export class Topic {
2 | id: string;
3 | title: string;
4 | content: string;
5 | }
6 |
--------------------------------------------------------------------------------
/resources/ios/icon/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-40.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-50.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-60.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-72.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-76.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon@2x.png
--------------------------------------------------------------------------------
/ionic.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cnodejs-ionic3",
3 | "app_id": "",
4 | "v2": true,
5 | "typescript": true
6 | }
7 |
--------------------------------------------------------------------------------
/resources/ios/icon/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-40@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-40@3x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-50@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-60@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-60@3x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-72@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-76@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-83.5@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-small.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-small@2x.png
--------------------------------------------------------------------------------
/resources/ios/icon/icon-small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/icon/icon-small@3x.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-667h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/splash/Default-667h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-736h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/splash/Default-736h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/splash/Default~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default@2x~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/splash/Default@2x~iphone.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-hdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/icon/drawable-hdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-ldpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/icon/drawable-ldpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-mdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/icon/drawable-mdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-xhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/icon/drawable-xhdpi-icon.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-xxhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/icon/drawable-xxhdpi-icon.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-568h@2x~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/splash/Default-568h@2x~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape-736h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/splash/Default-Landscape-736h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/splash/Default-Landscape~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/splash/Default-Portrait~ipad.png
--------------------------------------------------------------------------------
/resources/android/icon/drawable-xxxhdpi-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/icon/drawable-xxxhdpi-icon.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/splash/Default-Landscape@2x~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/ios/splash/Default-Portrait@2x~ipad.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-hdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/splash/drawable-land-hdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-ldpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/splash/drawable-land-ldpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-mdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/splash/drawable-land-mdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-xhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/splash/drawable-land-xhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-hdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/splash/drawable-port-hdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-ldpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/splash/drawable-port-ldpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-mdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/splash/drawable-port-mdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-xhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/splash/drawable-port-xhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-xxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/splash/drawable-land-xxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-land-xxxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/splash/drawable-land-xxxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-xxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/splash/drawable-port-xxhdpi-screen.png
--------------------------------------------------------------------------------
/resources/android/splash/drawable-port-xxxhdpi-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanceli/cnodejs-ionic3/HEAD/resources/android/splash/drawable-port-xxxhdpi-screen.png
--------------------------------------------------------------------------------
/config/webpack.common.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | plugins: [
5 | new webpack.EnvironmentPlugin(['IONIC_ENV'])
6 | ]
7 | };
8 |
9 |
--------------------------------------------------------------------------------
/src/classes/message.ts:
--------------------------------------------------------------------------------
1 | export class Message {
2 | id: string;
3 | }
4 | export class Messages {
5 | has_read_messages: Message[];
6 | hasnot_read_messages: Message[];
7 | }
8 |
--------------------------------------------------------------------------------
/src/app/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/src/classes/user.ts:
--------------------------------------------------------------------------------
1 | export class User {
2 | id?: string;
3 | accesstoken?: string;
4 | loginname: string;
5 | avatar_url: string;
6 | githubUsername: string;
7 | create_at: string;
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-duplicate-variable": true,
4 | "no-unused-variable": [
5 | true
6 | ]
7 | },
8 | "rulesDirectory": [
9 | "node_modules/tslint-eslint-rules/dist/rules"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/config/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpackMerge = require('webpack-merge');
2 |
3 | const commonConfig = require('./webpack.common.js');
4 | const ionicConfig = require('../node_modules/@ionic/app-scripts/config/webpack.config.js');
5 |
6 | module.exports = webpackMerge(
7 | commonConfig,
8 | ionicConfig
9 | );
10 |
--------------------------------------------------------------------------------
/src/pages/page1/page1.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { NavController } from 'ionic-angular';
4 |
5 | @Component({
6 | selector: 'page-page1',
7 | templateUrl: 'page1.html'
8 | })
9 | export class Page1 {
10 |
11 | constructor(public navCtrl: NavController) {
12 |
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Ionic",
3 | "short_name": "Ionic",
4 | "start_url": "index.html",
5 | "display": "standalone",
6 | "icons": [{
7 | "src": "assets/imgs/logo.png",
8 | "sizes": "512x512",
9 | "type": "image/png"
10 | }],
11 | "background_color": "#4e8ef7",
12 | "theme_color": "#4e8ef7"
13 | }
--------------------------------------------------------------------------------
/src/pages/message/message.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { IonicPageModule } from 'ionic-angular';
3 | import { MessagePage } from './message';
4 |
5 | @NgModule({
6 | declarations: [
7 | MessagePage,
8 | ],
9 | imports: [
10 | IonicPageModule.forChild(MessagePage),
11 | ],
12 | exports: [
13 | MessagePage
14 | ]
15 | })
16 | export class MessageModule {}
17 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs
2 | # editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | indent_style = space
8 | indent_size = 2
9 |
10 | # We recommend you to keep these unchanged
11 | end_of_line = lf
12 | charset = utf-8
13 | trim_trailing_whitespace = true
14 | insert_final_newline = true
15 |
16 | [*.md]
17 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/src/pages/topics/topics.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { TopicsPage } from './topics';
3 | import { IonicPageModule } from 'ionic-angular';
4 |
5 | @NgModule({
6 | declarations: [
7 | TopicsPage
8 | ],
9 | imports: [
10 | IonicPageModule.forChild(TopicsPage)
11 | ],
12 | entryComponents: [
13 | TopicsPage
14 | ]
15 | })
16 | export class TopicsPageModule {}
17 |
18 |
--------------------------------------------------------------------------------
/src/pages/topic/topic.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { TopicPage } from './topic';
3 | import { IonicPageModule } from 'ionic-angular';
4 | import { MomentModule } from 'angular2-moment';
5 |
6 | @NgModule({
7 | declarations: [
8 | TopicPage
9 | ],
10 | imports: [
11 | MomentModule,
12 | IonicPageModule.forChild(TopicPage)
13 | ],
14 | entryComponents: [
15 | TopicPage
16 | ]
17 | })
18 | export class TopicPageModule {}
19 |
--------------------------------------------------------------------------------
/src/pages/user/user.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { UserPage } from './user';
3 | import { IonicPageModule } from 'ionic-angular';
4 | import { MomentModule } from 'angular2-moment';
5 |
6 | @NgModule({
7 | declarations: [
8 | UserPage
9 | ],
10 | imports: [
11 | MomentModule,
12 | IonicPageModule.forChild(UserPage)
13 | ],
14 | entryComponents: [
15 | UserPage
16 | ]
17 | })
18 | export class UserPageModule {}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/pages/new-topic-modal/new-topic-modal.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { IonicPageModule } from 'ionic-angular';
3 | import { NewTopicModal } from './new-topic-modal';
4 |
5 | console.log('aaa,', NewTopicModal)
6 | @NgModule({
7 | declarations: [
8 | NewTopicModal,
9 | ],
10 | imports: [
11 | IonicPageModule.forChild(NewTopicModal)
12 | ],
13 | exports: [
14 | NewTopicModal
15 | ]
16 | })
17 | export class NewTopicModalModule {}
18 |
--------------------------------------------------------------------------------
/src/pages/page1/page1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 | Page One
7 |
8 |
9 |
10 |
11 | Ionic Menu Starter
12 |
13 |
14 | If you get lost, the docs will show you the way.
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/providers/storage-service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Http } from '@angular/http';
3 | import 'rxjs/add/operator/map';
4 |
5 | /*
6 | Generated class for the StorageService provider.
7 |
8 | See https://angular.io/docs/ts/latest/guide/dependency-injection.html
9 | for more info on providers and Angular 2 DI.
10 | */
11 | @Injectable()
12 | export class StorageService {
13 |
14 | constructor(public http: Http) {
15 | console.log('Hello StorageService Provider');
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/providers/config-service.ts:
--------------------------------------------------------------------------------
1 | import {Injectable} from '@angular/core';
2 | declare const process: any; // Typescript compiler will complain without this
3 | @Injectable()
4 |
5 | export class ConfigService {
6 | public api:string;
7 | public token:string;
8 | constructor() {
9 | console.log(process);
10 | if (process.env.IONIC_ENV === 'prod') {
11 | this.api = 'https://cnodejs.org/api/v1/';
12 | } else {
13 | this.api = 'http://localhost:3000/api/v1/';
14 | this.token = ' 08bb9fe1-d42a-44ca-bae5-7c90585f8d7b';
15 | }
16 | }
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Specifies intentionally untracked files to ignore when using Git
2 | # http://git-scm.com/docs/gitignore
3 |
4 | *~
5 | *.sw[mnpcod]
6 | *.log
7 | *.tmp
8 | *.tmp.*
9 | log.txt
10 | *.sublime-project
11 | *.sublime-workspace
12 | .vscode/
13 | npm-debug.log*
14 |
15 | .idea/
16 | .sass-cache/
17 | .tmp/
18 | .versions/
19 | coverage/
20 | dist/
21 | node_modules/
22 | tmp/
23 | temp/
24 | hooks/
25 | platforms/
26 | plugins/
27 | plugins/android.json
28 | plugins/ios.json
29 | www/
30 | $RECYCLE.BIN/
31 |
32 | .DS_Store
33 | Thumbs.db
34 | UserInterfaceState.xcuserstate
35 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "declaration": false,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "lib": [
8 | "dom",
9 | "es2015"
10 | ],
11 | "module": "es2015",
12 | "moduleResolution": "node",
13 | "sourceMap": true,
14 | "target": "es5"
15 | },
16 | "include": [
17 | "src/**/*.ts"
18 | ],
19 | "exclude": [
20 | "node_modules"
21 | ],
22 | "compileOnSave": false,
23 | "atom": {
24 | "rewriteTsconfig": false
25 | }
26 | }
--------------------------------------------------------------------------------
/src/pages/page2/page2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 | Page Two
7 |
8 |
9 |
10 |
11 |
12 |
19 |
20 |
21 | You navigated here from {{selectedItem.title}}
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/declarations.d.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Declaration files are how the Typescript compiler knows about the type information(or shape) of an object.
3 | They're what make intellisense work and make Typescript know all about your code.
4 |
5 | A wildcard module is declared below to allow third party libraries to be used in an app even if they don't
6 | provide their own type declarations.
7 |
8 | To learn more about using third party libraries in an Ionic app, check out the docs here:
9 | http://ionicframework.com/docs/v2/resources/third-party-libs/
10 |
11 | For more info on type definition files, check out the Typescript docs here:
12 | https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html
13 | */
14 | declare module '*';
--------------------------------------------------------------------------------
/src/providers/tabs-service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | import { Tab } from '../classes/tab';
4 | /*
5 | Generated class for the TabsService provider.
6 |
7 | See https://angular.io/docs/ts/latest/guide/dependency-injection.html
8 | for more info on providers and Angular 2 DI.
9 | */
10 | @Injectable()
11 | export class TabsService {
12 | tabs: Tab[] = [
13 | {
14 | value: 'all',
15 | label: '最新'
16 | },
17 | {
18 | value: 'share',
19 | label: '分享'
20 | },
21 | {
22 | value: 'ask',
23 | label: '问答'
24 | },
25 | {
26 | value: 'job',
27 | label: '招聘'
28 | },
29 | {
30 | value: undefined,
31 | label: '其他'
32 | }
33 | ]
34 |
35 | getTabs(): Tab[] {
36 | return this.tabs;
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/src/service-worker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Check out https://googlechrome.github.io/sw-toolbox/docs/master/index.html for
3 | * more info on how to use sw-toolbox to custom configure your service worker.
4 | */
5 |
6 |
7 | 'use strict';
8 | importScripts('./build/sw-toolbox.js');
9 |
10 | self.toolbox.options.cache = {
11 | name: 'ionic-cache'
12 | };
13 |
14 | // pre-cache our key assets
15 | self.toolbox.precache(
16 | [
17 | './build/main.js',
18 | './build/main.css',
19 | './build/polyfills.js',
20 | 'index.html',
21 | 'manifest.json'
22 | ]
23 | );
24 |
25 | // dynamically cache any other local assets
26 | self.toolbox.router.any('/*', self.toolbox.cacheFirst);
27 |
28 | // for any other requests go to the network, cache,
29 | // and then only use that cached resource if your user goes offline
30 | self.toolbox.router.default = self.toolbox.networkFirst;
--------------------------------------------------------------------------------
/src/pages/topics/topics.scss:
--------------------------------------------------------------------------------
1 | page-topics {
2 | .topics {
3 | .item-content {
4 | padding: 14px 16px 18px 72px;
5 | > img {
6 | &:not(:first-child) {
7 | -webkit-transform: translate3d(-2000px, -2000px, 0px);
8 | position: absolute;
9 | }
10 | }
11 | }
12 | .activated {
13 | .tab {
14 | &:not(.hl) {
15 | background-color: #aeaeae;
16 | color: #fff;
17 | }
18 | }
19 | }
20 | .ago,
21 | .summary {
22 | font-size: 12px;
23 | }
24 | .tab {
25 | background-color: #E5E5E5;
26 | color: #999;
27 | border-radius: 2px;
28 | padding: 2px 4px;
29 | }
30 | .hl {
31 | background-color: $node-green;
32 | color: #fff;
33 | }
34 | }
35 | .topic-content {
36 | img {
37 | max-width: 100%;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/app/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Menu
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | {{user.loginname}}
13 |
14 |
15 |
16 | 我的消息
17 |
18 |
19 | 登录
20 |
21 |
22 |
23 |
24 | 板块
25 |
26 |
27 | {{tab.label}}
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/pages/page2/page2.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { NavController, NavParams } from 'ionic-angular';
4 |
5 | @Component({
6 | selector: 'page-page2',
7 | templateUrl: 'page2.html'
8 | })
9 | export class Page2 {
10 | selectedItem: any;
11 | icons: string[];
12 | items: Array<{title: string, note: string, icon: string}>;
13 |
14 | constructor(public navCtrl: NavController, public navParams: NavParams) {
15 | // If we navigated to this page, we will have an item available as a nav param
16 | this.selectedItem = navParams.get('item');
17 |
18 | // Let's populate this page with some filler content for funzies
19 | this.icons = ['flask', 'wifi', 'beer', 'football', 'basketball', 'paper-plane',
20 | 'american-football', 'boat', 'bluetooth', 'build'];
21 |
22 | this.items = [];
23 | for (let i = 1; i < 11; i++) {
24 | this.items.push({
25 | title: 'Item ' + i,
26 | note: 'This is item #' + i,
27 | icon: this.icons[Math.floor(Math.random() * this.icons.length)]
28 | });
29 | }
30 | }
31 |
32 | itemTapped(event, item) {
33 | // That's right, we're pushing to ourselves!
34 | this.navCtrl.push(Page2, {
35 | item: item
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule, ErrorHandler } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { HttpModule } from '@angular/http';
4 | import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
5 | import { IonicStorageModule } from '@ionic/storage';
6 | import { MomentModule } from 'angular2-moment';
7 |
8 | import { StatusBar } from '@ionic-native/status-bar';
9 | import { SplashScreen } from '@ionic-native/splash-screen';
10 |
11 | import { MyApp } from './app.component';
12 | import { ConfigService } from '../providers/config-service';
13 |
14 | import { NewTopicModal } from '../pages/new-topic-modal/new-topic-modal';
15 |
16 | @NgModule({
17 | declarations: [
18 | MyApp,
19 | NewTopicModal
20 | ],
21 | imports: [
22 | BrowserModule,
23 | HttpModule,
24 | MomentModule,
25 | IonicStorageModule.forRoot(),
26 | IonicModule.forRoot(MyApp, {
27 | locationStrategy: 'hash'
28 | })
29 | ],
30 | bootstrap: [IonicApp],
31 | entryComponents: [
32 | MyApp,
33 | NewTopicModal
34 | ],
35 | providers: [
36 | StatusBar,
37 | SplashScreen,
38 | {provide: ErrorHandler, useClass: IonicErrorHandler},
39 | ConfigService
40 | ]
41 | })
42 | export class AppModule {}
43 |
--------------------------------------------------------------------------------
/src/pages/user/user.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { NavController, NavParams, IonicPage } from 'ionic-angular';
3 |
4 | import { User } from '../../classes/user';
5 | import { UserService } from '../../providers/user-service';
6 | /*
7 | Generated class for the User page.
8 |
9 | See http://ionicframework.com/docs/v2/components/#navigation for more info on
10 | Ionic pages and navigation.
11 | */
12 | @IonicPage({
13 | name: 'user',
14 | segment: 'user/:loginName'
15 | })
16 | @Component({
17 | selector: 'page-user',
18 | templateUrl: 'user.html',
19 | providers: [UserService]
20 | })
21 | export class UserPage {
22 |
23 | user: User
24 |
25 | constructor(public navCtrl: NavController, public navParams: NavParams, private userService: UserService) {
26 | }
27 |
28 | ionViewDidLoad() {
29 | console.log('ionViewDidLoad UserPage');
30 | }
31 |
32 | ngOnInit(): void {
33 | this.getUser()
34 | }
35 |
36 | getUser(): void {
37 | this.userService.getByLoginName(this.navParams.get('loginName')).then(
38 | (user) => {
39 | this.user = user
40 | console.log(this.user)
41 | }
42 | );
43 | }
44 |
45 | gotoTopicPage(id: string): void {
46 | console.log('go to topic', id);
47 | this.navCtrl.push('topic', {id: id});
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/pages/new-topic-modal/new-topic-modal.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 | NewTopicModal
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/pages/topics/topics.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 | Topics
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | {{topic.title}}
23 |
24 | {{topic.tab}}
25 | 置顶
26 | 精华
27 | {{topic.author.loginname}}
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/app/app.scss:
--------------------------------------------------------------------------------
1 | // http://ionicframework.com/docs/v2/theming/
2 |
3 |
4 | // App Global Sass
5 | // --------------------------------------------------
6 | // Put style rules here that you want to apply globally. These
7 | // styles are for the entire app and not just one component.
8 | // Additionally, this file can be also used as an entry point
9 | // to import other Sass files to be included in the output CSS.
10 | //
11 | // Shared Sass variables, which can be used to adjust Ionic's
12 | // default Sass variables, belong in "theme/variables.scss".
13 | //
14 | // To declare rules for a specific mode, create a child rule
15 | // for the .md, .ios, or .wp mode classes. The mode class is
16 | // automatically applied to the element in the app.
17 | .item {
18 | left: 0;
19 | right: 0;
20 | }
21 | .item-divider {
22 | color: #555;
23 | font-weight: normal;
24 | font-size: 14px;
25 | }
26 | .item-gap {
27 | border: 0 none;
28 | min-height: 0px;
29 | }
30 | .item-loading {
31 | text-align: center;
32 | color: #aaa;
33 | }
34 | .saverMode {
35 | .item-avatar {
36 | padding-left: 14px;
37 | &.item-complex {
38 | padding-left: 0;
39 | }
40 | > img {
41 | &:first-child {
42 | -webkit-transform: translate3d(-2000px, -2000px, 0px);
43 | }
44 | }
45 | .item-content {
46 | padding-left: 14px;
47 | padding-right: 16px;
48 | > img {
49 | &:first-child {
50 | -webkit-transform: translate3d(-2000px, -2000px, 0px);
51 | }
52 | }
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/pages/topic/topic.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { NavController, NavParams, IonicPage } from 'ionic-angular';
3 |
4 | import { Topic } from '../../classes/topic';
5 | import { TopicService } from '../../providers/topic-service';
6 | /*
7 | Generated class for the Topic page.
8 |
9 | See http://ionicframework.com/docs/v2/components/#navigation for more info on
10 | Ionic pages and navigation.
11 | */
12 | @IonicPage({
13 | name: 'topic',
14 | segment: 'topic/:id'
15 | })
16 | @Component({
17 | selector: 'page-topic',
18 | templateUrl: 'topic.html',
19 | providers: [TopicService]
20 | })
21 | export class TopicPage {
22 |
23 | topic: Topic
24 |
25 | constructor(
26 | public navCtrl: NavController,
27 | public navParams: NavParams,
28 | private topicService: TopicService
29 | ) {
30 | }
31 |
32 | ionViewDidLoad() {
33 | console.log('ionViewDidLoad TopicPage');
34 | }
35 |
36 | ngOnInit(): void {
37 | this.getTopic();
38 | }
39 |
40 | doRefresh(refresher): void {
41 | this.getTopic().then(
42 | (topic) => {
43 | refresher.complete();
44 | }
45 | );
46 | }
47 |
48 | getTopic(): Promise {
49 | return this.topicService.getTopicById(this.navParams.get('id')).then(
50 | (topic) => {
51 | this.topic = topic
52 | console.log(this.topic)
53 | }
54 | );
55 | }
56 |
57 | gotoUserPage(loginName: String): void {
58 | console.log('goto user', loginName);
59 | this.navCtrl.push('user', {loginName: loginName})
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/pages/message/message.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { IonicPage, NavController, NavParams } from 'ionic-angular';
3 |
4 | import { Message, Messages } from '../../classes/message';
5 | import { MessageService } from '../../providers/message-service';
6 | /**
7 | * Generated class for the MessagePage page.
8 | *
9 | * See http://ionicframework.com/docs/components/#navigation for more info
10 | * on Ionic pages and navigation.
11 | */
12 | @IonicPage({
13 | name: 'message',
14 | segment: 'message'
15 | })
16 | @Component({
17 | selector: 'page-message',
18 | templateUrl: 'message.html',
19 | providers: [MessageService]
20 | })
21 | export class MessagePage {
22 |
23 | messages: Messages;
24 |
25 | constructor(
26 | public navCtrl: NavController,
27 | public navParams: NavParams,
28 | private messageService: MessageService
29 | ) {
30 | }
31 |
32 | ionViewDidLoad() {
33 | console.log('ionViewDidLoad MessagePage');
34 | }
35 |
36 | ngOnInit(): void {
37 | this.loadMessage();
38 | }
39 |
40 | loadMessage() {
41 | this.messageService.getMessages().then((messages) => {
42 | console.log(messages);
43 | this.messages = messages;
44 | console.log(this);
45 | });
46 | }
47 |
48 | gotoUserPage(loginName: String): void {
49 | console.log('goto user', loginName);
50 | this.navCtrl.push('user', {loginName: loginName});
51 | }
52 |
53 | gotoTopicPage(id: String): void {
54 | console.log('goto topic', id);
55 | this.navCtrl.push('topic', {id: id});
56 | }
57 |
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/src/pages/user/user.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | User
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | {{user.loginname}}
23 | {{user.score}}积分
24 |
25 | 注册于:{{user.create_at | amTimeAgo}}
26 |
27 |
28 |
29 | 最近主题
30 |
31 |
32 | {{topic.title}}
33 |
34 | {{topic.author.loginname}}
35 |
36 | {{topic.last_reply_at | amTimeAgo}}
37 |
38 |
39 |
40 |
41 | 最近回复
42 |
43 |
44 |
45 | {{topic.title}}
46 |
47 | {{topic.author.loginname}}
48 |
49 | {{topic.last_reply_at | amTimeAgo}}
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/pages/new-topic-modal/new-topic-modal.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { IonicPage, ViewController } from 'ionic-angular';
3 |
4 | import { TabsService } from '../../providers/tabs-service';
5 | import { TopicService } from '../../providers/topic-service';
6 | import { UserService } from '../../providers/user-service';
7 | import { Tab } from '../../classes/tab';
8 |
9 | /**
10 | * Generated class for the NewTopicModal page.
11 | *
12 | * See http://ionicframework.com/docs/components/#navigation for more info
13 | * on Ionic pages and navigation.
14 | */
15 | @IonicPage()
16 | @Component({
17 | selector: 'page-new-topic-modal',
18 | templateUrl: 'new-topic-modal.html',
19 | providers: [
20 | UserService,
21 | TabsService,
22 | TopicService
23 | ]
24 | })
25 | export class NewTopicModal {
26 |
27 | tabs: Tab[];
28 | newTopicData: any = {
29 | tab: 'share',
30 | title: '',
31 | content: ''
32 | };
33 | newTopicId:string;
34 |
35 | constructor(
36 | private userService: UserService,
37 | private tabsService: TabsService,
38 | private topicService: TopicService,
39 | public viewCtrl: ViewController
40 | ) {
41 | this.tabs = this.tabsService.getTabs();
42 | }
43 |
44 | ionViewDidLoad() {
45 | console.log('ionViewDidLoad NewTopicModal');
46 | }
47 |
48 | closeModal() {
49 | this.viewCtrl.dismiss();
50 | }
51 | saveNewTopic() {
52 | console.log('new topic data:', this.newTopicData);
53 | this.topicService.saveNewTopic(this.newTopicData).then((response) => {
54 | this.newTopicId = response['topic_id'];
55 | this.closeModal();
56 | });
57 | };
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/src/pages/topic/topic.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | Topic
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
{{topic.title}}
24 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | {{reply.author.loginname}}
42 |
43 |
44 | {{ reply.create_at | amTimeAgo }}
45 |
46 | 0">
47 |
48 | {{reply.ups.length}}
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cnodejs-ionic3",
3 | "version": "3.0.0",
4 | "author": "Lance Li",
5 | "homepage": "https://github.com/lanceli/cnodejs-ionic3",
6 | "private": true,
7 | "scripts": {
8 | "clean": "ionic-app-scripts clean",
9 | "build": "ionic-app-scripts build",
10 | "ionic:build": "ionic-app-scripts build",
11 | "ionic:serve": "ionic-app-scripts serve"
12 | },
13 | "dependencies": {
14 | "@angular/common": "4.0.0",
15 | "@angular/compiler": "4.0.0",
16 | "@angular/compiler-cli": "4.0.0",
17 | "@angular/core": "4.0.0",
18 | "@angular/forms": "4.0.0",
19 | "@angular/http": "4.0.0",
20 | "@angular/platform-browser": "4.0.0",
21 | "@angular/platform-browser-dynamic": "4.0.0",
22 | "@ionic-native/core": "3.4.2",
23 | "@ionic-native/splash-screen": "3.4.2",
24 | "@ionic-native/status-bar": "3.4.2",
25 | "@ionic/storage": "2.0.1",
26 | "angular2-moment": "^1.3.3",
27 | "ionic-angular": "3.0.1",
28 | "ionicons": "3.0.0",
29 | "rxjs": "5.1.1",
30 | "sw-toolbox": "3.4.0",
31 | "webpack-merge": "^4.1.0",
32 | "zone.js": "0.8.4"
33 | },
34 | "devDependencies": {
35 | "@ionic/app-scripts": "1.3.0",
36 | "typescript": "2.2.1"
37 | },
38 | "cordovaPlugins": [
39 | "cordova-plugin-whitelist",
40 | "cordova-plugin-console",
41 | "cordova-plugin-statusbar",
42 | "cordova-plugin-device",
43 | "cordova-plugin-splashscreen",
44 | "ionic-plugin-keyboard"
45 | ],
46 | "cordovaPlatforms": [
47 | "ios",
48 | {
49 | "platform": "ios",
50 | "version": "",
51 | "locator": "ios"
52 | }
53 | ],
54 | "config": {
55 | "ionic_webpack": "./config/webpack.config.js"
56 | },
57 | "description": "cnodejs-ionic2: An Ionic project"
58 | }
59 |
--------------------------------------------------------------------------------
/src/pages/message/message.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | Message
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 未读消息
20 |
21 |
22 |
23 | {{message.author.loginname}}
24 |
25 | 回复了
26 |
27 |
28 | 在
29 |
30 | {{message.topic.title}}
31 |
32 | 中@了你
33 |
34 |
35 |
36 |
37 | 已读消息
38 |
39 |
40 |
41 | {{message.author.loginname}}
42 |
43 | 回复了
44 |
45 |
46 | 在
47 |
48 | {{message.topic.title}}
49 |
50 | 中@了你
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/providers/message-service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Http } from '@angular/http';
3 | import 'rxjs/add/operator/map';
4 | import 'rxjs/add/operator/toPromise';
5 |
6 | import { ConfigService } from './config-service';
7 | import { Message, Messages } from '../classes/message';
8 | import { UserService } from './user-service';
9 |
10 | /*
11 | Generated class for the MessageService provider.
12 |
13 | See https://angular.io/docs/ts/latest/guide/dependency-injection.html
14 | for more info on providers and Angular 2 DI.
15 | */
16 | @Injectable()
17 | export class MessageService {
18 | private countUrl: string
19 | private messagesUrl: string
20 |
21 | constructor(public http: Http, public configService: ConfigService, private userService: UserService) {
22 | console.log('Hello MessageService Provider');
23 | this.countUrl = this.configService.api + 'message/count';
24 | this.messagesUrl = this.configService.api + 'messages';
25 | }
26 |
27 | getMessageCount(): Promise {
28 |
29 | console.log('get messages count');
30 | return this.userService.getCurrentUser().then((currentUser) => {
31 | return this.http.get(this.countUrl, {
32 | params: {
33 | accesstoken: currentUser.accesstoken
34 | }
35 | }).toPromise().then(
36 | (resposne) => {
37 | console.log(resposne);
38 | return resposne.json().data;
39 | }
40 | );
41 | });
42 | }
43 |
44 | getMessages(): Promise {
45 | console.log('get messages');
46 | return this.userService.getCurrentUser().then((currentUser) => {
47 | return this.http.get(this.messagesUrl, {
48 | params: {
49 | accesstoken: currentUser.accesstoken
50 | }
51 | }).toPromise().then(
52 | (resposne) => {
53 | return resposne.json().data as Messages;
54 | }
55 | );
56 | });
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | CNodeJs
4 |
5 | Ionic app for https://cnodejs.org
6 |
7 |
8 | Lance Li
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 |
--------------------------------------------------------------------------------
/src/pages/topics/topics.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { NavController, NavParams, IonicPage, ModalController } from 'ionic-angular';
3 |
4 | import { Topic } from '../../classes/topic';
5 | import { NewTopicModal } from '../new-topic-modal/new-topic-modal';
6 |
7 | import { TopicService } from '../../providers/topic-service';
8 |
9 | /*
10 | Generated class for the Topics page.
11 |
12 | See http://ionicframework.com/docs/v2/components/#navigation for more info on
13 | Ionic pages and navigation.
14 | */
15 |
16 | @IonicPage({
17 | name: 'topics',
18 | segment: 'topics/:tab'
19 | })
20 | @Component({
21 | selector: 'page-topics',
22 | templateUrl: 'topics.html',
23 | providers: [TopicService]
24 | })
25 | export class TopicsPage {
26 |
27 | topics: Topic[] = [];
28 |
29 |
30 | constructor(
31 | public navCtrl: NavController,
32 | public navParams: NavParams,
33 | private topicService: TopicService,
34 | public modalCtrl: ModalController
35 | ) {
36 | }
37 |
38 | ngOnInit(): void {
39 | let newTab = this.navParams.get('tab');
40 | if (newTab) {
41 | console.log('changing tab');
42 | this.topicService.currentTab = newTab;
43 | }
44 | console.log('current tab', this.topicService.currentTab);
45 | this.doRefresh();
46 | }
47 |
48 | ionViewDidLoad() {
49 | console.log('ionViewDidLoad TopicsPage');
50 | }
51 |
52 | onSelect(topic: Topic): void {
53 | console.log(topic)
54 | this.navCtrl.push('topic', {id: topic.id})
55 | }
56 |
57 | getTopics(): void {
58 | this.topicService.getTopics().then(
59 | topics => this.topics = topics
60 | );
61 | }
62 |
63 | doRefresh(refresher = undefined): void {
64 | console.log('do refresh')
65 | this.topicService.refresh().then(
66 | (topics) => {
67 | this.topics = topics;
68 | if (refresher) {
69 | refresher.complete();
70 | }
71 | }
72 | );
73 | }
74 |
75 | loadMore(infiniteScroll): void {
76 | console.log('do infinite');
77 | this.topicService.pagination().then(
78 | (topics) => {
79 | this.topics = this.topics.concat(topics)
80 | infiniteScroll.complete();
81 | }
82 | );
83 | }
84 |
85 | showNewTopicModal (): void {
86 | console.log('new topic modal');
87 |
88 | let modal = this.modalCtrl.create(NewTopicModal);
89 | modal.present();
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/src/theme/variables.scss:
--------------------------------------------------------------------------------
1 | // Ionic Variables and Theming. For more info, please see:
2 | // http://ionicframework.com/docs/v2/theming/
3 | $font-path: "../assets/fonts";
4 |
5 | @import "ionic.globals";
6 |
7 |
8 | // Shared Variables
9 | // --------------------------------------------------
10 | // To customize the look and feel of this app, you can override
11 | // the Sass variables found in Ionic's source scss files.
12 | // To view all the possible Ionic variables, see:
13 | // http://ionicframework.com/docs/v2/theming/overriding-ionic-variables/
14 |
15 |
16 |
17 |
18 | // Named Color Variables
19 | // --------------------------------------------------
20 | // Named colors makes it easy to reuse colors on various components.
21 | // It's highly recommended to change the default colors
22 | // to match your app's branding. Ionic uses a Sass map of
23 | // colors so you can add, rename and remove colors as needed.
24 | // The "primary" color is the only required color in the map.
25 |
26 | $colors: (
27 | primary: #387ef5,
28 | secondary: #32db64,
29 | danger: #f53d3d,
30 | light: #f4f4f4,
31 | dark: #222
32 | );
33 |
34 |
35 | // App iOS Variables
36 | // --------------------------------------------------
37 | // iOS only Sass variables can go here
38 |
39 |
40 |
41 |
42 | // App Material Design Variables
43 | // --------------------------------------------------
44 | // Material Design only Sass variables can go here
45 |
46 |
47 |
48 |
49 | // App Windows Variables
50 | // --------------------------------------------------
51 | // Windows only Sass variables can go here
52 |
53 |
54 |
55 |
56 | // App Theme
57 | // --------------------------------------------------
58 | // Ionic apps can have different themes applied, which can
59 | // then be future customized. This import comes last
60 | // so that the above variables are used and Ionic's
61 | // default are overridden.
62 |
63 | @import "ionic.theme.default";
64 |
65 |
66 | // Ionicons
67 | // --------------------------------------------------
68 | // The premium icon font for Ionic. For more info, please see:
69 | // http://ionicframework.com/docs/v2/ionicons/
70 |
71 | @import "ionic.ionicons";
72 |
73 |
74 | // Fonts
75 | // --------------------------------------------------
76 |
77 | @import "roboto";
78 | @import "noto-sans";
79 |
80 | // Colors
81 | // -------------------------------
82 |
83 | $node-green: #80bd01;
84 | $node-black: #444;
85 |
--------------------------------------------------------------------------------
/src/providers/user-service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Http, Headers, RequestOptions } from '@angular/http';
3 | import { Storage } from '@ionic/storage';
4 | import 'rxjs/add/operator/map';
5 | import 'rxjs/add/operator/toPromise';
6 |
7 | import { ConfigService } from './config-service';
8 | import { User } from '../classes/user';
9 |
10 | /*
11 | Generated class for the UserService provider.
12 |
13 | See https://angular.io/docs/ts/latest/guide/dependency-injection.html
14 | for more info on providers and Angular 2 DI.
15 | */
16 | @Injectable()
17 | export class UserService {
18 | private userUrl: string
19 | private authUrl: string
20 | private user: User
21 | private storageKey = 'user'
22 |
23 | constructor(public http: Http, public storage: Storage, public configService: ConfigService) {
24 | console.log('Hello UserService Provider');
25 | this.userUrl = configService.api + 'user';
26 | this.authUrl = configService.api + 'accesstoken';
27 | }
28 |
29 | getCurrentUser(): Promise {
30 | console.log('current user:', this.user);
31 | if (this.user) {
32 | return new Promise((resolve, reject) => {
33 | resolve(this.user);
34 | });
35 | } else {
36 | return this.storage.get(this.storageKey).then((user) => {
37 | console.log('user storage', user);
38 | this.user = user;
39 | return this.user;
40 | });
41 | }
42 | }
43 |
44 | getByLoginName(loginName: string): Promise {
45 | return this.http.get(`${this.userUrl}/${loginName}`)
46 | .toPromise()
47 | .then(
48 | (resposne) => {
49 | console.log(resposne);
50 | return resposne.json().data as User;
51 | }
52 | )
53 | }
54 |
55 | login(accesstoken: string): Promise {
56 | let body = JSON.stringify({
57 | accesstoken: accesstoken
58 | });
59 | let headers = new Headers({
60 | 'content-type': 'application/json'
61 | });
62 | let options = new RequestOptions({
63 | headers: headers
64 | });
65 | return this.http.post(this.authUrl, body, options).toPromise().then((response) => {
66 | //$log.debug('post accesstoken:', response);
67 | let authResp = response.json();
68 | this.user = authResp as User;
69 | return this.getByLoginName(authResp.loginname).then((user) => {
70 | this.user = user;
71 | this.user.id = authResp.id;
72 | this.user.accesstoken = accesstoken;
73 | this.user.loginname = authResp.loginname;
74 |
75 | this.storage.ready().then(() => {
76 | this.storage.set(this.storageKey, user);
77 | });
78 | return this.user;
79 | });
80 | });
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/providers/topic-service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Http, Headers, RequestOptions } from '@angular/http';
3 | import 'rxjs/add/operator/map';
4 | import 'rxjs/add/operator/toPromise';
5 |
6 | import { ConfigService } from '../providers/config-service';
7 | import { Topic } from '../classes/topic';
8 |
9 | import { UserService } from './user-service';
10 |
11 | /*
12 | Generated class for the TopicService provider.
13 |
14 | See https://angular.io/docs/ts/latest/guide/dependency-injection.html
15 | for more info on providers and Angular 2 DI.
16 | */
17 | @Injectable()
18 | export class TopicService {
19 | private topicsUrl: string
20 | private topicUrl: string
21 | currentTab: string = 'all'
22 | private nextPage: number = 2
23 | private hasNextPage: boolean = true
24 | topics: Topic[] = []
25 |
26 | constructor(
27 | public http: Http,
28 | public configService: ConfigService,
29 | private userService: UserService
30 | ) {
31 | console.log('Hello TopicService Provider');
32 | this.topicsUrl = configService.api + 'topics';
33 | this.topicUrl = configService.api + 'topic';
34 | }
35 |
36 | getTopicById(id: string): Promise{
37 | return this.http.get(`${this.topicUrl}/${id}`)
38 | .toPromise()
39 | .then(
40 | (resposne) => {
41 | console.log(resposne);
42 | return resposne.json().data as Topic
43 | }
44 | )
45 | }
46 | getTopics(tab: string = 'all', page: number = 1, limit: number = 40): Promise {
47 | return this.http.get(`${this.topicsUrl}?tab=${tab}&page=${page}&limit=${limit}`)
48 | .toPromise()
49 | .then(
50 | (resposne) => {
51 | console.log(resposne);
52 | return resposne.json().data as Topic[]
53 | }
54 | );
55 | }
56 |
57 | refresh(): Promise {
58 | console.log(`current tab: ${this.currentTab}, page number 1`);
59 | return this.getTopics(this.currentTab, 1).then(
60 | (topics) => {
61 | this.nextPage = 2
62 | this.hasNextPage = true
63 | this.topics = topics
64 | return Promise.resolve(this.topics);
65 | }
66 | );
67 | }
68 |
69 | pagination(): Promise {
70 | console.log(`current tab: ${this.currentTab}, next page number ${this.nextPage}`);
71 | return this.getTopics(this.currentTab, this.nextPage).then(
72 | (topics) => {
73 | if (topics.length < 10) {
74 | this.hasNextPage = false
75 | }
76 | this.nextPage++;
77 | this.topics = this.topics.concat(topics)
78 | return Promise.resolve(this.topics);
79 | }
80 | );
81 | }
82 | saveNewTopic(newTopicData) {
83 | let body = JSON.stringify(newTopicData);
84 | let headers = new Headers({
85 | 'content-type': 'application/json'
86 | });
87 | let options = new RequestOptions({
88 | headers: headers
89 | });
90 | return this.userService.getCurrentUser().then((currentUser) => {
91 | return this.http.post(`${this.topicsUrl}?accesstoken=${currentUser.accesstoken}`, body, options).toPromise()
92 | })
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ViewChild } from '@angular/core';
2 | import { Nav, Platform, AlertController } from 'ionic-angular';
3 | import { StatusBar } from '@ionic-native/status-bar';
4 | import { SplashScreen } from '@ionic-native/splash-screen';
5 |
6 | import { ConfigService } from '../providers/config-service';
7 |
8 | import { TabsService } from '../providers/tabs-service';
9 | import { UserService } from '../providers/user-service';
10 | import { MessageService } from '../providers/message-service';
11 | import { Tab } from '../classes/tab';
12 | import { User } from '../classes/user';
13 |
14 |
15 | @Component({
16 | templateUrl: 'app.html',
17 | providers: [
18 | TabsService,
19 | UserService,
20 | MessageService
21 | ]
22 | })
23 | export class MyApp {
24 | @ViewChild(Nav) nav: Nav;
25 |
26 | rootPage: any;
27 |
28 | tabs: Tab[];
29 |
30 | user: User;
31 | messagesCount: 0;
32 |
33 | constructor(
34 | public platform: Platform,
35 | statusBar: StatusBar,
36 | splashScreen: SplashScreen,
37 | private configService: ConfigService,
38 | private tabsService: TabsService,
39 | private userService: UserService,
40 | private messageService: MessageService,
41 | private alertCtrl: AlertController
42 | ) {
43 | platform.ready().then(() => {
44 | // Okay, so the platform is ready and our plugins are available.
45 | // Here you can do any higher level native things you might need.
46 | statusBar.styleDefault();
47 | splashScreen.hide();
48 | });
49 | }
50 |
51 | initializeApp() {
52 | }
53 |
54 | ngOnInit() {
55 | console.log('ng on init');
56 | }
57 |
58 | ngAfterViewInit() {
59 | console.log('ng after view init');
60 |
61 | this.userService.getCurrentUser().then((user) => {
62 | this.user = user;
63 | });
64 | this.tabs = this.tabsService.getTabs();
65 | this.nav.setRoot('topics', {
66 | tab: this.tabs[0].value
67 | });
68 | }
69 |
70 | openTab(tab: any) {
71 | console.log('open tab', tab)
72 | this.nav.setRoot('topics', {
73 | tab: tab.value
74 | });
75 | }
76 |
77 | gotoUserPage(loginName: String) {
78 | console.log('goto user', loginName);
79 | this.nav.setRoot('user', {loginName: loginName})
80 | }
81 |
82 | gotoMessagePage() {
83 | console.log('go to message page')
84 | this.nav.setRoot('message');
85 | }
86 |
87 | getMessageCount() {
88 | this.messageService.getMessageCount().then((response) => {
89 | this.messagesCount = response.data;
90 | //setBadge($scope.messagesCount);
91 | }, function(response) {
92 | //$log.log('get messages count fail', response);
93 | });
94 | };
95 |
96 | // login action callback
97 | loginCallback(user: User) {
98 | console.log('login callback', arguments);
99 | this.user = user;
100 | this.getMessageCount();
101 | }
102 |
103 | login() {
104 | console.log('login');
105 | // login automatic if have token
106 | if (this.configService.token) {
107 | this.userService.login(this.configService.token).then((response) => {
108 | this.loginCallback(response);
109 | });
110 | } else {
111 | let alert = this.alertCtrl.create({
112 | title: '输入Access Token',
113 | subTitle: 'PC端登录cnodejs.org后,在设置页可以找到Access Token',
114 | inputs: [
115 | {
116 | name: 'token',
117 | placeholder: 'Token'
118 | }
119 | ],
120 | buttons: [
121 | {
122 | text: '取消',
123 | role: 'cancel',
124 | handler: data => {
125 | console.log('Cancel clicked');
126 | }
127 | },
128 | {
129 | text: '提交',
130 | handler: data => {
131 | console.log(data);
132 | if (data.token) {
133 | this.userService.login(data.token).then((response) => {
134 | this.loginCallback(response);
135 | });
136 | }
137 | }
138 | }
139 | ]
140 | });
141 | alert.present();
142 | }
143 | }
144 | }
145 |
--------------------------------------------------------------------------------