Compare commits

...
181 Commits
Author SHA1 Message Date
github-actions[bot] 8af713636c chore: release v2.8.3 (#788)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-03-04 22:13:11 +08:00
qwqcode 5bf6e5f1dc fix(exception): missing message field after refactoring exception data structure 2024-03-04 21:04:38 +08:00
qwqcode 929faf0722 fix(sidebar/login): cannot select a name with the same email upon login (#781) 2024-03-04 21:01:04 +08:00
qwqcode 5322f90383 fix(captcha/image): unable to display image captcha on initial load 2024-03-04 20:56:31 +08:00
qwqcode fa3575cbae fix(conf): skip patching IP region conf if disabled 2024-03-04 20:05:20 +08:00
qwqcode c94a34ffd7 feat(comment): add is_verified field for comment entity 2024-02-16 19:43:35 +08:00
qwqcode 50b49448b6 feat(app): add onConfUpdated hook 2024-02-15 23:02:33 +08:00
qwqcode 8ff3f5e875 refactor(dao): validate the args of the FindCreateUser function 2024-02-14 00:21:48 +08:00
qwqcode 640fa7ded4 feat(ui/plugins): support dynamic loading of ui plug-in scripts (#774) 2024-02-12 21:12:55 +08:00
qwqcode 18123f7002 refactor(origin): extract CheckURLTrusted function 2024-02-12 20:36:43 +08:00
qwqcode cf2094667d feat(api/domain): add GET /conf/domain endpoint 2024-02-11 23:47:04 +08:00
qwqcode 2cd2165f06 refactor(entity/user): extract CheckPassword function 2024-02-11 23:36:19 +08:00
qwqcode 4eada4b628 feat(api/auth): invalidate old auth tokens after changing password 2024-02-11 23:34:32 +08:00
qwqcode 05f3ad043a feat(ui/editor): add beforeSubmit hook for editor submitting 2024-02-11 23:11:04 +08:00
qwqcode 6e9083e75d feat(ui/api): add ctx.getApiHandlers() to handle error responses and expose hooks 2024-02-11 23:00:22 +08:00
qwqcode 7bbdb5900f fix(ui/layer): ensure immediate operation when calling show() after hide() 2024-02-11 22:36:18 +08:00
qwqcode 5be45315dc chore(style/icon): standardized icon css styles 2024-02-09 16:59:58 +08:00
qwqcode 5d20ff1ef5 chore(fiber_logger): correct the http status code range for err log 2024-02-06 16:03:04 +08:00
qwqcode 86e0eeafd1 perf(ui/editor): improve the icon details for editor 2024-02-05 21:49:04 +08:00
github-actions[bot] 49c1a87a67 chore: release v2.8.2 (#769)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-02-05 19:09:15 +08:00
qwqcode ec7f81cb83 chore(docs): import artalk css via node 2024-02-05 19:01:39 +08:00
qwqcode 4b115d7b6a perf(ui/editor): optimize editor styles for narrow-width screens 2024-02-05 17:19:53 +08:00
qwqcode 1bae6d8d2a perf(ui/editor): modify editor plug-in text buttons to icons for brevity 2024-02-05 17:19:53 +08:00
qwqcode bdafa19470 perf(ui/editor): place Cancel Reply at the bottom of editor area (#644) 2024-02-05 17:19:40 +08:00
qwqcode 342236b6a7 perf(ui/lite): disable ArtalkLite preview config option by default 2024-02-05 17:05:00 +08:00
qwqcode ffce9f9e85 fix(style): replace style break-all with break-word in content el (#644) 2024-02-05 15:05:58 +08:00
qwqcode 0097e041b1 fix(api/comments): ua field is optional and not required (#767) 2024-02-05 14:30:17 +08:00
github-actions[bot] 42da621dfc chore: release v2.8.1 (#766)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-02-04 22:21:43 +08:00
qwqcode 2f5dbaa022 chore(i18n): update zh-CN 2024-02-04 22:02:13 +08:00
qwqcode e181a6d5dd perf(style/sidebar): improve some detail in sidebar 2024-02-04 21:55:59 +08:00
qwqcode 7873b21fb7 fix(ui/scroll): scroll into view issue when relativeTo parameter is provided 2024-02-04 21:53:02 +08:00
qwqcode 2a219518a4 feat(ui/goto): improved solution of navigating to comment via link hash (#693) (#765) 2024-02-04 21:47:06 +08:00
qwqcode afa7888db0 chore(typo): fix comment typo 2024-02-04 20:26:34 +08:00
qwqcode f6a589d5b2 refactor(ui/list): refactor the list layout manager 2024-02-04 20:25:21 +08:00
qwqcode 41a09d5996 refactor(ui/comment): loose coupling between Comment and Context 2024-02-04 20:15:28 +08:00
qwqcode 191977c0df feat(api): add GET /comments/:id endpoint (#764) 2024-02-04 20:08:38 +08:00
qwqcode 5a4c06daee chore(ip_region): skip empty string 2024-02-04 19:48:26 +08:00
qwqcode c4942ab807 chore(Makefile): add http-client build cmd to update-swagger 2024-02-04 03:24:58 +08:00
qwqcode 6b83a9f632 chore(transfer): remove the url_resolver disabled warning msg 2024-02-04 02:25:33 +08:00
qwqcode 3c88c0c29c docs: supplement and refine fe-api.md 2024-02-04 02:22:49 +08:00
qwqcode 35aab6bedc fix(ui/list): unable to reply or delete comments after switching pagination 2024-02-04 01:40:07 +08:00
qwqcode 17033dc111 fix(ui/no_comment): always appears when creating comment 2024-02-03 23:45:48 +08:00
qwqcode 559df60f0d fix(ui/pv): missing pageTitle field in the PV request 2024-02-03 23:12:12 +08:00
qwqcode 22d4ec1c31 chore(docs): rename IP region in zh-CN 2024-02-03 21:44:37 +08:00
qwqcode d97ad5c843 fix(ip_region): unable to output the IP region correctly (#760) 2024-02-03 21:43:42 +08:00
qwqcode 34a67f647b chore(docs): update cdn source links 2024-02-03 19:58:38 +08:00
qwqcode 9c3228b8fc feat(config): add db.prepare_stmt config option (#760) (#762)
The Prepared Statement database feature is enabled by default. You can disable it in config file or a env variable `ATK_DB_PREPARE__STMT=0`.
2024-02-03 19:19:00 +08:00
qwqcode 4012d3e090 fix(cmd/admin): update user role to admin if already exists 2024-02-03 16:54:13 +08:00
qwqcode bc1c4d315c fix(api/comments): counting comments issue in PostgreSQL db (#760) (#761) 2024-02-03 15:34:25 +08:00
qwqcode 2a6f0c56a4 chore(docs): fix script cdn links 2024-02-01 21:43:52 +08:00
github-actions[bot] 46e2a15116 chore: release v2.8.0 (#756)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-02-01 00:19:18 +08:00
qwqcode c068f5a240 chore(deps): bump golang deps 2024-02-01 00:11:34 +08:00
qwqcode 29bf49958f perf(ui/pagination): replace the prev/next text on pagination buttons with icons (#743) 2024-01-31 23:59:58 +08:00
qwqcode 2fcad539ca perf(ui/i18n): refine some translation (#743) 2024-01-31 23:28:56 +08:00
qwqcode 45b79124c9 chore(ui/deps): bump deps for ui 2024-01-31 20:27:14 +08:00
qwqcode 2b44452234 refactor(ui): optimize init and update lifecycle events 2024-01-31 19:44:40 +08:00
qwqcode 0e0b53fe9e perf(ui/sidebar): prevent potential token leakage by clearing query in iframe url
The previous referrer policy was already set to `strict-origin`, but to further enhance security, this modification was made.
2024-01-30 23:07:37 +08:00
qwqcode dba5ba5277 fix(ui/no_comment): flickering when clearing list before fetch 2024-01-30 22:24:53 +08:00
qwqcode 942aaf654f fix(ui/sidebar): incorrectly increasing pv count in sidebar (#724) 2024-01-30 20:27:19 +08:00
qwqcode 37e0091502 perf(ui/conf): support for watching partial changes in config with watchConf() (#755) 2024-01-30 19:14:09 +08:00
qwqcode a7c3f1bbda feat(notify): add notify_pending config option (#728) (#754) 2024-01-29 21:22:36 +08:00
qwqcode a40a070bdb chore(fix/pin): fix pinned comment sort rule 2024-01-29 14:46:19 +08:00
Frost Ming 082bfc63d1 fix(ui/editor): prevent propagation of click event in editor (#734)
Signed-off-by: Frost Ming <me@frostming.com>
2024-01-29 14:12:21 +08:00
qwqcode 0de8009e65 feat(ui/admin): add logout button in admin panel (#488) (#753)
fixes #488
2024-01-29 13:56:02 +08:00
qwqcode a5e4c81e72 fix(ui/sidebar_layer): sidebar still displays when login is required 2024-01-29 13:34:51 +08:00
qwqcode c52c26145c fix(ui/layer): unexpected behavior with multiple items when closing 2024-01-29 00:47:50 +08:00
qwqcode f5e310a182 chore(ui/ctx): remove token public in context 2024-01-28 22:14:24 +08:00
qwqcode 0828b91602 refactor(ui/comment): rename class Comment to CommentNode 2024-01-28 22:13:20 +08:00
qwqcode c4f664e412 refactor(ui/ctx): add getComments and getCommentNodes in context (#752)
* refactor(ui/ctx): add `getComments` and `getCommentNodes` func in context

* fix import
2024-01-28 22:03:15 +08:00
qwqcode a084c50095 refactor(transfer): normalize transfer payload parameter name 2024-01-28 13:33:03 +08:00
qwqcode 9dacd0954d fix(cache): unable to change admin list after caching (#748) (#750) 2024-01-26 22:27:10 +08:00
qwqcode 50b0a6068c chore(ci): fix ui test trigger rules 2024-01-26 17:16:18 +08:00
qwqcode 4689492bf5 fix(ui/pagination): auto load list when scroll reaches bottom 2024-01-26 17:09:56 +08:00
qwqcode 6ee9ee9ea4 fix(ui/lite): correct the instance name for compiling ArtalkLite (#740) 2024-01-26 11:45:22 +08:00
qwqcode 8e3a743ed8 fix(i18n): sidebar language cannot be changed
Also follow 0d35e66
2024-01-26 11:42:39 +08:00
qwqcode 9550a16a0c chore(fetch): returns empty object when json deserialize failed 2024-01-25 01:07:48 +08:00
qwqcode a9edac3ce0 refactor(api): update swagger file of API v2
BREAKING CHANGE: For Developers: The HTTP API has now been updated to version v2, with a lot of adjustments made, such as changing to Restful API style, request type, request body, response body, etc. data structure, adding error response codes. You can refer to #735 or https://artalk.js.org/http-api Please update all your existing clients to adapt to the new v2 server. The new base path is `/api/v2/`. The UI package's HTTP client has been implemented to auto-generate based on `Swagger.json`, and there have been a lot of adjustments to the `artalk.ctx.getApi()` related code. In addition, the HTTP API no longer enforces checks on the header's `Origin` and `Referer` (to implement strict isolation of different sites) but still maintains the original CORS origin check.

For General Users: Now all administrators have the same level of authority (there is no longer super admin authority), the function of assigning sub-administrators with independent scope authority to individual sites has been removed, which can simplify the HTTP server maintenance and implementation. Upgrading only requires updating the client and server application at the same time, and there are no additional operations.
2024-01-24 21:53:34 +08:00
qwqcode 589850d311 refactor(api): refactor HTTP API to version 2 (#735)
* refactor(api): refactor HTTP API to version 2

* refactor: remove forced site_origin check

* refactor: update http client

* fix

* add more api description and error code

* reduce nestings in response structures

* separate unread

* refactor(api/comments): get comments

* refactor: frontend api module

* chore: remove vite temporary file

* chore: restore swagger file

* update

* 移除为管理员分配站点名的站点隔离功能,简化实现

* refactor pagesAllFetch

* fix ci

* remove useless codes

* limiter protected paths

* add test for version endpoint

* rename handler code files

* code file separate

* fix some bug of interacting with backend

* add fetch error class for handling

* fix and rename

* refactor: checker support both `Promise` and callback fn

* fix new checker captcha iframe url

* rename and add swagger id field

* replace tab with spaces in go comment

* chore: refine

* complete the validate tag for request fields and enable `--defaultRequired`

90% of the request fields of our API are required,100% of response fields in our API are required.
Each field add validate:"required" is easy to miss.

* replace original api client with auto-generated codes

* artalk pkg apply new api client

* artalk-sidebar pkg apply new api client

* fix issues

* fix sidebar locale conf and refactor user login

* fix and refactor captcha and limiter

* fix ui testing

* add script to build http client by swagger.json
2024-01-24 21:33:30 +08:00
qwqcode 9ba9439831 chore(typo): fix typo for login in zh 2024-01-24 21:14:50 +08:00
qwqcode 38f6b6996a docs: update multi-sites manual (#747) 2024-01-24 21:01:56 +08:00
qwqcode 1e16570b2f chore(ci): fix ui test trigger rules 2024-01-24 16:24:36 +08:00
qwqcode 889adc6bae chore(docs): update security.md 2023-12-31 23:46:34 +08:00
qwqcode 0de59911b3 chore(docs): fix broken links 2023-12-29 12:40:04 +08:00
qwqcode f22e557b1c feat(go): upgrade golang to v1.21.5 and some deps 2023-12-28 23:26:56 +08:00
qwqcode 92ff757efc chore: fix docker build ci workflow 2023-12-28 21:43:17 +08:00
github-actions[bot]andqwqcode 63165599ce chore: release v2.7.3 (#726)
* chore: release v2.7.3

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: qwqcode <22412567+qwqcode@users.noreply.github.com>
2023-12-28 17:06:57 +08:00
qwqcode a5b428d1ec refactor(test/ui): add more ui api tests 2023-12-28 16:56:00 +08:00
qwqcode cf3f9b1ac3 chore: patch pacakge.json for i18n exports 2023-12-28 15:43:30 +08:00
qwqcode c212d67f49 perf(ui/build): better dts generation (#689)
* chore: move types as a subfolder of src

* perf(ui/build): better dts generation

* chore: update pnpm-lock.yaml

* chore: fix env variable on windows

* fix i18n types
2023-12-28 15:25:01 +08:00
qwqcode b00a257699 docs: update ui api documentation 2023-12-26 22:18:43 +08:00
3698c0c593 refactor(ui/conf): better handling of mutable config (#722)
* fix(ui): mergeDeep causes some configurations to be overridden by the default configuration

* fix: config always get override by defaults

Signed-off-by: Frost Ming <me@frostming.com>

* refactor(ui/conf): better handling of mutable config

* chore: fix path issue on win env

* fix: mergeDeep avoid prototype pollution

BREAKING CHANGE: Directly referencing `artalk.conf` and `artalk.$root` is deprecated. Please use functions instead: `artalk.getConf()` and `artalk.getEl()`.

---------

Signed-off-by: Frost Ming <me@frostming.com>
Co-authored-by: syfxlin <i@ixk.me>
Co-authored-by: Frost Ming <me@frostming.com>
2023-12-26 22:13:37 +08:00
qwqcode 32a398609c chore(tsconfig): modify moduleResolution to bundler 2023-12-26 00:30:50 +08:00
qwqcode 54729fbafc chore(build): use vite internal mergeConfig func 2023-12-26 00:06:21 +08:00
qwqcode b74e5cf94c refactor(ui/test): add vitest for unit testing 2023-12-26 00:03:08 +08:00
Frost Ming 475dd933fe fix(ui/init): stack overflow when merging with config defaults (#717)
Close #716
2023-12-23 21:40:18 +08:00
qwqcode 60e0e7e61a chore(ci): fixed tag version for git checkout branch 2023-12-23 01:32:19 +08:00
qwqcode e4a42d3a90 refactor(docker): add --build-arg argument to skip ui build 2023-12-22 23:54:32 +08:00
qwqcode d86cd73ea6 refactor(ci): better release workflow 2023-12-22 22:06:09 +08:00
qwqcode 67280f2ca2 feat(ci): add dry-run mode for build workflow 2023-12-22 02:30:54 +08:00
qwqcode a8bcd41f36 refactor(ui): refactor directory structure (#712)
* refactor(ui): refactor directory structure

* update config files

* update github workflows

* update vscode settings.json

* update docs

* update build scripts

* tidy up

* fix docs build
2023-12-21 23:51:26 +08:00
qwqcode 04cf137a74 feat(cmd): support cli flag for creating admin account 2023-12-21 22:35:10 +08:00
qwqcode d542e98581 chore(eslint): fix sidebar eslint configuration 2023-12-21 22:28:24 +08:00
qwqcode dfaf95bf1d chore(docs): bump Artalk to v2.7.2 2023-12-21 01:51:36 +08:00
github-actions[bot] 0a89426c93 chore: release v2.7.2 2023-12-20 17:20:40 +00:00
qwqcode 7a026ef0e2 fix(sidebar): sidebar language switch and config save issue (#708) 2023-12-21 01:14:49 +08:00
qwqcode 855f6c261f docs(i18n): add translation for open button 2023-12-20 23:35:58 +08:00
qwqcode 7099598a92 fix(ui): add referrerpolicy attribute for iframe (#687) (#707) 2023-12-20 23:34:46 +08:00
qwqcode ad8851ea94 fix(ui/pagination): auto switch page by url hashtag issue (#693) 2023-12-20 21:44:06 +08:00
qwqcode def9dc2707 fix(ui/sidebar): refactor settings and fix save issue (#677) (#706) 2023-12-20 20:53:04 +08:00
Mr.Hopeandqwqcode 91228a9446 docs(refactor): organize the pkgs and fix some issues (#702)
* docs: rebuild docs

* chore: fix eslint

* ci: add docs build test

* update test-docs.yml

* fix script

* add netlify.toml

* fix docs:patch

---------

Co-authored-by: qwqcode <qwqcode@gmail.com>
2023-12-19 21:55:04 +08:00
qwqcode 7a0a9dbd92 chore(ci): fix ci pnpm version 2023-12-19 17:07:23 +08:00
dependabot[bot] 441c4fa6a9 chore(deps/ui): bump the dev-deps group in /ui with 3 updates (#698)
Bumps the dev-deps group in /ui with 3 updates: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) and [@vue/tsconfig](https://github.com/vuejs/tsconfig).


Updates `@typescript-eslint/eslint-plugin` from 6.14.0 to 6.15.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.15.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 6.14.0 to 6.15.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.15.0/packages/parser)

Updates `@vue/tsconfig` from 0.5.0 to 0.5.1
- [Commits](https://github.com/vuejs/tsconfig/compare/v0.5.0...v0.5.1)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-deps
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-deps
- dependency-name: "@vue/tsconfig"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-19 17:04:01 +08:00
Mr.Hope a16169f69d chore(docs): fix redocly config (#696) 2023-12-19 17:00:58 +08:00
da42676656 chore(deps): bump frontend deps (#679)
* chore: bump deps

* chore: add exports field

* chore: remove src folder

* fix: vite cjs deprecated warning

* chore(ci): fix test ci

* chore: update linter

---------

Co-authored-by: qwqcode <qwqcode@gmail.com>
Co-authored-by: qwqcode <22412567+qwqcode@users.noreply.github.com>
2023-12-19 16:54:34 +08:00
qwqcode f3a42e892f chore(ci): fix test ci 2023-12-18 23:59:18 +08:00
Mr.Hope 6a53597485 chore(docs): update README.md (#691) 2023-12-18 23:19:46 +08:00
qwqcode 60336e567d test(ci): migrate UI tests back to Github Actions (#692) 2023-12-18 23:16:16 +08:00
Mr.Hopeandqwqcode 8918c62ffd chore: update description and fix typos (#684)
* chore: update description

* chore: fix typos

* chore: tweaks

* chore: fix case

---------

Co-authored-by: qwqcode <qwqcode@gmail.com>
2023-12-18 21:21:42 +08:00
qwqcode 362fc19cd8 feat: patch locale config from zh-cn to zh-CN (#678) 2023-12-18 20:17:04 +08:00
qwqcode 1b938752ff fix(ui/dark-mode): potential memory leak issue in auto mode (#688) 2023-12-18 19:14:58 +08:00
qwqcode 835a886dc8 test(ssg): add SSG test case (#675) 2023-12-18 19:09:04 +08:00
qwqcode f390b57fe7 refactor(ui): move window references into function scope (#675) 2023-12-18 19:05:57 +08:00
qwqcode 6d21a0f204 refactor(ui/api): losing coupling between Api and User 2023-12-18 18:37:18 +08:00
qwqcode a1d0c37828 refactor(ui/user): user class no longer globally singleton 2023-12-18 18:37:18 +08:00
github-actions[bot] 763fbc417e chore: release v2.7.1 2023-12-17 17:24:29 +00:00
qwqcode 776d5e66fe docs(i18n): add translation of update notice 2023-12-18 01:22:53 +08:00
qwqcode 10c0975ce0 fix(build): generate source maps to ease debugging 2023-12-18 00:53:54 +08:00
qwqcode 7286642fc9 fix(ui): static method export issue in JS module (#669) 2023-12-18 00:46:56 +08:00
qwqcode 8db4fb3524 fix(cout-widget): loadCountWidget issue 2023-12-17 23:50:44 +08:00
qwqcode 08be04979d chore(docs): bump Artalk to v2.7.0 2023-12-17 20:33:21 +08:00
github-actions[bot] d7ea9ba43f chore: release v2.7.0 2023-12-17 11:57:30 +00:00
qwqcode bad248534c docs: revise and add more examples
BREAKING CHANGE: The following top-level functions exported by the 'artalk' npm package have been deprecated: `Artalk.update`, `Artalk.reload`, and `Artalk.destroy`. These methods now require invocation on an instance created by either `Artalk.init` or `new Artalk`. Please utilize instance-level methods instead, such as `artalkInstance.update`. For more information, refer to  [the documentation](https://artalk.js.org/guide/frontend/import-framework.html). The update was implemented to enable the concurrent creation of multiple instances, adapting to situations where Vue components are simultaneously referenced across various pages. Initially, only a singular instance was permitted to mitigate memory leak concerns. However, this proved limiting for scenarios involving the caching of multiple component instances through 'keep-alive.' To better suit intricate SPA application needs, the choice was made to permit the creation of multiple independent instances. It's crucial to remember to manually invoke the `artalk.destroy` method when releasing components to avoid memory leaks (Issue #660).
2023-12-17 19:16:33 +08:00
Zijing Zhang f56ac4eabc perf(cache): implement GC feature for simple_cache pkg (#656)
* feat: garbage collection feature

A new `GC()` method has been added to the `Cache` struct,
which performs garbage collection by deleting expired entries from the
cache.
2023-12-17 02:32:47 +08:00
qwqcode bbe2e8416c chore(docs): more description for VitePress example 2023-12-17 02:23:43 +08:00
qwqcode d44e79b1f4 docs(import): update the examples in import-framework.md (#665) 2023-12-17 01:54:21 +08:00
qwqcode e816dd686c fix(api/img-upload): public_path config enables the use of full url (#659) (#664) 2023-12-17 01:29:59 +08:00
qwqcode c9ea8f6162 fix(lifecycle): create multi-instances at the same time (#660) (#663) 2023-12-17 01:16:27 +08:00
qwqcode 87102cd3b0 refactor(ui/layer): better layer implements and independence (#662) 2023-12-17 01:10:22 +08:00
qwqcode 8b6bab828d fix(ui/dark-mode): setDarkMode cannot save to instance config (#661) 2023-12-17 01:04:30 +08:00
qwqcode 9fb658599a test(vue): add test cases for vue framework 2023-12-17 00:48:24 +08:00
qwqcode f8c33003a8 chore(docs): replace artalk to npm import in docs 2023-12-15 20:20:24 +08:00
qwqcode b97136b83f chore(docs): tidy up documentation 2023-12-13 19:09:14 +08:00
qwqcode df3e983e7f docs(conf): disable frontend.uaBadge config option by default 2023-12-13 19:06:57 +08:00
qwqcode 1b878fb3cc fix(ui): scroll to the center of the viewport issue 2023-12-13 18:57:03 +08:00
LeenHawk aa87ab94f5 docs(deploy): add deployment guide for render.com (#649)
* 添加render.com部署指南文章链接

* Update
2023-11-21 21:38:26 +08:00
qwqcode 4e9afd9761 fix(ui/editor): fix position of the comment box when replying (#643) (#648) 2023-11-20 19:21:44 +08:00
qwqcode 2b7d0ecb72 chore(ci): integrate with codecov 2023-11-19 23:35:12 +08:00
qwqcode 603c7d9439 docs: provide clearer and more detailed instructions in CONTRIBUTING.md 2023-11-05 22:48:00 +08:00
qwqcode fb93231b35 feat(ui/test): add end-to-end (e2e) testing using Playwright 2023-11-05 22:45:53 +08:00
qwqcode fed83263e2 fix(notify_pusher): panic when admin ids array is empty (#634) 2023-11-03 10:39:56 +08:00
qwqcode 9dc2d83486 chore(dev): fix .eslintignore in vscode
Add this config in `.vscode/settings.json`: `{"eslint.workingDirectories": ["./path/to/nested/front/project"]}` In this case, your `.eslintignore` file should be located in the nested path location (you have a front project in a nested folder inside the main project at root).
2023-11-01 10:59:58 +08:00
qwqcode d918caaf81 fix(ui/conf): sanitize noComment conf option for security (#624) 2023-10-31 20:11:47 +08:00
qwqcode d44212bd90 refactor(ui/marked): separate markdown related codes 2023-10-30 20:13:18 +08:00
qwqcode 37d4ca76fa refactor(ui): reduce coupling with ContextApi 2023-10-30 19:50:32 +08:00
qwqcode 8cc39f322c chore(ui/deps): downgrade eslint-import-resolver-typescript
Downgrade `eslint-import-resolver-typescript` to version 2.7.0 to resolve linting issue on Windows development environment.

https://github.com/ArtalkJS/Artalk/discussions/621#discussioncomment-7416173
2023-10-29 22:59:47 +08:00
qwqcode 2b4e80651a feat(ui): support scrollRelativeTo config option 2023-10-29 21:52:59 +08:00
qwqcode 415fa0f2e3 chore(ui/sidebar): fix sidebar dependant issues caused by refactoring 2023-10-29 21:51:54 +08:00
qwqcode 91809002d7 chore(ui): fix issues caused by refactoring 2023-10-29 19:01:16 +08:00
qwqcode dcaad1b2d5 chore(ui/lint): follow the import/no-cycle eslint rule 2023-10-29 13:12:36 +08:00
qwqcode 5e635bba68 chore(ui/list): let the service of list non-optional 2023-10-28 20:33:38 +08:00
qwqcode d136d086eb refactor(ui/stat): losing coupling of CountWidget 2023-10-28 20:07:55 +08:00
qwqcode 9fe765f874 refactor(ui/api): loose coupling between Api and Context 2023-10-28 00:02:17 +08:00
qwqcode 72317ead34 refactor(ui): separate standalone admin-only-elem checker 2023-10-27 22:50:24 +08:00
qwqcode 75c7914fb1 refactor(ui/types): better ArtalkType import and export (#620) 2023-10-27 22:24:53 +08:00
qwqcode 863b4deec0 refactor(ui/conf): loose coupling between config and list fetch 2023-10-27 17:23:05 +08:00
qwqcode 6e6fd8d587 refactor(ui/marked): loose coupling with marked func 2023-10-27 16:32:24 +08:00
qwqcode 1608911328 refactor(ui/list): separate list into standalone components (#618)
* refactor(ui/list): separate the functions of list

* fix

* move files
2023-10-27 14:28:58 +08:00
qwqcode 87a62961b6 fix(style/list): replace float to text-align in footer part (#619) 2023-10-27 00:24:11 +08:00
qwqcode e6a9748e70 refactor(ui/plugin): further divide functionality into plugins (#615)
* move stat to plugins folder

* move editor plugs to common plugins folder

* implement list-close-editor standalone plugin

* impl StateManager for Loose Coupling of Reply, Edit, and Submit Components

* rename

* remove Mover dep in editor edit state plugin

* rename editor state plugins

* refactor header plugin of editor

* separate header plugins

* add and remove event binding

* fix plugin btn ui refresh when conf updating

* rename editor plugins and remove plug classname suffix

* editor kit reload plugin when conf-loaded

* impl clear method in editor-kit class

* separate version-check from list

* separate unread from list

* make context maintain globally accessible `page` data

* rename plug to plugin

* wrap the options of List up

* separate functionalities of list

* rename
2023-10-20 17:14:53 +08:00
qwqcode 0f35532f0b refactor(editor): refactor plug kit and events (#613) 2023-10-17 20:11:47 +08:00
qwqcode d21e47f881 refactor(ui/event): refactor core event manager (#611) 2023-10-15 23:08:31 +08:00
qwqcode 8d11a239fa refactor(editor): refactor editor plugin manager (#609)
* refactor(editor): refactor editor plugin manager

* update

* modify editorTravelBack to editorResetUI
2023-10-15 21:05:30 +08:00
github-actions[bot] 8867eb296c chore: release v2.6.4 2023-10-12 06:19:33 +00:00
qwqcode a53ddc9f76 feat(go): upgrade golang to v1.21.3 and some deps 2023-10-12 14:14:07 +08:00
qwqcode 5ee9e76dcf fix(style): fix copyright text overlay on send button (#607) 2023-10-12 13:35:24 +08:00
qwqcode 3d5f77ab35 fix(email): sender not initialized correctly 2023-10-12 13:30:45 +08:00
qwqcode 25a4f48e5e fix(editor): fix duplicate event binding when update conf (#605) 2023-10-12 09:48:34 +08:00
qwqcode 2dc3bc8934 test(simple_cache): add unit test 2023-09-25 21:15:58 +08:00
qwqcode 7b1bb25d6a test(image_captcha): add unit test 2023-09-25 21:07:05 +08:00
qwqcode 9bed5be236 test(email): add unit test for queue 2023-09-25 20:54:22 +08:00
qwqcode ec0ef12b0e refactor(anti_spam): refactor anti_spam pkg and add unit test (#589)
* refactor(anti_spam): refactor anti_spam pkg and add unit test

* add more test
2023-09-21 21:48:56 +08:00
652 changed files with 37421 additions and 27434 deletions

No files matched your search

+9 -35
View File
@@ -2,6 +2,7 @@ version: 2.1
orbs:
node: circleci/node@5.0.3
codecov: codecov/codecov@3.3.0
executors:
base:
@@ -9,18 +10,15 @@ executors:
- image: cimg/base:stable
node:
docker:
- image: 'cimg/node:18.17.1'
- image: 'cimg/node:18.19.0'
go:
docker:
- image: cimg/go:1.21.0
- image: cimg/go:1.21.5
parameters:
trigger-app:
type: boolean
default: false
trigger-ui:
type: boolean
default: false
run-them-all:
type: boolean
default: false
@@ -40,40 +38,24 @@ jobs:
go version
- restore_cache:
keys:
- go-mod-1.21.0-{{ checksum "go.sum" }}
- go-mod-1.21.5-{{ checksum "go.sum" }}
- run:
name: Install Dependencies
command: go mod download
- save_cache:
key: go-mod-1.21.0-{{ checksum "go.sum" }}
key: go-mod-1.21.5-{{ checksum "go.sum" }}
paths:
- "~/go/pkg/mod"
- run:
name: Run tests
command: |
mkdir -p /tmp/test-reports
gotestsum --junitfile /tmp/test-reports/unit-tests.xml
gotestsum --junitfile /tmp/test-reports/unit-tests.xml -- -coverprofile=/tmp/test-reports/coverage.out ./...
- store_test_results:
path: /tmp/test-reports
## Frontend
test_ui:
executor: node
steps:
- node/install
- checkout
- run:
name: Print the node version
command: node -v
- run:
name: Install pnpm
command: npm i -g pnpm@8.7.0
- run:
name: Install Dependencies
command: pnpm --dir ./ui install --frozen-lockfile
- run:
name: Build Artalk
command: pnpm --dir ./ui build:all
- codecov/upload:
flags: go
file: /tmp/test-reports/coverage.out
all_projects:
executor: base
@@ -91,14 +73,6 @@ workflows:
jobs:
- test_app
build-ui:
when:
or:
- << pipeline.parameters.trigger-ui >>
- << pipeline.parameters.run-them-all >>
jobs:
- test_ui
build-shared-other:
when: << pipeline.parameters.run-them-all >>
jobs:
-1
View File
@@ -17,7 +17,6 @@ workflows:
mapping: |
(cmd|internal|server|pkg|test|conf)/.* trigger-app true
main.go|go.mod|go.sum trigger-app true
(ui)/.* trigger-ui true
base-revision: master # git branch name
config-path: .circleci/conditional_config.yml
filters:
+1
View File
@@ -0,0 +1 @@
node_modules
+5 -2
View File
@@ -7,5 +7,8 @@ coverage
vite*.config*
# 不检测 js
**/*.js
# ignore all js files
**/*.*js
# ignore all config files
*.config.ts
+16 -14
View File
@@ -1,9 +1,11 @@
const path = require('node:path')
module.exports = {
root: true,
parser: "@typescript-eslint/parser",
env: { "browser": true },
parser: '@typescript-eslint/parser',
env: { browser: true },
parserOptions: {
project: ['./packages/*/tsconfig.json'],
project: ['./ui/*/tsconfig.json'],
tsconfigRootDir: __dirname,
},
extends: [
@@ -12,37 +14,37 @@ module.exports = {
'prettier',
'plugin:import/recommended',
'plugin:import/typescript',
"plugin:compat/recommended",
'plugin:compat/recommended',
],
plugins: ['@typescript-eslint', 'import'],
rules: {
'no-alert': 'off',
'no-unused-vars': 'off',
'no-alert': 'warn',
'no-unused-vars': 0,
'no-plusplus': 0,
'no-param-reassign': 0,
'no-console': 0,
'no-underscore-dangle': 0,
'no-constructor-return': 0,
'class-methods-use-this': 0,
'spaced-comment': 0,
'no-lonely-if': 0,
'prefer-destructuring': 0,
'import/no-cycle': 0,
'import/prefer-default-export': 0,
'import/no-extraneous-dependencies': 0,
'@typescript-eslint/lines-between-class-members': 0,
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-use-before-define': 0,
'@typescript-eslint/naming-convention': 0,
'@typescript-eslint/no-useless-constructor': 0,
'@typescript-eslint/no-unused-expressions': 0, // for `func && func()` expressions
},
settings: {
'import/resolver': {
typescript: {
"project": [__dirname + "/packages/*/tsconfig.json"]
project: ['ui/artalk/tsconfig.json'].map((p) =>
path.resolve(__dirname, p),
),
},
},
'polyfills': [
'AbortController'
]
polyfills: ['AbortController'],
},
// @see https://stackoverflow.com/questions/63118405/how-to-fix-eslintrc-the-file-does-not-match-your-project-config
ignorePatterns: ['.eslintrc.js'],
}
+25
View File
@@ -0,0 +1,25 @@
name: Comment issue
description: Create comment on a issue
inputs:
issue_number:
required: true
description: The issue number you want to comment
content:
required: true
description: The content of comment
runs:
using: "composite"
steps:
- uses: actions/github-script@v7
env:
STDOUT: ${{ inputs.content }}
with:
script: |
github.rest.issues.createComment({
issue_number: ${{ inputs.issue_number }},
owner: context.repo.owner,
repo: context.repo.repo,
body: process.env.STDOUT
})
+21 -19
View File
@@ -1,13 +1,18 @@
name: Build App
run-name: Build Go App and Publish
on:
repository_dispatch:
types: [artalk-release]
workflow_call:
inputs:
version:
required: true
type: string
dry_run:
required: true
type: boolean
env:
GO_VERSION: '1.21.0'
PKG_NAME: 'github.com/ArtalkJS/Artalk'
GO_VERSION: 1.21.5
PKG_NAME: github.com/ArtalkJS/Artalk
DOCKER_IMG: ghcr.io/goreleaser/goreleaser-cross
CACHE_DIR: /tmp/cache/docker-image
@@ -17,18 +22,12 @@ jobs:
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Checkout latest tag
run: |
# fetch tags
git fetch --prune --unshallow --tags -f
# checkout latest version
VERSION=$(git describe --tags --abbrev=0)
git checkout ${VERSION}
echo "VERSION=${VERSION}" >> $GITHUB_ENV
uses: actions/checkout@v4
with:
ref: ${{ inputs.version }}
# `go-releaser` will read the semver version from git tag name
# `git-chglog` will diff the tag and generate changelog
fetch-depth: 0
# disable cache because the err `no space left on device`
# - name: Docker Image Cache
@@ -64,11 +63,14 @@ jobs:
echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" > local/.release-env
# changelog
git-chglog --config .github/chglog/config.yml ${VERSION} > local/release-notes.md
git-chglog --config .github/chglog/config.yml ${{ inputs.version }} > local/release-notes.md
# copy config file
cp conf/artalk.example.yml artalk.yml
- name: Print Relase Notes
run: cat local/release-notes.md
- name: Build and Release
run: |
docker run \
@@ -81,4 +83,4 @@ jobs:
-e CGO_ENABLED=1 \
--env-file local/.release-env \
ghcr.io/goreleaser/goreleaser-cross:v${GO_VERSION} \
release --release-notes local/release-notes.md
release --release-notes local/release-notes.md ${{ inputs.dry_run && '--skip=publish' || '' }}
+45 -73
View File
@@ -1,9 +1,17 @@
name: Build Docker
run-name: Build Docker Image and Publish
on:
repository_dispatch:
types: [artalk-release]
workflow_call:
inputs:
version:
required: true
type: string
dry_run:
required: true
type: boolean
target:
required: true
type: string
env:
DOCKER_IMG: artalk/artalk-go
@@ -14,58 +22,14 @@ jobs:
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Checkout latest tag
run: |
# fetch tags
git fetch --prune --unshallow --tags -f
# checkout latest version
VERSION=$(git describe --tags --abbrev=0)
git checkout ${VERSION}
VERSION_SHORT="$(cut -d '.' -f 1,2 <<< ${VERSION#v})" # (i.e "v1.2.3" -> "1.2")
COMMIT_HASH="$(git rev-parse --short HEAD)"
COMMIT_HASH_FULL="$(git rev-parse HEAD)"
echo "VERSION=${VERSION}" >> $GITHUB_ENV
echo "VERSION_SHORT=${VERSION_SHORT}" >> $GITHUB_ENV
echo "COMMIT_HASH=${COMMIT_HASH}" >> $GITHUB_ENV
echo "COMMIT_HASH_FULL=${COMMIT_HASH_FULL}" >> $GITHUB_ENV
# https://github.com/docker/login-action
- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
uses: actions/checkout@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# https://github.com/docker/setup-qemu-action
- name: Setup QEMU
id: qemu
uses: docker/setup-qemu-action@v2
with:
platforms: 'amd64,arm64'
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v2
- name: Cache Docker layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
ref: ${{ inputs.version }}
# https://github.com/docker/metadata-action
- name: Gen docker meta
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
context: git
images: |
@@ -77,34 +41,42 @@ jobs:
type=semver,pattern={{major}}.{{minor}}
type=sha
# https://github.com/docker/login-action
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# https://github.com/docker/setup-qemu-action
- name: Setup QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: ${{ inputs.target }}
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
# Build UI outside of Docker to speed up cross-platform builds
- name: Build UI
run: |
make build-frontend
# https://github.com/docker/build-push-action
- name: Build and Push
id: docker_build
uses: docker/build-push-action@v4
id: build
uses: docker/build-push-action@v5
with:
builder: ${{ steps.buildx.outputs.name }}
context: ./
push: ${{ !inputs.dry_run }}
context: .
file: ./Dockerfile
platforms: 'linux/amd64,linux/arm64'
push: true
build-args: |
APP_VERSION=${{ inputs.version }}
SKIP_UI_BUILD=true
platforms: ${{ inputs.target }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Comment build info in commit
uses: actions/github-script@v6
env:
STDOUT: "🐳 Published new docker image: [${{ env.DOCKER_IMG }}](https://hub.docker.com/r/${{ env.DOCKER_IMG }}) (${{ env.VERSION }} / sha-${{ env.COMMIT_HASH }})"
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.repos.createCommitComment({
owner: context.repo.owner,
repo: context.repo.repo,
commit_sha: process.env.COMMIT_HASH_FULL, // context.sha
body: process.env.STDOUT
})
- name: Print image digest
run: echo ${{ steps.docker_build.outputs.digest }}
run: echo ${{ steps.build.outputs.digest }}
+31
View File
@@ -0,0 +1,31 @@
name: Build Done
on:
workflow_call:
inputs:
version:
required: true
type: string
dry_run:
required: true
type: boolean
issue_number:
required: true
type: number
jobs:
done:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
ref: ${{ inputs.version }}
- name: Comment done info
uses: ./.github/actions/comment
if: ${{ inputs.issue_number != 0 }}
with:
issue_number: ${{ inputs.issue_number }}
content: |-
🎉 Finished build and publish ${{ inputs.version }} ([NPM Package](https://www.npmjs.com/package/artalk?activeTab=versions) / [Docker Image](https://hub.docker.com/r/artalk/artalk-go/tags) / [Github Release](https://github.com/ArtalkJS/Artalk/releases/tag/${{ inputs.version }})).
-58
View File
@@ -1,58 +0,0 @@
name: Build Frontend
run-name: Build Frontend and Publish
on:
repository_dispatch:
types: [artalk-release]
jobs:
build_publish:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./ui # set for building frontend
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Checkout latest tag
run: |
git fetch --prune --unshallow --tags -f
git checkout $(git describe --tags --abbrev=0)
- name: Use pnpm
uses: pnpm/action-setup@v2
with:
version: 8
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 18.x
registry-url: https://registry.npmjs.org/
cache: 'pnpm'
cache-dependency-path: './ui/pnpm-lock.yaml'
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm build
- name: Publish
run: pnpm publish -F artalk --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# GitHub Packages
#
# Setup .npmrc file to publish to GitHub Packages
# - uses: actions/setup-node@v2
# with:
# registry-url: 'https://npm.pkg.github.com'
# # Publish to GitHub Packages
# - run: npm publish
# env:
# NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+60
View File
@@ -0,0 +1,60 @@
name: Build Pre Tagging
on:
workflow_call:
inputs:
dry_run:
required: true
type: boolean
issue_number:
required: true
type: number
outputs:
version:
description: 'Version'
value: ${{ jobs.tagging.outputs.version }}
jobs:
tagging:
runs-on: ubuntu-latest
steps:
- name: Get release version
run: |
# `github.head_ref` only exists for pull_request events
REF="${{ github.head_ref || github.ref }}"
VERSION="${REF#release/}"
VERSION="${VERSION#refs/tags/}"
echo "Version: $VERSION"
echo "VERSION=$VERSION" >> $GITHUB_ENV
if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Invalid version format: $VERSION, please check git ref or tag."
exit 1
fi
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Create Tag
run: |
if [ ! $(git tag -l "${VERSION}") ]; then
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git tag -a $VERSION -m "Release $VERSION"
git push origin $VERSION
else
echo "Skip creating tag $VERSION, already exists."
fi
- name: Comment tag info to PR
uses: ./.github/actions/comment
if: ${{ inputs.issue_number != 0 }}
with:
issue_number: ${{ inputs.issue_number }}
content: |-
🔖 Tagged version [${{ env.VERSION }}](https://github.com/ArtalkJS/Artalk/tree/${{ env.VERSION }}) and updated the [CHANGELOG.md](https://github.com/ArtalkJS/Artalk/blob/master/CHANGELOG.md).
outputs:
version: ${{ env.VERSION }}
+55
View File
@@ -0,0 +1,55 @@
name: Build UI
on:
workflow_call:
inputs:
version:
required: true
type: string
dry_run:
required: true
type: boolean
jobs:
build_publish:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
ref: ${{ inputs.version }}
- name: Use pnpm
uses: pnpm/action-setup@v2
with:
version: 8
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 18.x
registry-url: https://registry.npmjs.org/
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm build
- name: Publish
run: pnpm publish -F artalk --no-git-checks ${{ inputs.dry_run && '--dry-run' || '' }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# GitHub Packages
#
# Setup .npmrc file to publish to GitHub Packages
# - uses: actions/setup-node@v4
# with:
# registry-url: 'https://npm.pkg.github.com'
# # Publish to GitHub Packages
# - run: npm publish
# env:
# NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+82
View File
@@ -0,0 +1,82 @@
name: Build and Publish
run-name: Build and Publish (${{ github.head_ref || github.ref }}) ${{ inputs.dry_run && '(🧪 Dry-Run)' || '' }}
on:
pull_request:
branches: [master]
types: [closed]
workflow_dispatch:
inputs:
dry_run:
description: 'Dry run'
type: boolean
default: true
build_items:
description: 'Build items'
type: string
default: 'ui,app,docker'
jobs:
# Tag the release version code before building
# Getting the version code from the branch name or git ref.
tagging:
# Only run on manual trigger
# or when a PR is merged into master.
# (which the branch name start with `relase/`)
if: |
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.merged == true && startsWith(github.head_ref, 'release/'))
uses: ./.github/workflows/build-tagging.yml
with:
issue_number: ${{ github.event.pull_request.number || 0 }}
dry_run: ${{ inputs.dry_run || false }}
secrets: inherit
# Build the UI
ui:
if: inputs.build_items == '' || contains(inputs.build_items, 'ui')
needs: tagging
uses: ./.github/workflows/build-ui.yml
with:
version: ${{ needs.tagging.outputs.version }}
dry_run: ${{ inputs.dry_run || false }}
secrets: inherit
# Build the Docker image
docker:
if: inputs.build_items == '' || contains(inputs.build_items, 'docker')
needs: tagging
uses: ./.github/workflows/build-docker.yml
# Parallel build the multi-arch docker image
strategy:
matrix:
# since docker push actions will override the previous images,
# so need to build `linux/amd64` and push first,
# then build `linux/amd64` twice with other archs (build very slow so keep it last).
target: ["linux/amd64", "linux/amd64,linux/arm64,linux/arm/v7"]
with:
version: ${{ needs.tagging.outputs.version }}
dry_run: ${{ inputs.dry_run || false }}
target: ${{ matrix.target }}
secrets: inherit
# Build the binary app
app:
if: inputs.build_items == '' || contains(inputs.build_items, 'app')
needs: tagging
uses: ./.github/workflows/build-app.yml
with:
version: ${{ needs.tagging.outputs.version }}
dry_run: ${{ inputs.dry_run || false }}
secrets: inherit
# All builds are complete
done:
needs: [tagging, ui, docker, app]
uses: ./.github/workflows/build-done.yml
with:
version: ${{ needs.tagging.outputs.version }}
issue_number: ${{ github.event.pull_request.number || 0 }}
dry_run: ${{ inputs.dry_run || false }}
secrets: inherit
+1 -1
View File
@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
+25 -47
View File
@@ -2,61 +2,39 @@ name: Docs CN Mirror Deploy
on:
push:
branches:
- master
paths:
- "docs/**"
branches: ['master']
paths: ['docs/**']
jobs:
deploy:
if: github.repository == 'ArtalkJS/Artalk'
runs-on: ubuntu-latest
defaults:
run:
# set for building docs
working-directory: ./docs
steps:
# - name: Wait for other docs build to succeed
# uses: lewagon/wait-on-check-action@v1.2.0
# with:
# running-workflow-name: 'Docs CN Mirror Deploy'
# check-name: 'Build Docs'
# ref: ${{ github.ref }}
# repo-token: ${{ secrets.GITHUB_TOKEN }}
# allowed-conclusions: success,skipped,cancelled
# wait-interval: 10
- name: Checkout
uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v3
- name: Use pnpm
uses: pnpm/action-setup@v2
- name: Use pnpm
uses: pnpm/action-setup@v2
with:
version: 8
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 18
cache: "pnpm"
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 18.x
registry-url: https://registry.npmjs.org/
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Install dependencies
run: pnpm install
- name: Build Docs
run: pnpm build:docs
- name: Build Docs
run: pnpm docs:build
- name: Deploy
uses: TencentCloud/cos-action@v1
with:
secret_id: ${{ secrets.TENCENT_CLOUD_SECRET_ID }}
secret_key: ${{ secrets.TENCENT_CLOUD_SECRET_KEY }}
cos_bucket: ${{ secrets.DOCS_CN_COS_BUCKET }}
cos_region: ${{ secrets.DOCS_CN_COS_REGION }}
local_path: .vitepress/dist/
remote_path: /
clean: true
- name: Deploy
uses: TencentCloud/cos-action@v1
with:
secret_id: ${{ secrets.TENCENT_CLOUD_SECRET_ID }}
secret_key: ${{ secrets.TENCENT_CLOUD_SECRET_KEY }}
cos_bucket: ${{ secrets.DOCS_CN_COS_BUCKET }}
cos_region: ${{ secrets.DOCS_CN_COS_REGION }}
local_path: docs/docs/.vitepress/dist/
remote_path: /
clean: true
+46 -52
View File
@@ -1,5 +1,5 @@
name: 📦 Release New Version
run-name: 📦 Release ${{ inputs.custom || inputs.semver }} by @${{ github.actor }}
name: 0x📦 Release New Version
run-name: 📦 Release ${{ inputs.semver }} by @${{ github.actor }} ${{ inputs.dry_run && '(🧪 Dry-Run)' || '' }}
on:
workflow_dispatch:
@@ -12,49 +12,40 @@ on:
- minor
- major
required: true
# custom:
# description: 'Custom tag name (i.e v1.0.0-rc.1)'
# required: false
# default: ''
env:
REPO_DISPATCH_EVENT_TYPE: 'artalk-release'
UI_NPM_PKG_FILE: 'ui/packages/artalk/package.json'
dry_run:
description: 'Dry run?'
type: boolean
default: false
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Git Fetch
run: git fetch --prune --unshallow --tags -f
uses: actions/checkout@v4
with:
ref: master
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18.x
registry-url: https://registry.npmjs.org/
- name: Setup semver
run: npm install -g semver
- name: Handle Version Number
run: |
if [ ! -z "${{ inputs.custom }}" ]; then
next_version="${{ inputs.custom }}"
else
npm install -g semver
prev_version="$(git describe --tags --abbrev=0)"
echo "prev_version: ${prev_version}"
next_version="v$(semver --increment ${{ inputs.semver }} ${prev_version})"
fi
PREV_VERSION="$(git describe --tags --abbrev=0)"
NEXT_VERSION="v$(semver --increment ${{ inputs.semver }} ${PREV_VERSION})"
if [[ ! "${next_version}" =~ ^v.* ]]; then
echo "[err] custom tag name must be v*."
exit 1
fi
echo "PREV_VERSION=${PREV_VERSION}" >> $GITHUB_ENV
echo "VERSION=${NEXT_VERSION}" >> $GITHUB_ENV
echo "next_version: ${next_version}"
echo "VERSION=${next_version}" >> $GITHUB_ENV
- name: Print Next Version
run: echo "${VERSION}"
- name: Setup git-chglog
run: |
@@ -62,32 +53,35 @@ jobs:
| grep -oP '"https://.+linux_amd64.tar.gz"' | tr -d \") | tar -C /usr/local/bin -xz git-chglog
git-chglog --version
- name: Version Changelog and Tagging
- name: Version Changelog
run: |
if [ ! $(git tag -l "${VERSION}") ]; then
# prepend changelog
changelog=$(git-chglog --config .github/chglog/config.yml --next-tag "${VERSION}" "${VERSION}")
echo -e "${changelog}\n" | cat - CHANGELOG.md > temp && mv temp CHANGELOG.md
# prepend changelog
changelog=$(git-chglog --config .github/chglog/config.yml --next-tag "${VERSION}" "${VERSION}")
echo -e "${changelog}\n" | cat - CHANGELOG.md > temp && mv temp CHANGELOG.md
# modify the version of `package.json`
perl -i -pe 's/"version": ".*?"/"version": "'${VERSION#v}'"/g' "${UI_NPM_PKG_FILE}"
# modify the version of `package.json`
perl -i -pe 's/"version": ".*?"/"version": "'${VERSION#v}'"/g' ui/artalk/package.json
# modify the version in docs
perl -pi -e 's#"latest"(\W+)?:(\W+)?".*?"#"latest": "'${VERSION#v}'"#g' docs/code/ArtalkVersion.json
# modify the version in docs
perl -pi -e 's#"latest"(\W+)?:(\W+)?".*?"#"latest": "'${VERSION#v}'"#g' docs/docs/code/ArtalkVersion.json
# git commit and push
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git add .
git commit -m "chore: release ${VERSION}"
git tag "${VERSION}"
- name: Print Git Diff
run: git diff
git push origin master "${VERSION}"
else
echo "skipped because git tag already exists."
fi
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@v2
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
if: ${{ !inputs.dry_run }}
with:
event-type: ${{ env.REPO_DISPATCH_EVENT_TYPE }}
branch: "release/${{ env.VERSION }}"
commit-message: "chore: release ${{ env.VERSION }}"
title: "chore: release ${{ env.VERSION }}"
labels: release
body: |
## Release ${{ env.VERSION }} 📦🚀
This PR is auto-generated, please check the changelog and confirm the release. 😀
The build workflow will be triggered after the PR is merged.
committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
assignees: ${{ github.actor }}
+33
View File
@@ -0,0 +1,33 @@
name: Test Docs
on:
push:
branches: ['*', '!release/*']
paths: ['docs/**']
tags-ignore: ['v*']
pull_request:
paths: ['docs/**']
branches: ['*', '!release/*']
jobs:
test_docs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Use pnpm
uses: pnpm/action-setup@v2
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 18.x
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Build Docs
run: pnpm build:docs
+46
View File
@@ -0,0 +1,46 @@
name: Test Frontend
on:
push:
branches: ['*', '!release/*']
paths: ['ui/**']
tags-ignore: ['v*']
pull_request:
paths: ['ui/**']
branches: ['*', '!release/*']
jobs:
test_ui:
strategy:
matrix:
node: [18, 20]
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
- name: Use Node.js ${{ matrix.node }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: pnpm
- name: Install Dependencies
run: pnpm install --frozen-lockfile
- name: Package Build Test
run: pnpm build:all
- name: Unit test
run: pnpm test
# https://github.com/arethetypeswrong/arethetypeswrong.github.io
- name: 'arethetypeswrong test'
run: pnpm -F artalk attw
+3
View File
@@ -65,3 +65,6 @@ node_modules
# always compile latest version
/public/sidebar
/public/dist
playwright-report
test-results
View File
File renamed without changes.
View File
File renamed without changes.
+1 -1
View File
@@ -16,4 +16,4 @@
"sqlite",
"pkged"
]
}
}
+269
View File
@@ -1,4 +1,273 @@
## [v2.8.3](https://github.com/ArtalkJS/Artalk/compare/v2.8.2...v2.8.3) (2024-03-04)
### Features
* **api/auth:** invalidate old auth tokens after changing password
* **api/domain:** add GET `/conf/domain` endpoint
* **app:** add `onConfUpdated` hook
* **comment:** add `is_verified` field for comment entity
* **ui/api:** add `ctx.getApiHandlers()` to handle error responses and expose hooks
* **ui/editor:** add `beforeSubmit` hook for editor submitting
* **ui/plugins:** support dynamic loading of ui plug-in scripts ([#774](https://github.com/ArtalkJS/Artalk/issues/774))
### Bug Fixes
* **captcha/image:** unable to display image captcha on initial load
* **conf:** skip patching IP region conf if disabled
* **exception:** missing `message` field after refactoring exception data structure
* **sidebar/login:** cannot select a name with the same email upon login ([#781](https://github.com/ArtalkJS/Artalk/issues/781))
* **ui/layer:** ensure immediate operation when calling `show()` after `hide()`
### Performance Improvements
* **ui/editor:** improve the icon details for editor
### Code Refactoring
* **dao:** validate the args of the `FindCreateUser` function
* **entity/user:** extract `CheckPassword` function
* **origin:** extract `CheckURLTrusted` function
## [v2.8.2](https://github.com/ArtalkJS/Artalk/compare/v2.8.1...v2.8.2) (2024-02-05)
### Bug Fixes
* **api/comments:** `ua` field is optional and not required ([#767](https://github.com/ArtalkJS/Artalk/issues/767))
* **style:** replace style `break-all` with `break-word` in content el ([#644](https://github.com/ArtalkJS/Artalk/issues/644))
### Performance Improvements
* **ui/editor:** optimize editor styles for narrow-width screens
* **ui/editor:** modify editor plug-in text buttons to icons for brevity
* **ui/editor:** place `Cancel Reply` at the bottom of editor area ([#644](https://github.com/ArtalkJS/Artalk/issues/644))
* **ui/lite:** disable ArtalkLite `preview` config option by default
## [v2.8.1](https://github.com/ArtalkJS/Artalk/compare/v2.8.0...v2.8.1) (2024-02-04)
### Features
* **api:** add GET `/comments/:id` endpoint ([#764](https://github.com/ArtalkJS/Artalk/issues/764))
* **config:** add `db.prepare_stmt` config option ([#760](https://github.com/ArtalkJS/Artalk/issues/760)) ([#762](https://github.com/ArtalkJS/Artalk/issues/762))
* **ui/goto:** improved solution of navigating to comment via link hash ([#693](https://github.com/ArtalkJS/Artalk/issues/693)) ([#765](https://github.com/ArtalkJS/Artalk/issues/765))
### Bug Fixes
* **api/comments:** counting comments issue in PostgreSQL db ([#760](https://github.com/ArtalkJS/Artalk/issues/760)) ([#761](https://github.com/ArtalkJS/Artalk/issues/761))
* **cmd/admin:** update user role to admin if already exists
* **ip_region:** unable to output the IP region correctly ([#760](https://github.com/ArtalkJS/Artalk/issues/760))
* **ui/list:** unable to reply or delete comments after switching pagination
* **ui/no_comment:** always appears when creating comment
* **ui/pv:** missing `pageTitle` field in the PV request
* **ui/scroll:** scroll into view issue when `relativeTo` parameter is provided
### Performance Improvements
* **style/sidebar:** improve some detail in sidebar
### Code Refactoring
* **ui/comment:** loose coupling between `Comment` and `Context`
* **ui/list:** refactor the list layout manager
### Documentation
* supplement and refine `fe-api.md`
## [v2.8.0](https://github.com/ArtalkJS/Artalk/compare/v2.7.3...v2.8.0) (2024-01-31)
### Features
* **go:** upgrade golang to v1.21.5 and some deps
* **notify:** add `notify_pending` config option ([#728](https://github.com/ArtalkJS/Artalk/issues/728)) ([#754](https://github.com/ArtalkJS/Artalk/issues/754))
* **ui/admin:** add logout button in admin panel ([#488](https://github.com/ArtalkJS/Artalk/issues/488)) ([#753](https://github.com/ArtalkJS/Artalk/issues/753))
### Bug Fixes
* **cache:** unable to change admin list after caching ([#748](https://github.com/ArtalkJS/Artalk/issues/748)) ([#750](https://github.com/ArtalkJS/Artalk/issues/750))
* **i18n:** sidebar language cannot be changed
* **ui/editor:** prevent propagation of click event in editor ([#734](https://github.com/ArtalkJS/Artalk/issues/734))
* **ui/layer:** unexpected behavior with multiple items when closing
* **ui/lite:** correct the instance name for compiling ArtalkLite ([#740](https://github.com/ArtalkJS/Artalk/issues/740))
* **ui/no_comment:** flickering when clearing list before fetch
* **ui/pagination:** auto load list when scroll reaches bottom
* **ui/sidebar:** incorrectly increasing pv count in sidebar ([#724](https://github.com/ArtalkJS/Artalk/issues/724))
* **ui/sidebar_layer:** sidebar still displays when login is required
### Performance Improvements
* **ui/conf:** support for watching partial changes in config with `watchConf()` ([#755](https://github.com/ArtalkJS/Artalk/issues/755))
* **ui/i18n:** refine some translation ([#743](https://github.com/ArtalkJS/Artalk/issues/743))
* **ui/pagination:** replace the prev/next text on pagination buttons with icons ([#743](https://github.com/ArtalkJS/Artalk/issues/743))
* **ui/sidebar:** prevent potential token leakage by clearing query in iframe url
### Code Refactoring
* **api:** update swagger file of API v2
* **api:** refactor HTTP API to version 2 ([#735](https://github.com/ArtalkJS/Artalk/issues/735))
* **transfer:** normalize transfer payload parameter name
* **ui:** optimize init and update lifecycle events
* **ui/comment:** rename class `Comment` to `CommentNode`
* **ui/ctx:** add `getComments` and `getCommentNodes` in context ([#752](https://github.com/ArtalkJS/Artalk/issues/752))
### Documentation
* update multi-sites manual ([#747](https://github.com/ArtalkJS/Artalk/issues/747))
### BREAKING CHANGE
For Developers: The HTTP API has now been updated to version v2, with a lot of adjustments made, such as changing to Restful API style, request type, request body, response body, etc. data structure, adding error response codes. You can refer to [#735](https://github.com/ArtalkJS/Artalk/issues/735) or https://artalk.js.org/http-api Please update all your existing clients to adapt to the new v2 server. The new base path is `/api/v2/`. The UI package's HTTP client has been implemented to auto-generate based on `Swagger.json`, and there have been a lot of adjustments to the `artalk.ctx.getApi()` related code. In addition, the HTTP API no longer enforces checks on the header's `Origin` and `Referer` (to implement strict isolation of different sites) but still maintains the original CORS origin check.
For General Users: Now all administrators have the same level of authority (there is no longer super admin authority), the function of assigning sub-administrators with independent scope authority to individual sites has been removed, which can simplify the HTTP server maintenance and implementation. Upgrading only requires updating the client and server application at the same time, and there are no additional operations.
## [v2.7.3](https://github.com/ArtalkJS/Artalk/compare/v2.7.2...v2.7.3) (2023-12-28)
### Features
* **ci:** add dry-run mode for build workflow
* **cmd:** support cli flag for creating admin account
### Bug Fixes
* **ui/init:** stack overflow when merging with config defaults ([#717](https://github.com/ArtalkJS/Artalk/issues/717))
### Performance Improvements
* **ui/build:** better dts generation ([#689](https://github.com/ArtalkJS/Artalk/issues/689))
### Code Refactoring
* **ci:** better release workflow
* **docker:** add `--build-arg` argument to skip ui build
* **test/ui:** add more ui api tests
* **ui:** refactor directory structure ([#712](https://github.com/ArtalkJS/Artalk/issues/712))
* **ui/conf:** better handling of mutable config ([#722](https://github.com/ArtalkJS/Artalk/issues/722))
* **ui/test:** add vitest for unit testing
### Documentation
* update ui api documentation
### BREAKING CHANGE
Directly referencing `artalk.conf` and `artalk.$root` is deprecated. Please use functions instead: `artalk.getConf()` and `artalk.getEl()`.
## [v2.7.2](https://github.com/ArtalkJS/Artalk/compare/v2.7.1...v2.7.2) (2023-12-20)
### Features
* patch `locale` config from `zh-cn` to `zh-CN` ([#678](https://github.com/ArtalkJS/Artalk/issues/678))
### Bug Fixes
* **sidebar:** sidebar language switch and config save issue ([#708](https://github.com/ArtalkJS/Artalk/issues/708))
* **ui:** add `referrerpolicy` attribute for iframe ([#687](https://github.com/ArtalkJS/Artalk/issues/687)) ([#707](https://github.com/ArtalkJS/Artalk/issues/707))
* **ui/dark-mode:** potential memory leak issue in auto mode ([#688](https://github.com/ArtalkJS/Artalk/issues/688))
* **ui/pagination:** auto switch page by url hashtag issue ([#693](https://github.com/ArtalkJS/Artalk/issues/693))
* **ui/sidebar:** refactor settings and fix save issue ([#677](https://github.com/ArtalkJS/Artalk/issues/677)) ([#706](https://github.com/ArtalkJS/Artalk/issues/706))
### Code Refactoring
* **ui:** move window references into function scope ([#675](https://github.com/ArtalkJS/Artalk/issues/675))
* **ui/api:** losing coupling between `Api` and `User`
* **ui/user:** user class no longer globally singleton
### Documentation
* **i18n:** add translation for `open` button
* **refactor:** organize the pkgs and fix some issues ([#702](https://github.com/ArtalkJS/Artalk/issues/702))
## [v2.7.1](https://github.com/ArtalkJS/Artalk/compare/v2.7.0...v2.7.1) (2023-12-17)
### Bug Fixes
* **build:** generate source maps to ease debugging
* **cout-widget:** `loadCountWidget` issue
* **ui:** static method export issue in JS module ([#669](https://github.com/ArtalkJS/Artalk/issues/669))
### Documentation
* **i18n:** add translation of update notice
## [v2.7.0](https://github.com/ArtalkJS/Artalk/compare/v2.6.4...v2.7.0) (2023-12-17)
### Features
* **ui:** support `scrollRelativeTo` config option
* **ui/test:** add end-to-end (e2e) testing using Playwright
### Bug Fixes
* **api/img-upload:** `public_path` config enables the use of full url ([#659](https://github.com/ArtalkJS/Artalk/issues/659)) ([#664](https://github.com/ArtalkJS/Artalk/issues/664))
* **lifecycle:** create multi-instances at the same time ([#660](https://github.com/ArtalkJS/Artalk/issues/660)) ([#663](https://github.com/ArtalkJS/Artalk/issues/663))
* **notify_pusher:** panic when admin ids array is empty ([#634](https://github.com/ArtalkJS/Artalk/issues/634))
* **style/list:** replace `float` to `text-align` in footer part ([#619](https://github.com/ArtalkJS/Artalk/issues/619))
* **ui:** scroll to the center of the viewport issue
* **ui/conf:** sanitize `noComment` conf option for security ([#624](https://github.com/ArtalkJS/Artalk/issues/624))
* **ui/dark-mode:** `setDarkMode` cannot save to instance config ([#661](https://github.com/ArtalkJS/Artalk/issues/661))
* **ui/editor:** fix position of the comment box when replying ([#643](https://github.com/ArtalkJS/Artalk/issues/643)) ([#648](https://github.com/ArtalkJS/Artalk/issues/648))
### Performance Improvements
* **cache:** implement GC feature for simple_cache pkg ([#656](https://github.com/ArtalkJS/Artalk/issues/656))
### Code Refactoring
* **editor:** refactor editor plugin manager ([#609](https://github.com/ArtalkJS/Artalk/issues/609))
* **editor:** refactor plug kit and events ([#613](https://github.com/ArtalkJS/Artalk/issues/613))
* **ui:** reduce coupling with `ContextApi`
* **ui:** separate standalone admin-only-elem checker
* **ui/api:** loose coupling between `Api` and `Context`
* **ui/conf:** loose coupling between config and list fetch
* **ui/event:** refactor core event manager ([#611](https://github.com/ArtalkJS/Artalk/issues/611))
* **ui/layer:** better layer implements and independence ([#662](https://github.com/ArtalkJS/Artalk/issues/662))
* **ui/list:** separate list into standalone components ([#618](https://github.com/ArtalkJS/Artalk/issues/618))
* **ui/marked:** separate markdown related codes
* **ui/marked:** loose coupling with `marked` func
* **ui/plugin:** further divide functionality into plugins ([#615](https://github.com/ArtalkJS/Artalk/issues/615))
* **ui/stat:** losing coupling of `CountWidget`
* **ui/types:** better `ArtalkType` import and export ([#620](https://github.com/ArtalkJS/Artalk/issues/620))
### Documentation
* revise and add more examples
* provide clearer and more detailed instructions in CONTRIBUTING.md
* **conf:** disable `frontend.uaBadge` config option by default
* **deploy:** add deployment guide for render.com ([#649](https://github.com/ArtalkJS/Artalk/issues/649))
* **import:** update the examples in import-framework.md ([#665](https://github.com/ArtalkJS/Artalk/issues/665))
### BREAKING CHANGE
The following top-level functions exported by the 'artalk' npm package have been deprecated: `Artalk.update`, `Artalk.reload`, and `Artalk.destroy`. These methods now require invocation on an instance created by either `Artalk.init` or `new Artalk`. Please utilize instance-level methods instead, such as `artalkInstance.update`. For more information, refer to [the documentation](https://artalk.js.org/guide/frontend/import-framework.html). The update was implemented to enable the concurrent creation of multiple instances, adapting to situations where Vue components are simultaneously referenced across various pages. Initially, only a singular instance was permitted to mitigate memory leak concerns. However, this proved limiting for scenarios involving the caching of multiple component instances through 'keep-alive.' To better suit intricate SPA application needs, the choice was made to permit the creation of multiple independent instances. It's crucial to remember to manually invoke the `artalk.destroy` method when releasing components to avoid memory leaks (Issue [#660](https://github.com/ArtalkJS/Artalk/issues/660)).
## [v2.6.4](https://github.com/ArtalkJS/Artalk/compare/v2.6.3...v2.6.4) (2023-10-12)
### Features
* **go:** upgrade golang to v1.21.3 and some deps
### Bug Fixes
* **editor:** fix duplicate event binding when update conf ([#605](https://github.com/ArtalkJS/Artalk/issues/605))
* **email:** sender not initialized correctly
* **style:** fix copyright text overlay on send button ([#607](https://github.com/ArtalkJS/Artalk/issues/607))
### Code Refactoring
* **anti_spam:** refactor anti_spam pkg and add unit test ([#589](https://github.com/ArtalkJS/Artalk/issues/589))
## [v2.6.3](https://github.com/ArtalkJS/Artalk/compare/v2.6.2...v2.6.3) (2023-09-20)
### Features
+11 -11
View File
@@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
- Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of
- The use of sexualized language or imagery, and sexual attention or advances of
any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
@@ -59,7 +59,7 @@ representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at artalkjs@gmail.com.
reported to the community leaders responsible for enforcement at <artalkjs@gmail.com>.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
+38 -11
View File
@@ -6,7 +6,7 @@ This guide is for developers who want to contribute to the project.
To develop Artalk, including the frontend and backend, you need to install the following tools:
- [Node.js](https://nodejs.org/en/) (>= 16.0.0)
- [Node.js](https://nodejs.org/en/) (>= 18.12.0)
- [Go](https://golang.org/) (>= 1.21)
- [Docker](https://www.docker.com/) (>= 20.10.0) (optional)
- [Docker Compose](https://docs.docker.com/compose/) (>= 1.29.0) (optional)
@@ -29,22 +29,41 @@ Enter the directory:
cd Artalk
```
### Build frontend and backend
### Build Backend
First, we need to install the dependencies for backend written in Go. Simply run the following command:
First, you need to install the dependencies for the backend written in Go. Simply run the `make install` command to install the dependencies.
```sh
make build-debug
```
Then, run the `make dev` to build and run `./bin/artalk`, and you can pass startup parameters to the program using `ARGS="version" make dev`.
This will build both the frontend and backend, with debugging symbols.
This will build the backend with debugging symbols. The binary file will be placed under the `./bin` directory.
- **Frontend** will be built under `./ui/packages/artalk` and copied to `./public` directory.
- **Backend** will be built under `./bin` directory.
The backend program will run by default on port `23366`. You can access it through a browser at `http://localhost:23366`. It's recommended not to change this port number for testing the backend program.
### Optional: Use one-key script to run a demo site
### Build Frontend
If you want to run a demo site, you can use the following command:
First, you need to install the dependencies for the frontend. Simply run the `pnpm install` command to install the dependencies.
Then, run the `pnpm dev` to build and run the frontend, and you can pass startup parameters to the program using `ARGS="--port 5173" pnpm dev`.
The frontend program will run by default on port `5173`, and you can access it in a browser at `http://localhost:5173`. The frontend testing client will, by default, request the backend on port `23366`, so it's essential to keep the backend on this port.
The frontend program is divided into the main program and a sidebar program, with the sidebar program running on a separate port, which is `23367`.
### Development Workflow
In most cases, to set up a complete development instance, you need to navigate to the Artalk Repo directory and then execute `make dev`. This will run the backend on port `23366`. Then, execute `pnpm dev`, which will run the frontend on port `5173`. You can optionally execute `pnpm dev:sidebar` to run the sidebar frontend on port `23367`. For frontend development, you need to access `http://localhost:5173` in your browser to perform your development and testing.
When you make changes to the frontend code, you can build the complete frontend program using `pnpm build:all`. The JavaScript and CSS code can be found in `ui/artalk/dist`.
When you make changes to the backend code, running `make all` will build the complete backend program. Note that since the backend program also embeds the frontend code, the `scripts/build-frontend.sh` script will run during backend program building, which includes the embedded frontend main program and sidebar frontend program. If you are interested, you can explore the complete frontend build process in the `Makefile` code.
Additionally, there is automated CI on GitHub for building. You can find the relevant code in the `.github/workflows` directory.
### Optional: Use a One-Key Script to Run a Demo Site
When you access `http://localhost:5173` during frontend development, you will get a minimalist interface that only contains the Artalk program interface and not a real blog environment. If you want to make testing closer to a real environment, you can create a demo blog site using the following steps.
Run the following command:
```sh
./scripts/setup-example-site.sh
@@ -70,6 +89,14 @@ email: "admin@test.com"
password: "admin"
```
## Testing
The backend Go program can be tested by running `make test` for unit testing. The test results will be outputted in the terminal. You can also execute `test-coverage` to check the code test coverage.
Frontend testing is conducted using Playwright for end-to-end (E2E) testing. To start the E2E testing, run `make test-frontend-e2e`.
Both frontend and backend testing are automated and will be performed during Git pull requests and as part of the build process using CircleCI or GitHub Actions.
## Project Structure
Artalk is a monorepo project, which means all the source code is in the same repository. However, the frontend and backend are separated. The frontend part is located in `./ui` directory.
+24 -7
View File
@@ -1,12 +1,11 @@
### build Artalk
FROM golang:1.21.0-alpine3.18 as builder
FROM golang:1.21.5-alpine3.19 as builder
WORKDIR /source
# install tools
RUN set -ex \
&& apk add --no-cache make git gcc musl-dev nodejs bash npm\
&& npm install -g pnpm@8.7.0
&& apk add --no-cache make git gcc musl-dev bash
# download go deps
# (cache by separating the downloading of deps)
@@ -16,14 +15,32 @@ RUN go mod download
# copy source code
COPY . .
# build
## build UI
ARG SKIP_UI_BUILD=false
# install ui build toolchain
RUN set -ex \
&& export VERSION=$(git describe --tags --abbrev=0) \
&& export COMMIT_SHA=$(git rev-parse --short HEAD) \
&& if [ "$SKIP_UI_BUILD" = "false" ]; then \
apk add --no-cache nodejs npm \
&& npm install -g pnpm@8.12.1 \
;fi
RUN set -ex \
&& if [ "$SKIP_UI_BUILD" = "false" ]; then \
make build-frontend \
;fi
## build App
ARG APP_VERSION=""
ARG APP_COMMIT_HASH=""
RUN set -ex \
&& if [[ ! -z "$APP_VERSION" ]]; then export VERSION=$APP_VERSION ;fi \
&& if [[ ! -z "$APP_COMMIT_HASH" ]]; then export COMMIT_HASH=$APP_COMMIT_HASH ;fi \
&& make build
### build final image
FROM alpine:3.18
FROM alpine:3.19
# we set the timezone `Asia/Shanghai` by default, you can be modified
# by `docker build --build-arg="TZ=Other_Timezone ..."`
+8 -5
View File
@@ -1,8 +1,7 @@
PKG_NAME := github.com/ArtalkJS/Artalk
BIN_NAME := ./bin/artalk
VERSION ?= $(shell git describe --tags --abbrev=0)
COMMIT_HASH := $(shell git rev-parse --short HEAD)
DEV_VERSION := dev-$(COMMIT_HASH)
COMMIT_HASH ?= $(shell git rev-parse --short HEAD)
HAS_RICHGO := $(shell which richgo)
GOTEST ?= $(if $(HAS_RICHGO), richgo test, go test)
@@ -13,7 +12,7 @@ all: install build
install:
go mod tidy
build: build-frontend
build:
go build \
-ldflags "-s -w -X $(PKG_NAME)/internal/config.Version=$(VERSION) \
-X $(PKG_NAME)/internal/config.CommitHash=$(COMMIT_HASH)" \
@@ -53,7 +52,8 @@ update-i18n:
update-swagger:
go install github.com/swaggo/swag/cmd/swag@latest
swag init -g server/server.go --output ./docs/swagger
swag init -g server/server.go --output ./docs/swagger --requiredByDefault
pnpm -r swagger:build-http-client
docker-build:
./scripts/docker-build.sh
@@ -61,6 +61,9 @@ docker-build:
docker-push:
./scripts/docker-build.sh --push
test-frontend-e2e:
./scripts/frontend-e2e-test.sh $(if $(REPORT), --show-report)
.PHONY: all install build build-frontend build-debug \
dev test test-coverage test-coverage-html update-i18n \
docker-build docker-push;
docker-build docker-push test-frontend-e2e;
+4 -4
View File
@@ -4,12 +4,12 @@
# Artalk
[![](https://img.shields.io/npm/v/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![](https://img.shields.io/npm/dt/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![](https://badgen.net/bundlephobia/minzip/artalk?style=flat-square)](https://bundlephobia.com/package/artalk)
[![npm 版本](https://img.shields.io/npm/v/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![npm 下载量](https://img.shields.io/npm/dt/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![尺寸](https://badgen.net/bundlephobia/minzip/artalk?style=flat-square)](https://bundlephobia.com/package/artalk)
[![CircleCI](https://circleci.com/gh/ArtalkJS/Artalk/tree/master.svg?style=svg)](https://circleci.com/gh/ArtalkJS/Artalk/tree/master)
> 🌌 A Self-hosted comment system
> 🌌 A self-hosted comment system
[简体中文](./README.md) / [Documentation](https://artalk.js.org) / [Releases](https://github.com/ArtalkJS/Artalk/releases) / [Artalk](https://github.com/ArtalkJS/Artalk)
+23 -12
View File
@@ -4,11 +4,13 @@
# Artalk
[![](https://img.shields.io/npm/v/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![](https://img.shields.io/npm/dt/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![](https://badgen.net/bundlephobia/minzip/artalk?style=flat-square)](https://bundlephobia.com/package/artalk)
[![npm version](https://img.shields.io/npm/v/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![npm downloads](https://img.shields.io/npm/dt/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![Docker Pulls](https://img.shields.io/docker/pulls/artalk/artalk-go?style=flat-square)](https://hub.docker.com/r/artalk/artalk-go)
[![CircleCI](https://circleci.com/gh/ArtalkJS/Artalk/tree/master.svg?style=svg)](https://circleci.com/gh/ArtalkJS/Artalk/tree/master)
[![Go Report Card](https://goreportcard.com/badge/github.com/ArtalkJS/Artalk?style=flat-square)](https://goreportcard.com/report/github.com/ArtalkJS/Artalk)
[![CircleCI](https://img.shields.io/circleci/build/gh/ArtalkJS/Artalk?style=flat-square)](https://circleci.com/gh/ArtalkJS/Artalk/tree/master)
[![Codecov](https://img.shields.io/codecov/c/gh/ArtalkJS/Artalk?style=flat-square)](https://codecov.io/gh/ArtalkJS/Artalk)
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/artalk?style=flat-square)](https://bundlephobia.com/package/artalk)
> 🌌 Golang 自托管评论系统
@@ -53,17 +55,24 @@
- 支持 Latex:提供集成 Katex 插件
- 使用 [Vite](https://github.com/vitejs/vite):属于开发者的极致体验
更多内容请查看:[“**介绍文档**”](https://artalk.js.org/guide/intro.html)
更多内容请查看:[**介绍文档**](https://artalk.js.org/guide/intro.html)
## 食用方针
## 安装
前往:[“**部署文档**”](https://artalk.js.org/guide/deploy.html)
参考:[**部署文档**](https://artalk.js.org/guide/deploy.html)
```bash
npm install artalk
```
```ts
import Artalk from 'artalk'
Artalk.init({
el: '#Comments',
site: 'Artalk 的博客',
server: 'https://artalk.example.com'
el: '#Comments',
site: 'Artalk 的博客',
server: 'https://artalk.example.com',
pageKey: '/2018/10/02/hello-world.html'
})
```
@@ -74,6 +83,7 @@ docker run -d \
--name artalk \
-p 8080:23366 \
-v $(pwd)/data:/data \
--restart=always \
artalk/artalk-go
```
@@ -89,6 +99,7 @@ services:
artalk:
container_name: artalk
image: artalk/artalk-go
restart: always
ports:
- 8080:23366
volumes:
@@ -119,7 +130,7 @@ see [CONTRIBUTING.md](./CONTRIBUTING.md)
感谢社区提供的帮助与反馈,若有好的建议与意见欢迎前往 [ISSUES](https://github.com/ArtalkJS/Artalk/issues) 随时告知。
## TODOs
## TODOs
- [x] Golang 后端
- [x] 多数据库支持
@@ -192,7 +203,7 @@ see [CONTRIBUTING.md](./CONTRIBUTING.md)
- [x] 用户鉴权机制
- [x] 跨域非法请求阻止
- [x] 全局验证码操作次数限制
- [x] JWT 登陆状态验证
- [x] JWT 登录状态验证
- [x] 时区自定义
- [x] 只看作者功能
- [x] 图片上传
+16 -3
View File
@@ -25,14 +25,23 @@ func NewAdminCommand(app *ArtalkCmd) *cobra.Command {
fmt.Println(" " + i18n.T("Create admin account"))
fmt.Println("--------------------------------")
username, email, password, err := credentials()
if err != nil {
log.Fatal(err)
// get from flags
username, _ := cmd.Flags().GetString("name")
email, _ := cmd.Flags().GetString("email")
password, _ := cmd.Flags().GetString("password")
if username == "" || email == "" || password == "" {
var err error
username, email, password, err = credentials()
if err != nil {
log.Fatal(err)
}
}
findUser := app.Dao().FindUser(username, email)
if !findUser.IsEmpty() {
findUser.SetPasswordEncrypt(password)
findUser.IsAdmin = true
if err := app.Dao().UpdateUser(&findUser); err != nil {
log.Fatal(err)
}
@@ -62,6 +71,10 @@ func NewAdminCommand(app *ArtalkCmd) *cobra.Command {
},
}
flag(adminCmd, "name", "", i18n.T("Username"))
flag(adminCmd, "email", "", i18n.T("Email"))
flag(adminCmd, "password", "", i18n.T("Password"))
return adminCmd
}
+2 -2
View File
@@ -26,7 +26,7 @@ var Banner = `
Artalk (` + Version + `)
-> A Selfhosted Comment System.
-> A Self-hosted Comment System.
-> https://artalk.js.org
`
@@ -50,7 +50,7 @@ func New() *ArtalkCmd {
cmd := &ArtalkCmd{
RootCmd: &cobra.Command{
Use: "artalk",
Short: "Artalk: Your self-hosted comment system",
Short: "Artalk: A self-hosted comment system",
Long: Banner,
Version: Version,
Run: func(cmd *cobra.Command, args []string) {
-2
View File
@@ -30,8 +30,6 @@ func NewImportCommand(app *ArtalkCmd) *cobra.Command {
params := artransfer.ArrToImportParams(payload)
params.Assumeyes, _ = cmd.Flags().GetBool("assumeyes")
artransfer.RunImportArtrans(app.Dao(), params)
log.Info(i18n.T("Import complete"))
},
}
+4 -1
View File
@@ -17,6 +17,7 @@ db:
password: ""
charset: "utf8mb4"
ssl: false
prepare_stmt: true
log:
enabled: true
filename: "./data/artalk.log"
@@ -102,6 +103,7 @@ email:
account_name: "noreply@example.com"
admin_notify:
notify_tpl: "default"
notify_pending: false
noise_mode: false
email:
enabled: true
@@ -145,7 +147,7 @@ frontend:
emoticons: "https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json"
vote: true
voteDown: false
uaBadge: true
uaBadge: false
listSort: true
pvEl: "#ArtalkPV"
countEl: "#ArtalkCount"
@@ -166,3 +168,4 @@ frontend:
scrollable: false
reqTimeout: 15000
versionCheck: true
pluginURLs: []
+8 -2
View File
@@ -47,6 +47,8 @@ db:
charset: "utf8mb4"
# Enable SSL mode
ssl: false
# Prepared Statement
prepare_stmt: true
# Logging
log:
@@ -214,10 +216,12 @@ email:
access_key_secret: ""
account_name: "noreply@example.com"
# Multi-push
# Multi-Push
admin_notify:
# Notification template (set to file path to use custom template)
notify_tpl: "default"
# Pending comment still send notification (notifications are still sent when comments are intercepted)
notify_pending: false
# Noise mode
# -- noise_mode is disabled by default. --
# -- When this option is set to `false`, only messages sent to the administrator will be notified, --
@@ -284,7 +288,7 @@ frontend:
# Dislike button
voteDown: false
# User UA badge
uaBadge: true
uaBadge: false
# Comment sorting
listSort: true
# Page PV binding element
@@ -325,3 +329,5 @@ frontend:
reqTimeout: 15000
# Version check
versionCheck: true
# Plugins
pluginURLs: []
+11 -5
View File
@@ -19,7 +19,7 @@ timezone: "Asia/Shanghai"
# 默认站点名
site_default: "默认站点"
# 登陆有效时长 (单位:秒)
# 登录有效时长 (单位:秒)
login_timeout: 259200
# 数据库
@@ -44,6 +44,8 @@ db:
table_prefix: ""
# 启用 SSL
ssl: false
# 预编译语句
prepare_stmt: true
# 日志
log:
@@ -162,9 +164,9 @@ captcha:
captcha_id: ""
captcha_key: ""
# IP 归属地
# IP 属地
ip_region:
# 启用 IP 归属地展示
# 启用 IP 属地展示
enabled: false
# 数据文件路径 (.xdb 格式)
db_path: "./data/ip2region.xdb"
@@ -226,6 +228,8 @@ email:
admin_notify:
# 通知模版 (填入文件路径使用自定义模板)
notify_tpl: "default"
# 待审评论仍然发送通知 (当评论被拦截时仍然发送通知)
notify_pending: false
# 嘈杂模式
noise_mode: false
# 邮件通知管理员
@@ -274,7 +278,7 @@ admin_notify:
- "USER_ID_1"
- "GROUP_ID_1"
# 前端配置
# 界面配置
frontend:
# 评论框占位文字
placeholder: ""
@@ -291,7 +295,7 @@ frontend:
# 反对按钮
voteDown: false
# 用户 UA 徽标
uaBadge: true
uaBadge: false
# 评论排序功能
listSort: true
# 页面 PV 绑定元素
@@ -332,3 +336,5 @@ frontend:
reqTimeout: 15000
# 版本检测
versionCheck: true
# 插件
pluginURLs: []
-2
View File
@@ -1,2 +0,0 @@
shamefully-hoist=true
auto-install-peers=true
-209
View File
@@ -1,209 +0,0 @@
import { defineConfig } from 'vitepress'
import iterator from 'markdown-it-for-inline'
import * as Version from '../code/ArtalkVersion.json'
export default defineConfig({
title: 'Artalk',
description: '一款简洁的自托管评论系统',
lang: 'zh-CN',
head: [
['link', { rel: 'icon', href: '/favicon.png' }],
['meta', { name: 'viewport', content: 'width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi' }],
// artalk
// ['link', { href: `https://npm.elemecdn.com/artalk@${Version.latest}/dist/Artalk.css`, rel: 'stylesheet' }],
['link', { href: `https://artalk.qwqaq.com/dist/Artalk.css`, rel: 'stylesheet' }],
// ['script', { src: ArtalkCDN.JS }],
// light gallery
['link', { href: 'https://npm.elemecdn.com/lightgallery@2.3.0/css/lightgallery.css', rel: 'stylesheet' }],
['script', { src: 'https://npm.elemecdn.com/lightgallery@2.3.0/lightgallery.min.js' }],
// katex
// ['link', { href: "https://npm.elemecdn.com/katex@0.15.3/dist/katex.min.css", rel: 'stylesheet' }],
// ['script', { src: 'https://npm.elemecdn.com/katex@0.15.3/dist/katex.min.js' }],
// ['script', { src: 'https://npm.elemecdn.com/@artalkjs/plugin-katex/dist/artalk-plugin-katex.js' }],
],
lastUpdated: true,
markdown: {
// @link https://github.com/shikijs/shiki
theme: {
light: 'github-light',
dark: 'github-dark',
},
config: (md) => {
md.use(iterator, 'artalk_version', 'text', function (tokens, idx) {
tokens[idx].content = tokens[idx].content.replace(/:ArtalkVersion:/g, Version.latest)
});
md.use(iterator, 'artalk_version_link', 'link_open', (tokens, idx) => {
const href = tokens[idx].attrGet('href')
tokens[idx].attrSet('href', href.replace(/:ArtalkVersion:/g, Version.latest))
});
},
},
locales: {
root: {
label: '简体中文',
lang: 'zh'
},
en: {
label: 'English',
lang: 'en',
link: '/en/'
}
},
themeConfig: {
sidebar: {
"/guide/": [
{
text: "快速开始",
collapsed: false,
items: [
{ text: '项目介绍', link: '/guide/intro.md' },
{ text: '程序部署', link: '/guide/deploy.md' },
{ text: '数据迁移', link: '/guide/transfer.md' },
]
},
{
text: "核心指南",
collapsed: false,
items: [
{ text: '侧边栏', link: '/guide/frontend/sidebar.md' },
{ text: '邮件通知', link: '/guide/backend/email.md' },
{ text: '多元推送', link: '/guide/backend/admin_notify.md' },
{ text: '评论审核', link: '/guide/backend/moderator.md' },
{ text: '验证码', link: '/guide/backend/captcha.md' },
{ text: '图片上传', link: '/guide/backend/img-upload.md' },
{ text: '账户与多站点', link: '/guide/backend/multi-site.md' },
{ text: '解析相对路径', link: '/guide/backend/relative-path.md' },
{ text: '如何配置界面', link: '/guide/backend/fe-control.md' },
{ text: 'English (i18n)', link: '/guide/frontend/i18n.md' },
]
},
{
text: "进阶指南",
collapsed: false,
items: [
{ text: '表情包', link: '/guide/frontend/emoticons.md' },
{ text: '浏览量统计', link: '/guide/frontend/pv.md' },
{ text: 'Latex', link: '/guide/frontend/latex.md' },
{ text: '图片灯箱', link: '/guide/frontend/lightbox.md' },
{ text: 'IP 归属地', link: '/guide/frontend/ip-region.md' },
{ text: '精简版本', link: '/guide/frontend/artalk-lite.md' },
{ text: '置入博客', link: '/guide/frontend/import-blog.md' },
{ text: '置入框架', link: '/guide/frontend/import-framework.md' },
{ text: '开发文档', link: '/develop/index.md', },
],
},
{
text: "配置文档",
collapsed: true,
items: [
{ text: '后端配置', link: '/guide/backend/config.md' },
{ text: '前端配置', link: '/guide/frontend/config.md' },
]
},
{
text: "部署说明",
collapsed: true,
items: [
{ text: 'Docker', link: '/guide/backend/docker.md' },
{ text: '守护进程', link: '/guide/backend/daemon.md' },
{ text: '反向代理', link: '/guide/backend/reverse-proxy.md' },
{ text: '编译构建', link: '/guide/backend/build.md' },
{ text: '程序升级', link: '/guide/backend/update.md' },
]
},
{
text: '更多内容',
collapsed: true,
items: [
{ text: '安全防范', link: '/guide/security.md' },
{ text: '扩展阅读', link: '/guide/extras.md' },
{ text: '案例展示', link: '/guide/cases.md' },
{ text: '关于我们', link: '/guide/about.md' },
]
}
],
"/develop/": [
{
text: '开发文档',
items: [
{ text: '开发说明', link: '/develop/index.md', },
{ text: '前端 API', link: '/develop/fe-api.md', },
{ text: '前端 Event', link: '/develop/event.md', },
{ text: '插件开发', link: '/develop/plugs.md' },
{ text: '🔬 HTTP API', link: 'https://artalk.js.org/http-api.html', },
{ text: '📖 Contributing Guide', link: 'https://github.com/ArtalkJS/Artalk/blob/master/CONTRIBUTING.md' },
{ text: '🔖 Code of Conduct', link: 'https://github.com/ArtalkJS/Artalk/blob/master/CODE_OF_CONDUCT.md' },
]
}
]
},
nav: [
// NavbarItem
{
text: '介绍',
link: '/guide/intro',
},
{
text: '部署',
link: '/guide/deploy',
},
{
text: '配置',
link: '/guide/backend/config',
},
{
text: '迁移',
link: '/guide/transfer',
},
{
text: '案例',
link: '/guide/cases',
},
{
text: '开发',
link: '/develop/',
},
// NavbarGroup
{
text: '传送',
items: [
{
text: '代码仓库',
link: 'https://github.com/ArtalkJS/Artalk',
},
{
text: '文档镜像 (国内)',
link: 'https://artalk-docs.qwqaq.com'
}
],
},
],
socialLinks: [
{ icon: 'github', link: 'https://github.com/ArtalkJS/Artalk' }
],
search: {
provider: 'algolia',
options: {
appId: '2WNJ32WVTY',
apiKey: '6c6ebc345a87b738264f19095b78c91c',
indexName: 'artalk-js',
searchParameters: {
facetFilters: ['lang:zh-CN']
}
}
},
editLink: {
pattern: 'https://github.com/ArtalkJS/Artalk/edit/master/docs/:path',
text: '完善文档'
},
}
})
-3
View File
@@ -1,3 +0,0 @@
{
"latest": "2.6.3"
}
-36
View File
@@ -1,36 +0,0 @@
# Event
## 基本事件
|事件名|描述|
|-|-|
| `list-load` | 评论加载事件 |
| `list-loaded` | 评论加载完成事件 |
| `list-inserted` | 新增评论插入事件 |
| `editor-submit` | 编辑器提交事件 |
| `editor-submitted` | 编辑器提交完成事件 |
| `user-changed` | 本地用户数据变更事件 |
| `conf-loaded` | 配置变更事件 |
| `sidebar-show` | 侧边栏显示事件 |
| `sidebar-hide` | 侧边栏隐藏事件 |
## 添加事件监听
```js
Artalk.use(ctx => {
ctx.on('list-loaded', () => {
alert('评论已加载完毕')
})
})
```
## 解除事件监听
```js
let foo = function() { /* do something */ }
Artalk.use(ctx => {
ctx.on('list-loaded', foo)
ctx.off('list-loaded', foo)
})
```
-106
View File
@@ -1,106 +0,0 @@
# Frontend API
## 初始化 `Artalk.init`
创建 Artalk 实例化对象。
```js
Artalk.init({
el: '#Comments',
pageKey: '/post/1',
pageTitle: '关于引入 Artalk 的这档子事',
server: 'http://your_domain:8080',
site: 'Artalk 的博客',
})
```
## 更新配置 `Artalk.update`
修改 Artalk 当前配置。
```js
Artalk.update({
// 新的配置...
})
```
该函数调用后,`conf-loaded` 事件将被触发。
更新配置不会自动刷新评论列表,可按需继续执行 `Artalk.reload()` 函数。
注:前端的一些配置将会被后端的配置覆盖,详情见:[在后端控制前端](../guide/backend/fe-control.md)
## 重新加载 `Artalk.reload`
刷新 Artalk 评论列表。
```js
Artalk.reload()
```
列表加载前将触发 `list-load` 事件,加载完毕后将触发 `list-loaded` 事件。
## 释放资源 `Artalk.destroy`
销毁 Artalk 实例,用于资源释放。
```js
Artalk.destroy()
```
## 事件监听 `Artalk.on`
添加 Artalk 事件监听。
```js
Artalk.on('list-loaded', () => {
alert('评论列表加载完毕')
})
```
可监听事件类型见:[前端界面事件](./event.md)
## 解除监听 `Artalk.off`
解除 Artalk 事件监听。
```js
const handler = () => {
alert('评论列表加载完毕')
}
Artalk.on('list-loaded', handler)
Artalk.off('list-loaded', handler)
```
## 触发事件 `Artalk.trigger`
触发 Artalk 事件。
```js
Artalk.trigger('list-loaded')
```
## 扩展插件 `Artalk.use`
该 API 用于扩展 Artalk。
```js
Artalk.use((ctx) => {
ctx.editor.setContent("Hello World")
})
```
详情见:[插件开发](./plugs.md)
## 夜间模式 `Artalk.setDarkMode`
修改夜间模式,可以配合博客主题调用,例如当用户点击夜间模式切换按钮。
```js
Artalk.setDarkMode(true)
```
## 浏览量组件 `Artalk.loadCountWidget`
详情见:[浏览量统计](../guide/frontend/pv.md)
-17
View File
@@ -1,17 +0,0 @@
# 插件开发
你可以使用 `Artalk.use` 来扩展 Artalk。
```js
Artalk.use((ctx) => {
ctx.editor.setContent("Hello World")
})
```
## Context
::: warning
Context API 目前仍不稳定,开发可能会有变动,升级请关注 CHANGELOG。
:::
参考:[@artalk/types/context.d.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/packages/artalk/types/context.d.ts)
+2
View File
@@ -0,0 +1,2 @@
.vitepress/dist/**
.vitepress/cache/**
+253
View File
@@ -0,0 +1,253 @@
import { defineConfig } from "vitepress";
import iterator from "markdown-it-for-inline";
import * as Version from "../code/ArtalkVersion.json";
export default defineConfig({
title: "Artalk",
description: "一款简洁的自托管评论系统",
lang: "zh-CN",
head: [
["link", { rel: "icon", href: "/favicon.png" }],
[
"meta",
{
name: "viewport",
content:
"width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi",
},
],
// artalk
// ['link', { href: `https://npm.elemecdn.com/artalk@${Version.latest}/dist/Artalk.css`, rel: 'stylesheet' }],
// [
// "link",
// { href: `https://artalk.qwqaq.com/dist/Artalk.css`, rel: "stylesheet" },
// ],
// ['script', { src: ArtalkCDN.JS }],
// light gallery
[
"link",
{
href: "https://cdnjs.cloudflare.com/ajax/libs/lightgallery/2.3.0/css/lightgallery.css",
rel: "stylesheet",
},
],
[
"script",
{
src: "https://cdnjs.cloudflare.com/ajax/libs/lightgallery/2.3.0/lightgallery.min.js",
},
],
// katex
['link', { href: "https://unpkg.com/katex@0.15.3/dist/katex.min.css", rel: 'stylesheet' }],
['script', { src: 'https://unpkg.com/katex@0.15.3/dist/katex.min.js' }],
// ['script', { src: 'https://unpkg.com/@artalk/plugin-katex/dist/artalk-plugin-katex.js' }],
],
lastUpdated: true,
markdown: {
// @link https://github.com/shikijs/shiki
theme: {
light: "github-light",
dark: "github-dark",
},
config: (md) => {
md.use(iterator, "artalk_version", "text", function (tokens, idx) {
tokens[idx].content = tokens[idx].content.replace(
/:ArtalkVersion:/g,
Version.latest
);
});
md.use(iterator, "artalk_version_link", "link_open", (tokens, idx) => {
const href = tokens[idx].attrGet("href");
tokens[idx].attrSet(
"href",
href.replace(/:ArtalkVersion:/g, Version.latest)
);
});
},
},
locales: {
root: {
label: "简体中文",
lang: "zh",
link: "https://artalk.js.org/",
},
en: {
label: "English",
lang: "en",
link: "https://artalk-js-org.translate.goog/guide/intro?_x_tr_sl=auto&_x_tr_tl=en-US&_x_tr_hl=en-US&_x_tr_pto=wapp",
},
},
themeConfig: {
sidebar: {
"/guide/": [
{
text: "快速开始",
collapsed: false,
items: [
{ text: "项目介绍", link: "/guide/intro.md" },
{ text: "程序部署", link: "/guide/deploy.md" },
{ text: "数据迁移", link: "/guide/transfer.md" },
],
},
{
text: "核心指南",
collapsed: false,
items: [
{ text: "侧边栏", link: "/guide/frontend/sidebar.md" },
{ text: "邮件通知", link: "/guide/backend/email.md" },
{ text: "多元推送", link: "/guide/backend/admin_notify.md" },
{ text: "评论审核", link: "/guide/backend/moderator.md" },
{ text: "验证码", link: "/guide/backend/captcha.md" },
{ text: "图片上传", link: "/guide/backend/img-upload.md" },
{ text: "账户与多站点", link: "/guide/backend/multi-site.md" },
{ text: "解析相对路径", link: "/guide/backend/relative-path.md" },
{ text: "如何配置界面", link: "/guide/backend/fe-control.md" },
{ text: "English (i18n)", link: "/guide/frontend/i18n.md" },
],
},
{
text: "进阶指南",
collapsed: false,
items: [
{ text: "表情包", link: "/guide/frontend/emoticons.md" },
{ text: "浏览量统计", link: "/guide/frontend/pv.md" },
{ text: "Latex", link: "/guide/frontend/latex.md" },
{ text: "图片灯箱", link: "/guide/frontend/lightbox.md" },
{ text: "IP 属地", link: "/guide/frontend/ip-region.md" },
{ text: "精简版本", link: "/guide/frontend/artalk-lite.md" },
{ text: "置入博客", link: "/guide/frontend/import-blog.md" },
{ text: "置入框架", link: "/guide/frontend/import-framework.md" },
{ text: "前端 API", link: "/develop/fe-api.md" },
{ text: "开发文档", link: "/develop/index.md" },
],
},
{
text: "配置文档",
collapsed: true,
items: [
{ text: "后端配置", link: "/guide/backend/config.md" },
{ text: "前端配置", link: "/guide/frontend/config.md" },
],
},
{
text: "部署说明",
collapsed: true,
items: [
{ text: "守护进程", link: "/guide/backend/daemon.md" },
{ text: "反向代理", link: "/guide/backend/reverse-proxy.md" },
{ text: "编译构建", link: "/guide/backend/build.md" },
{ text: "程序升级", link: "/guide/backend/update.md" },
{ text: "Docker", link: "/guide/backend/docker.md" },
],
},
{
text: "更多内容",
collapsed: true,
items: [
{ text: "安全防范", link: "/guide/security.md" },
{ text: "扩展阅读", link: "/guide/extras.md" },
{ text: "案例展示", link: "/guide/cases.md" },
{ text: "关于我们", link: "/guide/about.md" },
],
},
],
"/develop/": [
{
text: "开发文档",
items: [
{ text: "开发说明", link: "/develop/index.md" },
{ text: "前端 API", link: "/develop/fe-api.md" },
{ text: "前端 Event", link: "/develop/event.md" },
{ text: "插件开发", link: "/develop/plugs.md" },
{
text: "🔬 HTTP API",
link: "https://artalk.js.org/http-api.html",
},
{
text: "📖 Contributing Guide",
link: "https://github.com/ArtalkJS/Artalk/blob/master/CONTRIBUTING.md",
},
{
text: "🔖 Code of Conduct",
link: "https://github.com/ArtalkJS/Artalk/blob/master/CODE_OF_CONDUCT.md",
},
],
},
],
},
nav: [
// NavbarItem
{
text: "介绍",
link: "/guide/intro",
},
{
text: "部署",
link: "/guide/deploy",
},
{
text: "配置",
link: "/guide/backend/config",
},
{
text: "迁移",
link: "/guide/transfer",
},
{
text: "案例",
link: "/guide/cases",
},
{
text: "开发",
link: "/develop/",
},
// NavbarGroup
{
text: "传送",
items: [
{
text: "代码仓库",
link: "https://github.com/ArtalkJS/Artalk",
},
// {
// text: "文档镜像 (国内)",
// link: "https://artalk-docs.qwqaq.com",
// },
],
},
],
socialLinks: [
{ icon: "github", link: "https://github.com/ArtalkJS/Artalk" },
],
search: {
provider: "algolia",
options: {
appId: "2WNJ32WVTY",
apiKey: "6c6ebc345a87b738264f19095b78c91c",
indexName: "artalk-js",
searchParameters: {
facetFilters: ["lang:zh-CN"],
},
},
},
editLink: {
pattern: "https://github.com/ArtalkJS/Artalk/edit/master/docs/:path",
text: "完善文档",
},
},
vite: {
server: {
open: "/guide/intro.html",
},
},
});
@@ -1,53 +1,62 @@
<template>
<div ref="artalkEl" style="margin-top: 20px;"></div>
<div ref="el" style="margin-top: 20px;"></div>
</template>
<script setup lang="ts">
import { watch, nextTick, ref, onMounted } from 'vue'
import { watch, nextTick, ref, onMounted, onUnmounted } from 'vue'
import { useData, useRouter } from 'vitepress'
import Artalk from 'artalk'
import 'artalk/dist/Artalk.css'
const artalkEl = ref<HTMLElement | null>(null)
const el = ref<HTMLElement | null>(null)
const router = useRouter()
const page = useData().page
onMounted(() => {
const script = document.createElement('script')
script.src = `https://artalk.qwqaq.com/dist/Artalk.js`
document.getElementsByTagName('head')[0].appendChild(script)
script.onload = () => {
initArtalk(page.value)
}
})
let artalk: Artalk
watch(() => router.route.data.relativePath, (path) => {
onMounted(() => {
nextTick(() => {
Artalk.update(getArtalkConfByPage(page.value))
Artalk.reload()
initArtalk(getConfByPage())
})
})
function getArtalkConfByPage(page: any) {
watch(() => router.route.path, () => {
nextTick(() => {
artalk.update(getConfByPage())
artalk.reload()
})
})
onUnmounted(() => {
artalk.destroy()
})
function initArtalk(conf: any) {
artalk = Artalk.init({
el: el.value,
emoticons: '/assets/emoticons/default.json',
gravatar: {
mirror: 'https://cravatar.cn/avatar/'
},
...conf
})
loadExtraFuncs()
}
function getConfByPage() {
return {
pageKey: 'https://artalk.js.org'+location.pathname,
pageTitle: page.title,
pageKey: 'https://artalk.js.org'+router.route.path,
pageTitle: page.value.title,
server: 'https://artalk.qwqaq.com',
site: 'ArtalkDocs',
}
}
function initArtalk(page: any) {
Artalk.init({
el: artalkEl.value,
emoticons: '/assets/emoticons/default.json',
gravatar: {
mirror: 'https://cravatar.cn/avatar/'
},
...getArtalkConfByPage(page)
})
function loadExtraFuncs() {
// 图片灯箱插件
Artalk.on('list-loaded', () => {
artalk.on('list-loaded', () => {
document.querySelectorAll('.atk-comment .atk-content').forEach(($content) => {
const imgEls = $content.querySelectorAll<HTMLImageElement>('img:not([atk-emoticon]):not([atk-lightbox])');
imgEls.forEach((imgEl) => {
@@ -66,7 +75,7 @@ function initArtalk(page: any) {
// 夜间模式
const darkMode = document.querySelector('html').classList.contains('dark')
Artalk.setDarkMode(darkMode)
artalk.setDarkMode(darkMode)
new MutationObserver((mList) => {
mList.forEach((m) => {
@@ -74,7 +83,7 @@ function initArtalk(page: any) {
// @ts-ignore
const darkMode = m.target.classList.contains('dark')
Artalk.setDarkMode(darkMode)
artalk.setDarkMode(darkMode)
})
}).observe(document.querySelector('html'), { attributes: true })
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+7 -6
View File
@@ -1,19 +1,20 @@
## Artalk Documentation
# Artalk Documentation
> The Documentation of Artalk
[![Netlify Status](https://api.netlify.com/api/v1/badges/6580cce0-4b27-465e-8d73-1e6a832942e9/deploy-status)](https://app.netlify.com/sites/artalk/deploys)
Documentation of Artalk
## Build
```bash
pnpm docs:dev
pnpm docs:build
pnpm dev:docs
pnpm build:docs
```
## Deploy
[![Netlify Status](https://api.netlify.com/api/v1/badges/6580cce0-4b27-465e-8d73-1e6a832942e9/deploy-status)](https://app.netlify.com/sites/artalk/deploys)
文档通过 [Netlify](https://www.netlify.com/) 对 master 分支进行自动部署。
## Licensed
CC BY-NC-SA 4.0
File renamed without changes.
File renamed without changes.
+3
View File
@@ -0,0 +1,3 @@
{
"latest": "2.8.3"
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
+49
View File
@@ -0,0 +1,49 @@
# Event
## 基本事件
|事件名|描述|
|-|-|
| `created` | 初始化后 |
| `mounted` | 数据加载后 |
| `updated` | 数据更新后 |
| `unmounted` | 销毁后 |
| `list-fetch` | 评论列表请求时 |
| `list-fetched` | 评论列表请求后 |
| `list-load` | 评论装载前 |
| `list-loaded` | 评论装载后 |
| `list-failed` | 评论加载错误时 |
| `list-goto-first` | 评论列表归位时 |
| `list-reach-bottom` | 评论列表滚动到底部时 |
| `comment-inserted` | 评论插入后 |
| `comment-updated` | 评论更新后 |
| `comment-deleted` | 评论删除后 |
| `comment-rendered` | 评论节点渲染后 |
| `notifies-updated` | 未读消息变更时 |
| `list-goto` | 评论跳转时 |
| `page-loaded` | 页面数据更新后 |
| `editor-submit` | 编辑器提交时 |
| `editor-submitted` | 编辑器提交后 |
| `user-changed` | 本地用户数据变更时 |
| `sidebar-show` | 侧边栏显示 |
| `sidebar-hide` | 侧边栏隐藏 |
事件声明代码:[@ArtalkJS/Artalk - src/types/event.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/artalk/src/types/event.ts)
## 添加事件监听
```js
artalk.on('list-loaded', () => {
alert('评论已加载完毕')
})
```
## 解除事件监听
```js
let foo = function() { /* do something */ }
artalk.on('list-loaded', foo)
artalk.off('list-loaded', foo)
```
+191
View File
@@ -0,0 +1,191 @@
# Frontend API
## 安装依赖
用你喜欢的包管理器安装 Artalk:
```bash
pnpm add artalk
# 或者使用 npm
npm install artalk
```
## 创建实例 `init`
调用该函数将创建并得到一个 Artalk 的实例化对象,可用于后续操作。
```js
import Artalk from 'artalk'
const artalk = Artalk.init({
el: '#Comments',
pageKey: '/post/1',
pageTitle: '关于引入 Artalk 的这档子事',
server: 'http://your_domain:8080',
site: 'Artalk 的博客',
})
```
调用该函数会异步地向后端发起请求:
1. 获取前端配置
2. 获取评论列表
配置和插件加载完毕后会触发 `mounted` 事件。
评论列表加载完毕后会触发 `list-loaded` 事件。
注:前端界面配置可能会被覆盖,详情见:[在后端控制前端](../guide/backend/fe-control.md)。
## 释放资源 `destroy`
销毁 Artalk 实例,用于资源释放。
```js
const artalk = Artalk.init({ ... })
artalk.destroy()
```
调用该函数时,将触发 `unmounted` 事件。释放资源将执行 Artalk 挂载的 DOM 节点删除,以及解除 Artalk 事件监听等操作。当该函数执行完毕后,Artalk 实例将不再可用。
在 Vue / React 等框架中,务必在组件销毁时调用该函数,否则会造成内存泄漏:
```ts
import { onUnmounted } from 'vue'
onUnmounted(() => {
artalk.destroy()
})
```
## 更新配置 `update`
修改 Artalk 当前配置。
```js
const artalk = Artalk.init({ ... })
artalk.update({
// 新的配置...
})
```
调用该函数将触发 `updated` 事件。
更新配置不会自动刷新评论列表,可按需继续执行 `artalk.reload()` 函数。
请注意,该函数是一个实例化对象中的成员方法,并非全局函数。
前端配置参考:[前端配置](../guide/frontend/config.md)
## 重新加载 `reload`
重新从后端加载 Artalk 评论列表数据。
```js
const artalk = Artalk.init({ ... })
artalk.reload()
```
列表加载前将触发 `list-load` 事件,加载完毕后将触发 `list-loaded` 事件。
## 监听事件 `on`
添加 Artalk 事件监听。
```js
const artalk = Artalk.init({ ... })
artalk.on('list-loaded', (comments) => {
// comments 包含当前页面所有评论数据 (而非仅本次请求获取的部分评论)
console.log('评论列表加载完毕: ', comments)
})
```
可参考:[前端 Event](./event.md)。
## 解除监听 `off`
解除 Artalk 事件监听。
```js
const artalk = Artalk.init({ ... })
const handler = () => {
alert('评论列表加载完毕')
}
artalk.on('list-loaded', handler)
artalk.off('list-loaded', handler)
```
## 触发事件 `trigger`
触发 Artalk 事件。
```js
const artalk = Artalk.init({ ... })
artalk.trigger('list-loaded', [...])
```
## 加载插件 `use`
通过 `Artalk.use` 函数加载插件。请注意,该函数是一个全局函数,并非实例化对象中的方法。通过该函数加载的插件将对所有 Artalk 实例生效。
```js
import Artalk from 'artalk'
Artalk.use((ctx) => {
ctx.editor.setContent("Hello World")
})
const artalk = Artalk.init({ ... })
```
详情见:[插件开发](./plugs.md)
## 夜间模式 `setDarkMode`
修改夜间模式,可以配合博客主题调用,例如当用户点击夜间模式切换按钮。
```js
const artalk = Artalk.init({ ... })
artalk.setDarkMode(true)
```
也可以通过调用 `Artalk.init` 时,通过 `darkMode` 参数设置初始夜间模式。
```js
const artalk = Artalk.init({
// ...其他配置
darkMode: 'auto',
})
```
## 浏览量组件 `loadCountWidget`
详情见:[浏览量统计](../guide/frontend/pv.md)
## 获取配置 `getConf`
获取当前 Artalk 配置。
```js
const artalk = Artalk.init({ ... })
const conf = artalk.getConf()
```
## 获取挂载元素 `getEl`
获取当前 Artalk 挂载的 DOM 元素。
```js
const artalk = Artalk.init({ ... })
const el = artalk.getEl()
```
@@ -19,10 +19,10 @@
由于 Artalk 正处于开发阶段,使用此文档中 `API`、`Event` 前请务必检查时效性。
- `API` 部分参考源码
* [@ArtalkJS/Artalk - src/api/](https://github.com/ArtalkJS/Artalk/tree/master/ui/packages/artalk/src/api)
* [@ArtalkJS/Artalk - src/api/](https://github.com/ArtalkJS/Artalk/tree/master/ui/artalk/src/api)
* [@ArtalkJS/Artalk - server/server.go](https://github.com/ArtalkJS/Artalk/blob/master/server/server.go)
- `UI` 及 `Event` 部分参考源码
* [@ArtalkJS/Artalk - src/artalk.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/packages/artalk/src/artalk.ts)
* [@ArtalkJS/Artalk - types/event.d.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/packages/artalk/types/event.d.ts)
* [@ArtalkJS/Artalk - src/artalk.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/artalk/src/artalk.ts)
* [@ArtalkJS/Artalk - src/types/event.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/artalk/src/types/event.ts)
通过 Artalk 提供的 `API` 和 `Event`,你可以实现很多高级功能,比如编写评论管理机器人、评论提醒推送插件等。Artalk 并不为此提供技术指导,但鼓励你参考此处的文档自行定制。
+90
View File
@@ -0,0 +1,90 @@
# 插件开发
使用 `Artalk.use` 来扩展 Artalk。
```js
import Artalk from 'artalk'
Artalk.use((ctx) => {
ctx.on('list-loaded', () => {
console.log('评论列表加载完毕')
ctx.getCommentNodes().forEach((node) => {
node.getEl().style.background = 'red'
})
})
})
Artalk.use((ctx) => {
let el = null
ctx.on('mounted', () => {
el = document.createElement('div')
document.body.appendChild(el)
console.log('Artalk 实例被挂载')
})
ctx.on('unmounted', () => {
el.remove()
console.log('Artalk 实例被销毁')
})
})
const artalk = Artalk.init({ ... })
```
请注意:
- `Artalk.use` 必须在 `Artalk.init` 之前调用才生效。
- 请勿依赖插件的加载顺序,请监听事件来执行插件逻辑。
- 当所有的插件加载完毕后,会触发 `created` 事件。
- 当插件和配置加载完毕后,会触发 `mounted` 事件。
- 当 Artalk 实例被销毁时,会触发 `unmounted` 事件。
- 当配置发生变化时,会触发 `updated` 事件。
在 use 函数中,你可以通过 `ctx` 来访问 Artalk 的 Context 对象。
## Context
Context 对象包含了 Artalk 的上下文信息。
| 成员 | 说明 |
| --- | --- |
| `ctx.getEl` | 获取容器元素 |
| `ctx.getConf` | 获取配置 |
| `ctx.updateConf` | 更新配置 |
| `ctx.watchConf` | 监听配置 |
| `ctx.setDarkMode` | 设置夜间模式 |
| `ctx.getApi` | 获取 API 客户端对象 |
|--|--|
| `ctx.fetch` | 获取评论数据 |
| `ctx.reload` | 重载评论列表 |
| `ctx.getComments` | 获取所有评论数据对象 |
| `ctx.getCommentNodes` | 获取所有评论节点对象 |
|--|--|
| `ctx.on` | 添加事件监听 |
| `ctx.off` | 解除事件监听 |
| `ctx.trigger` | 触发事件 |
|--|--|
| `ctx.get` | 获取依赖 |
| `ctx.inject` | 注入依赖 |
::: warning
Context API 目前仍不稳定,开发可能会有变动,升级请关注 CHANGELOG。
:::
参考:[@artalk/src/types/context.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/artalk/src/types/context.ts)
Artalk 包含完整的 TypeScript 类型定义,你可以通过编辑器的自动补全来查看 API。
## 示例插件
Artalk 有很多内置的插件,你可以参考它们的源码来开发自己的插件。
[@ArtalkJS/Artalk - src/plugins](https://github.com/ArtalkJS/Artalk/tree/master/ui/artalk/src/plugins)
我们还提供了一些外置的插件,同样可以参考:
| 插件 | 说明 |
| --- | --- |
| [@artalk/plugin-katex](https://github.com/ArtalkJS/Artalk/tree/master/ui/plugin-katex) | LaTeX 公式插件 |
| [@artalk/plugin-lightbox](https://github.com/ArtalkJS/Artalk/tree/master/ui/plugin-lightbox) | 图片灯箱插件 |
+2 -3
View File
@@ -2,11 +2,11 @@
layout: home
title: Artalk
titleTemplate: The Selfhosted Comment System
titleTemplate: A Self-hosted Comment System
hero:
name: Artalk
text: The Selfhosted Comment System
text: A Self-hosted Comment System
tagline: Elevate your online conversations with a comment system that embodies the trifecta of lightness, security, and refinement.
actions:
- theme: brand
@@ -30,4 +30,3 @@ features:
title: Flexible
details: Use Golang to interpret the excellence of multiple platforms
---
File renamed without changes.
@@ -113,7 +113,7 @@ admin_notify:
![](/images/notify/tg-2.png)
详情可参考:[“Bots: An introduction for developers - Telegram”](https://core.telegram.org/bots)
详情可参考:[Bots: An introduction for developers - Telegram](https://core.telegram.org/bots)
::: tip
@@ -151,7 +151,7 @@ admin_notify:
<img src="/images/notify/lark-3.png" width="400px">
可参考:[“飞书帮助中心文档”](https://www.feishu.cn/hc/zh-CN/articles/360024984973)
可参考:[飞书帮助中心文档](https://www.feishu.cn/hc/zh-CN/articles/360024984973)
## 钉钉
@@ -164,7 +164,7 @@ admin_notify:
secret: ""
```
可参考:[“钉钉开放文档”](https://open.dingtalk.com/document/robots/custom-robot-access)
可参考:[钉钉开放文档](https://open.dingtalk.com/document/robots/custom-robot-access)
## Bark
@@ -227,7 +227,16 @@ admin_notify:
{{link_to_reply}}
```
可用变量和邮件模板相同,可参考:[“邮件模版”](./email.md#邮件模板)
可用变量和邮件模板相同,可参考:[邮件模版](./email.md#邮件模板)
## 待审评论仍然发送通知 `notify_pending`
```yaml
admin_notify:
notify_pending: false
```
`notify_pending` 默认为关闭状态,当该项设置为 `false` 时,待审评论不会发送通知。你可以在控制中心查看所有待审核的评论。
## 嘈杂模式 `noise_mode`
@@ -236,7 +245,7 @@ admin_notify:
noise_mode: false
```
noise_mode 默认为关闭状态,当该项设置为 `false` 时,站内仅向管理员回复的消息会发送通知,例如「普通用户 A」回复「普通用户 B」,这两个用户之间的通讯不会通知管理员。
`noise_mode` 默认为关闭状态,当该项设置为 `false` 时,站内仅向管理员回复的消息会发送通知,例如「普通用户 A」回复「普通用户 B」,这两个用户之间的通讯不会通知管理员。
注:当 `moderator.pending_default` 为 `true` 时,noise_mode 为始终开启状态。
@@ -264,7 +273,7 @@ admin_notify:
|`notify_subject`|通知标题 |String| 对应 admin_notify.notify_subject 配置项 |
|`notify_body` |通知内容 |String| 根据 admin_notify.notify_tpl 模版渲染 |
|`comment` |评论内容 |Object| 新创建的评论数据对象 |
|`parent_comment`|评论回复的目标|Object| Root 根节点评论类型改项为 null |
|`parent_comment`|评论回复的目标|Object| 如果是根节点评论值为 null |
**Body 数据样本**
File renamed without changes.
File renamed without changes.
@@ -65,7 +65,7 @@ app_key: "<任意的字符>"
locale: "zh-CN"
```
详情参考:[“多语言”](../frontend/i18n.md)
详情参考:[多语言](../frontend/i18n.md)
## 数据库 `db`
@@ -96,6 +96,7 @@ db:
charset: "utf8mb4" # 编码格式
table_prefix: "" # 表前缀 (例如:"atk_")
ssl: false # 启用 SSL
prepare_stmt: true # 预编译语句
```
数据表将在 Artalk 启动时自动完成创建,无需额外操作。
@@ -118,7 +119,7 @@ db:
Artalk 支持多站点,你可以创建多个管理员账户,为其分配站点,让你的朋友们共用同一个后端程序。
详情参考:[“管理员 × 多站点”](/guide/backend/multi-site.md)
详情参考:[管理员 × 多站点](/guide/backend/multi-site.md)
## 可信域名 `trusted_domains`
@@ -178,31 +179,31 @@ Artalk.init({ site: "Artalk 官网" })
## 前端配置 `frontend`
增加 `frontend` 字段内容可以在后端控制前端的配置,详情可参考:[“在后端控制前端”](/guide/backend/fe-control)。
增加 `frontend` 字段内容可以在后端控制前端的配置,详情可参考:[在后端控制前端](/guide/backend/fe-control)。
## 邮件通知 `email`
配置邮件通知,让回复通过邮件的形式通知目标用户,你可以自定义邮件发送者名称、标题、模版等。
详情参考:[“后端 · 邮件通知”](/guide/backend/email.md)
详情参考:[后端 · 邮件通知](/guide/backend/email.md)
## 多元推送 `admin_notify`
你可以配置多种消息发送方式,例如飞书、Telegram 等,当收到新的评论时通知管理员。
详情参考:[“后端 · 多元推送”](/guide/backend/admin_notify.md)
详情参考:[后端 · 多元推送](/guide/backend/admin_notify.md)
## 评论审核 `moderator`
配置评论审核来自动拦截垃圾评论。
详情参考:[“后端 · 评论审核”](/guide/backend/moderator.md)
详情参考:[后端 · 评论审核](/guide/backend/moderator.md)
## 验证码 `captcha`
支持图片、滑动验证码,通过验证码对请求频率进行限制。
详情参考:[“后端 · 验证码”](/guide/backend/captcha.md)
详情参考:[后端 · 验证码](/guide/backend/captcha.md)
## 高速缓存 `cache`
@@ -348,5 +349,5 @@ test_file: "./data/artalk.log"
配置文件相关代码:[/internal/config/config.go](https://github.com/ArtalkJS/Artalk/blob/master/internal/config/config.go)
前往:[“前端配置”](/guide/frontend/config.md)
前往:[前端配置](/guide/frontend/config.md)
:::
+144
View File
@@ -0,0 +1,144 @@
# 守护进程
## Systemd
前提条件:
- Artalk 二进制文件,可在 [GitHub Release](https://github.com/ArtalkJS/Artalk/releases) 下载
- `systemctl --version` 232 或更新的版本
- `sudo` 管理员权限
移动 Artalk 到 `$PATH`,例如:
```bash
sudo mv artalk /usr/bin/
```
测试是否有效:
```bash
artalk version
```
创建名为 artalk 的用户组:
```bash
sudo groupadd --system artalk
```
创建一个名为 artalk 的用户,并且拥有一个可写的 home 目录:
```bash
sudo useradd --system \
--gid artalk \
--create-home \
--home-dir /var/lib/artalk \
--shell /usr/sbin/nologin \
--comment "Artalk server" \
artalk
```
如果你有 Artalk 的配置文件,请确保刚刚创建的 artalk 用户有权限可以读取。
创建服务文件:
```bash
sudo vim /etc/systemd/system/artalk.service
```
```ini
[Unit]
Description=Artalk
Documentation=https://artalk.js.org
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=notify
User=artalk
Group=artalk
ExecStart=/usr/bin/artalk server -w /var/lib/artalk -c /etc/artalk/artalk.yml
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
```
请仔细检查 `ExecStart` 和 `ExecReload`。 确保二进制文件的位置和程序启动参数是正确的
例如:更改 `-c` 参数的路径来指定配置文件,`-w` 参数可以更改工作目录。
请注意配置文件中的所有相对路径都是基于工作目录,例如配置文件中的 `./data/` 文件夹,如果启动参数 `-w /var/lib/artalk`,将读取 `/var/lib/artalk/data/` 目录。请确保该目录中的文件对于创建的 `artalk` 账户有权限可读写。
保存服务文件后,你可以设置自动启动服务:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now artalk
```
验证服务是否正常运行:
```bash
systemctl status artalk
```
一些常用的命令:
- 启动服务:`systemctl start artalk`
- 停止服务:`systemctl stop artalk`
- 查看状态:`systemctl status artalk`
- 查看日志:`journalctl -u artalk --no-pager | less +G`
## Tmux
tmux 将创建一个持续的命令行会话,在 SSH 或 tty 断开后保持在后台。
Note: 服务器关闭或重启后,tmux 会话将被清除,需要手动重新运行程序。
1. 创建会话 `tmux new -s artalk`
2. 运行程序 `./artalk server`
恢复接入会话:`tmux attach -t artalk`
查看所有会话:`tmux ls`
## Supervisor
以宝塔面板举例:打开「软件商店」,搜索并安装「Supervisor管理器」:
![](/images/baota-supervisor/0.png)
安装后,打开插件,点击「添加守护程序」:
![](/images/baota-supervisor/1.png)
> - 启动用户:`root` 或其他
> - 运行目录:点击右侧图标,选择 Artalk 所在目录
> - 启动命令:`./artalk server`
## Docker
更新 Docker 容器的 [Restart 策略](https://docs.docker.com/config/containers/start-containers-automatically/#use-a-restart-policy) 以达到进程守护效果。
```bash
docker update --restart=unless-stopped artalk
```
## Docker Compose
在 `docker-compose.yml` 文件给服务添加 `restart: unless-stopped` 策略:
```diff
version: '3'
services:
artalk:
+ restart: unless-stopped
```
+5
View File
@@ -0,0 +1,5 @@
# 数据
## 备份
前往:[数据迁移 · 备份](/guide/transfer.md)
@@ -12,11 +12,11 @@ Artalk 提供后端程序的 Docker 镜像,以便加速部署流程,提供
:::tip
推荐使用 Docker Compose:[“后端部署”](/guide/backend/install) 页面已详细讲解。
推荐使用 Docker Compose,可参考 [程序部署](/guide/deploy) 页面的步骤。
:::
常规的 Docker 容器创建可参考:
Docker 容器创建:
```bash
# 为 Artalk 创建一个目录
@@ -112,4 +112,4 @@ docker exec -it artalk bash
## 多平台兼容性
Docker 镜像暂仅提供 amd_64 构建,若需要在 ARM 架构运行,请下载 [二进制编译构建](/guide/backend/install.md#普通方式)
Docker 镜像暂仅提供 x86、arm64 的镜像构建,如需更多平台架构版本,请下载 [二进制构建部署](/guide/deploy.md#普通方式部署)。
@@ -324,4 +324,4 @@ admin_notify:
注:旧版 `email.mail_subject_to_admin` 配置项已弃用,请使用以上替代。
不局限于邮件,Artalk 支持多种方式向管理员发送通知,参考:[“多元推送”](./admin_notify.md#邮件通知)。
不局限于邮件,Artalk 支持多种方式向管理员发送通知,参考:[多元推送](./admin_notify.md#邮件通知)。
@@ -1,10 +1,10 @@
# 在后端控制前端
你可以在后端完全控制前端界面的行为(包括设定[前端的配置](/guide/frontend/config)),我们推荐使用这种方式部署 Artalk,并且这个特性「默认开启」。
你可以在后端完全控制前端界面的行为(包括设定几乎所有[前端配置项](/guide/frontend/config)),我们推荐使用这种方式配置 Artalk 界面,并且这个特性「默认开启」。
## 如何修改前端配置
## 如何修改前端界面配置
在侧边栏的[控制中心](/guide/frontend/sidebar.md#控制中心)提供了图形设置界面,你能快速轻松地对前端配置进行修改。
在侧边栏的[控制中心](/guide/frontend/sidebar.md#控制中心)提供了图形设置界面,你能快速轻松地对前端界面配置进行修改。
<img src="../../images/sidebar/fe-setting.png" width="400px">
@@ -60,7 +60,7 @@ Artalk.init({
建议 `frontend.emoticons` 填入表情包的 URL,而非 Object。
参考文档:[“表情包”](/guide/frontend/emoticons)
参考文档:[表情包](/guide/frontend/emoticons)
如需传递 Object,可以将其转为 JSON 字符串格式,例如:
@@ -41,7 +41,7 @@ img_upload:
频率限制跟随 `captcha` 验证码配置,当超出限制将弹出验证码。
可参考:[“后端 · 验证码”](/guide/backend/captcha.md)
可参考:[后端 · 验证码](/guide/backend/captcha.md)
## path
File renamed without changes.
File renamed without changes.
@@ -63,7 +63,7 @@ moderator:
## 腾讯云文本内容安全
可参考:[“腾讯云文档”](https://cloud.tencent.com/document/product/1124/64508)
可参考:[腾讯云文档](https://cloud.tencent.com/document/product/1124/64508)
开通「文本内容安全」后,在「访问管理」-「API 密钥管理」新增具有权限的 Secret,然后填入配置:
@@ -78,7 +78,7 @@ moderator:
## 阿里云内容安全
可参考:[“阿里云文档”](https://help.aliyun.com/document_detail/28417.html)
可参考:[阿里云文档](https://help.aliyun.com/document_detail/28417.html)
开通「阿里云内容安全」后,阿里云后台创建 Access Key 并填入配置:
+82
View File
@@ -0,0 +1,82 @@
# 管理员 × 多站点
Artalk 支持多站点,管理员可以创建多个站点,并对不同站点的评论、页面进行集中管理。
## 创建管理员
执行命令根据命令行提示快速创建管理员。
```sh
./artalk admin
```
如果使用 Docker 可以执行以下命令:
```sh
docker exec -it artalk artalk admin
```
之后可使用管理员账户登录控制中心,在用户管理页面的图形界面可创建更多账户,无需手动编辑配置文件。
## 站点的创建和管理
你可以在侧边栏「[控制中心](../frontend/sidebar.md#控制中心)」创建多个站点,管理站点和快速切换站点,详情可参考:[侧边栏](/guide/frontend/sidebar.html)。
## 管理员配置
你可以设置多个管理员账户,当输入框输入匹配管理员用户名和邮箱时,将弹出密码验证提示框,
并且只有管理员才能访问「[控制中心](../frontend/sidebar.md#控制中心)」,在前端对评论内容进行管理操作。
(可选操作)通过配置文件添加管理员:
```yaml
admin_users:
- name: "admin"
email: "admin@example.com"
password: "(bcrypt)$2y$10$ti4vZYIrxVN8rLcYXVgXCO.GJND0dyI49r7IoF3xqIx8bBRmIBZRm"
badge_name: "管理员"
badge_color: "#0083FF"
- name: "admin2"
email: "admin2@example.com"
password: "(bcrypt)$2y$10$ti4vZYIrxVN8rLcYXVgXCO.GJND0dyI49r7IoF3xqIx8bBRmIBZRm"
badge_name: "小管理员"
badge_color: "#0083FF"
```
每项配置的解释:
- **name** & **email**:用户名和邮箱,**不区分大小写**。
- **password**:用户密码。
支持 bcrypt 和 md5 加密,例如填写:`"(md5)50c21190c6e4e5418c6a90d2b5031119"`。
**建议使用更安全的 bcrypt 加密算法**,在 Linux 环境下,你可以使用 [htpasswd 命令](https://httpd.apache.org/docs/2.4/programs/htpasswd.html) 来生成密文:
```bash
unset HISTFILE # 临时禁用 history 防止密码在历史记录中出现
htpasswd -bnBC 10 "" "your_password" | tr -d ':'
```
然后配置填写:`"(bcrypt)$2y$10$ti4vZYIrxVN8rLcY..."`,以 `(bcrypt)` 开头。
命令解释参考:[Compute bcrypt hash from command line](https://unix.stackexchange.com/questions/307994/compute-bcrypt-hash-from-command-line#answer-419855)
- **badge_name**:用户显示的头衔徽标文字。
- **badge_color**:用户显示的头衔徽标背景颜色。
### 控制管理员接收邮件通知
当页面有新的评论时,默认配置是邮件会发送给全部管理员,但你可以配置 `receive_email` 强制禁用它。
这对于设定了多个邮箱,但又不希望某些邮箱收到评论邮件的情况很有帮助。
- **receive_email**:设置为 `false` 系统将不会发送邮件通知给该用户。
注:禁止后该管理员用户仍可以收到来自他人的 @AT 回复,只是当用户对页面进行评论时 (创建根评论时) 不发送邮件通知。
```yaml
admin_users:
- name: "admin"
receive_email: false # ← 强制不接收邮件
```
File renamed without changes.
File renamed without changes.
@@ -1,5 +1,25 @@
# 反向代理
## Caddy
**/etc/caddy/Caddyfile**
```nginx
artalk.your_domain.com {
tls /etc/caddy/ssl/cert.pem /etc/caddy/ssl/cert.key
reverse_proxy http://localhost:23366 {
header_up X-Forwarded-For {header.X-Forwarded-For}
}
}
```
执行重载命令:
```sh
sudo systemctl reload caddy
```
## Nginx
假定:
@@ -67,16 +87,6 @@ Artalk.init({ server: "http://artalk.your_domain.com" })
尤其是运行在 Docker 容器内的 artalk,注意检查 IP 和端口是否能够被 Nginx 正常访问
:::
## Caddy
创建 Caddyfile:
```
artalk.your_domain.com {
reverse_proxy / http://localhost:23366
}
```
## Apache
需要启用反代模块 `mod_proxy.c`
@@ -12,13 +12,13 @@
:::tip
执行 `./artalk upgrade -f` 携带参数 `-f` 来进行同版本号的补充更新。
执行 `./artalk upgrade -f` 携带参数 `-f` 执行强制更新。
:::
## Docker 升级
可参考:[“Docker · 升级”](./docker.md#升级)
可参考:[Docker · 升级](./docker.md#升级)
## 普通方式
File renamed without changes.
@@ -15,7 +15,7 @@ docker run -d \
> 假设域名 `http://your_domain` 已正确添加 DNS 记录并指向你的服务器 IP
浏览器打开 `http://your_domain:8080` 将出现 Artalk 后台登陆界面。
浏览器打开 `http://your_domain:8080` 将出现 Artalk 后台登录界面。
执行命令创建管理员账户:
@@ -51,14 +51,11 @@ Artalk.init({
在控制台,你可以根据喜好配置评论系统、[将评论迁移到 Artalk](./transfer.md)。
祝贺!你已成功完成 Artalk 部署 🥳
🥳 你已成功完成 Artalk 部署!
## 普通方式部署
1. 前往 [GitHub Release](https://github.com/ArtalkJS/Artalk/releases) 下载程序压缩包
> 注:我们已将 ArtalkGo 与主仓库合并,历史旧版可在[此页面](https://github.com/ArtalkJS/ArtalkGo/releases)查看,日后新版将在[新页面](https://github.com/ArtalkJS/Artalk/releases)发布。
2. 提取压缩包:`tar -zxvf artalk_版本号_系统_架构.tar.gz`
3. 运行程序 `./artalk server`
4. 前端配置
@@ -67,25 +64,16 @@ Artalk.init({
Artalk.init({ server: "http://your_domain:23366" })
```
**其它可选操作:**
**进一步操作:**
- [“反向代理端口到 80 / 443 (Nginx, Apache)”](./backend/reverse-proxy.md)
- ["持久化运作 (tmux, systemd, supervisor)"](./backend/daemon.md)
- [守护进程 (Systemd, Supervisor)](./backend/daemon.md)
- [反向代理 (Caddy, Nginx, Apache)](./backend/reverse-proxy.md)
**附表:文件名释义表**
如果有需要,你还可以自行编译程序,参考:[后端构建](./backend/build.md)。
|文件名|操作系统|CPU 架构|
|:-|:-:|:-:|
|artalk_linux_amd64.tar.gz|Linux|x86_64|
|artalk_linux_arm64.tar.gz|Linux|ARM64|
|artalk_linux_arm7.tar.gz|Linux|ARMv7|
|artalk_windows_amd64.zip|Windows|x86_64|
|artalk_darwin_arm64.tar.gz|macOS|Apple Silicon|
|artalk_darwin_amd64.tar.gz|macOS|Intel Chip|
## Compose 部署
## Docker Compose 部署
提供 docker-compose.yaml 文件可供参考:
**compose.yaml**
```yaml
version: "3.5"
@@ -100,7 +88,7 @@ services:
- ./data:/data
```
在与配置文件相同的目录执行命令创建容器:
执行命令创建容器:
```bash
docker-compose up -d
@@ -118,11 +106,7 @@ docker-compose exec artalk bash # 进入容器
:::
> 详细可见:[“后端 · Docker”](./backend/docker.md)
## 自行编译并运行
可参考:[“后端构建”](./backend/build.md)
可参考:[Docker 部署文档](./backend/docker.md)
## CDN 资源
@@ -135,20 +119,7 @@ docker-compose exec artalk bash # 进入容器
Artalk 后端程序内嵌了前端 JS、CSS 文件,使用公共 CDN 资源请注意前后端版本的兼容性。
Artalk 静态资源通过上游 [CDNJS](https://cdnjs.com/) 分发,国内有许多镜像可供选择:
**BootCDN (国内)**
> https://cdn.bootcdn.net/ajax/libs/artalk/:ArtalkVersion:/Artalk.js
>
> https://cdn.bootcdn.net/ajax/libs/artalk/:ArtalkVersion:/Artalk.css
**ElemeCDN (国内)**
> https://npm.elemecdn.com/artalk@:ArtalkVersion:/dist/Artalk.js
>
> https://npm.elemecdn.com/artalk@:ArtalkVersion:/dist/Artalk.css
Artalk 静态资源通过上游 CDNJS 分发,以下镜像资源可供选择:
**CDNJS**
@@ -156,6 +127,32 @@ Artalk 静态资源通过上游 [CDNJS](https://cdnjs.com/) 分发,国内有
>
> https://cdnjs.cloudflare.com/ajax/libs/artalk/:ArtalkVersion:/Artalk.css
**SUSTech Mirrors (境内)**
> https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/artalk/:ArtalkVersion:/Artalk.js
>
> https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/artalk/:ArtalkVersion:/Artalk.css
::: details 查看更多
**Staticfile CDN (境内)**
> https://cdn.staticfile.org/artalk/:ArtalkVersion:/Artalk.js
>
> https://cdn.staticfile.org/artalk/:ArtalkVersion:/Artalk.css
**BootCDN (境内)**
> https://cdn.bootcdn.net/ajax/libs/artalk/:ArtalkVersion:/Artalk.js
>
> https://cdn.bootcdn.net/ajax/libs/artalk/:ArtalkVersion:/Artalk.css
**75CDN (境内)**
> https://lib.baomitu.com/artalk/:ArtalkVersion:/Artalk.js
>
> https://lib.baomitu.com/artalk/:ArtalkVersion:/Artalk.css
**UNPKG**
> https://unpkg.com/artalk@:ArtalkVersion:/dist/Artalk.js
@@ -168,11 +165,9 @@ Artalk 静态资源通过上游 [CDNJS](https://cdnjs.com/) 分发,国内有
>
> https://cdn.jsdelivr.net/npm/artalk@:ArtalkVersion:/dist/Artalk.css
## ArtalkLite
:::
可选择精简版 [ArtalkLite](./frontend/artalk-lite.md):体积更小、更简约。
## Node 环境
## Node 项目
```bash
pnpm add artalk
@@ -189,13 +184,20 @@ Artalk.init({
})
```
## 何时引入、何时 init?
可参考:
- 可以在任意位置引入 JS 和 CSS 资源,但需确保 JS 引入在执行 `Artalk.init({})` 前。
- 执行 `Artalk.init({ el: '#x' })` 时,需要确保 `<div id="x"></div>` 存在于页面当中。
可参考:[“前端框架引入”](./frontend/import-framework.md) / [“博客引入”](./frontend/import-blog.md)
- [置入框架文档](./frontend/import-framework.md)
- [置入博客文档](./frontend/import-blog.md)
- [前端 API](../develop/fe-api.md)
## 数据导入
从其他评论系统导入数据:[“数据迁移”](./transfer.md)
从其他评论系统导入数据:[数据迁移](./transfer.md)
## ArtalkLite
可选择精简版 [ArtalkLite](./frontend/artalk-lite.md):体积更小、更简约。
## 开发环境
可参考:[开发者指南](https://github.com/ArtalkJS/Artalk/blob/master/CONTRIBUTING.md)
File renamed without changes.
@@ -14,8 +14,9 @@ Artalk 离不开社区的支持与帮助,**是你们让 Artalk 走得更远!
- [Vuepress配置评论插件为Artalk](https://wiki.eryajf.net/pages/b74c2b/)
- [Fly.io 部署 Artalk 评论系统](https://wayjam.me/posts/artalk-deploy-on-flyio/)
- [Railway.app 部署 Artalk 评论系统](https://blog.moraxyc.com/post/eidb8276/)
- [Render.com 部署Artalk自托管评论系统](https://www.leenhawk.com/posts/3932123804/)
更多新版读物正在撰写当中(
更多新版读物正在撰写当中...
## Artalk v1
File renamed without changes.
@@ -1,18 +1,19 @@
# 前端配置
```js
Artalk.init({ 你的配置... })
Artalk.update({ 更新配置... })
const artalk = Artalk.init({ ... })
artalk.update({ ... })
```
- 默认配置:[defaults.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/packages/artalk/src/defaults.ts)
- 声明文件:[artalk-config.d.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/packages/artalk/types/artalk-config.d.ts)
- 默认配置:[defaults.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/artalk/src/defaults.ts)
- 声明文件:[config.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/artalk/src/types/config.ts)
## 轻松配置
推荐在侧边栏 “[控制中心](/guide/frontend/sidebar.md)” 通过图形界面修改前端的配置,而无需在代码中对界面进行设定。
注:前端的设定可能会被后端覆盖,更多内容参考:[“在后端控制前端”](/guide/backend/fe-control.md)
注:前端的设定可能会被后端覆盖,更多内容参考:[在后端控制前端](/guide/backend/fe-control.md)
## 基本配置(必填项)
@@ -36,7 +37,7 @@ Artalk.update({ 更新配置... })
可以填写由博客系统生成的 `固定链接`,但建议使用相对路径以便日后切换域名。
参考:[“关于使用相对 / 绝对路径”](/guide/backend/relative-path.md)
参考:[关于使用相对 / 绝对路径](/guide/backend/relative-path.md)
### pageTitle
@@ -84,7 +85,7 @@ Artalk 支持多站点统一管理,此项用于站点隔离。
可以在后端的配置文件中定义前端的配置,让前端配置始终跟随后端。
详情可参考:[“在后端控制前端”](/guide/backend/fe-control)
详情可参考:[在后端控制前端](/guide/backend/fe-control)
## 国际化 (i18n)
@@ -99,7 +100,7 @@ Artalk 支持多站点统一管理,此项用于站点隔离。
欢迎提交 PR 帮助翻译 Artalk 的多语言,为社区贡献一份力量!
详情参考:[“多语言”](./i18n.md)
详情参考:[多语言](./i18n.md)
## 请求
@@ -121,7 +122,7 @@ Artalk 支持多站点统一管理,此项用于站点隔离。
- 类型:`Object|Array|String|Boolean`
- 默认值:"[https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json](https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json)"
详细内容:[“前端 · 表情包”](/guide/frontend/emoticons.md)
详细内容:[前端 · 表情包](/guide/frontend/emoticons.md)
更新兼容 [OwO 格式](https://github.com/DIYgod/OwO),支持 URL 动态加载。
@@ -175,10 +176,10 @@ JS DELIVR 在中国大陆的 [ICP 牌照已被吊销](https://github.com/jsdeliv
代码动态修改 darkMode:
```js
Artalk.setDarkMode(true)
artalk.setDarkMode(true)
```
> 参考代码:“[index.html](https://github.com/ArtalkJS/Artalk/blob/master/ui/packages/artalk/index.html#L97-L150)”
> 参考代码:“[index.html](https://github.com/ArtalkJS/Artalk/blob/master/ui/artalk/index.html#L97-L150)”
可设置为 `"auto"`,Artalk 将监听 `(prefers-color-scheme: dark)` 根据用户操作系统判断自动切换夜间模式。
@@ -268,7 +269,7 @@ pvEl 和 countEl 元素标签都可以设置 `data-page-key` 属性值,来指
**显示用户的 UserAgent 信息徽标**
- 类型:`Boolean`
- 默认值:`true`
- 默认值:`false`
### listSort
@@ -9,7 +9,7 @@ frontend:
## 表情包预设
Artalk 社区提供许多表情包预设,你能够挑选几套喜欢的表情包,仅需简单的配置,轻松添加到你的评论系统中,前往仓库:[“@ArtalkJS/Emoticons”](https://github.com/ArtalkJS/Emoticons)。
Artalk 社区提供许多表情包预设,你能够挑选几套喜欢的表情包,仅需简单的配置,轻松添加到你的评论系统中,前往仓库:[@ArtalkJS/Emoticons](https://github.com/ArtalkJS/Emoticons)。
## 格式支持
@@ -57,7 +57,7 @@ Artalk 除了支持 OwO 格式外,还内置支持一种标准的表情包列
::: warning
前端的配置将默认被后端覆盖,详情参考:[“在后端控制前端”](/guide/backend/fe-control.html)
前端的配置可能会被后端所覆盖,详情参考:[在后端控制前端](/guide/backend/fe-control.html)
:::
@@ -22,7 +22,7 @@ locale 配置项格式遵循 Unicode BCP 47 规范,默认为 "zh-CN" (简体
|翻译内容|语言文件目录|模板文件|
|-|-|-|
|后端程序|[/i18n/[LANG].yml](https://github.com/ArtalkJS/Artalk/tree/master/i18n)|[zh-CN.yml](https://github.com/ArtalkJS/Artalk/blob/master/i18n/zh-CN.yml)|
|前端界面|[/ui/packages/artalk/src/i18n/[LANG].ts](https://github.com/ArtalkJS/Artalk/tree/master/ui/packages/artalk/src/i18n)|[zh-CN.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/packages/artalk/src/i18n/zh-CN.ts)|
|前端界面|[/ui/artalk/src/i18n/[LANG].ts](https://github.com/ArtalkJS/Artalk/tree/master/ui/artalk/src/i18n)|[zh-CN.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/artalk/src/i18n/zh-CN.ts)|
|配置文件|[/conf/artalk.example.[LANG].yml](https://github.com/ArtalkJS/Artalk/tree/master/conf)|[artalk.example.zh-CN.yml](https://github.com/ArtalkJS/Artalk/blob/master/conf/artalk.example.zh-CN.yml)
|说明文档|[/docs/[LANG]/**\/*.md](https://github.com/ArtalkJS/Artalk/tree/master/docs)|[/docs/**\/*.md](https://github.com/ArtalkJS/Artalk/tree/master/docs)
@@ -52,7 +52,7 @@ Artalk.init({
### 前端自定义 locale 内容
在前端可传入 Object 类型,按照 [模板文件](https://github.com/ArtalkJS/Artalk/blob/master/ui/packages/artalk/src/i18n/zh-CN.ts) 中的 Keys 编写自定义 locale 内容。
在前端可传入 Object 类型,按照 [模板文件](https://github.com/ArtalkJS/Artalk/blob/master/ui/artalk/src/i18n/zh-CN.ts) 中的 Keys 编写自定义 locale 内容。
```js
Artalk.init({
@@ -4,6 +4,11 @@
<<< @/code/quick-start/cdn.html
#### 什么时候执行 `Artalk.init({})`?
- 可以在任意位置引入 JS 和 CSS 资源,但需确保 JS 引入在执行 `Artalk.init({})` 前。
- 执行 `Artalk.init({ el: '#artalk' })` 前需要确保 `<div id="artalk"></div>` 在页面当中。
## Hugo
创建模板文件 `/主题目录/layouts/partials/comment/artalk.html`:
@@ -99,66 +104,36 @@ NexT 主题可以安装 [Hexo NexT 主题的 Artalk 插件](https://github.com/l
:::
## VitePress
可参考:[@ArtalkJS/Artalk:/docs/.vitepress](https://github.com/ArtalkJS/Artalk/tree/master/docs/.vitepress)
- `config.ts` 修改配置引入 CSS 资源
- `theme/Artalk.vue` 创建组件
- `theme/index.ts` 注册组件
- `theme/Layout.vue` 使用组件
注:SSG 应用需通过 `import()` 函数异步引入 Artalk,否则会导致构建失败。
```ts
import('artalk').then(({ default: Artalk }) => {
artalk = Artalk.init({
//...
})
})
```
参考文件:[.vitepress/theme/Artalk.vue](https://github.com/ArtalkJS/Artalk/blob/master/docs/.vitepress/theme/Artalk.vue)
## VuePress
以 [VuePress v2](https://github.com/vuepress/vuepress-next) 为例,继承默认主题 `@vuepress/theme-default`
(待补充)
可参考:[“/.vuepress/theme/Artalk.vue”](https://github.com/ArtalkJS/Docs/blob/eef37bca8cc0c9973bf121fdef4014dcd940f104/docs/.vuepress/theme/Artalk.vue) 创建 Artalk 评论组件。
::: tip 提示
在 `/.vuepress/theme/clientAppEnhance.ts` 文件中全局注册组件:
可参考:[置入框架](./import-framework.md)
```ts
import { defineClientAppEnhance } from '@vuepress/client'
import Artalk from './Artalk.vue'
export default defineClientAppEnhance(({ app, router, siteData }) => {
app.component('Artalk', Artalk)
})
```
主题布局 `/.vuepress/theme/Layout.vue`:
```vue
<template>
<Layout>
<template #page-bottom>
<div class="page-meta">
<!-- Artalk -->
<Artalk />
</div>
</template>
</Layout>
</template>
<script lang="ts">
import { defineComponent, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import Layout from '@vuepress/theme-default/lib/client/layouts/Layout.vue'
export default defineComponent({
components: { Layout },
mounted: () => {
}
})
</script>
```
主题配置文件 `/.vuepress/theme/index.ts`:
```ts
import { path } from '@vuepress/utils'
export default ({
name: 'vuepress-theme-local',
extends: '@vuepress/theme-default',
layouts: {
Layout: path.resolve(__dirname, 'Layout.vue'),
},
clientAppEnhanceFiles: path.resolve(__dirname, 'clientAppEnhance.ts'),
})
```
:::
## Typecho
@@ -0,0 +1,146 @@
# 置入框架
## 安装 Artalk
通过包管理工具引入 Artalk,推荐使用 [pnpm](https://pnpm.io/zh/)
```bash
pnpm add artalk
```
## Vue
Vue 3 + TypeScript 例:
```vue
<template>
<view ref="el"></view>
</template>
<script lang="ts" setup>
import { onMounted, onUnmounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import 'artalk/dist/Artalk.css'
import Artalk from 'artalk'
const el = ref<HTMLElement>()
const route = useRoute()
let artalk: Artalk
onMounted(() => {
artalk = Artalk.init({
el: el.value,
pageKey: route.path,
pageTitle: `${document.title}`,
server: 'http://localhost:8080',
site: 'Artalk 的博客',
// ...
})
})
onUnmounted(() => {
artalk.destroy()
})
</script>
```
## React
```tsx
import React, { useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';
import 'artalk/dist/Artalk.css';
import Artalk from 'artalk';
const ArtalkComment = () => {
const el = useRef(null);
const location = useLocation();
let artalk = null;
useEffect(() => {
artalk = new Artalk({
el: el.current,
pageKey: location.pathname,
pageTitle: document.title,
server: 'http://localhost:8080',
site: 'Artalk 的博客',
// ...
});
return () => {
if (artalk) {
artalk.destroy();
}
};
}, [location.pathname]);
return <div ref={el}></div>;
};
export default ArtalkComment;
```
```jsx
import React, { createRef } from 'react'
import 'artalk/dist/Artalk.css'
import Artalk from 'artalk'
export default class Artalk extends React.Component {
el = createRef()
artalk = null
componentDidMount() {
this.artalk = Artalk.init({
el: this.el.current,
pageKey: `${location.pathname}`,
pageTitle: `${document.title}`,
server: 'http://localhost:8080',
site: 'Artalk 的博客',
// ...
})
}
componentWillUnmount() {
this.artalk?.destroy()
}
render() {
return (
<div ref={this.el} />
)
}
}
```
## Svelte
```html
<script>
import { onMount, onDestroy } from 'svelte';
import 'artalk/dist/Artalk.css';
import Artalk from 'artalk';
let el;
let artalk;
onMount(() => {
artalk = Artalk.init({
el: el,
pageKey: location.pathname,
pageTitle: document.title,
server: 'http://localhost:8080',
site: 'Artalk 的博客',
// ...
});
onDestroy(() => {
if (artalk) {
artalk.destroy();
}
});
});
</script>
<div bind:this={el}></div>
```
+7
View File
@@ -0,0 +1,7 @@
# ArtalkJS
Artalk 拥有一个前端,[GitHub 代码仓库](https://github.com/ArtalkJS/Artalk)。
## 特性
可见:[README.md · 特性](https://github.com/ArtalkJS/Artalk#%E7%89%B9%E6%80%A7)
File renamed without changes.
@@ -1,14 +1,14 @@
# IP 归属地
# IP 属地
Artalk 内置用户 IP 归属地展示功能,并且你可以设置显示的精度:精确到市、省。
Artalk 内置用户 IP 属地展示功能,并且你可以设置显示的精度:精确到市、省。
该功能默认关闭,你可在 Artalk 控制中心设置中启用 IP 归属地展示功能。
该功能默认关闭,你可在 Artalk 控制中心设置中启用 IP 属地展示功能。
## IP 归属地数据库
## IP 属地数据库
在开启 IP 归属地展示功能之前,你需要下载一个数据库文件:
在开启 IP 属地展示功能之前,你需要下载一个数据库文件:
- [GitHub 下载](https://github.com/lionsoul2014/ip2region/raw/master/data/ip2region.xdb) / [镜像站下载](https://ghproxy.com/?q=https%3A%2F%2Fgithub.com%2Flionsoul2014%2Fip2region%2Fblob%2Fmaster%2Fdata%2Fip2region.xdb) (国内推荐)
- [GitHub 下载](https://github.com/lionsoul2014/ip2region/raw/master/data/ip2region.xdb) / [镜像站下载](https://gh-proxy.com/?q=https%3A%2F%2Fgithub.com%2Flionsoul2014%2Fip2region%2Fblob%2Fmaster%2Fdata%2Fip2region.xdb) (境内推荐)
下载后请手动放置到 `./data/` 目录下,文件命名为:`ip2region.xdb`
@@ -25,9 +25,9 @@ Artalk 内置用户 IP 归属地展示功能,并且你可以设置显示的精
配置文件:
```yaml
# IP 归属地
# IP 属地
ip_region:
# 启用 IP 归属地展示
# 启用 IP 属地展示
enabled: false
# 数据文件路径 (.xdb 格式)
db_path: "./data/ip2region.xdb"
File renamed without changes.
@@ -18,7 +18,7 @@ Artalk LightBox 插件能帮助你将网站**现有的图片灯箱**功能自动
目前自动集成支持:[LightGallery](https://github.com/sachinchoolur/lightGallery) [v2.5.0] / [FancyBox](https://github.com/fancyapps/fancybox) [v4.0.27] / [lightbox2](https://github.com/lokesh/lightbox2) [v2.11.3]
对于还未适配的图片灯箱,欢迎提交 PR -> [查看代码](https://github.com/ArtalkJS/Artalk/blob/master/packages/plugin-lightbox/main.ts)
对于还未适配的图片灯箱,欢迎提交 PR -> [查看代码](https://github.com/ArtalkJS/Artalk/blob/master/ui/plugin-lightbox/main.ts)
::: details 附:图片灯箱依赖 CDN 资源
@@ -6,7 +6,7 @@ Artalk 内置页面浏览量统计功能,你可以在你的页面任意位置
<span id="ArtalkPV"></span>
```
当 Artalk 加载完毕时,该标签内容将修改为页面的浏览量计数。
当 Artalk 评论列表加载完毕时,该标签内容将修改为页面的浏览量计数。
Artalk 加载需要时间,所以你可以给它一个占位字符:
@@ -14,7 +14,7 @@ Artalk 加载需要时间,所以你可以给它一个占位字符:
<span id="ArtalkPV">加载中...</span>
```
你也可以绑定使用其他的元素,修改 Artalk 配置项,例如:
配置项 `pvEl` 的默认值是 `"#ArtalkPV"`,可修改将评论量加载到指定元素,例如:
```js
Artalk.init({
@@ -22,9 +22,12 @@ Artalk.init({
})
```
### 显示多个页面的浏览量
### 加载多个页面的浏览量
你能在除评论页面之外的任何页面,例如「文章列表」页,显示页面浏览量或评论数。
在非评论页,无需调用 `Artalk.init` 加载评论框 (会使页面浏览量 PV 数增加),仅调用 `loadCountWidget` 静态方法即可:
你能在除评论页面之外的任何页面,例如「文章列表」页,显示页面浏览量或评论数:
```js
Artalk.loadCountWidget({
@@ -35,8 +38,6 @@ Artalk.loadCountWidget({
});
```
在非评论页时,就无需再 Artalk.init 实例了 (否则页面浏览量 PV 数会无故增加),仅调用 `loadCountWidget` 静态方法即可。
然后你可以放置多个 `#ArtalkPV` 元素,通过属性 `data-page-key` 来指定需要查询的页面:
```html
@@ -40,4 +40,4 @@
## 设置
登陆管理员账户可进入到 “控制中心” 的图形设置界面,轻松地对 [“配置文件”](/guide/backend/config.md) 以及 [“前端的配置”](/guide/frontend/config.md) 进行修改,而无需手动编辑复杂的配置文件。
登录管理员账户可进入到 “控制中心” 的图形设置界面,轻松地对 [配置文件](/guide/backend/config.md) 以及 [前端的配置](/guide/frontend/config.md) 进行修改,而无需手动编辑复杂的配置文件。
@@ -36,7 +36,7 @@
不论是 Vue、React、Svelte 的前端项目,还是 WordPress、Typecho、Hexo 等博客系统,都可以快速引入 Artalk,结合诸位的聪明才智,我们相信 Artalk 能够自如应对各种业务场景。
> 更多支持 / 计划的功能,详见:[“README.md”](https://github.com/ArtalkJS/Artalk#todos)。
> 更多支持 / 计划的功能,详见:[README.md](https://github.com/ArtalkJS/Artalk#todos)。
## 用户体验
@@ -64,7 +64,7 @@ Artalk 社区是包容开放的社区,我们欢迎不同水平的人员帮助
“More action, less talk”,Artalk 社区不欢迎无意义的争论,我们希望社区成员和谐共处、为社区发展出谋划策。在提出问题前,你应当读过《[提问的智慧](https://lug.ustc.edu.cn/wiki/doc/smart-questions/)》,这可能决定了你最终是否能得到有用的回答。在表达观点前,你应当具备基本的礼仪,比如保持平和的态度、使用得体的语言,切忌恶语相向、冷嘲热讽、不尊重他人信仰和立场等。
我们作为开源精神的推崇者以及实践者,希望我们所创造的自由软件,都应该被自由的使用,自由的研究,自由的更改和自由的分享。本项目前后端代码使用 [MIT](https://github.com/ArtalkJS/Artalk/blob/master/LICENSE) 协议开源,文档请遵循知识共享许可协议 ([Creative Commons License](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh))。
我们作为开源精神的推崇者以及实践者,希望我们所创造的自由软件,都应该被自由的使用,自由的研究,自由的更改和自由的分享。本项目主程序使用 [MIT](https://github.com/ArtalkJS/Artalk/blob/master/LICENSE) 协议开源,文档使用 [CC](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh) 许可协议。
::: tip 立即为社区贡献力量?
- 浏览开发者资料([开发文档](../develop/index.md) / [CONTRIBUTING.md](https://github.com/ArtalkJS/Artalk/blob/master/CONTRIBUTING.md))
Loaded 100 of 652 files, more files were not shown because too many files have changed in this diff. Show more