artalk 2.8.2 → 2.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -468,6 +468,21 @@ let Api$1 = class Api extends HttpClient {
468
468
  path: `/conf`,
469
469
  method: "GET",
470
470
  format: "json"
471
+ }, params)),
472
+ /**
473
+ * @description Get Domain Info
474
+ *
475
+ * @tags System
476
+ * @name GetDomain
477
+ * @summary Get Domain Info
478
+ * @request GET:/conf/domain
479
+ * @response `200` `HandlerResponseConfDomain` OK
480
+ */
481
+ getDomain: (query, params = {}) => this.request(__spreadValues({
482
+ path: `/conf/domain`,
483
+ method: "GET",
484
+ query,
485
+ format: "json"
471
486
  }, params))
472
487
  });
473
488
  __publicField(this, "notifies", {
@@ -1036,7 +1051,7 @@ let Api$1 = class Api extends HttpClient {
1036
1051
  /**
1037
1052
  * @description Get user info to prepare for login or check current user status
1038
1053
  *
1039
- * @tags Account
1054
+ * @tags Auth
1040
1055
  * @name GetUser
1041
1056
  * @summary Get User Info
1042
1057
  * @request GET:/user
@@ -1057,23 +1072,23 @@ let Api$1 = class Api extends HttpClient {
1057
1072
  /**
1058
1073
  * @description Login user by name or email
1059
1074
  *
1060
- * @tags Account
1075
+ * @tags Auth
1061
1076
  * @name Login
1062
1077
  * @summary Get Access Token
1063
1078
  * @request POST:/user/access_token
1064
1079
  * @response `200` `HandlerResponseUserLogin` OK
1065
1080
  * @response `400` `(HandlerMap & {
1066
- " data"?: {
1081
+ data?: {
1067
1082
  need_name_select?: (string)[],
1068
1083
 
1069
1084
  },
1070
1085
  msg?: string,
1071
1086
 
1072
1087
  })` Multiple users with the same email address are matched
1073
- * @response `403` `(HandlerMap & {
1088
+ * @response `401` `(HandlerMap & {
1074
1089
  msg?: string,
1075
1090
 
1076
- })` Forbidden
1091
+ })` Unauthorized
1077
1092
  * @response `500` `(HandlerMap & {
1078
1093
  msg?: string,
1079
1094
 
@@ -1089,7 +1104,7 @@ let Api$1 = class Api extends HttpClient {
1089
1104
  /**
1090
1105
  * @description Get user login status by header Authorization
1091
1106
  *
1092
- * @tags Account
1107
+ * @tags Auth
1093
1108
  * @name GetUserStatus
1094
1109
  * @summary Get Login Status
1095
1110
  * @request GET:/user/status
@@ -1701,16 +1716,16 @@ const Fetch$1 = (opts, input, init2) => __async(void 0, null, function* () {
1701
1716
  if (!resp.ok) {
1702
1717
  const json = (yield resp.json().catch(() => {
1703
1718
  })) || {};
1704
- if (json.need_captcha) {
1705
- opts.onNeedCheckCaptcha && (yield opts.onNeedCheckCaptcha({
1706
- data: { imgData: json.img_data, iframe: json.iframe }
1707
- }));
1708
- return Fetch$1(opts, input, init2);
1709
- }
1710
- if (json.need_login) {
1711
- opts.onNeedCheckAdmin && (yield opts.onNeedCheckAdmin({}));
1719
+ let retry = false;
1720
+ opts.handlers && (yield opts.handlers.get().reduce((promise, item) => __async(void 0, null, function* () {
1721
+ yield promise;
1722
+ if (json[item.action] === true) {
1723
+ yield item.handler(json);
1724
+ retry = true;
1725
+ }
1726
+ }), Promise.resolve()));
1727
+ if (retry)
1712
1728
  return Fetch$1(opts, input, init2);
1713
- }
1714
1729
  throw createError(resp.status, json);
1715
1730
  }
1716
1731
  return resp;
@@ -1731,6 +1746,15 @@ function createError(code, data) {
1731
1746
  console.error(err);
1732
1747
  return err;
1733
1748
  }
1749
+ function createApiHandlers() {
1750
+ const handlers = [];
1751
+ return {
1752
+ add: (action, handler) => {
1753
+ handlers.push({ action, handler });
1754
+ },
1755
+ get: () => handlers
1756
+ };
1757
+ }
1734
1758
  class Api2 extends Api$1 {
1735
1759
  constructor(opts) {
1736
1760
  super({
@@ -2524,6 +2548,7 @@ const en = {
2524
2548
  /* Sidebar */
2525
2549
  msgCenter: "Messages",
2526
2550
  ctrlCenter: "Admin",
2551
+ emailVerified: "Email has been verified",
2527
2552
  /* General */
2528
2553
  frontend: "Frontend",
2529
2554
  backend: "Backend",
@@ -2604,6 +2629,7 @@ const zhCN = {
2604
2629
  /* Sidebar */
2605
2630
  msgCenter: "通知中心",
2606
2631
  ctrlCenter: "控制中心",
2632
+ emailVerified: "邮箱已验证",
2607
2633
  /* General */
2608
2634
  frontend: "前端",
2609
2635
  backend: "后端",
@@ -2954,21 +2980,15 @@ function convertApiOptions(conf, ctx) {
2954
2980
  name: ctx == null ? void 0 : ctx.get("user").getData().nick,
2955
2981
  email: ctx == null ? void 0 : ctx.get("user").getData().email
2956
2982
  } : void 0,
2957
- onNeedCheckAdmin: (payload) => {
2958
- if (!ctx)
2959
- throw new Error("`ctx` is required when `onNeedCheckAdmin` is called.");
2960
- return ctx.checkAdmin({});
2961
- },
2962
- onNeedCheckCaptcha: (payload) => {
2963
- if (!ctx)
2964
- throw new Error("`ctx` is required when `onNeedCheckCaptcha` is called.");
2965
- return ctx.checkCaptcha({
2966
- imgData: payload.data.imgData,
2967
- iframe: payload.data.iframe
2968
- });
2969
- }
2983
+ handlers: ctx == null ? void 0 : ctx.getApiHandlers()
2970
2984
  };
2971
2985
  }
2986
+ function createNewApiHandlers(ctx) {
2987
+ const h = createApiHandlers();
2988
+ h.add("need_captcha", (res) => ctx.checkCaptcha(res));
2989
+ h.add("need_login", () => ctx.checkAdmin({}));
2990
+ return h;
2991
+ }
2972
2992
  function watchConf(ctx, keys, effect) {
2973
2993
  const deepEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
2974
2994
  const val = () => {
@@ -3000,6 +3020,7 @@ class Context {
3000
3020
  /* Event Manager */
3001
3021
  __publicField(this, "events", new EventManager());
3002
3022
  __publicField(this, "mounted", false);
3023
+ __publicField(this, "apiHandlers", null);
3003
3024
  __publicField(this, "getCommentList", this.getCommentNodes);
3004
3025
  __publicField(this, "getCommentDataList", this.getComments);
3005
3026
  this.conf = conf;
@@ -3020,6 +3041,11 @@ class Context {
3020
3041
  getApi() {
3021
3042
  return new Api2(convertApiOptions(this.conf, this));
3022
3043
  }
3044
+ getApiHandlers() {
3045
+ if (!this.apiHandlers)
3046
+ this.apiHandlers = createNewApiHandlers(this);
3047
+ return this.apiHandlers;
3048
+ }
3023
3049
  getData() {
3024
3050
  return this.data;
3025
3051
  }
@@ -3412,7 +3438,7 @@ class CheckerLauncher {
3412
3438
  constructor(opts) {
3413
3439
  __publicField(this, "checkCaptcha", wrapPromise((p) => {
3414
3440
  this.fire(CaptchaChecker, p, (ctx) => {
3415
- ctx.set("img_data", p.imgData);
3441
+ ctx.set("img_data", p.img_data);
3416
3442
  ctx.set("iframe", p.iframe);
3417
3443
  });
3418
3444
  }));
@@ -3490,7 +3516,7 @@ class CheckerLauncher {
3490
3516
  if (payload.onSuccess)
3491
3517
  payload.onSuccess();
3492
3518
  }).catch((err) => {
3493
- btnTextSet(String(err.msg || String(err)));
3519
+ btnTextSet(String(err.message || String(err)));
3494
3520
  if (checker.onError)
3495
3521
  checker.onError(checkerCtx, err, inputVal, formEl);
3496
3522
  const tf = setTimeout(() => btnTextRestore(), 3e3);
@@ -3738,10 +3764,15 @@ class Editor extends Component {
3738
3764
  hideLoading(this.ui.$el);
3739
3765
  }
3740
3766
  submit() {
3741
- this.ctx.trigger("editor-submit");
3767
+ const next = () => this.ctx.trigger("editor-submit");
3768
+ if (this.ctx.conf.beforeSubmit) {
3769
+ this.ctx.conf.beforeSubmit(this, next);
3770
+ } else {
3771
+ next();
3772
+ }
3742
3773
  }
3743
3774
  }
3744
- const SidebarHTML = '<div class="atk-sidebar-layer">\n <div class="atk-sidebar-inner">\n <div class="atk-sidebar-header">\n <div class="atk-sidebar-close"><i class="atk-icon atk-icon-close"></i></div>\n </div>\n <div class="atk-sidebar-iframe-wrap"></div>\n </div>\n</div>\n';
3775
+ const SidebarHTML = '<div class="atk-sidebar-layer">\n <div class="atk-sidebar-inner">\n <div class="atk-sidebar-header">\n <div class="atk-sidebar-close"><i class="atk-icon atk-icon-close-slim"></i></div>\n </div>\n <div class="atk-sidebar-iframe-wrap"></div>\n </div>\n</div>\n';
3745
3776
  class SidebarLayer extends Component {
3746
3777
  constructor(ctx) {
3747
3778
  super(ctx);
@@ -4296,6 +4327,9 @@ function renderVerifyBadge(ctx) {
4296
4327
  $badge.innerText = badgeText.replace("管理员", t("admin"));
4297
4328
  $badge.style.backgroundColor = badgeColor || "";
4298
4329
  ctx.$headerBadgeWrap.append($badge);
4330
+ } else if (ctx.data.is_verified) {
4331
+ const $verifiedBadge = createElement(`<span class="atk-verified-icon" title="${t("emailVerified")}"></span>`);
4332
+ ctx.$headerBadgeWrap.append($verifiedBadge);
4299
4333
  }
4300
4334
  if (ctx.data.is_pinned) {
4301
4335
  const $pinnedBadge = createElement(`<span class="atk-pinned-badge">${t("pin")}</span>`);
@@ -5550,18 +5584,8 @@ class LayerWrap {
5550
5584
  if (this.items.map((l) => l.getEl()).filter((e) => e !== $el && e.isConnected && e.style.display !== "none").length > 0) {
5551
5585
  return;
5552
5586
  }
5553
- const onHide = () => {
5554
- this.$wrap.style.display = "none";
5555
- this.$wrap.classList.remove("atk-fade-out");
5556
- getScrollbarHelper().unlock();
5557
- this.$wrap.onanimationend = null;
5558
- };
5559
- this.$wrap.classList.add("atk-fade-out");
5560
- if (window.getComputedStyle(this.$wrap)["animation-name"] !== "none") {
5561
- this.$wrap.onanimationend = () => onHide();
5562
- } else {
5563
- onHide();
5564
- }
5587
+ this.$wrap.style.display = "none";
5588
+ getScrollbarHelper().unlock();
5565
5589
  }
5566
5590
  }
5567
5591
  class LayerManager {
@@ -5680,6 +5704,70 @@ const services = {
5680
5704
  return void 0;
5681
5705
  }
5682
5706
  };
5707
+ const PvCountWidget = (ctx) => {
5708
+ ctx.watchConf([
5709
+ "site",
5710
+ "pageKey",
5711
+ "pageTitle",
5712
+ "countEl",
5713
+ "pvEl"
5714
+ ], (conf) => {
5715
+ initCountWidget({
5716
+ getApi: () => ctx.getApi(),
5717
+ siteName: conf.site,
5718
+ pageKey: conf.pageKey,
5719
+ pageTitle: conf.pageTitle,
5720
+ countEl: conf.countEl,
5721
+ pvEl: conf.pvEl,
5722
+ pvAdd: typeof ctx.conf.pvAdd === "boolean" ? ctx.conf.pvAdd : true
5723
+ });
5724
+ });
5725
+ };
5726
+ function initCountWidget(opt) {
5727
+ return __async(this, null, function* () {
5728
+ if (opt.countEl && document.querySelector(opt.countEl)) {
5729
+ refreshStatCount(opt, { query: "page_comment", numEl: opt.countEl });
5730
+ }
5731
+ const initialData = opt.pvAdd && opt.pageKey ? {
5732
+ [opt.pageKey]: (yield opt.getApi().pages.logPv({
5733
+ page_key: opt.pageKey,
5734
+ page_title: opt.pageTitle,
5735
+ site_name: opt.siteName
5736
+ })).data.pv
5737
+ // pv+1 and get pv count
5738
+ } : void 0;
5739
+ if (opt.pvEl && document.querySelector(opt.pvEl)) {
5740
+ refreshStatCount(opt, {
5741
+ query: "page_pv",
5742
+ numEl: opt.pvEl,
5743
+ data: initialData
5744
+ });
5745
+ }
5746
+ });
5747
+ }
5748
+ function refreshStatCount(opt, args) {
5749
+ return __async(this, null, function* () {
5750
+ let data = args.data || {};
5751
+ let queryPageKeys = Array.from(document.querySelectorAll(args.numEl)).map((e) => e.getAttribute("data-page-key") || opt.pageKey).filter((k) => k && typeof data[k] !== "number");
5752
+ queryPageKeys = [...new Set(queryPageKeys)];
5753
+ if (queryPageKeys.length > 0) {
5754
+ const res = (yield opt.getApi().stats.getStats(args.query, {
5755
+ page_keys: queryPageKeys.join(","),
5756
+ site_name: opt.siteName
5757
+ })).data.data;
5758
+ data = __spreadValues(__spreadValues({}, data), res);
5759
+ }
5760
+ const defaultCount = opt.pageKey ? data[opt.pageKey] : 0;
5761
+ applyCountData(args.numEl, data, defaultCount);
5762
+ });
5763
+ }
5764
+ function applyCountData(selector, data, defaultCount) {
5765
+ document.querySelectorAll(selector).forEach((el) => {
5766
+ const pageKey = el.getAttribute("data-page-key");
5767
+ const count = Number(pageKey ? data[pageKey] : defaultCount);
5768
+ el.innerHTML = `${count}`;
5769
+ });
5770
+ }
5683
5771
  function showErrorDialog(opts) {
5684
5772
  const errEl = createElement(`<span><span class="error-message"></span><br/><br/></span>`);
5685
5773
  errEl.querySelector(".error-message").innerText = `${t("listLoadFailMsg")}
@@ -5696,58 +5784,6 @@ ${opts.errMsg}`;
5696
5784
  }
5697
5785
  setError(opts.$err, errEl);
5698
5786
  }
5699
- const ConfRemoter = (ctx) => {
5700
- ctx.on("created", () => {
5701
- if (ctx.conf.immediateFetch !== false)
5702
- ctx.trigger("conf-fetch");
5703
- });
5704
- ctx.on("conf-fetch", () => {
5705
- loadConf(ctx);
5706
- });
5707
- };
5708
- function loadConf(ctx) {
5709
- ctx.getApi().conf.conf().then((res) => {
5710
- var _a;
5711
- let conf = {
5712
- apiVersion: (_a = res.data.version) == null ? void 0 : _a.version
5713
- // version info
5714
- };
5715
- if (ctx.conf.useBackendConf) {
5716
- if (!res.data.frontend_conf)
5717
- throw new Error("The remote backend does not respond to the frontend conf, but `useBackendConf` conf is enabled");
5718
- conf = __spreadValues(__spreadValues({}, conf), handleConfFormServer(res.data.frontend_conf));
5719
- }
5720
- ctx.conf.remoteConfModifier && ctx.conf.remoteConfModifier(conf);
5721
- ctx.updateConf(conf);
5722
- }).catch((err) => {
5723
- var _a;
5724
- ctx.updateConf({});
5725
- let sidebarOpenView = "";
5726
- if ((_a = err.data) == null ? void 0 : _a.err_no_site) {
5727
- const viewLoadParam = { create_name: ctx.conf.site, create_urls: `${window.location.protocol}//${window.location.host}` };
5728
- sidebarOpenView = `sites|${JSON.stringify(viewLoadParam)}`;
5729
- }
5730
- showErrorDialog({
5731
- $err: ctx.get("list").$el,
5732
- errMsg: err.msg || String(err),
5733
- errData: err.data,
5734
- retryFn: () => loadConf(ctx),
5735
- onOpenSidebar: ctx.get("user").getData().isAdmin ? () => ctx.showSidebar({
5736
- view: sidebarOpenView
5737
- }) : void 0
5738
- // only show open sidebar button when user is admin
5739
- });
5740
- console.error(err);
5741
- throw err;
5742
- }).then(() => {
5743
- ctx.trigger("mounted");
5744
- }).then(() => {
5745
- if (ctx.conf.remoteConfModifier)
5746
- return;
5747
- ctx.fetch({ offset: 0 });
5748
- }).catch(() => {
5749
- });
5750
- }
5751
5787
  const Markdown = (ctx) => {
5752
5788
  initMarked();
5753
5789
  ctx.on("updated", (conf) => {
@@ -5903,7 +5939,7 @@ class Submit extends EditorPlug {
5903
5939
  this.defaultPreset.postSubmitAdd(nComment);
5904
5940
  } catch (err) {
5905
5941
  console.error(err);
5906
- this.kit.useEditor().showNotify(`${t("commentFail")}: ${err.msg || String(err)}`, "e");
5942
+ this.kit.useEditor().showNotify(`${t("commentFail")}: ${err.message || String(err)}`, "e");
5907
5943
  return;
5908
5944
  } finally {
5909
5945
  this.kit.useEditor().hideLoading();
@@ -5956,7 +5992,7 @@ class StateReply extends EditorPlug {
5956
5992
  const ui = this.kit.useUI();
5957
5993
  if (!ui.$sendReplyBtn) {
5958
5994
  const $btn = createElement(
5959
- `<span class="atk-state-btn"><span class="atk-text-wrap">${t("reply")} <span class="atk-text"></span></span><span class="atk-cancel">×</span></span>`
5995
+ `<span class="atk-state-btn"><span class="atk-text-wrap">${t("reply")} <span class="atk-text"></span></span><span class="atk-cancel atk-icon-close atk-icon"></span></span>`
5960
5996
  );
5961
5997
  $btn.querySelector(".atk-text").innerText = `@${commentData.nick}`;
5962
5998
  $btn.addEventListener("click", () => {
@@ -6021,7 +6057,7 @@ class StateEdit extends EditorPlug {
6021
6057
  const ui = this.kit.useUI();
6022
6058
  if (!ui.$editCancelBtn) {
6023
6059
  const $btn = createElement(
6024
- `<span class="atk-state-btn"><span class="atk-text-wrap">${t("editCancel")}</span><span class="atk-cancel">×</span></span>`
6060
+ `<span class="atk-state-btn"><span class="atk-text-wrap">${t("editCancel")}</span><span class="atk-cancel atk-icon-close atk-icon"></span></span>`
6025
6061
  );
6026
6062
  $btn.onclick = () => {
6027
6063
  this.kit.useEditor().resetState();
@@ -6556,7 +6592,7 @@ class Upload extends EditorPlug {
6556
6592
  }
6557
6593
  } catch (err) {
6558
6594
  console.error(err);
6559
- this.kit.useEditor().showNotify(`${t("uploadFail")}: ${err.msg}`, "e");
6595
+ this.kit.useEditor().showNotify(`${t("uploadFail")}: ${err.message}`, "e");
6560
6596
  }
6561
6597
  if (!!resp && resp.public_url) {
6562
6598
  let imgURL = resp.public_url;
@@ -6719,9 +6755,6 @@ class PlugManager {
6719
6755
  this.editor.getUI().$plugPanelWrap.innerHTML = "";
6720
6756
  this.editor.getUI().$plugPanelWrap.style.display = "none";
6721
6757
  this.editor.getUI().$plugBtnWrap.innerHTML = "";
6722
- this.editor.getUI().$el.addEventListener("click", (e) => {
6723
- e.stopPropagation();
6724
- });
6725
6758
  this.plugs.forEach((plug) => this.loadPluginItem(plug));
6726
6759
  }
6727
6760
  /** Load the plug btn and plug panel on editor ui */
@@ -6817,7 +6850,7 @@ function adminPageEditSave(ctx, page) {
6817
6850
  ctx.getApi().pages.updatePage(page.id, page).then(({ data }) => {
6818
6851
  ctx.getData().updatePage(data);
6819
6852
  }).catch((err) => {
6820
- ctx.editorShowNotify(`${t("editFail")}: ${err.msg || String(err)}`, "e");
6853
+ ctx.editorShowNotify(`${t("editFail")}: ${err.message || String(err)}`, "e");
6821
6854
  }).finally(() => {
6822
6855
  ctx.editorHideLoading();
6823
6856
  });
@@ -6963,7 +6996,7 @@ const GotoFocus = (ctx) => {
6963
6996
  comment.focus();
6964
6997
  }));
6965
6998
  };
6966
- const version = "2.8.2";
6999
+ const version = "2.8.3";
6967
7000
  const Copyright = (ctx) => {
6968
7001
  ctx.on("mounted", () => {
6969
7002
  const list = ctx.get("list");
@@ -7247,70 +7280,6 @@ const Notifies = (ctx) => {
7247
7280
  });
7248
7281
  });
7249
7282
  };
7250
- const PvCountWidget = (ctx) => {
7251
- ctx.watchConf([
7252
- "site",
7253
- "pageKey",
7254
- "pageTitle",
7255
- "countEl",
7256
- "pvEl"
7257
- ], (conf) => {
7258
- initCountWidget({
7259
- getApi: () => ctx.getApi(),
7260
- siteName: conf.site,
7261
- pageKey: conf.pageKey,
7262
- pageTitle: conf.pageTitle,
7263
- countEl: conf.countEl,
7264
- pvEl: conf.pvEl,
7265
- pvAdd: typeof ctx.conf.pvAdd === "boolean" ? ctx.conf.pvAdd : true
7266
- });
7267
- });
7268
- };
7269
- function initCountWidget(opt) {
7270
- return __async(this, null, function* () {
7271
- if (opt.countEl && document.querySelector(opt.countEl)) {
7272
- refreshStatCount(opt, { query: "page_comment", numEl: opt.countEl });
7273
- }
7274
- const initialData = opt.pvAdd && opt.pageKey ? {
7275
- [opt.pageKey]: (yield opt.getApi().pages.logPv({
7276
- page_key: opt.pageKey,
7277
- page_title: opt.pageTitle,
7278
- site_name: opt.siteName
7279
- })).data.pv
7280
- // pv+1 and get pv count
7281
- } : void 0;
7282
- if (opt.pvEl && document.querySelector(opt.pvEl)) {
7283
- refreshStatCount(opt, {
7284
- query: "page_pv",
7285
- numEl: opt.pvEl,
7286
- data: initialData
7287
- });
7288
- }
7289
- });
7290
- }
7291
- function refreshStatCount(opt, args) {
7292
- return __async(this, null, function* () {
7293
- let data = args.data || {};
7294
- let queryPageKeys = Array.from(document.querySelectorAll(args.numEl)).map((e) => e.getAttribute("data-page-key") || opt.pageKey).filter((k) => k && typeof data[k] !== "number");
7295
- queryPageKeys = [...new Set(queryPageKeys)];
7296
- if (queryPageKeys.length > 0) {
7297
- const res = (yield opt.getApi().stats.getStats(args.query, {
7298
- page_keys: queryPageKeys.join(","),
7299
- site_name: opt.siteName
7300
- })).data.data;
7301
- data = __spreadValues(__spreadValues({}, data), res);
7302
- }
7303
- const defaultCount = opt.pageKey ? data[opt.pageKey] : 0;
7304
- applyCountData(args.numEl, data, defaultCount);
7305
- });
7306
- }
7307
- function applyCountData(selector, data, defaultCount) {
7308
- document.querySelectorAll(selector).forEach((el) => {
7309
- const pageKey = el.getAttribute("data-page-key");
7310
- const count = Number(pageKey ? data[pageKey] : defaultCount);
7311
- el.innerHTML = `${count}`;
7312
- });
7313
- }
7314
7283
  let IgnoreVersionCheck = false;
7315
7284
  const VersionCheck = (ctx) => {
7316
7285
  ctx.watchConf(["apiVersion", "versionCheck"], (conf) => {
@@ -7404,7 +7373,6 @@ const DarkMode = (ctx) => {
7404
7373
  });
7405
7374
  };
7406
7375
  const DefaultPlugins = [
7407
- ConfRemoter,
7408
7376
  Markdown,
7409
7377
  EditorKit,
7410
7378
  AdminOnlyElem,
@@ -7415,23 +7383,98 @@ const DefaultPlugins = [
7415
7383
  DarkMode
7416
7384
  ];
7417
7385
  const GlobalPlugins = [...DefaultPlugins];
7386
+ function load(ctx) {
7387
+ return __async(this, null, function* () {
7388
+ var _a;
7389
+ const loadedPlugins = [];
7390
+ const loadPlugins = (plugins) => {
7391
+ plugins.forEach((plugin) => {
7392
+ if (typeof plugin === "function" && !loadedPlugins.includes(plugin)) {
7393
+ plugin(ctx);
7394
+ loadedPlugins.push(plugin);
7395
+ }
7396
+ });
7397
+ };
7398
+ loadPlugins(GlobalPlugins);
7399
+ const { data } = yield ctx.getApi().conf.conf().catch((err) => {
7400
+ onLoadErr(ctx, err);
7401
+ throw err;
7402
+ });
7403
+ let conf = {
7404
+ apiVersion: (_a = data.version) == null ? void 0 : _a.version
7405
+ // version info
7406
+ };
7407
+ if (ctx.conf.useBackendConf) {
7408
+ if (!data.frontend_conf)
7409
+ throw new Error("The remote backend does not respond to the frontend conf, but `useBackendConf` conf is enabled");
7410
+ conf = __spreadValues(__spreadValues({}, conf), handleConfFormServer(data.frontend_conf));
7411
+ }
7412
+ ctx.conf.remoteConfModifier && ctx.conf.remoteConfModifier(conf);
7413
+ conf.pluginURLs && (yield loadNetworkPlugins(conf.pluginURLs, ctx.conf.server).then((plugins) => {
7414
+ loadPlugins(plugins);
7415
+ }).catch((err) => {
7416
+ console.error("Failed to load plugin", err);
7417
+ }));
7418
+ ctx.trigger("created");
7419
+ ctx.updateConf(conf);
7420
+ ctx.trigger("mounted");
7421
+ if (!ctx.conf.remoteConfModifier) {
7422
+ ctx.fetch({ offset: 0 });
7423
+ }
7424
+ });
7425
+ }
7426
+ function loadNetworkPlugins(scripts, apiBase) {
7427
+ return __async(this, null, function* () {
7428
+ if (!scripts || !Array.isArray(scripts))
7429
+ return [];
7430
+ const tasks = [];
7431
+ scripts.forEach((url) => {
7432
+ if (!/^(http|https):\/\//.test(url))
7433
+ url = `${apiBase.replace(/\/$/, "")}/${url.replace(/^\//, "")}`;
7434
+ tasks.push(new Promise((resolve, reject) => {
7435
+ if (document.querySelector(`script[src="${url}"]`)) {
7436
+ resolve();
7437
+ return;
7438
+ }
7439
+ const script = document.createElement("script");
7440
+ script.src = url;
7441
+ document.head.appendChild(script);
7442
+ script.onload = () => resolve();
7443
+ script.onerror = (err) => reject(err);
7444
+ }));
7445
+ });
7446
+ yield Promise.all(tasks);
7447
+ return Object.values(window.ArtalkPlugins || {});
7448
+ });
7449
+ }
7450
+ function onLoadErr(ctx, err) {
7451
+ var _a;
7452
+ let sidebarOpenView = "";
7453
+ if ((_a = err.data) == null ? void 0 : _a.err_no_site) {
7454
+ const viewLoadParam = { create_name: ctx.conf.site, create_urls: `${window.location.protocol}//${window.location.host}` };
7455
+ sidebarOpenView = `sites|${JSON.stringify(viewLoadParam)}`;
7456
+ }
7457
+ showErrorDialog({
7458
+ $err: ctx.get("list").$el,
7459
+ errMsg: err.msg || String(err),
7460
+ errData: err.data,
7461
+ retryFn: () => load(ctx),
7462
+ onOpenSidebar: ctx.get("user").getData().isAdmin ? () => ctx.showSidebar({
7463
+ view: sidebarOpenView
7464
+ }) : void 0
7465
+ // only show open sidebar button when user is admin
7466
+ });
7467
+ }
7418
7468
  class Artalk {
7419
7469
  constructor(conf) {
7420
7470
  __publicField(this, "ctx");
7421
- /** Plugins */
7422
- __publicField(this, "plugins", [...GlobalPlugins]);
7423
7471
  const handledConf = handelCustomConf(conf, true);
7424
7472
  this.ctx = new Context(handledConf);
7425
7473
  Object.entries(services).forEach(([name, initService]) => {
7426
7474
  const obj = initService(this.ctx);
7427
- if (obj)
7428
- this.ctx.inject(name, obj);
7429
- });
7430
- this.plugins.forEach((plugin) => {
7431
- if (typeof plugin === "function")
7432
- plugin(this.ctx);
7475
+ obj && this.ctx.inject(name, obj);
7433
7476
  });
7434
- this.ctx.trigger("created");
7477
+ load(this.ctx);
7435
7478
  }
7436
7479
  /** Get the config of Artalk */
7437
7480
  getConf() {