├── assets ├── close.png ├── logo.jpg ├── logo.png ├── banner.jpg ├── banner.png ├── qcode.jpeg ├── radiocolor.png ├── images │ ├── blog.gif │ ├── avatar.png │ ├── logoBig.png │ ├── weixin.jpeg │ ├── WechatIMG2.jpeg │ ├── WechatIMG6.jpeg │ └── WechatIMG8.jpeg ├── font │ ├── iconfont.eot │ ├── iconfont.ttf │ ├── iconfont.woff │ └── iconfont.svg ├── README.md ├── gitment │ ├── constants.js │ ├── constants.js.map │ ├── icons.js │ ├── icons.js.map │ ├── utils.js │ ├── utils.js.map │ ├── gitment.js │ ├── theme │ │ ├── default.js │ │ └── default.js.map │ └── gitment.js.map ├── hybrid.css └── atom-one-light.css ├── static ├── favicon.ico ├── images │ └── slide.jpeg ├── README.md └── css │ └── layui-mobile.css ├── plugins ├── element-ui.js ├── vue-cookie.js ├── axios.js └── README.md ├── .gitignore ├── components ├── README.md ├── sidebar.vue ├── ArticleList.vue ├── Loading.vue ├── slide.vue ├── FlashArticleList.vue └── Comment.vue ├── .editorconfig ├── layouts ├── README.md ├── error.vue └── default.vue ├── pages ├── README.md ├── search │ └── _search.vue ├── user │ ├── login.vue │ ├── register.vue │ ├── find-password.vue │ └── _id.vue ├── _tag.vue ├── index.vue ├── flash.vue ├── flashnews │ └── _id.vue └── details │ └── _id.vue ├── middleware └── README.md ├── store ├── README.md └── index.js ├── .eslintrc.js ├── pull.js ├── utils └── index.js ├── package.json ├── nuxt.config.js └── README.md /assets/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/close.png -------------------------------------------------------------------------------- /assets/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/logo.jpg -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/logo.png -------------------------------------------------------------------------------- /assets/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/banner.jpg -------------------------------------------------------------------------------- /assets/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/banner.png -------------------------------------------------------------------------------- /assets/qcode.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/qcode.jpeg -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/static/favicon.ico -------------------------------------------------------------------------------- /assets/radiocolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/radiocolor.png -------------------------------------------------------------------------------- /assets/images/blog.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/images/blog.gif -------------------------------------------------------------------------------- /assets/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/font/iconfont.eot -------------------------------------------------------------------------------- /assets/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/font/iconfont.ttf -------------------------------------------------------------------------------- /assets/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/font/iconfont.woff -------------------------------------------------------------------------------- /assets/images/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/images/avatar.png -------------------------------------------------------------------------------- /assets/images/logoBig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/images/logoBig.png -------------------------------------------------------------------------------- /assets/images/weixin.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/images/weixin.jpeg -------------------------------------------------------------------------------- /static/images/slide.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/static/images/slide.jpeg -------------------------------------------------------------------------------- /plugins/element-ui.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Element from 'element-ui' 3 | 4 | Vue.use(Element); 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/WechatIMG2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/images/WechatIMG2.jpeg -------------------------------------------------------------------------------- /assets/images/WechatIMG6.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/images/WechatIMG6.jpeg -------------------------------------------------------------------------------- /assets/images/WechatIMG8.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beijing-xiaotinghua/layBlog-ui/HEAD/assets/images/WechatIMG8.jpeg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | 4 | # logs 5 | npm-debug.log 6 | 7 | # Nuxt build 8 | .nuxt 9 | 10 | # Nuxt generate 11 | dist 12 | -------------------------------------------------------------------------------- /plugins/vue-cookie.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueCookie from 'vue-cookie' // api: https://github.com/alfhen/vue-cookie 3 | 4 | Vue.use(VueCookie) -------------------------------------------------------------------------------- /plugins/axios.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | let options = {} 4 | if (process.server) { 5 | options.baseURL = process.env.apiUrl 6 | } 7 | 8 | export default axios.create(options) 9 | -------------------------------------------------------------------------------- /components/README.md: -------------------------------------------------------------------------------- 1 | # COMPONENTS 2 | 3 | The components directory contains your Vue.js Components. 4 | Nuxt.js doesn't supercharge these components. 5 | 6 | **This directory is not required, you can delete it if you don't want to use it.** 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_size = 2 6 | indent_style = space 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /layouts/README.md: -------------------------------------------------------------------------------- 1 | # LAYOUTS 2 | 3 | This directory contains your Application Layouts. 4 | 5 | More information about the usage of this directory in the documentation: 6 | https://nuxtjs.org/guide/views#layouts 7 | 8 | **This directory is not required, you can delete it if you don't want to use it.** 9 | -------------------------------------------------------------------------------- /pages/README.md: -------------------------------------------------------------------------------- 1 | # PAGES 2 | 3 | This directory contains your Application Views and Routes. 4 | The framework reads all the .vue files inside this directory and creates the router of your application. 5 | 6 | More information about the usage of this directory in the documentation: 7 | https://nuxtjs.org/guide/routing 8 | -------------------------------------------------------------------------------- /assets/README.md: -------------------------------------------------------------------------------- 1 | # ASSETS 2 | 3 | This directory contains your un-compiled assets such as LESS, SASS, or JavaScript. 4 | 5 | More information about the usage of this directory in the documentation: 6 | https://nuxtjs.org/guide/assets#webpacked 7 | 8 | **This directory is not required, you can delete it if you don't want to use it.** 9 | -------------------------------------------------------------------------------- /plugins/README.md: -------------------------------------------------------------------------------- 1 | # PLUGINS 2 | 3 | This directory contains your Javascript plugins that you want to run before instantiating the root vue.js application. 4 | 5 | More information about the usage of this directory in the documentation: 6 | https://nuxtjs.org/guide/plugins 7 | 8 | **This directory is not required, you can delete it if you don't want to use it.** 9 | -------------------------------------------------------------------------------- /static/README.md: -------------------------------------------------------------------------------- 1 | # STATIC 2 | 3 | This directory contains your static files. 4 | Each file inside this directory is mapped to /. 5 | 6 | Example: /static/robots.txt is mapped as /robots.txt. 7 | 8 | More information about the usage of this directory in the documentation: 9 | https://nuxtjs.org/guide/assets#static 10 | 11 | **This directory is not required, you can delete it if you don't want to use it.** 12 | -------------------------------------------------------------------------------- /assets/gitment/constants.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | var LS_ACCESS_TOKEN_KEY = exports.LS_ACCESS_TOKEN_KEY = 'gitment-comments-token'; 7 | var LS_USER_KEY = exports.LS_USER_KEY = 'gitment-user-info'; 8 | 9 | var NOT_INITIALIZED_ERROR = exports.NOT_INITIALIZED_ERROR = new Error('Comments Not Initialized'); 10 | //# sourceMappingURL=constants.js.map -------------------------------------------------------------------------------- /middleware/README.md: -------------------------------------------------------------------------------- 1 | # MIDDLEWARE 2 | 3 | This directory contains your Application Middleware. 4 | The middleware lets you define custom function to be ran before rendering a page or a group of pages (layouts). 5 | 6 | More information about the usage of this directory in the documentation: 7 | https://nuxtjs.org/guide/routing#middleware 8 | 9 | **This directory is not required, you can delete it if you don't want to use it.** 10 | -------------------------------------------------------------------------------- /store/README.md: -------------------------------------------------------------------------------- 1 | # STORE 2 | 3 | This directory contains your Vuex Store files. 4 | Vuex Store option is implemented in the Nuxt.js framework. 5 | Creating a index.js file in this directory activate the option in the framework automatically. 6 | 7 | More information about the usage of this directory in the documentation: 8 | https://nuxtjs.org/guide/vuex-store 9 | 10 | **This directory is not required, you can delete it if you don't want to use it.** 11 | -------------------------------------------------------------------------------- /assets/gitment/constants.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/constants.js"],"names":["LS_ACCESS_TOKEN_KEY","LS_USER_KEY","NOT_INITIALIZED_ERROR","Error"],"mappings":";;;;;AAAO,IAAMA,oDAAsB,wBAA5B;AACA,IAAMC,oCAAc,mBAApB;;AAEA,IAAMC,wDAAwB,IAAIC,KAAJ,CAAU,0BAAV,CAA9B","file":"constants.js","sourcesContent":["export const LS_ACCESS_TOKEN_KEY = 'gitment-comments-token'\nexport const LS_USER_KEY = 'gitment-user-info'\n\nexport const NOT_INITIALIZED_ERROR = new Error('Comments Not Initialized')\n"]} -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true 6 | }, 7 | parserOptions: { 8 | parser: 'babel-eslint' 9 | }, 10 | extends: [ 11 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention 12 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 13 | 'plugin:vue/essential' 14 | ], 15 | // required to lint *.vue files 16 | plugins: [ 17 | 'vue' 18 | ], 19 | // add your custom rules here 20 | rules: {} 21 | } 22 | -------------------------------------------------------------------------------- /pull.js: -------------------------------------------------------------------------------- 1 | const http = require('http'); 2 | const exec = require('exec'); 3 | const PORT = 3389 4 | 5 | var deployServer = http.createServer(function(request, response) { 6 | if (request.url.search(/pull\/?$/i) > 0) { 7 | var commands = ['git pull', 'npm run server'].join(' && '); 8 | exec(commands, function(err, out, code) { 9 | if (err instanceof Error) { 10 | response.writeHead(500) 11 | response.end('Server Internal Error.') 12 | throw err 13 | } 14 | process.stderr.write(err) 15 | process.stdout.write(out) 16 | response.writeHead(200) 17 | }) 18 | } else { 19 | response.writeHead(404) 20 | response.end('Not Found.') 21 | } 22 | }) 23 | 24 | deployServer.listen(PORT); 25 | -------------------------------------------------------------------------------- /layouts/error.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 22 | 23 | 26 | -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | 5 | Vue.use(Vuex); 6 | 7 | const state = { 8 | 'newlistfirst':true, 9 | 'newArticlelist':[], 10 | 'taglistfirst':true, 11 | 'taglistcon':[], 12 | 'userinfo': {} 13 | }; 14 | // 创建一个对象存储一系列 15 | const mutations = { 16 | updatenewlistcon (state, newArticlelist) { 17 | state.newArticlelist = newArticlelist 18 | }, 19 | newlistfirst (state,newlistfirst) { 20 | state.newlistfirst = newlistfirst 21 | }, 22 | updatetaglistcon (state,taglistcon) { 23 | state.taglistcon = taglistcon 24 | }, 25 | taglistfirst (state,taglistfirst) { 26 | state.taglistfirst = taglistfirst 27 | }, 28 | updateuserinfo (state,userinfo) { 29 | state.userinfo = userinfo 30 | }, 31 | 32 | }; 33 | 34 | 35 | const store = () => new Vuex.Store({ 36 | state, 37 | mutations 38 | }) 39 | 40 | export default store; 41 | -------------------------------------------------------------------------------- /components/sidebar.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | -------------------------------------------------------------------------------- /utils/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | export function dateFormat(){ 4 | Date.prototype.format = function(format) { 5 | var o = { 6 | "M+": this.getMonth() + 1, //month 7 | "d+": this.getDate(), //day 8 | "h+": this.getHours(), //hour 9 | "m+": this.getMinutes(), //minute 10 | "s+": this.getSeconds(), //second 11 | "q+": Math.floor((this.getMonth() + 3) / 3), //quarter 12 | "S": this.getMilliseconds() //millisecond 13 | } 14 | if (/(y+)/.test(format)) { 15 | format = format.replace(RegExp.$1,(this.getFullYear() + "").substr(4 - RegExp.$1.length)); 16 | } 17 | for (var k in o){ 18 | if (new RegExp("(" + k + ")").test(format)){ 19 | format = format.replace(RegExp.$1,RegExp.$1.length == 1 ? o[k] :("00" + o[k]).substr(("" + o[k]).length)); 20 | } 21 | } 22 | return format; 23 | } 24 | } 25 | 26 | /** 27 | * 获取uuid 28 | */ 29 | export function getUUID () { 30 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { 31 | return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16) 32 | }) 33 | } 34 | 35 | /** 36 | * 手机号码 37 | * @param {*} s 38 | */ 39 | export function isMobile (s) { 40 | return /^1[0-9]{10}$/.test(s) 41 | } 42 | -------------------------------------------------------------------------------- /components/ArticleList.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blog", 3 | "version": "1.0.1", 4 | "description": "blog vue ssr", 5 | "author": "buptzlk", 6 | "private": true, 7 | "scripts": { 8 | "dev": "nuxt", 9 | "build": "nuxt build", 10 | "start": "nuxt start", 11 | "server": "npm run build && pm2 delete blog && pm2 start npm --name 'blog' -- start", 12 | "generate": "nuxt generate", 13 | "lint": "eslint --ext .js,.vue --ignore-path .gitignore .", 14 | "precommit": "npm run lint", 15 | "firstserver": "npm run build && pm2 start npm --name 'blog' -- start", 16 | "list": "pm2 list", 17 | "stop": "pm2 stop 'blog'" 18 | }, 19 | "dependencies": { 20 | "axios": "^0.18.0", 21 | "crypto": "^1.0.1", 22 | "element-ui": "^2.3.6", 23 | "highlight.js": "^9.12.0", 24 | "html2canvas": "^1.0.0-rc.3", 25 | "identicon.js": "^2.3.3", 26 | "jquery": "^3.4.1", 27 | "marked": "^0.3.19", 28 | "mobx": "^4.2.0", 29 | "nuxt": "^1.0.0", 30 | "qrcode": "^1.4.1", 31 | "vue-cookie": "^1.1.4", 32 | "wangeditor": "^3.1.1" 33 | }, 34 | "devDependencies": { 35 | "@nuxtjs/axios": "^5.3.1", 36 | "@nuxtjs/proxy": "^1.2.4", 37 | "babel-eslint": "^8.2.1", 38 | "babel-plugin-component": "^1.1.0", 39 | "eslint": "^4.15.0", 40 | "eslint-friendly-formatter": "^3.0.0", 41 | "eslint-loader": "^1.7.1", 42 | "eslint-plugin-vue": "^4.0.0", 43 | "pm2": "^2.10.3" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /assets/hybrid.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/ 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #23241f; 12 | } 13 | 14 | .hljs, 15 | .hljs-tag, 16 | .hljs-subst { 17 | color: #f8f8f2; 18 | } 19 | 20 | .hljs-strong, 21 | .hljs-emphasis { 22 | color: #a8a8a2; 23 | } 24 | 25 | .hljs-bullet, 26 | .hljs-quote, 27 | .hljs-number, 28 | .hljs-regexp, 29 | .hljs-link { 30 | color: #ae81ff; 31 | } 32 | .hljs-literal{color:#f92672} 33 | .hljs-code, 34 | .hljs-title, 35 | .hljs-section, 36 | .hljs-selector-class { 37 | color: #a6e22e; 38 | } 39 | 40 | .hljs-strong { 41 | font-weight: bold; 42 | } 43 | 44 | .hljs-emphasis { 45 | font-style: italic; 46 | } 47 | 48 | .hljs-keyword{color:#66d9ef} 49 | .hljs-selector-tag, 50 | .hljs-name{ 51 | color: #f92672; 52 | } 53 | .hljs-attr { 54 | color: #a6e22e; 55 | } 56 | 57 | .hljs-symbol, 58 | .hljs-attribute { 59 | color: #66d9ef; 60 | } 61 | 62 | .hljs-params{color:#fd971f} 63 | .hljs-class .hljs-title { 64 | color: #f8f8f2; 65 | } 66 | 67 | .hljs-string, 68 | .hljs-type, 69 | 70 | .hljs-builtin-name, 71 | .hljs-selector-id, 72 | .hljs-selector-attr, 73 | .hljs-selector-pseudo, 74 | .hljs-addition, 75 | .hljs-variable, 76 | .hljs-template-variable { 77 | color: #e6db74; 78 | } 79 | .hljs-built_in{color:#66d9ef} 80 | .hljs-comment, 81 | .hljs-deletion, 82 | .hljs-meta { 83 | color: #75715e; 84 | } 85 | .hljs-comment{font-style:inherit} -------------------------------------------------------------------------------- /assets/atom-one-light.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Atom One Light by Daniel Gamage 4 | Original One Light Syntax theme from https://github.com/atom/one-light-syntax 5 | 6 | base: #fafafa 7 | mono-1: #383a42 8 | mono-2: #686b77 9 | mono-3: #a0a1a7 10 | hue-1: #0184bb 11 | hue-2: #4078f2 12 | hue-3: #a626a4 13 | hue-4: #50a14f 14 | hue-5: #e45649 15 | hue-5-2: #c91243 16 | hue-6: #986801 17 | hue-6-2: #c18401 18 | 19 | */ 20 | 21 | .hljs { 22 | display: block; 23 | overflow-x: auto; 24 | padding: 0.5em; 25 | color: #383a42; 26 | background: #fafafa; 27 | } 28 | 29 | .hljs-comment, 30 | .hljs-quote { 31 | color: #a0a1a7; 32 | font-style: italic; 33 | } 34 | 35 | .hljs-doctag, 36 | .hljs-keyword, 37 | .hljs-formula { 38 | color: #a626a4; 39 | } 40 | 41 | .hljs-section, 42 | .hljs-name, 43 | .hljs-selector-tag, 44 | .hljs-deletion, 45 | .hljs-subst { 46 | color: #e45649; 47 | } 48 | 49 | .hljs-literal { 50 | color: #0184bb; 51 | } 52 | 53 | .hljs-string, 54 | .hljs-regexp, 55 | .hljs-addition, 56 | .hljs-attribute, 57 | .hljs-meta-string { 58 | color: #50a14f; 59 | } 60 | 61 | .hljs-built_in, 62 | .hljs-class .hljs-title { 63 | color: #c18401; 64 | } 65 | 66 | .hljs-attr, 67 | .hljs-variable, 68 | .hljs-template-variable, 69 | .hljs-type, 70 | .hljs-selector-class, 71 | .hljs-selector-attr, 72 | .hljs-selector-pseudo, 73 | .hljs-number { 74 | color: #986801; 75 | } 76 | 77 | .hljs-symbol, 78 | .hljs-bullet, 79 | .hljs-link, 80 | .hljs-meta, 81 | .hljs-selector-id, 82 | .hljs-title { 83 | color: #4078f2; 84 | } 85 | 86 | .hljs-emphasis { 87 | font-style: italic; 88 | } 89 | 90 | .hljs-strong { 91 | font-weight: bold; 92 | } 93 | 94 | .hljs-link { 95 | text-decoration: underline; 96 | } 97 | -------------------------------------------------------------------------------- /pages/search/_search.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 57 | 58 | 73 | -------------------------------------------------------------------------------- /components/Loading.vue: -------------------------------------------------------------------------------- 1 | 11 | 19 | 20 | 89 | -------------------------------------------------------------------------------- /components/slide.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 57 | 58 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | 3 | module.exports = { 4 | env: { 5 | apiUrl: 'http://blog.layadmin.cn', // 后端api接口地址 6 | homeUrl: 'https://localhost:3000' //前端域名 7 | }, 8 | /* 9 | ** Headers of the page 10 | */ 11 | head: { 12 | title: 'layBlog-ui', 13 | meta: [ 14 | { charset: 'utf-8' }, 15 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 16 | { name: 'keywords', content: 'vue|博客' }, 17 | { hid: 'description', name: 'description', content: 'layBlog-ui是开源的前端博客系统,基于它你能更快速的打造一套功能完备的商业级新媒体网站' } 18 | ], 19 | link: [ 20 | { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' } 21 | ] 22 | }, 23 | /* 24 | ** Customize the progress bar color 25 | */ 26 | loading: { color: '#44C1B8', height: '4px' }, 27 | vender:[ 28 | 'element-ui', 'axios', '~untils/index.js' 29 | ], 30 | css: [ 31 | 'element-ui/lib/theme-chalk/index.css', 32 | {src: '@/static/css/layui.css', lang: 'css'}, 33 | {src: '@/static/css/layui-mobile.css', lang: 'css'}, 34 | {src: '@/static/css/style.css', lang: 'css'}, 35 | {src: '@/static/css/layadmin.css', lang: 'css'} 36 | 37 | ], 38 | plugins: [ 39 | { src: '~plugins/element-ui', ssr: true }, 40 | { src: '~plugins/vue-cookie', ssr: true } 41 | 42 | ], 43 | /* 44 | ** Build configuration 45 | */ 46 | build: { 47 | vendor: ['wangeditor'], 48 | build: { 49 | vendor: ['element-ui', 'axios', 'Button', 'Input', 'Tabs', 'Message', 'TabPane', 'Row', 'Col', 'Loading', 'Notification', 'Icon', 'Carousel', 'Tag'] 50 | }, 51 | analyze: false, 52 | plugins: [ 53 | new webpack.ContextReplacementPlugin( 54 | /highlight\.js\/lib\/languages$/, 55 | new RegExp(`^./(${['javascript', 'css', 'php', 'sql', 'python', 'bash'].join('|')})$`), 56 | ) 57 | ], 58 | babel: { 59 | plugins: [['component', [{ 60 | libraryName: 'element-ui', 61 | styleLibraryName: 'theme-chalk' 62 | }]]], 63 | comments: true 64 | }, 65 | /* 66 | ** Run ESLint on save 67 | */ 68 | extend (config, { isDev, isClient }) { 69 | if (isDev && isClient) { 70 | config.module.rules.push({ 71 | enforce: 'pre', 72 | test: /\.(js|vue)$/, 73 | loader: 'eslint-loader', 74 | exclude: /(node_modules)/ 75 | }) 76 | } 77 | } 78 | }, 79 | modules: [ 80 | '@nuxtjs/axios', 81 | '@nuxtjs/proxy' 82 | ], 83 | proxy: [ 84 | ['/api', { target: 'http://blog.layadmin.cn' }] 85 | ] 86 | } 87 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 基于vue nuxt element-ui 打造,采用服务器端渲染ssr技术,更利于seo[线上预览](https://bw31d.com "线上预览") 2 | 3 | ## 效果图 4 | ![image](https://github.com/beijing-xiaotinghua/layBlog-ui/blob/master/assets/images/blog.gif) 5 | ## 安装 6 | 7 | ``` 8 | git clone https://github.com/beijing-xiaotinghua/layBlog-ui.git 9 | ``` 10 | 安装包依赖 11 | ``` 12 | npm install 13 | ``` 14 | 使用cnpm安装包依赖更快,首先安装cnpm 15 | ``` 16 | npm install -g cnpm --registry=https://registry.npm.taobao.org 17 | cnpm install 18 | ``` 19 | ## 运行 20 | 运行发开环境 21 | ```js 22 | npm run dev 23 | ``` 24 | **本地访问http://localhost:3000** 25 | ## 打包部署,打包部署必须在服务器端 26 | **首先打包编译项目** 27 | ```js 28 | npm run build 29 | ``` 30 | **运行项目** 31 | ```js 32 | npm run start 33 | ``` 34 | 35 | **建议使用pm2管理npm进程** 36 | #### 安装pm2 37 | ``` 38 | cnpm install -g pm2 39 | 40 | ``` 41 | #### pm2运行项目 42 | 执行时确保已经在项目根目录 43 | ``` 44 | pm2 start ./node_modules/nuxt/bin/nuxt -- start 45 | ``` 46 | #### 如何在同一个服务器上运行两个node进程 47 | 48 | 开启新的端口 49 | 50 | ``` 51 | pm2 start ./node_modules/nuxt/bin/nuxt --name 'layblog' -- --hostname localhost --port 3001 52 | ``` 53 | #### pm2查看项目列表 54 | ``` 55 | pm2 list 56 | ``` 57 | #### pm2关闭项目 58 | ``` 59 | pm2 stop id 60 | ``` 61 | #### pm2启动项目 62 | ``` 63 | pm2 start id 64 | ``` 65 | ## 在真实的服务器环境中运行项目 66 | 67 | 配置nginx反向代理 68 | 69 | ``` 70 | server { 71 | listen 80; 72 | server_name your domain; 73 | root /var/www/html/layadmin-blog-ui; 74 | index index.php index.html index.htm; 75 | location / { 76 | proxy_pass http://127.0.0.1:3000; 77 | } 78 | } 79 | ``` 80 | 以上只是能够确保运行的简洁配置,生产环境中根据需要自行增加配置 81 | 82 | ## 功能说明 83 | 84 | - 使用nuxt.js做服务端渲染ssr. 85 | - 使用element-ui 组件库. 86 | - 使用axios网络请求库 87 | - 使用了layui前端css样式 88 | - 使用了短信验证码登陆、注册 89 | - 实现了评论、点赞功能 90 | 91 | ## 线上服务预览 92 | 93 | See [layBlog-ui](https://bw31d.com "layBlog-ui"). 94 | 95 | ## 本地后端接口配置 96 | 修改`nuxt.config.js`文件, 根据需要修改你的接口地址 97 | ```javascript 98 | proxy: [ 99 | ['/api', { target: 'http://api.bw31d.com' }] 100 | ] 101 | ``` 102 | 修改`plugins/axios.js`文件 103 | ```javascript 104 | if (process.server) { 105 | options.baseURL = 'http://api.bw31d.com' 106 | } 107 | ``` 108 | ## 后台管理系统截图 109 | ![image](https://github.com/beijing-xiaotinghua/layBlog-ui/blob/master/assets/images/WechatIMG6.jpeg) 110 | ![image](https://github.com/beijing-xiaotinghua/layBlog-ui/blob/master/assets/images/WechatIMG8.jpeg) 111 | 112 | ## 加qq群大家一起交流 113 | 114 | ![image](https://github.com/beijing-xiaotinghua/layBlog-ui/blob/master/assets/images/WechatIMG2.jpeg) 115 | 116 | ## 需要后端接口代码和后台管理系统联系作者 117 | 118 | ![image](https://github.com/beijing-xiaotinghua/layBlog-ui/blob/master/assets/images/weixin.jpeg) 119 | 120 | ## 授权说明 121 | 此项目仅供参考学习,商业用途,请联系作者授权,此源码禁止传播。 122 | 123 | ## 下一步开发计划 124 | 1. 关注功能 125 | 2. 私信功能 126 | 3. 加入es搜索引擎,提供全文检索功能 127 | 128 | -------------------------------------------------------------------------------- /assets/gitment/icons.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | /** 7 | * Modified from https://github.com/evil-icons/evil-icons 8 | */ 9 | 10 | var close = exports.close = ''; 11 | var github = exports.github = ''; 12 | var heart = exports.heart = ''; 13 | var spinner = exports.spinner = ''; 14 | //# sourceMappingURL=icons.js.map -------------------------------------------------------------------------------- /assets/gitment/icons.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/icons.js"],"names":["close","github","heart","spinner"],"mappings":";;;;;AAAA;;;;AAIO,IAAMA,wBAAQ,gOAAd;AACA,IAAMC,0BAAS,0jBAAf;AACA,IAAMC,wBAAQ,iYAAd;AACA,IAAMC,4BAAU,48CAAhB","file":"icons.js","sourcesContent":["/**\n * Modified from https://github.com/evil-icons/evil-icons\n */\n\nexport const close = ''\nexport const github = ''\nexport const heart = ''\nexport const spinner = ''\n"]} -------------------------------------------------------------------------------- /pages/user/login.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | -------------------------------------------------------------------------------- /components/FlashArticleList.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 111 | 112 | 141 | -------------------------------------------------------------------------------- /assets/gitment/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.http = exports.Query = exports.isString = undefined; 7 | 8 | var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); 9 | 10 | exports.getTargetContainer = getTargetContainer; 11 | 12 | var _constants = require('./constants'); 13 | 14 | var isString = exports.isString = function isString(s) { 15 | return toString.call(s) === '[object String]'; 16 | }; 17 | 18 | function getTargetContainer(container) { 19 | var targetContainer = void 0; 20 | if (container instanceof Element) { 21 | targetContainer = container; 22 | } else if (isString(container)) { 23 | targetContainer = document.getElementById(container); 24 | } else { 25 | targetContainer = document.createElement('div'); 26 | } 27 | 28 | return targetContainer; 29 | } 30 | 31 | var Query = exports.Query = { 32 | parse: function parse() { 33 | var search = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.location.search; 34 | 35 | if (!search) return {}; 36 | var queryString = search[0] === '?' ? search.substring(1) : search; 37 | var query = {}; 38 | queryString.split('&').forEach(function (queryStr) { 39 | var _queryStr$split = queryStr.split('='), 40 | _queryStr$split2 = _slicedToArray(_queryStr$split, 2), 41 | key = _queryStr$split2[0], 42 | value = _queryStr$split2[1]; 43 | 44 | if (key) query[key] = value; 45 | }); 46 | 47 | return query; 48 | }, 49 | stringify: function stringify(query) { 50 | var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '?'; 51 | 52 | var queryString = Object.keys(query).map(function (key) { 53 | return key + '=' + encodeURIComponent(query[key] || ''); 54 | }).join('&'); 55 | return queryString ? prefix + queryString : ''; 56 | } 57 | }; 58 | 59 | function ajaxFactory(method) { 60 | return function (apiPath) { 61 | var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 62 | var base = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'https://api.github.com'; 63 | 64 | var req = new XMLHttpRequest(); 65 | var token = localStorage.getItem(_constants.LS_ACCESS_TOKEN_KEY); 66 | 67 | var url = '' + base + apiPath; 68 | var body = null; 69 | if (method === 'GET' || method === 'DELETE') { 70 | url += Query.stringify(data); 71 | } 72 | 73 | var p = new Promise(function (resolve, reject) { 74 | req.addEventListener('load', function () { 75 | var contentType = req.getResponseHeader('content-type'); 76 | var res = req.responseText; 77 | if (!/json/.test(contentType)) { 78 | resolve(res); 79 | return; 80 | } 81 | var data = req.responseText ? JSON.parse(res) : {}; 82 | if (data.message) { 83 | reject(new Error(data.message)); 84 | } else { 85 | resolve(data); 86 | } 87 | }); 88 | req.addEventListener('error', function (error) { 89 | return reject(error); 90 | }); 91 | }); 92 | req.open(method, url, true); 93 | 94 | req.setRequestHeader('Accept', 'application/vnd.github.squirrel-girl-preview, application/vnd.github.html+json'); 95 | if (token) { 96 | req.setRequestHeader('Authorization', 'token ' + token); 97 | } 98 | if (method !== 'GET' && method !== 'DELETE') { 99 | body = JSON.stringify(data); 100 | req.setRequestHeader('Content-Type', 'application/json'); 101 | } 102 | 103 | req.send(body); 104 | return p; 105 | }; 106 | } 107 | 108 | var http = exports.http = { 109 | get: ajaxFactory('GET'), 110 | post: ajaxFactory('POST'), 111 | delete: ajaxFactory('DELETE'), 112 | put: ajaxFactory('PUT') 113 | }; 114 | //# sourceMappingURL=utils.js.map -------------------------------------------------------------------------------- /pages/user/register.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 65 | 139 | -------------------------------------------------------------------------------- /pages/_tag.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 137 | 138 | 156 | -------------------------------------------------------------------------------- /pages/index.vue: -------------------------------------------------------------------------------- 1 | 23 | 145 | 146 | 151 | -------------------------------------------------------------------------------- /components/Comment.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 50 | 51 | 52 | 228 | -------------------------------------------------------------------------------- /pages/flash.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 141 | 142 | 160 | -------------------------------------------------------------------------------- /pages/user/find-password.vue: -------------------------------------------------------------------------------- 1 | 54 | 55 | -------------------------------------------------------------------------------- /pages/user/_id.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 154 | 155 | 173 | -------------------------------------------------------------------------------- /pages/flashnews/_id.vue: -------------------------------------------------------------------------------- 1 | 46 | 47 | 161 | 162 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /assets/gitment/utils.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/utils.js"],"names":["getTargetContainer","isString","toString","call","s","container","targetContainer","Element","document","getElementById","createElement","Query","parse","search","window","location","queryString","substring","query","split","forEach","queryStr","key","value","stringify","prefix","Object","keys","map","encodeURIComponent","join","ajaxFactory","method","apiPath","data","base","req","XMLHttpRequest","token","localStorage","getItem","url","body","p","Promise","resolve","reject","addEventListener","contentType","getResponseHeader","res","responseText","test","JSON","message","Error","error","open","setRequestHeader","send","http","get","post","delete","put"],"mappings":";;;;;;;;;QAIgBA,kB,GAAAA,kB;;AAJhB;;AAEO,IAAMC,8BAAW,SAAXA,QAAW;AAAA,SAAKC,SAASC,IAAT,CAAcC,CAAd,MAAqB,iBAA1B;AAAA,CAAjB;;AAEA,SAASJ,kBAAT,CAA4BK,SAA5B,EAAuC;AAC5C,MAAIC,wBAAJ;AACA,MAAID,qBAAqBE,OAAzB,EAAkC;AAChCD,sBAAkBD,SAAlB;AACD,GAFD,MAEO,IAAIJ,SAASI,SAAT,CAAJ,EAAyB;AAC9BC,sBAAkBE,SAASC,cAAT,CAAwBJ,SAAxB,CAAlB;AACD,GAFM,MAEA;AACLC,sBAAkBE,SAASE,aAAT,CAAuB,KAAvB,CAAlB;AACD;;AAED,SAAOJ,eAAP;AACD;;AAEM,IAAMK,wBAAQ;AACnBC,OADmB,mBACoB;AAAA,QAAjCC,MAAiC,uEAAxBC,OAAOC,QAAP,CAAgBF,MAAQ;;AACrC,QAAI,CAACA,MAAL,EAAa,OAAO,EAAP;AACb,QAAMG,cAAcH,OAAO,CAAP,MAAc,GAAd,GAAoBA,OAAOI,SAAP,CAAiB,CAAjB,CAApB,GAA0CJ,MAA9D;AACA,QAAMK,QAAQ,EAAd;AACAF,gBAAYG,KAAZ,CAAkB,GAAlB,EACGC,OADH,CACW,oBAAY;AAAA,4BACEC,SAASF,KAAT,CAAe,GAAf,CADF;AAAA;AAAA,UACZG,GADY;AAAA,UACPC,KADO;;AAEnB,UAAID,GAAJ,EAASJ,MAAMI,GAAN,IAAaC,KAAb;AACV,KAJH;;AAMA,WAAOL,KAAP;AACD,GAZkB;AAanBM,WAbmB,qBAaTN,KAbS,EAaY;AAAA,QAAdO,MAAc,uEAAL,GAAK;;AAC7B,QAAMT,cAAcU,OAAOC,IAAP,CAAYT,KAAZ,EACjBU,GADiB,CACb;AAAA,aAAUN,GAAV,SAAiBO,mBAAmBX,MAAMI,GAAN,KAAc,EAAjC,CAAjB;AAAA,KADa,EAEjBQ,IAFiB,CAEZ,GAFY,CAApB;AAGA,WAAOd,cAAcS,SAAST,WAAvB,GAAqC,EAA5C;AACD;AAlBkB,CAAd;;AAqBP,SAASe,WAAT,CAAqBC,MAArB,EAA6B;AAC3B,SAAO,UAASC,OAAT,EAA8D;AAAA,QAA5CC,IAA4C,uEAArC,EAAqC;AAAA,QAAjCC,IAAiC,uEAA1B,wBAA0B;;AACnE,QAAMC,MAAM,IAAIC,cAAJ,EAAZ;AACA,QAAMC,QAAQC,aAAaC,OAAb,gCAAd;;AAEA,QAAIC,WAASN,IAAT,GAAgBF,OAApB;AACA,QAAIS,OAAO,IAAX;AACA,QAAIV,WAAW,KAAX,IAAoBA,WAAW,QAAnC,EAA6C;AAC3CS,aAAO9B,MAAMa,SAAN,CAAgBU,IAAhB,CAAP;AACD;;AAED,QAAMS,IAAI,IAAIC,OAAJ,CAAY,UAACC,OAAD,EAAUC,MAAV,EAAqB;AACzCV,UAAIW,gBAAJ,CAAqB,MAArB,EAA6B,YAAM;AACjC,YAAMC,cAAcZ,IAAIa,iBAAJ,CAAsB,cAAtB,CAApB;AACA,YAAMC,MAAMd,IAAIe,YAAhB;AACA,YAAI,CAAC,OAAOC,IAAP,CAAYJ,WAAZ,CAAL,EAA+B;AAC7BH,kBAAQK,GAAR;AACA;AACD;AACD,YAAMhB,OAAOE,IAAIe,YAAJ,GAAmBE,KAAKzC,KAAL,CAAWsC,GAAX,CAAnB,GAAqC,EAAlD;AACA,YAAIhB,KAAKoB,OAAT,EAAkB;AAChBR,iBAAO,IAAIS,KAAJ,CAAUrB,KAAKoB,OAAf,CAAP;AACD,SAFD,MAEO;AACLT,kBAAQX,IAAR;AACD;AACF,OAbD;AAcAE,UAAIW,gBAAJ,CAAqB,OAArB,EAA8B;AAAA,eAASD,OAAOU,KAAP,CAAT;AAAA,OAA9B;AACD,KAhBS,CAAV;AAiBApB,QAAIqB,IAAJ,CAASzB,MAAT,EAAiBS,GAAjB,EAAsB,IAAtB;;AAEAL,QAAIsB,gBAAJ,CAAqB,QAArB,EAA+B,gFAA/B;AACA,QAAIpB,KAAJ,EAAW;AACTF,UAAIsB,gBAAJ,CAAqB,eAArB,aAA+CpB,KAA/C;AACD;AACD,QAAIN,WAAW,KAAX,IAAoBA,WAAW,QAAnC,EAA6C;AAC3CU,aAAOW,KAAK7B,SAAL,CAAeU,IAAf,CAAP;AACAE,UAAIsB,gBAAJ,CAAqB,cAArB,EAAqC,kBAArC;AACD;;AAEDtB,QAAIuB,IAAJ,CAASjB,IAAT;AACA,WAAOC,CAAP;AACD,GAxCD;AAyCD;;AAEM,IAAMiB,sBAAO;AAClBC,OAAK9B,YAAY,KAAZ,CADa;AAElB+B,QAAM/B,YAAY,MAAZ,CAFY;AAGlBgC,UAAQhC,YAAY,QAAZ,CAHU;AAIlBiC,OAAKjC,YAAY,KAAZ;AAJa,CAAb","file":"utils.js","sourcesContent":["import { LS_ACCESS_TOKEN_KEY } from './constants'\n\nexport const isString = s => toString.call(s) === '[object String]'\n\nexport function getTargetContainer(container) {\n let targetContainer\n if (container instanceof Element) {\n targetContainer = container\n } else if (isString(container)) {\n targetContainer = document.getElementById(container)\n } else {\n targetContainer = document.createElement('div')\n }\n\n return targetContainer\n}\n\nexport const Query = {\n parse(search = window.location.search) {\n if (!search) return {}\n const queryString = search[0] === '?' ? search.substring(1) : search\n const query = {}\n queryString.split('&')\n .forEach(queryStr => {\n const [key, value] = queryStr.split('=')\n if (key) query[key] = value\n })\n\n return query\n },\n stringify(query, prefix = '?') {\n const queryString = Object.keys(query)\n .map(key => `${key}=${encodeURIComponent(query[key] || '')}`)\n .join('&')\n return queryString ? prefix + queryString : ''\n },\n}\n\nfunction ajaxFactory(method) {\n return function(apiPath, data = {}, base = 'https://api.github.com') {\n const req = new XMLHttpRequest()\n const token = localStorage.getItem(LS_ACCESS_TOKEN_KEY)\n\n let url = `${base}${apiPath}`\n let body = null\n if (method === 'GET' || method === 'DELETE') {\n url += Query.stringify(data)\n }\n\n const p = new Promise((resolve, reject) => {\n req.addEventListener('load', () => {\n const contentType = req.getResponseHeader('content-type')\n const res = req.responseText\n if (!/json/.test(contentType)) {\n resolve(res)\n return\n }\n const data = req.responseText ? JSON.parse(res) : {}\n if (data.message) {\n reject(new Error(data.message))\n } else {\n resolve(data)\n }\n })\n req.addEventListener('error', error => reject(error))\n })\n req.open(method, url, true)\n\n req.setRequestHeader('Accept', 'application/vnd.github.squirrel-girl-preview, application/vnd.github.html+json')\n if (token) {\n req.setRequestHeader('Authorization', `token ${token}`)\n }\n if (method !== 'GET' && method !== 'DELETE') {\n body = JSON.stringify(data)\n req.setRequestHeader('Content-Type', 'application/json')\n }\n\n req.send(body)\n return p\n }\n}\n\nexport const http = {\n get: ajaxFactory('GET'),\n post: ajaxFactory('POST'),\n delete: ajaxFactory('DELETE'),\n put: ajaxFactory('PUT'),\n}\n"]} -------------------------------------------------------------------------------- /assets/gitment/gitment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 4 | 5 | var _mobx = require('mobx'); 6 | 7 | var _constants = require('./constants'); 8 | 9 | var _utils = require('./utils'); 10 | 11 | var _default = require('./theme/default'); 12 | 13 | var _default2 = _interopRequireDefault(_default); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 18 | 19 | var scope = 'public_repo'; 20 | 21 | function extendRenderer(instance, renderer) { 22 | instance[renderer] = function (container) { 23 | var targetContainer = (0, _utils.getTargetContainer)(container); 24 | var render = instance.theme[renderer] || instance.defaultTheme[renderer]; 25 | 26 | (0, _mobx.autorun)(function () { 27 | var e = render(instance.state, instance); 28 | if (targetContainer.firstChild) { 29 | targetContainer.replaceChild(e, targetContainer.firstChild); 30 | } else { 31 | targetContainer.appendChild(e); 32 | } 33 | }); 34 | 35 | return targetContainer; 36 | }; 37 | } 38 | 39 | var Gitment = function () { 40 | _createClass(Gitment, [{ 41 | key: 'accessToken', 42 | get: function get() { 43 | return localStorage.getItem(_constants.LS_ACCESS_TOKEN_KEY); 44 | }, 45 | set: function set(token) { 46 | localStorage.setItem(_constants.LS_ACCESS_TOKEN_KEY, token); 47 | } 48 | }, { 49 | key: 'loginLink', 50 | get: function get() { 51 | var oauthUri = 'https://github.com/login/oauth/authorize'; 52 | var redirect_uri = this.oauth.redirect_uri || window.location.href; 53 | 54 | var oauthParams = Object.assign({ 55 | scope: scope, 56 | redirect_uri: redirect_uri 57 | }, this.oauth); 58 | 59 | return '' + oauthUri + _utils.Query.stringify(oauthParams); 60 | } 61 | }]); 62 | 63 | function Gitment() { 64 | var _this = this; 65 | 66 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 67 | 68 | _classCallCheck(this, Gitment); 69 | 70 | this.defaultTheme = _default2.default; 71 | this.useTheme(_default2.default); 72 | 73 | Object.assign(this, { 74 | id: window.location.href, 75 | title: window.document.title, 76 | link: window.location.href, 77 | desc: '', 78 | labels: [], 79 | theme: _default2.default, 80 | oauth: {}, 81 | perPage: 20, 82 | maxCommentHeight: 250 83 | }, options); 84 | 85 | this.useTheme(this.theme); 86 | 87 | var user = {}; 88 | try { 89 | var userInfo = localStorage.getItem(_constants.LS_USER_KEY); 90 | if (this.accessToken && userInfo) { 91 | Object.assign(user, JSON.parse(userInfo), { 92 | fromCache: true 93 | }); 94 | } 95 | } catch (e) { 96 | localStorage.removeItem(_constants.LS_USER_KEY); 97 | } 98 | 99 | this.state = (0, _mobx.observable)({ 100 | user: user, 101 | error: null, 102 | meta: {}, 103 | comments: undefined, 104 | reactions: [], 105 | commentReactions: {}, 106 | currentPage: 1 107 | }); 108 | 109 | var query = _utils.Query.parse(); 110 | if (query.code) { 111 | var _oauth = this.oauth, 112 | client_id = _oauth.client_id, 113 | client_secret = _oauth.client_secret; 114 | 115 | var code = query.code; 116 | delete query.code; 117 | var search = _utils.Query.stringify(query); 118 | var replacedUrl = '' + window.location.origin + window.location.pathname + search + window.location.hash; 119 | history.replaceState({}, '', replacedUrl); 120 | 121 | Object.assign(this, { 122 | id: replacedUrl, 123 | link: replacedUrl 124 | }, options); 125 | 126 | this.state.user.isLoggingIn = true; 127 | _utils.http.post('https://gh-oauth.imsun.net', { 128 | code: code, 129 | client_id: client_id, 130 | client_secret: client_secret 131 | }, '').then(function (data) { 132 | _this.accessToken = data.access_token; 133 | _this.update(); 134 | }).catch(function (e) { 135 | _this.state.user.isLoggingIn = false; 136 | alert(e); 137 | }); 138 | } else { 139 | this.update(); 140 | } 141 | } 142 | 143 | _createClass(Gitment, [{ 144 | key: 'init', 145 | value: function init() { 146 | var _this2 = this; 147 | 148 | return this.createIssue().then(function () { 149 | return _this2.loadComments(); 150 | }).then(function (comments) { 151 | _this2.state.error = null; 152 | return comments; 153 | }); 154 | } 155 | }, { 156 | key: 'useTheme', 157 | value: function useTheme() { 158 | var _this3 = this; 159 | 160 | var theme = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 161 | 162 | this.theme = theme; 163 | 164 | var renderers = Object.keys(this.theme); 165 | renderers.forEach(function (renderer) { 166 | return extendRenderer(_this3, renderer); 167 | }); 168 | } 169 | }, { 170 | key: 'update', 171 | value: function update() { 172 | var _this4 = this; 173 | 174 | return Promise.all([this.loadMeta(), this.loadUserInfo()]).then(function () { 175 | return Promise.all([_this4.loadComments().then(function () { 176 | return _this4.loadCommentReactions(); 177 | }), _this4.loadReactions()]); 178 | }).catch(function (e) { 179 | return _this4.state.error = e; 180 | }); 181 | } 182 | }, { 183 | key: 'markdown', 184 | value: function markdown(text) { 185 | return _utils.http.post('/markdown', { 186 | text: text, 187 | mode: 'gfm' 188 | }); 189 | } 190 | }, { 191 | key: 'createIssue', 192 | value: function createIssue() { 193 | var _this5 = this; 194 | 195 | var id = this.id, 196 | owner = this.owner, 197 | repo = this.repo, 198 | title = this.title, 199 | link = this.link, 200 | desc = this.desc, 201 | labels = this.labels; 202 | 203 | 204 | return _utils.http.post('/repos/' + owner + '/' + repo + '/issues', { 205 | title: title, 206 | labels: labels.concat(['gitment', id]), 207 | body: link + '\n\n' + desc 208 | }).then(function (meta) { 209 | _this5.state.meta = meta; 210 | return meta; 211 | }); 212 | } 213 | }, { 214 | key: 'getIssue', 215 | value: function getIssue() { 216 | if (this.state.meta.id) return Promise.resolve(this.state.meta); 217 | 218 | return this.loadMeta(); 219 | } 220 | }, { 221 | key: 'post', 222 | value: function post(body) { 223 | var _this6 = this; 224 | 225 | return this.getIssue().then(function (issue) { 226 | return _utils.http.post(issue.comments_url, { body: body }, ''); 227 | }).then(function (data) { 228 | _this6.state.meta.comments++; 229 | var pageCount = Math.ceil(_this6.state.meta.comments / _this6.perPage); 230 | if (_this6.state.currentPage === pageCount) { 231 | _this6.state.comments.push(data); 232 | } 233 | return data; 234 | }); 235 | } 236 | }, { 237 | key: 'loadMeta', 238 | value: function loadMeta() { 239 | var _this7 = this; 240 | 241 | var id = this.id, 242 | owner = this.owner, 243 | repo = this.repo; 244 | 245 | return _utils.http.get('/repos/' + owner + '/' + repo + '/issues', { 246 | creator: owner, 247 | labels: id 248 | }).then(function (issues) { 249 | if (!issues.length) return Promise.reject(_constants.NOT_INITIALIZED_ERROR); 250 | _this7.state.meta = issues[0]; 251 | return issues[0]; 252 | }); 253 | } 254 | }, { 255 | key: 'loadComments', 256 | value: function loadComments() { 257 | var _this8 = this; 258 | 259 | var page = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state.currentPage; 260 | 261 | return this.getIssue().then(function (issue) { 262 | return _utils.http.get(issue.comments_url, { page: page, per_page: _this8.perPage }, ''); 263 | }).then(function (comments) { 264 | _this8.state.comments = comments; 265 | return comments; 266 | }); 267 | } 268 | }, { 269 | key: 'loadUserInfo', 270 | value: function loadUserInfo() { 271 | var _this9 = this; 272 | 273 | if (!this.accessToken) { 274 | this.logout(); 275 | return Promise.resolve({}); 276 | } 277 | 278 | return _utils.http.get('/user').then(function (user) { 279 | _this9.state.user = user; 280 | localStorage.setItem(_constants.LS_USER_KEY, JSON.stringify(user)); 281 | return user; 282 | }); 283 | } 284 | }, { 285 | key: 'loadReactions', 286 | value: function loadReactions() { 287 | var _this10 = this; 288 | 289 | if (!this.accessToken) { 290 | this.state.reactions = []; 291 | return Promise.resolve([]); 292 | } 293 | 294 | return this.getIssue().then(function (issue) { 295 | if (!issue.reactions.total_count) return []; 296 | return _utils.http.get(issue.reactions.url, {}, ''); 297 | }).then(function (reactions) { 298 | _this10.state.reactions = reactions; 299 | return reactions; 300 | }); 301 | } 302 | }, { 303 | key: 'loadCommentReactions', 304 | value: function loadCommentReactions() { 305 | var _this11 = this; 306 | 307 | if (!this.accessToken) { 308 | this.state.commentReactions = {}; 309 | return Promise.resolve([]); 310 | } 311 | 312 | var comments = this.state.comments; 313 | var comentReactions = {}; 314 | 315 | return Promise.all(comments.map(function (comment) { 316 | if (!comment.reactions.total_count) return []; 317 | 318 | var owner = _this11.owner, 319 | repo = _this11.repo; 320 | 321 | return _utils.http.get('/repos/' + owner + '/' + repo + '/issues/comments/' + comment.id + '/reactions', {}); 322 | })).then(function (reactionsArray) { 323 | comments.forEach(function (comment, index) { 324 | comentReactions[comment.id] = reactionsArray[index]; 325 | }); 326 | _this11.state.commentReactions = comentReactions; 327 | 328 | return comentReactions; 329 | }); 330 | } 331 | }, { 332 | key: 'login', 333 | value: function login() { 334 | window.location.href = this.loginLink; 335 | } 336 | }, { 337 | key: 'logout', 338 | value: function logout() { 339 | localStorage.removeItem(_constants.LS_ACCESS_TOKEN_KEY); 340 | localStorage.removeItem(_constants.LS_USER_KEY); 341 | this.state.user = {}; 342 | } 343 | }, { 344 | key: 'goto', 345 | value: function goto(page) { 346 | this.state.currentPage = page; 347 | this.state.comments = undefined; 348 | return this.loadComments(page); 349 | } 350 | }, { 351 | key: 'like', 352 | value: function like() { 353 | var _this12 = this; 354 | 355 | if (!this.accessToken) { 356 | alert('Login to Like'); 357 | return Promise.reject(); 358 | } 359 | 360 | var owner = this.owner, 361 | repo = this.repo; 362 | 363 | 364 | return _utils.http.post('/repos/' + owner + '/' + repo + '/issues/' + this.state.meta.number + '/reactions', { 365 | content: 'heart' 366 | }).then(function (reaction) { 367 | _this12.state.reactions.push(reaction); 368 | _this12.state.meta.reactions.heart++; 369 | }); 370 | } 371 | }, { 372 | key: 'unlike', 373 | value: function unlike() { 374 | var _this13 = this; 375 | 376 | if (!this.accessToken) return Promise.reject(); 377 | 378 | var _state = this.state, 379 | user = _state.user, 380 | reactions = _state.reactions; 381 | 382 | var index = reactions.findIndex(function (reaction) { 383 | return reaction.user.login === user.login; 384 | }); 385 | return _utils.http.delete('/reactions/' + reactions[index].id).then(function () { 386 | reactions.splice(index, 1); 387 | _this13.state.meta.reactions.heart--; 388 | }); 389 | } 390 | }, { 391 | key: 'likeAComment', 392 | value: function likeAComment(commentId) { 393 | var _this14 = this; 394 | 395 | if (!this.accessToken) { 396 | alert('Login to Like'); 397 | return Promise.reject(); 398 | } 399 | 400 | var owner = this.owner, 401 | repo = this.repo; 402 | 403 | var comment = this.state.comments.find(function (comment) { 404 | return comment.id === commentId; 405 | }); 406 | 407 | return _utils.http.post('/repos/' + owner + '/' + repo + '/issues/comments/' + commentId + '/reactions', { 408 | content: 'heart' 409 | }).then(function (reaction) { 410 | _this14.state.commentReactions[commentId].push(reaction); 411 | comment.reactions.heart++; 412 | }); 413 | } 414 | }, { 415 | key: 'unlikeAComment', 416 | value: function unlikeAComment(commentId) { 417 | if (!this.accessToken) return Promise.reject(); 418 | 419 | var reactions = this.state.commentReactions[commentId]; 420 | var comment = this.state.comments.find(function (comment) { 421 | return comment.id === commentId; 422 | }); 423 | var user = this.state.user; 424 | 425 | var index = reactions.findIndex(function (reaction) { 426 | return reaction.user.login === user.login; 427 | }); 428 | 429 | return _utils.http.delete('/reactions/' + reactions[index].id).then(function () { 430 | reactions.splice(index, 1); 431 | comment.reactions.heart--; 432 | }); 433 | } 434 | }]); 435 | 436 | return Gitment; 437 | }(); 438 | 439 | module.exports = Gitment; 440 | //# sourceMappingURL=gitment.js.map -------------------------------------------------------------------------------- /pages/details/_id.vue: -------------------------------------------------------------------------------- 1 | 141 | 142 | 428 | 429 | 437 | -------------------------------------------------------------------------------- /assets/font/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Created by iconfont 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /static/css/layui-mobile.css: -------------------------------------------------------------------------------- 1 | /** layui-v2.4.5 MIT License By https://www.layui.com */ 2 | blockquote, 3 | body, 4 | button, 5 | dd, 6 | div, 7 | dl, 8 | dt, 9 | form, 10 | h1, 11 | h2, 12 | h3, 13 | h4, 14 | h5, 15 | h6, 16 | input, 17 | legend, 18 | li, 19 | ol, 20 | p, 21 | td, 22 | textarea, 23 | th, 24 | ul { 25 | margin: 0; 26 | padding: 0; 27 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0) 28 | } 29 | 30 | html { 31 | font: 12px 'Helvetica Neue', 'PingFang SC', STHeitiSC-Light, Helvetica, Arial, sans-serif; 32 | -ms-text-size-adjust: 100%; 33 | -webkit-text-size-adjust: 100% 34 | } 35 | 36 | a, 37 | button, 38 | input { 39 | -webkit-tap-highlight-color: rgba(255, 0, 0, 0) 40 | } 41 | 42 | a { 43 | text-decoration: none; 44 | background: 0 0 45 | } 46 | 47 | a:active, 48 | a:hover { 49 | outline: 0 50 | } 51 | 52 | table { 53 | border-collapse: collapse; 54 | border-spacing: 0 55 | } 56 | 57 | li { 58 | list-style: none 59 | } 60 | 61 | b, 62 | strong { 63 | font-weight: 700 64 | } 65 | 66 | h1, 67 | h2, 68 | h3, 69 | h4, 70 | h5, 71 | h6 { 72 | font-weight: 500 73 | } 74 | 75 | address, 76 | cite, 77 | dfn, 78 | em, 79 | var { 80 | font-style: normal 81 | } 82 | 83 | dfn { 84 | font-style: italic 85 | } 86 | 87 | sub, 88 | sup { 89 | font-size: 75%; 90 | line-height: 0; 91 | position: relative; 92 | vertical-align: baseline 93 | } 94 | 95 | img { 96 | border: 0; 97 | vertical-align: bottom 98 | } 99 | 100 | .layui-inline, 101 | input, 102 | label { 103 | vertical-align: middle 104 | } 105 | 106 | button, 107 | input, 108 | optgroup, 109 | select, 110 | textarea { 111 | color: inherit; 112 | font: inherit; 113 | margin: 0; 114 | outline: 0 115 | } 116 | 117 | button, 118 | select { 119 | text-transform: none 120 | } 121 | 122 | select { 123 | -webkit-appearance: none; 124 | border: none 125 | } 126 | 127 | input { 128 | line-height: normal 129 | } 130 | 131 | input[type=checkbox], 132 | input[type=radio] { 133 | box-sizing: border-box; 134 | padding: 0 135 | } 136 | 137 | input[type=number]::-webkit-inner-spin-button, 138 | input[type=number]::-webkit-outer-spin-button { 139 | height: auto 140 | } 141 | 142 | input[type=search] { 143 | -webkit-appearance: textfield; 144 | -moz-box-sizing: content-box; 145 | -webkit-box-sizing: content-box; 146 | box-sizing: content-box 147 | } 148 | 149 | input[type=search]::-webkit-search-cancel-button, 150 | input[type=search]::-webkit-search-decoration { 151 | -webkit-appearance: none 152 | } 153 | /* 154 | @font-face { 155 | font-family: layui-icon; 156 | src: url(@/static/font/iconfont.eot); 157 | src: url(@/static/font/iconfont.eot) format('embedded-opentype'), url(@/static/font/iconfont.woff) format('woff'), url(@/static/font/iconfont.ttf) format('truetype'), url(@/static/font/iconfont.svg) format('svg') 158 | } */ 159 | 160 | .layui-icon { 161 | font-family: layui-icon !important; 162 | font-size: 16px; 163 | font-style: normal; 164 | -webkit-font-smoothing: antialiased; 165 | -moz-osx-font-smoothing: grayscale 166 | } 167 | 168 | .layui-box, 169 | .layui-box * { 170 | -webkit-box-sizing: content-box !important; 171 | -moz-box-sizing: content-box !important; 172 | box-sizing: content-box !important 173 | } 174 | 175 | .layui-border-box, 176 | .layui-border-box * { 177 | -webkit-box-sizing: border-box !important; 178 | -moz-box-sizing: border-box !important; 179 | box-sizing: border-box !important 180 | } 181 | 182 | .layui-inline { 183 | position: relative; 184 | display: inline-block; 185 | *display: inline; 186 | *zoom: 1 187 | } 188 | 189 | .layui-edge, 190 | .layui-upload-iframe { 191 | position: absolute; 192 | width: 0; 193 | height: 0 194 | } 195 | 196 | .layui-edge { 197 | border-style: dashed; 198 | border-color: transparent; 199 | overflow: hidden 200 | } 201 | 202 | .layui-elip { 203 | text-overflow: ellipsis; 204 | overflow: hidden; 205 | white-space: nowrap 206 | } 207 | 208 | .layui-unselect { 209 | -moz-user-select: none; 210 | -webkit-user-select: none; 211 | -ms-user-select: none 212 | } 213 | 214 | .layui-disabled, 215 | .layui-disabled:active { 216 | background-color: #d2d2d2 !important; 217 | color: #fff !important; 218 | cursor: not-allowed !important 219 | } 220 | 221 | .layui-circle { 222 | border-radius: 100% 223 | } 224 | 225 | .layui-show { 226 | display: block !important 227 | } 228 | 229 | .layui-hide { 230 | display: none !important 231 | } 232 | 233 | .layui-upload-iframe { 234 | border: 0; 235 | visibility: hidden 236 | } 237 | 238 | .layui-upload-enter { 239 | border: 1px solid #009E94; 240 | background-color: #009E94; 241 | color: #fff; 242 | -webkit-transform: scale(1.1); 243 | transform: scale(1.1) 244 | } 245 | 246 | @-webkit-keyframes layui-m-anim-scale { 247 | 0% { 248 | opacity: 0; 249 | -webkit-transform: scale(.5); 250 | transform: scale(.5) 251 | } 252 | 253 | 100% { 254 | opacity: 1; 255 | -webkit-transform: scale(1); 256 | transform: scale(1) 257 | } 258 | } 259 | 260 | @keyframes layui-m-anim-scale { 261 | 0% { 262 | opacity: 0; 263 | -webkit-transform: scale(.5); 264 | transform: scale(.5) 265 | } 266 | 267 | 100% { 268 | opacity: 1; 269 | -webkit-transform: scale(1); 270 | transform: scale(1) 271 | } 272 | } 273 | 274 | .layui-m-anim-scale { 275 | animation-name: layui-m-anim-scale; 276 | -webkit-animation-name: layui-m-anim-scale 277 | } 278 | 279 | @-webkit-keyframes layui-m-anim-up { 280 | 0% { 281 | opacity: 0; 282 | -webkit-transform: translateY(800px); 283 | transform: translateY(800px) 284 | } 285 | 286 | 100% { 287 | opacity: 1; 288 | -webkit-transform: translateY(0); 289 | transform: translateY(0) 290 | } 291 | } 292 | 293 | @keyframes layui-m-anim-up { 294 | 0% { 295 | opacity: 0; 296 | -webkit-transform: translateY(800px); 297 | transform: translateY(800px) 298 | } 299 | 300 | 100% { 301 | opacity: 1; 302 | -webkit-transform: translateY(0); 303 | transform: translateY(0) 304 | } 305 | } 306 | 307 | .layui-m-anim-up { 308 | -webkit-animation-name: layui-m-anim-up; 309 | animation-name: layui-m-anim-up 310 | } 311 | 312 | @-webkit-keyframes layui-m-anim-left { 313 | 0% { 314 | -webkit-transform: translateX(100%); 315 | transform: translateX(100%) 316 | } 317 | 318 | 100% { 319 | -webkit-transform: translateX(0); 320 | transform: translateX(0) 321 | } 322 | } 323 | 324 | @keyframes layui-m-anim-left { 325 | 0% { 326 | -webkit-transform: translateX(100%); 327 | transform: translateX(100%) 328 | } 329 | 330 | 100% { 331 | -webkit-transform: translateX(0); 332 | transform: translateX(0) 333 | } 334 | } 335 | 336 | .layui-m-anim-left { 337 | -webkit-animation-name: layui-m-anim-left; 338 | animation-name: layui-m-anim-left 339 | } 340 | 341 | @-webkit-keyframes layui-m-anim-right { 342 | 0% { 343 | -webkit-transform: translateX(-100%); 344 | transform: translateX(-100%) 345 | } 346 | 347 | 100% { 348 | -webkit-transform: translateX(0); 349 | transform: translateX(0) 350 | } 351 | } 352 | 353 | @keyframes layui-m-anim-right { 354 | 0% { 355 | -webkit-transform: translateX(-100%); 356 | transform: translateX(-100%) 357 | } 358 | 359 | 100% { 360 | -webkit-transform: translateX(0); 361 | transform: translateX(0) 362 | } 363 | } 364 | 365 | .layui-m-anim-right { 366 | -webkit-animation-name: layui-m-anim-right; 367 | animation-name: layui-m-anim-right 368 | } 369 | 370 | @-webkit-keyframes layui-m-anim-lout { 371 | 0% { 372 | -webkit-transform: translateX(0); 373 | transform: translateX(0) 374 | } 375 | 376 | 100% { 377 | -webkit-transform: translateX(-100%); 378 | transform: translateX(-100%) 379 | } 380 | } 381 | 382 | @keyframes layui-m-anim-lout { 383 | 0% { 384 | -webkit-transform: translateX(0); 385 | transform: translateX(0) 386 | } 387 | 388 | 100% { 389 | -webkit-transform: translateX(-100%); 390 | transform: translateX(-100%) 391 | } 392 | } 393 | 394 | .layui-m-anim-lout { 395 | -webkit-animation-name: layui-m-anim-lout; 396 | animation-name: layui-m-anim-lout 397 | } 398 | 399 | @-webkit-keyframes layui-m-anim-rout { 400 | 0% { 401 | -webkit-transform: translateX(0); 402 | transform: translateX(0) 403 | } 404 | 405 | 100% { 406 | -webkit-transform: translateX(100%); 407 | transform: translateX(100%) 408 | } 409 | } 410 | 411 | @keyframes layui-m-anim-rout { 412 | 0% { 413 | -webkit-transform: translateX(0); 414 | transform: translateX(0) 415 | } 416 | 417 | 100% { 418 | -webkit-transform: translateX(100%); 419 | transform: translateX(100%) 420 | } 421 | } 422 | 423 | .layui-m-anim-rout { 424 | -webkit-animation-name: layui-m-anim-rout; 425 | animation-name: layui-m-anim-rout 426 | } 427 | 428 | .layui-m-layer { 429 | position: relative; 430 | z-index: 19891014 431 | } 432 | 433 | .layui-m-layer * { 434 | -webkit-box-sizing: content-box; 435 | -moz-box-sizing: content-box; 436 | box-sizing: content-box 437 | } 438 | 439 | .layui-m-layermain, 440 | .layui-m-layershade { 441 | position: fixed; 442 | left: 0; 443 | top: 0; 444 | width: 100%; 445 | height: 100% 446 | } 447 | 448 | .layui-m-layershade { 449 | background-color: rgba(0, 0, 0, .7); 450 | pointer-events: auto 451 | } 452 | 453 | .layui-m-layermain { 454 | display: table; 455 | font-family: Helvetica, arial, sans-serif; 456 | pointer-events: none 457 | } 458 | 459 | .layui-m-layermain .layui-m-layersection { 460 | display: table-cell; 461 | vertical-align: middle; 462 | text-align: center 463 | } 464 | 465 | .layui-m-layerchild { 466 | position: relative; 467 | display: inline-block; 468 | text-align: left; 469 | background-color: #fff; 470 | font-size: 14px; 471 | border-radius: 5px; 472 | box-shadow: 0 0 8px rgba(0, 0, 0, .1); 473 | pointer-events: auto; 474 | -webkit-overflow-scrolling: touch; 475 | -webkit-animation-fill-mode: both; 476 | animation-fill-mode: both; 477 | -webkit-animation-duration: .2s; 478 | animation-duration: .2s 479 | } 480 | 481 | .layui-m-layer0 .layui-m-layerchild { 482 | width: 90%; 483 | max-width: 640px 484 | } 485 | 486 | .layui-m-layer1 .layui-m-layerchild { 487 | border: none; 488 | border-radius: 0 489 | } 490 | 491 | .layui-m-layer2 .layui-m-layerchild { 492 | width: auto; 493 | max-width: 260px; 494 | min-width: 40px; 495 | border: none; 496 | background: 0 0; 497 | box-shadow: none; 498 | color: #fff 499 | } 500 | 501 | .layui-m-layerchild h3 { 502 | padding: 0 10px; 503 | height: 60px; 504 | line-height: 60px; 505 | font-size: 16px; 506 | font-weight: 400; 507 | border-radius: 5px 5px 0 0; 508 | text-align: center 509 | } 510 | 511 | .layui-m-layerbtn span, 512 | .layui-m-layerchild h3 { 513 | text-overflow: ellipsis; 514 | overflow: hidden; 515 | white-space: nowrap 516 | } 517 | 518 | .layui-m-layercont { 519 | padding: 50px 30px; 520 | line-height: 22px; 521 | text-align: center 522 | } 523 | 524 | .layui-m-layer1 .layui-m-layercont { 525 | padding: 0; 526 | text-align: left 527 | } 528 | 529 | .layui-m-layer2 .layui-m-layercont { 530 | text-align: center; 531 | padding: 0; 532 | line-height: 0 533 | } 534 | 535 | .layui-m-layer2 .layui-m-layercont i { 536 | width: 25px; 537 | height: 25px; 538 | margin-left: 8px; 539 | display: inline-block; 540 | background-color: #fff; 541 | border-radius: 100%; 542 | -webkit-animation: layui-m-anim-loading 1.4s infinite ease-in-out; 543 | animation: layui-m-anim-loading 1.4s infinite ease-in-out; 544 | -webkit-animation-fill-mode: both; 545 | animation-fill-mode: both 546 | } 547 | 548 | .layui-m-layerbtn, 549 | .layui-m-layerbtn span { 550 | position: relative; 551 | text-align: center; 552 | border-radius: 0 0 5px 5px 553 | } 554 | 555 | .layui-m-layer2 .layui-m-layercont p { 556 | margin-top: 20px 557 | } 558 | 559 | @-webkit-keyframes layui-m-anim-loading { 560 | 561 | 0%, 562 | 100%, 563 | 80% { 564 | transform: scale(0); 565 | -webkit-transform: scale(0) 566 | } 567 | 568 | 40% { 569 | transform: scale(1); 570 | -webkit-transform: scale(1) 571 | } 572 | } 573 | 574 | @keyframes layui-m-anim-loading { 575 | 576 | 0%, 577 | 100%, 578 | 80% { 579 | transform: scale(0); 580 | -webkit-transform: scale(0) 581 | } 582 | 583 | 40% { 584 | transform: scale(1); 585 | -webkit-transform: scale(1) 586 | } 587 | } 588 | 589 | .layui-m-layer2 .layui-m-layercont i:first-child { 590 | margin-left: 0; 591 | -webkit-animation-delay: -.32s; 592 | animation-delay: -.32s 593 | } 594 | 595 | .layui-m-layer2 .layui-m-layercont i.layui-m-layerload { 596 | -webkit-animation-delay: -.16s; 597 | animation-delay: -.16s 598 | } 599 | 600 | .layui-m-layer2 .layui-m-layercont>div { 601 | line-height: 22px; 602 | padding-top: 7px; 603 | margin-bottom: 20px; 604 | font-size: 14px 605 | } 606 | 607 | .layui-m-layerbtn { 608 | display: flex; 609 | display: -moz-box; 610 | display: -webkit-box; 611 | width: 100%; 612 | height: 50px; 613 | line-height: 50px; 614 | font-size: 0; 615 | border-top: 1px solid #D0D0D0; 616 | background-color: #F2F2F2 617 | } 618 | 619 | .layui-m-layerbtn span { 620 | display: block; 621 | -moz-box-flex: 1; 622 | box-flex: 1; 623 | -webkit-box-flex: 1; 624 | font-size: 14px; 625 | cursor: pointer 626 | } 627 | 628 | .layui-m-layerbtn span[yes] { 629 | color: #40AFFE 630 | } 631 | 632 | .layui-m-layerbtn span[no] { 633 | border-right: 1px solid #D0D0D0; 634 | border-radius: 0 0 0 5px 635 | } 636 | 637 | .layui-m-layerbtn span:active { 638 | background-color: #F6F6F6 639 | } 640 | 641 | .layui-m-layerend { 642 | position: absolute; 643 | right: 7px; 644 | top: 10px; 645 | width: 30px; 646 | height: 30px; 647 | border: 0; 648 | font-weight: 400; 649 | background: 0 0; 650 | cursor: pointer; 651 | -webkit-appearance: none; 652 | font-size: 30px 653 | } 654 | 655 | .layui-m-layerend::after, 656 | .layui-m-layerend::before { 657 | position: absolute; 658 | left: 5px; 659 | top: 15px; 660 | content: ''; 661 | width: 18px; 662 | height: 1px; 663 | background-color: #999; 664 | transform: rotate(45deg); 665 | -webkit-transform: rotate(45deg); 666 | border-radius: 3px 667 | } 668 | 669 | .layui-m-layerend::after { 670 | transform: rotate(-45deg); 671 | -webkit-transform: rotate(-45deg) 672 | } 673 | 674 | body .layui-m-layer .layui-m-layer-footer { 675 | position: fixed; 676 | width: 95%; 677 | max-width: 100%; 678 | margin: 0 auto; 679 | left: 0; 680 | right: 0; 681 | bottom: 10px; 682 | background: 0 0 683 | } 684 | 685 | .layui-m-layer-footer .layui-m-layercont { 686 | padding: 20px; 687 | border-radius: 5px 5px 0 0; 688 | background-color: rgba(255, 255, 255, .8) 689 | } 690 | 691 | .layui-m-layer-footer .layui-m-layerbtn { 692 | display: block; 693 | height: auto; 694 | background: 0 0; 695 | border-top: none 696 | } 697 | 698 | .layui-m-layer-footer .layui-m-layerbtn span { 699 | background-color: rgba(255, 255, 255, .8) 700 | } 701 | 702 | .layui-m-layer-footer .layui-m-layerbtn span[no] { 703 | color: #FD482C; 704 | border-top: 1px solid #c2c2c2; 705 | border-radius: 0 0 5px 5px 706 | } 707 | 708 | .layui-m-layer-footer .layui-m-layerbtn span[yes] { 709 | margin-top: 10px; 710 | border-radius: 5px 711 | } 712 | 713 | body .layui-m-layer .layui-m-layer-msg { 714 | width: auto; 715 | max-width: 90%; 716 | margin: 0 auto; 717 | bottom: -150px; 718 | background-color: rgba(0, 0, 0, .7); 719 | color: #fff 720 | } 721 | 722 | .layui-m-layer-msg .layui-m-layercont { 723 | padding: 10px 20px 724 | } 725 | -------------------------------------------------------------------------------- /assets/gitment/theme/default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); 8 | 9 | var _icons = require('../icons'); 10 | 11 | var _constants = require('../constants'); 12 | 13 | var _mobx = require('mobx'); 14 | 15 | Date.prototype.format = function (format) { 16 | var o = { 17 | "M+": this.getMonth() + 1, //month 18 | "d+": this.getDate(), //day 19 | "h+": this.getHours(), //hour 20 | "m+": this.getMinutes(), //minute 21 | "s+": this.getSeconds(), //second 22 | "q+": Math.floor((this.getMonth() + 3) / 3), //quarter 23 | "S": this.getMilliseconds() //millisecond 24 | }; 25 | if (/(y+)/.test(format)) { 26 | format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 27 | } 28 | for (var k in o) { 29 | if (new RegExp("(" + k + ")").test(format)) { 30 | format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)); 31 | } 32 | } 33 | return format; 34 | }; 35 | 36 | function renderHeader(_ref, instance) { 37 | var meta = _ref.meta, 38 | user = _ref.user, 39 | reactions = _ref.reactions; 40 | 41 | var container = document.createElement('div'); 42 | container.lang = "en-US"; 43 | container.className = 'gitment-container gitment-header-container'; 44 | 45 | var likeButton = document.createElement('span'); 46 | var likedReaction = reactions.find(function (reaction) { 47 | return reaction.content === 'heart' && reaction.user.login === user.login; 48 | }); 49 | likeButton.className = 'gitment-header-like-btn'; 50 | likeButton.innerHTML = '\n ' + _icons.heart + '\n ' + (likedReaction ? 'Unlike' : 'Like') + '\n ' + (meta.reactions && meta.reactions.heart ? ' \u2022 ' + meta.reactions.heart + ' Liked' : '') + '\n '; 51 | 52 | if (likedReaction) { 53 | likeButton.classList.add('liked'); 54 | likeButton.onclick = function () { 55 | return instance.unlike(); 56 | }; 57 | } else { 58 | likeButton.classList.remove('liked'); 59 | likeButton.onclick = function () { 60 | return instance.like(); 61 | }; 62 | } 63 | container.appendChild(likeButton); 64 | 65 | var commentsCount = document.createElement('span'); 66 | commentsCount.innerHTML = '\n ' + (meta.comments ? ' \u2022 ' + meta.comments + ' Comments' : '') + '\n '; 67 | container.appendChild(commentsCount); 68 | 69 | var issueLink = document.createElement('a'); 70 | issueLink.className = 'gitment-header-issue-link'; 71 | issueLink.href = meta.html_url; 72 | issueLink.target = '_blank'; 73 | issueLink.innerText = 'Issue Page'; 74 | container.appendChild(issueLink); 75 | 76 | return container; 77 | } 78 | 79 | function renderComments(_ref2, instance) { 80 | var meta = _ref2.meta, 81 | comments = _ref2.comments, 82 | commentReactions = _ref2.commentReactions, 83 | currentPage = _ref2.currentPage, 84 | user = _ref2.user, 85 | error = _ref2.error; 86 | 87 | var container = document.createElement('div'); 88 | container.lang = "en-US"; 89 | container.className = 'gitment-container gitment-comments-container'; 90 | 91 | if (error) { 92 | var errorBlock = document.createElement('div'); 93 | errorBlock.className = 'gitment-comments-error'; 94 | 95 | if (error === _constants.NOT_INITIALIZED_ERROR && user.login && user.login.toLowerCase() === instance.owner.toLowerCase()) { 96 | var initHint = document.createElement('div'); 97 | var initButton = document.createElement('button'); 98 | initButton.className = 'gitment-comments-init-btn'; 99 | initButton.onclick = function () { 100 | initButton.setAttribute('disabled', true); 101 | instance.init().catch(function (e) { 102 | initButton.removeAttribute('disabled'); 103 | alert(e); 104 | }); 105 | }; 106 | initButton.innerText = '初始化评论'; 107 | initHint.appendChild(initButton); 108 | errorBlock.appendChild(initHint); 109 | } else { 110 | errorBlock.innerText = error; 111 | } 112 | container.appendChild(errorBlock); 113 | return container; 114 | } else if (comments === undefined) { 115 | var loading = document.createElement('div'); 116 | loading.innerText = '加载评论中...'; 117 | loading.className = 'gitment-comments-loading'; 118 | container.appendChild(loading); 119 | return container; 120 | } else if (!comments.length) { 121 | var emptyBlock = document.createElement('div'); 122 | emptyBlock.className = 'gitment-comments-empty'; 123 | emptyBlock.innerText = '暂无评论'; 124 | container.appendChild(emptyBlock); 125 | return container; 126 | } 127 | 128 | var commentsList = document.createElement('ul'); 129 | commentsList.className = 'gitment-comments-list'; 130 | 131 | comments.forEach(function (comment) { 132 | var createDate = new Date(comment.created_at); 133 | var updateDate = new Date(comment.updated_at); 134 | var commentItem = document.createElement('li'); 135 | commentItem.className = 'gitment-comment'; 136 | commentItem.innerHTML = '\n \n \n \n
\n
\n \n ' + comment.user.login + '\n \n \u521B\u5EFA\u4E8E\n ' + new Date(createDate).format('yyyy-MM-dd hh:mm:ss') + '\n ' + (createDate.toString() !== updateDate.toString() ? ' \u2022 edited' : '') + '\n
' + _icons.heart + ' ' + (comment.reactions.heart || '') + '
\n
\n
' + comment.body_html + '
\n
\n '; 137 | var likeButton = commentItem.querySelector('.gitment-comment-like-btn'); 138 | var likedReaction = commentReactions[comment.id] && commentReactions[comment.id].find(function (reaction) { 139 | return reaction.content === 'heart' && reaction.user.login === user.login; 140 | }); 141 | if (likedReaction) { 142 | likeButton.classList.add('liked'); 143 | likeButton.onclick = function () { 144 | return instance.unlikeAComment(comment.id); 145 | }; 146 | } else { 147 | likeButton.classList.remove('liked'); 148 | likeButton.onclick = function () { 149 | return instance.likeAComment(comment.id); 150 | }; 151 | } 152 | 153 | // dirty 154 | // use a blank image to trigger height calculating when element rendered 155 | var imgTrigger = document.createElement('img'); 156 | var markdownBody = commentItem.querySelector('.gitment-comment-body'); 157 | imgTrigger.className = 'gitment-hidden'; 158 | imgTrigger.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; 159 | imgTrigger.onload = function () { 160 | if (markdownBody.clientHeight > instance.maxCommentHeight) { 161 | markdownBody.classList.add('gitment-comment-body-folded'); 162 | markdownBody.style.maxHeight = instance.maxCommentHeight + 'px'; 163 | markdownBody.title = 'Click to Expand'; 164 | markdownBody.onclick = function () { 165 | markdownBody.classList.remove('gitment-comment-body-folded'); 166 | markdownBody.style.maxHeight = ''; 167 | markdownBody.title = ''; 168 | markdownBody.onclick = null; 169 | }; 170 | } 171 | }; 172 | commentItem.appendChild(imgTrigger); 173 | 174 | commentsList.appendChild(commentItem); 175 | }); 176 | 177 | container.appendChild(commentsList); 178 | 179 | if (meta) { 180 | var pageCount = Math.ceil(meta.comments / instance.perPage); 181 | if (pageCount > 1) { 182 | var pagination = document.createElement('ul'); 183 | pagination.className = 'gitment-comments-pagination'; 184 | 185 | if (currentPage > 1) { 186 | var previousButton = document.createElement('li'); 187 | previousButton.className = 'gitment-comments-page-item'; 188 | previousButton.innerText = 'Previous'; 189 | previousButton.onclick = function () { 190 | return instance.goto(currentPage - 1); 191 | }; 192 | pagination.appendChild(previousButton); 193 | } 194 | 195 | var _loop = function _loop(i) { 196 | var pageItem = document.createElement('li'); 197 | pageItem.className = 'gitment-comments-page-item'; 198 | pageItem.innerText = i; 199 | pageItem.onclick = function () { 200 | return instance.goto(i); 201 | }; 202 | if (currentPage === i) pageItem.classList.add('gitment-selected'); 203 | pagination.appendChild(pageItem); 204 | }; 205 | 206 | for (var i = 1; i <= pageCount; i++) { 207 | _loop(i); 208 | } 209 | 210 | if (currentPage < pageCount) { 211 | var nextButton = document.createElement('li'); 212 | nextButton.className = 'gitment-comments-page-item'; 213 | nextButton.innerText = 'Next'; 214 | nextButton.onclick = function () { 215 | return instance.goto(currentPage + 1); 216 | }; 217 | pagination.appendChild(nextButton); 218 | } 219 | 220 | container.appendChild(pagination); 221 | } 222 | } 223 | 224 | return container; 225 | } 226 | 227 | function renderEditor(_ref3, instance) { 228 | var user = _ref3.user, 229 | error = _ref3.error; 230 | 231 | var container = document.createElement('div'); 232 | container.lang = "en-US"; 233 | container.className = 'gitment-container gitment-editor-container'; 234 | 235 | var shouldDisable = user.login && !error ? '' : 'disabled'; 236 | var disabledTip = user.login ? '' : 'Login to Comment'; 237 | container.innerHTML = '\n ' + (user.login ? '\n \n ' : user.isLoggingIn ? '
' + _icons.spinner + '
' : '\n ' + _icons.github + '\n ') + '\n \n
\n
\n \n \n
\n
\n
\n \n
\n
\n
\n
\n
\n
\n \n '; 238 | if (user.login) { 239 | container.querySelector('.gitment-editor-logout-link').onclick = function () { 240 | return instance.logout(); 241 | }; 242 | } 243 | 244 | var writeField = container.querySelector('.gitment-editor-write-field'); 245 | var previewField = container.querySelector('.gitment-editor-preview-field'); 246 | 247 | var textarea = writeField.querySelector('textarea'); 248 | textarea.oninput = function () { 249 | textarea.style.height = 'auto'; 250 | var style = window.getComputedStyle(textarea, null); 251 | var height = parseInt(style.height, 10); 252 | var clientHeight = textarea.clientHeight; 253 | var scrollHeight = textarea.scrollHeight; 254 | if (clientHeight < scrollHeight) { 255 | textarea.style.height = height + scrollHeight - clientHeight + 'px'; 256 | } 257 | }; 258 | 259 | var _container$querySelec = container.querySelectorAll('.gitment-editor-tab'), 260 | _container$querySelec2 = _slicedToArray(_container$querySelec, 2), 261 | writeTab = _container$querySelec2[0], 262 | previewTab = _container$querySelec2[1]; 263 | 264 | writeTab.onclick = function () { 265 | writeTab.classList.add('gitment-selected'); 266 | previewTab.classList.remove('gitment-selected'); 267 | writeField.classList.remove('gitment-hidden'); 268 | previewField.classList.add('gitment-hidden'); 269 | 270 | textarea.focus(); 271 | }; 272 | previewTab.onclick = function () { 273 | previewTab.classList.add('gitment-selected'); 274 | writeTab.classList.remove('gitment-selected'); 275 | previewField.classList.remove('gitment-hidden'); 276 | writeField.classList.add('gitment-hidden'); 277 | 278 | var preview = previewField.querySelector('.gitment-editor-preview'); 279 | var content = textarea.value.trim(); 280 | if (!content) { 281 | preview.innerText = '暂无内容可预览'; 282 | return; 283 | } 284 | 285 | preview.innerText = 'Loading preview...'; 286 | instance.markdown(content).then(function (html) { 287 | return preview.innerHTML = html; 288 | }); 289 | }; 290 | 291 | var submitButton = container.querySelector('.gitment-editor-submit'); 292 | submitButton.onclick = function () { 293 | submitButton.innerText = 'Submitting...'; 294 | submitButton.setAttribute('disabled', true); 295 | instance.post(textarea.value.trim()).then(function (data) { 296 | textarea.value = ''; 297 | textarea.style.height = 'auto'; 298 | submitButton.removeAttribute('disabled'); 299 | submitButton.innerText = 'Comment'; 300 | }).catch(function (e) { 301 | alert(e); 302 | submitButton.removeAttribute('disabled'); 303 | submitButton.innerText = 'Comment'; 304 | }); 305 | }; 306 | 307 | return container; 308 | } 309 | 310 | function renderFooter() { 311 | var container = document.createElement('div'); 312 | container.lang = "en-US"; 313 | container.className = 'gitment-container gitment-footer-container'; 314 | container.innerHTML = '\n Powered by\n \n Gitment\n \n '; 315 | return container; 316 | } 317 | 318 | function render(state, instance) { 319 | var container = document.createElement('div'); 320 | container.lang = "en-US"; 321 | container.className = 'gitment-container gitment-root-container'; 322 | container.appendChild(instance.renderHeader(state, instance)); 323 | container.appendChild(instance.renderComments(state, instance)); 324 | container.appendChild(instance.renderEditor(state, instance)); 325 | container.appendChild(instance.renderFooter(state, instance)); 326 | return container; 327 | } 328 | 329 | exports.default = { render: render, renderHeader: renderHeader, renderComments: renderComments, renderEditor: renderEditor, renderFooter: renderFooter }; 330 | //# sourceMappingURL=default.js.map -------------------------------------------------------------------------------- /assets/gitment/gitment.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/gitment.js"],"names":["scope","extendRenderer","instance","renderer","container","targetContainer","render","theme","defaultTheme","e","state","firstChild","replaceChild","appendChild","Gitment","localStorage","getItem","token","setItem","oauthUri","redirect_uri","oauth","window","location","href","oauthParams","Object","assign","stringify","options","useTheme","id","title","document","link","desc","labels","perPage","maxCommentHeight","user","userInfo","accessToken","JSON","parse","fromCache","removeItem","error","meta","comments","undefined","reactions","commentReactions","currentPage","query","code","client_id","client_secret","search","replacedUrl","origin","pathname","hash","history","replaceState","isLoggingIn","post","then","data","access_token","update","catch","alert","createIssue","loadComments","renderers","keys","forEach","Promise","all","loadMeta","loadUserInfo","loadCommentReactions","loadReactions","text","mode","owner","repo","concat","body","resolve","getIssue","issue","comments_url","pageCount","Math","ceil","push","get","creator","issues","length","reject","page","per_page","logout","total_count","url","comentReactions","map","comment","index","reactionsArray","loginLink","number","content","reaction","heart","findIndex","login","delete","splice","commentId","find","module","exports"],"mappings":"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","file":"gitment.js","sourcesContent":["import { autorun, observable } from 'mobx'\n\nimport { LS_ACCESS_TOKEN_KEY, LS_USER_KEY, NOT_INITIALIZED_ERROR } from './constants'\nimport { getTargetContainer, http, Query } from './utils'\nimport defaultTheme from './theme/default'\n\nconst scope = 'public_repo'\n\nfunction extendRenderer(instance, renderer) {\n instance[renderer] = (container) => {\n const targetContainer = getTargetContainer(container)\n const render = instance.theme[renderer] || instance.defaultTheme[renderer]\n\n autorun(() => {\n const e = render(instance.state, instance)\n if (targetContainer.firstChild) {\n targetContainer.replaceChild(e, targetContainer.firstChild)\n } else {\n targetContainer.appendChild(e)\n }\n })\n\n return targetContainer\n }\n}\n\nclass Gitment {\n get accessToken() {\n return localStorage.getItem(LS_ACCESS_TOKEN_KEY)\n }\n set accessToken(token) {\n localStorage.setItem(LS_ACCESS_TOKEN_KEY, token)\n }\n\n get loginLink() {\n const oauthUri = 'https://github.com/login/oauth/authorize'\n const redirect_uri = this.oauth.redirect_uri || window.location.href\n\n const oauthParams = Object.assign({\n scope,\n redirect_uri,\n }, this.oauth)\n\n return `${oauthUri}${Query.stringify(oauthParams)}`\n }\n\n constructor(options = {}) {\n this.defaultTheme = defaultTheme\n this.useTheme(defaultTheme)\n\n Object.assign(this, {\n id: window.location.href,\n title: window.document.title,\n link: window.location.href,\n desc: '',\n labels: [],\n theme: defaultTheme,\n oauth: {},\n perPage: 20,\n maxCommentHeight: 250,\n }, options)\n\n this.useTheme(this.theme)\n\n const user = {}\n try {\n const userInfo = localStorage.getItem(LS_USER_KEY)\n if (this.accessToken && userInfo) {\n Object.assign(user, JSON.parse(userInfo), {\n fromCache: true,\n })\n }\n } catch (e) {\n localStorage.removeItem(LS_USER_KEY)\n }\n\n this.state = observable({\n user,\n error: null,\n meta: {},\n comments: undefined,\n reactions: [],\n commentReactions: {},\n currentPage: 1,\n })\n\n const query = Query.parse()\n if (query.code) {\n const { client_id, client_secret } = this.oauth\n const code = query.code\n delete query.code\n const search = Query.stringify(query)\n const replacedUrl = `${window.location.origin}${window.location.pathname}${search}${window.location.hash}`\n history.replaceState({}, '', replacedUrl)\n\n Object.assign(this, {\n id: replacedUrl,\n link: replacedUrl,\n }, options)\n\n this.state.user.isLoggingIn = true\n http.post('https://gh-oauth.imsun.net', {\n code,\n client_id,\n client_secret,\n }, '')\n .then(data => {\n this.accessToken = data.access_token\n this.update()\n })\n .catch(e => {\n this.state.user.isLoggingIn = false\n alert(e)\n })\n } else {\n this.update()\n }\n }\n\n init() {\n return this.createIssue()\n .then(() => this.loadComments())\n .then(comments => {\n this.state.error = null\n return comments\n })\n }\n\n useTheme(theme = {}) {\n this.theme = theme\n\n const renderers = Object.keys(this.theme)\n renderers.forEach(renderer => extendRenderer(this, renderer))\n }\n\n update() {\n return Promise.all([this.loadMeta(), this.loadUserInfo()])\n .then(() => Promise.all([\n this.loadComments().then(() => this.loadCommentReactions()),\n this.loadReactions(),\n ]))\n .catch(e => this.state.error = e)\n }\n\n markdown(text) {\n return http.post('/markdown', {\n text,\n mode: 'gfm',\n })\n }\n\n createIssue() {\n const { id, owner, repo, title, link, desc, labels } = this\n\n return http.post(`/repos/${owner}/${repo}/issues`, {\n title,\n labels: labels.concat(['gitment', id]),\n body: `${link}\\n\\n${desc}`,\n })\n .then((meta) => {\n this.state.meta = meta\n return meta\n })\n }\n\n getIssue() {\n if (this.state.meta.id) return Promise.resolve(this.state.meta)\n\n return this.loadMeta()\n }\n\n post(body) {\n return this.getIssue()\n .then(issue => http.post(issue.comments_url, { body }, ''))\n .then(data => {\n this.state.meta.comments++\n const pageCount = Math.ceil(this.state.meta.comments / this.perPage)\n if (this.state.currentPage === pageCount) {\n this.state.comments.push(data)\n }\n return data\n })\n }\n\n loadMeta() {\n const { id, owner, repo } = this\n return http.get(`/repos/${owner}/${repo}/issues`, {\n creator: owner,\n labels: id,\n })\n .then(issues => {\n if (!issues.length) return Promise.reject(NOT_INITIALIZED_ERROR)\n this.state.meta = issues[0]\n return issues[0]\n })\n }\n\n loadComments(page = this.state.currentPage) {\n return this.getIssue()\n .then(issue => http.get(issue.comments_url, { page, per_page: this.perPage }, ''))\n .then((comments) => {\n this.state.comments = comments\n return comments\n })\n }\n\n loadUserInfo() {\n if (!this.accessToken) {\n this.logout()\n return Promise.resolve({})\n }\n\n return http.get('/user')\n .then((user) => {\n this.state.user = user\n localStorage.setItem(LS_USER_KEY, JSON.stringify(user))\n return user\n })\n }\n\n loadReactions() {\n if (!this.accessToken) {\n this.state.reactions = []\n return Promise.resolve([])\n }\n\n return this.getIssue()\n .then((issue) => {\n if (!issue.reactions.total_count) return []\n return http.get(issue.reactions.url, {}, '')\n })\n .then((reactions) => {\n this.state.reactions = reactions\n return reactions\n })\n }\n\n loadCommentReactions() {\n if (!this.accessToken) {\n this.state.commentReactions = {}\n return Promise.resolve([])\n }\n\n const comments = this.state.comments\n const comentReactions = {}\n\n return Promise.all(comments.map((comment) => {\n if (!comment.reactions.total_count) return []\n\n const { owner, repo } = this\n return http.get(`/repos/${owner}/${repo}/issues/comments/${comment.id}/reactions`, {})\n }))\n .then(reactionsArray => {\n comments.forEach((comment, index) => {\n comentReactions[comment.id] = reactionsArray[index]\n })\n this.state.commentReactions = comentReactions\n\n return comentReactions\n })\n }\n\n login() {\n window.location.href = this.loginLink\n }\n\n logout() {\n localStorage.removeItem(LS_ACCESS_TOKEN_KEY)\n localStorage.removeItem(LS_USER_KEY)\n this.state.user = {}\n }\n\n goto(page) {\n this.state.currentPage = page\n this.state.comments = undefined\n return this.loadComments(page)\n }\n\n like() {\n if (!this.accessToken) {\n alert('Login to Like')\n return Promise.reject()\n }\n\n const { owner, repo } = this\n\n return http.post(`/repos/${owner}/${repo}/issues/${this.state.meta.number}/reactions`, {\n content: 'heart',\n })\n .then(reaction => {\n this.state.reactions.push(reaction)\n this.state.meta.reactions.heart++\n })\n }\n\n unlike() {\n if (!this.accessToken) return Promise.reject()\n\n\n const { user, reactions } = this.state\n const index = reactions.findIndex(reaction => reaction.user.login === user.login)\n return http.delete(`/reactions/${reactions[index].id}`)\n .then(() => {\n reactions.splice(index, 1)\n this.state.meta.reactions.heart--\n })\n }\n\n likeAComment(commentId) {\n if (!this.accessToken) {\n alert('Login to Like')\n return Promise.reject()\n }\n\n const { owner, repo } = this\n const comment = this.state.comments.find(comment => comment.id === commentId)\n\n return http.post(`/repos/${owner}/${repo}/issues/comments/${commentId}/reactions`, {\n content: 'heart',\n })\n .then(reaction => {\n this.state.commentReactions[commentId].push(reaction)\n comment.reactions.heart++\n })\n }\n\n unlikeAComment(commentId) {\n if (!this.accessToken) return Promise.reject()\n\n const reactions = this.state.commentReactions[commentId]\n const comment = this.state.comments.find(comment => comment.id === commentId)\n const { user } = this.state\n const index = reactions.findIndex(reaction => reaction.user.login === user.login)\n\n return http.delete(`/reactions/${reactions[index].id}`)\n .then(() => {\n reactions.splice(index, 1)\n comment.reactions.heart--\n })\n }\n}\n\nmodule.exports = Gitment\n"]} -------------------------------------------------------------------------------- /assets/gitment/theme/default.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../../src/theme/default.js"],"names":["Date","prototype","format","o","getMonth","getDate","getHours","getMinutes","getSeconds","Math","floor","getMilliseconds","test","replace","RegExp","$1","getFullYear","substr","length","k","renderHeader","instance","meta","user","reactions","container","document","createElement","lang","className","likeButton","likedReaction","find","reaction","content","login","innerHTML","heart","classList","add","onclick","unlike","remove","like","appendChild","commentsCount","comments","issueLink","href","html_url","target","innerText","renderComments","commentReactions","currentPage","error","errorBlock","toLowerCase","owner","initHint","initButton","setAttribute","init","catch","removeAttribute","alert","e","undefined","loading","emptyBlock","commentsList","forEach","createDate","comment","created_at","updateDate","updated_at","commentItem","avatar_url","toString","body_html","querySelector","id","unlikeAComment","likeAComment","imgTrigger","markdownBody","src","onload","clientHeight","maxCommentHeight","style","maxHeight","title","pageCount","ceil","perPage","pagination","previousButton","goto","i","pageItem","nextButton","renderEditor","shouldDisable","disabledTip","isLoggingIn","loginLink","logout","writeField","previewField","textarea","oninput","height","window","getComputedStyle","parseInt","scrollHeight","querySelectorAll","writeTab","previewTab","focus","preview","value","trim","markdown","then","html","submitButton","post","renderFooter","render","state"],"mappings":"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","file":"default.js","sourcesContent":["import { github as githubIcon, heart as heartIcon, spinner as spinnerIcon } from '../icons'\nimport { NOT_INITIALIZED_ERROR } from '../constants'\nimport {toJS} from 'mobx';\n\nDate.prototype.format = function(format) {\n var o = {\n \"M+\": this.getMonth() + 1, //month\n \"d+\": this.getDate(), //day\n \"h+\": this.getHours(), //hour\n \"m+\": this.getMinutes(), //minute\n \"s+\": this.getSeconds(), //second\n \"q+\": Math.floor((this.getMonth() + 3) / 3), //quarter\n \"S\": this.getMilliseconds() //millisecond\n }\n if (/(y+)/.test(format)) {\n format = format.replace(RegExp.$1,(this.getFullYear() + \"\").substr(4 - RegExp.$1.length));\n }\n for (var k in o){\n if (new RegExp(\"(\" + k + \")\").test(format)){\n format = format.replace(RegExp.$1,RegExp.$1.length == 1 ? o[k] :(\"00\" + o[k]).substr((\"\" + o[k]).length));\n }\n }\n return format;\n}\n\nfunction renderHeader({ meta, user, reactions }, instance) {\n const container = document.createElement('div')\n container.lang = \"en-US\"\n container.className = 'gitment-container gitment-header-container'\n\n const likeButton = document.createElement('span')\n const likedReaction = reactions.find(reaction => (\n reaction.content === 'heart' && reaction.user.login === user.login\n ))\n likeButton.className = 'gitment-header-like-btn'\n likeButton.innerHTML = `\n ${heartIcon}\n ${ likedReaction\n ? 'Unlike'\n : 'Like'\n }\n ${ meta.reactions && meta.reactions.heart\n ? ` • ${meta.reactions.heart} Liked`\n : ''\n }\n `\n\n if (likedReaction) {\n likeButton.classList.add('liked')\n likeButton.onclick = () => instance.unlike()\n } else {\n likeButton.classList.remove('liked')\n likeButton.onclick = () => instance.like()\n }\n container.appendChild(likeButton)\n\n const commentsCount = document.createElement('span')\n commentsCount.innerHTML = `\n ${ meta.comments\n ? ` • ${meta.comments} Comments`\n : ''\n }\n `\n container.appendChild(commentsCount)\n\n const issueLink = document.createElement('a')\n issueLink.className = 'gitment-header-issue-link'\n issueLink.href = meta.html_url\n issueLink.target = '_blank'\n issueLink.innerText = 'Issue Page'\n container.appendChild(issueLink)\n\n return container\n}\n\nfunction renderComments({ meta, comments, commentReactions, currentPage, user, error }, instance) {\n const container = document.createElement('div')\n container.lang = \"en-US\"\n container.className = 'gitment-container gitment-comments-container'\n\n if (error) {\n const errorBlock = document.createElement('div')\n errorBlock.className = 'gitment-comments-error'\n\n if (error === NOT_INITIALIZED_ERROR\n && user.login\n && user.login.toLowerCase() === instance.owner.toLowerCase()) {\n const initHint = document.createElement('div')\n const initButton = document.createElement('button')\n initButton.className = 'gitment-comments-init-btn'\n initButton.onclick = () => {\n initButton.setAttribute('disabled', true)\n instance.init()\n .catch(e => {\n initButton.removeAttribute('disabled')\n alert(e)\n })\n }\n initButton.innerText = '初始化评论'\n initHint.appendChild(initButton)\n errorBlock.appendChild(initHint)\n } else {\n errorBlock.innerText = error\n }\n container.appendChild(errorBlock)\n return container\n } else if (comments === undefined) {\n const loading = document.createElement('div')\n loading.innerText = '加载评论中...'\n loading.className = 'gitment-comments-loading'\n container.appendChild(loading)\n return container\n } else if (!comments.length) {\n const emptyBlock = document.createElement('div')\n emptyBlock.className = 'gitment-comments-empty'\n emptyBlock.innerText = '暂无评论'\n container.appendChild(emptyBlock)\n return container\n }\n\n const commentsList = document.createElement('ul')\n commentsList.className = 'gitment-comments-list'\n\n comments.forEach(comment => {\n const createDate = new Date(comment.created_at)\n const updateDate = new Date(comment.updated_at)\n const commentItem = document.createElement('li')\n commentItem.className = 'gitment-comment'\n commentItem.innerHTML = `\n \n \n \n
\n
\n \n ${comment.user.login}\n \n 创建于\n ${new Date(createDate).format('yyyy-MM-dd hh:mm:ss')}\n ${ createDate.toString() !== updateDate.toString()\n ? ` • edited`\n : ''\n }\n
${heartIcon} ${comment.reactions.heart || ''}
\n
\n
${comment.body_html}
\n
\n `\n const likeButton = commentItem.querySelector('.gitment-comment-like-btn')\n const likedReaction = commentReactions[comment.id]\n && commentReactions[comment.id].find(reaction => (\n reaction.content === 'heart' && reaction.user.login === user.login\n ))\n if (likedReaction) {\n likeButton.classList.add('liked')\n likeButton.onclick = () => instance.unlikeAComment(comment.id)\n } else {\n likeButton.classList.remove('liked')\n likeButton.onclick = () => instance.likeAComment(comment.id)\n }\n\n // dirty\n // use a blank image to trigger height calculating when element rendered\n const imgTrigger = document.createElement('img')\n const markdownBody = commentItem.querySelector('.gitment-comment-body')\n imgTrigger.className = 'gitment-hidden'\n imgTrigger.src = \"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\"\n imgTrigger.onload = () => {\n if (markdownBody.clientHeight > instance.maxCommentHeight) {\n markdownBody.classList.add('gitment-comment-body-folded')\n markdownBody.style.maxHeight = instance.maxCommentHeight + 'px'\n markdownBody.title = 'Click to Expand'\n markdownBody.onclick = () => {\n markdownBody.classList.remove('gitment-comment-body-folded')\n markdownBody.style.maxHeight = ''\n markdownBody.title = ''\n markdownBody.onclick = null\n }\n }\n }\n commentItem.appendChild(imgTrigger)\n\n commentsList.appendChild(commentItem)\n })\n\n container.appendChild(commentsList)\n\n if (meta) {\n const pageCount = Math.ceil(meta.comments / instance.perPage)\n if (pageCount > 1) {\n const pagination = document.createElement('ul')\n pagination.className = 'gitment-comments-pagination'\n\n if (currentPage > 1) {\n const previousButton = document.createElement('li')\n previousButton.className = 'gitment-comments-page-item'\n previousButton.innerText = 'Previous'\n previousButton.onclick = () => instance.goto(currentPage - 1)\n pagination.appendChild(previousButton)\n }\n\n for (let i = 1; i <= pageCount; i++) {\n const pageItem = document.createElement('li')\n pageItem.className = 'gitment-comments-page-item'\n pageItem.innerText = i\n pageItem.onclick = () => instance.goto(i)\n if (currentPage === i) pageItem.classList.add('gitment-selected')\n pagination.appendChild(pageItem)\n }\n\n if (currentPage < pageCount) {\n const nextButton = document.createElement('li')\n nextButton.className = 'gitment-comments-page-item'\n nextButton.innerText = 'Next'\n nextButton.onclick = () => instance.goto(currentPage + 1)\n pagination.appendChild(nextButton)\n }\n\n container.appendChild(pagination)\n }\n }\n\n return container\n}\n\nfunction renderEditor({ user, error }, instance) {\n const container = document.createElement('div')\n container.lang = \"en-US\"\n container.className = 'gitment-container gitment-editor-container'\n\n const shouldDisable = user.login && !error ? '' : 'disabled'\n const disabledTip = user.login ? '' : 'Login to Comment'\n container.innerHTML = `\n ${ user.login\n ? `\n \n `\n : user.isLoggingIn\n ? `
${spinnerIcon}
`\n : `\n ${githubIcon}\n `\n }\n \n
\n
\n \n
\n ${ user.login\n ? '退出登录'\n : user.isLoggingIn\n ? 'Logging in...'\n : ``\n }\n
\n
\n
\n
\n \n
\n
\n
\n
\n
\n
\n
\n \n 支持 Markdown\n \n \n
\n `\n if (user.login) {\n container.querySelector('.gitment-editor-logout-link').onclick = () => instance.logout()\n }\n\n const writeField = container.querySelector('.gitment-editor-write-field')\n const previewField = container.querySelector('.gitment-editor-preview-field')\n\n const textarea = writeField.querySelector('textarea')\n textarea.oninput = () => {\n textarea.style.height = 'auto'\n const style = window.getComputedStyle(textarea, null)\n const height = parseInt(style.height, 10)\n const clientHeight = textarea.clientHeight\n const scrollHeight = textarea.scrollHeight\n if (clientHeight < scrollHeight) {\n textarea.style.height = (height + scrollHeight - clientHeight) + 'px'\n }\n }\n\n const [writeTab, previewTab] = container.querySelectorAll('.gitment-editor-tab')\n writeTab.onclick = () => {\n writeTab.classList.add('gitment-selected')\n previewTab.classList.remove('gitment-selected')\n writeField.classList.remove('gitment-hidden')\n previewField.classList.add('gitment-hidden')\n\n textarea.focus()\n }\n previewTab.onclick = () => {\n previewTab.classList.add('gitment-selected')\n writeTab.classList.remove('gitment-selected')\n previewField.classList.remove('gitment-hidden')\n writeField.classList.add('gitment-hidden')\n\n const preview = previewField.querySelector('.gitment-editor-preview')\n const content = textarea.value.trim()\n if (!content) {\n preview.innerText = '暂无内容可预览'\n return\n }\n\n preview.innerText = 'Loading preview...'\n instance.markdown(content)\n .then(html => preview.innerHTML = html)\n }\n\n const submitButton = container.querySelector('.gitment-editor-submit')\n submitButton.onclick = () => {\n submitButton.innerText = 'Submitting...'\n submitButton.setAttribute('disabled', true)\n instance.post(textarea.value.trim())\n .then(data => {\n textarea.value = ''\n textarea.style.height = 'auto'\n submitButton.removeAttribute('disabled')\n submitButton.innerText = 'Comment'\n })\n .catch(e => {\n alert(e)\n submitButton.removeAttribute('disabled')\n submitButton.innerText = 'Comment'\n })\n }\n\n return container\n}\n\nfunction renderFooter() {\n const container = document.createElement('div')\n container.lang = \"en-US\"\n container.className = 'gitment-container gitment-footer-container'\n container.innerHTML = `\n Powered by\n \n Gitment\n \n `\n return container\n}\n\nfunction render(state, instance) {\n const container = document.createElement('div')\n container.lang = \"en-US\"\n container.className = 'gitment-container gitment-root-container'\n container.appendChild(instance.renderHeader(state, instance))\n container.appendChild(instance.renderComments(state, instance))\n container.appendChild(instance.renderEditor(state, instance))\n container.appendChild(instance.renderFooter(state, instance))\n return container\n}\n\nexport default { render, renderHeader, renderComments, renderEditor, renderFooter }\n"]} --------------------------------------------------------------------------------