artalk 2.8.0 → 2.8.1
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.
- package/dist/Artalk.cjs +2 -2
- package/dist/Artalk.cjs.map +1 -1
- package/dist/Artalk.iife.js +2 -2
- package/dist/Artalk.iife.js.map +1 -1
- package/dist/Artalk.js +2 -2
- package/dist/Artalk.js.map +1 -1
- package/dist/Artalk.mjs +289 -247
- package/dist/Artalk.mjs.map +1 -1
- package/dist/ArtalkLite.cjs +2 -2
- package/dist/ArtalkLite.cjs.map +1 -1
- package/dist/ArtalkLite.iife.js +2 -2
- package/dist/ArtalkLite.iife.js.map +1 -1
- package/dist/ArtalkLite.js +2 -2
- package/dist/ArtalkLite.js.map +1 -1
- package/dist/ArtalkLite.mjs +289 -247
- package/dist/ArtalkLite.mjs.map +1 -1
- package/dist/main.d.cts +105 -48
- package/dist/main.d.ts +105 -48
- package/package.json +1 -1
package/dist/Artalk.mjs
CHANGED
|
@@ -381,6 +381,29 @@ let Api$1 = class Api extends HttpClient {
|
|
|
381
381
|
type: "application/json",
|
|
382
382
|
format: "json"
|
|
383
383
|
}, params)),
|
|
384
|
+
/**
|
|
385
|
+
* @description Get the detail of a comment by comment id
|
|
386
|
+
*
|
|
387
|
+
* @tags Comment
|
|
388
|
+
* @name GetComment
|
|
389
|
+
* @summary Get a comment
|
|
390
|
+
* @request GET:/comments/{id}
|
|
391
|
+
* @response `200` `HandlerResponseCommentGet` OK
|
|
392
|
+
* @response `404` `(HandlerMap & {
|
|
393
|
+
msg?: string,
|
|
394
|
+
|
|
395
|
+
})` Not Found
|
|
396
|
+
* @response `500` `(HandlerMap & {
|
|
397
|
+
msg?: string,
|
|
398
|
+
|
|
399
|
+
})` Internal Server Error
|
|
400
|
+
*/
|
|
401
|
+
getComment: (id, params = {}) => this.request(__spreadValues({
|
|
402
|
+
path: `/comments/${id}`,
|
|
403
|
+
method: "GET",
|
|
404
|
+
type: "application/json",
|
|
405
|
+
format: "json"
|
|
406
|
+
}, params)),
|
|
384
407
|
/**
|
|
385
408
|
* @description Update a specific comment
|
|
386
409
|
*
|
|
@@ -5152,7 +5175,7 @@ function showLoading(parentElem, conf) {
|
|
|
5152
5175
|
let $loading = parentElem.querySelector(":scope > .atk-loading");
|
|
5153
5176
|
if (!$loading) {
|
|
5154
5177
|
$loading = createElement(
|
|
5155
|
-
`<div class="atk-loading
|
|
5178
|
+
`<div class="atk-loading" style="display: none;">
|
|
5156
5179
|
<div class="atk-loading-spinner">
|
|
5157
5180
|
<svg viewBox="25 25 50 50"><circle cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"></circle></svg>
|
|
5158
5181
|
</div>
|
|
@@ -5167,7 +5190,8 @@ function showLoading(parentElem, conf) {
|
|
|
5167
5190
|
if ($spinner) {
|
|
5168
5191
|
$spinner.style.display = "none";
|
|
5169
5192
|
window.setTimeout(() => {
|
|
5170
|
-
$spinner.
|
|
5193
|
+
if ($spinner.isConnected)
|
|
5194
|
+
$spinner.style.display = "";
|
|
5171
5195
|
}, 500);
|
|
5172
5196
|
}
|
|
5173
5197
|
}
|
|
@@ -5187,8 +5211,7 @@ function scrollIntoView(elem, enableAnim = true, relativeTo) {
|
|
|
5187
5211
|
if (relativeTo) {
|
|
5188
5212
|
const containerRect = relativeTo.getBoundingClientRect();
|
|
5189
5213
|
const elementRect = elem.getBoundingClientRect();
|
|
5190
|
-
top = elementRect.top - containerRect.top + relativeTo.scrollTop;
|
|
5191
|
-
top += getHeight(relativeTo) / 2 - getHeight(elem) / 2;
|
|
5214
|
+
top = elementRect.top - containerRect.top + relativeTo.scrollTop - relativeTo.clientHeight / 2 + elem.clientHeight / 2;
|
|
5192
5215
|
} else {
|
|
5193
5216
|
const rect = elem.getBoundingClientRect();
|
|
5194
5217
|
const elemTop = rect.top + window.scrollY;
|
|
@@ -5522,6 +5545,9 @@ class Component {
|
|
|
5522
5545
|
get conf() {
|
|
5523
5546
|
return this.ctx.conf;
|
|
5524
5547
|
}
|
|
5548
|
+
getEl() {
|
|
5549
|
+
return this.$el;
|
|
5550
|
+
}
|
|
5525
5551
|
}
|
|
5526
5552
|
const EditorHTML = '<div class="atk-main-editor">\n <div class="atk-header">\n <input name="nick" class="atk-nick" type="text" required="required">\n <input name="email" class="atk-email" type="email" required="required">\n <input name="link" class="atk-link" type="url">\n </div>\n <div class="atk-textarea-wrap">\n <textarea class="atk-textarea"></textarea>\n </div>\n <div class="atk-plug-panel-wrap" style="display: none;"></div>\n <div class="atk-bottom">\n <div class="atk-item atk-plug-btn-wrap"></div>\n <div class="atk-item">\n <button type="button" class="atk-send-btn"></button>\n </div>\n </div>\n <div class="atk-notify-wrap"></div>\n</div>\n';
|
|
5527
5553
|
const Sel = {
|
|
@@ -5906,39 +5932,18 @@ function makeNestCommentNodeList(srcData, sortBy = "DATE_DESC", nestMax = 2) {
|
|
|
5906
5932
|
})(nodeList);
|
|
5907
5933
|
return nodeList;
|
|
5908
5934
|
}
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
}
|
|
5913
|
-
// TODO: refactor `if syntax` to strategy pattern
|
|
5914
|
-
import(comments) {
|
|
5915
|
-
if (this.options.flatMode) {
|
|
5916
|
-
comments.forEach((commentData) => {
|
|
5917
|
-
this.putCommentFlatMode(commentData, comments, "append");
|
|
5918
|
-
});
|
|
5919
|
-
} else {
|
|
5920
|
-
this.importCommentsNestMode(comments);
|
|
5921
|
-
}
|
|
5922
|
-
}
|
|
5923
|
-
insert(comment) {
|
|
5924
|
-
if (!this.options.flatMode) {
|
|
5925
|
-
this.insertCommentNest(comment);
|
|
5926
|
-
} else {
|
|
5927
|
-
this.insertCommentFlatMode(comment);
|
|
5928
|
-
}
|
|
5929
|
-
}
|
|
5930
|
-
// 导入评论 · 嵌套模式
|
|
5931
|
-
importCommentsNestMode(srcData) {
|
|
5932
|
-
const rootNodes = makeNestCommentNodeList(srcData, this.options.nestSortBy, this.options.nestMax);
|
|
5935
|
+
const createNestStrategy = (opts) => ({
|
|
5936
|
+
import: (comments) => {
|
|
5937
|
+
const rootNodes = makeNestCommentNodeList(comments, opts.nestSortBy, opts.nestMax);
|
|
5933
5938
|
rootNodes.forEach((rootNode) => {
|
|
5934
5939
|
var _a;
|
|
5935
|
-
const rootC =
|
|
5936
|
-
(_a =
|
|
5940
|
+
const rootC = opts.createCommentNode(rootNode.comment);
|
|
5941
|
+
(_a = opts.$commentsWrap) == null ? void 0 : _a.appendChild(rootC.getEl());
|
|
5937
5942
|
rootC.getRender().playFadeAnim();
|
|
5938
5943
|
const loadChildren = (parentC, parentNode) => {
|
|
5939
5944
|
parentNode.children.forEach((node) => {
|
|
5940
5945
|
const childD = node.comment;
|
|
5941
|
-
const childC =
|
|
5946
|
+
const childC = opts.createCommentNode(childD, parentC.getData());
|
|
5942
5947
|
parentC.putChild(childC);
|
|
5943
5948
|
loadChildren(childC, node);
|
|
5944
5949
|
});
|
|
@@ -5946,44 +5951,66 @@ class ListLayout {
|
|
|
5946
5951
|
loadChildren(rootC, rootNode);
|
|
5947
5952
|
rootC.getRender().checkHeightLimit();
|
|
5948
5953
|
});
|
|
5949
|
-
}
|
|
5950
|
-
|
|
5951
|
-
putCommentFlatMode(cData, ctxData, insertMode) {
|
|
5952
|
-
var _a, _b;
|
|
5953
|
-
if (cData.is_collapsed)
|
|
5954
|
-
cData.is_allow_reply = false;
|
|
5955
|
-
const comment = this.options.createCommentNode(cData, ctxData);
|
|
5956
|
-
if (cData.visible) {
|
|
5957
|
-
if (insertMode === "append")
|
|
5958
|
-
(_a = this.options.$commentsWrap) == null ? void 0 : _a.append(comment.getEl());
|
|
5959
|
-
if (insertMode === "prepend")
|
|
5960
|
-
(_b = this.options.$commentsWrap) == null ? void 0 : _b.prepend(comment.getEl());
|
|
5961
|
-
comment.getRender().playFadeAnim();
|
|
5962
|
-
}
|
|
5963
|
-
comment.getRender().checkHeightLimit();
|
|
5964
|
-
return comment;
|
|
5965
|
-
}
|
|
5966
|
-
insertCommentNest(commentData) {
|
|
5954
|
+
},
|
|
5955
|
+
insert: (comment, replyComment) => {
|
|
5967
5956
|
var _a;
|
|
5968
|
-
const
|
|
5969
|
-
if (
|
|
5970
|
-
(_a =
|
|
5957
|
+
const node = opts.createCommentNode(comment, replyComment);
|
|
5958
|
+
if (comment.rid === 0) {
|
|
5959
|
+
(_a = opts.$commentsWrap) == null ? void 0 : _a.prepend(node.getEl());
|
|
5971
5960
|
} else {
|
|
5972
|
-
const parent =
|
|
5961
|
+
const parent = opts.findCommentNode(comment.rid);
|
|
5973
5962
|
if (parent) {
|
|
5974
|
-
parent.putChild(
|
|
5975
|
-
|
|
5963
|
+
parent.putChild(node, opts.nestSortBy === "DATE_ASC" ? "append" : "prepend");
|
|
5964
|
+
node.getParents().forEach((p) => {
|
|
5976
5965
|
p.getRender().heightLimitRemoveForChildren();
|
|
5977
5966
|
});
|
|
5978
5967
|
}
|
|
5979
5968
|
}
|
|
5980
|
-
|
|
5981
|
-
scrollIntoView(
|
|
5982
|
-
|
|
5969
|
+
node.getRender().checkHeightLimit();
|
|
5970
|
+
node.scrollIntoView();
|
|
5971
|
+
node.getRender().playFadeAnim();
|
|
5972
|
+
}
|
|
5973
|
+
});
|
|
5974
|
+
const createFlatStrategy = (opts) => ({
|
|
5975
|
+
import: (comments) => {
|
|
5976
|
+
comments.forEach((comment) => {
|
|
5977
|
+
const replyComment = comment.rid === 0 ? void 0 : comments.find((c) => c.id === comment.rid);
|
|
5978
|
+
insertComment(opts, "append", comment, replyComment);
|
|
5979
|
+
});
|
|
5980
|
+
},
|
|
5981
|
+
insert: (comment, replyComment) => {
|
|
5982
|
+
const node = insertComment(opts, "prepend", comment, replyComment);
|
|
5983
|
+
node.scrollIntoView();
|
|
5983
5984
|
}
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5985
|
+
});
|
|
5986
|
+
function insertComment(opts, insertMode, comment, replyComment) {
|
|
5987
|
+
if (comment.is_collapsed)
|
|
5988
|
+
comment.is_allow_reply = false;
|
|
5989
|
+
const node = opts.createCommentNode(comment, replyComment);
|
|
5990
|
+
if (comment.visible) {
|
|
5991
|
+
const $comment = node.getEl();
|
|
5992
|
+
const $listCommentsWrap = opts.$commentsWrap;
|
|
5993
|
+
if (insertMode === "append")
|
|
5994
|
+
$listCommentsWrap == null ? void 0 : $listCommentsWrap.append($comment);
|
|
5995
|
+
if (insertMode === "prepend")
|
|
5996
|
+
$listCommentsWrap == null ? void 0 : $listCommentsWrap.prepend($comment);
|
|
5997
|
+
node.getRender().playFadeAnim();
|
|
5998
|
+
}
|
|
5999
|
+
node.getRender().checkHeightLimit();
|
|
6000
|
+
return node;
|
|
6001
|
+
}
|
|
6002
|
+
class ListLayout {
|
|
6003
|
+
constructor(options) {
|
|
6004
|
+
this.options = options;
|
|
6005
|
+
}
|
|
6006
|
+
getStrategy() {
|
|
6007
|
+
return this.options.flatMode ? createFlatStrategy(this.options) : createNestStrategy(this.options);
|
|
6008
|
+
}
|
|
6009
|
+
import(comments) {
|
|
6010
|
+
this.getStrategy().import(comments);
|
|
6011
|
+
}
|
|
6012
|
+
insert(comment, replyComment) {
|
|
6013
|
+
this.getStrategy().insert(comment, replyComment);
|
|
5987
6014
|
}
|
|
5988
6015
|
}
|
|
5989
6016
|
function Detect(userAgent) {
|
|
@@ -6246,7 +6273,7 @@ const CommentHTML = '<div class="atk-comment-wrap">\n <div class="atk-comment">
|
|
|
6246
6273
|
function renderAvatar(r) {
|
|
6247
6274
|
const $avatar = r.$el.querySelector(".atk-avatar");
|
|
6248
6275
|
const $avatarImg = createElement("<img />");
|
|
6249
|
-
const avatarURLBuilder = r.
|
|
6276
|
+
const avatarURLBuilder = r.opts.avatarURLBuilder;
|
|
6250
6277
|
$avatarImg.src = avatarURLBuilder ? avatarURLBuilder(r.data) : r.comment.getGravatarURL();
|
|
6251
6278
|
if (r.data.link) {
|
|
6252
6279
|
const $avatarA = createElement('<a target="_blank" rel="noreferrer noopener nofollow"></a>');
|
|
@@ -6285,12 +6312,12 @@ function renderVerifyBadge(ctx) {
|
|
|
6285
6312
|
const badgeColor = ctx.data.badge_color;
|
|
6286
6313
|
if (badgeText) {
|
|
6287
6314
|
const $badge = createElement(`<span class="atk-badge"></span>`);
|
|
6288
|
-
$badge.innerText = badgeText.replace("管理员",
|
|
6315
|
+
$badge.innerText = badgeText.replace("管理员", t("admin"));
|
|
6289
6316
|
$badge.style.backgroundColor = badgeColor || "";
|
|
6290
6317
|
ctx.$headerBadgeWrap.append($badge);
|
|
6291
6318
|
}
|
|
6292
6319
|
if (ctx.data.is_pinned) {
|
|
6293
|
-
const $pinnedBadge = createElement(`<span class="atk-pinned-badge">${
|
|
6320
|
+
const $pinnedBadge = createElement(`<span class="atk-pinned-badge">${t("pin")}</span>`);
|
|
6294
6321
|
ctx.$headerBadgeWrap.append($pinnedBadge);
|
|
6295
6322
|
}
|
|
6296
6323
|
}
|
|
@@ -6300,7 +6327,7 @@ function renderDate(ctx) {
|
|
|
6300
6327
|
$date.setAttribute("data-atk-comment-date", String(+new Date(ctx.data.date)));
|
|
6301
6328
|
}
|
|
6302
6329
|
function renderUABadge(ctx) {
|
|
6303
|
-
if (!ctx.
|
|
6330
|
+
if (!ctx.opts.uaBadge && !ctx.data.ip_region)
|
|
6304
6331
|
return;
|
|
6305
6332
|
let $uaWrap = ctx.$header.querySelector("atk-ua-wrap");
|
|
6306
6333
|
if (!$uaWrap) {
|
|
@@ -6313,7 +6340,7 @@ function renderUABadge(ctx) {
|
|
|
6313
6340
|
$regionBadge.innerText = ctx.data.ip_region;
|
|
6314
6341
|
$uaWrap.append($regionBadge);
|
|
6315
6342
|
}
|
|
6316
|
-
if (ctx.
|
|
6343
|
+
if (ctx.opts.uaBadge) {
|
|
6317
6344
|
const { browser, os } = ctx.comment.getUserUA();
|
|
6318
6345
|
if (String(browser).trim()) {
|
|
6319
6346
|
const $uaBrowser = createElement(`<span class="atk-ua ua-browser"></span>`);
|
|
@@ -6336,8 +6363,8 @@ function renderContent(r) {
|
|
|
6336
6363
|
r.$content.classList.add("atk-hide", "atk-type-collapsed");
|
|
6337
6364
|
const collapsedInfoEl = createElement(`
|
|
6338
6365
|
<div class="atk-collapsed">
|
|
6339
|
-
<span class="atk-text">${
|
|
6340
|
-
<span class="atk-show-btn">${
|
|
6366
|
+
<span class="atk-text">${t("collapsedMsg")}</span>
|
|
6367
|
+
<span class="atk-show-btn">${t("expand")}</span>
|
|
6341
6368
|
</div>`);
|
|
6342
6369
|
r.$body.insertAdjacentElement("beforeend", collapsedInfoEl);
|
|
6343
6370
|
const contentShowBtn = collapsedInfoEl.querySelector(".atk-show-btn");
|
|
@@ -6347,51 +6374,51 @@ function renderContent(r) {
|
|
|
6347
6374
|
r.$content.innerHTML = r.comment.getContentMarked();
|
|
6348
6375
|
r.$content.classList.remove("atk-hide");
|
|
6349
6376
|
playFadeInAnim(r.$content);
|
|
6350
|
-
contentShowBtn.innerText =
|
|
6377
|
+
contentShowBtn.innerText = t("collapse");
|
|
6351
6378
|
} else {
|
|
6352
6379
|
r.$content.innerHTML = "";
|
|
6353
6380
|
r.$content.classList.add("atk-hide");
|
|
6354
|
-
contentShowBtn.innerText =
|
|
6381
|
+
contentShowBtn.innerText = t("expand");
|
|
6355
6382
|
}
|
|
6356
6383
|
});
|
|
6357
6384
|
}
|
|
6358
6385
|
function renderReplyAt(r) {
|
|
6359
|
-
if (r.
|
|
6386
|
+
if (r.opts.flatMode || r.data.rid === 0)
|
|
6360
6387
|
return;
|
|
6361
|
-
if (!r.
|
|
6388
|
+
if (!r.opts.replyTo)
|
|
6362
6389
|
return;
|
|
6363
6390
|
r.$replyAt = createElement(`<span class="atk-item atk-reply-at"><span class="atk-arrow"></span><span class="atk-nick"></span></span>`);
|
|
6364
|
-
r.$replyAt.querySelector(".atk-nick").innerText = `${r.
|
|
6391
|
+
r.$replyAt.querySelector(".atk-nick").innerText = `${r.opts.replyTo.nick}`;
|
|
6365
6392
|
r.$replyAt.onclick = () => {
|
|
6366
6393
|
r.comment.getActions().goToReplyComment();
|
|
6367
6394
|
};
|
|
6368
6395
|
r.$headerBadgeWrap.insertAdjacentElement("afterend", r.$replyAt);
|
|
6369
6396
|
}
|
|
6370
6397
|
function renderReplyTo(r) {
|
|
6371
|
-
if (!r.
|
|
6398
|
+
if (!r.opts.flatMode)
|
|
6372
6399
|
return;
|
|
6373
|
-
if (!r.
|
|
6400
|
+
if (!r.opts.replyTo)
|
|
6374
6401
|
return;
|
|
6375
6402
|
r.$replyTo = createElement(`
|
|
6376
6403
|
<div class="atk-reply-to">
|
|
6377
|
-
<div class="atk-meta">${
|
|
6404
|
+
<div class="atk-meta">${t("reply")} <span class="atk-nick"></span>:</div>
|
|
6378
6405
|
<div class="atk-content"></div>
|
|
6379
6406
|
</div>`);
|
|
6380
6407
|
const $nick = r.$replyTo.querySelector(".atk-nick");
|
|
6381
|
-
$nick.innerText = `@${r.
|
|
6408
|
+
$nick.innerText = `@${r.opts.replyTo.nick}`;
|
|
6382
6409
|
$nick.onclick = () => {
|
|
6383
6410
|
r.comment.getActions().goToReplyComment();
|
|
6384
6411
|
};
|
|
6385
|
-
let replyContent = marked(r.
|
|
6386
|
-
if (r.
|
|
6387
|
-
replyContent = `[${
|
|
6412
|
+
let replyContent = marked(r.opts.replyTo.content);
|
|
6413
|
+
if (r.opts.replyTo.is_collapsed)
|
|
6414
|
+
replyContent = `[${t("collapsed")}]`;
|
|
6388
6415
|
r.$replyTo.querySelector(".atk-content").innerHTML = replyContent;
|
|
6389
6416
|
r.$body.prepend(r.$replyTo);
|
|
6390
6417
|
}
|
|
6391
6418
|
function renderPending(r) {
|
|
6392
6419
|
if (!r.data.is_pending)
|
|
6393
6420
|
return;
|
|
6394
|
-
const pendingEl = createElement(`<div class="atk-pending">${
|
|
6421
|
+
const pendingEl = createElement(`<div class="atk-pending">${t("pendingMsg")}</div>`);
|
|
6395
6422
|
r.$body.prepend(pendingEl);
|
|
6396
6423
|
}
|
|
6397
6424
|
class ActionBtn {
|
|
@@ -6544,14 +6571,14 @@ function renderActions(r) {
|
|
|
6544
6571
|
});
|
|
6545
6572
|
}
|
|
6546
6573
|
function renderVote(r) {
|
|
6547
|
-
if (!r.
|
|
6574
|
+
if (!r.opts.vote)
|
|
6548
6575
|
return;
|
|
6549
|
-
r.voteBtnUp = new ActionBtn(() => `${
|
|
6576
|
+
r.voteBtnUp = new ActionBtn(() => `${t("voteUp")} (${r.data.vote_up || 0})`).appendTo(r.$actions);
|
|
6550
6577
|
r.voteBtnUp.setClick(() => {
|
|
6551
6578
|
r.comment.getActions().vote("up");
|
|
6552
6579
|
});
|
|
6553
|
-
if (r.
|
|
6554
|
-
r.voteBtnDown = new ActionBtn(() => `${
|
|
6580
|
+
if (r.opts.voteDown) {
|
|
6581
|
+
r.voteBtnDown = new ActionBtn(() => `${t("voteDown")} (${r.data.vote_down || 0})`).appendTo(r.$actions);
|
|
6555
6582
|
r.voteBtnDown.setClick(() => {
|
|
6556
6583
|
r.comment.getActions().vote("down");
|
|
6557
6584
|
});
|
|
@@ -6560,20 +6587,16 @@ function renderVote(r) {
|
|
|
6560
6587
|
function renderReply(r) {
|
|
6561
6588
|
if (!r.data.is_allow_reply)
|
|
6562
6589
|
return;
|
|
6563
|
-
const replyBtn = createElement(`<span>${
|
|
6590
|
+
const replyBtn = createElement(`<span>${t("reply")}</span>`);
|
|
6564
6591
|
r.$actions.append(replyBtn);
|
|
6565
6592
|
replyBtn.addEventListener("click", (e) => {
|
|
6566
6593
|
e.stopPropagation();
|
|
6567
|
-
|
|
6568
|
-
r.ctx.replyComment(r.data, r.$el);
|
|
6569
|
-
} else {
|
|
6570
|
-
r.cConf.onReplyBtnClick();
|
|
6571
|
-
}
|
|
6594
|
+
r.opts.replyComment(r.data, r.$el);
|
|
6572
6595
|
});
|
|
6573
6596
|
}
|
|
6574
6597
|
function renderCollapse(r) {
|
|
6575
6598
|
const collapseBtn = new ActionBtn({
|
|
6576
|
-
text: () => r.data.is_collapsed ?
|
|
6599
|
+
text: () => r.data.is_collapsed ? t("expand") : t("collapse"),
|
|
6577
6600
|
adminOnly: true
|
|
6578
6601
|
});
|
|
6579
6602
|
collapseBtn.appendTo(r.$actions);
|
|
@@ -6583,7 +6606,7 @@ function renderCollapse(r) {
|
|
|
6583
6606
|
}
|
|
6584
6607
|
function renderModerator(r) {
|
|
6585
6608
|
const pendingBtn = new ActionBtn({
|
|
6586
|
-
text: () => r.data.is_pending ?
|
|
6609
|
+
text: () => r.data.is_pending ? t("pending") : t("approved"),
|
|
6587
6610
|
adminOnly: true
|
|
6588
6611
|
});
|
|
6589
6612
|
pendingBtn.appendTo(r.$actions);
|
|
@@ -6593,7 +6616,7 @@ function renderModerator(r) {
|
|
|
6593
6616
|
}
|
|
6594
6617
|
function renderPin(r) {
|
|
6595
6618
|
const pinnedBtn = new ActionBtn({
|
|
6596
|
-
text: () => r.data.is_pinned ?
|
|
6619
|
+
text: () => r.data.is_pinned ? t("unpin") : t("pin"),
|
|
6597
6620
|
adminOnly: true
|
|
6598
6621
|
});
|
|
6599
6622
|
pinnedBtn.appendTo(r.$actions);
|
|
@@ -6603,19 +6626,19 @@ function renderPin(r) {
|
|
|
6603
6626
|
}
|
|
6604
6627
|
function renderEdit(r) {
|
|
6605
6628
|
const editBtn = new ActionBtn({
|
|
6606
|
-
text:
|
|
6629
|
+
text: t("edit"),
|
|
6607
6630
|
adminOnly: true
|
|
6608
6631
|
});
|
|
6609
6632
|
editBtn.appendTo(r.$actions);
|
|
6610
6633
|
editBtn.setClick(() => {
|
|
6611
|
-
r.
|
|
6634
|
+
r.opts.editComment(r.data, r.$el);
|
|
6612
6635
|
});
|
|
6613
6636
|
}
|
|
6614
6637
|
function renderDel(r) {
|
|
6615
6638
|
const delBtn = new ActionBtn({
|
|
6616
|
-
text:
|
|
6639
|
+
text: t("delete"),
|
|
6617
6640
|
confirm: true,
|
|
6618
|
-
confirmText:
|
|
6641
|
+
confirmText: t("deleteConfirm"),
|
|
6619
6642
|
adminOnly: true
|
|
6620
6643
|
});
|
|
6621
6644
|
delBtn.appendTo(r.$actions);
|
|
@@ -6657,18 +6680,21 @@ class Render {
|
|
|
6657
6680
|
__publicField(this, "$replyAt");
|
|
6658
6681
|
this.comment = comment;
|
|
6659
6682
|
}
|
|
6660
|
-
get ctx() {
|
|
6661
|
-
return this.comment.ctx;
|
|
6662
|
-
}
|
|
6663
6683
|
get data() {
|
|
6664
6684
|
return this.comment.getData();
|
|
6665
6685
|
}
|
|
6666
|
-
get
|
|
6667
|
-
return this.comment.
|
|
6668
|
-
}
|
|
6669
|
-
get cConf() {
|
|
6670
|
-
return this.comment.getConf();
|
|
6686
|
+
get opts() {
|
|
6687
|
+
return this.comment.getOpts();
|
|
6671
6688
|
}
|
|
6689
|
+
/**
|
|
6690
|
+
* Render the comment ui
|
|
6691
|
+
*
|
|
6692
|
+
* If comment data is updated, call this method to re-render the comment ui.
|
|
6693
|
+
* The method will be called multiple times, so it should be idempotent.
|
|
6694
|
+
*
|
|
6695
|
+
* Renders may add event listeners to the comment ui, so it should be called only once or override the original.
|
|
6696
|
+
* Please be aware of the memory leak caused by the event listener.
|
|
6697
|
+
*/
|
|
6672
6698
|
render() {
|
|
6673
6699
|
this.$el = createElement(CommentHTML);
|
|
6674
6700
|
this.$main = this.$el.querySelector(".atk-main");
|
|
@@ -6678,12 +6704,14 @@ class Render {
|
|
|
6678
6704
|
this.$actions = this.$el.querySelector(".atk-actions");
|
|
6679
6705
|
this.$el.setAttribute("id", `atk-comment-${this.data.id}`);
|
|
6680
6706
|
loadRenders(this);
|
|
6681
|
-
this
|
|
6707
|
+
if (this.$childrenWrap) {
|
|
6708
|
+
this.$main.append(this.$childrenWrap);
|
|
6709
|
+
}
|
|
6682
6710
|
return this.$el;
|
|
6683
6711
|
}
|
|
6684
6712
|
/** 内容限高检测 */
|
|
6685
6713
|
checkHeightLimit() {
|
|
6686
|
-
const conf = this.
|
|
6714
|
+
const conf = this.opts.heightLimit;
|
|
6687
6715
|
if (!conf || !conf.content || !conf.children)
|
|
6688
6716
|
return;
|
|
6689
6717
|
const contentMaxH = conf.content;
|
|
@@ -6717,24 +6745,21 @@ class Render {
|
|
|
6717
6745
|
playFadeAnimForBody() {
|
|
6718
6746
|
playFadeInAnim(this.comment.getRender().$body);
|
|
6719
6747
|
}
|
|
6748
|
+
/** Perform the flash animation */
|
|
6749
|
+
playFlashAnim() {
|
|
6750
|
+
this.$el.classList.remove("atk-flash-once");
|
|
6751
|
+
window.setTimeout(() => {
|
|
6752
|
+
this.$el.classList.add("atk-flash-once");
|
|
6753
|
+
}, 150);
|
|
6754
|
+
}
|
|
6720
6755
|
/** 获取子评论 Wrap */
|
|
6721
6756
|
getChildrenWrap() {
|
|
6722
|
-
return this.$childrenWrap;
|
|
6723
|
-
}
|
|
6724
|
-
/** 初始化子评论区域 Wrap */
|
|
6725
|
-
renderChildrenWrap() {
|
|
6726
6757
|
if (!this.$childrenWrap) {
|
|
6727
6758
|
this.$childrenWrap = createElement('<div class="atk-comment-children"></div>');
|
|
6728
6759
|
this.$main.append(this.$childrenWrap);
|
|
6729
6760
|
}
|
|
6730
6761
|
return this.$childrenWrap;
|
|
6731
6762
|
}
|
|
6732
|
-
/** 恢复原有的子评论区域 Wrap */
|
|
6733
|
-
recoveryChildrenWrap() {
|
|
6734
|
-
if (this.$childrenWrap) {
|
|
6735
|
-
this.$main.append(this.$childrenWrap);
|
|
6736
|
-
}
|
|
6737
|
-
}
|
|
6738
6763
|
/** 设置已读 */
|
|
6739
6764
|
setUnread(val) {
|
|
6740
6765
|
if (val)
|
|
@@ -6753,17 +6778,15 @@ class Render {
|
|
|
6753
6778
|
setOpenURL(url) {
|
|
6754
6779
|
this.setOpenable(true);
|
|
6755
6780
|
this.$el.onclick = (evt) => {
|
|
6756
|
-
evt.
|
|
6781
|
+
evt.stopPropagation();
|
|
6757
6782
|
window.open(url);
|
|
6758
|
-
if (this.cConf.openEvt)
|
|
6759
|
-
this.cConf.openEvt();
|
|
6760
6783
|
};
|
|
6761
6784
|
}
|
|
6762
6785
|
/** 设置点击评论时的操作 */
|
|
6763
6786
|
setOpenAction(action) {
|
|
6764
6787
|
this.setOpenable(true);
|
|
6765
6788
|
this.$el.onclick = (evt) => {
|
|
6766
|
-
evt.
|
|
6789
|
+
evt.stopPropagation();
|
|
6767
6790
|
action();
|
|
6768
6791
|
};
|
|
6769
6792
|
}
|
|
@@ -6773,26 +6796,26 @@ class CommentActions {
|
|
|
6773
6796
|
__publicField(this, "comment");
|
|
6774
6797
|
this.comment = comment;
|
|
6775
6798
|
}
|
|
6776
|
-
get ctx() {
|
|
6777
|
-
return this.comment.ctx;
|
|
6778
|
-
}
|
|
6779
6799
|
get data() {
|
|
6780
6800
|
return this.comment.getData();
|
|
6781
6801
|
}
|
|
6782
|
-
get
|
|
6783
|
-
return this.comment.
|
|
6802
|
+
get opts() {
|
|
6803
|
+
return this.comment.getOpts();
|
|
6804
|
+
}
|
|
6805
|
+
getApi() {
|
|
6806
|
+
return this.comment.getOpts().getApi();
|
|
6784
6807
|
}
|
|
6785
6808
|
/** 投票操作 */
|
|
6786
6809
|
vote(type) {
|
|
6787
6810
|
const actionBtn = type === "up" ? this.comment.getRender().voteBtnUp : this.comment.getRender().voteBtnDown;
|
|
6788
|
-
this.
|
|
6811
|
+
this.getApi().votes.vote(`comment_${type}`, this.data.id, __spreadValues({}, this.getApi().getUserFields())).then((res) => {
|
|
6789
6812
|
var _a, _b;
|
|
6790
6813
|
this.data.vote_up = res.data.up;
|
|
6791
6814
|
this.data.vote_down = res.data.down;
|
|
6792
6815
|
(_a = this.comment.getRender().voteBtnUp) == null ? void 0 : _a.updateText();
|
|
6793
6816
|
(_b = this.comment.getRender().voteBtnDown) == null ? void 0 : _b.updateText();
|
|
6794
6817
|
}).catch((err) => {
|
|
6795
|
-
actionBtn == null ? void 0 : actionBtn.setError(
|
|
6818
|
+
actionBtn == null ? void 0 : actionBtn.setError(t("voteFail"));
|
|
6796
6819
|
console.log(err);
|
|
6797
6820
|
});
|
|
6798
6821
|
}
|
|
@@ -6800,7 +6823,7 @@ class CommentActions {
|
|
|
6800
6823
|
adminEdit(type, btnElem) {
|
|
6801
6824
|
if (btnElem.isLoading)
|
|
6802
6825
|
return;
|
|
6803
|
-
btnElem.setLoading(true, `${
|
|
6826
|
+
btnElem.setLoading(true, `${t("editing")}...`);
|
|
6804
6827
|
const modify = __spreadValues({}, this.data);
|
|
6805
6828
|
if (type === "collapsed") {
|
|
6806
6829
|
modify.is_collapsed = !modify.is_collapsed;
|
|
@@ -6809,26 +6832,26 @@ class CommentActions {
|
|
|
6809
6832
|
} else if (type === "pinned") {
|
|
6810
6833
|
modify.is_pinned = !modify.is_pinned;
|
|
6811
6834
|
}
|
|
6812
|
-
this.
|
|
6835
|
+
this.getApi().comments.updateComment(this.data.id, __spreadValues({}, modify)).then((res) => {
|
|
6813
6836
|
btnElem.setLoading(false);
|
|
6814
6837
|
this.comment.setData(res.data);
|
|
6815
6838
|
}).catch((err) => {
|
|
6816
6839
|
console.error(err);
|
|
6817
|
-
btnElem.setError(
|
|
6840
|
+
btnElem.setError(t("editFail"));
|
|
6818
6841
|
});
|
|
6819
6842
|
}
|
|
6820
6843
|
/** 管理员 - 评论删除 */
|
|
6821
6844
|
adminDelete(btnElem) {
|
|
6822
6845
|
if (btnElem.isLoading)
|
|
6823
6846
|
return;
|
|
6824
|
-
btnElem.setLoading(true, `${
|
|
6825
|
-
this.
|
|
6847
|
+
btnElem.setLoading(true, `${t("deleting")}...`);
|
|
6848
|
+
this.getApi().comments.deleteComment(this.data.id).then(() => {
|
|
6826
6849
|
btnElem.setLoading(false);
|
|
6827
|
-
if (this.
|
|
6828
|
-
this.
|
|
6850
|
+
if (this.opts.onDelete)
|
|
6851
|
+
this.opts.onDelete(this.comment);
|
|
6829
6852
|
}).catch((e) => {
|
|
6830
6853
|
console.error(e);
|
|
6831
|
-
btnElem.setError(
|
|
6854
|
+
btnElem.setError(t("deleteFail"));
|
|
6832
6855
|
});
|
|
6833
6856
|
}
|
|
6834
6857
|
/** 快速跳转到该评论 */
|
|
@@ -6840,21 +6863,18 @@ class CommentActions {
|
|
|
6840
6863
|
window.dispatchEvent(new Event("hashchange"));
|
|
6841
6864
|
}
|
|
6842
6865
|
}
|
|
6843
|
-
class CommentNode
|
|
6844
|
-
//
|
|
6845
|
-
constructor(
|
|
6846
|
-
|
|
6866
|
+
class CommentNode {
|
|
6867
|
+
// 当前嵌套层数
|
|
6868
|
+
constructor(data, opts) {
|
|
6869
|
+
__publicField(this, "$el");
|
|
6847
6870
|
__publicField(this, "renderInstance");
|
|
6848
6871
|
__publicField(this, "actionInstance");
|
|
6849
6872
|
__publicField(this, "data");
|
|
6850
|
-
__publicField(this, "
|
|
6873
|
+
__publicField(this, "opts");
|
|
6851
6874
|
__publicField(this, "parent");
|
|
6852
6875
|
__publicField(this, "children", []);
|
|
6853
6876
|
__publicField(this, "nestCurt");
|
|
6854
|
-
|
|
6855
|
-
__publicField(this, "nestMax");
|
|
6856
|
-
this.nestMax = ctx.conf.nestMax || 3;
|
|
6857
|
-
this.cConf = conf;
|
|
6877
|
+
this.opts = opts;
|
|
6858
6878
|
this.data = __spreadValues({}, data);
|
|
6859
6879
|
this.data.date = this.data.date.replace(/-/g, "/");
|
|
6860
6880
|
this.parent = null;
|
|
@@ -6868,8 +6888,8 @@ class CommentNode extends Component {
|
|
|
6868
6888
|
if (this.$el)
|
|
6869
6889
|
this.$el.replaceWith(newEl);
|
|
6870
6890
|
this.$el = newEl;
|
|
6871
|
-
if (this.
|
|
6872
|
-
this.
|
|
6891
|
+
if (this.opts.onAfterRender)
|
|
6892
|
+
this.opts.onAfterRender();
|
|
6873
6893
|
}
|
|
6874
6894
|
/** 获取评论操作实例对象 */
|
|
6875
6895
|
getActions() {
|
|
@@ -6910,51 +6930,76 @@ class CommentNode extends Component {
|
|
|
6910
6930
|
return this.data.id;
|
|
6911
6931
|
}
|
|
6912
6932
|
/** 置入子评论 */
|
|
6913
|
-
putChild(
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
this.children.push(
|
|
6917
|
-
const $
|
|
6933
|
+
putChild(childNode, insertMode = "append") {
|
|
6934
|
+
childNode.parent = this;
|
|
6935
|
+
childNode.nestCurt = this.nestCurt + 1;
|
|
6936
|
+
this.children.push(childNode);
|
|
6937
|
+
const $childrenWrap = this.getChildrenWrapEl();
|
|
6938
|
+
const $childComment = childNode.getEl();
|
|
6918
6939
|
if (insertMode === "append")
|
|
6919
|
-
$
|
|
6940
|
+
$childrenWrap.append($childComment);
|
|
6920
6941
|
else if (insertMode === "prepend")
|
|
6921
|
-
$
|
|
6922
|
-
|
|
6923
|
-
|
|
6942
|
+
$childrenWrap.prepend($childComment);
|
|
6943
|
+
childNode.getRender().playFadeAnim();
|
|
6944
|
+
childNode.getRender().checkHeightLimit();
|
|
6924
6945
|
}
|
|
6925
6946
|
/** 获取存放子评论的元素对象 */
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
if (this.nestCurt < this.nestMax) {
|
|
6930
|
-
$children = this.getRender().renderChildrenWrap();
|
|
6931
|
-
} else {
|
|
6932
|
-
$children = this.parent.getChildrenEl();
|
|
6933
|
-
}
|
|
6947
|
+
getChildrenWrapEl() {
|
|
6948
|
+
if (this.nestCurt >= this.opts.nestMax) {
|
|
6949
|
+
return this.parent.getChildrenWrapEl();
|
|
6934
6950
|
}
|
|
6935
|
-
return
|
|
6951
|
+
return this.getRender().getChildrenWrap();
|
|
6936
6952
|
}
|
|
6937
6953
|
/** 获取所有父评论 */
|
|
6938
6954
|
getParents() {
|
|
6939
|
-
const
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
once(this);
|
|
6947
|
-
return parents;
|
|
6955
|
+
const flattenParents = [];
|
|
6956
|
+
let parent = this.parent;
|
|
6957
|
+
while (parent) {
|
|
6958
|
+
flattenParents.push(parent);
|
|
6959
|
+
parent = parent.getParent();
|
|
6960
|
+
}
|
|
6961
|
+
return flattenParents;
|
|
6948
6962
|
}
|
|
6949
|
-
/**
|
|
6963
|
+
/**
|
|
6964
|
+
* Get the element of the comment
|
|
6965
|
+
*
|
|
6966
|
+
* The `getEl()` will always return the latest $el after calling `render()`.
|
|
6967
|
+
* Please be aware of the memory leak if you use the $el reference directly.
|
|
6968
|
+
*/
|
|
6950
6969
|
getEl() {
|
|
6970
|
+
if (!this.$el)
|
|
6971
|
+
throw new Error("comment element not initialized before `getEl()`");
|
|
6951
6972
|
return this.$el;
|
|
6952
6973
|
}
|
|
6974
|
+
/**
|
|
6975
|
+
* Focus on the comment
|
|
6976
|
+
*
|
|
6977
|
+
* Scroll to the comment and perform flash animation
|
|
6978
|
+
*/
|
|
6979
|
+
focus() {
|
|
6980
|
+
if (!this.$el)
|
|
6981
|
+
throw new Error("comment element not initialized before `focus()`");
|
|
6982
|
+
this.getParents().forEach((p) => {
|
|
6983
|
+
p.getRender().heightLimitRemoveForChildren();
|
|
6984
|
+
});
|
|
6985
|
+
this.scrollIntoView();
|
|
6986
|
+
this.getRender().playFlashAnim();
|
|
6987
|
+
}
|
|
6988
|
+
scrollIntoView() {
|
|
6989
|
+
this.$el && scrollIntoView(this.$el, false, this.opts.scrollRelativeTo && this.opts.scrollRelativeTo());
|
|
6990
|
+
}
|
|
6991
|
+
/**
|
|
6992
|
+
* Remove the comment node
|
|
6993
|
+
*/
|
|
6994
|
+
remove() {
|
|
6995
|
+
var _a;
|
|
6996
|
+
(_a = this.$el) == null ? void 0 : _a.remove();
|
|
6997
|
+
}
|
|
6953
6998
|
/** 获取 Gravatar 头像 URL */
|
|
6954
6999
|
getGravatarURL() {
|
|
6955
7000
|
return getGravatarURL({
|
|
6956
|
-
mirror: this.
|
|
6957
|
-
params: this.
|
|
7001
|
+
mirror: this.opts.gravatar.mirror,
|
|
7002
|
+
params: this.opts.gravatar.params,
|
|
6958
7003
|
emailMD5: this.data.email_encrypted
|
|
6959
7004
|
});
|
|
6960
7005
|
}
|
|
@@ -6964,7 +7009,7 @@ class CommentNode extends Component {
|
|
|
6964
7009
|
}
|
|
6965
7010
|
/** 获取格式化后的日期 */
|
|
6966
7011
|
getDateFormatted() {
|
|
6967
|
-
return timeAgo(new Date(this.data.date),
|
|
7012
|
+
return timeAgo(new Date(this.data.date), t);
|
|
6968
7013
|
}
|
|
6969
7014
|
/** 获取用户 UserAgent 信息 */
|
|
6970
7015
|
getUserUA() {
|
|
@@ -6975,21 +7020,33 @@ class CommentNode extends Component {
|
|
|
6975
7020
|
};
|
|
6976
7021
|
}
|
|
6977
7022
|
/** 获取配置 */
|
|
6978
|
-
|
|
6979
|
-
return this.
|
|
7023
|
+
getOpts() {
|
|
7024
|
+
return this.opts;
|
|
6980
7025
|
}
|
|
6981
7026
|
}
|
|
6982
|
-
function
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
isFlatMode: (_a = ctx.getData().getListLastFetch()) == null ? void 0 : _a.params.flatMode,
|
|
6986
|
-
afterRender: () => {
|
|
7027
|
+
function createCommentNode(ctx, comment, replyComment, opts) {
|
|
7028
|
+
const instance2 = new CommentNode(comment, {
|
|
7029
|
+
onAfterRender: () => {
|
|
6987
7030
|
ctx.trigger("comment-rendered", instance2);
|
|
6988
7031
|
},
|
|
6989
7032
|
onDelete: (c) => {
|
|
6990
7033
|
ctx.getData().deleteComment(c.getID());
|
|
6991
7034
|
},
|
|
6992
|
-
replyTo:
|
|
7035
|
+
replyTo: replyComment,
|
|
7036
|
+
// TODO simplify reference
|
|
7037
|
+
flatMode: typeof (opts == null ? void 0 : opts.forceFlatMode) === "boolean" ? opts == null ? void 0 : opts.forceFlatMode : ctx.conf.flatMode,
|
|
7038
|
+
gravatar: ctx.conf.gravatar,
|
|
7039
|
+
nestMax: ctx.conf.nestMax,
|
|
7040
|
+
heightLimit: ctx.conf.heightLimit,
|
|
7041
|
+
avatarURLBuilder: ctx.conf.avatarURLBuilder,
|
|
7042
|
+
scrollRelativeTo: ctx.conf.scrollRelativeTo,
|
|
7043
|
+
vote: ctx.conf.vote,
|
|
7044
|
+
voteDown: ctx.conf.voteDown,
|
|
7045
|
+
uaBadge: ctx.conf.uaBadge,
|
|
7046
|
+
// TODO: move to plugin folder and remove from core
|
|
7047
|
+
getApi: () => ctx.getApi(),
|
|
7048
|
+
replyComment: (c, $el) => ctx.replyComment(c, $el),
|
|
7049
|
+
editComment: (c, $el) => ctx.editComment(c, $el)
|
|
6993
7050
|
});
|
|
6994
7051
|
instance2.render();
|
|
6995
7052
|
return instance2;
|
|
@@ -7365,20 +7422,19 @@ class List extends Component {
|
|
|
7365
7422
|
getCommentNodes() {
|
|
7366
7423
|
return this.commentNodes;
|
|
7367
7424
|
}
|
|
7368
|
-
getListLayout() {
|
|
7425
|
+
getListLayout({ forceFlatMode } = {}) {
|
|
7369
7426
|
return new ListLayout({
|
|
7370
7427
|
$commentsWrap: this.$commentsWrap,
|
|
7371
7428
|
nestSortBy: this.ctx.conf.nestSort,
|
|
7372
7429
|
nestMax: this.ctx.conf.nestMax,
|
|
7373
|
-
flatMode: this.ctx.conf.flatMode,
|
|
7430
|
+
flatMode: typeof forceFlatMode === "boolean" ? forceFlatMode : this.ctx.conf.flatMode,
|
|
7374
7431
|
// flatMode must be boolean because it had been handled when Artalk.init
|
|
7375
|
-
createCommentNode: (d,
|
|
7376
|
-
const node =
|
|
7432
|
+
createCommentNode: (d, r) => {
|
|
7433
|
+
const node = createCommentNode(this.ctx, d, r, { forceFlatMode });
|
|
7377
7434
|
this.commentNodes.push(node);
|
|
7378
7435
|
return node;
|
|
7379
7436
|
},
|
|
7380
|
-
findCommentNode: (id) => this.commentNodes.find((c) => c.getID() === id)
|
|
7381
|
-
getCommentDataList: () => this.ctx.getData().getComments()
|
|
7437
|
+
findCommentNode: (id) => this.commentNodes.find((c) => c.getID() === id)
|
|
7382
7438
|
});
|
|
7383
7439
|
}
|
|
7384
7440
|
initCrudEvents() {
|
|
@@ -7386,8 +7442,10 @@ class List extends Component {
|
|
|
7386
7442
|
this.getListLayout().import(comments);
|
|
7387
7443
|
});
|
|
7388
7444
|
this.ctx.on("list-loaded", (comments) => {
|
|
7389
|
-
if (comments.length === 0)
|
|
7445
|
+
if (comments.length === 0) {
|
|
7446
|
+
this.commentNodes = [];
|
|
7390
7447
|
this.$commentsWrap.innerHTML = "";
|
|
7448
|
+
}
|
|
7391
7449
|
});
|
|
7392
7450
|
this.ctx.on("comment-inserted", (comment) => {
|
|
7393
7451
|
this.getListLayout().insert(comment);
|
|
@@ -7398,7 +7456,7 @@ class List extends Component {
|
|
|
7398
7456
|
console.error(`comment node id=${comment.id} not found`);
|
|
7399
7457
|
return;
|
|
7400
7458
|
}
|
|
7401
|
-
node.
|
|
7459
|
+
node.remove();
|
|
7402
7460
|
this.commentNodes = this.commentNodes.filter((c) => c.getID() !== comment.id);
|
|
7403
7461
|
});
|
|
7404
7462
|
this.ctx.on("comment-updated", (comment) => {
|
|
@@ -8883,62 +8941,50 @@ const UnreadBadge = (ctx) => {
|
|
|
8883
8941
|
showUnreadBadge(notifies.length || 0);
|
|
8884
8942
|
});
|
|
8885
8943
|
};
|
|
8886
|
-
const
|
|
8887
|
-
let
|
|
8888
|
-
const check2 = () => {
|
|
8944
|
+
const GotoDispatcher = (ctx) => {
|
|
8945
|
+
let lastID = 0;
|
|
8946
|
+
const check2 = ({ locker }) => {
|
|
8889
8947
|
const commentID = extractCommentID();
|
|
8890
8948
|
if (!commentID)
|
|
8891
8949
|
return;
|
|
8950
|
+
if (locker && lastID === commentID)
|
|
8951
|
+
return;
|
|
8952
|
+
lastID = commentID;
|
|
8892
8953
|
ctx.trigger("list-goto", commentID);
|
|
8893
|
-
delayGoto = true;
|
|
8894
|
-
};
|
|
8895
|
-
const hashChangeHandler = () => {
|
|
8896
|
-
delayGoto = false;
|
|
8897
|
-
check2();
|
|
8898
8954
|
};
|
|
8955
|
+
const hashChangeHandler = () => check2({ locker: false });
|
|
8956
|
+
const listLoadedHandler = () => check2({ locker: true });
|
|
8899
8957
|
ctx.on("mounted", () => {
|
|
8900
8958
|
window.addEventListener("hashchange", hashChangeHandler);
|
|
8901
|
-
ctx.on("list-loaded",
|
|
8959
|
+
ctx.on("list-loaded", listLoadedHandler);
|
|
8902
8960
|
});
|
|
8903
8961
|
ctx.on("unmounted", () => {
|
|
8904
8962
|
window.removeEventListener("hashchange", hashChangeHandler);
|
|
8905
|
-
ctx.off("list-loaded",
|
|
8906
|
-
});
|
|
8907
|
-
let foundID = 0;
|
|
8908
|
-
ctx.on("list-goto", (commentID) => {
|
|
8909
|
-
if (foundID === commentID)
|
|
8910
|
-
return;
|
|
8911
|
-
const comment = ctx.get("list").getCommentNodes().find((c) => c.getID() === commentID);
|
|
8912
|
-
if (!comment)
|
|
8913
|
-
return;
|
|
8914
|
-
foundID = commentID;
|
|
8915
|
-
comment.getParents().forEach((p) => {
|
|
8916
|
-
p.getRender().heightLimitRemoveForChildren();
|
|
8917
|
-
});
|
|
8918
|
-
const goTo = () => {
|
|
8919
|
-
scrollIntoView(comment.getEl(), false);
|
|
8920
|
-
comment.getEl().classList.remove("atk-flash-once");
|
|
8921
|
-
window.setTimeout(() => {
|
|
8922
|
-
comment.getEl().classList.add("atk-flash-once");
|
|
8923
|
-
}, 150);
|
|
8924
|
-
};
|
|
8925
|
-
if (!delayGoto)
|
|
8926
|
-
goTo();
|
|
8927
|
-
else
|
|
8928
|
-
window.setTimeout(() => goTo(), 350);
|
|
8963
|
+
ctx.off("list-loaded", listLoadedHandler);
|
|
8929
8964
|
});
|
|
8930
8965
|
};
|
|
8931
8966
|
function extractCommentID() {
|
|
8932
|
-
|
|
8967
|
+
const match = window.location.hash.match(/#atk-comment-([0-9]+)/);
|
|
8968
|
+
let commentId = match && match[1] && !Number.isNaN(parseFloat(match[1])) ? parseFloat(match[1]) : null;
|
|
8933
8969
|
if (!commentId) {
|
|
8934
|
-
|
|
8935
|
-
if (!match || !match[1] || Number.isNaN(Number(match[1])))
|
|
8936
|
-
return null;
|
|
8937
|
-
commentId = Number(match[1]);
|
|
8970
|
+
commentId = Number(getQueryParam("atk_comment"));
|
|
8938
8971
|
}
|
|
8939
8972
|
return commentId || null;
|
|
8940
8973
|
}
|
|
8941
|
-
const
|
|
8974
|
+
const GotoFocus = (ctx) => {
|
|
8975
|
+
ctx.on("list-goto", (commentID) => __async(void 0, null, function* () {
|
|
8976
|
+
let comment = ctx.getCommentNodes().find((c) => c.getID() === commentID);
|
|
8977
|
+
if (!comment) {
|
|
8978
|
+
const data = (yield ctx.getApi().comments.getComment(commentID)).data;
|
|
8979
|
+
ctx.get("list").getListLayout({ forceFlatMode: true }).insert(data.comment, data.reply_comment);
|
|
8980
|
+
comment = ctx.getCommentNodes().find((c) => c.getID() === commentID);
|
|
8981
|
+
}
|
|
8982
|
+
if (!comment)
|
|
8983
|
+
return;
|
|
8984
|
+
comment.focus();
|
|
8985
|
+
}));
|
|
8986
|
+
};
|
|
8987
|
+
const version = "2.8.1";
|
|
8942
8988
|
const Copyright = (ctx) => {
|
|
8943
8989
|
ctx.on("mounted", () => {
|
|
8944
8990
|
const list2 = ctx.get("list");
|
|
@@ -8949,14 +8995,7 @@ const Copyright = (ctx) => {
|
|
|
8949
8995
|
});
|
|
8950
8996
|
};
|
|
8951
8997
|
const NoComment = (ctx) => {
|
|
8952
|
-
let isFetching = false;
|
|
8953
|
-
ctx.on("list-fetch", (params) => {
|
|
8954
|
-
isFetching = true;
|
|
8955
|
-
});
|
|
8956
8998
|
ctx.on("list-loaded", (comments) => {
|
|
8957
|
-
if (!isFetching)
|
|
8958
|
-
return;
|
|
8959
|
-
isFetching = false;
|
|
8960
8999
|
const list2 = ctx.get("list");
|
|
8961
9000
|
const isNoComment = comments.length <= 0;
|
|
8962
9001
|
let $noComment = list2.getCommentsWrapEl().querySelector(".atk-list-no-comment");
|
|
@@ -9208,7 +9247,8 @@ const ListPlugins = [
|
|
|
9208
9247
|
SidebarBtn,
|
|
9209
9248
|
UnreadBadge,
|
|
9210
9249
|
Dropdown,
|
|
9211
|
-
|
|
9250
|
+
GotoDispatcher,
|
|
9251
|
+
GotoFocus,
|
|
9212
9252
|
NoComment,
|
|
9213
9253
|
Copyright,
|
|
9214
9254
|
TimeTicking,
|
|
@@ -9232,6 +9272,7 @@ const PvCountWidget = (ctx) => {
|
|
|
9232
9272
|
ctx.watchConf([
|
|
9233
9273
|
"site",
|
|
9234
9274
|
"pageKey",
|
|
9275
|
+
"pageTitle",
|
|
9235
9276
|
"countEl",
|
|
9236
9277
|
"pvEl"
|
|
9237
9278
|
], (conf) => {
|
|
@@ -9239,6 +9280,7 @@ const PvCountWidget = (ctx) => {
|
|
|
9239
9280
|
getApi: () => ctx.getApi(),
|
|
9240
9281
|
siteName: conf.site,
|
|
9241
9282
|
pageKey: conf.pageKey,
|
|
9283
|
+
pageTitle: conf.pageTitle,
|
|
9242
9284
|
countEl: conf.countEl,
|
|
9243
9285
|
pvEl: conf.pvEl,
|
|
9244
9286
|
pvAdd: typeof ctx.conf.pvAdd === "boolean" ? ctx.conf.pvAdd : true
|
|
@@ -9250,10 +9292,10 @@ function initCountWidget(opt) {
|
|
|
9250
9292
|
if (opt.countEl && document.querySelector(opt.countEl)) {
|
|
9251
9293
|
refreshStatCount(opt, { query: "page_comment", numEl: opt.countEl });
|
|
9252
9294
|
}
|
|
9253
|
-
const initialData = opt.pvAdd ? {
|
|
9295
|
+
const initialData = opt.pvAdd && opt.pageKey ? {
|
|
9254
9296
|
[opt.pageKey]: (yield opt.getApi().pages.logPv({
|
|
9255
9297
|
page_key: opt.pageKey,
|
|
9256
|
-
page_title: opt.
|
|
9298
|
+
page_title: opt.pageTitle,
|
|
9257
9299
|
site_name: opt.siteName
|
|
9258
9300
|
})).data.pv
|
|
9259
9301
|
// pv+1 and get pv count
|
|
@@ -9270,7 +9312,7 @@ function initCountWidget(opt) {
|
|
|
9270
9312
|
function refreshStatCount(opt, args) {
|
|
9271
9313
|
return __async(this, null, function* () {
|
|
9272
9314
|
let data = args.data || {};
|
|
9273
|
-
let queryPageKeys = Array.from(document.querySelectorAll(args.numEl)).map((e) => e.getAttribute("data-page-key") || opt.pageKey).filter((k) => typeof data[k] !== "number");
|
|
9315
|
+
let queryPageKeys = Array.from(document.querySelectorAll(args.numEl)).map((e) => e.getAttribute("data-page-key") || opt.pageKey).filter((k) => k && typeof data[k] !== "number");
|
|
9274
9316
|
queryPageKeys = [...new Set(queryPageKeys)];
|
|
9275
9317
|
if (queryPageKeys.length > 0) {
|
|
9276
9318
|
const res = (yield opt.getApi().stats.getStats(args.query, {
|
|
@@ -9279,7 +9321,8 @@ function refreshStatCount(opt, args) {
|
|
|
9279
9321
|
})).data.data;
|
|
9280
9322
|
data = __spreadValues(__spreadValues({}, data), res);
|
|
9281
9323
|
}
|
|
9282
|
-
|
|
9324
|
+
const defaultCount = opt.pageKey ? data[opt.pageKey] : 0;
|
|
9325
|
+
applyCountData(args.numEl, data, defaultCount);
|
|
9283
9326
|
});
|
|
9284
9327
|
}
|
|
9285
9328
|
function applyCountData(selector, data, defaultCount) {
|
|
@@ -9468,7 +9511,6 @@ class Artalk {
|
|
|
9468
9511
|
initCountWidget({
|
|
9469
9512
|
getApi: () => new Api2(convertApiOptions(conf)),
|
|
9470
9513
|
siteName: conf.site,
|
|
9471
|
-
pageKey: conf.pageKey,
|
|
9472
9514
|
countEl: conf.countEl,
|
|
9473
9515
|
pvEl: conf.pvEl,
|
|
9474
9516
|
pvAdd: false
|