├── .angular-cli.json ├── .editorconfig ├── .gitignore ├── README.md ├── e2e ├── app.e2e-spec.ts ├── app.po.ts └── tsconfig.e2e.json ├── front ├── 0.a64d51d41345e4785e00.chunk.js ├── 1.81b1c86a421d2add2606.chunk.js ├── 2.3ccdb5a0d4848a97a84c.chunk.js ├── 3rdpartylicenses.txt ├── assets │ └── avator.jpg ├── favicon.ico ├── index.html ├── inline.8f9113764960a7b7d2b9.bundle.js ├── main.ad858c8bc2f7b5483404.bundle.js ├── polyfills.a7336a77bb940b952f1f.bundle.js └── styles.e4ef5ac6e23bb0ae90b6.bundle.css ├── karma.conf.js ├── package-lock.json ├── package.json ├── protractor.conf.js ├── snapshot └── blog_front.png ├── src ├── app │ ├── aboutus │ │ ├── aboutus.component.css │ │ ├── aboutus.component.html │ │ ├── aboutus.component.ts │ │ └── aboutus.module.ts │ ├── app.component.css │ ├── app.component.html │ ├── app.component.spec.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── artdetail │ │ ├── artdetail.component.css │ │ ├── artdetail.component.html │ │ ├── artdetail.component.ts │ │ └── artdetail.module.ts │ ├── artlist │ │ ├── artlist.component.css │ │ ├── artlist.component.html │ │ ├── artlist.component.ts │ │ └── artlist.module.ts │ ├── nav-bar │ │ ├── nav-bar.component.css │ │ ├── nav-bar.component.html │ │ ├── nav-bar.component.ts │ │ └── nav-bar.module.ts │ ├── pipe │ │ ├── html.pipe.ts │ │ └── safehtml.pipe.ts │ ├── recommend │ │ ├── recommend.component.css │ │ ├── recommend.component.html │ │ ├── recommend.component.ts │ │ └── recommend.module.ts │ ├── routing │ │ ├── aboutus.routing.module.ts │ │ ├── app.routing.module.ts │ │ ├── nav.routing.module.ts │ │ └── recommend.routing.module.ts │ ├── service │ │ ├── base.service.ts │ │ ├── blog.service.ts │ │ ├── highlight.service.ts │ │ └── sidenav.service.ts │ ├── side-nav-drawer │ │ ├── side-nav-drawer.component.css │ │ ├── side-nav-drawer.component.html │ │ ├── side-nav-drawer.component.ts │ │ └── side-nav-drawer.module.ts │ └── side-nav │ │ ├── side-nav.component.css │ │ ├── side-nav.component.html │ │ ├── side-nav.component.ts │ │ └── side-nav.module.ts ├── assets │ ├── .gitkeep │ └── avator.jpg ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── index.html ├── main.ts ├── polyfills.ts ├── styles.css ├── test.ts ├── tsconfig.app.json ├── tsconfig.spec.json └── typings.d.ts ├── tsconfig.json └── tslint.json /.angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "project": { 4 | "name": "blog-frontend" 5 | }, 6 | "apps": [ 7 | { 8 | "root": "src", 9 | "outDir": "dist", 10 | "assets": [ 11 | "assets", 12 | "favicon.ico" 13 | ], 14 | "index": "index.html", 15 | "main": "main.ts", 16 | "polyfills": "polyfills.ts", 17 | "test": "test.ts", 18 | "tsconfig": "tsconfig.app.json", 19 | "testTsconfig": "tsconfig.spec.json", 20 | "prefix": "app", 21 | "styles": [ 22 | "styles.css" 23 | ], 24 | "scripts": [], 25 | "environmentSource": "environments/environment.ts", 26 | "environments": { 27 | "dev": "environments/environment.ts", 28 | "prod": "environments/environment.prod.ts" 29 | } 30 | } 31 | ], 32 | "e2e": { 33 | "protractor": { 34 | "config": "./protractor.conf.js" 35 | } 36 | }, 37 | "lint": [ 38 | { 39 | "project": "src/tsconfig.app.json", 40 | "exclude": "**/node_modules/**" 41 | }, 42 | { 43 | "project": "src/tsconfig.spec.json", 44 | "exclude": "**/node_modules/**" 45 | }, 46 | { 47 | "project": "e2e/tsconfig.e2e.json", 48 | "exclude": "**/node_modules/**" 49 | } 50 | ], 51 | "test": { 52 | "karma": { 53 | "config": "./karma.conf.js" 54 | } 55 | }, 56 | "defaults": { 57 | "styleExt": "css", 58 | "component": {} 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /dist-server 6 | /tmp 7 | /out-tsc 8 | 9 | # dependencies 10 | /node_modules 11 | 12 | # IDEs and editors 13 | /.idea 14 | .project 15 | .classpath 16 | .c9/ 17 | *.launch 18 | .settings/ 19 | *.sublime-workspace 20 | 21 | # IDE - VSCode 22 | .vscode/* 23 | !.vscode/settings.json 24 | !.vscode/tasks.json 25 | !.vscode/launch.json 26 | !.vscode/extensions.json 27 | 28 | # misc 29 | /.sass-cache 30 | /connect.lock 31 | /coverage 32 | /libpeerconnection.log 33 | npm-debug.log 34 | yarn-error.log 35 | testem.log 36 | /typings 37 | 38 | # e2e 39 | /e2e/*.js 40 | /e2e/*.map 41 | 42 | # System Files 43 | .DS_Store 44 | Thumbs.db 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Angular5-Blog-Front 2 | 3 | ![blog](./snapshot/blog_front.png) 4 | 5 | Angular5 Material2编写的简易版博客,预览地址[Track的博客](http://blog.yinguiw.com) 6 | 7 | + 项目创建基于 [Angular CLI](https://github.com/angular/angular-cli) version 1.7.2. 8 | + 当前项目目录下, 使用 `npm install` 安装依赖 9 | + 测试环境使用`ng serve` 打开 `http://localhost:4200/` 10 | + 正式环境使用 `ng build --aot --prod` 编译打包位于`dist/`目录下 11 | 12 | ## 项目依赖 13 | * [Angular Material](https://v5.material.angular.io/) 14 | 15 | ## 其他项目 16 | * [Admin后台管理系统](https://github.com/lyw1995/Angular5-Blog-Admin) 17 | * [BlogServrer博客服务端](https://github.com/lyw1995/Golang-Blog-Server) 18 | 19 | -------------------------------------------------------------------------------- /e2e/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('blog-frontend App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('Welcome to app!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /e2e/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": [ 9 | "jasmine", 10 | "jasminewd2", 11 | "node" 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /front/2.3ccdb5a0d4848a97a84c.chunk.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([2],{NblT:function(t,i,l){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var a=l("WT6e"),e=function(){},n=l("mu/C"),s=l("1OzB"),m=l("sqmn"),o=l("9Sd6"),d=l("Xjw4"),r=l("XHgV"),c=l("Uo70"),u=l("ZuzD");l("tBE9"),l("7DMc");var p=a._2({encapsulation:2,styles:[".mat-divider{display:block;margin:0;border-top-width:1px;border-top-style:solid}.mat-divider.mat-divider-vertical{border-top:0;border-right-width:1px;border-right-style:solid}.mat-divider.mat-divider-inset{margin-left:80px}[dir=rtl] .mat-divider.mat-divider-inset{margin-left:auto;margin-right:80px}.mat-subheader{display:flex;box-sizing:border-box;padding:16px;align-items:center}.mat-list .mat-subheader,.mat-nav-list .mat-subheader,.mat-selection-list .mat-subheader{margin:0}.mat-list,.mat-nav-list,.mat-selection-list{padding-top:8px;display:block}.mat-list .mat-subheader,.mat-nav-list .mat-subheader,.mat-selection-list .mat-subheader{height:48px;line-height:16px}.mat-list .mat-subheader:first-child,.mat-nav-list .mat-subheader:first-child,.mat-selection-list .mat-subheader:first-child{margin-top:-8px}.mat-list .mat-list-item,.mat-list .mat-list-option,.mat-nav-list .mat-list-item,.mat-nav-list .mat-list-option,.mat-selection-list .mat-list-item,.mat-selection-list .mat-list-option{display:block;height:48px}.mat-list .mat-list-item .mat-list-item-content,.mat-list .mat-list-option .mat-list-item-content,.mat-nav-list .mat-list-item .mat-list-item-content,.mat-nav-list .mat-list-option .mat-list-item-content,.mat-selection-list .mat-list-item .mat-list-item-content,.mat-selection-list .mat-list-option .mat-list-item-content{display:flex;flex-direction:row;align-items:center;box-sizing:border-box;padding:0 16px;position:relative;height:inherit}.mat-list .mat-list-item .mat-list-item-content-reverse,.mat-list .mat-list-option .mat-list-item-content-reverse,.mat-nav-list .mat-list-item .mat-list-item-content-reverse,.mat-nav-list .mat-list-option .mat-list-item-content-reverse,.mat-selection-list .mat-list-item .mat-list-item-content-reverse,.mat-selection-list .mat-list-option .mat-list-item-content-reverse{display:flex;align-items:center;padding:0 16px;flex-direction:row-reverse;justify-content:space-around}.mat-list .mat-list-item .mat-list-item-ripple,.mat-list .mat-list-option .mat-list-item-ripple,.mat-nav-list .mat-list-item .mat-list-item-ripple,.mat-nav-list .mat-list-option .mat-list-item-ripple,.mat-selection-list .mat-list-item .mat-list-item-ripple,.mat-selection-list .mat-list-option .mat-list-item-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}.mat-list .mat-list-item.mat-list-item-with-avatar,.mat-list .mat-list-option.mat-list-item-with-avatar,.mat-nav-list .mat-list-item.mat-list-item-with-avatar,.mat-nav-list .mat-list-option.mat-list-item-with-avatar,.mat-selection-list .mat-list-item.mat-list-item-with-avatar,.mat-selection-list .mat-list-option.mat-list-item-with-avatar{height:56px}.mat-list .mat-list-item.mat-2-line,.mat-list .mat-list-option.mat-2-line,.mat-nav-list .mat-list-item.mat-2-line,.mat-nav-list .mat-list-option.mat-2-line,.mat-selection-list .mat-list-item.mat-2-line,.mat-selection-list .mat-list-option.mat-2-line{height:72px}.mat-list .mat-list-item.mat-3-line,.mat-list .mat-list-option.mat-3-line,.mat-nav-list .mat-list-item.mat-3-line,.mat-nav-list .mat-list-option.mat-3-line,.mat-selection-list .mat-list-item.mat-3-line,.mat-selection-list .mat-list-option.mat-3-line{height:88px}.mat-list .mat-list-item.mat-multi-line,.mat-list .mat-list-option.mat-multi-line,.mat-nav-list .mat-list-item.mat-multi-line,.mat-nav-list .mat-list-option.mat-multi-line,.mat-selection-list .mat-list-item.mat-multi-line,.mat-selection-list .mat-list-option.mat-multi-line{height:auto}.mat-list .mat-list-item.mat-multi-line .mat-list-item-content,.mat-list .mat-list-option.mat-multi-line .mat-list-item-content,.mat-nav-list .mat-list-item.mat-multi-line .mat-list-item-content,.mat-nav-list .mat-list-option.mat-multi-line .mat-list-item-content,.mat-selection-list .mat-list-item.mat-multi-line .mat-list-item-content,.mat-selection-list .mat-list-option.mat-multi-line .mat-list-item-content{padding-top:16px;padding-bottom:16px}.mat-list .mat-list-item .mat-list-text,.mat-list .mat-list-option .mat-list-text,.mat-nav-list .mat-list-item .mat-list-text,.mat-nav-list .mat-list-option .mat-list-text,.mat-selection-list .mat-list-item .mat-list-text,.mat-selection-list .mat-list-option .mat-list-text{display:flex;flex-direction:column;width:100%;box-sizing:border-box;overflow:hidden;padding:0}.mat-list .mat-list-item .mat-list-text>*,.mat-list .mat-list-option .mat-list-text>*,.mat-nav-list .mat-list-item .mat-list-text>*,.mat-nav-list .mat-list-option .mat-list-text>*,.mat-selection-list .mat-list-item .mat-list-text>*,.mat-selection-list .mat-list-option .mat-list-text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.mat-list .mat-list-item .mat-list-text:empty,.mat-list .mat-list-option .mat-list-text:empty,.mat-nav-list .mat-list-item .mat-list-text:empty,.mat-nav-list .mat-list-option .mat-list-text:empty,.mat-selection-list .mat-list-item .mat-list-text:empty,.mat-selection-list .mat-list-option .mat-list-text:empty{display:none}.mat-list .mat-list-item .mat-list-item-content .mat-list-text:not(:nth-child(2)),.mat-list .mat-list-option .mat-list-item-content .mat-list-text:not(:nth-child(2)),.mat-nav-list .mat-list-item .mat-list-item-content .mat-list-text:not(:nth-child(2)),.mat-nav-list .mat-list-option .mat-list-item-content .mat-list-text:not(:nth-child(2)),.mat-selection-list .mat-list-item .mat-list-item-content .mat-list-text:not(:nth-child(2)),.mat-selection-list .mat-list-option .mat-list-item-content .mat-list-text:not(:nth-child(2)){padding-right:0;padding-left:16px}[dir=rtl] .mat-list .mat-list-item .mat-list-item-content .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-list .mat-list-option .mat-list-item-content .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-nav-list .mat-list-item .mat-list-item-content .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-nav-list .mat-list-option .mat-list-item-content .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-selection-list .mat-list-item .mat-list-item-content .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-selection-list .mat-list-option .mat-list-item-content .mat-list-text:not(:nth-child(2)){padding-right:16px;padding-left:0}.mat-list .mat-list-item .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),.mat-list .mat-list-option .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),.mat-nav-list .mat-list-item .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),.mat-nav-list .mat-list-option .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),.mat-selection-list .mat-list-item .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),.mat-selection-list .mat-list-option .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)){padding-left:0;padding-right:16px}[dir=rtl] .mat-list .mat-list-item .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-list .mat-list-option .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-nav-list .mat-list-item .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-nav-list .mat-list-option .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-selection-list .mat-list-item .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-selection-list .mat-list-option .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)){padding-right:0;padding-left:16px}.mat-list .mat-list-item .mat-list-avatar,.mat-list .mat-list-option .mat-list-avatar,.mat-nav-list .mat-list-item .mat-list-avatar,.mat-nav-list .mat-list-option .mat-list-avatar,.mat-selection-list .mat-list-item .mat-list-avatar,.mat-selection-list .mat-list-option .mat-list-avatar{flex-shrink:0;width:40px;height:40px;border-radius:50%}.mat-list .mat-list-item .mat-list-avatar~.mat-divider-inset,.mat-list .mat-list-option .mat-list-avatar~.mat-divider-inset,.mat-nav-list .mat-list-item .mat-list-avatar~.mat-divider-inset,.mat-nav-list .mat-list-option .mat-list-avatar~.mat-divider-inset,.mat-selection-list .mat-list-item .mat-list-avatar~.mat-divider-inset,.mat-selection-list .mat-list-option .mat-list-avatar~.mat-divider-inset{margin-left:72px;width:calc(100% - 72px)}[dir=rtl] .mat-list .mat-list-item .mat-list-avatar~.mat-divider-inset,[dir=rtl] .mat-list .mat-list-option .mat-list-avatar~.mat-divider-inset,[dir=rtl] .mat-nav-list .mat-list-item .mat-list-avatar~.mat-divider-inset,[dir=rtl] .mat-nav-list .mat-list-option .mat-list-avatar~.mat-divider-inset,[dir=rtl] .mat-selection-list .mat-list-item .mat-list-avatar~.mat-divider-inset,[dir=rtl] .mat-selection-list .mat-list-option .mat-list-avatar~.mat-divider-inset{margin-left:auto;margin-right:72px}.mat-list .mat-list-item .mat-list-icon,.mat-list .mat-list-option .mat-list-icon,.mat-nav-list .mat-list-item .mat-list-icon,.mat-nav-list .mat-list-option .mat-list-icon,.mat-selection-list .mat-list-item .mat-list-icon,.mat-selection-list .mat-list-option .mat-list-icon{flex-shrink:0;width:24px;height:24px;font-size:24px;box-sizing:content-box;border-radius:50%;padding:4px}.mat-list .mat-list-item .mat-list-icon~.mat-divider-inset,.mat-list .mat-list-option .mat-list-icon~.mat-divider-inset,.mat-nav-list .mat-list-item .mat-list-icon~.mat-divider-inset,.mat-nav-list .mat-list-option .mat-list-icon~.mat-divider-inset,.mat-selection-list .mat-list-item .mat-list-icon~.mat-divider-inset,.mat-selection-list .mat-list-option .mat-list-icon~.mat-divider-inset{margin-left:64px;width:calc(100% - 64px)}[dir=rtl] .mat-list .mat-list-item .mat-list-icon~.mat-divider-inset,[dir=rtl] .mat-list .mat-list-option .mat-list-icon~.mat-divider-inset,[dir=rtl] .mat-nav-list .mat-list-item .mat-list-icon~.mat-divider-inset,[dir=rtl] .mat-nav-list .mat-list-option .mat-list-icon~.mat-divider-inset,[dir=rtl] .mat-selection-list .mat-list-item .mat-list-icon~.mat-divider-inset,[dir=rtl] .mat-selection-list .mat-list-option .mat-list-icon~.mat-divider-inset{margin-left:auto;margin-right:64px}.mat-list .mat-list-item .mat-divider,.mat-list .mat-list-option .mat-divider,.mat-nav-list .mat-list-item .mat-divider,.mat-nav-list .mat-list-option .mat-divider,.mat-selection-list .mat-list-item .mat-divider,.mat-selection-list .mat-list-option .mat-divider{position:absolute;bottom:0;left:0;width:100%;margin:0}[dir=rtl] .mat-list .mat-list-item .mat-divider,[dir=rtl] .mat-list .mat-list-option .mat-divider,[dir=rtl] .mat-nav-list .mat-list-item .mat-divider,[dir=rtl] .mat-nav-list .mat-list-option .mat-divider,[dir=rtl] .mat-selection-list .mat-list-item .mat-divider,[dir=rtl] .mat-selection-list .mat-list-option .mat-divider{margin-left:auto;margin-right:0}.mat-list .mat-list-item .mat-divider.mat-divider-inset,.mat-list .mat-list-option .mat-divider.mat-divider-inset,.mat-nav-list .mat-list-item .mat-divider.mat-divider-inset,.mat-nav-list .mat-list-option .mat-divider.mat-divider-inset,.mat-selection-list .mat-list-item .mat-divider.mat-divider-inset,.mat-selection-list .mat-list-option .mat-divider.mat-divider-inset{position:absolute}.mat-list[dense],.mat-nav-list[dense],.mat-selection-list[dense]{padding-top:4px;display:block}.mat-list[dense] .mat-subheader,.mat-nav-list[dense] .mat-subheader,.mat-selection-list[dense] .mat-subheader{height:40px;line-height:8px}.mat-list[dense] .mat-subheader:first-child,.mat-nav-list[dense] .mat-subheader:first-child,.mat-selection-list[dense] .mat-subheader:first-child{margin-top:-4px}.mat-list[dense] .mat-list-item,.mat-list[dense] .mat-list-option,.mat-nav-list[dense] .mat-list-item,.mat-nav-list[dense] .mat-list-option,.mat-selection-list[dense] .mat-list-item,.mat-selection-list[dense] .mat-list-option{display:block;height:40px}.mat-list[dense] .mat-list-item .mat-list-item-content,.mat-list[dense] .mat-list-option .mat-list-item-content,.mat-nav-list[dense] .mat-list-item .mat-list-item-content,.mat-nav-list[dense] .mat-list-option .mat-list-item-content,.mat-selection-list[dense] .mat-list-item .mat-list-item-content,.mat-selection-list[dense] .mat-list-option .mat-list-item-content{display:flex;flex-direction:row;align-items:center;box-sizing:border-box;padding:0 16px;position:relative;height:inherit}.mat-list[dense] .mat-list-item .mat-list-item-content-reverse,.mat-list[dense] .mat-list-option .mat-list-item-content-reverse,.mat-nav-list[dense] .mat-list-item .mat-list-item-content-reverse,.mat-nav-list[dense] .mat-list-option .mat-list-item-content-reverse,.mat-selection-list[dense] .mat-list-item .mat-list-item-content-reverse,.mat-selection-list[dense] .mat-list-option .mat-list-item-content-reverse{display:flex;align-items:center;padding:0 16px;flex-direction:row-reverse;justify-content:space-around}.mat-list[dense] .mat-list-item .mat-list-item-ripple,.mat-list[dense] .mat-list-option .mat-list-item-ripple,.mat-nav-list[dense] .mat-list-item .mat-list-item-ripple,.mat-nav-list[dense] .mat-list-option .mat-list-item-ripple,.mat-selection-list[dense] .mat-list-item .mat-list-item-ripple,.mat-selection-list[dense] .mat-list-option .mat-list-item-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}.mat-list[dense] .mat-list-item.mat-list-item-with-avatar,.mat-list[dense] .mat-list-option.mat-list-item-with-avatar,.mat-nav-list[dense] .mat-list-item.mat-list-item-with-avatar,.mat-nav-list[dense] .mat-list-option.mat-list-item-with-avatar,.mat-selection-list[dense] .mat-list-item.mat-list-item-with-avatar,.mat-selection-list[dense] .mat-list-option.mat-list-item-with-avatar{height:48px}.mat-list[dense] .mat-list-item.mat-2-line,.mat-list[dense] .mat-list-option.mat-2-line,.mat-nav-list[dense] .mat-list-item.mat-2-line,.mat-nav-list[dense] .mat-list-option.mat-2-line,.mat-selection-list[dense] .mat-list-item.mat-2-line,.mat-selection-list[dense] .mat-list-option.mat-2-line{height:60px}.mat-list[dense] .mat-list-item.mat-3-line,.mat-list[dense] .mat-list-option.mat-3-line,.mat-nav-list[dense] .mat-list-item.mat-3-line,.mat-nav-list[dense] .mat-list-option.mat-3-line,.mat-selection-list[dense] .mat-list-item.mat-3-line,.mat-selection-list[dense] .mat-list-option.mat-3-line{height:76px}.mat-list[dense] .mat-list-item.mat-multi-line,.mat-list[dense] .mat-list-option.mat-multi-line,.mat-nav-list[dense] .mat-list-item.mat-multi-line,.mat-nav-list[dense] .mat-list-option.mat-multi-line,.mat-selection-list[dense] .mat-list-item.mat-multi-line,.mat-selection-list[dense] .mat-list-option.mat-multi-line{height:auto}.mat-list[dense] .mat-list-item.mat-multi-line .mat-list-item-content,.mat-list[dense] .mat-list-option.mat-multi-line .mat-list-item-content,.mat-nav-list[dense] .mat-list-item.mat-multi-line .mat-list-item-content,.mat-nav-list[dense] .mat-list-option.mat-multi-line .mat-list-item-content,.mat-selection-list[dense] .mat-list-item.mat-multi-line .mat-list-item-content,.mat-selection-list[dense] .mat-list-option.mat-multi-line .mat-list-item-content{padding-top:16px;padding-bottom:16px}.mat-list[dense] .mat-list-item .mat-list-text,.mat-list[dense] .mat-list-option .mat-list-text,.mat-nav-list[dense] .mat-list-item .mat-list-text,.mat-nav-list[dense] .mat-list-option .mat-list-text,.mat-selection-list[dense] .mat-list-item .mat-list-text,.mat-selection-list[dense] .mat-list-option .mat-list-text{display:flex;flex-direction:column;width:100%;box-sizing:border-box;overflow:hidden;padding:0}.mat-list[dense] .mat-list-item .mat-list-text>*,.mat-list[dense] .mat-list-option .mat-list-text>*,.mat-nav-list[dense] .mat-list-item .mat-list-text>*,.mat-nav-list[dense] .mat-list-option .mat-list-text>*,.mat-selection-list[dense] .mat-list-item .mat-list-text>*,.mat-selection-list[dense] .mat-list-option .mat-list-text>*{margin:0;padding:0;font-weight:400;font-size:inherit}.mat-list[dense] .mat-list-item .mat-list-text:empty,.mat-list[dense] .mat-list-option .mat-list-text:empty,.mat-nav-list[dense] .mat-list-item .mat-list-text:empty,.mat-nav-list[dense] .mat-list-option .mat-list-text:empty,.mat-selection-list[dense] .mat-list-item .mat-list-text:empty,.mat-selection-list[dense] .mat-list-option .mat-list-text:empty{display:none}.mat-list[dense] .mat-list-item .mat-list-item-content .mat-list-text:not(:nth-child(2)),.mat-list[dense] .mat-list-option .mat-list-item-content .mat-list-text:not(:nth-child(2)),.mat-nav-list[dense] .mat-list-item .mat-list-item-content .mat-list-text:not(:nth-child(2)),.mat-nav-list[dense] .mat-list-option .mat-list-item-content .mat-list-text:not(:nth-child(2)),.mat-selection-list[dense] .mat-list-item .mat-list-item-content .mat-list-text:not(:nth-child(2)),.mat-selection-list[dense] .mat-list-option .mat-list-item-content .mat-list-text:not(:nth-child(2)){padding-right:0;padding-left:16px}[dir=rtl] .mat-list[dense] .mat-list-item .mat-list-item-content .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-list[dense] .mat-list-option .mat-list-item-content .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-nav-list[dense] .mat-list-item .mat-list-item-content .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-nav-list[dense] .mat-list-option .mat-list-item-content .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-selection-list[dense] .mat-list-item .mat-list-item-content .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-selection-list[dense] .mat-list-option .mat-list-item-content .mat-list-text:not(:nth-child(2)){padding-right:16px;padding-left:0}.mat-list[dense] .mat-list-item .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),.mat-list[dense] .mat-list-option .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),.mat-nav-list[dense] .mat-list-item .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),.mat-nav-list[dense] .mat-list-option .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),.mat-selection-list[dense] .mat-list-item .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),.mat-selection-list[dense] .mat-list-option .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)){padding-left:0;padding-right:16px}[dir=rtl] .mat-list[dense] .mat-list-item .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-list[dense] .mat-list-option .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-nav-list[dense] .mat-list-item .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-nav-list[dense] .mat-list-option .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-selection-list[dense] .mat-list-item .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)),[dir=rtl] .mat-selection-list[dense] .mat-list-option .mat-list-item-content-reverse .mat-list-text:not(:nth-child(2)){padding-right:0;padding-left:16px}.mat-list[dense] .mat-list-item .mat-list-avatar,.mat-list[dense] .mat-list-option .mat-list-avatar,.mat-nav-list[dense] .mat-list-item .mat-list-avatar,.mat-nav-list[dense] .mat-list-option .mat-list-avatar,.mat-selection-list[dense] .mat-list-item .mat-list-avatar,.mat-selection-list[dense] .mat-list-option .mat-list-avatar{flex-shrink:0;width:36px;height:36px;border-radius:50%}.mat-list[dense] .mat-list-item .mat-list-avatar~.mat-divider-inset,.mat-list[dense] .mat-list-option .mat-list-avatar~.mat-divider-inset,.mat-nav-list[dense] .mat-list-item .mat-list-avatar~.mat-divider-inset,.mat-nav-list[dense] .mat-list-option .mat-list-avatar~.mat-divider-inset,.mat-selection-list[dense] .mat-list-item .mat-list-avatar~.mat-divider-inset,.mat-selection-list[dense] .mat-list-option .mat-list-avatar~.mat-divider-inset{margin-left:68px;width:calc(100% - 68px)}[dir=rtl] .mat-list[dense] .mat-list-item .mat-list-avatar~.mat-divider-inset,[dir=rtl] .mat-list[dense] .mat-list-option .mat-list-avatar~.mat-divider-inset,[dir=rtl] .mat-nav-list[dense] .mat-list-item .mat-list-avatar~.mat-divider-inset,[dir=rtl] .mat-nav-list[dense] .mat-list-option .mat-list-avatar~.mat-divider-inset,[dir=rtl] .mat-selection-list[dense] .mat-list-item .mat-list-avatar~.mat-divider-inset,[dir=rtl] .mat-selection-list[dense] .mat-list-option .mat-list-avatar~.mat-divider-inset{margin-left:auto;margin-right:68px}.mat-list[dense] .mat-list-item .mat-list-icon,.mat-list[dense] .mat-list-option .mat-list-icon,.mat-nav-list[dense] .mat-list-item .mat-list-icon,.mat-nav-list[dense] .mat-list-option .mat-list-icon,.mat-selection-list[dense] .mat-list-item .mat-list-icon,.mat-selection-list[dense] .mat-list-option .mat-list-icon{flex-shrink:0;width:20px;height:20px;font-size:20px;box-sizing:content-box;border-radius:50%;padding:4px}.mat-list[dense] .mat-list-item .mat-list-icon~.mat-divider-inset,.mat-list[dense] .mat-list-option .mat-list-icon~.mat-divider-inset,.mat-nav-list[dense] .mat-list-item .mat-list-icon~.mat-divider-inset,.mat-nav-list[dense] .mat-list-option .mat-list-icon~.mat-divider-inset,.mat-selection-list[dense] .mat-list-item .mat-list-icon~.mat-divider-inset,.mat-selection-list[dense] .mat-list-option .mat-list-icon~.mat-divider-inset{margin-left:60px;width:calc(100% - 60px)}[dir=rtl] .mat-list[dense] .mat-list-item .mat-list-icon~.mat-divider-inset,[dir=rtl] .mat-list[dense] .mat-list-option .mat-list-icon~.mat-divider-inset,[dir=rtl] .mat-nav-list[dense] .mat-list-item .mat-list-icon~.mat-divider-inset,[dir=rtl] .mat-nav-list[dense] .mat-list-option .mat-list-icon~.mat-divider-inset,[dir=rtl] .mat-selection-list[dense] .mat-list-item .mat-list-icon~.mat-divider-inset,[dir=rtl] .mat-selection-list[dense] .mat-list-option .mat-list-icon~.mat-divider-inset{margin-left:auto;margin-right:60px}.mat-list[dense] .mat-list-item .mat-divider,.mat-list[dense] .mat-list-option .mat-divider,.mat-nav-list[dense] .mat-list-item .mat-divider,.mat-nav-list[dense] .mat-list-option .mat-divider,.mat-selection-list[dense] .mat-list-item .mat-divider,.mat-selection-list[dense] .mat-list-option .mat-divider{position:absolute;bottom:0;left:0;width:100%;margin:0}[dir=rtl] .mat-list[dense] .mat-list-item .mat-divider,[dir=rtl] .mat-list[dense] .mat-list-option .mat-divider,[dir=rtl] .mat-nav-list[dense] .mat-list-item .mat-divider,[dir=rtl] .mat-nav-list[dense] .mat-list-option .mat-divider,[dir=rtl] .mat-selection-list[dense] .mat-list-item .mat-divider,[dir=rtl] .mat-selection-list[dense] .mat-list-option .mat-divider{margin-left:auto;margin-right:0}.mat-list[dense] .mat-list-item .mat-divider.mat-divider-inset,.mat-list[dense] .mat-list-option .mat-divider.mat-divider-inset,.mat-nav-list[dense] .mat-list-item .mat-divider.mat-divider-inset,.mat-nav-list[dense] .mat-list-option .mat-divider.mat-divider-inset,.mat-selection-list[dense] .mat-list-item .mat-divider.mat-divider-inset,.mat-selection-list[dense] .mat-list-option .mat-divider.mat-divider-inset{position:absolute}.mat-nav-list a{text-decoration:none;color:inherit}.mat-nav-list .mat-list-item{cursor:pointer;outline:0}.mat-list-option:not(.mat-list-item-disabled){cursor:pointer;outline:0}"],data:{}});function v(t){return a._27(2,[a._15(null,0)],null,null)}var h=a._2({encapsulation:2,styles:[],data:{}});function _(t){return a._27(2,[(t()(),a._4(0,0,null,null,6,"div",[["class","mat-list-item-content"]],null,null,null,null,null)),(t()(),a._4(1,0,null,null,1,"div",[["class","mat-list-item-ripple mat-ripple"],["mat-ripple",""]],[[2,"mat-ripple-unbounded",null]],null,null,null,null)),a._3(2,212992,null,0,c.v,[a.k,a.y,r.a,[2,c.k]],{disabled:[0,"disabled"],trigger:[1,"trigger"]},null),a._15(null,0),(t()(),a._4(4,0,null,null,1,"div",[["class","mat-list-text"]],null,null,null,null,null)),a._15(null,1),a._15(null,2)],function(t,i){var l=i.component;t(i,2,0,l._isRippleDisabled(),l._getHostElement())},function(t,i){t(i,1,0,a._16(i,2).unbounded)})}var x=a._2({encapsulation:2,styles:[".mat-divider{display:block;margin:0;border-top-width:1px;border-top-style:solid}.mat-divider.mat-divider-vertical{border-top:0;border-right-width:1px;border-right-style:solid}.mat-divider.mat-divider-inset{margin-left:80px}[dir=rtl] .mat-divider.mat-divider-inset{margin-left:auto;margin-right:80px}"],data:{}});function g(t){return a._27(2,[],null,null)}var b=l("RoIQ"),f=l("z7Rf"),w=l("s8YX"),y=l("bfOx"),k=function(){function t(t,i){this.bs=t,this.router=i,this.userData=null,this.userLinks=[]}return t.prototype.ngOnInit=function(){var t=this;this.bs.isInit()?(this.bs.getUserInfo(function(i){t.userData=i.data}),this.bs.getUserLinks(function(i){t.userLinks=i.data})):this.router.navigate(["/"])},t}(),O=a._2({encapsulation:0,styles:[[".about-container[_ngcontent-%COMP%]{margin:20px;vertical-align:top;padding:10px}.sidenav-content-header-container[_ngcontent-%COMP%]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:#3f51b5;padding-left:20px}.sidenav-content-header-container[_ngcontent-%COMP%] h1[_ngcontent-%COMP%]{font-size:20px;font-weight:300;margin:0;padding:20px 8px;outline:0;color:#fff}.views-count[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{vertical-align:middle}.mb-3[_ngcontent-%COMP%]{margin-bottom:2px}.soical-link[_ngcontent-%COMP%]{display:inline-block;cursor:pointer;margin:10px}.soical-link[_ngcontent-%COMP%] img[_ngcontent-%COMP%]{border-radius:50%;width:60px;height:60px}.soical-link[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{font-size:13px;color:#666;margin:0!important}.soical-link[_ngcontent-%COMP%]:hover > p[_ngcontent-%COMP%]{color:red}"]],data:{}});function z(t){return a._27(0,[(t()(),a._4(0,0,null,null,65,"mat-card",[["class","about-container mat-card"]],null,null,null,n.b,n.a)),a._3(1,49152,null,0,s.a,[],null,null),(t()(),a._25(-1,0,["\n "])),(t()(),a._4(3,0,null,0,61,"mat-list",[["class","mat-list"]],null,null,null,v,p)),a._3(4,49152,null,0,m.a,[],null,null),(t()(),a._25(-1,0,["\n "])),(t()(),a._4(6,0,null,0,2,"h3",[["class","mat-subheader"],["mat-subheader",""]],null,null,null,null,null)),a._3(7,16384,null,0,m.e,[],null,null),(t()(),a._25(-1,null,["\u4e2a\u4eba\u7b80\u4ecb"])),(t()(),a._25(-1,0,["\n "])),(t()(),a._4(10,0,null,0,8,"mat-list-item",[["class","mat-list-item"]],[[2,"mat-list-item-avatar",null],[2,"mat-list-item-with-avatar",null]],[[null,"focus"],[null,"blur"]],function(t,i,l){var e=!0;return"focus"===i&&(e=!1!==a._16(t,11)._handleFocus()&&e),"blur"===i&&(e=!1!==a._16(t,11)._handleBlur()&&e),e},_,h)),a._3(11,1097728,null,2,m.b,[a.k,[2,m.f]],null,null),a._23(603979776,1,{_lines:1}),a._23(335544320,2,{_avatar:0}),(t()(),a._25(-1,2,["\n "])),(t()(),a._25(-1,2,["\n "])),(t()(),a._4(16,0,null,2,1,"p",[],null,null,null,null,null)),(t()(),a._25(17,null,["",""])),(t()(),a._25(-1,2,["\n "])),(t()(),a._25(-1,0,["\n "])),(t()(),a._4(20,0,null,0,1,"mat-divider",[["class","mat-divider"],["role","separator"]],[[1,"aria-orientation",0],[2,"mat-divider-vertical",null],[2,"mat-divider-inset",null]],null,null,g,x)),a._3(21,49152,null,0,u.a,[],null,null),(t()(),a._25(-1,0,["\n "])),(t()(),a._4(23,0,null,0,12,"mat-list-item",[["class","mat-list-item"]],[[2,"mat-list-item-avatar",null],[2,"mat-list-item-with-avatar",null]],[[null,"focus"],[null,"blur"]],function(t,i,l){var e=!0;return"focus"===i&&(e=!1!==a._16(t,24)._handleFocus()&&e),"blur"===i&&(e=!1!==a._16(t,24)._handleBlur()&&e),e},_,h)),a._3(24,1097728,null,2,m.b,[a.k,[2,m.f]],null,null),a._23(603979776,3,{_lines:1}),a._23(335544320,4,{_avatar:0}),(t()(),a._25(-1,2,["\n "])),(t()(),a._4(28,0,null,1,6,"a",[["class","views-count mat-line"],["mat-line",""]],null,null,null,null,null)),a._3(29,16384,[[3,4]],0,c.m,[],null,null),(t()(),a._25(-1,null,["\n "])),(t()(),a._4(31,0,null,null,2,"mat-icon",[["class","mb-3 mat-icon"],["role","img"]],null,null,null,b.b,b.a)),a._3(32,638976,null,0,f.b,[a.k,f.d,[8,null]],null,null),(t()(),a._25(-1,0,["supervisor_account"])),(t()(),a._25(34,null,["\n ",""])),(t()(),a._25(-1,2,["\n "])),(t()(),a._25(-1,0,["\n "])),(t()(),a._4(37,0,null,0,12,"mat-list-item",[["class","mat-list-item"]],[[2,"mat-list-item-avatar",null],[2,"mat-list-item-with-avatar",null]],[[null,"focus"],[null,"blur"]],function(t,i,l){var e=!0;return"focus"===i&&(e=!1!==a._16(t,38)._handleFocus()&&e),"blur"===i&&(e=!1!==a._16(t,38)._handleBlur()&&e),e},_,h)),a._3(38,1097728,null,2,m.b,[a.k,[2,m.f]],null,null),a._23(603979776,5,{_lines:1}),a._23(335544320,6,{_avatar:0}),(t()(),a._25(-1,2,["\n "])),(t()(),a._4(42,0,null,1,6,"a",[["class","views-count mat-line"],["mat-line",""]],null,null,null,null,null)),a._3(43,16384,[[5,4]],0,c.m,[],null,null),(t()(),a._25(-1,null,["\n "])),(t()(),a._4(45,0,null,null,2,"mat-icon",[["class","mb-3 mat-icon"],["role","img"]],null,null,null,b.b,b.a)),a._3(46,638976,null,0,f.b,[a.k,f.d,[8,null]],null,null),(t()(),a._25(-1,0,["email"])),(t()(),a._25(48,null,["\n ",""])),(t()(),a._25(-1,2,["\n "])),(t()(),a._25(-1,0,["\n "])),(t()(),a._4(51,0,null,0,12,"mat-list-item",[["class","mat-list-item"]],[[2,"mat-list-item-avatar",null],[2,"mat-list-item-with-avatar",null]],[[null,"focus"],[null,"blur"]],function(t,i,l){var e=!0;return"focus"===i&&(e=!1!==a._16(t,52)._handleFocus()&&e),"blur"===i&&(e=!1!==a._16(t,52)._handleBlur()&&e),e},_,h)),a._3(52,1097728,null,2,m.b,[a.k,[2,m.f]],null,null),a._23(603979776,7,{_lines:1}),a._23(335544320,8,{_avatar:0}),(t()(),a._25(-1,2,["\n "])),(t()(),a._4(56,0,null,1,6,"a",[["class","views-count mat-line"],["mat-line",""]],null,null,null,null,null)),a._3(57,16384,[[7,4]],0,c.m,[],null,null),(t()(),a._25(-1,null,["\n "])),(t()(),a._4(59,0,null,null,2,"mat-icon",[["class","mb-3 mat-icon"],["role","img"]],null,null,null,b.b,b.a)),a._3(60,638976,null,0,f.b,[a.k,f.d,[8,null]],null,null),(t()(),a._25(-1,0,["location_on"])),(t()(),a._25(62,null,["\n ",""])),(t()(),a._25(-1,2,["\n "])),(t()(),a._25(-1,0,["\n "])),(t()(),a._25(-1,0,["\n "]))],function(t,i){t(i,32,0),t(i,46,0),t(i,60,0)},function(t,i){var l=i.component;t(i,10,0,a._16(i,11)._avatar,a._16(i,11)._avatar),t(i,17,0,l.userData.user_desc),t(i,20,0,a._16(i,21).vertical?"vertical":"horizontal",a._16(i,21).vertical,a._16(i,21).inset),t(i,23,0,a._16(i,24)._avatar,a._16(i,24)._avatar),t(i,34,0,l.userData.nick_name),t(i,37,0,a._16(i,38)._avatar,a._16(i,38)._avatar),t(i,48,0,l.userData.user_email),t(i,51,0,a._16(i,52)._avatar,a._16(i,52)._avatar),t(i,62,0,l.userData.user_addr)})}function M(t){return a._27(0,[(t()(),a._4(0,0,null,null,6,"a",[["class","soical-link"],["target","_blank"]],[[8,"href",4]],null,null,null,null)),(t()(),a._25(-1,null,["\n "])),(t()(),a._4(2,0,null,null,0,"img",[],[[8,"src",4]],null,null,null,null)),(t()(),a._25(-1,null,["\n "])),(t()(),a._4(4,0,null,null,1,"p",[],null,null,null,null,null)),(t()(),a._25(5,null,["",""])),(t()(),a._25(-1,null,["\n "]))],null,function(t,i){t(i,0,0,a._7(1,"",i.context.$implicit.link_url,"")),t(i,2,0,a._7(1,"",i.context.$implicit.link_icon,"")),t(i,5,0,i.context.$implicit.link_name)})}function C(t){return a._27(0,[(t()(),a._4(0,0,null,null,16,"mat-card",[["class","about-container mat-card"]],null,null,null,n.b,n.a)),a._3(1,49152,null,0,s.a,[],null,null),(t()(),a._25(-1,0,["\n "])),(t()(),a._4(3,0,null,0,12,"mat-list",[["class","mat-list"]],null,null,null,v,p)),a._3(4,49152,null,0,m.a,[],null,null),(t()(),a._25(-1,0,["\n "])),(t()(),a._4(6,0,null,0,2,"h3",[["class","mat-subheader"],["mat-subheader",""]],null,null,null,null,null)),a._3(7,16384,null,0,m.e,[],null,null),(t()(),a._25(-1,null,["\u53cb\u60c5\u94fe\u63a5"])),(t()(),a._25(-1,0,["\n "])),(t()(),a._4(10,0,null,0,1,"mat-divider",[["class","mat-divider"],["role","separator"]],[[1,"aria-orientation",0],[2,"mat-divider-vertical",null],[2,"mat-divider-inset",null]],null,null,g,x)),a._3(11,49152,null,0,u.a,[],null,null),(t()(),a._25(-1,0,["\n "])),(t()(),a.Z(16777216,null,0,1,null,M)),a._3(14,802816,null,0,d.k,[a.N,a.K,a.r],{ngForOf:[0,"ngForOf"]},null),(t()(),a._25(-1,0,["\n "])),(t()(),a._25(-1,0,["\n "]))],function(t,i){t(i,14,0,i.component.userLinks)},function(t,i){t(i,10,0,a._16(i,11).vertical?"vertical":"horizontal",a._16(i,11).vertical,a._16(i,11).inset)})}function P(t){return a._27(0,[(t()(),a._4(0,0,null,null,13,"div",[],null,null,null,null,null)),(t()(),a._25(-1,null,["\n "])),(t()(),a._4(2,0,null,null,4,"div",[["class","sidenav-content-header-container"]],null,null,null,null,null)),(t()(),a._25(-1,null,["\n "])),(t()(),a._4(4,0,null,null,1,"h1",[],null,null,null,null,null)),(t()(),a._25(-1,null,["\u5173\u4e8e\u6211"])),(t()(),a._25(-1,null,["\n "])),(t()(),a._25(-1,null,["\n "])),(t()(),a.Z(16777216,null,null,1,null,z)),a._3(9,16384,null,0,d.l,[a.N,a.K],{ngIf:[0,"ngIf"]},null),(t()(),a._25(-1,null,["\n "])),(t()(),a.Z(16777216,null,null,1,null,C)),a._3(12,16384,null,0,d.l,[a.N,a.K],{ngIf:[0,"ngIf"]},null),(t()(),a._25(-1,null,["\n"])),(t()(),a._25(-1,null,["\n"]))],function(t,i){var l=i.component;t(i,9,0,l.userData),t(i,12,0,l.userLinks)},null)}var D=a._0("app-aboutus",k,function(t){return a._27(0,[(t()(),a._4(0,0,null,null,1,"app-aboutus",[],null,null,null,P,O)),a._3(1,114688,null,0,k,[w.a,y.k],null,null)],function(t,i){t(i,1,0)},null)},{},{},[]),I=l("ItHS"),F=l("OE0E"),j=function(){};l.d(i,"AboutusModuleNgFactory",function(){return B});var B=a._1(e,[],function(t){return a._12([a._13(512,a.j,a.X,[[8,[D]],[3,a.j],a.w]),a._13(4608,d.n,d.m,[a.t,[2,d.u]]),a._13(6144,o.b,null,[d.d]),a._13(4608,o.c,o.c,[[2,o.b]]),a._13(5120,f.d,f.a,[[3,f.d],[2,I.c],F.c,[2,d.d]]),a._13(4608,r.a,r.a,[]),a._13(512,d.c,d.c,[]),a._13(512,y.n,y.n,[[2,y.s],[2,y.k]]),a._13(512,j,j,[]),a._13(512,o.a,o.a,[]),a._13(256,c.e,!0,[]),a._13(512,c.l,c.l,[[2,c.e]]),a._13(512,f.c,f.c,[]),a._13(512,c.n,c.n,[]),a._13(512,r.b,r.b,[]),a._13(512,c.w,c.w,[]),a._13(512,c.u,c.u,[]),a._13(512,u.b,u.b,[]),a._13(512,m.c,m.c,[]),a._13(512,s.c,s.c,[]),a._13(512,e,e,[]),a._13(1024,y.i,function(){return[[{path:"",component:k}]]},[])])})}}); -------------------------------------------------------------------------------- /front/3rdpartylicenses.txt: -------------------------------------------------------------------------------- 1 | @angular/material@5.2.5 2 | MIT 3 | The MIT License 4 | 5 | Copyright (c) 2018 Google LLC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | 25 | cache-loader@1.2.2 26 | MIT 27 | Copyright JS Foundation and other contributors 28 | 29 | Permission is hereby granted, free of charge, to any person obtaining 30 | a copy of this software and associated documentation files (the 31 | 'Software'), to deal in the Software without restriction, including 32 | without limitation the rights to use, copy, modify, merge, publish, 33 | distribute, sublicense, and/or sell copies of the Software, and to 34 | permit persons to whom the Software is furnished to do so, subject to 35 | the following conditions: 36 | 37 | The above copyright notice and this permission notice shall be 38 | included in all copies or substantial portions of the Software. 39 | 40 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 41 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 42 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 43 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 44 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 45 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 46 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 47 | 48 | @angular-devkit/build-optimizer@0.3.2 49 | MIT 50 | The MIT License 51 | 52 | Copyright (c) 2017 Google, Inc. 53 | 54 | Permission is hereby granted, free of charge, to any person obtaining a copy 55 | of this software and associated documentation files (the "Software"), to deal 56 | in the Software without restriction, including without limitation the rights 57 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 58 | copies of the Software, and to permit persons to whom the Software is 59 | furnished to do so, subject to the following conditions: 60 | 61 | The above copyright notice and this permission notice shall be included in all 62 | copies or substantial portions of the Software. 63 | 64 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 65 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 66 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 67 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 68 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 69 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 70 | SOFTWARE. 71 | 72 | @angular/forms@5.2.11 73 | MIT 74 | MIT 75 | 76 | @angular/cdk@5.2.5 77 | MIT 78 | The MIT License 79 | 80 | Copyright (c) 2018 Google LLC. 81 | 82 | Permission is hereby granted, free of charge, to any person obtaining a copy 83 | of this software and associated documentation files (the "Software"), to deal 84 | in the Software without restriction, including without limitation the rights 85 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 86 | copies of the Software, and to permit persons to whom the Software is 87 | furnished to do so, subject to the following conditions: 88 | 89 | The above copyright notice and this permission notice shall be included in 90 | all copies or substantial portions of the Software. 91 | 92 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 93 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 94 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 95 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 96 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 97 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 98 | THE SOFTWARE. 99 | 100 | jquery@3.3.1 101 | MIT 102 | Copyright JS Foundation and other contributors, https://js.foundation/ 103 | 104 | This software consists of voluntary contributions made by many 105 | individuals. For exact contribution history, see the revision history 106 | available at https://github.com/jquery/jquery 107 | 108 | The following license applies to all parts of this software except as 109 | documented below: 110 | 111 | ==== 112 | 113 | Permission is hereby granted, free of charge, to any person obtaining 114 | a copy of this software and associated documentation files (the 115 | "Software"), to deal in the Software without restriction, including 116 | without limitation the rights to use, copy, modify, merge, publish, 117 | distribute, sublicense, and/or sell copies of the Software, and to 118 | permit persons to whom the Software is furnished to do so, subject to 119 | the following conditions: 120 | 121 | The above copyright notice and this permission notice shall be 122 | included in all copies or substantial portions of the Software. 123 | 124 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 125 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 126 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 127 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 128 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 129 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 130 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 131 | 132 | ==== 133 | 134 | All files located in the node_modules and external directories are 135 | externally maintained libraries used by this software which have their 136 | own licenses; we recommend you read them, as their terms may differ from 137 | the terms above. 138 | 139 | @angular/core@5.2.11 140 | MIT 141 | MIT 142 | 143 | @angular/common@5.2.11 144 | MIT 145 | MIT 146 | 147 | @angular/router@5.2.11 148 | MIT 149 | MIT 150 | 151 | @angular/platform-browser@5.2.11 152 | MIT 153 | MIT 154 | 155 | @types/jquery@3.3.10 156 | MIT 157 | MIT License 158 | 159 | Copyright (c) Microsoft Corporation. All rights reserved. 160 | 161 | Permission is hereby granted, free of charge, to any person obtaining a copy 162 | of this software and associated documentation files (the "Software"), to deal 163 | in the Software without restriction, including without limitation the rights 164 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 165 | copies of the Software, and to permit persons to whom the Software is 166 | furnished to do so, subject to the following conditions: 167 | 168 | The above copyright notice and this permission notice shall be included in all 169 | copies or substantial portions of the Software. 170 | 171 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 172 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 173 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 174 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 175 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 176 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 177 | SOFTWARE 178 | 179 | core-js@2.5.7 180 | MIT 181 | Copyright (c) 2014-2018 Denis Pushkarev 182 | 183 | Permission is hereby granted, free of charge, to any person obtaining a copy 184 | of this software and associated documentation files (the "Software"), to deal 185 | in the Software without restriction, including without limitation the rights 186 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 187 | copies of the Software, and to permit persons to whom the Software is 188 | furnished to do so, subject to the following conditions: 189 | 190 | The above copyright notice and this permission notice shall be included in 191 | all copies or substantial portions of the Software. 192 | 193 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 194 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 195 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 196 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 197 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 198 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 199 | THE SOFTWARE. 200 | 201 | zone.js@0.8.26 202 | MIT 203 | The MIT License 204 | 205 | Copyright (c) 2016-2018 Google, Inc. 206 | 207 | Permission is hereby granted, free of charge, to any person obtaining a copy 208 | of this software and associated documentation files (the "Software"), to deal 209 | in the Software without restriction, including without limitation the rights 210 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 211 | copies of the Software, and to permit persons to whom the Software is 212 | furnished to do so, subject to the following conditions: 213 | 214 | The above copyright notice and this permission notice shall be included in 215 | all copies or substantial portions of the Software. 216 | 217 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 218 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 219 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 220 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 221 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 222 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 223 | THE SOFTWARE. 224 | 225 | webpack@3.11.0 226 | MIT 227 | Copyright JS Foundation and other contributors 228 | 229 | Permission is hereby granted, free of charge, to any person obtaining 230 | a copy of this software and associated documentation files (the 231 | 'Software'), to deal in the Software without restriction, including 232 | without limitation the rights to use, copy, modify, merge, publish, 233 | distribute, sublicense, and/or sell copies of the Software, and to 234 | permit persons to whom the Software is furnished to do so, subject to 235 | the following conditions: 236 | 237 | The above copyright notice and this permission notice shall be 238 | included in all copies or substantial portions of the Software. 239 | 240 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 241 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 242 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 243 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 244 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 245 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 246 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 247 | 248 | @angular/animations@5.2.11 249 | MIT 250 | MIT 251 | 252 | ts-md5@1.2.4 253 | MIT 254 | MIT 255 | 256 | hammerjs@2.0.8 257 | MIT 258 | The MIT License (MIT) 259 | 260 | Copyright (C) 2011-2014 by Jorik Tangelder (Eight Media) 261 | 262 | Permission is hereby granted, free of charge, to any person obtaining a copy 263 | of this software and associated documentation files (the "Software"), to deal 264 | in the Software without restriction, including without limitation the rights 265 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 266 | copies of the Software, and to permit persons to whom the Software is 267 | furnished to do so, subject to the following conditions: 268 | 269 | The above copyright notice and this permission notice shall be included in 270 | all copies or substantial portions of the Software. 271 | 272 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 273 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 274 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 275 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 276 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 277 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 278 | THE SOFTWARE. 279 | 280 | @angular/platform-browser-dynamic@5.2.11 281 | MIT 282 | MIT -------------------------------------------------------------------------------- /front/assets/avator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyw1995/Angular5-Blog-Front/6a8a722a4895f317eeff698389c15b49e614fb5e/front/assets/avator.jpg -------------------------------------------------------------------------------- /front/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyw1995/Angular5-Blog-Front/6a8a722a4895f317eeff698389c15b49e614fb5e/front/favicon.ico -------------------------------------------------------------------------------- /front/index.html: -------------------------------------------------------------------------------- 1 | 博客loading... -------------------------------------------------------------------------------- /front/inline.8f9113764960a7b7d2b9.bundle.js: -------------------------------------------------------------------------------- 1 | !function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,a){for(var u,i,f,l=0,s=[];l.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){color:rgba(0,0,0,.38)}.cdk-keyboard-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.cdk-program-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),:not(.mat-calendar-body-disabled):hover>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){background-color:rgba(0,0,0,.04)}.mat-calendar-body-selected{background-color:#3f51b5;color:#fff}.mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(63,81,181,.4)}.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.38)}.mat-calendar-body-today.mat-calendar-body-selected{-webkit-box-shadow:inset 0 0 0 1px #fff;box-shadow:inset 0 0 0 1px #fff}.mat-calendar-body-disabled>.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.18)}.mat-datepicker-toggle-active{color:#3f51b5}.mat-dialog-container{background:#fff;color:rgba(0,0,0,.87)}.mat-divider{border-top-color:rgba(0,0,0,.12)}.mat-divider-vertical{border-right-color:rgba(0,0,0,.12)}.mat-expansion-panel{background:#fff;color:rgba(0,0,0,.87)}.mat-action-row{border-top-color:rgba(0,0,0,.12)}.mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-keyboard-focused,.mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]).cdk-program-focused,.mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:rgba(0,0,0,.04)}.mat-expansion-panel-header-title{color:rgba(0,0,0,.87)}.mat-expansion-indicator::after,.mat-expansion-panel-header-description{color:rgba(0,0,0,.54)}.mat-expansion-panel-header[aria-disabled=true]{color:rgba(0,0,0,.26)}.mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-description,.mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-title{color:inherit}.mat-form-field-label,.mat-hint{color:rgba(0,0,0,.54)}.mat-focused .mat-form-field-label{color:#3f51b5}.mat-focused .mat-form-field-label.mat-accent{color:#ff4081}.mat-focused .mat-form-field-label.mat-warn{color:#f44336}.mat-focused .mat-form-field-required-marker{color:#ff4081}.mat-form-field-underline{background-color:rgba(0,0,0,.42)}.mat-form-field-disabled .mat-form-field-underline{background-image:-webkit-gradient(linear,left top,right top,color-stop(0,rgba(0,0,0,.42)),color-stop(33%,rgba(0,0,0,.42)),color-stop(0,transparent));background-image:linear-gradient(to right,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);background-size:4px 1px;background-repeat:repeat-x}.mat-form-field-ripple{background-color:#3f51b5}.mat-form-field-ripple.mat-accent{background-color:#ff4081}.mat-form-field-ripple.mat-warn{background-color:#f44336}.mat-form-field-invalid .mat-form-field-label,.mat-form-field-invalid .mat-form-field-label .mat-form-field-required-marker,.mat-form-field-invalid .mat-form-field-label.mat-accent{color:#f44336}.mat-form-field-invalid .mat-form-field-ripple{background-color:#f44336}.mat-error{color:#f44336}.mat-icon.mat-primary{color:#3f51b5}.mat-icon.mat-accent{color:#ff4081}.mat-icon.mat-warn{color:#f44336}.mat-input-element:disabled{color:rgba(0,0,0,.38)}.mat-input-element{caret-color:#3f51b5}.mat-input-element::-ms-input-placeholder{color:rgba(0,0,0,.42)}.mat-input-element::placeholder{color:rgba(0,0,0,.42)}.mat-input-element::-moz-placeholder{color:rgba(0,0,0,.42)}.mat-input-element::-webkit-input-placeholder{color:rgba(0,0,0,.42)}.mat-input-element:-ms-input-placeholder{color:rgba(0,0,0,.42)}.mat-accent .mat-input-element{caret-color:#ff4081}.mat-form-field-invalid .mat-input-element,.mat-warn .mat-input-element{caret-color:#f44336}.mat-list .mat-list-item,.mat-list .mat-list-option,.mat-nav-list .mat-list-item,.mat-nav-list .mat-list-option,.mat-selection-list .mat-list-item,.mat-selection-list .mat-list-option{color:rgba(0,0,0,.87)}.mat-list .mat-subheader,.mat-nav-list .mat-subheader,.mat-selection-list .mat-subheader{font-family:Roboto,"Helvetica Neue",sans-serif;font-size:14px;font-weight:500;color:rgba(0,0,0,.54)}.mat-list-item-disabled{background-color:#eee}.mat-list-option.mat-list-item-focus,.mat-list-option:hover,.mat-nav-list .mat-list-item.mat-list-item-focus,.mat-nav-list .mat-list-item:hover{background:rgba(0,0,0,.04)}.mat-menu-panel{background:#fff}.mat-menu-item{background:0 0;color:rgba(0,0,0,.87)}.mat-menu-item[disabled]{color:rgba(0,0,0,.38)}.mat-menu-item .mat-icon:not([color]),.mat-menu-item-submenu-trigger::after{color:rgba(0,0,0,.54)}.mat-menu-item-highlighted:not([disabled]),.mat-menu-item.cdk-keyboard-focused:not([disabled]),.mat-menu-item.cdk-program-focused:not([disabled]),.mat-menu-item:hover:not([disabled]){background:rgba(0,0,0,.04)}.mat-paginator{background:#fff}.mat-paginator,.mat-paginator-page-size .mat-select-trigger{color:rgba(0,0,0,.54)}.mat-paginator-decrement,.mat-paginator-increment{border-top:2px solid rgba(0,0,0,.54);border-right:2px solid rgba(0,0,0,.54)}.mat-paginator-first,.mat-paginator-last{border-top:2px solid rgba(0,0,0,.54)}.mat-icon-button[disabled] .mat-paginator-decrement,.mat-icon-button[disabled] .mat-paginator-first,.mat-icon-button[disabled] .mat-paginator-increment,.mat-icon-button[disabled] .mat-paginator-last{border-color:rgba(0,0,0,.38)}.mat-progress-bar-background{fill:#c5cae9}.mat-progress-bar-buffer{background-color:#c5cae9}.mat-progress-bar-fill::after{background-color:#3f51b5}.mat-progress-bar.mat-accent .mat-progress-bar-background{fill:#ff80ab}.mat-progress-bar.mat-accent .mat-progress-bar-buffer{background-color:#ff80ab}.mat-progress-bar.mat-accent .mat-progress-bar-fill::after{background-color:#ff4081}.mat-progress-bar.mat-warn .mat-progress-bar-background{fill:#ffcdd2}.mat-progress-bar.mat-warn .mat-progress-bar-buffer{background-color:#ffcdd2}.mat-progress-bar.mat-warn .mat-progress-bar-fill::after{background-color:#f44336}.mat-progress-spinner circle,.mat-spinner circle{stroke:#3f51b5}.mat-progress-spinner.mat-accent circle,.mat-spinner.mat-accent circle{stroke:#ff4081}.mat-progress-spinner.mat-warn circle,.mat-spinner.mat-warn circle{stroke:#f44336}.mat-radio-outer-circle{border-color:rgba(0,0,0,.54)}.mat-radio-disabled .mat-radio-outer-circle{border-color:rgba(0,0,0,.38)}.mat-radio-disabled .mat-radio-inner-circle,.mat-radio-disabled .mat-radio-ripple .mat-ripple-element{background-color:rgba(0,0,0,.38)}.mat-radio-disabled .mat-radio-label-content{color:rgba(0,0,0,.38)}.mat-radio-button.mat-primary.mat-radio-checked .mat-radio-outer-circle{border-color:#3f51b5}.mat-radio-button.mat-primary .mat-radio-inner-circle{background-color:#3f51b5}.mat-radio-button.mat-primary .mat-radio-ripple .mat-ripple-element{background-color:rgba(63,81,181,.26)}.mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:#ff4081}.mat-radio-button.mat-accent .mat-radio-inner-circle{background-color:#ff4081}.mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element{background-color:rgba(255,64,129,.26)}.mat-radio-button.mat-warn.mat-radio-checked .mat-radio-outer-circle{border-color:#f44336}.mat-radio-button.mat-warn .mat-radio-inner-circle{background-color:#f44336}.mat-radio-button.mat-warn .mat-radio-ripple .mat-ripple-element{background-color:rgba(244,67,54,.26)}.mat-select-content,.mat-select-panel-done-animating{background:#fff}.mat-select-value{color:rgba(0,0,0,.87)}.mat-select-placeholder{color:rgba(0,0,0,.42)}.mat-select-disabled .mat-select-value{color:rgba(0,0,0,.38)}.mat-select-arrow{color:rgba(0,0,0,.54)}.mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple){background:rgba(0,0,0,.12)}.mat-form-field.mat-focused.mat-primary .mat-select-arrow{color:#3f51b5}.mat-form-field.mat-focused.mat-accent .mat-select-arrow{color:#ff4081}.mat-form-field .mat-select.mat-select-invalid .mat-select-arrow,.mat-form-field.mat-focused.mat-warn .mat-select-arrow{color:#f44336}.mat-form-field .mat-select.mat-select-disabled .mat-select-arrow{color:rgba(0,0,0,.38)}.mat-drawer-container{background-color:#fafafa;color:rgba(0,0,0,.87)}.mat-drawer{background-color:#fff;color:rgba(0,0,0,.87)}.mat-drawer.mat-drawer-push{background-color:#fff}.mat-drawer-backdrop.mat-drawer-shown{background-color:rgba(0,0,0,.6)}.mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#e91e63}.mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(233,30,99,.5)}.mat-slide-toggle:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.mat-slide-toggle .mat-ripple-element{background-color:rgba(233,30,99,.12)}.mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#3f51b5}.mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(63,81,181,.5)}.mat-slide-toggle.mat-primary:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.mat-slide-toggle.mat-primary .mat-ripple-element{background-color:rgba(63,81,181,.12)}.mat-slide-toggle.mat-warn.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#f44336}.mat-slide-toggle.mat-warn.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(244,67,54,.5)}.mat-slide-toggle.mat-warn:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.mat-slide-toggle.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.12)}.mat-disabled .mat-slide-toggle-thumb{background-color:#bdbdbd}.mat-disabled .mat-slide-toggle-bar{background-color:rgba(0,0,0,.1)}.mat-slide-toggle-thumb{background-color:#fafafa}.mat-slide-toggle-bar{background-color:rgba(0,0,0,.38)}.mat-slider-track-background{background-color:rgba(0,0,0,.26)}.mat-primary .mat-slider-thumb,.mat-primary .mat-slider-thumb-label,.mat-primary .mat-slider-track-fill{background-color:#3f51b5}.mat-primary .mat-slider-thumb-label-text{color:#fff}.mat-accent .mat-slider-thumb,.mat-accent .mat-slider-thumb-label,.mat-accent .mat-slider-track-fill{background-color:#ff4081}.mat-accent .mat-slider-thumb-label-text{color:#fff}.mat-warn .mat-slider-thumb,.mat-warn .mat-slider-thumb-label,.mat-warn .mat-slider-track-fill{background-color:#f44336}.mat-warn .mat-slider-thumb-label-text{color:#fff}.mat-slider-focus-ring{background-color:rgba(255,64,129,.2)}.cdk-focused .mat-slider-track-background,.mat-slider:hover .mat-slider-track-background{background-color:rgba(0,0,0,.38)}.mat-slider-disabled .mat-slider-thumb,.mat-slider-disabled .mat-slider-track-background,.mat-slider-disabled .mat-slider-track-fill,.mat-slider-disabled:hover .mat-slider-track-background{background-color:rgba(0,0,0,.26)}.mat-slider-min-value .mat-slider-focus-ring{background-color:rgba(0,0,0,.12)}.mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb,.mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb-label{background-color:rgba(0,0,0,.87)}.mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb,.mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb-label{background-color:rgba(0,0,0,.26)}.mat-slider-min-value:not(.mat-slider-thumb-label-showing) .mat-slider-thumb{border-color:rgba(0,0,0,.26);background-color:transparent}.mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused .mat-slider-thumb,.mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover .mat-slider-thumb{border-color:rgba(0,0,0,.38)}.mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused.mat-slider-disabled .mat-slider-thumb,.mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover.mat-slider-disabled .mat-slider-thumb{border-color:rgba(0,0,0,.26)}.mat-slider-has-ticks .mat-slider-wrapper::after{border-color:rgba(0,0,0,.7)}.mat-slider-horizontal .mat-slider-ticks{background-image:repeating-linear-gradient(to right,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent);background-image:-moz-repeating-linear-gradient(.0001deg,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.mat-slider-vertical .mat-slider-ticks{background-image:repeating-linear-gradient(to bottom,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.mat-step-header.cdk-keyboard-focused,.mat-step-header.cdk-program-focused,.mat-step-header:hover{background-color:rgba(0,0,0,.04)}.mat-step-header .mat-step-label,.mat-step-header .mat-step-optional{color:rgba(0,0,0,.38)}.mat-step-header .mat-step-icon{background-color:#3f51b5;color:#fff}.mat-step-header .mat-step-icon-not-touched{background-color:rgba(0,0,0,.38);color:#fff}.mat-step-header .mat-step-label.mat-step-label-active{color:rgba(0,0,0,.87)}.mat-stepper-horizontal,.mat-stepper-vertical{background-color:#fff}.mat-stepper-vertical-line::before{border-left-color:rgba(0,0,0,.12)}.mat-stepper-horizontal-line{border-top-color:rgba(0,0,0,.12)}.mat-tab-header,.mat-tab-nav-bar{border-bottom:1px solid rgba(0,0,0,.12)}.mat-tab-group-inverted-header .mat-tab-header,.mat-tab-group-inverted-header .mat-tab-nav-bar{border-top:1px solid rgba(0,0,0,.12);border-bottom:none}.mat-tab-label,.mat-tab-link{color:rgba(0,0,0,.87)}.mat-tab-label.mat-tab-disabled,.mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.38)}.mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.87)}.mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,.38)}.mat-tab-group[class*=mat-background-] .mat-tab-header,.mat-tab-nav-bar[class*=mat-background-]{border-bottom:none;border-top:none}.mat-tab-group.mat-primary .mat-tab-label:not(.mat-tab-disabled):focus,.mat-tab-group.mat-primary .mat-tab-link:not(.mat-tab-disabled):focus,.mat-tab-nav-bar.mat-primary .mat-tab-label:not(.mat-tab-disabled):focus,.mat-tab-nav-bar.mat-primary .mat-tab-link:not(.mat-tab-disabled):focus{background-color:rgba(197,202,233,.3)}.mat-tab-group.mat-primary .mat-ink-bar,.mat-tab-nav-bar.mat-primary .mat-ink-bar{background-color:#3f51b5}.mat-tab-group.mat-primary.mat-background-primary .mat-ink-bar,.mat-tab-nav-bar.mat-primary.mat-background-primary .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-accent .mat-tab-label:not(.mat-tab-disabled):focus,.mat-tab-group.mat-accent .mat-tab-link:not(.mat-tab-disabled):focus,.mat-tab-nav-bar.mat-accent .mat-tab-label:not(.mat-tab-disabled):focus,.mat-tab-nav-bar.mat-accent .mat-tab-link:not(.mat-tab-disabled):focus{background-color:rgba(255,128,171,.3)}.mat-tab-group.mat-accent .mat-ink-bar,.mat-tab-nav-bar.mat-accent .mat-ink-bar{background-color:#ff4081}.mat-tab-group.mat-accent.mat-background-accent .mat-ink-bar,.mat-tab-nav-bar.mat-accent.mat-background-accent .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-warn .mat-tab-label:not(.mat-tab-disabled):focus,.mat-tab-group.mat-warn .mat-tab-link:not(.mat-tab-disabled):focus,.mat-tab-nav-bar.mat-warn .mat-tab-label:not(.mat-tab-disabled):focus,.mat-tab-nav-bar.mat-warn .mat-tab-link:not(.mat-tab-disabled):focus{background-color:rgba(255,205,210,.3)}.mat-tab-group.mat-warn .mat-ink-bar,.mat-tab-nav-bar.mat-warn .mat-ink-bar{background-color:#f44336}.mat-tab-group.mat-warn.mat-background-warn .mat-ink-bar,.mat-tab-nav-bar.mat-warn.mat-background-warn .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-background-primary .mat-tab-label:not(.mat-tab-disabled):focus,.mat-tab-group.mat-background-primary .mat-tab-link:not(.mat-tab-disabled):focus,.mat-tab-nav-bar.mat-background-primary .mat-tab-label:not(.mat-tab-disabled):focus,.mat-tab-nav-bar.mat-background-primary .mat-tab-link:not(.mat-tab-disabled):focus{background-color:rgba(197,202,233,.3)}.mat-tab-group.mat-background-primary .mat-tab-header,.mat-tab-group.mat-background-primary .mat-tab-links,.mat-tab-nav-bar.mat-background-primary .mat-tab-header,.mat-tab-nav-bar.mat-background-primary .mat-tab-links{background-color:#3f51b5}.mat-tab-group.mat-background-primary .mat-tab-label,.mat-tab-group.mat-background-primary .mat-tab-link,.mat-tab-nav-bar.mat-background-primary .mat-tab-label,.mat-tab-nav-bar.mat-background-primary .mat-tab-link{color:#fff}.mat-tab-group.mat-background-primary .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-primary .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-primary .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-primary .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-primary .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-primary .mat-ripple-element,.mat-tab-nav-bar.mat-background-primary .mat-ripple-element{background-color:rgba(255,255,255,.12)}.mat-tab-group.mat-background-accent .mat-tab-label:not(.mat-tab-disabled):focus,.mat-tab-group.mat-background-accent .mat-tab-link:not(.mat-tab-disabled):focus,.mat-tab-nav-bar.mat-background-accent .mat-tab-label:not(.mat-tab-disabled):focus,.mat-tab-nav-bar.mat-background-accent .mat-tab-link:not(.mat-tab-disabled):focus{background-color:rgba(255,128,171,.3)}.mat-tab-group.mat-background-accent .mat-tab-header,.mat-tab-group.mat-background-accent .mat-tab-links,.mat-tab-nav-bar.mat-background-accent .mat-tab-header,.mat-tab-nav-bar.mat-background-accent .mat-tab-links{background-color:#ff4081}.mat-tab-group.mat-background-accent .mat-tab-label,.mat-tab-group.mat-background-accent .mat-tab-link,.mat-tab-nav-bar.mat-background-accent .mat-tab-label,.mat-tab-nav-bar.mat-background-accent .mat-tab-link{color:#fff}.mat-tab-group.mat-background-accent .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-accent .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-accent .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-accent .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-accent .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-accent .mat-ripple-element,.mat-tab-nav-bar.mat-background-accent .mat-ripple-element{background-color:rgba(255,255,255,.12)}.mat-tab-group.mat-background-warn .mat-tab-label:not(.mat-tab-disabled):focus,.mat-tab-group.mat-background-warn .mat-tab-link:not(.mat-tab-disabled):focus,.mat-tab-nav-bar.mat-background-warn .mat-tab-label:not(.mat-tab-disabled):focus,.mat-tab-nav-bar.mat-background-warn .mat-tab-link:not(.mat-tab-disabled):focus{background-color:rgba(255,205,210,.3)}.mat-tab-group.mat-background-warn .mat-tab-header,.mat-tab-group.mat-background-warn .mat-tab-links,.mat-tab-nav-bar.mat-background-warn .mat-tab-header,.mat-tab-nav-bar.mat-background-warn .mat-tab-links{background-color:#f44336}.mat-tab-group.mat-background-warn .mat-tab-label,.mat-tab-group.mat-background-warn .mat-tab-link,.mat-tab-nav-bar.mat-background-warn .mat-tab-label,.mat-tab-nav-bar.mat-background-warn .mat-tab-link{color:#fff}.mat-tab-group.mat-background-warn .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-warn .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-warn .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-warn .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-warn .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,.4)}.mat-tab-group.mat-background-warn .mat-ripple-element,.mat-tab-nav-bar.mat-background-warn .mat-ripple-element{background-color:rgba(255,255,255,.12)}.mat-toolbar{background:#f5f5f5;color:rgba(0,0,0,.87)}.mat-toolbar.mat-primary{background:#3f51b5;color:#fff}.mat-toolbar.mat-accent{background:#ff4081;color:#fff}.mat-toolbar.mat-warn{background:#f44336;color:#fff}.mat-tooltip{background:rgba(97,97,97,.9)}.mat-snack-bar-container{background:#323232;color:#fff}.mat-simple-snackbar-action{line-height:1;font-family:inherit;font-size:inherit;font-weight:500;color:#ff4081}app-side-nav,app-side-nav-drawer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}app-blog-material>app-side-nav{-webkit-box-flex:1;-ms-flex:1;flex:1}app-artdetail,app-artlist{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-box-sizing:border-box;box-sizing:border-box}ul{margin:0;list-style:none}body{font-family:Roboto,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif;margin:0} -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular/cli'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular/cli/plugins/karma') 14 | ], 15 | client:{ 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | reports: [ 'html', 'lcovonly' ], 20 | fixWebpackSourcePaths: true 21 | }, 22 | angularCli: { 23 | environment: 'dev' 24 | }, 25 | reporters: ['progress', 'kjhtml'], 26 | port: 9876, 27 | colors: true, 28 | logLevel: config.LOG_INFO, 29 | autoWatch: true, 30 | browsers: ['Chrome'], 31 | singleRun: false 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blog-frontend", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "ng serve", 8 | "build": "ng build --prod", 9 | "test": "ng test", 10 | "lint": "ng lint", 11 | "e2e": "ng e2e" 12 | }, 13 | "private": true, 14 | "dependencies": { 15 | "@angular/animations": "^5.2.11", 16 | "@angular/cdk": "^5.2.0", 17 | "@angular/common": "^5.2.0", 18 | "@angular/compiler": "^5.2.0", 19 | "@angular/core": "^5.2.0", 20 | "@angular/forms": "^5.2.0", 21 | "@angular/http": "^5.2.0", 22 | "@angular/material": "^5.2.0", 23 | "@angular/platform-browser": "^5.2.0", 24 | "@angular/platform-browser-dynamic": "^5.2.0", 25 | "@angular/router": "^5.2.0", 26 | "@types/jquery": "^3.3.10", 27 | "core-js": "^2.4.1", 28 | "hammerjs": "^2.0.8", 29 | "jquery": "^3.3.1", 30 | "rxjs": "^5.5.6", 31 | "ts-md5": "^1.2.4", 32 | "zone.js": "^0.8.19" 33 | }, 34 | "devDependencies": { 35 | "@angular/cli": "~1.7.2", 36 | "@angular/compiler-cli": "^5.2.0", 37 | "@angular/language-service": "^5.2.0", 38 | "@types/jasmine": "~2.8.3", 39 | "@types/jasminewd2": "~2.0.2", 40 | "@types/node": "~6.0.60", 41 | "codelyzer": "^4.0.1", 42 | "jasmine-core": "~2.8.0", 43 | "jasmine-spec-reporter": "~4.2.1", 44 | "karma": "~2.0.0", 45 | "karma-chrome-launcher": "~2.2.0", 46 | "karma-coverage-istanbul-reporter": "^1.2.1", 47 | "karma-jasmine": "~1.1.0", 48 | "karma-jasmine-html-reporter": "^0.2.2", 49 | "protractor": "~5.1.2", 50 | "ts-node": "~4.1.0", 51 | "tslint": "~5.9.1", 52 | "typescript": "~2.5.3" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './e2e/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: 'e2e/tsconfig.e2e.json' 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /snapshot/blog_front.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyw1995/Angular5-Blog-Front/6a8a722a4895f317eeff698389c15b49e614fb5e/snapshot/blog_front.png -------------------------------------------------------------------------------- /src/app/aboutus/aboutus.component.css: -------------------------------------------------------------------------------- 1 | .about-container { 2 | margin: 20px; 3 | vertical-align: top; 4 | padding: 10px; 5 | } 6 | 7 | /*TODO 共用头样式*/ 8 | .sidenav-content-header-container { 9 | display: flex; 10 | align-items: center; 11 | background: #3f51b5; 12 | padding-left: 20px; 13 | } 14 | 15 | .sidenav-content-header-container h1 { 16 | font-size: 20px; 17 | font-weight: 300; 18 | margin: 0; 19 | padding: 20px 8px; 20 | outline: none; 21 | color: #fff; 22 | } 23 | 24 | /*TODO 共用icon样式*/ 25 | .views-count mat-icon { 26 | vertical-align: middle; 27 | } 28 | 29 | .mb-3 { 30 | margin-bottom: 2px; 31 | } 32 | .soical-link{ 33 | display: inline-block; 34 | cursor: pointer; 35 | margin: 10px; 36 | } 37 | 38 | .soical-link img{ 39 | border-radius: 50%; 40 | width: 60px; 41 | height: 60px; 42 | } 43 | .soical-link p{ 44 | font-size: 13px; 45 | color: #666666; 46 | margin: 0px !important; 47 | } 48 | .soical-link:hover > p{ 49 | color: red; 50 | } 51 | -------------------------------------------------------------------------------- /src/app/aboutus/aboutus.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

关于我

4 |
5 | 6 | 7 |

个人简介

8 | 9 | 10 |

{{userData['user_desc']}}

11 |
12 | 13 | 14 | 15 | supervisor_account 16 | {{userData['nick_name']}} 17 | 18 | 19 | 20 | email 21 | {{userData['user_email']}} 22 | 23 | 24 | 25 | location_on 26 | {{userData['user_addr']}} 27 | 28 |
29 |
30 | 31 | 32 |

友情链接

33 | 34 | 35 | 36 |

{{item['link_name']}}

37 |
38 |
39 |
40 |
41 | -------------------------------------------------------------------------------- /src/app/aboutus/aboutus.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {BlogService} from '../service/blog.service'; 3 | import {Router} from '@angular/router'; 4 | 5 | @Component({ 6 | selector: 'app-aboutus', 7 | templateUrl: './aboutus.component.html', 8 | styleUrls: ['./aboutus.component.css'] 9 | }) 10 | export class AboutusComponent implements OnInit { 11 | userData = null; 12 | userLinks = []; 13 | 14 | constructor(private bs: BlogService, private router: Router) { 15 | } 16 | 17 | ngOnInit() { 18 | if (this.bs.isInit()) { 19 | this.bs.getUserInfo(value => { 20 | this.userData = value['data']; 21 | }); 22 | this.bs.getUserLinks(value => { 23 | this.userLinks = value['data']; 24 | }); 25 | } else { 26 | this.router.navigate(['/']); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/app/aboutus/aboutus.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {AboutusComponent} from './aboutus.component'; 4 | import {AboutusRoutingModule} from '../routing/aboutus.routing.module'; 5 | import {MatCardModule, MatDividerModule, MatIconModule, MatListModule} from '@angular/material'; 6 | 7 | @NgModule({ 8 | imports: [ 9 | CommonModule, 10 | AboutusRoutingModule, 11 | MatIconModule, 12 | MatListModule, 13 | MatDividerModule, 14 | MatCardModule, 15 | ], 16 | declarations: [AboutusComponent] 17 | }) 18 | // 关于我 19 | export class AboutusModule { 20 | } 21 | -------------------------------------------------------------------------------- /src/app/app.component.css: -------------------------------------------------------------------------------- 1 | /*顶部导航栏 容器*/ 2 | app-nav-bar { 3 | position: fixed; 4 | top: 0; 5 | left: 0; 6 | right: 0; 7 | z-index: 2; 8 | } 9 | -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | describe('AppComponent', () => { 4 | beforeEach(async(() => { 5 | TestBed.configureTestingModule({ 6 | declarations: [ 7 | AppComponent 8 | ], 9 | }).compileComponents(); 10 | })); 11 | it('should create the app', async(() => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.debugElement.componentInstance; 14 | expect(app).toBeTruthy(); 15 | })); 16 | it(`should have as title 'app'`, async(() => { 17 | const fixture = TestBed.createComponent(AppComponent); 18 | const app = fixture.debugElement.componentInstance; 19 | expect(app.title).toEqual('app'); 20 | })); 21 | it('should render title in a h1 tag', async(() => { 22 | const fixture = TestBed.createComponent(AppComponent); 23 | fixture.detectChanges(); 24 | const compiled = fixture.debugElement.nativeElement; 25 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!'); 26 | })); 27 | }); 28 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {BlogService} from './service/blog.service'; 3 | import {Title} from '@angular/platform-browser'; 4 | 5 | @Component({ 6 | selector: 'app-blog-material', 7 | templateUrl: './app.component.html', 8 | styleUrls: ['./app.component.css'] 9 | }) 10 | export class AppComponent { 11 | constructor(private bs: BlogService, private ts: Title) { 12 | // bs.initBlog(value => { 13 | // localStorage.setItem('user_id', value['data']['user_id']); 14 | // localStorage.setItem('nick_name', value['data']['nick_name']); 15 | // localStorage.setItem('user_avator', value['data']['user_avator']); 16 | // this.ts.setTitle(value['data']['nick_name'] + '的博客'); 17 | // }); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {AppComponent} from './app.component'; 3 | import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; 4 | import {AppRoutingModule} from './routing/app.routing.module'; 5 | import {NavBarModule} from './nav-bar/nav-bar.module'; 6 | import {BlogService} from './service/blog.service'; 7 | import {HttpClientModule} from '@angular/common/http'; 8 | 9 | @NgModule({ 10 | declarations: [ 11 | AppComponent, 12 | ], 13 | imports: [ 14 | BrowserAnimationsModule, 15 | AppRoutingModule, 16 | NavBarModule, 17 | HttpClientModule 18 | ], 19 | providers: [BlogService], 20 | bootstrap: [AppComponent] 21 | }) 22 | // app入口 23 | export class AppModule { 24 | } 25 | -------------------------------------------------------------------------------- /src/app/artdetail/artdetail.component.css: -------------------------------------------------------------------------------- 1 | .detail-container { 2 | margin: 20px; 3 | vertical-align: top; 4 | padding: 10px; 5 | } 6 | 7 | /*TODO 与文章列表 共用样式可以抽取*/ 8 | .article-type { 9 | margin-right: 8px; 10 | margin-top: 0; 11 | vertical-align: 2px; 12 | display: inline-block; 13 | width: 26px; 14 | height: 26px; 15 | line-height: 26px; 16 | text-align: center; 17 | font-size: 12px; 18 | border-radius: 50%; 19 | } 20 | 21 | .article-title { 22 | color: black; 23 | font-size: 16px; 24 | font-weight: 500; 25 | } 26 | 27 | .article-title:hover { 28 | color: red; 29 | } 30 | 31 | .type-2 { 32 | color: #86ca5e; 33 | border: 1px solid #e7f4df; 34 | } 35 | 36 | .type-1 { 37 | color: #ca0c16; 38 | border: 1px solid #f4ced0; 39 | } 40 | 41 | .article-bottom { 42 | margin: 0px !important; 43 | color: #666; 44 | font-size: 13px; 45 | padding-top: 5px; 46 | display: flex; 47 | flex-direction: row; 48 | } 49 | 50 | .article-bottom-right { 51 | text-align: right; 52 | flex: 1; 53 | flex-grow: 1; 54 | } 55 | 56 | .article-bottom a { 57 | display: inline; 58 | color: #666; 59 | } 60 | 61 | .views-count { 62 | margin-left: 10px; 63 | } 64 | 65 | .views-count mat-icon { 66 | vertical-align: middle; 67 | transform: scale(0.7); 68 | } 69 | 70 | .mb-3 { 71 | margin-bottom: 2px; 72 | } 73 | 74 | .content-bottom-container { 75 | display: flex; 76 | flex-direction: row; 77 | box-sizing: border-box; 78 | } 79 | 80 | .content-bottom-container a { 81 | flex: 1; 82 | flex-grow: 1; 83 | display: inline-block; 84 | color: #666; 85 | cursor: pointer; 86 | font-size: 12px; 87 | box-sizing: border-box; 88 | overflow: hidden; 89 | text-overflow: ellipsis; 90 | white-space: nowrap; 91 | width: 100%; 92 | } 93 | 94 | .content-bottom-container a span { 95 | min-width: 60px; 96 | line-height: 26px; 97 | padding: 5px 10px; 98 | border: 1px solid #b4b4b4; 99 | margin-right: 8px; 100 | background: #fafafa; 101 | color: #666666; 102 | } 103 | 104 | .content-bottom-container a:hover { 105 | color: red; 106 | } 107 | 108 | .content-bottom-container a:hover > span { 109 | color: red; 110 | border: 1px solid red; 111 | } 112 | 113 | .detail-css { 114 | max-width: 75vw; 115 | overflow-x: hidden; 116 | } 117 | 118 | @media (max-width: 720px) { 119 | .content-bottom-container { 120 | display: block; 121 | max-width: 83vw; 122 | } 123 | 124 | .detail-css { 125 | max-width: 83vw; 126 | overflow-x: hidden; 127 | } 128 | } 129 | 130 | -------------------------------------------------------------------------------- /src/app/artdetail/artdetail.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 5 | {{contentData['origin'] == 1?"原":"转"}} 6 | {{contentData['title']}} 7 |

8 | 发表时间: {{contentData['create_time'] | date: 'yyyy-MM-dd HH:mm:ss'}} 9 | 10 | 11 | remove_red_eye 12 | {{contentData['views']}} 13 | 14 | textsms 15 | 0 16 | 17 |

18 |
19 |
20 |
21 |
22 |
23 |
24 | 25 | -------------------------------------------------------------------------------- /src/app/artdetail/artdetail.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AfterContentChecked, 3 | AfterViewChecked, 4 | AfterViewInit, 5 | ChangeDetectorRef, 6 | Component, DoCheck, Input, KeyValueDiffers, 7 | OnChanges, 8 | OnInit, 9 | SimpleChanges 10 | } from '@angular/core'; 11 | import {BlogService} from '../service/blog.service'; 12 | import {ActivatedRoute, Router} from '@angular/router'; 13 | import * as $ from 'jquery'; 14 | import {HighlightService} from '../service/highlight.service'; 15 | 16 | @Component({ 17 | selector: 'app-artdetail', 18 | templateUrl: './artdetail.component.html', 19 | styleUrls: ['./artdetail.component.css'] 20 | }) 21 | export class ArtdetailComponent implements OnInit { 22 | contentData = null; 23 | aid = -1; 24 | 25 | constructor(private route: ActivatedRoute, private bs: BlogService, private router: Router, private hs: HighlightService) { 26 | this.route.params.subscribe(data => { 27 | this.aid = data['id']; 28 | 29 | if (this.aid === undefined) { 30 | this.aid = parseInt(localStorage.getItem('hot_id'), 10); 31 | } 32 | if ((this.aid !== undefined || this.aid !== -1) && this.bs.isInit()) { 33 | this.bs.getArticleByAid(this.aid + '', value => { 34 | this.contentData = value['data']; 35 | this.hs.contentSub.next(this.contentData); 36 | }); 37 | } else { 38 | setTimeout(() => { 39 | if (isNaN(this.aid)) { 40 | return; 41 | } 42 | this.bs.getArticleByAid(this.aid + '', value => { 43 | this.contentData = value['data']; 44 | this.hs.contentSub.next(this.contentData); 45 | }); 46 | }, 300); 47 | } 48 | }); 49 | } 50 | 51 | ngOnInit() { 52 | this.hs.contentSub.subscribe(data => { 53 | if (data != null) { 54 | setTimeout(() => { 55 | $('pre').each(function (i, block) { 56 | hljs.highlightBlock(block); 57 | }); 58 | }, 100); 59 | } 60 | }); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/app/artdetail/artdetail.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {ArtdetailComponent} from './artdetail.component'; 4 | import {MatButtonModule, MatIconModule} from '@angular/material'; 5 | import {SafehtmlPipe} from '../pipe/safehtml.pipe'; 6 | import {HighlightService} from '../service/highlight.service'; 7 | 8 | @NgModule({ 9 | imports: [ 10 | CommonModule, 11 | MatIconModule, 12 | MatButtonModule 13 | ], 14 | providers: [HighlightService], 15 | declarations: [ArtdetailComponent, SafehtmlPipe] 16 | }) 17 | // 文章详情 18 | export class ArtdetailModule { 19 | } 20 | -------------------------------------------------------------------------------- /src/app/artlist/artlist.component.css: -------------------------------------------------------------------------------- 1 | 2 | .card-list-item { 3 | margin: 20px; 4 | vertical-align: top; 5 | padding: 10px; 6 | } 7 | 8 | .article-type { 9 | margin-right: 8px; 10 | margin-top: 0; 11 | vertical-align: 2px; 12 | display: inline-block; 13 | width: 26px; 14 | height: 26px; 15 | line-height: 26px; 16 | text-align: center; 17 | font-size: 12px; 18 | border-radius: 50%; 19 | } 20 | 21 | .article-title { 22 | color: black; 23 | font-size: 16px; 24 | font-weight: 500; 25 | } 26 | 27 | .article-subtitle { 28 | max-width: 83vw; 29 | margin: 0 !important; 30 | color: #999 !important; 31 | padding-top: 5px; 32 | font-size: 13px; 33 | line-height: 20px; 34 | overflow: hidden; 35 | text-overflow: ellipsis; 36 | display: -webkit-box; 37 | -webkit-line-clamp: 3; 38 | -webkit-box-orient: vertical; 39 | } 40 | 41 | .article-title:hover { 42 | color: red; 43 | } 44 | 45 | .type-2 { 46 | color: #86ca5e; 47 | border: 1px solid #e7f4df; 48 | } 49 | 50 | .type-1 { 51 | color: #ca0c16; 52 | border: 1px solid #f4ced0; 53 | } 54 | 55 | .card-list-item a { 56 | width: 54vw; 57 | display: inline-block; 58 | text-decoration: none; 59 | cursor: pointer; 60 | color: #333; 61 | box-sizing: inherit; 62 | word-break: break-all; 63 | overflow: hidden; 64 | text-overflow: ellipsis; 65 | white-space: nowrap; 66 | } 67 | 68 | .card-list-item-container { 69 | display: flex; 70 | flex-direction: row; 71 | } 72 | 73 | .card-list-item-container img { 74 | width: 125px; 75 | height: 100px; 76 | vertical-align: middle; 77 | margin: auto 0; 78 | } 79 | 80 | .card-list-item-container div { 81 | flex: 1; 82 | box-sizing: content-box; 83 | margin-left: 8px; 84 | } 85 | 86 | .article-bottom { 87 | margin: 0px !important; 88 | color: #b4b4b4; 89 | font-size: 13px; 90 | padding-top: 5px; 91 | } 92 | 93 | .article-bottom a { 94 | display: inline; 95 | color: #b4b4b4; 96 | cursor: pointer; 97 | } 98 | 99 | .article-bottom a:hover { 100 | transition: .1s ease-in; 101 | -webkit-transition: .1s ease-in; 102 | color: #666; 103 | } 104 | 105 | .views-count { 106 | margin-left: 10px; 107 | } 108 | 109 | .views-count mat-icon { 110 | vertical-align: middle; 111 | transform: scale(0.7); 112 | } 113 | 114 | .mb-3 { 115 | margin-bottom: 2px; 116 | } 117 | 118 | .sort_container { 119 | background: #fff; 120 | margin: 20px; 121 | font-size: 14px; 122 | padding-left: 10px; 123 | } 124 | 125 | .sort-normal, mat-form-field { 126 | color: #333333; 127 | } 128 | 129 | .sort-selected { 130 | color: red; 131 | } 132 | 133 | .sort_container a:hover { 134 | color: red; 135 | } 136 | 137 | .search-btn { 138 | float: right; 139 | } 140 | 141 | .sort_container-center { 142 | text-align: center; 143 | box-sizing: border-box; 144 | } 145 | 146 | @media (max-width: 720px) { 147 | .card-list-item-container img { 148 | display: none; 149 | } 150 | 151 | .card-list-item-container div { 152 | margin-left: 0px; 153 | } 154 | 155 | .card-list-item a { 156 | width: 83vw; 157 | } 158 | .sort_container .mat-button{ 159 | min-width: 44px ; 160 | padding: 0 8px ; 161 | } 162 | .search-btn { 163 | min-width: 24px; 164 | padding: 0px !important; 165 | } 166 | } 167 | 168 | -------------------------------------------------------------------------------- /src/app/artlist/artlist.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 |
7 | 排序: 8 | 默认 9 | 按更新时间 10 | 按阅读量 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 |
26 | 28 | {{item.origin == 1?"原":"转"}} 29 | {{item.title}} 30 |

31 | {{item['content'] | cust_html}} 32 |

33 |

34 | {{item['create_time'] | date: 'yyyy-MM-dd HH:mm:ss'}} 35 | 36 | remove_red_eye 37 | {{item['views']}} 38 | 39 | textsms 40 | 0 41 |

42 |
43 |
44 |
45 | 46 |
47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
58 |
59 |
60 | -------------------------------------------------------------------------------- /src/app/artlist/artlist.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, NgZone, OnInit} from '@angular/core'; 2 | import {ActivatedRoute, Router} from '@angular/router'; 3 | import {BlogService} from '../service/blog.service'; 4 | 5 | @Component({ 6 | selector: 'app-artlist', 7 | templateUrl: './artlist.component.html', 8 | styleUrls: ['./artlist.component.css'] 9 | }) 10 | // 文章列表 11 | export class ArtlistComponent implements OnInit { 12 | userArticles = []; 13 | cid = -1; 14 | ds = true; 15 | cs = false; 16 | vs = false; 17 | totalCount = -1; 18 | pageIndex = 0; 19 | defaultS = ''; 20 | 21 | constructor(private router: Router, private route: ActivatedRoute, private bs: BlogService) { 22 | this.route.params.subscribe(data => { 23 | this.cid = data['id']; 24 | if (bs.isInit()) { 25 | this.getArticlesByCid(); 26 | } else { 27 | setTimeout(() => { 28 | this.getArticlesByCid(); 29 | }, 300); 30 | } 31 | }); 32 | } 33 | 34 | ngOnInit() { 35 | } 36 | 37 | getArticlesByCid() { 38 | if (this.cid === undefined) { 39 | // 获取全部 40 | this.bs.getAllArticles(this.pageIndex + '', this.defaultS, value => { 41 | this.userArticles = value['data']['articles']; 42 | this.totalCount = value['data']['count']; 43 | this.ds = true; 44 | this.cs = false; 45 | this.vs = false; 46 | }); 47 | } else { 48 | this.bs.getAllArticlesByCid(this.cid + '', this.pageIndex + '', this.defaultS, value => { 49 | this.userArticles = value['data']['articles']; 50 | this.totalCount = value['data']['count']; 51 | this.ds = true; 52 | this.cs = false; 53 | this.vs = false; 54 | }); 55 | } 56 | } 57 | 58 | defaultSort() { 59 | if (this.defaultS === '') { 60 | return; 61 | } 62 | this.defaultS = ''; 63 | if (this.cid === undefined) { 64 | // 获取全部 65 | this.bs.getAllArticles(this.pageIndex + '', this.defaultS, value => { 66 | this.userArticles = value['data']['articles']; 67 | this.ds = true; 68 | this.cs = false; 69 | this.vs = false; 70 | }); 71 | } else { 72 | this.bs.getAllArticlesByCid(this.cid + '', this.pageIndex + '', this.defaultS, value => { 73 | this.userArticles = value['data']['articles']; 74 | this.ds = true; 75 | this.cs = false; 76 | this.vs = false; 77 | }); 78 | } 79 | } 80 | 81 | sortByCreate_time() { 82 | if (this.defaultS === 'create_time,desc') { 83 | return; 84 | } 85 | this.defaultS = 'create_time,desc'; 86 | if (this.cid === undefined) { 87 | this.bs.getAllArticles(this.pageIndex + '', this.defaultS, value => { 88 | this.userArticles = value['data']['articles']; 89 | this.ds = false; 90 | this.cs = true; 91 | this.vs = false; 92 | }); 93 | } else { 94 | this.bs.getAllArticlesByCid(this.cid + '', this.pageIndex + '', this.defaultS, value => { 95 | this.userArticles = value['data']['articles']; 96 | this.ds = false; 97 | this.cs = true; 98 | this.vs = false; 99 | }); 100 | } 101 | } 102 | 103 | sortByViews() { 104 | if (this.defaultS === 'views,desc') { 105 | return; 106 | } 107 | this.defaultS = 'views,desc'; 108 | if (this.cid === undefined) { 109 | this.bs.getAllArticles(this.pageIndex + '', this.defaultS, value => { 110 | this.userArticles = value['data']['articles']; 111 | this.ds = false; 112 | this.cs = false; 113 | this.vs = true; 114 | }); 115 | } else { 116 | this.bs.getAllArticlesByCid(this.cid + '', this.pageIndex + '', this.defaultS, value => { 117 | this.userArticles = value['data']['articles']; 118 | this.ds = false; 119 | this.cs = false; 120 | this.vs = true; 121 | }); 122 | } 123 | } 124 | 125 | change(e: any) { 126 | this.pageIndex = e['pageIndex']; 127 | if (this.ds) { 128 | this.defaultSort(); 129 | } else if (this.cs) { 130 | this.sortByCreate_time(); 131 | } else if (this.vs) { 132 | this.sortByViews(); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/app/artlist/artlist.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {ArtlistComponent} from './artlist.component'; 4 | import {MatButtonModule, MatCardModule, MatIconModule, MatInputModule, MatMenuModule, MatPaginatorModule} from '@angular/material'; 5 | import {RouterModule} from '@angular/router'; 6 | import {CustHtmlPipe} from '../pipe/html.pipe'; 7 | 8 | @NgModule({ 9 | imports: [ 10 | CommonModule, 11 | MatCardModule, 12 | MatIconModule, 13 | MatButtonModule, 14 | MatMenuModule, 15 | MatInputModule, 16 | RouterModule, 17 | MatPaginatorModule, 18 | ], 19 | declarations: [ArtlistComponent, CustHtmlPipe] 20 | }) 21 | export class ArtlistModule { 22 | } 23 | -------------------------------------------------------------------------------- /src/app/nav-bar/nav-bar.component.css: -------------------------------------------------------------------------------- 1 | 2 | /*头部内容*/ 3 | .app-navbar-header { 4 | display: flex; 5 | flex-wrap: wrap; 6 | align-items: center; 7 | padding: 8px 16px; 8 | } 9 | 10 | .app-navbar-link-small, app-navbar-link { 11 | display: none; 12 | } 13 | 14 | .app-navbar, .app-navbar-header, .app-navbar-link, .app-navbar-link-small { 15 | background: #3f51b5; 16 | } 17 | 18 | /*适配移动端*/ 19 | @media (max-width: 720px) { 20 | .app-navbar-link { 21 | display: flex; 22 | } 23 | .app-navbar-link-small { 24 | display: block; 25 | display: flex; 26 | } 27 | 28 | .app-navbar-link-small-hide { 29 | display: none; 30 | } 31 | 32 | .app-navbar-git_label-hide { 33 | display: none; 34 | } 35 | .app-blog{ 36 | top: 92px; 37 | } 38 | } 39 | /* 链接标签 样式 */ 40 | .app-navbar-link a{ 41 | color: white; 42 | flex: 1; 43 | -webkit-box-flex: 1; 44 | -ms-flex-positive: 1; 45 | flex-grow: 1; 46 | } 47 | /*头像 样式*/ 48 | .app-navbar-avator { 49 | height: 40px; 50 | margin: 0 4px 3px 0; 51 | vertical-align: middle; 52 | border-radius: 40px; 53 | } 54 | 55 | .app-navbar-header a { 56 | color: white; 57 | } 58 | 59 | /*占位容器样式*/ 60 | .flex-spacer { 61 | flex: 1; 62 | -webkit-box-flex: 1; 63 | -ms-flex-positive: 1; 64 | flex-grow: 1; 65 | } 66 | /*git 图标样式*/ 67 | .app-navbar-git_icon { 68 | height: 26px; 69 | margin: 0 4px 3px 0; 70 | vertical-align: middle; 71 | } 72 | -------------------------------------------------------------------------------- /src/app/nav-bar/nav-bar.component.html: -------------------------------------------------------------------------------- 1 | 26 | 38 | -------------------------------------------------------------------------------- /src/app/nav-bar/nav-bar.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {BlogService} from '../service/blog.service'; 3 | import {Title} from '@angular/platform-browser'; 4 | 5 | @Component({ 6 | selector: 'app-nav-bar', 7 | templateUrl: './nav-bar.component.html', 8 | styleUrls: ['./nav-bar.component.css'], 9 | }) 10 | // 顶部导航栏 11 | export class NavBarComponent implements OnInit { 12 | title = ''; 13 | avator = ''; 14 | 15 | constructor(private bs: BlogService, private ts: Title) { 16 | bs.initBlog(value => { 17 | localStorage.setItem('user_id', value['data']['user_id']); 18 | localStorage.setItem('nick_name', value['data']['nick_name']); 19 | localStorage.setItem('user_avator', value['data']['user_avator']); 20 | this.ts.setTitle(value['data']['nick_name'] + '的博客'); 21 | this.title = localStorage.getItem('nick_name') + '的博客'; 22 | this.avator = localStorage.getItem('user_avator'); 23 | }); 24 | } 25 | 26 | ngOnInit() { 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/app/nav-bar/nav-bar.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {MatButtonModule} from '@angular/material'; 4 | import {NavBarComponent} from './nav-bar.component'; 5 | import {RouterModule} from '@angular/router'; 6 | 7 | @NgModule({ 8 | imports: [ 9 | CommonModule, 10 | MatButtonModule, 11 | RouterModule 12 | ], 13 | declarations: [NavBarComponent], 14 | exports: [NavBarComponent] 15 | }) 16 | export class NavBarModule { 17 | } 18 | -------------------------------------------------------------------------------- /src/app/pipe/html.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | import {escapeHtml} from '@angular/platform-browser/src/browser/transfer_state'; 3 | 4 | @Pipe({ 5 | name: 'cust_html' 6 | }) 7 | // 格式化html 去掉标签, 用于显示文章详情 简易title 8 | export class CustHtmlPipe implements PipeTransform { 9 | 10 | transform(value: any, args?: any): any { 11 | return this.reformNoticeContent(value); 12 | } 13 | 14 | reformNoticeContent(content): string { 15 | 16 | content = content.split(''); 17 | let tagBoolean = false; 18 | content.forEach((c, index) => { 19 | if ('<' === c) { 20 | tagBoolean = true; 21 | } else if ('>' === c) { 22 | content[index] = ''; 23 | tagBoolean = false; 24 | // continue; 如果是JavaScript可以添加这句代码,angular4不行。 25 | } 26 | if (tagBoolean) { 27 | content[index] = ''; 28 | } 29 | }); 30 | content = content.join(''); 31 | return content; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/app/pipe/safehtml.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | import {DomSanitizer} from '@angular/platform-browser'; 3 | 4 | @Pipe({ 5 | name: 'safehtml' 6 | }) 7 | // 显示html 带样式 8 | export class SafehtmlPipe implements PipeTransform { 9 | 10 | constructor(private domSanitizer: DomSanitizer) { 11 | 12 | } 13 | 14 | transform(html: string, args: any[]): any { 15 | return this.domSanitizer.bypassSecurityTrustHtml(html); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/app/recommend/recommend.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyw1995/Angular5-Blog-Front/6a8a722a4895f317eeff698389c15b49e614fb5e/src/app/recommend/recommend.component.css -------------------------------------------------------------------------------- /src/app/recommend/recommend.component.html: -------------------------------------------------------------------------------- 1 |

2 | recommend works!aaa 3 |

4 | -------------------------------------------------------------------------------- /src/app/recommend/recommend.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-recommend', 5 | templateUrl: './recommend.component.html', 6 | styleUrls: ['./recommend.component.css'] 7 | }) 8 | // 热文推荐 9 | export class RecommendComponent implements OnInit { 10 | 11 | constructor() { } 12 | 13 | ngOnInit() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/app/recommend/recommend.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { RecommendComponent } from './recommend.component'; 4 | import {RecommendRoutingModule} from '../routing/recommend.routing.module'; 5 | 6 | @NgModule({ 7 | imports: [ 8 | CommonModule, 9 | RecommendRoutingModule 10 | ], 11 | declarations: [RecommendComponent] 12 | }) 13 | export class RecommendModule { } 14 | -------------------------------------------------------------------------------- /src/app/routing/aboutus.routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {RouterModule, Routes} from '@angular/router'; 3 | import {AboutusComponent} from '../aboutus/aboutus.component'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', component: AboutusComponent 8 | } 9 | ]; 10 | 11 | @NgModule({ 12 | imports: [RouterModule.forChild(routes)], 13 | exports: [RouterModule] 14 | }) 15 | // 关于我 路由配置 16 | export class AboutusRoutingModule { 17 | } 18 | -------------------------------------------------------------------------------- /src/app/routing/app.routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {RouterModule, Routes} from '@angular/router'; 3 | 4 | const routes: Routes = [ 5 | { 6 | path: '', 7 | redirectTo: '/article', 8 | pathMatch: 'full' 9 | }, 10 | { 11 | path: 'article', 12 | loadChildren: 'app/side-nav/side-nav.module#SideNavModule' 13 | }, 14 | { 15 | path: 'recommend', 16 | loadChildren: 'app/side-nav/side-nav.module#SideNavModule', 17 | }, 18 | { 19 | path: 'about', 20 | loadChildren: 'app/aboutus/aboutus.module#AboutusModule' 21 | }, { 22 | path: '**', 23 | redirectTo: '/article' 24 | } 25 | ]; 26 | 27 | @NgModule({ 28 | imports: [RouterModule.forRoot(routes)], 29 | exports: [RouterModule] 30 | }) 31 | // app 路由配置 32 | export class AppRoutingModule { 33 | } 34 | -------------------------------------------------------------------------------- /src/app/routing/nav.routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {RouterModule, Routes} from '@angular/router'; 3 | import {ArtlistComponent} from '../artlist/artlist.component'; 4 | import {ArtdetailComponent} from '../artdetail/artdetail.component'; 5 | import {SideNavComponent} from '../side-nav/side-nav.component'; 6 | 7 | const routes: Routes = [ 8 | { 9 | path: '', component: SideNavComponent, 10 | children: [ 11 | { 12 | path: '', 13 | component: ArtlistComponent 14 | }, 15 | { 16 | path: 'category/:id', 17 | component: ArtlistComponent 18 | }, 19 | { 20 | path: 'detail/:id', 21 | component: ArtdetailComponent 22 | }, 23 | { 24 | path: 'detail', 25 | component: ArtdetailComponent 26 | } 27 | ] 28 | } 29 | ]; 30 | 31 | @NgModule({ 32 | imports: [RouterModule.forChild(routes)], 33 | exports: [RouterModule] 34 | }) 35 | // 侧滑菜单路由配置 36 | export class NavRoutingModule { 37 | } 38 | -------------------------------------------------------------------------------- /src/app/routing/recommend.routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {RouterModule, Routes} from '@angular/router'; 3 | import {RecommendComponent} from '../recommend/recommend.component'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', component: RecommendComponent 8 | } 9 | ]; 10 | 11 | @NgModule({ 12 | imports: [RouterModule.forChild(routes)], 13 | exports: [RouterModule] 14 | }) 15 | // 热文推荐路由配置 16 | export class RecommendRoutingModule { 17 | } 18 | -------------------------------------------------------------------------------- /src/app/service/base.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http'; 3 | 4 | // 基类服务, 接口sign. 统一get请求 5 | @Injectable() 6 | export class BaseService { 7 | constructor(protected http: HttpClient) { 8 | } 9 | 10 | // 签名sign 11 | sign(signValue: string): HttpHeaders { 12 | return new HttpHeaders({ 13 | 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 14 | 'Sign': signValue 15 | }); 16 | } 17 | 18 | // 统一Get 请求 响应返回 19 | get(url: string, singValue: string, body: { 20 | [param: string]: string | string[]; 21 | }, next?: (value: any) => void, error?: (error: any) => void, complete?: () => void) { 22 | const headers = this.sign(singValue); 23 | return this.http.get(url, { 24 | headers: headers, params: new HttpParams({ 25 | fromObject: body 26 | }), 27 | }).subscribe( 28 | next, error, complete 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/app/service/blog.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http'; 3 | import {BaseService} from './base.service'; 4 | import {environment} from '../../environments/environment'; 5 | 6 | const baseUrl = environment.baseUrl; 7 | const v1 = '/api/v1'; 8 | const userUrl = v1 + '/users'; 9 | const categoryUrl = '/categorys'; 10 | const articleUrl = '/articles'; 11 | const linkUrl = '/links'; 12 | const secertKey = 'UQPdFMLjszp35gpj'; 13 | import {Md5} from 'ts-md5'; 14 | // blog 服务, 提供整个前端接口调用 15 | @Injectable() 16 | export class BlogService extends BaseService { 17 | initBlog(next?: (value: any) => void, error?: (error: any) => void) { 18 | const signValue: string = Md5.hashStr(userUrl + secertKey).toString(); 19 | this.get(baseUrl + userUrl, signValue, {}, next, error); 20 | } 21 | 22 | isInit(): Boolean { 23 | const user_id = localStorage.getItem('user_id'); 24 | if (user_id === null || user_id === undefined) { 25 | return false; 26 | } 27 | return true; 28 | } 29 | 30 | getUserInfo(next?: (value: any) => void, error?: (error: any) => void) { 31 | const url = userUrl + '/' + localStorage.getItem('user_id'); 32 | const signValue: string = Md5.hashStr(url + secertKey).toString(); 33 | this.get(baseUrl + url, signValue, {}, next, error); 34 | } 35 | 36 | getUserLinks(next?: (value: any) => void, error?: (error: any) => void) { 37 | const url = userUrl + '/' + localStorage.getItem('user_id') + linkUrl; 38 | const signValue: string = Md5.hashStr(url + secertKey).toString(); 39 | this.get(baseUrl + url, signValue, {}, next, error); 40 | } 41 | 42 | getCategoryByUserId(next?: (value: any) => void, error?: (error: any) => void) { 43 | const url = userUrl + '/' + localStorage.getItem('user_id') + categoryUrl; 44 | const signValue: string = Md5.hashStr(url + secertKey).toString(); 45 | this.get(baseUrl + url, signValue, {}, next, error); 46 | } 47 | 48 | getAllArticles(page: string, sort: string, next?: (value: any) => void, error?: (error: any) => void) { 49 | let url = userUrl + '/' + localStorage.getItem('user_id') + articleUrl; 50 | const signValue: string = Md5.hashStr(url + secertKey).toString(); 51 | url += '?page=' + page + '&published=true&sort=' + sort; 52 | this.get(baseUrl + url, signValue, {}, next, error); 53 | } 54 | 55 | getArticleByAid(aid: string, next?: (value: any) => void, error?: (error: any) => void) { 56 | const url = userUrl + '/' + localStorage.getItem('user_id') + articleUrl + '/' + aid; 57 | const signValue: string = Md5.hashStr(url + secertKey).toString(); 58 | this.get(baseUrl + url, signValue, {}, next, error); 59 | } 60 | 61 | getHotAndNewArticles(next?: (value: any) => void, error?: (error: any) => void) { 62 | const user_id = localStorage.getItem('user_id'); 63 | const url = userUrl + '/' + user_id + '/other'; 64 | const signValue: string = Md5.hashStr(url + secertKey).toString(); 65 | this.get(baseUrl + url, signValue, {}, next, error); 66 | } 67 | 68 | getAllArticlesByCid(cid: string, page: string, sort: string, next?: (value: any) => void, error?: (error: any) => void) { 69 | let url = userUrl + '/' + localStorage.getItem('user_id') + categoryUrl + '/' + cid + articleUrl; 70 | const signValue: string = Md5.hashStr(url + secertKey).toString(); 71 | url += '?page=' + page + '&sort=' + sort; 72 | this.get(baseUrl + url, signValue, {}, next, error); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/app/service/highlight.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import {BehaviorSubject} from 'rxjs/BehaviorSubject'; 3 | 4 | // 文章详情 代码高亮 5 | @Injectable() 6 | export class HighlightService { 7 | contentSub: BehaviorSubject = new BehaviorSubject(null); 8 | constructor() { } 9 | } 10 | -------------------------------------------------------------------------------- /src/app/service/sidenav.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {Subject} from 'rxjs/Subject'; 3 | import {Observable} from 'rxjs/Observable'; 4 | // 侧滑菜单 控制服务 5 | @Injectable() 6 | export class SidenavService { 7 | private subject = new Subject(); 8 | 9 | sendMessage(message: string) { 10 | this.subject.next({text: message}); 11 | } 12 | 13 | clearMessage() { 14 | this.subject.next(); 15 | } 16 | 17 | getMessage(): Observable { 18 | return this.subject.asObservable(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/app/side-nav-drawer/side-nav-drawer.component.css: -------------------------------------------------------------------------------- 1 | .sidenav-drawer { 2 | position: sticky; 3 | top: 25px; 4 | } 5 | 6 | .sidenav-drawer-content { 7 | /*background: rgba(0, 0, 0, .03);*/ 8 | background: none; 9 | } 10 | .sidenav-drawer-content::-webkit-scrollbar { 11 | height: 4px; 12 | width: 4px; 13 | } 14 | .sidenav-drawer-content::-webkit-scrollbar-thumb { 15 | /*background: rgba(0,0,0,.26);*/ 16 | background: none; 17 | } 18 | .sidenav-drawer .sidenav-drawer-content { 19 | width: 240px; 20 | max-height: 100vh; 21 | overflow: auto; 22 | } 23 | 24 | @media (max-width: 720px) { 25 | .sidenav-drawer { 26 | position: relative; 27 | top: 10px; 28 | } 29 | } 30 | 31 | @media (max-width: 720px) { 32 | .sidenav-drawer .sidenav-drawer-content { 33 | max-height: none; 34 | box-sizing: border-box; 35 | background: none; 36 | } 37 | } 38 | .cart-list-item{ 39 | margin: 20px; 40 | vertical-align: top; 41 | padding: 0px; 42 | } 43 | .account-info-label{ 44 | font-size: 14px !important; 45 | color: #333 !important; 46 | background: #f5f5f5; 47 | padding: 10px; 48 | } 49 | .cart-list-item p { 50 | margin: 0; 51 | padding: 10px; 52 | line-height: 16px; 53 | font-size: 12px; 54 | color: #666; 55 | } 56 | mat-grid-tile{ 57 | color: #000; 58 | font-size: 12px; 59 | } 60 | .mat-grid-tile-sub{ 61 | font-size: 14px; 62 | color: #333333; 63 | } 64 | .cart-list-item ul{ 65 | margin: 0; 66 | list-style: none; 67 | padding: 0px 0px 10px; 68 | font-size: 13px; 69 | } 70 | .cart-list-item ul li{ 71 | padding-left: 10px; 72 | padding-top: 10px; 73 | padding-right: 10px; 74 | } 75 | .cart-list-item ul li a{ 76 | cursor: pointer; 77 | color: #c88326; 78 | text-decoration: none; 79 | display: flex; 80 | flex-direction: row; 81 | } 82 | .cart-list-item ul li span{ 83 | flex: 1; 84 | text-align: right; 85 | color: #333; 86 | } 87 | .cart-list-item ul li a:hover{ 88 | color: red; 89 | } 90 | .list-item-bottom{ 91 | margin: 0 !important; 92 | padding: 0 !important; 93 | font-size: 11px; 94 | color: #b4b4b4; 95 | } 96 | 97 | 98 | -------------------------------------------------------------------------------- /src/app/side-nav-drawer/side-nav-drawer.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 | 6 | 7 | 文章 8 | 阅读 9 | 访客 10 | 11 | 12 | {{profileData['articles_count']}} 13 | {{profileData['total_pv']}} 14 | {{profileData['total_ip_count']}} 15 | 16 | 17 | 18 | 19 | 24 | 25 | 26 | 27 | 28 | 33 | 34 | 35 | 36 | 37 |
    38 |
  • 39 | {{item['title']}} 40 |

    发表时间: {{item['create_time'] | date: 'yyyy-MM-dd HH:mm:ss'}}

    41 |
  • 42 |
43 |
44 | 45 | 46 | 52 | 53 |
54 |
55 | -------------------------------------------------------------------------------- /src/app/side-nav-drawer/side-nav-drawer.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, EventEmitter, OnInit, Output} from '@angular/core'; 2 | import {ActivatedRoute, Router} from '@angular/router'; 3 | import {SidenavService} from '../service/sidenav.service'; 4 | import {BlogService} from '../service/blog.service'; 5 | 6 | @Component({ 7 | selector: 'app-side-nav-drawer', 8 | templateUrl: './side-nav-drawer.component.html', 9 | styleUrls: ['./side-nav-drawer.component.css'], 10 | }) 11 | // 侧滑组件 12 | export class SideNavDrawerComponent implements OnInit { 13 | isShowProfile: Boolean; 14 | profileData = null; 15 | howAndNewArticles = null; 16 | @Output() titleEmitter = new EventEmitter(); 17 | 18 | pushTitle(title: string) { 19 | this.titleEmitter.emit(title); 20 | this.sideNavService.sendMessage('close'); 21 | } 22 | 23 | constructor(private router: Router, private sideNavService: SidenavService, 24 | private route: ActivatedRoute, private bs: BlogService) { 25 | } 26 | 27 | ngOnInit() { 28 | this.changePage(); 29 | if (this.isShowProfile) { 30 | if (this.bs.isInit()) { 31 | this.bs.getCategoryByUserId(value => { 32 | this.profileData = value['data']; 33 | }); 34 | } else { 35 | setTimeout(() => { 36 | this.bs.getCategoryByUserId(value => { 37 | this.profileData = value['data']; 38 | }); 39 | }, 300); 40 | } 41 | } else { 42 | setTimeout(() => { 43 | 44 | }, 300); 45 | if (this.bs.isInit()) { 46 | this.bs.getHotAndNewArticles(value => { 47 | this.howAndNewArticles = value['data']; 48 | localStorage.setItem('hot_id', this.howAndNewArticles['hot_articles'][0]['aid']); 49 | }); 50 | } else { 51 | setTimeout(() => { 52 | this.bs.getHotAndNewArticles(value => { 53 | this.howAndNewArticles = value['data']; 54 | localStorage.setItem('hot_id', this.howAndNewArticles['hot_articles'][0]['aid']); 55 | }); 56 | }, 300); 57 | } 58 | } 59 | } 60 | 61 | closeSlide() { 62 | this.sideNavService.sendMessage('close'); 63 | } 64 | 65 | changePage() { 66 | if (window.location.href.indexOf('recommend') === -1) { 67 | this.titleEmitter.emit('文章列表'); 68 | this.isShowProfile = true; 69 | } else { 70 | this.titleEmitter.emit('热文推荐'); 71 | this.isShowProfile = false; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/app/side-nav-drawer/side-nav-drawer.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {SideNavDrawerComponent} from './side-nav-drawer.component'; 4 | import {MatCardModule, MatGridListModule, MatIconModule} from '@angular/material'; 5 | import {RouterModule} from '@angular/router'; 6 | 7 | @NgModule({ 8 | imports: [ 9 | CommonModule, 10 | MatGridListModule, 11 | MatCardModule, 12 | MatIconModule, 13 | RouterModule 14 | ], 15 | declarations: [SideNavDrawerComponent], 16 | exports: [SideNavDrawerComponent], 17 | }) 18 | export class SideNavDrawerModule { 19 | } 20 | -------------------------------------------------------------------------------- /src/app/side-nav/side-nav.component.css: -------------------------------------------------------------------------------- 1 | .sidenv-container { 2 | flex: 1; 3 | box-sizing: border-box; 4 | } 5 | .sidenav-drawer-container { 6 | overflow: auto; 7 | } 8 | .sidenav-content-container { 9 | display: flex; 10 | flex-direction: column; 11 | min-height: 100%; 12 | } 13 | .sidenav-content-header-container{ 14 | display: flex; 15 | align-items: center; 16 | background: #3f51b5; 17 | padding-left: 20px; 18 | } 19 | .sidenav_toggle{ 20 | padding: 0; 21 | margin-left: 8px; 22 | min-width: 64px; 23 | display: none; 24 | } 25 | .sidenav_toggle mat-icon{ 26 | font-size: 30px; 27 | height: 64px; 28 | width: 64px; 29 | line-height: 64px; 30 | color: #fff; 31 | } 32 | .sidenav-content-header-container h1{ 33 | font-size: 20px; 34 | font-weight: 300; 35 | margin: 0; 36 | padding: 20px 8px; 37 | outline: none; 38 | color: #fff; 39 | } 40 | .sidenav-content-inner-container{ 41 | display: flex; 42 | flex: 1; 43 | flex-direction: column; 44 | } 45 | .sidenav-content-inner-body{ 46 | display: flex; 47 | flex-direction: row; 48 | } 49 | 50 | @media (max-width: 720px) { 51 | .sidenv-container { 52 | flex: 1 0 auto; 53 | } 54 | .sidenav_toggle{ 55 | display: flex; 56 | align-items: center; 57 | justify-content: center; 58 | } 59 | .sidenav-content-header-container{ 60 | padding-left: 0px; 61 | } 62 | .sidenav-content-header-container h1{ 63 | font-size: 20px; 64 | padding: 20px 8px; 65 | } 66 | } 67 | 68 | @media (max-width: 720px) { 69 | .sidenv-container .sidenav-drawer-container { 70 | z-index: 4; 71 | } 72 | .mat-drawer::-webkit-scrollbar-thumb { 73 | background: rgba(0,0,0,.26); 74 | } 75 | } 76 | .mat-drawer::-webkit-scrollbar { 77 | height: 4px; 78 | width: 4px; 79 | } 80 | -------------------------------------------------------------------------------- /src/app/side-nav/side-nav.component.html: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 |
11 |
12 | 15 |

{{title}}

16 |
17 |
18 |
19 | 20 | 21 |
22 |
23 |
24 |
25 |
26 | -------------------------------------------------------------------------------- /src/app/side-nav/side-nav.component.ts: -------------------------------------------------------------------------------- 1 | import {ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; 2 | import {MediaMatcher} from '@angular/cdk/layout'; 3 | import {MatSidenav} from '@angular/material'; 4 | import {Title} from '@angular/platform-browser'; 5 | import {SidenavService} from '../service/sidenav.service'; 6 | import {Subscription} from 'rxjs/Subscription'; 7 | 8 | @Component({ 9 | selector: 'app-side-nav', 10 | templateUrl: './side-nav.component.html', 11 | styleUrls: ['./side-nav.component.css'] 12 | }) 13 | // 侧滑菜单 14 | export class SideNavComponent implements OnInit, OnDestroy { 15 | mobileQuery: MediaQueryList; 16 | @ViewChild(MatSidenav) 17 | nav: MatSidenav; 18 | private _mobileQueryListener: () => void; 19 | title = '文章列表'; 20 | subscription: Subscription; 21 | 22 | constructor(private titleService: Title, 23 | private sideNavService: SidenavService, 24 | private changeDetectorRef: ChangeDetectorRef, media: MediaMatcher) { 25 | 26 | this.initSideService(); 27 | 28 | this.mobileQuery = media.matchMedia('(max-width: 720px)'); 29 | this._mobileQueryListener = () => { 30 | if (!this.mobileQuery.matches && this.nav !== undefined) { 31 | this.nav.close(); 32 | } 33 | changeDetectorRef.detectChanges(); 34 | }; 35 | this.mobileQuery.addListener(this._mobileQueryListener); 36 | } 37 | 38 | getTitle(title: string) { 39 | this.title = title; 40 | // this.titleService.setTitle(title + '|Track的博客'); 41 | } 42 | 43 | ngOnDestroy(): void { 44 | this.mobileQuery.removeListener(this._mobileQueryListener); 45 | this.subscription.unsubscribe(); 46 | } 47 | 48 | initSideService() { 49 | this.subscription = this.sideNavService 50 | .getMessage().subscribe(message => { 51 | if (message['text'] === 'close') { 52 | if (this.mobileQuery.matches && this.nav !== undefined) { 53 | this.nav.close(); 54 | this.changeDetectorRef.detectChanges(); 55 | } 56 | } 57 | }); 58 | } 59 | 60 | ngOnInit() { 61 | 62 | if (this.nav !== undefined && this.nav.opened) { 63 | this.nav.close(); 64 | } 65 | } 66 | 67 | toggle() { 68 | if (this.nav !== undefined) { 69 | this.nav.open(); 70 | } 71 | } 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/app/side-nav/side-nav.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {SideNavComponent} from './side-nav.component'; 4 | import {MatButtonModule, MatCheckboxModule, MatIconModule, MatSidenavModule} from '@angular/material'; 5 | import {FormsModule} from '@angular/forms'; 6 | import {LayoutModule, MediaMatcher} from '@angular/cdk/layout'; 7 | import {SideNavDrawerComponent} from '../side-nav-drawer/side-nav-drawer.component'; 8 | import {CdkScrollable} from '@angular/cdk/scrolling'; 9 | import {PortalModule} from '@angular/cdk/portal'; 10 | import {NavRoutingModule} from '../routing/nav.routing.module'; 11 | import {ArtlistModule} from '../artlist/artlist.module'; 12 | import {SideNavDrawerModule} from '../side-nav-drawer/side-nav-drawer.module'; 13 | import {ArtdetailModule} from '../artdetail/artdetail.module'; 14 | import {SidenavService} from '../service/sidenav.service'; 15 | 16 | @NgModule({ 17 | imports: [ 18 | CommonModule, 19 | MatSidenavModule, 20 | MatButtonModule, 21 | MatCheckboxModule, 22 | FormsModule, 23 | MatIconModule, 24 | NavRoutingModule, 25 | ArtlistModule, 26 | ArtdetailModule, 27 | SideNavDrawerModule 28 | ], 29 | declarations: [SideNavComponent], 30 | providers: [MediaMatcher, SidenavService], 31 | }) 32 | export class SideNavModule { 33 | } 34 | -------------------------------------------------------------------------------- /src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyw1995/Angular5-Blog-Front/6a8a722a4895f317eeff698389c15b49e614fb5e/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/assets/avator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyw1995/Angular5-Blog-Front/6a8a722a4895f317eeff698389c15b49e614fb5e/src/assets/avator.jpg -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | baseUrl: '' // 正式环境 用了nginx反向代理,/api/ 4 | }; 5 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false, 8 | baseUrl: 'http://127.0.0.1:8888' 9 | }; 10 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyw1995/Angular5-Blog-Front/6a8a722a4895f317eeff698389c15b49e614fb5e/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 博客 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 50 | 51 | 52 | loading... 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | import 'hammerjs'; 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.log(err)); 13 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** IE10 and IE11 requires the following for the Reflect API. */ 41 | // import 'core-js/es6/reflect'; 42 | 43 | 44 | /** Evergreen browsers require these. **/ 45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 46 | import 'core-js/es7/reflect'; 47 | 48 | 49 | /** 50 | * Required to support Web Animations `@angular/platform-browser/animations`. 51 | * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation 52 | **/ 53 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 54 | 55 | /** 56 | * By default, zone.js will patch all possible macroTask and DomEvents 57 | * user can disable parts of macroTask/DomEvents patch by setting following flags 58 | */ 59 | 60 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 61 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 62 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 63 | 64 | /* 65 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 66 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 67 | */ 68 | // (window as any).__Zone_enable_cross_context_check = true; 69 | 70 | /*************************************************************************************************** 71 | * Zone JS is required by default for Angular itself. 72 | */ 73 | import 'zone.js/dist/zone'; // Included with Angular CLI. 74 | 75 | 76 | 77 | /*************************************************************************************************** 78 | * APPLICATION IMPORTS 79 | */ 80 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | @import "~@angular/material/prebuilt-themes/indigo-pink.css"; 3 | app-side-nav{ 4 | display: flex; 5 | flex-direction: column; 6 | } 7 | 8 | app-blog-material>app-side-nav{ 9 | flex: 1; 10 | } 11 | app-side-nav-drawer{ 12 | display: flex; 13 | flex-direction: column; 14 | } 15 | app-artlist,app-artdetail{ 16 | -webkit-box-flex: 1; 17 | -ms-flex-positive: 1; 18 | flex-grow: 1; 19 | box-sizing: border-box; 20 | } 21 | ul{ 22 | margin: 0; 23 | list-style: none; 24 | } 25 | body { 26 | font-family: Roboto,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif; 27 | margin: 0; 28 | } 29 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "./", 6 | "module": "es2015", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "types": [ 8 | "jasmine", 9 | "node" 10 | ] 11 | }, 12 | "files": [ 13 | "test.ts" 14 | ], 15 | "include": [ 16 | "**/*.spec.ts", 17 | "**/*.d.ts" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | declare var hljs: any; 4 | 5 | interface NodeModule { 6 | id: string; 7 | } 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "sourceMap": true, 6 | "declaration": false, 7 | "moduleResolution": "node", 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "target": "es5", 11 | "typeRoots": [ 12 | "node_modules/@types" 13 | ], 14 | "lib": [ 15 | "es2017", 16 | "dom" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs", 22 | "rxjs/Rx" 23 | ], 24 | "import-spacing": true, 25 | "indent": [ 26 | true, 27 | "spaces" 28 | ], 29 | "interface-over-type-literal": true, 30 | "label-position": true, 31 | "max-line-length": [ 32 | true, 33 | 140 34 | ], 35 | "member-access": false, 36 | "member-ordering": [ 37 | true, 38 | { 39 | "order": [ 40 | "static-field", 41 | "instance-field", 42 | "static-method", 43 | "instance-method" 44 | ] 45 | } 46 | ], 47 | "no-arg": true, 48 | "no-bitwise": true, 49 | "no-console": [ 50 | true, 51 | "debug", 52 | "info", 53 | "time", 54 | "timeEnd", 55 | "trace" 56 | ], 57 | "no-construct": true, 58 | "no-debugger": true, 59 | "no-duplicate-super": true, 60 | "no-empty": false, 61 | "no-empty-interface": true, 62 | "no-eval": true, 63 | "no-inferrable-types": [ 64 | true, 65 | "ignore-params" 66 | ], 67 | "no-misused-new": true, 68 | "no-non-null-assertion": true, 69 | "no-shadowed-variable": true, 70 | "no-string-literal": false, 71 | "no-string-throw": true, 72 | "no-switch-case-fall-through": true, 73 | "no-trailing-whitespace": true, 74 | "no-unnecessary-initializer": true, 75 | "no-unused-expression": true, 76 | "no-use-before-declare": true, 77 | "no-var-keyword": true, 78 | "object-literal-sort-keys": false, 79 | "one-line": [ 80 | true, 81 | "check-open-brace", 82 | "check-catch", 83 | "check-else", 84 | "check-whitespace" 85 | ], 86 | "prefer-const": true, 87 | "quotemark": [ 88 | true, 89 | "single" 90 | ], 91 | "radix": true, 92 | "semicolon": [ 93 | true, 94 | "always" 95 | ], 96 | "triple-equals": [ 97 | true, 98 | "allow-null-check" 99 | ], 100 | "typedef-whitespace": [ 101 | true, 102 | { 103 | "call-signature": "nospace", 104 | "index-signature": "nospace", 105 | "parameter": "nospace", 106 | "property-declaration": "nospace", 107 | "variable-declaration": "nospace" 108 | } 109 | ], 110 | "unified-signatures": true, 111 | "variable-name": false, 112 | "whitespace": [ 113 | true, 114 | "check-branch", 115 | "check-decl", 116 | "check-operator", 117 | "check-separator", 118 | "check-type" 119 | ], 120 | "directive-selector": [ 121 | true, 122 | "attribute", 123 | "app", 124 | "camelCase" 125 | ], 126 | "component-selector": [ 127 | true, 128 | "element", 129 | "app", 130 | "kebab-case" 131 | ], 132 | "no-output-on-prefix": true, 133 | "use-input-property-decorator": true, 134 | "use-output-property-decorator": true, 135 | "use-host-property-decorator": true, 136 | "no-input-rename": true, 137 | "no-output-rename": true, 138 | "use-life-cycle-interface": true, 139 | "use-pipe-transform-interface": true, 140 | "component-class-suffix": true, 141 | "directive-class-suffix": true 142 | } 143 | } 144 | --------------------------------------------------------------------------------