artalk 2.2.6 → 2.2.9
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.css +1 -1
- package/dist/Artalk.es.js +282 -121
- package/dist/Artalk.iife.js +1 -1
- package/dist/Artalk.js +1 -1
- package/index.html +10 -8
- package/package.json +2 -2
- package/src/api/index.ts +33 -1
- package/src/artalk.ts +40 -12
- package/src/components/comment.ts +54 -22
- package/src/components/editor-plugs/emoticons-plug.ts +2 -2
- package/src/components/editor-plugs/preview-plug.ts +1 -1
- package/src/components/editor.ts +16 -3
- package/src/components/list-lite.ts +64 -78
- package/src/components/list-nest.ts +66 -0
- package/src/components/list.ts +37 -17
- package/src/components/pagination.ts +1 -1
- package/src/components/sidebar-layer.ts +2 -2
- package/src/context.ts +1 -1
- package/src/defaults.ts +3 -1
- package/src/lib/checker/index.ts +1 -1
- package/src/lib/utils.ts +30 -0
- package/src/style/_color.less +2 -2
- package/src/style/comment.less +21 -0
- package/types/artalk-config.d.ts +5 -2
package/dist/Artalk.es.js
CHANGED
|
@@ -104,7 +104,7 @@ const defaults$3 = {
|
|
|
104
104
|
listSort: true,
|
|
105
105
|
pvEl: "#ArtalkPV",
|
|
106
106
|
flatMode: "auto",
|
|
107
|
-
|
|
107
|
+
nestMax: 3,
|
|
108
108
|
gravatar: {
|
|
109
109
|
default: "mp",
|
|
110
110
|
mirror: "https://sdn.geekzu.org/avatar/"
|
|
@@ -120,7 +120,8 @@ const defaults$3 = {
|
|
|
120
120
|
},
|
|
121
121
|
imgUpload: true,
|
|
122
122
|
reqTimeout: 15e3,
|
|
123
|
-
versionCheck: true
|
|
123
|
+
versionCheck: true,
|
|
124
|
+
useBackendConf: false
|
|
124
125
|
};
|
|
125
126
|
class Component {
|
|
126
127
|
constructor(ctx) {
|
|
@@ -1123,7 +1124,7 @@ function mangle(text) {
|
|
|
1123
1124
|
class Lexer {
|
|
1124
1125
|
constructor(options) {
|
|
1125
1126
|
this.tokens = [];
|
|
1126
|
-
this.tokens.links = Object.create(null);
|
|
1127
|
+
this.tokens.links = /* @__PURE__ */ Object.create(null);
|
|
1127
1128
|
this.options = options || defaults$2;
|
|
1128
1129
|
this.options.tokenizer = this.options.tokenizer || new Tokenizer();
|
|
1129
1130
|
this.tokenizer = this.options.tokenizer;
|
|
@@ -2813,6 +2814,24 @@ function getURLBasedOnApi(ctx, path) {
|
|
|
2813
2814
|
function getURLBasedOn(baseURL, path) {
|
|
2814
2815
|
return `${baseURL.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
|
|
2815
2816
|
}
|
|
2817
|
+
function mergeDeep(target, source) {
|
|
2818
|
+
const isObject = (obj) => obj && typeof obj === "object";
|
|
2819
|
+
if (!isObject(target) || !isObject(source)) {
|
|
2820
|
+
return source;
|
|
2821
|
+
}
|
|
2822
|
+
Object.keys(source).forEach((key) => {
|
|
2823
|
+
const targetValue = target[key];
|
|
2824
|
+
const sourceValue = source[key];
|
|
2825
|
+
if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
|
|
2826
|
+
target[key] = targetValue.concat(sourceValue);
|
|
2827
|
+
} else if (isObject(targetValue) && isObject(sourceValue)) {
|
|
2828
|
+
target[key] = mergeDeep(__spreadValues({}, targetValue), sourceValue);
|
|
2829
|
+
} else {
|
|
2830
|
+
target[key] = sourceValue;
|
|
2831
|
+
}
|
|
2832
|
+
});
|
|
2833
|
+
return target;
|
|
2834
|
+
}
|
|
2816
2835
|
function showLoading(parentElem, conf) {
|
|
2817
2836
|
if (parentElem instanceof Context)
|
|
2818
2837
|
parentElem = parentElem.$root;
|
|
@@ -3434,6 +3453,19 @@ class Api {
|
|
|
3434
3453
|
return json.data || {};
|
|
3435
3454
|
});
|
|
3436
3455
|
}
|
|
3456
|
+
conf() {
|
|
3457
|
+
return __async(this, null, function* () {
|
|
3458
|
+
const data = yield POST(this.ctx, `${this.baseURL}/conf`);
|
|
3459
|
+
const conf = data.frontend_conf || {};
|
|
3460
|
+
if (conf.emoticons && typeof conf.emoticons === "string") {
|
|
3461
|
+
conf.emoticons = conf.emoticons.trim();
|
|
3462
|
+
if (conf.emoticons.startsWith("[") || conf.emoticons.startsWith("{")) {
|
|
3463
|
+
conf.emoticons = JSON.parse(conf.emoticons);
|
|
3464
|
+
}
|
|
3465
|
+
}
|
|
3466
|
+
return conf;
|
|
3467
|
+
});
|
|
3468
|
+
}
|
|
3437
3469
|
captchaGet() {
|
|
3438
3470
|
return __async(this, null, function* () {
|
|
3439
3471
|
const data = yield POST(this.ctx, `${this.baseURL}/captcha/refresh`);
|
|
@@ -3452,6 +3484,14 @@ class Api {
|
|
|
3452
3484
|
return data || { is_pass: false };
|
|
3453
3485
|
});
|
|
3454
3486
|
}
|
|
3487
|
+
cacheFlushAll() {
|
|
3488
|
+
const params = { flush_all: true };
|
|
3489
|
+
return POST(this.ctx, `${this.baseURL}/admin/cache-flush`, params);
|
|
3490
|
+
}
|
|
3491
|
+
cacheWarmUp() {
|
|
3492
|
+
const params = {};
|
|
3493
|
+
return POST(this.ctx, `${this.baseURL}/admin/cache-warm`, params);
|
|
3494
|
+
}
|
|
3455
3495
|
}
|
|
3456
3496
|
const CaptchaChecker = {
|
|
3457
3497
|
request(that, ctx, inputVal) {
|
|
@@ -4005,15 +4045,26 @@ class Editor extends Component {
|
|
|
4005
4045
|
const inputEl = this.getInputEl(field);
|
|
4006
4046
|
if (inputEl && inputEl instanceof HTMLInputElement) {
|
|
4007
4047
|
inputEl.value = this.user.data[field] || "";
|
|
4008
|
-
inputEl.addEventListener("input", () => this.
|
|
4048
|
+
inputEl.addEventListener("input", () => this.onHeaderInput(field, inputEl));
|
|
4009
4049
|
}
|
|
4010
4050
|
});
|
|
4051
|
+
const $linkInput = this.getInputEl("link");
|
|
4052
|
+
if ($linkInput) {
|
|
4053
|
+
$linkInput.addEventListener("change", () => {
|
|
4054
|
+
const link = $linkInput.value.trim();
|
|
4055
|
+
if (!!link && !/^(http|https):\/\//.test(link)) {
|
|
4056
|
+
$linkInput.value = `https://${link}`;
|
|
4057
|
+
this.user.data.link = $linkInput.value;
|
|
4058
|
+
this.saveUser();
|
|
4059
|
+
}
|
|
4060
|
+
});
|
|
4061
|
+
}
|
|
4011
4062
|
}
|
|
4012
4063
|
getInputEl(field) {
|
|
4013
4064
|
const inputEl = this.$header.querySelector(`[name="${field}"]`);
|
|
4014
4065
|
return inputEl;
|
|
4015
4066
|
}
|
|
4016
|
-
|
|
4067
|
+
onHeaderInput(field, inputEl) {
|
|
4017
4068
|
this.user.data[field] = inputEl.value.trim();
|
|
4018
4069
|
if (field === "nick" || field === "email") {
|
|
4019
4070
|
this.user.data.token = "";
|
|
@@ -4707,6 +4758,7 @@ class Comment extends Component {
|
|
|
4707
4758
|
__publicField(this, "data");
|
|
4708
4759
|
__publicField(this, "$main");
|
|
4709
4760
|
__publicField(this, "$header");
|
|
4761
|
+
__publicField(this, "$headerNick");
|
|
4710
4762
|
__publicField(this, "$body");
|
|
4711
4763
|
__publicField(this, "$content");
|
|
4712
4764
|
__publicField(this, "$children");
|
|
@@ -4714,11 +4766,13 @@ class Comment extends Component {
|
|
|
4714
4766
|
__publicField(this, "voteBtnUp");
|
|
4715
4767
|
__publicField(this, "voteBtnDown");
|
|
4716
4768
|
__publicField(this, "parent");
|
|
4717
|
-
__publicField(this, "
|
|
4718
|
-
__publicField(this, "
|
|
4769
|
+
__publicField(this, "nestCurt");
|
|
4770
|
+
__publicField(this, "nestMax");
|
|
4719
4771
|
__publicField(this, "children", []);
|
|
4772
|
+
__publicField(this, "flatMode", false);
|
|
4720
4773
|
__publicField(this, "replyTo");
|
|
4721
4774
|
__publicField(this, "$replyTo");
|
|
4775
|
+
__publicField(this, "$replyAt");
|
|
4722
4776
|
__publicField(this, "afterRender");
|
|
4723
4777
|
__publicField(this, "unread", false);
|
|
4724
4778
|
__publicField(this, "openable", false);
|
|
@@ -4726,11 +4780,11 @@ class Comment extends Component {
|
|
|
4726
4780
|
__publicField(this, "openEvt");
|
|
4727
4781
|
__publicField(this, "onReplyBtnClick");
|
|
4728
4782
|
__publicField(this, "onDelete");
|
|
4729
|
-
this.
|
|
4783
|
+
this.nestMax = ctx.conf.nestMax || 3;
|
|
4730
4784
|
this.data = __spreadValues({}, data);
|
|
4731
4785
|
this.data.date = this.data.date.replace(/-/g, "/");
|
|
4732
4786
|
this.parent = null;
|
|
4733
|
-
this.
|
|
4787
|
+
this.nestCurt = 1;
|
|
4734
4788
|
}
|
|
4735
4789
|
render() {
|
|
4736
4790
|
this.$el = createElement(CommentHTML);
|
|
@@ -4746,6 +4800,7 @@ class Comment extends Component {
|
|
|
4746
4800
|
this.renderAvatar();
|
|
4747
4801
|
this.renderHeader();
|
|
4748
4802
|
this.renderContent();
|
|
4803
|
+
this.renderReplyAt();
|
|
4749
4804
|
this.renderReplyTo();
|
|
4750
4805
|
this.renderPending();
|
|
4751
4806
|
this.renderActionBtn();
|
|
@@ -4788,14 +4843,14 @@ class Comment extends Component {
|
|
|
4788
4843
|
}
|
|
4789
4844
|
}
|
|
4790
4845
|
renderHeader() {
|
|
4791
|
-
|
|
4846
|
+
this.$headerNick = this.$el.querySelector(".atk-nick");
|
|
4792
4847
|
if (this.data.link) {
|
|
4793
4848
|
const $nickA = createElement('<a target="_blank" rel="noreferrer noopener nofollow"></a>');
|
|
4794
4849
|
$nickA.innerText = this.data.nick;
|
|
4795
4850
|
$nickA.href = this.data.link;
|
|
4796
|
-
|
|
4851
|
+
this.$headerNick.append($nickA);
|
|
4797
4852
|
} else {
|
|
4798
|
-
|
|
4853
|
+
this.$headerNick.innerText = this.data.nick;
|
|
4799
4854
|
}
|
|
4800
4855
|
const $badge = this.$el.querySelector(".atk-badge");
|
|
4801
4856
|
if (this.data.badge_name) {
|
|
@@ -4807,7 +4862,7 @@ class Comment extends Component {
|
|
|
4807
4862
|
}
|
|
4808
4863
|
if (this.data.is_pinned) {
|
|
4809
4864
|
const $pinnedBadge = createElement(`<span class="atk-item atk-pinned-badge">\u7F6E\u9876</span>`);
|
|
4810
|
-
|
|
4865
|
+
this.$headerNick.insertAdjacentElement("afterend", $pinnedBadge);
|
|
4811
4866
|
}
|
|
4812
4867
|
const $date = this.$el.querySelector(".atk-date");
|
|
4813
4868
|
$date.innerText = this.getDateFormatted();
|
|
@@ -4850,7 +4905,23 @@ class Comment extends Component {
|
|
|
4850
4905
|
}
|
|
4851
4906
|
});
|
|
4852
4907
|
}
|
|
4908
|
+
renderReplyAt() {
|
|
4909
|
+
if (this.flatMode || this.data.rid === 0)
|
|
4910
|
+
return;
|
|
4911
|
+
if (this.$replyAt)
|
|
4912
|
+
return;
|
|
4913
|
+
if (!this.replyTo)
|
|
4914
|
+
return;
|
|
4915
|
+
this.$replyAt = createElement(`<span class="atk-item atk-reply-at"><span class="atk-arrow"></span><span class="atk-nick"></span></span>`);
|
|
4916
|
+
this.$replyAt.querySelector(".atk-nick").innerText = `${this.replyTo.nick}`;
|
|
4917
|
+
this.$replyAt.onclick = () => {
|
|
4918
|
+
this.goToReplyComment();
|
|
4919
|
+
};
|
|
4920
|
+
this.$headerNick.insertAdjacentElement("afterend", this.$replyAt);
|
|
4921
|
+
}
|
|
4853
4922
|
renderReplyTo() {
|
|
4923
|
+
if (!this.flatMode)
|
|
4924
|
+
return;
|
|
4854
4925
|
if (!this.replyTo)
|
|
4855
4926
|
return;
|
|
4856
4927
|
this.$replyTo = createElement(`
|
|
@@ -4858,13 +4929,24 @@ class Comment extends Component {
|
|
|
4858
4929
|
<div class="atk-meta">\u56DE\u590D <span class="atk-nick"></span>:</div>
|
|
4859
4930
|
<div class="atk-content"></div>
|
|
4860
4931
|
</div>`);
|
|
4861
|
-
this.$replyTo.querySelector(".atk-nick")
|
|
4932
|
+
const $nick = this.$replyTo.querySelector(".atk-nick");
|
|
4933
|
+
$nick.innerText = `@${this.replyTo.nick}`;
|
|
4934
|
+
$nick.onclick = () => {
|
|
4935
|
+
this.goToReplyComment();
|
|
4936
|
+
};
|
|
4862
4937
|
let replyContent = marked(this.ctx, this.replyTo.content);
|
|
4863
4938
|
if (this.replyTo.is_collapsed)
|
|
4864
4939
|
replyContent = "[\u5DF2\u6298\u53E0]";
|
|
4865
4940
|
this.$replyTo.querySelector(".atk-content").innerHTML = replyContent;
|
|
4866
4941
|
this.$body.prepend(this.$replyTo);
|
|
4867
4942
|
}
|
|
4943
|
+
goToReplyComment() {
|
|
4944
|
+
const origHash = window.location.hash;
|
|
4945
|
+
const modifyHash = `#atk-comment-${this.data.rid}`;
|
|
4946
|
+
window.location.hash = modifyHash;
|
|
4947
|
+
if (modifyHash === origHash)
|
|
4948
|
+
window.dispatchEvent(new Event("hashchange"));
|
|
4949
|
+
}
|
|
4868
4950
|
renderPending() {
|
|
4869
4951
|
if (!this.data.is_pending)
|
|
4870
4952
|
return;
|
|
@@ -4959,19 +5041,23 @@ class Comment extends Component {
|
|
|
4959
5041
|
getChildren() {
|
|
4960
5042
|
return this.children;
|
|
4961
5043
|
}
|
|
4962
|
-
putChild(childC) {
|
|
5044
|
+
putChild(childC, insertMode = "append") {
|
|
4963
5045
|
childC.parent = this;
|
|
4964
|
-
childC.
|
|
5046
|
+
childC.nestCurt = this.nestCurt + 1;
|
|
4965
5047
|
this.children.push(childC);
|
|
4966
|
-
this.getChildrenEl()
|
|
5048
|
+
const $children = this.getChildrenEl();
|
|
5049
|
+
if (insertMode === "append")
|
|
5050
|
+
$children.append(childC.getEl());
|
|
5051
|
+
else if (insertMode === "prepend")
|
|
5052
|
+
$children.prepend(childC.getEl());
|
|
4967
5053
|
childC.playFadeInAnim();
|
|
4968
5054
|
childC.checkHeightLimitArea("content");
|
|
4969
5055
|
}
|
|
4970
5056
|
getChildrenEl() {
|
|
4971
|
-
if (this.$children
|
|
4972
|
-
if (this.
|
|
5057
|
+
if (!this.$children) {
|
|
5058
|
+
if (this.nestCurt < this.nestMax) {
|
|
4973
5059
|
this.$children = createElement('<div class="atk-comment-children"></div>');
|
|
4974
|
-
this.$main.
|
|
5060
|
+
this.$main.append(this.$children);
|
|
4975
5061
|
} else if (this.parent) {
|
|
4976
5062
|
this.$children = this.parent.getChildrenEl();
|
|
4977
5063
|
}
|
|
@@ -5170,7 +5256,7 @@ class Pagination {
|
|
|
5170
5256
|
this.$el = createElement(`<div class="atk-pagination-wrap">
|
|
5171
5257
|
<div class="atk-pagination">
|
|
5172
5258
|
<div class="atk-btn atk-btn-prev">Prev</div>
|
|
5173
|
-
<input type="text" class="atk-input" />
|
|
5259
|
+
<input type="text" class="atk-input" aria-label="Enter the number of page" />
|
|
5174
5260
|
<div class="atk-btn atk-btn-next">Next</div>
|
|
5175
5261
|
</div>
|
|
5176
5262
|
</div>`);
|
|
@@ -5349,16 +5435,68 @@ class ReadMoreBtn {
|
|
|
5349
5435
|
this.hide();
|
|
5350
5436
|
}
|
|
5351
5437
|
}
|
|
5352
|
-
|
|
5438
|
+
function makeNestCommentNodeList(srcData, sortBy = "DATE_DESC", nestMax = 2) {
|
|
5439
|
+
const nodeList = [];
|
|
5440
|
+
const roots = srcData.filter((o) => o.rid === 0);
|
|
5441
|
+
roots.forEach((root) => {
|
|
5442
|
+
const rootNode = {
|
|
5443
|
+
id: root.id,
|
|
5444
|
+
comment: root,
|
|
5445
|
+
children: [],
|
|
5446
|
+
level: 1
|
|
5447
|
+
};
|
|
5448
|
+
rootNode.parent = rootNode;
|
|
5449
|
+
nodeList.push(rootNode);
|
|
5450
|
+
(function loadChildren(parentNode) {
|
|
5451
|
+
const children = srcData.filter((o) => o.rid === parentNode.id);
|
|
5452
|
+
if (children.length === 0)
|
|
5453
|
+
return;
|
|
5454
|
+
if (parentNode.level >= nestMax)
|
|
5455
|
+
parentNode = parentNode.parent;
|
|
5456
|
+
children.forEach((child) => {
|
|
5457
|
+
const childNode = {
|
|
5458
|
+
id: child.id,
|
|
5459
|
+
comment: child,
|
|
5460
|
+
children: [],
|
|
5461
|
+
parent: parentNode,
|
|
5462
|
+
level: parentNode.level + 1
|
|
5463
|
+
};
|
|
5464
|
+
parentNode.children.push(childNode);
|
|
5465
|
+
loadChildren(childNode);
|
|
5466
|
+
});
|
|
5467
|
+
})(rootNode);
|
|
5468
|
+
});
|
|
5469
|
+
const sortFunc = (a, b) => {
|
|
5470
|
+
let v = a.id - b.id;
|
|
5471
|
+
if (sortBy === "DATE_ASC")
|
|
5472
|
+
v = +new Date(a.comment.date) - +new Date(b.comment.date);
|
|
5473
|
+
else if (sortBy === "DATE_DESC")
|
|
5474
|
+
v = +new Date(b.comment.date) - +new Date(a.comment.date);
|
|
5475
|
+
else if (sortBy === "SRC_INDEX")
|
|
5476
|
+
v = srcData.indexOf(a.comment) - srcData.indexOf(b.comment);
|
|
5477
|
+
else if (sortBy === "VOTE_UP_DESC")
|
|
5478
|
+
v = b.comment.vote_up - a.comment.vote_up;
|
|
5479
|
+
return v;
|
|
5480
|
+
};
|
|
5481
|
+
(function sortLevels(nodes) {
|
|
5482
|
+
nodes.forEach((node) => {
|
|
5483
|
+
node.children = node.children.sort(sortFunc);
|
|
5484
|
+
sortLevels(node.children);
|
|
5485
|
+
});
|
|
5486
|
+
})(nodeList);
|
|
5487
|
+
return nodeList;
|
|
5488
|
+
}
|
|
5489
|
+
const backendMinVersion = "2.1.4";
|
|
5353
5490
|
class ListLite extends Component {
|
|
5354
5491
|
constructor(ctx) {
|
|
5355
5492
|
super(ctx);
|
|
5356
5493
|
__publicField(this, "$commentsWrap");
|
|
5357
|
-
__publicField(this, "
|
|
5494
|
+
__publicField(this, "commentList", []);
|
|
5358
5495
|
__publicField(this, "data");
|
|
5359
5496
|
__publicField(this, "isLoading", false);
|
|
5360
5497
|
__publicField(this, "noCommentText", "\u65E0\u5185\u5BB9");
|
|
5361
5498
|
__publicField(this, "flatMode", false);
|
|
5499
|
+
__publicField(this, "nestSortBy", "DATE_DESC");
|
|
5362
5500
|
__publicField(this, "pageMode", "pagination");
|
|
5363
5501
|
__publicField(this, "pageSize", 20);
|
|
5364
5502
|
__publicField(this, "scrollListenerAt");
|
|
@@ -5375,6 +5513,8 @@ class ListLite extends Component {
|
|
|
5375
5513
|
<div class="atk-list-comments-wrap"></div>
|
|
5376
5514
|
</div>`);
|
|
5377
5515
|
this.$commentsWrap = this.$el.querySelector(".atk-list-comments-wrap");
|
|
5516
|
+
if (ctx.conf.noComment)
|
|
5517
|
+
this.noCommentText = ctx.conf.noComment;
|
|
5378
5518
|
window.setInterval(() => {
|
|
5379
5519
|
this.$el.querySelectorAll("[data-atk-comment-date]").forEach((el) => {
|
|
5380
5520
|
const date = el.getAttribute("data-atk-comment-date");
|
|
@@ -5383,6 +5523,9 @@ class ListLite extends Component {
|
|
|
5383
5523
|
}, 30 * 1e3);
|
|
5384
5524
|
this.ctx.on("unread-update", (data) => this.updateUnread(data.notifies));
|
|
5385
5525
|
}
|
|
5526
|
+
get commentDataList() {
|
|
5527
|
+
return this.commentList.map((c) => c.data);
|
|
5528
|
+
}
|
|
5386
5529
|
fetchComments(offset) {
|
|
5387
5530
|
return __async(this, null, function* () {
|
|
5388
5531
|
if (this.isLoading)
|
|
@@ -5437,7 +5580,7 @@ class ListLite extends Component {
|
|
|
5437
5580
|
}
|
|
5438
5581
|
this.data = data;
|
|
5439
5582
|
const feMinVersion = ((_a = data.api_version) == null ? void 0 : _a.fe_min_version) || "0.0.0";
|
|
5440
|
-
if (this.ctx.conf.versionCheck && this.versionCheck("\u524D\u7AEF", feMinVersion, "2.2.
|
|
5583
|
+
if (this.ctx.conf.versionCheck && this.versionCheck("\u524D\u7AEF", feMinVersion, "2.2.9"))
|
|
5441
5584
|
return;
|
|
5442
5585
|
if (this.ctx.conf.versionCheck && this.versionCheck("\u540E\u7AEF", backendMinVersion, (_b = data.api_version) == null ? void 0 : _b.version))
|
|
5443
5586
|
return;
|
|
@@ -5548,7 +5691,7 @@ class ListLite extends Component {
|
|
|
5548
5691
|
setError(this.$el, $err);
|
|
5549
5692
|
}
|
|
5550
5693
|
refreshUI() {
|
|
5551
|
-
const isNoComment = this.
|
|
5694
|
+
const isNoComment = this.commentList.length <= 0;
|
|
5552
5695
|
let $noComment = this.$commentsWrap.querySelector(".atk-list-no-comment");
|
|
5553
5696
|
if (isNoComment) {
|
|
5554
5697
|
if (!$noComment) {
|
|
@@ -5561,8 +5704,11 @@ class ListLite extends Component {
|
|
|
5561
5704
|
}
|
|
5562
5705
|
this.ctx.trigger("check-admin-show-el");
|
|
5563
5706
|
}
|
|
5564
|
-
createComment(
|
|
5565
|
-
|
|
5707
|
+
createComment(cData, ctxData) {
|
|
5708
|
+
if (!ctxData)
|
|
5709
|
+
ctxData = this.commentDataList;
|
|
5710
|
+
const comment2 = new Comment(this.ctx, cData);
|
|
5711
|
+
comment2.flatMode = this.flatMode;
|
|
5566
5712
|
comment2.afterRender = () => {
|
|
5567
5713
|
if (this.renderComment)
|
|
5568
5714
|
this.renderComment(comment2);
|
|
@@ -5571,6 +5717,7 @@ class ListLite extends Component {
|
|
|
5571
5717
|
this.deleteComment(c);
|
|
5572
5718
|
this.refreshUI();
|
|
5573
5719
|
};
|
|
5720
|
+
comment2.replyTo = cData.rid ? ctxData.find((c) => c.id === cData.rid) : void 0;
|
|
5574
5721
|
return comment2;
|
|
5575
5722
|
}
|
|
5576
5723
|
importComments(srcData) {
|
|
@@ -5579,44 +5726,37 @@ class ListLite extends Component {
|
|
|
5579
5726
|
this.putCommentFlatMode(commentData, srcData, "append");
|
|
5580
5727
|
});
|
|
5581
5728
|
} else {
|
|
5582
|
-
this.
|
|
5729
|
+
this.importCommentsNest(srcData);
|
|
5583
5730
|
}
|
|
5584
5731
|
}
|
|
5585
|
-
|
|
5586
|
-
const
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
const childC = this.createComment(childData);
|
|
5590
|
-
childC.render();
|
|
5591
|
-
parentC.putChild(childC);
|
|
5592
|
-
loadChildren(childC);
|
|
5593
|
-
});
|
|
5594
|
-
};
|
|
5595
|
-
const rootComments = srcData.filter((o) => o.rid === 0);
|
|
5596
|
-
rootComments.forEach((rootData) => {
|
|
5597
|
-
const rootC = this.createComment(rootData);
|
|
5732
|
+
importCommentsNest(srcData) {
|
|
5733
|
+
const rootNodes = makeNestCommentNodeList(srcData, this.nestSortBy, this.conf.nestMax);
|
|
5734
|
+
rootNodes.forEach((rootNode) => {
|
|
5735
|
+
const rootC = this.createComment(rootNode.comment, srcData);
|
|
5598
5736
|
rootC.render();
|
|
5599
5737
|
this.$commentsWrap.appendChild(rootC.getEl());
|
|
5600
5738
|
rootC.playFadeInAnim();
|
|
5601
|
-
this.
|
|
5602
|
-
|
|
5739
|
+
this.commentList.push(rootC);
|
|
5740
|
+
const that = this;
|
|
5741
|
+
(function loadChildren(parentC, parentNode) {
|
|
5742
|
+
parentNode.children.forEach((node) => {
|
|
5743
|
+
const childD = node.comment;
|
|
5744
|
+
const childC = that.createComment(childD, srcData);
|
|
5745
|
+
childC.render();
|
|
5746
|
+
parentC.putChild(childC);
|
|
5747
|
+
that.commentList.push(childC);
|
|
5748
|
+
loadChildren(childC, node);
|
|
5749
|
+
});
|
|
5750
|
+
})(rootC, rootNode);
|
|
5603
5751
|
rootC.checkHeightLimit();
|
|
5604
5752
|
});
|
|
5605
5753
|
}
|
|
5606
|
-
putCommentFlatMode(cData,
|
|
5754
|
+
putCommentFlatMode(cData, ctxData, insertMode) {
|
|
5607
5755
|
if (cData.is_collapsed)
|
|
5608
5756
|
cData.is_allow_reply = false;
|
|
5609
|
-
const comment2 = this.createComment(cData);
|
|
5610
|
-
if (cData.rid !== 0) {
|
|
5611
|
-
const rComment = srcData.find((o) => o.id === cData.rid);
|
|
5612
|
-
if (rComment)
|
|
5613
|
-
comment2.replyTo = rComment;
|
|
5614
|
-
}
|
|
5757
|
+
const comment2 = this.createComment(cData, ctxData);
|
|
5615
5758
|
comment2.render();
|
|
5616
|
-
|
|
5617
|
-
this.comments.push(comment2);
|
|
5618
|
-
if (insertMode === "prepend")
|
|
5619
|
-
this.comments.unshift(comment2);
|
|
5759
|
+
this.commentList.push(comment2);
|
|
5620
5760
|
if (cData.visible) {
|
|
5621
5761
|
if (insertMode === "append")
|
|
5622
5762
|
this.$commentsWrap.append(comment2.getEl());
|
|
@@ -5630,14 +5770,15 @@ class ListLite extends Component {
|
|
|
5630
5770
|
insertComment(commentData) {
|
|
5631
5771
|
if (!this.flatMode) {
|
|
5632
5772
|
const comment2 = this.createComment(commentData);
|
|
5633
|
-
comment2.render();
|
|
5634
5773
|
if (commentData.rid === 0) {
|
|
5774
|
+
comment2.render();
|
|
5635
5775
|
this.$commentsWrap.prepend(comment2.getEl());
|
|
5636
|
-
this.
|
|
5776
|
+
this.commentList.push(comment2);
|
|
5637
5777
|
} else {
|
|
5638
5778
|
const parent = this.findComment(commentData.rid);
|
|
5639
5779
|
if (parent) {
|
|
5640
|
-
|
|
5780
|
+
comment2.render();
|
|
5781
|
+
parent.putChild(comment2, this.nestSortBy === "DATE_ASC" ? "append" : "prepend");
|
|
5641
5782
|
comment2.getParents().forEach((p) => {
|
|
5642
5783
|
if (p.$children)
|
|
5643
5784
|
p.heightLimitRemove(p.$children);
|
|
@@ -5648,7 +5789,7 @@ class ListLite extends Component {
|
|
|
5648
5789
|
scrollIntoView(comment2.getEl());
|
|
5649
5790
|
comment2.playFadeInAnim();
|
|
5650
5791
|
} else {
|
|
5651
|
-
const comment2 = this.putCommentFlatMode(commentData, this.
|
|
5792
|
+
const comment2 = this.putCommentFlatMode(commentData, this.commentDataList, "prepend");
|
|
5652
5793
|
scrollIntoView(comment2.getEl());
|
|
5653
5794
|
}
|
|
5654
5795
|
if (this.data)
|
|
@@ -5656,45 +5797,20 @@ class ListLite extends Component {
|
|
|
5656
5797
|
this.refreshUI();
|
|
5657
5798
|
this.ctx.trigger("comments-loaded");
|
|
5658
5799
|
}
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
return;
|
|
5662
|
-
commentList.every((item) => {
|
|
5663
|
-
if (action(item, commentList) === false)
|
|
5664
|
-
return false;
|
|
5665
|
-
this.eachComment(item.getChildren(), action);
|
|
5666
|
-
return true;
|
|
5667
|
-
});
|
|
5668
|
-
}
|
|
5669
|
-
findComment(id, src) {
|
|
5670
|
-
if (!src)
|
|
5671
|
-
src = this.comments;
|
|
5672
|
-
let comment2 = null;
|
|
5673
|
-
this.eachComment(src, (item) => {
|
|
5674
|
-
if (item.data.id === id) {
|
|
5675
|
-
comment2 = item;
|
|
5676
|
-
return false;
|
|
5677
|
-
}
|
|
5678
|
-
return true;
|
|
5679
|
-
});
|
|
5680
|
-
return comment2;
|
|
5800
|
+
findComment(id) {
|
|
5801
|
+
return this.commentList.find((c) => c.data.id === id);
|
|
5681
5802
|
}
|
|
5682
|
-
deleteComment(
|
|
5683
|
-
let
|
|
5684
|
-
if (typeof
|
|
5685
|
-
findComment = this.findComment(
|
|
5803
|
+
deleteComment(_comment) {
|
|
5804
|
+
let comment2;
|
|
5805
|
+
if (typeof _comment === "number") {
|
|
5806
|
+
const findComment = this.findComment(_comment);
|
|
5686
5807
|
if (!findComment)
|
|
5687
|
-
throw Error(`\u672A\u627E\u5230\u8BC4\u8BBA ${
|
|
5808
|
+
throw Error(`\u672A\u627E\u5230\u8BC4\u8BBA ${_comment}`);
|
|
5809
|
+
comment2 = findComment;
|
|
5688
5810
|
} else
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
this.
|
|
5692
|
-
if (item === findComment) {
|
|
5693
|
-
levelList.splice(levelList.indexOf(item), 1);
|
|
5694
|
-
return false;
|
|
5695
|
-
}
|
|
5696
|
-
return true;
|
|
5697
|
-
});
|
|
5811
|
+
comment2 = _comment;
|
|
5812
|
+
comment2.getEl().remove();
|
|
5813
|
+
this.commentList.splice(this.commentList.indexOf(comment2), 1);
|
|
5698
5814
|
if (this.data)
|
|
5699
5815
|
this.data.total -= 1;
|
|
5700
5816
|
this.refreshUI();
|
|
@@ -5702,12 +5818,12 @@ class ListLite extends Component {
|
|
|
5702
5818
|
clearAllComments() {
|
|
5703
5819
|
this.$commentsWrap.innerHTML = "";
|
|
5704
5820
|
this.data = void 0;
|
|
5705
|
-
this.
|
|
5821
|
+
this.commentList = [];
|
|
5706
5822
|
}
|
|
5707
5823
|
updateUnread(notifies) {
|
|
5708
5824
|
this.unread = notifies;
|
|
5709
5825
|
if (this.unreadHighlight === true) {
|
|
5710
|
-
this.
|
|
5826
|
+
this.commentList.forEach((comment2) => {
|
|
5711
5827
|
const notify = this.unread.find((o) => o.comment_id === comment2.data.id);
|
|
5712
5828
|
if (notify) {
|
|
5713
5829
|
comment2.setUnread(true);
|
|
@@ -5751,6 +5867,8 @@ class List extends ListLite {
|
|
|
5751
5867
|
__publicField(this, "$unreadBadge");
|
|
5752
5868
|
__publicField(this, "$commentCount");
|
|
5753
5869
|
__publicField(this, "$dropdownWrap");
|
|
5870
|
+
__publicField(this, "goToCommentFounded", false);
|
|
5871
|
+
__publicField(this, "goToCommentDelay", true);
|
|
5754
5872
|
el.querySelector(".atk-list-body").append(this.$el);
|
|
5755
5873
|
this.$el = el;
|
|
5756
5874
|
let flatMode = false;
|
|
@@ -5769,7 +5887,7 @@ class List extends ListLite {
|
|
|
5769
5887
|
if (this.ctx.conf.listSort) {
|
|
5770
5888
|
this.initDropdown();
|
|
5771
5889
|
}
|
|
5772
|
-
this.$el.querySelector(".atk-copyright").innerHTML = `Powered By <a href="https://artalk.js.org" target="_blank" title="Artalk v${"2.2.
|
|
5890
|
+
this.$el.querySelector(".atk-copyright").innerHTML = `Powered By <a href="https://artalk.js.org" target="_blank" title="Artalk v${"2.2.9"}">Artalk</a>`;
|
|
5773
5891
|
this.ctx.on("list-reload", () => this.fetchComments(0));
|
|
5774
5892
|
this.ctx.on("list-refresh-ui", () => this.refreshUI());
|
|
5775
5893
|
this.ctx.on("list-import", (data) => this.importComments(data));
|
|
@@ -5819,36 +5937,55 @@ class List extends ListLite {
|
|
|
5819
5937
|
}
|
|
5820
5938
|
onLoad(data, offset) {
|
|
5821
5939
|
super.onLoad(data, offset);
|
|
5822
|
-
this.
|
|
5940
|
+
if (!this.goToCommentFounded)
|
|
5941
|
+
this.checkGoToCommentByUrlHash();
|
|
5942
|
+
if (this.ctx.conf.editorTravel === true) {
|
|
5943
|
+
this.ctx.trigger("editor-travel-back");
|
|
5944
|
+
}
|
|
5823
5945
|
}
|
|
5824
5946
|
checkGoToCommentByUrlHash() {
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
if (!match || !match[1] || Number.isNaN(Number(match[1])))
|
|
5830
|
-
return;
|
|
5831
|
-
commentId = Number(match[1]);
|
|
5832
|
-
}
|
|
5833
|
-
if (!commentId)
|
|
5947
|
+
let commentId = Number(getQueryParam("atk_comment"));
|
|
5948
|
+
if (!commentId) {
|
|
5949
|
+
const match = window.location.hash.match(/#atk-comment-([0-9]+)/);
|
|
5950
|
+
if (!match || !match[1] || Number.isNaN(Number(match[1])))
|
|
5834
5951
|
return;
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5952
|
+
commentId = Number(match[1]);
|
|
5953
|
+
}
|
|
5954
|
+
if (!commentId)
|
|
5955
|
+
return;
|
|
5956
|
+
const comment2 = this.findComment(commentId);
|
|
5957
|
+
if (!comment2) {
|
|
5958
|
+
if (this.readMoreBtn)
|
|
5959
|
+
this.readMoreBtn.click();
|
|
5960
|
+
else if (this.pagination)
|
|
5961
|
+
this.pagination.next();
|
|
5962
|
+
return;
|
|
5963
|
+
}
|
|
5964
|
+
const notifyKey = getQueryParam("atk_notify_key");
|
|
5965
|
+
if (notifyKey) {
|
|
5966
|
+
new Api(this.ctx).markRead(notifyKey).then(() => {
|
|
5967
|
+
this.unread = this.unread.filter((o) => o.comment_id !== commentId);
|
|
5968
|
+
this.ctx.trigger("unread-update", {
|
|
5969
|
+
notifies: this.unread
|
|
5842
5970
|
});
|
|
5843
|
-
}
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5971
|
+
});
|
|
5972
|
+
}
|
|
5973
|
+
comment2.getParents().forEach((p) => {
|
|
5974
|
+
if (p.$children)
|
|
5975
|
+
p.heightLimitRemove(p.$children);
|
|
5976
|
+
});
|
|
5977
|
+
const goTo = () => {
|
|
5847
5978
|
scrollIntoView(comment2.getEl(), false);
|
|
5979
|
+
comment2.getEl().classList.remove("atk-flash-once");
|
|
5848
5980
|
window.setTimeout(() => {
|
|
5849
5981
|
comment2.getEl().classList.add("atk-flash-once");
|
|
5850
|
-
},
|
|
5851
|
-
}
|
|
5982
|
+
}, 150);
|
|
5983
|
+
};
|
|
5984
|
+
if (!this.goToCommentDelay)
|
|
5985
|
+
goTo();
|
|
5986
|
+
else
|
|
5987
|
+
window.setTimeout(() => goTo(), 350);
|
|
5988
|
+
this.goToCommentFounded = true;
|
|
5852
5989
|
}
|
|
5853
5990
|
adminPageEditSave() {
|
|
5854
5991
|
if (!this.data || !this.data.page)
|
|
@@ -6067,7 +6204,7 @@ const _Artalk = class {
|
|
|
6067
6204
|
__publicField(this, "editor");
|
|
6068
6205
|
__publicField(this, "list");
|
|
6069
6206
|
__publicField(this, "sidebarLayer");
|
|
6070
|
-
this.conf =
|
|
6207
|
+
this.conf = mergeDeep(_Artalk.defaults, customConf);
|
|
6071
6208
|
this.conf.server = this.conf.server.replace(/\/$/, "").replace(/\/api\/?$/, "");
|
|
6072
6209
|
if (!this.conf.pageKey) {
|
|
6073
6210
|
this.conf.pageKey = `${window.location.pathname}`;
|
|
@@ -6091,6 +6228,16 @@ const _Artalk = class {
|
|
|
6091
6228
|
this.ctx = new Context(this.$root, this.conf);
|
|
6092
6229
|
this.$root.classList.add("artalk");
|
|
6093
6230
|
this.$root.innerHTML = "";
|
|
6231
|
+
if (this.conf.useBackendConf) {
|
|
6232
|
+
return (() => __async(this, null, function* () {
|
|
6233
|
+
yield this.loadConfRemote();
|
|
6234
|
+
this.initCore();
|
|
6235
|
+
return this;
|
|
6236
|
+
}))();
|
|
6237
|
+
}
|
|
6238
|
+
this.initCore();
|
|
6239
|
+
}
|
|
6240
|
+
initCore() {
|
|
6094
6241
|
this.initLayer();
|
|
6095
6242
|
this.initDarkMode();
|
|
6096
6243
|
this.checkerLauncher = new CheckerLauncher(this.ctx);
|
|
@@ -6110,8 +6257,22 @@ const _Artalk = class {
|
|
|
6110
6257
|
}
|
|
6111
6258
|
});
|
|
6112
6259
|
}
|
|
6260
|
+
loadConfRemote() {
|
|
6261
|
+
return __async(this, null, function* () {
|
|
6262
|
+
showLoading(this.$root);
|
|
6263
|
+
let backendConf = {};
|
|
6264
|
+
try {
|
|
6265
|
+
backendConf = yield new Api(this.ctx).conf();
|
|
6266
|
+
} catch (err) {
|
|
6267
|
+
console.error("\u914D\u7F6E\u8FDC\u7A0B\u83B7\u53D6\u5931\u8D25", err);
|
|
6268
|
+
}
|
|
6269
|
+
this.ctx.conf = mergeDeep(this.ctx.conf, backendConf);
|
|
6270
|
+
hideLoading(this.$root);
|
|
6271
|
+
});
|
|
6272
|
+
}
|
|
6113
6273
|
initEventBind() {
|
|
6114
6274
|
window.addEventListener("hashchange", () => {
|
|
6275
|
+
this.list.goToCommentDelay = false;
|
|
6115
6276
|
this.list.checkGoToCommentByUrlHash();
|
|
6116
6277
|
});
|
|
6117
6278
|
this.ctx.on("check-admin-show-el", () => {
|