├── .gitignore ├── .prettierignore ├── README.md ├── deploy.sh ├── docs ├── .vuepress │ ├── buildConfig.js │ ├── components │ │ ├── Advertisement.vue │ │ ├── ArticleList.vue │ │ ├── AwesomePoetry.vue │ │ ├── Contact.vue │ │ └── comment │ │ │ ├── assets │ │ │ └── icon │ │ │ │ ├── arrow_down.svg │ │ │ │ ├── edit.svg │ │ │ │ ├── github.svg │ │ │ │ ├── heart.svg │ │ │ │ ├── heart_on.svg │ │ │ │ ├── reply.svg │ │ │ │ └── tip.svg │ │ │ ├── components │ │ │ ├── Action.vue │ │ │ ├── Button.vue │ │ │ ├── Comment.vue │ │ │ └── Svg.vue │ │ │ ├── const.js │ │ │ ├── graphql │ │ │ └── getComments.js │ │ │ ├── i18n │ │ │ ├── en.json │ │ │ ├── es-ES.json │ │ │ ├── fr.json │ │ │ ├── index.js │ │ │ ├── ru.json │ │ │ ├── zh-CN.json │ │ │ └── zh-TW.json │ │ │ ├── index.styl │ │ │ ├── index.vue │ │ │ ├── mixin │ │ │ └── index.js │ │ │ └── util.js │ ├── config.js │ ├── enhanceApp.js │ ├── override.styl │ ├── public │ │ ├── google21c733509a589aaa.html │ │ ├── icons │ │ │ ├── android-chrome-192x192.png │ │ │ ├── android-chrome-512x512.png │ │ │ ├── apple-touch-icon.png │ │ │ ├── browserconfig.xml │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon.ico │ │ │ ├── mstile-150x150.png │ │ │ └── safari-pinned-tab.svg │ │ ├── images │ │ │ └── MG-1P.png │ │ ├── logo.png │ │ ├── logo.svg │ │ ├── manifest.json │ │ └── site.webmanifest │ └── themeConfig.js ├── README.md ├── en │ ├── README.md │ └── application │ │ └── README.md ├── helper │ ├── index.js │ └── utils.js └── zh │ ├── README.md │ ├── application │ └── README.md │ ├── article │ ├── README.md │ ├── arya-jarvis-born-for-efficiency.md │ ├── awesome-quickapp.md │ ├── beautify-vue-by-eslint-and-prettier.md │ ├── develop-quick-app-experience-notes.md │ ├── how-to-elegantly-handle-quickapp-request.md │ ├── how-to-quickly-delete-git-repository-new-changes.md │ ├── how-to-use-npm-npx-tutorial.md │ ├── how-to-write-a-good-readme-for-your-project.md │ ├── js-import-export-vs-require-module-exports.md │ ├── quickapp-boilerplate-template.md │ ├── talk-about-my-blogs.md │ ├── talk-about-nice-links.md │ ├── top-100-front-end-awesome-awesome-list.md │ ├── vue-webpack-boilerplate-template.md │ └── vuepress-hexo-jekyll-ghost-gitbook-hugo-solo_compare-personal-website-generator.md │ ├── blog │ ├── README.md │ ├── csdn-blog.md │ ├── docz-blog.md │ ├── ghost-blog.md │ ├── hexo-blog.md │ ├── jekyll-blog.md │ ├── jianshu-blog.md │ ├── vuepress-blog.md │ └── wechat-blog.md │ └── recruit │ └── README.md ├── package.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | 4 | docs/dist 5 | 6 | # Log files 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | 11 | # Editor directories and files 12 | .idea 13 | .vscode 14 | *.suo 15 | *.ntvs* 16 | *.njsproj 17 | *.sln 18 | *.sw* -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | package.json 2 | README.md -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

静晴轩别苑

4 | 5 |
6 | 7 | 采用 VuePress 构建的 Web 应用程序:https://nice.lovejade.cn 8 | 9 |
10 | 11 | ## 目标与哲学 12 | 13 | [静晴轩别苑](https://nice.lovejade.cn)的诞生,其初衷完全是为了体验 `VuePress`: Vue 驱动的静态网站生成器。[VuePress](https://vuepress.vuejs.org/) 由两部分组成:一部分是支持用 `Vue` 开发主题的极简静态网站生成器,另一个部分是为书写技术文档而优化的默认主题。它的诞生初衷是为了支持 `Vue` 及其子项目的文档需求。 14 | 15 | 每一个由 `VuePress` 生成的页面都带有预渲染好的 HTML,也因此具有非常好的加载性能和搜索引擎优化(`SEO`)。同时,一旦页面被加载,Vue 将接管这些静态内容,并将其转换成一个完整的单页应用(`SPA`),其他的页面则会只在用户浏览到的时候才按需加载。除此之外,它还内置了以下优秀特性: 16 | 17 | - 为技术文档而优化的[内置 Markdown 拓展](https://vuepress.vuejs.org/zh/guide/markdown.html) 18 | - [在 Markdown 文件中使用 Vue 组件的能力](https://vuepress.vuejs.org/zh/guide/using-vue.html) 19 | - [Vue 驱动的自定义主题系统](https://vuepress.vuejs.org/zh/guide/custom-themes.html) 20 | - [自动生成 Service Worker](https://vuepress.vuejs.org/zh/config/#serviceworker) 21 | - [Google Analytics 集成](https://vuepress.vuejs.org/zh/config/#ga) 22 | - [多语言支持](https://vuepress.vuejs.org/zh/guide/i18n.html) 23 | - 默认主题包含: 24 | - 响应式布局 25 | - [可选的主页](https://vuepress.vuejs.org/zh/default-theme-config/#%E9%A6%96%E9%A1%B5) 26 | - [简洁的开箱即用的标题搜索](https://vuepress.vuejs.org/zh/default-theme-config/#%E5%86%85%E7%BD%AE%E6%90%9C%E7%B4%A2) 27 | - [Algolia 搜索](https://vuepress.vuejs.org/zh/default-theme-config/#algolia-%E6%90%9C%E7%B4%A2) 28 | - 可自定义的[导航栏](https://vuepress.vuejs.org/zh/default-theme-config/#%E5%AF%BC%E8%88%AA%E6%A0%8F)和[侧边栏](https://vuepress.vuejs.org/zh/default-theme-config/#%E4%BE%A7%E8%BE%B9%E6%A0%8F) 29 | - [自动生成的 GitHub 链接和页面的编辑链接](https://vuepress.vuejs.org/zh/default-theme-config/#git-%E4%BB%93%E5%BA%93%E5%92%8C%E7%BC%96%E8%BE%91%E9%93%BE%E6%8E%A5) 30 | 31 | 相比与 `Nuxt`、 `Hexo`、`Jekyll`、`Docsify`、`GitBook` 等工具,`VuePress` 在不同方向,都拥有着巨大优势,并且仍在开发更新当中;如果你有搭建个人博客、技术文档的需求,那么 `VuePress` 将是超棒的选择。 32 | 33 | ## 附加功能 34 | 35 | - 添加基于 `Github Issue` 的评论功能(相当于内置 `Gitalk`);只需修改 **.vuepress/themeConfig.js** 文件中 `comment` 字段配置即可;具体字段含义,可参见[Gitalk Options](https://github.com/gitalk/gitalk#options); 36 | - 有添加 `element-ui` 依赖,以方便编写常用组件;此项目中,内置除了评论组件外,还有 `Advertisement`(广告)、`ArticleList`(文章列表)、`Contact`(联系方式)等; 37 | - 引入 `prettier`, `lint-staged`, `husky` 等依赖,从而使得写出更合乎‘规范’的 markdown;同时注入至 Git hooks,以确保你的代码库具有一致的风格;即使你正与团队合作编写,也不必为统一风格的问题而感到忧虑! 38 | 39 | ## 如何使用 40 | 41 | 可将项目 `Fork` 至自己的代码仓库,运行以下命令即可: 42 | 43 | ```bash 44 | # 🎉 clone the project 45 | https://github.com/nicejade/vuepress-web-app.git 46 | cd vuepress-web-app 47 | 48 | # ➕ install dependencies & start dev 49 | yarn && yarn start 50 | ``` 51 | 52 | 修改 `deploy.sh` 文件中的“自定义域名”以及“仓库路径”,运行如下命令,即可实现部署(默认发布至 `github pages`;如果暂不使用自定义域名,注释该行即可。 53 | 54 | ```bash 55 | # 🚀 deploy to github-page 56 | yarn deploy 57 | ``` 58 | 59 | ## 相关链接 60 | 61 | - [**倾城之链**](https://nicelinks.site?utm_source=nice.lovejade.cn) 62 | - [About Me](https://aboutme.lovejade.cn/?utm_source=nice.lovejade.cn) 63 | - [个人博客](https://jeffjade.com/nicelinks?utm_source=nice.lovejade.cn) 64 | - [静轩之别苑](https://quickapp.lovejade.cn/?utm_source=nice.lovejade.cn) 65 | - [静晴轩别苑](https://nice.lovejade.cn/?utm_source=nice.lovejade.cn) 66 | - [吾意静晴轩](https://docz.lovejade.cn/?utm_source=nice.lovejade.cn) 67 | - [天意人间舫](https://blog.lovejade.cn/?utm_source=nice.lovejade.cn) 68 | - [新浪微博](https://weibo.com/jeffjade?utm_source=nice.lovejade.cn) 69 | - [知乎主页](https://www.zhihu.com/people/yang-qiong-pu/) 70 | - [简书主页](https://www.jianshu.com/u/9aae3d8f4c3d) 71 | - [SegmentFault](https://segmentfault.com/u/jeffjade) 72 | - [Twitter](https://twitter.com/nicejadeyang) 73 | - [Facebook](https://www.facebook.com/nice.jade.yang) 74 | 75 | | 微信公众号 | 前端微信群 | 推荐 Web 应用 | 76 | | --- | --- | --- | 77 | | 😉 静晴轩 | ✨ 大前端联盟 | 🎉 倾城之链 | 78 | | ![静晴轩](https://image.nicelinks.site/qrcode_jqx.jpg) | ![倾城之链](https://image.nicelinks.site/wqycx-weixin.png?ver=1) |倾城之链| 79 | 80 | ## 许可执照 81 | 82 | [MIT](http://opensource.org/licenses/MIT) 83 | 84 | Copyright (c) 2018-present, [nicejade](https://aboutme.lovejade.cn/) 85 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 确保脚本抛出遇到的错误 4 | set -e 5 | 6 | # 生成静态文件 7 | yarn run build 8 | 9 | # 进入生成的文件夹 10 | cd ./docs/dist 11 | 12 | # 如果是发布到自定义域名 13 | echo 'nice.lovejade.cn' > CNAME 14 | 15 | git init 16 | git add -A 17 | git commit -m 'deploy update 🎉' 18 | 19 | # 添加远程仓库 20 | git remote add origin git@github.com:nicejade/vuepress-web-app.git 21 | 22 | # 创建并切换到 master 分支 23 | git checkout -b master 24 | 25 | # 如果发布到 https://.github.io 26 | # git push -f git@github.com:/.github.io.git master 27 | 28 | # 如果发布到 https://.github.io/ 29 | git push -f git@github.com:nicejade/vuepress-web-app.git master:gh-pages 30 | cd - 31 | -------------------------------------------------------------------------------- /docs/.vuepress/buildConfig.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | configureWebpack: { 3 | resolve: { 4 | alias: { 5 | } 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /docs/.vuepress/components/Advertisement.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 75 | 76 | 102 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ArticleList.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 34 | 35 | -------------------------------------------------------------------------------- /docs/.vuepress/components/AwesomePoetry.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 25 | 26 | -------------------------------------------------------------------------------- /docs/.vuepress/components/Contact.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 27 | 28 | 42 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/assets/icon/arrow_down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/assets/icon/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/assets/icon/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/assets/icon/heart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/assets/icon/heart_on.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/assets/icon/reply.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/assets/icon/tip.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/components/Action.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/components/Button.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/components/Comment.vue: -------------------------------------------------------------------------------- 1 | 56 | 57 | 162 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/components/Svg.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/const.js: -------------------------------------------------------------------------------- 1 | export const GT_ACCESS_TOKEN = 'GT_ACCESS_TOKEN' 2 | export const GT_COMMENT = 'GT_COMMENT' 3 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/graphql/getComments.js: -------------------------------------------------------------------------------- 1 | import { axiosGithub } from "../util"; 2 | 3 | const getQL = (vars, pagerDirection) => { 4 | const cursorDirection = pagerDirection === "last" ? "before" : "after"; 5 | const ql = ` 6 | query getIssueAndComments( 7 | $owner: String!, 8 | $repo: String!, 9 | $id: Int!, 10 | $cursor: String, 11 | $pageSize: Int! 12 | ) { 13 | repository(owner: $owner, name: $repo) { 14 | issue(number: $id) { 15 | title 16 | url 17 | bodyHTML 18 | createdAt 19 | comments(${pagerDirection}: $pageSize, ${cursorDirection}: $cursor) { 20 | totalCount 21 | pageInfo { 22 | ${pagerDirection === "last" ? "hasPreviousPage" : "hasNextPage"} 23 | ${cursorDirection === "before" ? "startCursor" : "endCursor"} 24 | } 25 | nodes { 26 | id 27 | databaseId 28 | author { 29 | avatarUrl 30 | login 31 | url 32 | } 33 | bodyHTML 34 | body 35 | createdAt 36 | reactions(first: 100, content: HEART) { 37 | totalCount 38 | viewerHasReacted 39 | pageInfo{ 40 | hasNextPage 41 | } 42 | nodes { 43 | id 44 | databaseId 45 | user { 46 | login 47 | } 48 | } 49 | } 50 | } 51 | } 52 | } 53 | } 54 | } 55 | `; 56 | 57 | if (vars.cursor === null) delete vars.cursor; 58 | 59 | return { 60 | operationName: "getIssueAndComments", 61 | query: ql, 62 | variables: vars 63 | }; 64 | }; 65 | 66 | function getComments(issue) { 67 | const { 68 | owner, 69 | repo, 70 | perPage, 71 | pagerDirection, 72 | defaultAuthor 73 | } = this.options; 74 | return axiosGithub 75 | .post( 76 | "/graphql", 77 | getQL( 78 | { 79 | owner, 80 | repo, 81 | id: issue.number, 82 | pageSize: perPage, 83 | cursor: this.cursor 84 | }, 85 | pagerDirection 86 | ), 87 | { 88 | headers: { 89 | Authorization: `bearer ${this.accessToken}` 90 | } 91 | } 92 | ) 93 | .then(res => { 94 | const data = res.data.data.repository.issue.comments; 95 | const items = data.nodes.map(node => { 96 | const author = node.author || defaultAuthor; 97 | 98 | return { 99 | id: node.databaseId, 100 | gId: node.id, 101 | user: { 102 | avatar_url: author.avatarUrl, 103 | login: author.login, 104 | html_url: author.url 105 | }, 106 | created_at: node.createdAt, 107 | body_html: node.bodyHTML, 108 | body: node.body, 109 | html_url: `https://github.com/${owner}/${repo}/issues/${issue.number}#issuecomment-${node.databaseId}`, 110 | reactions: node.reactions 111 | }; 112 | }); 113 | 114 | let cs; 115 | 116 | if (pagerDirection === "last") { 117 | cs = [...items, ...this.comments]; 118 | } else { 119 | cs = [...this.comments, ...items]; 120 | } 121 | 122 | const isLoadOver = 123 | data.pageInfo.hasPreviousPage === false || 124 | data.pageInfo.hasNextPage === false; 125 | this.comments = cs; 126 | this.isLoadOver = isLoadOver; 127 | this.cursor = data.pageInfo.startCursor || data.pageInfo.endCursor; 128 | 129 | return cs; 130 | }); 131 | } 132 | 133 | export default getComments; 134 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/i18n/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "init": "Gitalking ...", 3 | "no-found-related": "Related %{link} not found", 4 | "please-contact": "Please contact %{user} to initialize the comment", 5 | "init-issue": "Init Issue", 6 | "leave-a-comment": "Leave a comment", 7 | "preview": "Preview", 8 | "edit": "Edit", 9 | "comment": "Comment", 10 | "support-markdown": "Markdown is supported", 11 | "login-with-github": "Login with GitHub", 12 | "first-comment-person": "Be the first guy leaving a comment!", 13 | "commented": "commented", 14 | "load-more": "Load more", 15 | "counts": "%{counts} comment |||| %{counts} comments", 16 | "sort-asc": "Sort by Oldest", 17 | "sort-desc": "Sort by Latest", 18 | "logout": "Logout", 19 | "anonymous": "Anonymous" 20 | } 21 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/i18n/es-ES.json: -------------------------------------------------------------------------------- 1 | { 2 | "init": "Gitalking ...", 3 | "no-found-related": "Link %{link} no encontrado", 4 | "please-contact": "Por favor contacta con %{user} para inicializar el comentario", 5 | "init-issue": "Iniciar Issue", 6 | "leave-a-comment": "Deja un comentario", 7 | "preview": "Avance", 8 | "edit": "Editar", 9 | "comment": "Comentario", 10 | "support-markdown": "Markdown es soportado", 11 | "login-with-github": "Entrar con GitHub", 12 | "first-comment-person": "Sé el primero en dejar un comentario!", 13 | "commented": "comentó", 14 | "load-more": "Cargar más", 15 | "counts": "%{counts} comentario |||| %{counts} comentarios", 16 | "sort-asc": "Ordenar por Antiguos", 17 | "sort-desc": "Ordenar por Recientes", 18 | "logout": "Salir", 19 | "anonymous": "Anónimo" 20 | } 21 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/i18n/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "init": "Gitalking ...", 3 | "no-found-related": "Lien %{link} non trouvé", 4 | "please-contact": "S’il vous plaît contactez %{user} pour initialiser les commentaires", 5 | "init-issue": "Initialisation des issues", 6 | "leave-a-comment": "Laisser un commentaire", 7 | "preview": "Aperçu", 8 | "edit": "Modifier", 9 | "comment": "Commentaire", 10 | "support-markdown": "Markdown est supporté", 11 | "login-with-github": "Se connecter avec GitHub", 12 | "first-comment-person": "Être le premier à laisser un commentaire !", 13 | "commented": "commenter", 14 | "load-more": "Charger plus", 15 | "counts": "%{counts} commentaire |||| %{counts} commentaires", 16 | "sort-asc": "Trier par plus ancien", 17 | "sort-desc": "Trier par plus récent", 18 | "logout": "Déconnexion", 19 | "anonymous": "Anonyme" 20 | } 21 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/i18n/index.js: -------------------------------------------------------------------------------- 1 | import Polyglot from 'node-polyglot' 2 | import ZHCN from './zh-CN.json' 3 | import ZHTW from './zh-TW.json' 4 | import EN from './en.json' 5 | import ES from './es-ES.json' 6 | import FR from './fr.json' 7 | import RU from './ru.json' 8 | 9 | const i18nMap = { 10 | 'zh': ZHCN, 11 | 'zh-CN': ZHCN, 12 | 'zh-TW': ZHTW, 13 | 'en': EN, 14 | 'es-ES': ES, 15 | 'fr': FR, 16 | 'ru': RU, 17 | } 18 | 19 | export default function (language) { 20 | return new Polyglot({ 21 | phrases: i18nMap[language] || i18nMap.en, 22 | locale: language 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/i18n/ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "init": "Gitalking ...", 3 | "no-found-related": "Связанные %{link} не найдены", 4 | "please-contact": "Пожалуйста, свяжитесь с %{user} чтобы инициализировать комментарий", 5 | "init-issue": "Выпуск инициализации", 6 | "leave-a-comment": "Оставить комментарий", 7 | "preview": "Предварительный просмотр", 8 | "edit": "Pедактировать", 9 | "comment": "Комментарий", 10 | "support-markdown": "Поддерживается Markdown", 11 | "login-with-github": "Вход через GitHub", 12 | "first-comment-person": "Будьте первым, кто оставил комментарий", 13 | "commented": "прокомментированный", 14 | "load-more": "Загрузить ещё", 15 | "counts": "%{counts} комментарий |||| %{counts} комментарьев", 16 | "sort-asc": "Сортировать по старым", 17 | "sort-desc": "Сортировать по последним", 18 | "logout": "Выход", 19 | "anonymous": "Анонимный" 20 | } 21 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/i18n/zh-CN.json: -------------------------------------------------------------------------------- 1 | { 2 | "init": "Gitalk 加载中 ...", 3 | "no-found-related": "未找到相关的 %{link} 进行评论", 4 | "please-contact": "请联系 %{user} 初始化创建", 5 | "init-issue": "初始化 Issue", 6 | "leave-a-comment": "说点什么", 7 | "preview": "预览", 8 | "edit": "编辑", 9 | "comment": "评论", 10 | "support-markdown": "支持 Markdown 语法", 11 | "login-with-github": "使用 GitHub 登录", 12 | "first-comment-person": "来做第一个留言的人吧!", 13 | "commented": "发表于", 14 | "load-more": "加载更多", 15 | "counts": "%{counts} 条评论", 16 | "sort-asc": "从旧到新排序", 17 | "sort-desc": "从新到旧排序", 18 | "logout": "注销", 19 | "anonymous": "未登录用户" 20 | } 21 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/i18n/zh-TW.json: -------------------------------------------------------------------------------- 1 | { 2 | "init": "Gitalk 載入中…", 3 | "no-found-related": "未找到相關的 %{link}", 4 | "please-contact": "請聯絡 %{user} 初始化評論", 5 | "init-issue": "初始化 Issue", 6 | "leave-a-comment": "寫點什麼", 7 | "preview": "預覽", 8 | "edit": "編輯", 9 | "comment": "評論", 10 | "support-markdown": "支援 Markdown 語法", 11 | "login-with-github": "使用 GitHub 登入", 12 | "first-comment-person": "成為首個留言的人吧!", 13 | "commented": "評論於", 14 | "load-more": "載入更多", 15 | "counts": "%{counts} 筆評論", 16 | "sort-asc": "從舊至新排序", 17 | "sort-desc": "從新至舊排序", 18 | "logout": "登出", 19 | "anonymous": "訪客" 20 | } 21 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/index.styl: -------------------------------------------------------------------------------- 1 | /* variables */ 2 | $gt-color-main := #6190e8 3 | $gt-color-sub := #a1a1a1 4 | $gt-color-loader := #999999 5 | $gt-color-error := #ff3860 6 | $gt-color-hr := #E9E9E9 7 | $gt-color-input-border := rgba(0,0,0,0.1) 8 | $gt-color-input-bg := #f6f6f6 9 | $gt-color-comment-bg := #f9f9f9 10 | $gt-color-comment-adminbg := #f6f9fe 11 | $gt-color-comment-txt := #333333 12 | $gt-color-link-active := #333333 13 | $gt-color-btn := #ffffff 14 | $gt-color-popbg := #ffffff 15 | $gt-size-base := 16px // default font-size 16 | $gt-size-border-radius := 5px 17 | $gt-breakpoint-mobile := 479px 18 | $gt-mask-z-index := 9999 19 | 20 | /* functions & mixins */ 21 | clearfix() { 22 | &:before, 23 | &:after { 24 | content: " "; 25 | display: table; 26 | } 27 | &:after { clear: both; } 28 | } 29 | em($px, $base-size = $gt-size-base) 30 | u = unit($px) 31 | if (u is 'px') 32 | unit($px / $base-size, 'em') 33 | else 34 | unit($px, u) 35 | 36 | mobile() 37 | @media (max-width: $gt-breakpoint-mobile) 38 | {block} 39 | 40 | /* variables - calculated */ 41 | $gt-size-loader-dot := em(6px) 42 | $gt-size-loader := em(28px) 43 | $gt-size-avatar := em(50px) 44 | $gt-size-avatar-mobi := em(32px) 45 | 46 | /* styles */ 47 | // Put everything under container to avoid style conflicts 48 | .gt-container 49 | box-sizing: border-box 50 | * 51 | box-sizing: border-box 52 | font-size: $gt-size-base 53 | // common 54 | a 55 | color: $gt-color-main 56 | &:hover 57 | color: lighten($gt-color-main, 20%) 58 | border-color: lighten($gt-color-main, 20%) 59 | &.is--active 60 | color: $gt-color-link-active 61 | cursor: default !important 62 | &:hover 63 | color: $gt-color-link-active 64 | .hide 65 | display: none !important 66 | // icons 67 | .gt-svg 68 | display: inline-block 69 | width: em(16px) 70 | height: em(16px) 71 | vertical-align: sub 72 | svg 73 | width: 100% 74 | height: 100% 75 | fill: $gt-color-main 76 | .gt-ico 77 | display: inline-block 78 | &-text 79 | margin-left: em(5px) 80 | &-github 81 | .gt-svg 82 | width: 100% 83 | height: 100% 84 | svg 85 | fill: inherit 86 | /* loader */ 87 | .gt-spinner 88 | position: relative 89 | &::before 90 | content: '' 91 | box-sizing: border-box 92 | position: absolute 93 | top: 3px 94 | width: em(12px) 95 | height: em(12px) 96 | margin-top: em(-3px) 97 | margin-left: em(-6px) 98 | border-radius: 50% 99 | border: 1px solid $gt-color-btn 100 | border-top-color: $gt-color-main 101 | animation: gt-kf-rotate .6s linear infinite 102 | 103 | .gt-loader 104 | position: relative 105 | border: 1px solid $gt-color-loader 106 | animation: ease gt-kf-rotate 1.5s infinite 107 | display: inline-block 108 | font-style: normal 109 | width: $gt-size-loader 110 | height: $gt-size-loader 111 | //font-size: $gt-size-loader 112 | line-height: $gt-size-loader 113 | border-radius: 50% 114 | &:before 115 | content: '' 116 | position: absolute 117 | display: block 118 | top: 0 119 | left: 50% 120 | margin-top: -($gt-size-loader-dot / 2) 121 | margin-left: -($gt-size-loader-dot / 2) 122 | width: $gt-size-loader-dot 123 | height: $gt-size-loader-dot 124 | background-color: $gt-color-loader 125 | border-radius: 50% 126 | // avatar 127 | .gt-avatar 128 | display: inline-block 129 | width: $gt-size-avatar 130 | height: $gt-size-avatar 131 | +mobile() 132 | width: $gt-size-avatar-mobi 133 | height: $gt-size-avatar-mobi 134 | img 135 | width: 100% 136 | height: auto 137 | border-radius: 3px 138 | &-github 139 | width: $gt-size-avatar - em(2px) 140 | height: $gt-size-avatar - em(2px) 141 | +mobile() 142 | width: $gt-size-avatar-mobi - em(2px) 143 | height: $gt-size-avatar-mobi - em(2px) 144 | // button 145 | .gt-btn 146 | padding: em(12px) em(20px) 147 | display: inline-block 148 | line-height: 1 149 | text-decoration: none 150 | white-space: nowrap 151 | cursor: pointer 152 | border: 1px solid $gt-color-main 153 | border-radius: $gt-size-border-radius 154 | background-color: $gt-color-main 155 | color: $gt-color-btn 156 | outline: none 157 | font-size: em(12px) 158 | &-text 159 | font-weight: 400 160 | &-loading 161 | position: relative 162 | margin-left: em(8px) 163 | display: inline-block 164 | width: em(12px) 165 | height: em(16px) 166 | vertical-align: top 167 | &.is--disable 168 | cursor: not-allowed 169 | opacity: 0.5 170 | &-login 171 | margin-right: 0 172 | &-preview 173 | background-color: $gt-color-btn 174 | color: $gt-color-main 175 | &:hover 176 | background-color: darken($gt-color-btn, 5%) 177 | border-color: lighten($gt-color-main, 20%) 178 | &-public 179 | &:hover 180 | background-color: lighten($gt-color-main, 20%) 181 | border-color: lighten($gt-color-main, 20%) 182 | &-loadmore 183 | // loadmore 184 | 185 | /* error */ 186 | .gt-error 187 | text-align: center 188 | margin: em(10px) 189 | color: $gt-color-error 190 | 191 | /* initing */ 192 | .gt-initing 193 | padding: em(20px) 0 194 | text-align: center 195 | &-text 196 | margin: em(10px) auto 197 | font-size: 92% 198 | 199 | /* no int */ 200 | .gt-no-init 201 | padding: em(20px) 0 202 | text-align: center 203 | 204 | /* link */ 205 | .gt-link 206 | border-bottom: 1px dotted $gt-color-main 207 | &-counts, &-project 208 | text-decoration: none 209 | 210 | /* meta */ 211 | .gt-meta 212 | margin: em(20px) 0 213 | padding: em(16px) 0 214 | position: relative 215 | border-bottom: 1px solid $gt-color-hr 216 | font-size: em(16px) 217 | position: relative 218 | z-index: 10 219 | clearfix() 220 | 221 | .gt-counts 222 | margin: 0 em(10px) 0 0 223 | 224 | .gt-user 225 | float: right 226 | margin: 0 227 | font-size: 92% 228 | &-pic 229 | width: 16px 230 | height: 16px 231 | vertical-align: top 232 | margin-right: em(8px) 233 | &-inner 234 | display: inline-block 235 | cursor: pointer 236 | .gt-ico 237 | margin: 0 0 0 em(5px) 238 | svg 239 | fill: inherit 240 | .is--poping 241 | .gt-ico 242 | svg 243 | fill: $gt-color-main 244 | 245 | .gt-version 246 | color: $gt-color-sub 247 | margin-left: em(6px) 248 | 249 | .gt-copyright 250 | margin: 0 em(15px) em(8px) 251 | border-top: 1px solid $gt-color-hr 252 | padding-top: em(8px) 253 | 254 | /* popup */ 255 | .gt-popup 256 | position: absolute 257 | right: 0 258 | top: em(38px) 259 | background: $gt-color-popbg 260 | display: inline-block 261 | border: 1px solid $gt-color-hr 262 | padding: em(10px) 0 263 | font-size: em(14px) 264 | letter-spacing: .5px 265 | .gt-action 266 | cursor: pointer 267 | display: block 268 | margin: em(8px) 0 269 | padding: 0 em(18px) 270 | position: relative 271 | text-decoration: none 272 | &.is--active 273 | &:before 274 | content: '' 275 | width: em(4px) 276 | height: em(4px) 277 | background: $gt-color-main 278 | position: absolute 279 | left: em(8px) 280 | top: em(7px) 281 | /* header */ 282 | .gt-header 283 | position: relative 284 | display: flex 285 | &-comment 286 | flex: 1 287 | margin-left: em(20px) 288 | +mobile() 289 | margin-left: em(14px) 290 | &-textarea 291 | padding: em(12px) 292 | display: block 293 | box-sizing: border-box 294 | width: 100% 295 | min-height: em(82px) 296 | max-height: em(240px) 297 | border-radius: $gt-size-border-radius 298 | border: 1px solid $gt-color-input-border 299 | font-size: em(14px) 300 | word-wrap: break-word 301 | resize: vertical 302 | background-color: $gt-color-input-bg 303 | outline: none 304 | transition: all 0.25s ease 305 | &:hover 306 | background-color: lighten($gt-color-input-bg, 50%) 307 | // box-shadow: 0 em(10px) em(60px) 0 $gt-color-input-bg 308 | &-preview 309 | padding: em(12px) 310 | border-radius: $gt-size-border-radius 311 | border: 1px solid $gt-color-input-border 312 | background-color: $gt-color-input-bg 313 | &-controls 314 | position: relative 315 | margin: em(12px) 0 0 316 | clearfix() 317 | +mobile() 318 | margin: 0 319 | &-tip 320 | font-size: em(14px) 321 | color: $gt-color-main 322 | text-decoration: none 323 | vertical-align: sub 324 | +mobile() 325 | display: none 326 | .gt-btn 327 | float: right 328 | margin-left: em(20px) 329 | +mobile() 330 | float: none 331 | width: 100% 332 | margin: em(12px) 0 0 333 | 334 | &:after 335 | content: '' 336 | position: fixed 337 | bottom: 100% 338 | left: 0 339 | right: 0 340 | top: 0 341 | opacity: 0 342 | &.gt-input-focused 343 | position: relative 344 | &:after 345 | content: '' 346 | position: fixed 347 | bottom: 0% 348 | left: 0 349 | right: 0 350 | top: 0 351 | background: #000 352 | opacity: 0.6 353 | transition: opacity .3s, bottom 0s 354 | z-index: $gt-mask-z-index 355 | .gt-header-comment 356 | z-index: $gt-mask-z-index + 1 357 | 358 | /* comments */ 359 | .gt-comments 360 | padding-top: em(20px) 361 | &-null 362 | text-align: center 363 | &-controls 364 | margin: em(20px) 0 365 | text-align: center 366 | 367 | /* comment */ 368 | .gt-comment 369 | position: relative 370 | padding: em(10px) 0 371 | display: flex 372 | &-content 373 | flex: 1 374 | margin-left: em(20px) 375 | padding: em(12px) em(16px) 376 | background-color: $gt-color-comment-bg 377 | overflow: auto 378 | transition: all ease 0.25s 379 | &:hover 380 | box-shadow: 0 em(10px) em(60px) 0 darken($gt-color-comment-bg, 2%) 381 | +mobile() 382 | margin-left: em(14px) 383 | padding: em(10px) em(12px) 384 | &-header 385 | margin-bottom: em(8px) 386 | font-size: em(14px) 387 | position: relative 388 | &-username 389 | font-weight: 500 390 | color: $gt-color-main 391 | text-decoration: none 392 | &:hover 393 | text-decoration: underline 394 | &-text 395 | margin-left: em(8px) 396 | color: $gt-color-sub 397 | &-date 398 | margin-left: em(8px) 399 | color: $gt-color-sub 400 | &-like, &-edit, &-reply 401 | position: absolute 402 | height: em(22px) 403 | &:hover 404 | cursor: pointer 405 | &-like 406 | top: 0 407 | right: em(32px) 408 | &-edit, &-reply 409 | top: 0 410 | right: 0 411 | &-body 412 | color: $gt-color-comment-txt !important 413 | &-admin 414 | .gt-comment-content 415 | background-color: $gt-color-comment-adminbg 416 | 417 | @keyframes gt-kf-rotate 418 | 0% 419 | transform: rotate(0) 420 | 100% 421 | transform: rotate(360deg) 422 | -------------------------------------------------------------------------------- /docs/.vuepress/components/comment/index.vue: -------------------------------------------------------------------------------- 1 |