├── .chcpenv ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── LICENSE ├── README.md ├── config.xml ├── cordova-hcp.json ├── doc └── super2.png ├── ionic.config.json ├── mock ├── login ├── pages └── slides ├── package-lock.json ├── package.json ├── resources ├── README.md ├── 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-land-xxhdpi-screen.png │ │ ├── drawable-land-xxxhdpi-screen.png │ │ ├── drawable-port-hdpi-screen.png │ │ ├── drawable-port-ldpi-screen.png │ │ ├── drawable-port-mdpi-screen.png │ │ ├── drawable-port-xhdpi-screen.png │ │ ├── drawable-port-xxhdpi-screen.png │ │ └── drawable-port-xxxhdpi-screen.png ├── icon.png ├── ios │ ├── icon │ │ ├── icon-1024.png │ │ ├── icon-40.png │ │ ├── icon-40@2x.png │ │ ├── icon-40@3x.png │ │ ├── icon-50.png │ │ ├── icon-50@2x.png │ │ ├── icon-60.png │ │ ├── icon-60@2x.png │ │ ├── icon-60@3x.png │ │ ├── icon-72.png │ │ ├── icon-72@2x.png │ │ ├── icon-76.png │ │ ├── icon-76@2x.png │ │ ├── icon-83.5@2x.png │ │ ├── icon-small.png │ │ ├── icon-small@2x.png │ │ ├── icon-small@3x.png │ │ ├── icon.png │ │ └── icon@2x.png │ └── splash │ │ ├── Default-568h@2x~iphone.png │ │ ├── Default-667h.png │ │ ├── Default-736h.png │ │ ├── Default-Landscape-736h.png │ │ ├── Default-Landscape@2x~ipad.png │ │ ├── Default-Landscape@~ipadpro.png │ │ ├── Default-Landscape~ipad.png │ │ ├── Default-Portrait@2x~ipad.png │ │ ├── Default-Portrait@~ipadpro.png │ │ ├── Default-Portrait~ipad.png │ │ ├── Default@2x~iphone.png │ │ ├── Default@2x~universal~anyany.png │ │ └── Default~iphone.png └── splash.png ├── src ├── app │ ├── app.component.ts │ ├── app.module.ts │ ├── app.scss │ └── main.ts ├── assets │ ├── i18n │ │ ├── en.json │ │ └── zh.json │ ├── icon │ │ └── favicon.ico │ └── img │ │ ├── advert.png │ │ ├── ian-avatar.png │ │ ├── ica-slidebox-img-1.png │ │ ├── ica-slidebox-img-2.png │ │ ├── ica-slidebox-img-3.png │ │ └── splashbg.png ├── components │ ├── components.module.ts │ └── ion-card-list │ │ ├── ion-card-list.html │ │ ├── ion-card-list.scss │ │ └── ion-card-list.ts ├── index.html ├── manifest.json ├── pages │ ├── README.md │ ├── advert │ │ ├── advert.html │ │ ├── advert.module.ts │ │ ├── advert.scss │ │ └── advert.ts │ ├── chat │ │ ├── chat.html │ │ ├── chat.module.ts │ │ ├── chat.scss │ │ └── chat.ts │ ├── home │ │ ├── home.html │ │ ├── home.module.ts │ │ ├── home.scss │ │ └── home.ts │ ├── item-create │ │ ├── README.md │ │ ├── item-create.html │ │ ├── item-create.module.ts │ │ ├── item-create.scss │ │ └── item-create.ts │ ├── login │ │ ├── README.md │ │ ├── login.html │ │ ├── login.module.ts │ │ ├── login.scss │ │ └── login.ts │ ├── news │ │ ├── news.html │ │ ├── news.module.ts │ │ ├── news.scss │ │ └── news.ts │ ├── pages.ts │ ├── profile │ │ ├── profile.html │ │ ├── profile.module.ts │ │ ├── profile.scss │ │ └── profile.ts │ ├── search │ │ ├── search.html │ │ ├── search.module.ts │ │ ├── search.scss │ │ └── search.ts │ ├── settings │ │ ├── README.md │ │ ├── settings.html │ │ ├── settings.module.ts │ │ ├── settings.scss │ │ └── settings.ts │ ├── signup │ │ ├── README.md │ │ ├── signup.html │ │ ├── signup.module.ts │ │ ├── signup.scss │ │ └── signup.ts │ ├── tabs │ │ ├── README.md │ │ ├── tabs.html │ │ ├── tabs.module.ts │ │ ├── tabs.scss │ │ └── tabs.ts │ └── tutorial │ │ ├── README.md │ │ ├── tutorial.html │ │ ├── tutorial.module.ts │ │ ├── tutorial.scss │ │ └── tutorial.ts ├── providers │ ├── api │ │ └── api.ts │ ├── browser │ │ └── browser.ts │ ├── constant │ │ └── constant.ts │ ├── jwt-interceptor │ │ └── jwt-interceptor.ts │ ├── providers.ts │ ├── settings │ │ └── settings.ts │ └── user │ │ └── user.ts ├── service-worker.js └── theme │ └── variables.scss ├── tsconfig.json └── tslint.json /.chcpenv: -------------------------------------------------------------------------------- 1 | { 2 | "content_url": "https://83eef14a.ngrok.io", 3 | "config_url": "https://83eef14a.ngrok.io/chcp.json" 4 | } 5 | -------------------------------------------------------------------------------- /.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 -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **I'm submitting a ...** (check one with "x") 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/ 5 | 6 | **Current behavior:** 7 | 8 | 9 | **Expected behavior:** 10 | 11 | 12 | **Steps to reproduce:** 13 | 18 | 19 | **Related code:** 20 | 21 | ``` 22 | insert any relevant code here 23 | ``` 24 | 25 | **Other information:** 26 | 27 | 28 | **Ionic info:** (run `ionic info` from a terminal/cmd prompt and paste output below): 29 | 30 | ``` 31 | insert the output from ionic info here 32 | ``` 33 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | #### Short description of what this resolves: 2 | 3 | 4 | #### Changes proposed in this pull request: 5 | 6 | - 7 | - 8 | - 9 | 10 | **Fixes**: # 11 | -------------------------------------------------------------------------------- /.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 | .sourcemaps/ 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2015-present Drifty Co. 2 | http://ionicframework.com/ 3 | 4 | MIT License 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | "Software"), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring4All App 🎮 2 | 3 | 4 | 5 | - Just Run App 6 | > _Note: the Ionic Super Starter requires Ionic CLI 3._ 7 | ## 1、安装 8 | 9 | #### 环境搭建 10 | `npm install -g ionic cordova` 11 | 12 | ## 2、部署 13 | #### 安装依赖 14 | `npm i` 15 | #### 浏览器启动 16 | `ionic serve` 17 | 18 | ## 3、打包 19 | #### 3-1 添加平台 20 | 21 | ```bash 22 | ionic cordova platform add ios 23 | ionic cordova platform add android 24 | ``` 25 | 26 | ```bash 27 | -- android 28 | ionic cordova run android 29 | 30 | ionic cordova run android --prod --release 31 | ionic cordova build android --prod --release 32 | 33 | -- ios 34 | ionic cordova run ios 35 | 36 | ionic cordova run ios --prod --release 37 | ionic cordova build ios --prod --release 38 | 39 | 40 | ``` 41 | 42 | #### 3-2 真机 43 | ```bash 44 | - usb 手机连接电脑,手机开启开发者模式 45 | ionic cordova run android --device 46 | ionic cordova run ios --device 47 | 48 | ``` 49 | 50 | -------- 51 | 52 | The Ionic Super Starter is a batteries-included starter project for Ionic apps complete with pre-built pages, providers, and best practices for Ionic development. 53 | 54 | The goal of the Super Starter is to get you from zero to app store faster than before, with a set of opinions from the Ionic team around page layout, data/user management, and project structure. 55 | 56 | The way to use this starter is to pick and choose the various page types you want use, and remove the ones you don't. If you want a blank slate, this starter isn't for you (use the `blank` type instead). 57 | 58 | One of the big advances in Ionic was moving from a rigid route-based navigation system to a flexible push/pop navigation system modeled off common native SDKs. We've embraced this pattern to provide a set of reusable pages that can be navigated to anywhere in the app. Take a look at the [Settings page](https://github.com/ionic-team/ionic-starter-super/blob/master/src/pages/settings/settings.html#L38) for a cool example of a page navigating to itself to provide a different UI without duplicating code. 59 | 60 | ## Pages 61 | 62 | The Super Starter comes with a variety of ready-made pages. These pages help you assemble common building blocks for your app so you can focus on your unique features and branding. 63 | 64 | The app loads with the `FirstRunPage` set to `TutorialPage` as the default. If the user has already gone through this page once, it will be skipped the next time they load the app. 65 | 66 | If the tutorial is skipped but the user hasn't logged in yet, the Welcome page will be displayed which is a "splash" prompting the user to log in or create an account. 67 | 68 | Once the user is authenticated, the app will load with the `MainPage` which is set to be the `TabsPage` as the default. 69 | 70 | The entry and main pages can be configured easily by updating the corresponding variables in [src/pages/pages.ts](https://github.com/ionic-team/ionic-starter-super/blob/master/src/pages/pages.ts). 71 | 72 | 73 | ## Providers 74 | 75 | The Super Starter comes with some basic implementations of common providers. 76 | 77 | ### User 78 | 79 | The `User` provider is used to authenticate users through its `login(accountInfo)` and `signup(accountInfo)` methods, which perform `POST` requests to an API endpoint that you will need to configure. 80 | 81 | ### Api 82 | 83 | The `Api` provider is a simple CRUD frontend to an API. Simply put the root of your API url in the Api class and call get/post/put/patch/delete 84 | 85 | ## i18n 86 | 87 | Ionic Super Starter comes with internationalization (i18n) out of the box with [ngx-translate](https://github.com/ngx-translate/core). This makes it easy to change the text used in the app by modifying only one file. 88 | 89 | ### Adding Languages 90 | 91 | To add new languages, add new files to the `src/assets/i18n` directory, following the pattern of LANGCODE.json where LANGCODE is the language/locale code (ex: en/gb/de/es/etc.). 92 | 93 | ### Changing the Language 94 | 95 | To change the language of the app, edit `src/app/app.component.ts` and modify `translate.use('en')` to use the LANGCODE from `src/assets/i18n/` 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Spring4All 4 | Spring4All 5 | Spring4All 6 | 7 | 8 | 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 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /cordova-hcp.json: -------------------------------------------------------------------------------- 1 | { 2 | "autogenerated": true, 3 | "content_url": "https://83eef14a.ngrok.io", 4 | "min_native_interface": 1, // app内核版本号 5 | "ios_identifier": "https://itunes.apple.com/cn/app/***", // iOS上线后的地址,用于内核版本更新后的确认跳转 6 | "update": "now" 7 | } 8 | -------------------------------------------------------------------------------- /doc/super2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/doc/super2.png -------------------------------------------------------------------------------- /ionic.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spring4all", 3 | "app_id": "", 4 | "type": "ionic-angular", 5 | "integrations": { 6 | "cordova": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /mock/login: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "data": { 4 | "name":"yanghuiqiang", 5 | "avator":"https://avatars2.githubusercontent.com/u/13185035" 6 | }, 7 | "msg": "success" 8 | } 9 | -------------------------------------------------------------------------------- /mock/pages: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "data": [ 4 | { 5 | "title": "MySQL Schema与数据类型的优化", 6 | "abstract": "选择优化的数据类型: 1、 更小的通常更好: 一般情况下,应该尽量使用可以正确存储数据的最小数据类型。更小的数据类型通常更快,因为他们占用更少的磁盘,内存和cpu缓存,并且处理时需要的cpu周期也更少", 7 | "time": "杨小强 发布于 4小时前", 8 | "like": "12", 9 | "commit": "21", 10 | "url":"https://juejin.im/entry/59f7d707f265da430c111b62" 11 | }, 12 | { 13 | "title": "疯狂Spring Cloud连载(十一)——Feign的编码器与解码器", 14 | "abstract": " 本文节选自《疯狂Spring Cloud微服务架构实战》,本书将于2017年11月出版。 Spring Cloud教学视频:https://my.oschina.net/JavaLaw/blog/1552993 本书代码共享地址:https://gitee.com/y", 15 | "time": "杨小强 发布于 一年前", 16 | "like": "122", 17 | "commit": "101", 18 | "url":"https://juejin.im/entry/59f7d707f265da430c111b62" 19 | }, 20 | { 21 | "title": "MySQL Schema与数据类型的优化", 22 | "abstract": "选择优化的数据类型: 1、 更小的通常更好: 一般情况下,应该尽量使用可以正确存储数据的最小数据类型。更小的数据类型通常更快,因为他们占用更少的磁盘,内存和cpu缓存,并且处理时需要的cpu周期也更少", 23 | "time": "杨小强 发布于 4小时前", 24 | "like": "12", 25 | "commit": "21", 26 | "url":"https://juejin.im/entry/59f7d707f265da430c111b62" 27 | }, 28 | { 29 | "title": "疯狂Spring Cloud连载(十一)——Feign的编码器与解码器", 30 | "abstract": " 本文节选自《疯狂Spring Cloud微服务架构实战》,本书将于2017年11月出版。 Spring Cloud教学视频:https://my.oschina.net/JavaLaw/blog/1552993 本书代码共享地址:https://gitee.com/y", 31 | "time": "杨小强 发布于 一年前", 32 | "like": "122", 33 | "commit": "101", 34 | "url":"https://juejin.im/entry/59f7d707f265da430c111b62" 35 | }, 36 | { 37 | "title": "MySQL Schema与数据类型的优化", 38 | "abstract": "选择优化的数据类型: 1、 更小的通常更好: 一般情况下,应该尽量使用可以正确存储数据的最小数据类型。更小的数据类型通常更快,因为他们占用更少的磁盘,内存和cpu缓存,并且处理时需要的cpu周期也更少", 39 | "time": "杨小强 发布于 4小时前", 40 | "like": "12", 41 | "commit": "21", 42 | "url":"https://juejin.im/entry/59f7d707f265da430c111b62" 43 | }, 44 | { 45 | "title": "疯狂Spring Cloud连载(十一)——Feign的编码器与解码器", 46 | "abstract": " 本文节选自《疯狂Spring Cloud微服务架构实战》,本书将于2017年11月出版。 Spring Cloud教学视频:https://my.oschina.net/JavaLaw/blog/1552993 本书代码共享地址:https://gitee.com/y", 47 | "time": "杨小强 发布于 一年前", 48 | "like": "122", 49 | "commit": "101", 50 | "url":"https://juejin.im/entry/59f7d707f265da430c111b62" 51 | } 52 | ], 53 | "msg": "success" 54 | } 55 | -------------------------------------------------------------------------------- /mock/slides: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "data": [ 4 | { 5 | "img": "http://images.csdn.net/20171023/u=1656509100,1818539814&fm=27&gp=0.jpg", 6 | "title": "2017年含金量最高的机器学习技能或知识有哪些?", 7 | "url":"https://juejin.im/entry/59f7d707f265da430c111b62" 8 | }, 9 | { 10 | "img": "http://images.csdn.net/20170704/1.png", 11 | "title": "世界上第一个时序数据的Middle-Out算法压缩", 12 | "url":"https://juejin.im/entry/59f7d707f265da430c111b62" 13 | }, 14 | { 15 | "img": "http://images.csdn.net/20171019/20171019084609390_%E5%89%AF%E6%9C%AC.jpg", 16 | "title": "不能给祖国母亲添堵!技术人讲解十九大期间如何护航网站安全", 17 | "url":"https://juejin.im/entry/59f7d707f265da430c111b62" 18 | }, 19 | { 20 | "img": "http://images.csdn.net/20171023/u=1656509100,1818539814&fm=27&gp=0.jpg", 21 | "title": "2017年含金量最高的机器学习技能或知识有哪些?", 22 | "url":"https://juejin.im/entry/59f7d707f265da430c111b62" 23 | }, 24 | { 25 | "img": "http://images.csdn.net/20170704/1.png", 26 | "title": "世界上第一个时序数据的Middle-Out算法压缩", 27 | "url":"https://juejin.im/entry/59f7d707f265da430c111b62" 28 | } 29 | ], 30 | "msg": "success" 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spring4all", 3 | "version": "0.0.1", 4 | "author": "spring4all team", 5 | "homepage": "http://spring4all.com/", 6 | "private": true, 7 | "scripts": { 8 | "clean": "ionic-app-scripts clean", 9 | "build": "ionic-app-scripts build", 10 | "lint": "ionic-app-scripts lint", 11 | "ionic:build": "ionic-app-scripts build", 12 | "ionic:serve": "ionic-app-scripts serve" 13 | }, 14 | "dependencies": { 15 | "@angular/common": "4.4.3", 16 | "@angular/compiler": "4.4.3", 17 | "@angular/compiler-cli": "4.4.3", 18 | "@angular/core": "4.4.3", 19 | "@angular/forms": "4.4.3", 20 | "@angular/http": "4.4.3", 21 | "@angular/platform-browser": "4.4.3", 22 | "@angular/platform-browser-dynamic": "4.4.3", 23 | "@ionic-native/camera": "4.3.1", 24 | "@ionic-native/core": "4.3.0", 25 | "@ionic-native/splash-screen": "4.3.0", 26 | "@ionic-native/status-bar": "4.3.0", 27 | "@ionic-native/themeable-browser": "^4.3.2", 28 | "@ionic/storage": "2.0.1", 29 | "@ngx-translate/core": "8.0.0", 30 | "@ngx-translate/http-loader": "^2.0.0", 31 | "cordova-android": "6.3.0", 32 | "cordova-hot-code-push-local-dev-addon": "^0.4.2", 33 | "cordova-hot-code-push-plugin": "^1.5.3", 34 | "cordova-ios": "4.5.2", 35 | "cordova-plugin-device": "^1.1.4", 36 | "cordova-plugin-ionic-webview": "^1.1.15", 37 | "cordova-plugin-splashscreen": "^4.0.3", 38 | "cordova-plugin-themeablebrowser": "^0.2.17", 39 | "cordova-plugin-whitelist": "^1.3.1", 40 | "ionic-angular": "3.7.1", 41 | "ionic-native": "^2.9.0", 42 | "ionic-plugin-keyboard": "^2.2.1", 43 | "ionicons": "3.0.0", 44 | "rxjs": "5.4.3", 45 | "sw-toolbox": "3.6.0", 46 | "zone.js": "0.8.18" 47 | }, 48 | "devDependencies": { 49 | "@ionic/app-scripts": "3.0.0", 50 | "typescript": "2.3.4" 51 | }, 52 | "description": "An Ionic project", 53 | "cordova": { 54 | "plugins": { 55 | "ionic-plugin-keyboard": {}, 56 | "cordova-plugin-whitelist": {}, 57 | "cordova-plugin-device": {}, 58 | "cordova-plugin-splashscreen": {}, 59 | "cordova-plugin-ionic-webview": {}, 60 | "cordova-plugin-themeablebrowser": {}, 61 | "cordova-hot-code-push-plugin": {}, 62 | "cordova-hot-code-push-local-dev-addon": {} 63 | }, 64 | "platforms": [ 65 | "android", 66 | "ios" 67 | ] 68 | } 69 | } -------------------------------------------------------------------------------- /resources/README.md: -------------------------------------------------------------------------------- 1 | These are Cordova resources. You can replace icon.png and splash.png and run 2 | `ionic cordova resources` to generate custom icons and splash screens for your 3 | app. See `ionic cordova resources --help` for details. 4 | 5 | Cordova reference documentation: 6 | 7 | - Icons: https://cordova.apache.org/docs/en/latest/config_ref/images.html 8 | - Splash Screens: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-splashscreen/ 9 | -------------------------------------------------------------------------------- /resources/android/icon/drawable-hdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/icon/drawable-hdpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-ldpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/icon/drawable-ldpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-mdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/icon/drawable-mdpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-xhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/icon/drawable-xhdpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-xxhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/icon/drawable-xxhdpi-icon.png -------------------------------------------------------------------------------- /resources/android/icon/drawable-xxxhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/icon/drawable-xxxhdpi-icon.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-hdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/splash/drawable-land-hdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-ldpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/splash/drawable-land-ldpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-mdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/splash/drawable-land-mdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-xhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/splash/drawable-land-xhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-xxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/splash/drawable-land-xxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-land-xxxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/splash/drawable-land-xxxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-hdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/splash/drawable-port-hdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-ldpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/splash/drawable-port-ldpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-mdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/splash/drawable-port-mdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-xhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/splash/drawable-port-xhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-xxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/splash/drawable-port-xxhdpi-screen.png -------------------------------------------------------------------------------- /resources/android/splash/drawable-port-xxxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/android/splash/drawable-port-xxxhdpi-screen.png -------------------------------------------------------------------------------- /resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/icon.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-1024.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-40.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-40@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-40@3x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-50.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-50@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-60.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-60@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-60@3x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-72.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-72@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-76.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-76@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-83.5@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-small.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-small@2x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon-small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon-small@3x.png -------------------------------------------------------------------------------- /resources/ios/icon/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon.png -------------------------------------------------------------------------------- /resources/ios/icon/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/icon/icon@2x.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-568h@2x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default-568h@2x~iphone.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-667h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default-667h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-736h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default-736h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape-736h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default-Landscape-736h.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default-Landscape@2x~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape@~ipadpro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default-Landscape@~ipadpro.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Landscape~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default-Landscape~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Portrait@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default-Portrait@2x~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Portrait@~ipadpro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default-Portrait@~ipadpro.png -------------------------------------------------------------------------------- /resources/ios/splash/Default-Portrait~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default-Portrait~ipad.png -------------------------------------------------------------------------------- /resources/ios/splash/Default@2x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default@2x~iphone.png -------------------------------------------------------------------------------- /resources/ios/splash/Default@2x~universal~anyany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default@2x~universal~anyany.png -------------------------------------------------------------------------------- /resources/ios/splash/Default~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/ios/splash/Default~iphone.png -------------------------------------------------------------------------------- /resources/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/resources/splash.png -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, ViewChild} from '@angular/core'; 2 | import {SplashScreen} from '@ionic-native/splash-screen'; 3 | import {StatusBar} from '@ionic-native/status-bar'; 4 | import {TranslateService} from '@ngx-translate/core'; 5 | import {Config, Nav, Platform, ToastController} from 'ionic-angular'; 6 | import {AdvertPage, FirstRunPage} from '../pages/pages'; 7 | import {TabsPage} from "../pages/tabs/tabs"; 8 | import {User} from '../providers/providers'; 9 | 10 | @Component({ 11 | template: ` 12 | ` 13 | }) 14 | export class MyApp { 15 | rootPage: any; 16 | backButtonPressed: boolean = false; 17 | 18 | @ViewChild(Nav) nav: Nav; 19 | 20 | constructor(private translate: TranslateService, 21 | public platform: Platform, 22 | private toastCtrl: ToastController, 23 | public config: Config, 24 | private statusBar: StatusBar, 25 | private user: User, 26 | private splashScreen: SplashScreen) { 27 | platform.ready().then(() => { 28 | // Okay, so the platform is ready and our plugins are available. 29 | // Here you can do any higher level native things you might need. 30 | this.statusBar.hide(); 31 | this.splashScreen.hide(); 32 | this.registerBackButtonAction(); 33 | this.registerAuthentication(); 34 | }); 35 | this.initTranslate(); 36 | } 37 | 38 | initTranslate() { 39 | // Set the default language for translation strings, and the current language. 40 | this.translate.setDefaultLang('zh'); 41 | 42 | if (this.translate.getBrowserLang() !== undefined) { 43 | this.translate.use('zh'); // Set your language here 44 | // this.translate.use(this.translate.getBrowserLang()); 45 | } else { 46 | this.translate.use('zh'); // Set your language here 47 | } 48 | 49 | this.translate.get(['BACK_BUTTON_TEXT']).subscribe(values => { 50 | this.config.set('ios', 'backButtonText', values.BACK_BUTTON_TEXT); 51 | }); 52 | } 53 | 54 | openPage(page) { 55 | // Reset the content nav to have just this page 56 | // we wouldn't want the back button to show in this scenario 57 | this.nav.setRoot(page.component); 58 | } 59 | 60 | registerAuthentication() { 61 | this.user.getToken().then(token=>{ 62 | if (token) { 63 | return this.rootPage = AdvertPage; 64 | } 65 | return this.rootPage = FirstRunPage; 66 | }) 67 | } 68 | 69 | registerBackButtonAction() { 70 | this.platform.registerBackButtonAction((): any => { 71 | let activeVC = this.nav.getActive(); 72 | let page = activeVC.instance; 73 | if (!(page instanceof TabsPage)) { 74 | if (!this.nav.canGoBack()) { 75 | //当前页面为tabs,退出APP 76 | return this.showExit(); 77 | } 78 | //当前页面为tabs的子页面,正常返回 79 | return this.nav.pop(); 80 | } 81 | let tabs = page.tabs; 82 | let activeNav = tabs.getSelected(); 83 | if (!activeNav.canGoBack()) { 84 | //当前页面为tab栏,退出APP 85 | return this.showExit(); 86 | } 87 | //当前页面为tab栏的子页面,正常返回 88 | return activeNav.pop(); 89 | }, 101); 90 | } 91 | 92 | //双击退出提示框 93 | showExit() { 94 | if (this.backButtonPressed) { 95 | this.platform.exitApp(); 96 | } else { 97 | let toast = this.toastCtrl.create({ 98 | message: '再按一次退出应用', 99 | duration: 2000, 100 | position: 'bottom' 101 | }); 102 | toast.present(); 103 | this.backButtonPressed = true; 104 | //2秒内没有再次点击返回则将触发标志标记为false 105 | setTimeout(() => { 106 | this.backButtonPressed = false; 107 | }, 2000) 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import {HTTP_INTERCEPTORS, HttpClient, HttpClientModule} from '@angular/common/http'; 2 | import {ErrorHandler, NgModule} from '@angular/core'; 3 | import {BrowserModule} from '@angular/platform-browser'; 4 | import {Camera} from '@ionic-native/camera'; 5 | import {SplashScreen} from '@ionic-native/splash-screen'; 6 | import {StatusBar} from '@ionic-native/status-bar'; 7 | import {IonicStorageModule, Storage} from '@ionic/storage'; 8 | import {TranslateLoader, TranslateModule} from '@ngx-translate/core'; 9 | import {TranslateHttpLoader} from '@ngx-translate/http-loader'; 10 | import {IonicApp, IonicErrorHandler, IonicModule} from 'ionic-angular'; 11 | import {Settings, User} from '../providers/providers'; 12 | import {Api} from '../providers/api/api'; 13 | import {MyApp} from './app.component'; 14 | import {Browser} from '../providers/browser/browser'; 15 | import {Constant} from '../providers/constant/constant'; 16 | import {JwtInterceptorProvider} from '../providers/jwt-interceptor/jwt-interceptor'; 17 | 18 | // The translate loader needs to know where to load i18n files 19 | // in Ionic's static asset pipeline. 20 | export function createTranslateLoader(http: HttpClient) { 21 | return new TranslateHttpLoader(http, './assets/i18n/', '.json'); 22 | } 23 | 24 | export function provideSettings(storage: Storage) { 25 | /** 26 | * The Settings provider takes a set of default settings for your app. 27 | * 28 | * You can add new settings options at any time. Once the settings are saved, 29 | * these values will not overwrite the saved values (this can be done manually if desired). 30 | */ 31 | return new Settings(storage, { 32 | option1: true, 33 | option2: 'Ionitron J. Framework', 34 | option3: '3', 35 | option4: 'Hello' 36 | }); 37 | } 38 | 39 | @NgModule({ 40 | declarations: [ 41 | MyApp 42 | ], 43 | imports: [ 44 | BrowserModule, 45 | HttpClientModule, 46 | TranslateModule.forRoot({ 47 | loader: { 48 | provide: TranslateLoader, 49 | useFactory: (createTranslateLoader), 50 | deps: [HttpClient] 51 | } 52 | }), 53 | IonicModule.forRoot(MyApp, { 54 | backButtonText: '', 55 | iconMode: 'ios', 56 | mode: 'ios', 57 | }), 58 | IonicStorageModule.forRoot() 59 | ], 60 | bootstrap: [IonicApp], 61 | entryComponents: [ 62 | MyApp 63 | ], 64 | providers: [ 65 | Api, 66 | User, 67 | Browser, 68 | Constant, 69 | Camera, 70 | SplashScreen, 71 | StatusBar, 72 | {provide: Settings, useFactory: provideSettings, deps: [Storage]}, 73 | // Keep this to enable Ionic's runtime error handling during development 74 | {provide: ErrorHandler, useClass: IonicErrorHandler}, 75 | { 76 | provide: HTTP_INTERCEPTORS, 77 | useClass: JwtInterceptorProvider, 78 | multi: true, 79 | }] 80 | }) 81 | export class AppModule { 82 | } 83 | -------------------------------------------------------------------------------- /src/app/app.scss: -------------------------------------------------------------------------------- 1 | // http://ionicframework.com/docs/v2/theming/ 2 | @import "../theme/variables.scss"; 3 | // App Global Sass 4 | // -------------------------------------------------- 5 | // Put style rules here that you want to apply globally. These 6 | // styles are for the entire app and not just one component. 7 | // Additionally, this file can be also used as an entry point 8 | // to import other Sass files to be included in the output CSS. 9 | // 10 | // Shared Sass variables, which can be used to adjust Ionic's 11 | // default Sass variables, belong in "theme/variables.scss". 12 | // 13 | // To declare rules for a specific mode, create a child rule 14 | // for the .md, .ios, or .wp mode classes. The mode class is 15 | // automatically applied to the element in the app. 16 | 17 | ion-navbar { 18 | opacity: 0.8; 19 | } 20 | 21 | ion-toolbar { 22 | opacity: 0.8; 23 | } 24 | 25 | .toolbar-background { 26 | background-color: color($colors, primary); 27 | } 28 | 29 | .toolbar-title-ios { 30 | color: color($colors, light); 31 | } 32 | 33 | p { 34 | color: #656565 !important; 35 | } 36 | -------------------------------------------------------------------------------- /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/assets/i18n/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "BACK_BUTTON_TEXT": "Back", 3 | "NAME": "Name", 4 | "EMAIL": "Email", 5 | "USERNAME": "Username", 6 | "PASSWORD": "Password", 7 | "FORGET": "Forget", 8 | "SIGNUP": "Sign up", 9 | "HOME_TITLE": "HOME", 10 | "CHAT_TITLE": "NEWS", 11 | "NEWS_TITLE": "CHAT", 12 | "PROFILE_TITLE": "PROFILE", 13 | "MAP_TITLE": "Map", 14 | "TUTORIAL_SKIP_BUTTON": "Skip", 15 | "TUTORIAL_CONTINUE_BUTTON": "Continue", 16 | "TUTORIAL_SLIDE1_TITLE": "Welcome to the Ionic Super Starter", 17 | "TUTORIAL_SLIDE1_DESCRIPTION": "The Ionic Super Starter is a fully-featured Ionic starter with many pre-built pages and best practices.", 18 | "TUTORIAL_SLIDE2_TITLE": "How to use the Super Starter", 19 | "TUTORIAL_SLIDE2_DESCRIPTION": "Assemble the various page types you want and remove the ones you don't. We've provided many common mobile app page layouts, like login and signup pages, tabs, and this tutorial page.", 20 | "TUTORIAL_SLIDE3_TITLE": "Ready to Play?", 21 | "WELCOME_INTRO": "The starting point for your next great Ionic app", 22 | "SETTINGS_TITLE": "Settings", 23 | "SETTINGS_OPTION1": "Option 1", 24 | "SETTINGS_OPTION2": "Option 2", 25 | "SETTINGS_OPTION3": "Option 3", 26 | "SETTINGS_OPTION4": "Option 4", 27 | "SETTINGS_PROFILE_BUTTON": "Edit Profile", 28 | "SETTINGS_PAGE_PROFILE": "Edit Profile", 29 | "WELCOME_TITLE": "Welcome", 30 | "LOGIN_TITLE": "Sign in", 31 | "LOGIN_ERROR": "Unable to sign in. Please check your account information and try again.", 32 | "LOGIN_BUTTON": "Sign in", 33 | "SIGNUP_TITLE": "Sign up", 34 | "SIGNUP_ERROR": "Unable to create account. Please check your account information and try again.", 35 | "SIGNUP_BUTTON": "Sign up", 36 | "LIST_MASTER_TITLE": "Items", 37 | "ITEM_CREATE_TITLE": "New Item", 38 | "ITEM_CREATE_CHOOSE_IMAGE": "Add Image", 39 | "ITEM_NAME_PLACEHOLDER": "Name", 40 | "ITEM_ABOUT_PLACEHOLDER": "About", 41 | "DONE_BUTTON": "Done", 42 | "CANCEL_BUTTON": "Cancel", 43 | "DELETE_BUTTON": "Delete", 44 | "CARDS_TITLE": "Social", 45 | "SEARCH_TITLE": "Search page and question", 46 | "LOADING_TEXT": "Loading more data...", 47 | "REFRESHING_TEXT": "Refreshing...", 48 | "PULLING_TEXT": "Pull to refresh", 49 | "BANK_TEXT": "back", 50 | "NETWORK_ERROR": "network may be have error", 51 | "ADVERT_TXT": "advert", 52 | "QUESTION_TXT": "QUESTION", 53 | "HOTTIP_TXT": "HOTTIP" 54 | } 55 | -------------------------------------------------------------------------------- /src/assets/i18n/zh.json: -------------------------------------------------------------------------------- 1 | { 2 | "BACK_BUTTON_TEXT": "返回", 3 | "NAME": "姓名", 4 | "EMAIL": "邮箱", 5 | "USERNAME": "用户名", 6 | "PASSWORD": "密码", 7 | "FORGET": "忘记密码", 8 | "SIGNUP": "注册", 9 | "HOME_TITLE": "综合", 10 | "CHAT_TITLE": "吐槽", 11 | "NEWS_TITLE": "发现", 12 | "PROFILE_TITLE": "我的", 13 | "MAP_TITLE": "地址", 14 | "TUTORIAL_SKIP_BUTTON": "跳过", 15 | "TUTORIAL_CONTINUE_BUTTON": "继续", 16 | "TUTORIAL_SLIDE1_TITLE": "欢迎加入Spring4All社区", 17 | "TUTORIAL_SLIDE1_DESCRIPTION": "Spring For All 玩最纯粹的技术!做最专业的 Spring 民间组织~", 18 | "TUTORIAL_SLIDE2_TITLE": "Spring For All,关于Spring 的一切", 19 | "TUTORIAL_SLIDE2_DESCRIPTION": "我们专注于研究、分享、交流关于Spring的一切!", 20 | "TUTORIAL_SLIDE3_TITLE": "开始社区之旅", 21 | "WELCOME_INTRO": "Spring4All社区", 22 | "SETTINGS_TITLE": "设置", 23 | "SETTINGS_OPTION1": "Option 1", 24 | "SETTINGS_OPTION2": "Option 2", 25 | "SETTINGS_OPTION3": "Option 3", 26 | "SETTINGS_OPTION4": "Option 4", 27 | "SETTINGS_PROFILE_BUTTON": "编辑信息", 28 | "SETTINGS_PAGE_PROFILE": "编辑信息", 29 | "WELCOME_TITLE": "欢迎", 30 | "LOGIN_TITLE": "登录", 31 | "LOGIN_ERROR": "登录失败,请检查您的账户后重试", 32 | "LOGIN_BUTTON": "登录", 33 | "SIGNUP_TITLE": "注册", 34 | "SIGNUP_ERROR": "注册失败,请检查您的填写信息", 35 | "SIGNUP_BUTTON": "注册", 36 | "LIST_MASTER_TITLE": "发现", 37 | "ITEM_CREATE_TITLE": "新建", 38 | "ITEM_CREATE_CHOOSE_IMAGE": "添加", 39 | "ITEM_NAME_PLACEHOLDER": "姓名", 40 | "ITEM_ABOUT_PLACEHOLDER": "关于我", 41 | "DONE_BUTTON": "完成", 42 | "CANCEL_BUTTON": "取消", 43 | "DELETE_BUTTON": "删除", 44 | "CARDS_TITLE": "社交", 45 | "SEARCH_TITLE": "搜索文章、提问", 46 | "LOADING_TEXT": "加载更多...", 47 | "REFRESHING_TEXT": "刷新中...", 48 | "PULLING_TEXT": "下拉刷新", 49 | "BANK_TEXT": "返回", 50 | "NETWORK_ERROR": "网络好像不通了(⊙o⊙)", 51 | "ADVERT_TXT": "广告", 52 | "QUESTION_TXT": "问答", 53 | "HOTTIP_TXT": "热门" 54 | } 55 | -------------------------------------------------------------------------------- /src/assets/icon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/src/assets/icon/favicon.ico -------------------------------------------------------------------------------- /src/assets/img/advert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/src/assets/img/advert.png -------------------------------------------------------------------------------- /src/assets/img/ian-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/src/assets/img/ian-avatar.png -------------------------------------------------------------------------------- /src/assets/img/ica-slidebox-img-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/src/assets/img/ica-slidebox-img-1.png -------------------------------------------------------------------------------- /src/assets/img/ica-slidebox-img-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/src/assets/img/ica-slidebox-img-2.png -------------------------------------------------------------------------------- /src/assets/img/ica-slidebox-img-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/src/assets/img/ica-slidebox-img-3.png -------------------------------------------------------------------------------- /src/assets/img/splashbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringForAll/spring4all-app/ec45be7985f26adfa984fbbdb2bbd8d7356d8dc6/src/assets/img/splashbg.png -------------------------------------------------------------------------------- /src/components/components.module.ts: -------------------------------------------------------------------------------- 1 | import {CUSTOM_ELEMENTS_SCHEMA, NgModule} from '@angular/core'; 2 | import {IonCardListComponent} from './ion-card-list/ion-card-list'; 3 | 4 | @NgModule({ 5 | declarations: [IonCardListComponent], 6 | imports: [], 7 | exports: [IonCardListComponent], 8 | schemas: [CUSTOM_ELEMENTS_SCHEMA] 9 | }) 10 | export class ComponentsModule { 11 | } 12 | -------------------------------------------------------------------------------- /src/components/ion-card-list/ion-card-list.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | {{text}} 4 |
5 | -------------------------------------------------------------------------------- /src/components/ion-card-list/ion-card-list.scss: -------------------------------------------------------------------------------- 1 | ion-card-list { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/components/ion-card-list/ion-card-list.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input} from '@angular/core'; 2 | 3 | /** 4 | * Generated class for the IonCardListComponent component. 5 | * 6 | * See https://angular.io/api/core/Component for more info on Angular 7 | * Components. 8 | */ 9 | @Component({ 10 | selector: 'ion-card-list', 11 | templateUrl: 'ion-card-list.html' 12 | }) 13 | export class IonCardListComponent { 14 | @Input() text: string; 15 | 16 | constructor() { 17 | console.log('Hello IonCardListComponent Component'); 18 | this.text = 'Hello World'; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Spring4All 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Ionic", 3 | "short_name": "Ionic", 4 | "start_url": "index.html", 5 | "display": "standalone", 6 | "icons": [ 7 | { 8 | "src": "assets/imgs/logo.png", 9 | "sizes": "512x512", 10 | "type": "image/png" 11 | } 12 | ], 13 | "background_color": "#4e8ef7", 14 | "theme_color": "#4e8ef7" 15 | } 16 | -------------------------------------------------------------------------------- /src/pages/README.md: -------------------------------------------------------------------------------- 1 | # Pages 2 | 3 | Each page type available has a corresponding README, take a look by navigating to a page directory above. 4 | -------------------------------------------------------------------------------- /src/pages/advert/advert.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/pages/advert/advert.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {IonicPageModule} from 'ionic-angular'; 3 | import {AdvertPage} from './advert'; 4 | import {TranslateModule} from "@ngx-translate/core"; 5 | 6 | @NgModule({ 7 | declarations: [ 8 | AdvertPage, 9 | ], 10 | imports: [ 11 | IonicPageModule.forChild(AdvertPage), 12 | TranslateModule.forChild() 13 | ], 14 | }) 15 | export class AdvertPageModule { 16 | } 17 | -------------------------------------------------------------------------------- /src/pages/advert/advert.scss: -------------------------------------------------------------------------------- 1 | page-advert { 2 | .toolbar-background { 3 | background: transparent; 4 | border-color: transparent; 5 | } 6 | .time { 7 | position: absolute; 8 | top: 5px; 9 | right: 5px; 10 | } 11 | .fullscreen { 12 | width: 100%; 13 | height: 100%; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/pages/advert/advert.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {IonicPage, NavController, NavParams} from 'ionic-angular'; 3 | 4 | /** 5 | * Generated class for the AdvertPage page. 6 | * 7 | * See https://ionicframework.com/docs/components/#navigation for more info on 8 | * Ionic pages and navigation. 9 | */ 10 | 11 | @IonicPage() 12 | @Component({ 13 | selector: 'page-advert', 14 | templateUrl: 'advert.html', 15 | }) 16 | export class AdvertPage { 17 | deadTime = 3; 18 | 19 | constructor(public navCtrl: NavController, public navParams: NavParams) { 20 | this.setTime(); 21 | } 22 | 23 | setTime() { 24 | if (this.deadTime == 2) { 25 | this.deadTime--; 26 | return this.startApp(); 27 | } else { 28 | this.deadTime--; 29 | } 30 | setTimeout(() => { 31 | this.setTime(); 32 | }, 1000); 33 | } 34 | 35 | ionViewDidLoad() { 36 | console.log('ionViewDidLoad AdvertPage'); 37 | } 38 | 39 | startApp() { 40 | this.navCtrl.setRoot('TabsPage', {}, { 41 | animate: true, 42 | direction: 'forward' 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/pages/chat/chat.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | {{"CHAT_TITLE" | translate}} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |

{{page.title}}

31 |
32 | 33 |

{{page.abstract}}

34 |
35 | 36 | 37 | 40 | 41 | 42 | 46 | 50 | 51 | 52 |
53 | 54 | 55 | 58 | 59 | 60 | 61 |
62 | -------------------------------------------------------------------------------- /src/pages/chat/chat.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {IonicPageModule} from 'ionic-angular'; 3 | import {ChatPage} from './chat'; 4 | import {TranslateModule} from '@ngx-translate/core'; 5 | 6 | @NgModule({ 7 | declarations: [ 8 | ChatPage, 9 | ], 10 | imports: [ 11 | IonicPageModule.forChild(ChatPage), 12 | TranslateModule.forChild() 13 | ], 14 | }) 15 | export class ChatPageModule { 16 | } 17 | -------------------------------------------------------------------------------- /src/pages/chat/chat.scss: -------------------------------------------------------------------------------- 1 | page-chat { 2 | 3 | .card-content-ios { 4 | padding-bottom: 0px; 5 | } 6 | 7 | .user-span { 8 | float: right; 9 | padding-right: 10px 10 | } 11 | 12 | .user-span span { 13 | color: #b2b2b2; 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/pages/chat/chat.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {IonicPage, ModalController, NavController, NavParams, ToastController} from 'ionic-angular'; 3 | import {TranslateService} from '@ngx-translate/core'; 4 | import {Api} from '../../providers/providers'; 5 | 6 | /** 7 | * Generated class for the ChatPage page. 8 | * 9 | * See https://ionicframework.com/docs/components/#navigation for more info on 10 | * Ionic pages and navigation. 11 | */ 12 | 13 | @IonicPage() 14 | @Component({ 15 | selector: 'page-chat', 16 | templateUrl: 'chat.html', 17 | }) 18 | export class ChatPage { 19 | 20 | private datas: Array = []; 21 | private networkErrorString: string; 22 | 23 | constructor(public translateService: TranslateService, 24 | public navCtrl: NavController, 25 | public navParams: NavParams, 26 | public api: Api, 27 | public toastCtrl: ToastController, 28 | public modalController: ModalController) { 29 | this.getDatas(); 30 | } 31 | 32 | ionViewDidLoad() { 33 | console.log('ionViewDidLoad ChatPage'); 34 | } 35 | 36 | doInfinite(infiniteScroll) { 37 | setTimeout(() => { 38 | this.getDatas() 39 | infiniteScroll.complete(); 40 | }, 500); 41 | } 42 | 43 | doRefresh(refresher) { 44 | console.log('Begin async operation', refresher); 45 | setTimeout(() => { 46 | this.datas = []; 47 | this.getDatas(); 48 | refresher.complete(); 49 | }, 500); 50 | } 51 | 52 | getDatas() { 53 | let seq = this.api.get('pages').share(); 54 | seq.subscribe((res: any) => { 55 | // If the API returned a successful response, mark the user as logged in 56 | if (res.success) { 57 | this.datas = this.datas.concat(res.data); 58 | } else { 59 | this.showToast().present(); 60 | } 61 | }, err => { 62 | this.showToast().present(); 63 | console.error('ERROR', err); 64 | }); 65 | return seq; 66 | } 67 | 68 | showToast() { 69 | return this.toastCtrl.create({ 70 | message: this.networkErrorString, 71 | duration: 3000, 72 | position: 'top' 73 | }); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/pages/home/home.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | {{"HOME_TITLE" | translate}} 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 26 | 27 | 28 | 30 | 31 | {{item.title}} 32 |
33 | {{item.title}} 34 |
35 |
36 | 37 | 38 | 39 |

{{page.title}}

40 |

{{page.abstract}}

41 |
42 | 45 | 49 | 53 |
54 |
55 |
56 | 57 | 58 | 61 | 62 | 63 | 64 |
65 | -------------------------------------------------------------------------------- /src/pages/home/home.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {IonicPageModule} from 'ionic-angular'; 3 | import {HomePage} from './home'; 4 | import {TranslateModule} from '@ngx-translate/core'; 5 | 6 | @NgModule({ 7 | declarations: [ 8 | HomePage, 9 | ], 10 | imports: [ 11 | IonicPageModule.forChild(HomePage), 12 | TranslateModule.forChild() 13 | ], 14 | }) 15 | export class HomePageModule { 16 | } 17 | -------------------------------------------------------------------------------- /src/pages/home/home.scss: -------------------------------------------------------------------------------- 1 | page-home { 2 | 3 | ion-slides { 4 | height: 30%; 5 | .cover { 6 | position: absolute; 7 | bottom: 0px; 8 | width: 100%; 9 | height: 30px; 10 | //background: linear-gradient(to right, #f9a727, #265ff9); 11 | background: #c2beb3; 12 | opacity: 0.6; 13 | } 14 | .title { 15 | position: absolute; 16 | bottom: 0px; 17 | width: 90%; 18 | height: 30px; 19 | line-height: 30px; 20 | font-size: 80%; 21 | left: 5px; 22 | text-align: center; 23 | color: white; 24 | } 25 | } 26 | .item-block { 27 | min-height: 0; 28 | } 29 | 30 | .item-ios { 31 | font-size: 1.5rem; 32 | } 33 | 34 | .user-span span { 35 | color: #b2b2b2; 36 | } 37 | 38 | .label-ios { 39 | margin-bottom: 0px; 40 | } 41 | 42 | ion-label { 43 | white-space: normal; 44 | } 45 | .note-ios { 46 | color: #6b6b6b; 47 | } 48 | 49 | .button-small-ios { 50 | padding: 0 0em; 51 | } 52 | 53 | .buttom-btn { 54 | float: right; 55 | padding-right: 10px 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/pages/home/home.ts: -------------------------------------------------------------------------------- 1 | import {Component, ViewChild} from '@angular/core'; 2 | import {IonicPage, ModalController, NavController, NavParams, Slides, ToastController} from 'ionic-angular'; 3 | import {TranslateService} from "@ngx-translate/core"; 4 | import {Api} from "../../providers/api/api" 5 | import {Browser} from "../../providers/browser/browser" 6 | 7 | /** 8 | * Generated class for the HomePage page. 9 | * 10 | * See https://ionicframework.com/docs/components/#navigation for more info on 11 | * Ionic pages and navigation. 12 | */ 13 | 14 | @IonicPage() 15 | @Component({ 16 | selector: 'page-home', 17 | templateUrl: 'home.html', 18 | }) 19 | export class HomePage { 20 | @ViewChild(Slides) slides: Slides; 21 | 22 | slideData: Array = []; 23 | pages: Array = []; 24 | private networkErrorString: string; 25 | 26 | constructor(public translateService: TranslateService, 27 | public navCtrl: NavController, 28 | public navParams: NavParams, 29 | public api: Api, 30 | public toastCtrl: ToastController, 31 | public modalController: ModalController, 32 | public browser: Browser) { 33 | this.getSlides(); 34 | this.getPages(); 35 | this.translateService.get('NETWORK_ERROR').subscribe((value) => { 36 | this.networkErrorString = value; 37 | }); 38 | } 39 | 40 | ionViewDidLoad() { 41 | console.log('ionViewDidLoad HomePage'); 42 | } 43 | 44 | doRefresh(refresher) { 45 | console.log('Begin async operation', refresher); 46 | setTimeout(() => { 47 | this.pages = []; 48 | this.getPages(); 49 | refresher.complete(); 50 | }, 500); 51 | } 52 | 53 | doInfinite(infiniteScroll) { 54 | setTimeout(() => { 55 | this.getPages() 56 | infiniteScroll.complete(); 57 | }, 500); 58 | } 59 | 60 | getPages() { 61 | let seq = this.api.get('pages').share(); 62 | seq.subscribe((res: any) => { 63 | // If the API returned a successful response, mark the user as logged in 64 | if (res.success) { 65 | this.pages = this.pages.concat(res.data); 66 | } else { 67 | this.showToast().present(); 68 | } 69 | }, err => { 70 | this.showToast().present(); 71 | console.error('ERROR', err); 72 | }); 73 | return seq; 74 | } 75 | 76 | // 77 | getSlides() { 78 | let seq = this.api.get('slides').share(); 79 | seq.subscribe((res: any) => { 80 | // If the API returned a successful response, mark the user as logged in 81 | if (res.success) { 82 | this.slideData = res.data; 83 | } else { 84 | this.showToast().present(); 85 | } 86 | }, err => { 87 | this.showToast().present(); 88 | console.error('ERROR', err); 89 | }); 90 | return seq; 91 | } 92 | 93 | openSearch() { 94 | let modal = this.modalController.create("SearchPage"); 95 | modal.present(); 96 | } 97 | 98 | openPages(url) { 99 | this.browser.launch(url); 100 | } 101 | 102 | showToast() { 103 | return this.toastCtrl.create({ 104 | message: this.networkErrorString, 105 | duration: 3000, 106 | position: 'top' 107 | }); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/pages/item-create/README.md: -------------------------------------------------------------------------------- 1 | # Item Create 2 | 3 | The Item Create Page creates new instances of `Item`, and will most commonly be used in a modal window to be presented by `ListMasterPage`. 4 | -------------------------------------------------------------------------------- /src/pages/item-create/item-create.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ 'ITEM_CREATE_TITLE' | translate }} 5 | 6 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 30 |
31 |
32 | 33 |
34 | {{ 'ITEM_CREATE_CHOOSE_IMAGE' | translate }} 35 |
36 |
37 |
39 |
40 | 41 | 42 | 44 | 45 | 46 | 48 | 49 | 50 |
51 |
52 | -------------------------------------------------------------------------------- /src/pages/item-create/item-create.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {TranslateModule} from '@ngx-translate/core'; 3 | import {IonicPageModule} from 'ionic-angular'; 4 | 5 | import {ItemCreatePage} from './item-create'; 6 | 7 | @NgModule({ 8 | declarations: [ 9 | ItemCreatePage, 10 | ], 11 | imports: [ 12 | IonicPageModule.forChild(ItemCreatePage), 13 | TranslateModule.forChild() 14 | ], 15 | exports: [ 16 | ItemCreatePage 17 | ] 18 | }) 19 | export class ItemCreatePageModule { 20 | } 21 | -------------------------------------------------------------------------------- /src/pages/item-create/item-create.scss: -------------------------------------------------------------------------------- 1 | page-item-create { 2 | .profile-image-wrapper { 3 | text-align: center; 4 | margin: 20px 0; 5 | 6 | .profile-image { 7 | width: 96px; 8 | height: 96px; 9 | border-radius: 50%; 10 | 11 | display: inline-block; 12 | 13 | background-repeat: no-repeat; 14 | background-size: cover; 15 | background-position: center; 16 | } 17 | 18 | .profile-image-placeholder { 19 | display: inline-block; 20 | 21 | background-color: #eee; 22 | width: 96px; 23 | height: 96px; 24 | border-radius: 50%; 25 | 26 | font-size: 12px; 27 | 28 | ion-icon { 29 | font-size: 44px; 30 | margin-bottom: -10px; 31 | margin-top: 10px; 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/pages/item-create/item-create.ts: -------------------------------------------------------------------------------- 1 | import {Component, ViewChild} from '@angular/core'; 2 | import {FormBuilder, FormGroup, Validators} from '@angular/forms'; 3 | import {Camera} from '@ionic-native/camera'; 4 | import {IonicPage, NavController, ViewController} from 'ionic-angular'; 5 | 6 | @IonicPage() 7 | @Component({ 8 | selector: 'page-item-create', 9 | templateUrl: 'item-create.html' 10 | }) 11 | export class ItemCreatePage { 12 | @ViewChild('fileInput') fileInput; 13 | 14 | isReadyToSave: boolean; 15 | 16 | item: any; 17 | 18 | form: FormGroup; 19 | 20 | constructor(public navCtrl: NavController, public viewCtrl: ViewController, formBuilder: FormBuilder, public camera: Camera) { 21 | this.form = formBuilder.group({ 22 | profilePic: [''], 23 | name: ['', Validators.required], 24 | about: [''] 25 | }); 26 | 27 | // Watch the form for changes, and 28 | this.form.valueChanges.subscribe((v) => { 29 | this.isReadyToSave = this.form.valid; 30 | }); 31 | } 32 | 33 | ionViewDidLoad() { 34 | 35 | } 36 | 37 | getPicture() { 38 | if (Camera['installed']()) { 39 | this.camera.getPicture({ 40 | destinationType: this.camera.DestinationType.DATA_URL, 41 | targetWidth: 96, 42 | targetHeight: 96 43 | }).then((data) => { 44 | this.form.patchValue({'profilePic': 'data:image/jpg;base64,' + data}); 45 | }, (err) => { 46 | alert('Unable to take photo'); 47 | }) 48 | } else { 49 | this.fileInput.nativeElement.click(); 50 | } 51 | } 52 | 53 | processWebImage(event) { 54 | let reader = new FileReader(); 55 | reader.onload = (readerEvent) => { 56 | 57 | let imageData = (readerEvent.target as any).result; 58 | this.form.patchValue({'profilePic': imageData}); 59 | }; 60 | 61 | reader.readAsDataURL(event.target.files[0]); 62 | } 63 | 64 | getProfileImageStyle() { 65 | return 'url(' + this.form.controls['profilePic'].value + ')' 66 | } 67 | 68 | /** 69 | * The user cancelled, so we dismiss without sending data back. 70 | */ 71 | cancel() { 72 | this.viewCtrl.dismiss(); 73 | } 74 | 75 | /** 76 | * The user is done and wants to create the item, so return it 77 | * back to the presenter. 78 | */ 79 | done() { 80 | if (!this.form.valid) { 81 | return; 82 | } 83 | this.viewCtrl.dismiss(this.form.value); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/pages/login/README.md: -------------------------------------------------------------------------------- 1 | # Login 2 | 3 | The Login page renders a login form with email/password by default and an optional username field. 4 | -------------------------------------------------------------------------------- /src/pages/login/login.html: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/pages/login/login.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {TranslateModule} from '@ngx-translate/core'; 3 | import {IonicPageModule} from 'ionic-angular'; 4 | 5 | import {LoginPage} from './login'; 6 | 7 | @NgModule({ 8 | declarations: [ 9 | LoginPage, 10 | ], 11 | imports: [ 12 | IonicPageModule.forChild(LoginPage), 13 | TranslateModule.forChild() 14 | ], 15 | exports: [ 16 | LoginPage 17 | ] 18 | }) 19 | export class LoginPageModule { 20 | } 21 | -------------------------------------------------------------------------------- /src/pages/login/login.scss: -------------------------------------------------------------------------------- 1 | page-login { 2 | .splash-bg { 3 | background: url('../assets/img/splashbg.png') no-repeat; 4 | } 5 | 6 | .sign-up { 7 | padding-top: 30%; 8 | width: 95%; 9 | margin: 0 auto; 10 | } 11 | 12 | .item { 13 | color: #FFFFFF; 14 | background: transparent 15 | } 16 | 17 | @keyframes animatedBackground { 18 | from { 19 | background-position: 0 0; 20 | } 21 | to { 22 | background-position: 100% 0; 23 | } 24 | } 25 | 26 | button { 27 | opacity: 0.8; 28 | } 29 | 30 | .login-footer { 31 | a:first-child { 32 | margin-left: 10%; 33 | } 34 | a:last-child { 35 | margin-left: 50%; 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/pages/login/login.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {TranslateService} from '@ngx-translate/core'; 3 | import {IonicPage, NavController, ToastController} from 'ionic-angular'; 4 | import {Storage} from '@ionic/storage'; 5 | import {User} from '../../providers/providers'; 6 | import {MainPage} from '../pages'; 7 | import {Settings} from "../../providers/settings/settings"; 8 | 9 | @IonicPage() 10 | @Component({ 11 | selector: 'page-login', 12 | templateUrl: 'login.html' 13 | }) 14 | export class LoginPage { 15 | // The account fields for the login form. 16 | // If you're using the username field with or without email, make 17 | // sure to add it to the type 18 | account: { email: string, password: string } = { 19 | email: '', 20 | password: '' 21 | }; 22 | 23 | // Our translated text strings 24 | private loginErrorString: string; 25 | private networkErrorString: string; 26 | 27 | constructor(public navCtrl: NavController, 28 | public user: User, 29 | public settings: Settings, 30 | public storage: Storage, 31 | public toastCtrl: ToastController, 32 | public translateService: TranslateService) { 33 | 34 | this.translateService.get('LOGIN_ERROR').subscribe((value) => { 35 | this.loginErrorString = value; 36 | }); 37 | this.translateService.get('NETWORK_ERROR').subscribe((value) => { 38 | this.networkErrorString = value; 39 | }); 40 | } 41 | 42 | // Attempt to login in through our User service 43 | doLogin() { 44 | this.user.login(this.account).subscribe((resp: any) => { 45 | if (resp.success) { 46 | this.navCtrl.push(MainPage); 47 | } else { 48 | let toast = this.toastCtrl.create({ 49 | message: this.loginErrorString, 50 | duration: 3000, 51 | position: 'top' 52 | }); 53 | toast.present(); 54 | } 55 | }, (err) => { 56 | // Unable to log in 57 | let toast = this.toastCtrl.create({ 58 | message: this.networkErrorString, 59 | duration: 3000, 60 | position: 'top' 61 | }); 62 | toast.present(); 63 | }); 64 | } 65 | 66 | forget() { 67 | //TODO yhq 68 | this.navCtrl.push('LoginPage'); 69 | } 70 | 71 | signup() { 72 | this.navCtrl.push('SignupPage'); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/pages/news/news.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | {{'QUESTION_TXT'| translate}} 12 | 13 | 14 | {{'HOTTIP_TXT'| translate}} 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 |

{{question.title}}

25 |

{{question.abstract}}

26 |
27 | 30 | 34 | 38 |
39 |
40 |
41 | 42 | 43 | 44 |

{{hottip.title}}

45 |

{{hottip.abstract}}

46 |
47 | 50 | 54 | 58 |
59 |
60 |
61 |
62 |
-------------------------------------------------------------------------------- /src/pages/news/news.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {IonicPageModule} from 'ionic-angular'; 3 | import {NewsPage} from './news'; 4 | import {TranslateModule} from '@ngx-translate/core'; 5 | 6 | @NgModule({ 7 | declarations: [ 8 | NewsPage, 9 | ], 10 | imports: [ 11 | IonicPageModule.forChild(NewsPage), 12 | TranslateModule.forChild() 13 | ], 14 | }) 15 | export class NewsPageModule { 16 | } 17 | -------------------------------------------------------------------------------- /src/pages/news/news.scss: -------------------------------------------------------------------------------- 1 | page-news { 2 | .item-block { 3 | min-height: 0; 4 | } 5 | 6 | .item-ios { 7 | font-size: 1.5rem; 8 | } 9 | 10 | .user-span span { 11 | color: #b2b2b2; 12 | } 13 | .label-ios { 14 | margin-bottom: 0px; 15 | } 16 | ion-label { 17 | white-space: normal; 18 | } 19 | .note-ios { 20 | color: #6b6b6b; 21 | } 22 | 23 | .button-small-ios { 24 | padding: 0 0em; 25 | } 26 | 27 | .buttom-btn { 28 | float: right; 29 | padding-right: 10px 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/pages/news/news.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {IonicPage, NavController, NavParams, ToastController} from 'ionic-angular'; 3 | import {Api} from "../../providers/api/api" 4 | import {TranslateService} from '@ngx-translate/core'; 5 | import {Browser} from '../../providers/providers'; 6 | 7 | /** 8 | * Generated class for the NewsPage page. 9 | * 10 | * See https://ionicframework.com/docs/components/#navigation for more info on 11 | * Ionic pages and navigation. 12 | */ 13 | 14 | @IonicPage() 15 | @Component({ 16 | selector: 'page-news', 17 | templateUrl: 'news.html', 18 | }) 19 | export class NewsPage { 20 | 21 | type: string = "question"; 22 | questions: Array = []; 23 | hotTips: Array = []; 24 | private networkErrorString: string; 25 | 26 | constructor(public navCtrl: NavController, 27 | public navParams: NavParams, 28 | public translateService: TranslateService, 29 | public toastCtrl: ToastController, 30 | public browser: Browser, 31 | public api: Api) { 32 | this.translateService.get('NETWORK_ERROR').subscribe((value) => { 33 | this.networkErrorString = value; 34 | }); 35 | this.getQuestions(); 36 | this.getHotTips(); 37 | console.log(this.hotTips) 38 | } 39 | 40 | getQuestions() { 41 | let param = {'key': 'value'} 42 | let seq = this.api.get('questions', param).share(); 43 | seq.subscribe((res: any) => { 44 | // If the API returned a successful response, mark the user as logged in 45 | if (res.success) { 46 | this.questions = this.questions.concat(res.data); 47 | } else { 48 | this.showToast().present(); 49 | } 50 | }, err => { 51 | this.showToast().present(); 52 | console.error('ERROR', err); 53 | }); 54 | return seq; 55 | } 56 | 57 | getHotTips() { 58 | let seq = this.api.get('hottips').share(); 59 | seq.subscribe((res: any) => { 60 | // If the API returned a successful response, mark the user as logged in 61 | if (res.success) { 62 | this.hotTips = this.hotTips.concat(res.data); 63 | } else { 64 | this.showToast().present(); 65 | } 66 | }, err => { 67 | this.showToast().present(); 68 | console.error('ERROR', err); 69 | }); 70 | return seq; 71 | } 72 | 73 | ionViewDidLoad() { 74 | console.log('ionViewDidLoad NewsPage'); 75 | } 76 | 77 | showToast() { 78 | return this.toastCtrl.create({ 79 | message: this.networkErrorString, 80 | duration: 3000, 81 | position: 'top' 82 | }); 83 | } 84 | 85 | openPages(url) { 86 | this.browser.launch(url); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/pages/pages.ts: -------------------------------------------------------------------------------- 1 | // The page the user lands on after opening the app and without a session 2 | export const FirstRunPage = 'TutorialPage'; 3 | export const AdvertPage = 'AdvertPage'; 4 | 5 | // The main page the user will see as they use the app over a long period of time. 6 | // Change this if not using tabs 7 | export const MainPage = 'TabsPage'; 8 | 9 | // The initial root pages for our tabs (remove if not using tabs) 10 | export const Tab1Root = 'HomePage'; 11 | export const Tab2Root = 'NewsPage'; 12 | export const Tab3Root = 'ChatPage'; 13 | export const Tab4Root = 'ProfilePage'; 14 | -------------------------------------------------------------------------------- /src/pages/profile/profile.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | {{"PROFILE_TITLE" | translate}} 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | {{profile.name}}    26 | 27 | 28 | 29 | 30 | 31 | 32 | 123 33 | 文章 34 | 35 | 36 | 66 37 | 提问 38 | 39 | 40 | 9 41 | 关注 42 | 43 | 44 | 59 45 | 粉丝 46 | 47 | 48 | 49 | 50 | 51 | 52 | 57 | 61 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 夜间模式 73 | 74 | 75 | 76 | 77 | 78 | 79 | 83 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /src/pages/profile/profile.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {IonicPageModule} from 'ionic-angular'; 3 | import {ProfilePage} from './profile'; 4 | import {TranslateModule} from '@ngx-translate/core'; 5 | 6 | @NgModule({ 7 | declarations: [ 8 | ProfilePage, 9 | ], 10 | imports: [ 11 | IonicPageModule.forChild(ProfilePage), 12 | TranslateModule.forChild() 13 | ], 14 | }) 15 | export class ProfilePageModule { 16 | } 17 | -------------------------------------------------------------------------------- /src/pages/profile/profile.scss: -------------------------------------------------------------------------------- 1 | page-profile { 2 | .profile-avatar { 3 | padding-bottom: 10px; 4 | padding-top: 10px; 5 | border-bottom: 0.55px solid rgb(200, 199, 204); 6 | .item-inner { 7 | border-bottom: none !important; 8 | } 9 | span { 10 | font-size: 20px; 11 | color: #767676; 12 | } 13 | } 14 | 15 | ion-item-divider { 16 | min-height: 20px; 17 | } 18 | .item-ios { 19 | color: #767676; 20 | } 21 | .item-ios ion-avatar img { 22 | width: 60px; 23 | height: 60px; 24 | } 25 | 26 | .profile-title { 27 | display: block; 28 | font-size: 20px; 29 | margin-bottom: 5px; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/pages/profile/profile.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {IonicPage, NavController, NavParams} from 'ionic-angular'; 3 | import {Browser} from '../../providers/providers'; 4 | import {User} from "../../providers/user/user"; 5 | 6 | /** 7 | * Generated class for the ProfilePage page. 8 | * 9 | * See https://ionicframework.com/docs/components/#navigation for more info on 10 | * Ionic pages and navigation. 11 | */ 12 | @IonicPage() 13 | @Component({ 14 | selector: 'page-profile', 15 | templateUrl: 'profile.html', 16 | }) 17 | export class ProfilePage { 18 | 19 | private profile: any; 20 | 21 | constructor(public navCtrl: NavController, 22 | public navParams: NavParams, 23 | private user: User, 24 | public browser: Browser) { 25 | this.profile = this.user._user; 26 | console.log(this.profile) 27 | } 28 | 29 | ionViewDidLoad() { 30 | console.log('ionViewDidLoad ProfilePage'); 31 | } 32 | 33 | openProjects() { 34 | let url = 'http://spring4all.com/projects'; 35 | this.browser.launch(url); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/pages/search/search.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/pages/search/search.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {IonicPageModule} from 'ionic-angular'; 3 | import {SearchPage} from './search'; 4 | import {TranslateModule} from '@ngx-translate/core'; 5 | 6 | @NgModule({ 7 | declarations: [ 8 | SearchPage, 9 | ], 10 | imports: [ 11 | IonicPageModule.forChild(SearchPage), 12 | TranslateModule.forChild() 13 | ], 14 | }) 15 | export class SearchPageModule { 16 | } 17 | -------------------------------------------------------------------------------- /src/pages/search/search.scss: -------------------------------------------------------------------------------- 1 | page-search { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/pages/search/search.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {IonicPage, NavController, NavParams, ViewController} from 'ionic-angular'; 3 | 4 | /** 5 | * Generated class for the SearchPage page. 6 | * 7 | * See https://ionicframework.com/docs/components/#navigation for more info on 8 | * Ionic pages and navigation. 9 | */ 10 | 11 | @IonicPage() 12 | @Component({ 13 | selector: 'page-search', 14 | templateUrl: 'search.html', 15 | }) 16 | export class SearchPage { 17 | 18 | constructor(public navCtrl: NavController, public navParams: NavParams, public viewController: ViewController) { 19 | } 20 | 21 | ionViewDidLoad() { 22 | console.log('ionViewDidLoad SearchPage'); 23 | } 24 | 25 | search(event) { 26 | console.log(event) 27 | } 28 | 29 | dismiss() { 30 | this.viewController.dismiss(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/pages/settings/README.md: -------------------------------------------------------------------------------- 1 | # Settings 2 | 3 | The Settings page shows a settings form that is configurable, along with features for nested options where the user navigates to sub options while still using the same Settings page code. 4 | -------------------------------------------------------------------------------- /src/pages/settings/settings.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ pageTitle }} 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | {{ 'SETTINGS_OPTION1' | translate }} 15 | 16 | 17 | 18 | 19 | {{ 'SETTINGS_OPTION2' | translate }} 20 | 21 | 22 | 23 | 24 | {{ 'SETTINGS_OPTION3' | translate }} 25 | 26 | 1 27 | 2 28 | 3 29 | 30 | 31 | 32 | 35 | 36 | 37 | 38 | 39 | {{ 'SETTINGS_OPTION4' | translate }} 40 | 41 | 42 | 43 |
44 | 45 |
-------------------------------------------------------------------------------- /src/pages/settings/settings.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {TranslateModule} from '@ngx-translate/core'; 3 | import {IonicPageModule} from 'ionic-angular'; 4 | 5 | import {SettingsPage} from './settings'; 6 | 7 | @NgModule({ 8 | declarations: [ 9 | SettingsPage, 10 | ], 11 | imports: [ 12 | IonicPageModule.forChild(SettingsPage), 13 | TranslateModule.forChild() 14 | ], 15 | exports: [ 16 | SettingsPage 17 | ] 18 | }) 19 | export class SettingsPageModule { 20 | } 21 | -------------------------------------------------------------------------------- /src/pages/settings/settings.scss: -------------------------------------------------------------------------------- 1 | page-settings { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/pages/settings/settings.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {FormBuilder, FormGroup} from '@angular/forms'; 3 | import {TranslateService} from '@ngx-translate/core'; 4 | import {IonicPage, NavController, NavParams} from 'ionic-angular'; 5 | 6 | import {Settings} from '../../providers/providers'; 7 | 8 | /** 9 | * The Settings page is a simple form that syncs with a Settings provider 10 | * to enable the user to customize settings for the app. 11 | * 12 | */ 13 | @IonicPage() 14 | @Component({ 15 | selector: 'page-settings', 16 | templateUrl: 'settings.html' 17 | }) 18 | export class SettingsPage { 19 | // Our local settings object 20 | options: any; 21 | 22 | settingsReady = false; 23 | 24 | form: FormGroup; 25 | 26 | profileSettings = { 27 | page: 'profile', 28 | pageTitleKey: 'SETTINGS_PAGE_PROFILE' 29 | }; 30 | 31 | page: string = 'main'; 32 | pageTitleKey: string = 'SETTINGS_TITLE'; 33 | pageTitle: string; 34 | 35 | subSettings: any = SettingsPage; 36 | 37 | constructor(public navCtrl: NavController, 38 | public settings: Settings, 39 | public formBuilder: FormBuilder, 40 | public navParams: NavParams, 41 | public translate: TranslateService) { 42 | } 43 | 44 | _buildForm() { 45 | let group: any = { 46 | option1: [this.options.option1], 47 | option2: [this.options.option2], 48 | option3: [this.options.option3] 49 | }; 50 | 51 | switch (this.page) { 52 | case 'main': 53 | break; 54 | case 'profile': 55 | group = { 56 | option4: [this.options.option4] 57 | }; 58 | break; 59 | } 60 | this.form = this.formBuilder.group(group); 61 | 62 | // Watch the form for changes, and 63 | this.form.valueChanges.subscribe((v) => { 64 | this.settings.merge(this.form.value); 65 | }); 66 | } 67 | 68 | ionViewDidLoad() { 69 | // Build an empty form for the template to render 70 | this.form = this.formBuilder.group({}); 71 | } 72 | 73 | ionViewWillEnter() { 74 | // Build an empty form for the template to render 75 | this.form = this.formBuilder.group({}); 76 | 77 | this.page = this.navParams.get('page') || this.page; 78 | this.pageTitleKey = this.navParams.get('pageTitleKey') || this.pageTitleKey; 79 | 80 | this.translate.get(this.pageTitleKey).subscribe((res) => { 81 | this.pageTitle = res; 82 | }) 83 | 84 | this.settings.load().then(() => { 85 | this.settingsReady = true; 86 | this.options = this.settings.allSettings; 87 | 88 | this._buildForm(); 89 | }); 90 | } 91 | 92 | ngOnChanges() { 93 | console.log('Ng All Changes'); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/pages/signup/README.md: -------------------------------------------------------------------------------- 1 | # Signup 2 | 3 | The Signup page renders a signup form with email/password by default and an optional username field. 4 | -------------------------------------------------------------------------------- /src/pages/signup/signup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ 'SIGNUP_TITLE' | translate }} 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | {{ 'NAME' | translate }} 16 | 17 | 18 | 19 | 20 | {{ 'EMAIL' | translate }} 21 | 22 | 23 | 24 | 32 | 33 | 34 | {{ 'PASSWORD' | translate }} 35 | 36 | 37 | 38 |
39 | 40 |
41 | 42 |
43 |
44 |
45 | -------------------------------------------------------------------------------- /src/pages/signup/signup.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {TranslateModule} from '@ngx-translate/core'; 3 | import {IonicPageModule} from 'ionic-angular'; 4 | 5 | import {SignupPage} from './signup'; 6 | 7 | @NgModule({ 8 | declarations: [ 9 | SignupPage, 10 | ], 11 | imports: [ 12 | IonicPageModule.forChild(SignupPage), 13 | TranslateModule.forChild() 14 | ], 15 | exports: [ 16 | SignupPage 17 | ] 18 | }) 19 | export class SignupPageModule { 20 | } 21 | -------------------------------------------------------------------------------- /src/pages/signup/signup.scss: -------------------------------------------------------------------------------- 1 | page-signup { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/pages/signup/signup.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {TranslateService} from '@ngx-translate/core'; 3 | import {IonicPage, NavController, ToastController} from 'ionic-angular'; 4 | 5 | import {User} from '../../providers/providers'; 6 | import {MainPage} from '../pages'; 7 | 8 | @IonicPage() 9 | @Component({ 10 | selector: 'page-signup', 11 | templateUrl: 'signup.html' 12 | }) 13 | export class SignupPage { 14 | // The account fields for the login form. 15 | // If you're using the username field with or without email, make 16 | // sure to add it to the type 17 | account: { name: string, email: string, password: string } = { 18 | name: 'Test Human', 19 | email: 'test@example.com', 20 | password: 'test' 21 | }; 22 | 23 | // Our translated text strings 24 | private signupErrorString: string; 25 | 26 | constructor(public navCtrl: NavController, 27 | public user: User, 28 | public toastCtrl: ToastController, 29 | public translateService: TranslateService) { 30 | 31 | this.translateService.get('SIGNUP_ERROR').subscribe((value) => { 32 | this.signupErrorString = value; 33 | }) 34 | } 35 | 36 | doSignup() { 37 | // Attempt to login in through our User service 38 | this.user.signup(this.account).subscribe((resp) => { 39 | this.navCtrl.push(MainPage); 40 | }, (err) => { 41 | 42 | this.navCtrl.push(MainPage); 43 | 44 | // Unable to sign up 45 | let toast = this.toastCtrl.create({ 46 | message: this.signupErrorString, 47 | duration: 3000, 48 | position: 'middle' 49 | }); 50 | toast.present(); 51 | }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/pages/tabs/README.md: -------------------------------------------------------------------------------- 1 | # Tabs 2 | 3 | Tabs is a common tabbed layout. 4 | -------------------------------------------------------------------------------- /src/pages/tabs/tabs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/pages/tabs/tabs.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {TranslateModule} from '@ngx-translate/core'; 3 | import {IonicPageModule} from 'ionic-angular'; 4 | 5 | import {TabsPage} from './tabs'; 6 | 7 | @NgModule({ 8 | declarations: [ 9 | TabsPage, 10 | ], 11 | imports: [ 12 | IonicPageModule.forChild(TabsPage), 13 | TranslateModule.forChild() 14 | ], 15 | exports: [ 16 | TabsPage 17 | ] 18 | }) 19 | export class TabsPageModule { 20 | } 21 | -------------------------------------------------------------------------------- /src/pages/tabs/tabs.scss: -------------------------------------------------------------------------------- 1 | page-tabs { 2 | ion-fab[bottom] { 3 | bottom: 0px; 4 | } 5 | 6 | ion-fab-list[side=left] { 7 | margin: -50px 30px; 8 | } 9 | 10 | ion-fab-list[side=right] { 11 | margin: -50px 30px; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/pages/tabs/tabs.ts: -------------------------------------------------------------------------------- 1 | import {Component, ViewChild} from '@angular/core'; 2 | import {TranslateService} from '@ngx-translate/core'; 3 | import {IonicPage, NavController, Tabs} from 'ionic-angular'; 4 | 5 | import {Tab1Root, Tab2Root, Tab3Root, Tab4Root} from '../pages'; 6 | 7 | /** 8 | * Generated class for the TabsPage tabs. 9 | * 10 | * See https://ionicframework.com/docs/components/#navigation for more info on 11 | * Ionic pages and navigation. 12 | */ 13 | 14 | @IonicPage() 15 | @Component({ 16 | selector: 'page-tabs', 17 | templateUrl: 'tabs.html' 18 | }) 19 | export class TabsPage { 20 | @ViewChild('mainTabs') tabs: Tabs; 21 | 22 | tab1Root: any = Tab1Root; 23 | tab2Root: any = Tab2Root; 24 | tab3Root: any = Tab3Root; 25 | tab4Root: any = Tab4Root; 26 | 27 | tab1Title = " "; 28 | tab2Title = " "; 29 | tab3Title = " "; 30 | tab4Title = " "; 31 | 32 | tab4Badge = 0; 33 | 34 | constructor(public navCtrl: NavController, public translateService: TranslateService) { 35 | translateService.get(['HOME_TITLE', 'CHAT_TITLE', 'NEWS_TITLE', 'PROFILE_TITLE']).subscribe(values => { 36 | this.tab1Title = values['HOME_TITLE']; 37 | this.tab2Title = values['NEWS_TITLE']; 38 | this.tab3Title = values['CHAT_TITLE']; 39 | this.tab4Title = values['PROFILE_TITLE']; 40 | }); 41 | this.tab4Badge = 2; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/pages/tutorial/README.md: -------------------------------------------------------------------------------- 1 | # Tutorial 2 | 3 | The Tutorial page renders a Slides component that lets you swipe through different sections or skip it alltogether. 4 | -------------------------------------------------------------------------------- /src/pages/tutorial/tutorial.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

14 |

15 |
16 | 17 | 18 |

{{ 'TUTORIAL_SLIDE3_TITLE' | translate }}

19 | 23 |
24 |
25 |
26 | -------------------------------------------------------------------------------- /src/pages/tutorial/tutorial.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {IonicPageModule} from 'ionic-angular'; 3 | import {TutorialPage} from './tutorial'; 4 | import {TranslateModule} from '@ngx-translate/core'; 5 | 6 | @NgModule({ 7 | declarations: [ 8 | TutorialPage, 9 | ], 10 | imports: [ 11 | IonicPageModule.forChild(TutorialPage), 12 | TranslateModule.forChild() 13 | ], 14 | exports: [ 15 | TutorialPage 16 | ] 17 | }) 18 | export class TutorialPageModule { 19 | } 20 | -------------------------------------------------------------------------------- /src/pages/tutorial/tutorial.scss: -------------------------------------------------------------------------------- 1 | page-tutorial { 2 | .toolbar-background { 3 | background: transparent; 4 | border-color: transparent; 5 | } 6 | 7 | .slide-zoom { 8 | height: 100%; 9 | } 10 | 11 | .slide-title { 12 | margin-top: 2.8rem; 13 | } 14 | 15 | .slide-image { 16 | max-height: 40%; 17 | max-width: 60%; 18 | margin: 36px 0; 19 | } 20 | 21 | b { 22 | font-weight: 500; 23 | } 24 | 25 | p { 26 | padding: 0 40px; 27 | font-size: 14px; 28 | line-height: 1.5; 29 | color: #60646B; 30 | 31 | b { 32 | color: #000000; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/pages/tutorial/tutorial.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {IonicPage, NavController, Platform} from 'ionic-angular'; 3 | import {TranslateService} from '@ngx-translate/core'; 4 | 5 | export interface Slide { 6 | title: string; 7 | description: string; 8 | image: string; 9 | } 10 | 11 | @IonicPage() 12 | @Component({ 13 | selector: 'page-tutorial', 14 | templateUrl: 'tutorial.html' 15 | }) 16 | export class TutorialPage { 17 | slides: Slide[]; 18 | showSkip = true; 19 | dir: string = 'ltr'; 20 | 21 | constructor(public navCtrl: NavController, 22 | translate: TranslateService, 23 | public platform: Platform) { 24 | this.dir = platform.dir(); 25 | translate.get(["TUTORIAL_SLIDE1_TITLE", 26 | "TUTORIAL_SLIDE1_DESCRIPTION", 27 | "TUTORIAL_SLIDE2_TITLE", 28 | "TUTORIAL_SLIDE2_DESCRIPTION" 29 | ]).subscribe( 30 | (values) => { 31 | console.log('Loaded values', values); 32 | this.slides = [ 33 | { 34 | title: values.TUTORIAL_SLIDE1_TITLE, 35 | description: values.TUTORIAL_SLIDE1_DESCRIPTION, 36 | image: 'assets/img/ica-slidebox-img-1.png', 37 | }, 38 | { 39 | title: values.TUTORIAL_SLIDE2_TITLE, 40 | description: values.TUTORIAL_SLIDE2_DESCRIPTION, 41 | image: 'assets/img/ica-slidebox-img-2.png', 42 | } 43 | ]; 44 | }); 45 | } 46 | 47 | startApp() { 48 | this.navCtrl.setRoot('LoginPage', {}, { 49 | animate: true, 50 | direction: 'forward' 51 | }); 52 | } 53 | 54 | onSlideChangeStart(slider) { 55 | this.showSkip = !slider.isEnd(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/providers/api/api.ts: -------------------------------------------------------------------------------- 1 | import {HttpClient, HttpParams} from '@angular/common/http'; 2 | import {Injectable} from '@angular/core'; 3 | 4 | /** 5 | * Api is a generic REST Api handler. Set your API url first. 6 | */ 7 | @Injectable() 8 | export class Api { 9 | url: string = 'http://www.mockhttp.cn/mock/mock'; 10 | 11 | constructor(public http: HttpClient) { 12 | } 13 | 14 | get(endpoint: string, params?: any, reqOpts?: any) { 15 | if (!reqOpts) { 16 | reqOpts = { 17 | params: new HttpParams() 18 | }; 19 | } 20 | 21 | // Support easy query params for GET requests 22 | if (params) { 23 | reqOpts.params = new HttpParams(); 24 | for (let k in params) { 25 | reqOpts.params.set(k, params[k]); 26 | } 27 | } 28 | return this.http.get(this.url + '/' + endpoint, reqOpts); 29 | } 30 | 31 | post(endpoint: string, body: any, reqOpts?: any) { 32 | return this.http.post(this.url + '/' + endpoint, body, reqOpts); 33 | } 34 | 35 | put(endpoint: string, body: any, reqOpts?: any) { 36 | return this.http.put(this.url + '/' + endpoint, body, reqOpts); 37 | } 38 | 39 | delete(endpoint: string, reqOpts?: any) { 40 | return this.http.delete(this.url + '/' + endpoint, reqOpts); 41 | } 42 | 43 | patch(endpoint: string, body: any, reqOpts?: any) { 44 | return this.http.put(this.url + '/' + endpoint, body, reqOpts); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/providers/browser/browser.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import 'rxjs/add/operator/map'; 3 | import {ThemeableBrowser} from 'ionic-native'; 4 | import {Constant} from '../constant/constant'; 5 | 6 | 7 | /* 8 | Generated class for the BrowserProvider provider. 9 | 10 | See https://angular.io/guide/dependency-injection for more info on providers 11 | and Angular DI. 12 | */ 13 | @Injectable() 14 | export class Browser { 15 | 16 | target: string = '_blank'; 17 | private options: any = { 18 | statusbar: { 19 | color: this.constant.colors_primary 20 | }, 21 | toolbar: { 22 | height: 44, 23 | color: this.constant.colors_primary 24 | }, 25 | title: { 26 | color: this.constant.colors_light, 27 | showPageTitle: true 28 | }, 29 | backButton: { 30 | image: 'back', 31 | imagePressed: 'back_pressed', 32 | align: 'left', 33 | event: 'backPressed' 34 | }, 35 | backButtonCanClose: true 36 | /* menu: { 37 | image: 'share', 38 | imagePressed: 'menu_pressed', 39 | title: '分享', 40 | cancel: '取消', 41 | align: 'right', 42 | items: [ 43 | { 44 | event: 'helloPressed', 45 | label: 'Hello World!' 46 | }, 47 | { 48 | event: 'testPressed', 49 | label: 'Test!' 50 | } 51 | ] 52 | }*/ 53 | }; 54 | 55 | constructor(public constant: Constant) { 56 | } 57 | 58 | launch(url) { 59 | return new ThemeableBrowser(url, this.target, this.options); 60 | } 61 | 62 | launchWithTaget(url, target) { 63 | this.target = target; 64 | return this.launch(url); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/providers/constant/constant.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | 3 | /** 4 | * Constant const 5 | */ 6 | @Injectable() 7 | export class Constant { 8 | public colors_primary: string = "#488aff"; 9 | public colors_secondary: string = "#32db64"; 10 | public colors_danger: string = "#f53d3d"; 11 | public colors_light: string = "#f4f4f4"; 12 | public colors_dark: string = "#222"; 13 | 14 | constructor() { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/providers/jwt-interceptor/jwt-interceptor.ts: -------------------------------------------------------------------------------- 1 | import {Injectable, Injector} from '@angular/core'; 2 | import 'rxjs/add/operator/map'; 3 | import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from "@angular/common/http"; 4 | import {Observable} from "rxjs/Observable"; 5 | import {User} from "../user/user"; 6 | import {timeout} from "rxjs/operator/timeout"; 7 | 8 | /* 9 | Generated class for the JwtInterceptorProvider provider. 10 | 11 | See https://angular.io/guide/dependency-injection for more info on providers 12 | and Angular DI. 13 | */ 14 | @Injectable() 15 | export class JwtInterceptorProvider implements HttpInterceptor { 16 | private user: User; 17 | 18 | constructor(private inj: Injector) { 19 | console.log('Hello JwtInterceptorProvider Provider'); 20 | } 21 | 22 | intercept(req: HttpRequest, next: HttpHandler): Observable> { 23 | this.user = this.inj.get(User); 24 | this.user.getToken().then(token => { 25 | req = req.clone({ 26 | setHeaders: { 27 | Authorization: token 28 | } 29 | }); 30 | }); 31 | return next.handle(req).map(event => { 32 | /* if (event instanceof HttpResponse) { 33 | if (event.status === 401 || event.status === 403) { 34 | return this.user.refreshToken().then((data) => { 35 | if (data.token !== '') { 36 | localStorage.setItem('currentUser', JSON.stringify(data.user)); 37 | localStorage.setItem('currentUserPermissions', JSON.stringify(data.permissions)); 38 | localStorage.setItem('JWToken', data.token); 39 | } else { 40 | localStorage.removeItem('currentUser'); 41 | localStorage.removeItem('currentUserPermissions'); 42 | localStorage.removeItem('JWToken'); 43 | this.nav.setRoot('LoginPage'); 44 | return Observable.throw(event); 45 | } 46 | const clonedRequestRepeat = req.clone({ 47 | headers: req.headers.set('Authorization', 'Bearer ' + localStorage.getItem('JWToken')) 48 | }); 49 | return next.handle(clonedRequestRepeat); 50 | }) 51 | } else { 52 | return Observable.throw(event); 53 | } 54 | } */ 55 | return event; 56 | }); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/providers/providers.ts: -------------------------------------------------------------------------------- 1 | import {Api} from './api/api'; 2 | import {Settings} from './settings/settings'; 3 | import {User} from './user/user'; 4 | import {Browser} from './browser/browser'; 5 | import {Constant} from './constant/constant'; 6 | import {JwtInterceptorProvider} from './jwt-interceptor/jwt-interceptor'; 7 | 8 | export { 9 | Api, 10 | Settings, 11 | User, 12 | Browser, 13 | Constant, 14 | JwtInterceptorProvider 15 | }; 16 | -------------------------------------------------------------------------------- /src/providers/settings/settings.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {Storage} from '@ionic/storage'; 3 | 4 | /** 5 | * A simple settings/config class for storing key/value pairs with persistence. 6 | */ 7 | @Injectable() 8 | export class Settings { 9 | settings: any; 10 | _defaults: any; 11 | _readyPromise: Promise; 12 | private SETTINGS_KEY: string = '_settings'; 13 | 14 | constructor(public storage: Storage, defaults: any) { 15 | this._defaults = defaults; 16 | } 17 | 18 | get allSettings() { 19 | return this.settings; 20 | } 21 | 22 | load() { 23 | return this.storage.get(this.SETTINGS_KEY).then((value) => { 24 | if (value) { 25 | this.settings = value; 26 | return this._mergeDefaults(this._defaults); 27 | } else { 28 | return this.setAll(this._defaults).then((val) => { 29 | this.settings = val; 30 | }) 31 | } 32 | }); 33 | } 34 | 35 | _mergeDefaults(defaults: any) { 36 | for (let k in defaults) { 37 | if (!(k in this.settings)) { 38 | this.settings[k] = defaults[k]; 39 | } 40 | } 41 | return this.setAll(this.settings); 42 | } 43 | 44 | merge(settings: any) { 45 | for (let k in settings) { 46 | this.settings[k] = settings[k]; 47 | } 48 | return this.save(); 49 | } 50 | 51 | setValue(key: string, value: any) { 52 | this.settings[key] = value; 53 | return this.storage.set(this.SETTINGS_KEY, this.settings); 54 | } 55 | 56 | setAll(value: any) { 57 | return this.storage.set(this.SETTINGS_KEY, value); 58 | } 59 | 60 | getValue(key: string) { 61 | return this.storage.get(this.SETTINGS_KEY) 62 | .then(settings => { 63 | return settings[key]; 64 | }); 65 | } 66 | 67 | save() { 68 | return this.setAll(this.settings); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/providers/user/user.ts: -------------------------------------------------------------------------------- 1 | import 'rxjs/add/operator/toPromise'; 2 | 3 | import {Injectable} from '@angular/core'; 4 | import {Storage} from '@ionic/storage'; 5 | import {Api} from '../api/api'; 6 | 7 | /** 8 | * Most apps have the concept of a User. This is a simple provider 9 | * with stubs for login/signup/etc. 10 | * 11 | * This User provider makes calls to our API at the `login` and `signup` endpoints. 12 | * 13 | * By default, it expects `login` and `signup` to return a JSON object of the shape: 14 | * 15 | * ```json 16 | * { 17 | * status: 'success', 18 | * data: { 19 | * // User fields your app needs, like "id", "name", "email", etc. 20 | * } 21 | * }Ø 22 | * ``` 23 | * 24 | * If the `status` field is not `success`, then an error is detected and returned. 25 | */ 26 | @Injectable() 27 | export class User { 28 | _user: any; 29 | _token: string; 30 | 31 | constructor(public api: Api, 32 | private storage: Storage) { 33 | this.init(); 34 | } 35 | 36 | /** 37 | * Send a POST request to our login endpoint with the data 38 | * the user entered on the form. 39 | */ 40 | login(accountInfo: any) { 41 | let seq = this.api.get('login', accountInfo).share(); 42 | 43 | seq.subscribe((res: any) => { 44 | // If the API returned a successful response, mark the user as logged in 45 | if (res.success) { 46 | this._loggedIn(res); 47 | } 48 | }, err => { 49 | console.error('ERROR', err); 50 | }); 51 | 52 | return seq; 53 | } 54 | 55 | /** 56 | * Send a POST request to our signup endpoint with the data 57 | * the user entered on the form. 58 | */ 59 | signup(accountInfo: any) { 60 | let seq = this.api.post('signup', accountInfo).share(); 61 | 62 | seq.subscribe((res: any) => { 63 | // If the API returned a successful response, mark the user as logged in 64 | if (res.success) { 65 | this._loggedIn(res); 66 | } 67 | }, err => { 68 | console.error('ERROR', err); 69 | }); 70 | 71 | return seq; 72 | } 73 | 74 | /** 75 | * Log the user out, which forgets the session 76 | */ 77 | logout() { 78 | this._user = null; 79 | } 80 | 81 | /** 82 | * Process a login/signup response to store user data 83 | */ 84 | _loggedIn(resp) { 85 | this._user = resp.data; 86 | this._token = resp.data.token; 87 | this.storage.set("user", this._user); 88 | } 89 | 90 | getToken() { 91 | return this.storage.get("user").then(res => { 92 | if (res) { 93 | return res.token; 94 | } 95 | }); 96 | } 97 | 98 | init() { 99 | this.storage.get("user").then(res => { 100 | if (res) { 101 | this._user = res; 102 | this._token = res.token; 103 | } 104 | }) 105 | } 106 | 107 | refreshToken() { 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/service-worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check out https://googlechrome.github.io/sw-toolbox/ 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/vendor.js', 19 | './build/main.css', 20 | './build/polyfills.js', 21 | 'index.html', 22 | 'manifest.json' 23 | ] 24 | ); 25 | 26 | // dynamically cache any other local assets 27 | self.toolbox.router.any('/*', self.toolbox.cacheFirst); 28 | 29 | // for any other requests go to the network, cache, 30 | // and then only use that cached resource if your user goes offline 31 | self.toolbox.router.default = self.toolbox.networkFirst; 32 | -------------------------------------------------------------------------------- /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 | // Shared Variables 8 | // -------------------------------------------------- 9 | // To customize the look and feel of this app, you can override 10 | // the Sass variables found in Ionic's source scss files. 11 | // To view all the possible Ionic variables, see: 12 | // http://ionicframework.com/docs/v2/theming/overriding-ionic-variables/ 13 | 14 | $text-color: #000; 15 | $background-color: #fff; 16 | 17 | // Named Color Variables 18 | // -------------------------------------------------- 19 | // Named colors makes it easy to reuse colors on various components. 20 | // It's highly recommended to change the default colors 21 | // to match your app's branding. Ionic uses a Sass map of 22 | // colors so you can add, rename and remove colors as needed. 23 | // The "primary" color is the only required color in the map. 24 | 25 | $colors: ( 26 | primary: #488aff, 27 | secondary: #32db64, 28 | danger: #f53d3d, 29 | light: #f4f4f4, 30 | dark: #808080 31 | ); 32 | 33 | // App iOS Variables 34 | // -------------------------------------------------- 35 | // iOS only Sass variables can go here 36 | 37 | // App Material Design Variables 38 | // -------------------------------------------------- 39 | // Material Design only Sass variables can go here 40 | 41 | // App Windows Variables 42 | // -------------------------------------------------- 43 | // Windows only Sass variables can go here 44 | 45 | // App Theme 46 | // -------------------------------------------------- 47 | // Ionic apps can have different themes applied, which can 48 | // then be future customized. This import comes last 49 | // so that the above variables are used and Ionic's 50 | // default are overridden. 51 | 52 | @import "ionic.theme.default"; 53 | 54 | // Ionicons 55 | // -------------------------------------------------- 56 | // The premium icon font for Ionic. For more info, please see: 57 | // http://ionicframework.com/docs/v2/ionicons/ 58 | 59 | @import "ionic.ionicons"; 60 | 61 | // Fonts 62 | // -------------------------------------------------- 63 | 64 | @import "roboto"; 65 | @import "noto-sans"; 66 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------