artalk 2.2.7 → 2.2.10
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 +281 -124
- 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 +16 -0
- package/src/artalk.ts +43 -10
- package/src/components/comment.ts +60 -25
- package/src/components/editor.ts +15 -2
- package/src/components/list-lite.ts +60 -77
- package/src/components/list-nest.ts +66 -0
- package/src/components/list.ts +36 -16
- package/src/components/pagination.ts +1 -1
- package/src/defaults.ts +3 -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: 2,
|
|
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) {
|
|
@@ -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`);
|
|
@@ -4013,15 +4045,26 @@ class Editor extends Component {
|
|
|
4013
4045
|
const inputEl = this.getInputEl(field);
|
|
4014
4046
|
if (inputEl && inputEl instanceof HTMLInputElement) {
|
|
4015
4047
|
inputEl.value = this.user.data[field] || "";
|
|
4016
|
-
inputEl.addEventListener("input", () => this.
|
|
4048
|
+
inputEl.addEventListener("input", () => this.onHeaderInput(field, inputEl));
|
|
4017
4049
|
}
|
|
4018
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
|
+
}
|
|
4019
4062
|
}
|
|
4020
4063
|
getInputEl(field) {
|
|
4021
4064
|
const inputEl = this.$header.querySelector(`[name="${field}"]`);
|
|
4022
4065
|
return inputEl;
|
|
4023
4066
|
}
|
|
4024
|
-
|
|
4067
|
+
onHeaderInput(field, inputEl) {
|
|
4025
4068
|
this.user.data[field] = inputEl.value.trim();
|
|
4026
4069
|
if (field === "nick" || field === "email") {
|
|
4027
4070
|
this.user.data.token = "";
|
|
@@ -4715,6 +4758,8 @@ class Comment extends Component {
|
|
|
4715
4758
|
__publicField(this, "data");
|
|
4716
4759
|
__publicField(this, "$main");
|
|
4717
4760
|
__publicField(this, "$header");
|
|
4761
|
+
__publicField(this, "$headerNick");
|
|
4762
|
+
__publicField(this, "$headerBadge");
|
|
4718
4763
|
__publicField(this, "$body");
|
|
4719
4764
|
__publicField(this, "$content");
|
|
4720
4765
|
__publicField(this, "$children");
|
|
@@ -4722,11 +4767,13 @@ class Comment extends Component {
|
|
|
4722
4767
|
__publicField(this, "voteBtnUp");
|
|
4723
4768
|
__publicField(this, "voteBtnDown");
|
|
4724
4769
|
__publicField(this, "parent");
|
|
4725
|
-
__publicField(this, "
|
|
4726
|
-
__publicField(this, "
|
|
4770
|
+
__publicField(this, "nestCurt");
|
|
4771
|
+
__publicField(this, "nestMax");
|
|
4727
4772
|
__publicField(this, "children", []);
|
|
4773
|
+
__publicField(this, "flatMode", false);
|
|
4728
4774
|
__publicField(this, "replyTo");
|
|
4729
4775
|
__publicField(this, "$replyTo");
|
|
4776
|
+
__publicField(this, "$replyAt");
|
|
4730
4777
|
__publicField(this, "afterRender");
|
|
4731
4778
|
__publicField(this, "unread", false);
|
|
4732
4779
|
__publicField(this, "openable", false);
|
|
@@ -4734,11 +4781,11 @@ class Comment extends Component {
|
|
|
4734
4781
|
__publicField(this, "openEvt");
|
|
4735
4782
|
__publicField(this, "onReplyBtnClick");
|
|
4736
4783
|
__publicField(this, "onDelete");
|
|
4737
|
-
this.
|
|
4784
|
+
this.nestMax = ctx.conf.nestMax || 3;
|
|
4738
4785
|
this.data = __spreadValues({}, data);
|
|
4739
4786
|
this.data.date = this.data.date.replace(/-/g, "/");
|
|
4740
4787
|
this.parent = null;
|
|
4741
|
-
this.
|
|
4788
|
+
this.nestCurt = 1;
|
|
4742
4789
|
}
|
|
4743
4790
|
render() {
|
|
4744
4791
|
this.$el = createElement(CommentHTML);
|
|
@@ -4754,6 +4801,7 @@ class Comment extends Component {
|
|
|
4754
4801
|
this.renderAvatar();
|
|
4755
4802
|
this.renderHeader();
|
|
4756
4803
|
this.renderContent();
|
|
4804
|
+
this.renderReplyAt();
|
|
4757
4805
|
this.renderReplyTo();
|
|
4758
4806
|
this.renderPending();
|
|
4759
4807
|
this.renderActionBtn();
|
|
@@ -4796,26 +4844,27 @@ class Comment extends Component {
|
|
|
4796
4844
|
}
|
|
4797
4845
|
}
|
|
4798
4846
|
renderHeader() {
|
|
4799
|
-
|
|
4847
|
+
this.$headerNick = this.$el.querySelector(".atk-nick");
|
|
4800
4848
|
if (this.data.link) {
|
|
4801
4849
|
const $nickA = createElement('<a target="_blank" rel="noreferrer noopener nofollow"></a>');
|
|
4802
4850
|
$nickA.innerText = this.data.nick;
|
|
4803
4851
|
$nickA.href = this.data.link;
|
|
4804
|
-
|
|
4852
|
+
this.$headerNick.append($nickA);
|
|
4805
4853
|
} else {
|
|
4806
|
-
|
|
4854
|
+
this.$headerNick.innerText = this.data.nick;
|
|
4807
4855
|
}
|
|
4808
|
-
|
|
4856
|
+
this.$headerBadge = this.$el.querySelector(".atk-badge");
|
|
4809
4857
|
if (this.data.badge_name) {
|
|
4810
|
-
|
|
4858
|
+
this.$headerBadge.innerText = this.data.badge_name;
|
|
4811
4859
|
if (this.data.badge_color)
|
|
4812
|
-
|
|
4860
|
+
this.$headerBadge.style.backgroundColor = this.data.badge_color;
|
|
4813
4861
|
} else {
|
|
4814
|
-
|
|
4862
|
+
this.$headerBadge.remove();
|
|
4863
|
+
this.$headerBadge = void 0;
|
|
4815
4864
|
}
|
|
4816
4865
|
if (this.data.is_pinned) {
|
|
4817
4866
|
const $pinnedBadge = createElement(`<span class="atk-item atk-pinned-badge">\u7F6E\u9876</span>`);
|
|
4818
|
-
|
|
4867
|
+
this.$headerNick.insertAdjacentElement("afterend", $pinnedBadge);
|
|
4819
4868
|
}
|
|
4820
4869
|
const $date = this.$el.querySelector(".atk-date");
|
|
4821
4870
|
$date.innerText = this.getDateFormatted();
|
|
@@ -4858,7 +4907,24 @@ class Comment extends Component {
|
|
|
4858
4907
|
}
|
|
4859
4908
|
});
|
|
4860
4909
|
}
|
|
4910
|
+
renderReplyAt() {
|
|
4911
|
+
if (this.flatMode || this.data.rid === 0)
|
|
4912
|
+
return;
|
|
4913
|
+
if (this.$replyAt)
|
|
4914
|
+
return;
|
|
4915
|
+
if (!this.replyTo)
|
|
4916
|
+
return;
|
|
4917
|
+
this.$replyAt = createElement(`<span class="atk-item atk-reply-at"><span class="atk-arrow"></span><span class="atk-nick"></span></span>`);
|
|
4918
|
+
this.$replyAt.querySelector(".atk-nick").innerText = `${this.replyTo.nick}`;
|
|
4919
|
+
this.$replyAt.onclick = () => {
|
|
4920
|
+
this.goToReplyComment();
|
|
4921
|
+
};
|
|
4922
|
+
const $after = this.$headerBadge || this.$headerNick;
|
|
4923
|
+
$after.insertAdjacentElement("afterend", this.$replyAt);
|
|
4924
|
+
}
|
|
4861
4925
|
renderReplyTo() {
|
|
4926
|
+
if (!this.flatMode)
|
|
4927
|
+
return;
|
|
4862
4928
|
if (!this.replyTo)
|
|
4863
4929
|
return;
|
|
4864
4930
|
this.$replyTo = createElement(`
|
|
@@ -4866,13 +4932,24 @@ class Comment extends Component {
|
|
|
4866
4932
|
<div class="atk-meta">\u56DE\u590D <span class="atk-nick"></span>:</div>
|
|
4867
4933
|
<div class="atk-content"></div>
|
|
4868
4934
|
</div>`);
|
|
4869
|
-
this.$replyTo.querySelector(".atk-nick")
|
|
4935
|
+
const $nick = this.$replyTo.querySelector(".atk-nick");
|
|
4936
|
+
$nick.innerText = `@${this.replyTo.nick}`;
|
|
4937
|
+
$nick.onclick = () => {
|
|
4938
|
+
this.goToReplyComment();
|
|
4939
|
+
};
|
|
4870
4940
|
let replyContent = marked(this.ctx, this.replyTo.content);
|
|
4871
4941
|
if (this.replyTo.is_collapsed)
|
|
4872
4942
|
replyContent = "[\u5DF2\u6298\u53E0]";
|
|
4873
4943
|
this.$replyTo.querySelector(".atk-content").innerHTML = replyContent;
|
|
4874
4944
|
this.$body.prepend(this.$replyTo);
|
|
4875
4945
|
}
|
|
4946
|
+
goToReplyComment() {
|
|
4947
|
+
const origHash = window.location.hash;
|
|
4948
|
+
const modifyHash = `#atk-comment-${this.data.rid}`;
|
|
4949
|
+
window.location.hash = modifyHash;
|
|
4950
|
+
if (modifyHash === origHash)
|
|
4951
|
+
window.dispatchEvent(new Event("hashchange"));
|
|
4952
|
+
}
|
|
4876
4953
|
renderPending() {
|
|
4877
4954
|
if (!this.data.is_pending)
|
|
4878
4955
|
return;
|
|
@@ -4967,19 +5044,23 @@ class Comment extends Component {
|
|
|
4967
5044
|
getChildren() {
|
|
4968
5045
|
return this.children;
|
|
4969
5046
|
}
|
|
4970
|
-
putChild(childC) {
|
|
5047
|
+
putChild(childC, insertMode = "append") {
|
|
4971
5048
|
childC.parent = this;
|
|
4972
|
-
childC.
|
|
5049
|
+
childC.nestCurt = this.nestCurt + 1;
|
|
4973
5050
|
this.children.push(childC);
|
|
4974
|
-
this.getChildrenEl()
|
|
5051
|
+
const $children = this.getChildrenEl();
|
|
5052
|
+
if (insertMode === "append")
|
|
5053
|
+
$children.append(childC.getEl());
|
|
5054
|
+
else if (insertMode === "prepend")
|
|
5055
|
+
$children.prepend(childC.getEl());
|
|
4975
5056
|
childC.playFadeInAnim();
|
|
4976
5057
|
childC.checkHeightLimitArea("content");
|
|
4977
5058
|
}
|
|
4978
5059
|
getChildrenEl() {
|
|
4979
|
-
if (this.$children
|
|
4980
|
-
if (this.
|
|
5060
|
+
if (!this.$children) {
|
|
5061
|
+
if (this.nestCurt < this.nestMax) {
|
|
4981
5062
|
this.$children = createElement('<div class="atk-comment-children"></div>');
|
|
4982
|
-
this.$main.
|
|
5063
|
+
this.$main.append(this.$children);
|
|
4983
5064
|
} else if (this.parent) {
|
|
4984
5065
|
this.$children = this.parent.getChildrenEl();
|
|
4985
5066
|
}
|
|
@@ -5178,7 +5259,7 @@ class Pagination {
|
|
|
5178
5259
|
this.$el = createElement(`<div class="atk-pagination-wrap">
|
|
5179
5260
|
<div class="atk-pagination">
|
|
5180
5261
|
<div class="atk-btn atk-btn-prev">Prev</div>
|
|
5181
|
-
<input type="text" class="atk-input" />
|
|
5262
|
+
<input type="text" class="atk-input" aria-label="Enter the number of page" />
|
|
5182
5263
|
<div class="atk-btn atk-btn-next">Next</div>
|
|
5183
5264
|
</div>
|
|
5184
5265
|
</div>`);
|
|
@@ -5357,16 +5438,68 @@ class ReadMoreBtn {
|
|
|
5357
5438
|
this.hide();
|
|
5358
5439
|
}
|
|
5359
5440
|
}
|
|
5360
|
-
|
|
5441
|
+
function makeNestCommentNodeList(srcData, sortBy = "DATE_DESC", nestMax = 2) {
|
|
5442
|
+
const nodeList = [];
|
|
5443
|
+
const roots = srcData.filter((o) => o.rid === 0);
|
|
5444
|
+
roots.forEach((root) => {
|
|
5445
|
+
const rootNode = {
|
|
5446
|
+
id: root.id,
|
|
5447
|
+
comment: root,
|
|
5448
|
+
children: [],
|
|
5449
|
+
level: 1
|
|
5450
|
+
};
|
|
5451
|
+
rootNode.parent = rootNode;
|
|
5452
|
+
nodeList.push(rootNode);
|
|
5453
|
+
(function loadChildren(parentNode) {
|
|
5454
|
+
const children = srcData.filter((o) => o.rid === parentNode.id);
|
|
5455
|
+
if (children.length === 0)
|
|
5456
|
+
return;
|
|
5457
|
+
if (parentNode.level >= nestMax)
|
|
5458
|
+
parentNode = parentNode.parent;
|
|
5459
|
+
children.forEach((child) => {
|
|
5460
|
+
const childNode = {
|
|
5461
|
+
id: child.id,
|
|
5462
|
+
comment: child,
|
|
5463
|
+
children: [],
|
|
5464
|
+
parent: parentNode,
|
|
5465
|
+
level: parentNode.level + 1
|
|
5466
|
+
};
|
|
5467
|
+
parentNode.children.push(childNode);
|
|
5468
|
+
loadChildren(childNode);
|
|
5469
|
+
});
|
|
5470
|
+
})(rootNode);
|
|
5471
|
+
});
|
|
5472
|
+
const sortFunc = (a, b) => {
|
|
5473
|
+
let v = a.id - b.id;
|
|
5474
|
+
if (sortBy === "DATE_ASC")
|
|
5475
|
+
v = +new Date(a.comment.date) - +new Date(b.comment.date);
|
|
5476
|
+
else if (sortBy === "DATE_DESC")
|
|
5477
|
+
v = +new Date(b.comment.date) - +new Date(a.comment.date);
|
|
5478
|
+
else if (sortBy === "SRC_INDEX")
|
|
5479
|
+
v = srcData.indexOf(a.comment) - srcData.indexOf(b.comment);
|
|
5480
|
+
else if (sortBy === "VOTE_UP_DESC")
|
|
5481
|
+
v = b.comment.vote_up - a.comment.vote_up;
|
|
5482
|
+
return v;
|
|
5483
|
+
};
|
|
5484
|
+
(function sortLevels(nodes) {
|
|
5485
|
+
nodes.forEach((node) => {
|
|
5486
|
+
node.children = node.children.sort(sortFunc);
|
|
5487
|
+
sortLevels(node.children);
|
|
5488
|
+
});
|
|
5489
|
+
})(nodeList);
|
|
5490
|
+
return nodeList;
|
|
5491
|
+
}
|
|
5492
|
+
const backendMinVersion = "2.1.4";
|
|
5361
5493
|
class ListLite extends Component {
|
|
5362
5494
|
constructor(ctx) {
|
|
5363
5495
|
super(ctx);
|
|
5364
5496
|
__publicField(this, "$commentsWrap");
|
|
5365
|
-
__publicField(this, "
|
|
5497
|
+
__publicField(this, "commentList", []);
|
|
5366
5498
|
__publicField(this, "data");
|
|
5367
5499
|
__publicField(this, "isLoading", false);
|
|
5368
5500
|
__publicField(this, "noCommentText", "\u65E0\u5185\u5BB9");
|
|
5369
5501
|
__publicField(this, "flatMode", false);
|
|
5502
|
+
__publicField(this, "nestSortBy", "DATE_DESC");
|
|
5370
5503
|
__publicField(this, "pageMode", "pagination");
|
|
5371
5504
|
__publicField(this, "pageSize", 20);
|
|
5372
5505
|
__publicField(this, "scrollListenerAt");
|
|
@@ -5393,6 +5526,9 @@ class ListLite extends Component {
|
|
|
5393
5526
|
}, 30 * 1e3);
|
|
5394
5527
|
this.ctx.on("unread-update", (data) => this.updateUnread(data.notifies));
|
|
5395
5528
|
}
|
|
5529
|
+
get commentDataList() {
|
|
5530
|
+
return this.commentList.map((c) => c.data);
|
|
5531
|
+
}
|
|
5396
5532
|
fetchComments(offset) {
|
|
5397
5533
|
return __async(this, null, function* () {
|
|
5398
5534
|
if (this.isLoading)
|
|
@@ -5447,7 +5583,7 @@ class ListLite extends Component {
|
|
|
5447
5583
|
}
|
|
5448
5584
|
this.data = data;
|
|
5449
5585
|
const feMinVersion = ((_a = data.api_version) == null ? void 0 : _a.fe_min_version) || "0.0.0";
|
|
5450
|
-
if (this.ctx.conf.versionCheck && this.versionCheck("\u524D\u7AEF", feMinVersion, "2.2.
|
|
5586
|
+
if (this.ctx.conf.versionCheck && this.versionCheck("\u524D\u7AEF", feMinVersion, "2.2.10"))
|
|
5451
5587
|
return;
|
|
5452
5588
|
if (this.ctx.conf.versionCheck && this.versionCheck("\u540E\u7AEF", backendMinVersion, (_b = data.api_version) == null ? void 0 : _b.version))
|
|
5453
5589
|
return;
|
|
@@ -5558,7 +5694,7 @@ class ListLite extends Component {
|
|
|
5558
5694
|
setError(this.$el, $err);
|
|
5559
5695
|
}
|
|
5560
5696
|
refreshUI() {
|
|
5561
|
-
const isNoComment = this.
|
|
5697
|
+
const isNoComment = this.commentList.length <= 0;
|
|
5562
5698
|
let $noComment = this.$commentsWrap.querySelector(".atk-list-no-comment");
|
|
5563
5699
|
if (isNoComment) {
|
|
5564
5700
|
if (!$noComment) {
|
|
@@ -5571,8 +5707,11 @@ class ListLite extends Component {
|
|
|
5571
5707
|
}
|
|
5572
5708
|
this.ctx.trigger("check-admin-show-el");
|
|
5573
5709
|
}
|
|
5574
|
-
createComment(
|
|
5575
|
-
|
|
5710
|
+
createComment(cData, ctxData) {
|
|
5711
|
+
if (!ctxData)
|
|
5712
|
+
ctxData = this.commentDataList;
|
|
5713
|
+
const comment2 = new Comment(this.ctx, cData);
|
|
5714
|
+
comment2.flatMode = this.flatMode;
|
|
5576
5715
|
comment2.afterRender = () => {
|
|
5577
5716
|
if (this.renderComment)
|
|
5578
5717
|
this.renderComment(comment2);
|
|
@@ -5581,6 +5720,7 @@ class ListLite extends Component {
|
|
|
5581
5720
|
this.deleteComment(c);
|
|
5582
5721
|
this.refreshUI();
|
|
5583
5722
|
};
|
|
5723
|
+
comment2.replyTo = cData.rid ? ctxData.find((c) => c.id === cData.rid) : void 0;
|
|
5584
5724
|
return comment2;
|
|
5585
5725
|
}
|
|
5586
5726
|
importComments(srcData) {
|
|
@@ -5589,44 +5729,37 @@ class ListLite extends Component {
|
|
|
5589
5729
|
this.putCommentFlatMode(commentData, srcData, "append");
|
|
5590
5730
|
});
|
|
5591
5731
|
} else {
|
|
5592
|
-
this.
|
|
5732
|
+
this.importCommentsNest(srcData);
|
|
5593
5733
|
}
|
|
5594
5734
|
}
|
|
5595
|
-
|
|
5596
|
-
const
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
const childC = this.createComment(childData);
|
|
5600
|
-
childC.render();
|
|
5601
|
-
parentC.putChild(childC);
|
|
5602
|
-
loadChildren(childC);
|
|
5603
|
-
});
|
|
5604
|
-
};
|
|
5605
|
-
const rootComments = srcData.filter((o) => o.rid === 0);
|
|
5606
|
-
rootComments.forEach((rootData) => {
|
|
5607
|
-
const rootC = this.createComment(rootData);
|
|
5735
|
+
importCommentsNest(srcData) {
|
|
5736
|
+
const rootNodes = makeNestCommentNodeList(srcData, this.nestSortBy, this.conf.nestMax);
|
|
5737
|
+
rootNodes.forEach((rootNode) => {
|
|
5738
|
+
const rootC = this.createComment(rootNode.comment, srcData);
|
|
5608
5739
|
rootC.render();
|
|
5609
5740
|
this.$commentsWrap.appendChild(rootC.getEl());
|
|
5610
5741
|
rootC.playFadeInAnim();
|
|
5611
|
-
this.
|
|
5612
|
-
|
|
5742
|
+
this.commentList.push(rootC);
|
|
5743
|
+
const that = this;
|
|
5744
|
+
(function loadChildren(parentC, parentNode) {
|
|
5745
|
+
parentNode.children.forEach((node) => {
|
|
5746
|
+
const childD = node.comment;
|
|
5747
|
+
const childC = that.createComment(childD, srcData);
|
|
5748
|
+
childC.render();
|
|
5749
|
+
parentC.putChild(childC);
|
|
5750
|
+
that.commentList.push(childC);
|
|
5751
|
+
loadChildren(childC, node);
|
|
5752
|
+
});
|
|
5753
|
+
})(rootC, rootNode);
|
|
5613
5754
|
rootC.checkHeightLimit();
|
|
5614
5755
|
});
|
|
5615
5756
|
}
|
|
5616
|
-
putCommentFlatMode(cData,
|
|
5757
|
+
putCommentFlatMode(cData, ctxData, insertMode) {
|
|
5617
5758
|
if (cData.is_collapsed)
|
|
5618
5759
|
cData.is_allow_reply = false;
|
|
5619
|
-
const comment2 = this.createComment(cData);
|
|
5620
|
-
if (cData.rid !== 0) {
|
|
5621
|
-
const rComment = srcData.find((o) => o.id === cData.rid);
|
|
5622
|
-
if (rComment)
|
|
5623
|
-
comment2.replyTo = rComment;
|
|
5624
|
-
}
|
|
5760
|
+
const comment2 = this.createComment(cData, ctxData);
|
|
5625
5761
|
comment2.render();
|
|
5626
|
-
|
|
5627
|
-
this.comments.push(comment2);
|
|
5628
|
-
if (insertMode === "prepend")
|
|
5629
|
-
this.comments.unshift(comment2);
|
|
5762
|
+
this.commentList.push(comment2);
|
|
5630
5763
|
if (cData.visible) {
|
|
5631
5764
|
if (insertMode === "append")
|
|
5632
5765
|
this.$commentsWrap.append(comment2.getEl());
|
|
@@ -5640,14 +5773,15 @@ class ListLite extends Component {
|
|
|
5640
5773
|
insertComment(commentData) {
|
|
5641
5774
|
if (!this.flatMode) {
|
|
5642
5775
|
const comment2 = this.createComment(commentData);
|
|
5643
|
-
comment2.render();
|
|
5644
5776
|
if (commentData.rid === 0) {
|
|
5777
|
+
comment2.render();
|
|
5645
5778
|
this.$commentsWrap.prepend(comment2.getEl());
|
|
5646
|
-
this.
|
|
5779
|
+
this.commentList.push(comment2);
|
|
5647
5780
|
} else {
|
|
5648
5781
|
const parent = this.findComment(commentData.rid);
|
|
5649
5782
|
if (parent) {
|
|
5650
|
-
|
|
5783
|
+
comment2.render();
|
|
5784
|
+
parent.putChild(comment2, this.nestSortBy === "DATE_ASC" ? "append" : "prepend");
|
|
5651
5785
|
comment2.getParents().forEach((p) => {
|
|
5652
5786
|
if (p.$children)
|
|
5653
5787
|
p.heightLimitRemove(p.$children);
|
|
@@ -5658,7 +5792,7 @@ class ListLite extends Component {
|
|
|
5658
5792
|
scrollIntoView(comment2.getEl());
|
|
5659
5793
|
comment2.playFadeInAnim();
|
|
5660
5794
|
} else {
|
|
5661
|
-
const comment2 = this.putCommentFlatMode(commentData, this.
|
|
5795
|
+
const comment2 = this.putCommentFlatMode(commentData, this.commentDataList, "prepend");
|
|
5662
5796
|
scrollIntoView(comment2.getEl());
|
|
5663
5797
|
}
|
|
5664
5798
|
if (this.data)
|
|
@@ -5666,45 +5800,20 @@ class ListLite extends Component {
|
|
|
5666
5800
|
this.refreshUI();
|
|
5667
5801
|
this.ctx.trigger("comments-loaded");
|
|
5668
5802
|
}
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
return;
|
|
5672
|
-
commentList.every((item) => {
|
|
5673
|
-
if (action(item, commentList) === false)
|
|
5674
|
-
return false;
|
|
5675
|
-
this.eachComment(item.getChildren(), action);
|
|
5676
|
-
return true;
|
|
5677
|
-
});
|
|
5678
|
-
}
|
|
5679
|
-
findComment(id, src) {
|
|
5680
|
-
if (!src)
|
|
5681
|
-
src = this.comments;
|
|
5682
|
-
let comment2 = null;
|
|
5683
|
-
this.eachComment(src, (item) => {
|
|
5684
|
-
if (item.data.id === id) {
|
|
5685
|
-
comment2 = item;
|
|
5686
|
-
return false;
|
|
5687
|
-
}
|
|
5688
|
-
return true;
|
|
5689
|
-
});
|
|
5690
|
-
return comment2;
|
|
5803
|
+
findComment(id) {
|
|
5804
|
+
return this.commentList.find((c) => c.data.id === id);
|
|
5691
5805
|
}
|
|
5692
|
-
deleteComment(
|
|
5693
|
-
let
|
|
5694
|
-
if (typeof
|
|
5695
|
-
findComment = this.findComment(
|
|
5806
|
+
deleteComment(_comment) {
|
|
5807
|
+
let comment2;
|
|
5808
|
+
if (typeof _comment === "number") {
|
|
5809
|
+
const findComment = this.findComment(_comment);
|
|
5696
5810
|
if (!findComment)
|
|
5697
|
-
throw Error(`\u672A\u627E\u5230\u8BC4\u8BBA ${
|
|
5811
|
+
throw Error(`\u672A\u627E\u5230\u8BC4\u8BBA ${_comment}`);
|
|
5812
|
+
comment2 = findComment;
|
|
5698
5813
|
} else
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
this.
|
|
5702
|
-
if (item === findComment) {
|
|
5703
|
-
levelList.splice(levelList.indexOf(item), 1);
|
|
5704
|
-
return false;
|
|
5705
|
-
}
|
|
5706
|
-
return true;
|
|
5707
|
-
});
|
|
5814
|
+
comment2 = _comment;
|
|
5815
|
+
comment2.getEl().remove();
|
|
5816
|
+
this.commentList.splice(this.commentList.indexOf(comment2), 1);
|
|
5708
5817
|
if (this.data)
|
|
5709
5818
|
this.data.total -= 1;
|
|
5710
5819
|
this.refreshUI();
|
|
@@ -5712,12 +5821,12 @@ class ListLite extends Component {
|
|
|
5712
5821
|
clearAllComments() {
|
|
5713
5822
|
this.$commentsWrap.innerHTML = "";
|
|
5714
5823
|
this.data = void 0;
|
|
5715
|
-
this.
|
|
5824
|
+
this.commentList = [];
|
|
5716
5825
|
}
|
|
5717
5826
|
updateUnread(notifies) {
|
|
5718
5827
|
this.unread = notifies;
|
|
5719
5828
|
if (this.unreadHighlight === true) {
|
|
5720
|
-
this.
|
|
5829
|
+
this.commentList.forEach((comment2) => {
|
|
5721
5830
|
const notify = this.unread.find((o) => o.comment_id === comment2.data.id);
|
|
5722
5831
|
if (notify) {
|
|
5723
5832
|
comment2.setUnread(true);
|
|
@@ -5761,6 +5870,8 @@ class List extends ListLite {
|
|
|
5761
5870
|
__publicField(this, "$unreadBadge");
|
|
5762
5871
|
__publicField(this, "$commentCount");
|
|
5763
5872
|
__publicField(this, "$dropdownWrap");
|
|
5873
|
+
__publicField(this, "goToCommentFounded", false);
|
|
5874
|
+
__publicField(this, "goToCommentDelay", true);
|
|
5764
5875
|
el.querySelector(".atk-list-body").append(this.$el);
|
|
5765
5876
|
this.$el = el;
|
|
5766
5877
|
let flatMode = false;
|
|
@@ -5779,7 +5890,7 @@ class List extends ListLite {
|
|
|
5779
5890
|
if (this.ctx.conf.listSort) {
|
|
5780
5891
|
this.initDropdown();
|
|
5781
5892
|
}
|
|
5782
|
-
this.$el.querySelector(".atk-copyright").innerHTML = `Powered By <a href="https://artalk.js.org" target="_blank" title="Artalk v${"2.2.
|
|
5893
|
+
this.$el.querySelector(".atk-copyright").innerHTML = `Powered By <a href="https://artalk.js.org" target="_blank" title="Artalk v${"2.2.10"}">Artalk</a>`;
|
|
5783
5894
|
this.ctx.on("list-reload", () => this.fetchComments(0));
|
|
5784
5895
|
this.ctx.on("list-refresh-ui", () => this.refreshUI());
|
|
5785
5896
|
this.ctx.on("list-import", (data) => this.importComments(data));
|
|
@@ -5829,36 +5940,55 @@ class List extends ListLite {
|
|
|
5829
5940
|
}
|
|
5830
5941
|
onLoad(data, offset) {
|
|
5831
5942
|
super.onLoad(data, offset);
|
|
5832
|
-
this.
|
|
5943
|
+
if (!this.goToCommentFounded)
|
|
5944
|
+
this.checkGoToCommentByUrlHash();
|
|
5945
|
+
if (this.ctx.conf.editorTravel === true) {
|
|
5946
|
+
this.ctx.trigger("editor-travel-back");
|
|
5947
|
+
}
|
|
5833
5948
|
}
|
|
5834
5949
|
checkGoToCommentByUrlHash() {
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
if (!match || !match[1] || Number.isNaN(Number(match[1])))
|
|
5840
|
-
return;
|
|
5841
|
-
commentId = Number(match[1]);
|
|
5842
|
-
}
|
|
5843
|
-
if (!commentId)
|
|
5950
|
+
let commentId = Number(getQueryParam("atk_comment"));
|
|
5951
|
+
if (!commentId) {
|
|
5952
|
+
const match = window.location.hash.match(/#atk-comment-([0-9]+)/);
|
|
5953
|
+
if (!match || !match[1] || Number.isNaN(Number(match[1])))
|
|
5844
5954
|
return;
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5955
|
+
commentId = Number(match[1]);
|
|
5956
|
+
}
|
|
5957
|
+
if (!commentId)
|
|
5958
|
+
return;
|
|
5959
|
+
const comment2 = this.findComment(commentId);
|
|
5960
|
+
if (!comment2) {
|
|
5961
|
+
if (this.readMoreBtn)
|
|
5962
|
+
this.readMoreBtn.click();
|
|
5963
|
+
else if (this.pagination)
|
|
5964
|
+
this.pagination.next();
|
|
5965
|
+
return;
|
|
5966
|
+
}
|
|
5967
|
+
const notifyKey = getQueryParam("atk_notify_key");
|
|
5968
|
+
if (notifyKey) {
|
|
5969
|
+
new Api(this.ctx).markRead(notifyKey).then(() => {
|
|
5970
|
+
this.unread = this.unread.filter((o) => o.comment_id !== commentId);
|
|
5971
|
+
this.ctx.trigger("unread-update", {
|
|
5972
|
+
notifies: this.unread
|
|
5852
5973
|
});
|
|
5853
|
-
}
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5974
|
+
});
|
|
5975
|
+
}
|
|
5976
|
+
comment2.getParents().forEach((p) => {
|
|
5977
|
+
if (p.$children)
|
|
5978
|
+
p.heightLimitRemove(p.$children);
|
|
5979
|
+
});
|
|
5980
|
+
const goTo = () => {
|
|
5857
5981
|
scrollIntoView(comment2.getEl(), false);
|
|
5982
|
+
comment2.getEl().classList.remove("atk-flash-once");
|
|
5858
5983
|
window.setTimeout(() => {
|
|
5859
5984
|
comment2.getEl().classList.add("atk-flash-once");
|
|
5860
|
-
},
|
|
5861
|
-
}
|
|
5985
|
+
}, 150);
|
|
5986
|
+
};
|
|
5987
|
+
if (!this.goToCommentDelay)
|
|
5988
|
+
goTo();
|
|
5989
|
+
else
|
|
5990
|
+
window.setTimeout(() => goTo(), 350);
|
|
5991
|
+
this.goToCommentFounded = true;
|
|
5862
5992
|
}
|
|
5863
5993
|
adminPageEditSave() {
|
|
5864
5994
|
if (!this.data || !this.data.page)
|
|
@@ -6077,7 +6207,7 @@ const _Artalk = class {
|
|
|
6077
6207
|
__publicField(this, "editor");
|
|
6078
6208
|
__publicField(this, "list");
|
|
6079
6209
|
__publicField(this, "sidebarLayer");
|
|
6080
|
-
this.conf =
|
|
6210
|
+
this.conf = mergeDeep(_Artalk.defaults, customConf);
|
|
6081
6211
|
this.conf.server = this.conf.server.replace(/\/$/, "").replace(/\/api\/?$/, "");
|
|
6082
6212
|
if (!this.conf.pageKey) {
|
|
6083
6213
|
this.conf.pageKey = `${window.location.pathname}`;
|
|
@@ -6085,6 +6215,9 @@ const _Artalk = class {
|
|
|
6085
6215
|
if (!this.conf.pageTitle) {
|
|
6086
6216
|
this.conf.pageTitle = `${document.title}`;
|
|
6087
6217
|
}
|
|
6218
|
+
if (this.conf.nestMax && this.conf.nestMax <= 1) {
|
|
6219
|
+
this.conf.flatMode = true;
|
|
6220
|
+
}
|
|
6088
6221
|
if (!!this.conf.el && this.conf.el instanceof HTMLElement) {
|
|
6089
6222
|
this.$root = this.conf.el;
|
|
6090
6223
|
} else {
|
|
@@ -6101,6 +6234,16 @@ const _Artalk = class {
|
|
|
6101
6234
|
this.ctx = new Context(this.$root, this.conf);
|
|
6102
6235
|
this.$root.classList.add("artalk");
|
|
6103
6236
|
this.$root.innerHTML = "";
|
|
6237
|
+
if (this.conf.useBackendConf) {
|
|
6238
|
+
return (() => __async(this, null, function* () {
|
|
6239
|
+
yield this.loadConfRemote();
|
|
6240
|
+
this.initCore();
|
|
6241
|
+
return this;
|
|
6242
|
+
}))();
|
|
6243
|
+
}
|
|
6244
|
+
this.initCore();
|
|
6245
|
+
}
|
|
6246
|
+
initCore() {
|
|
6104
6247
|
this.initLayer();
|
|
6105
6248
|
this.initDarkMode();
|
|
6106
6249
|
this.checkerLauncher = new CheckerLauncher(this.ctx);
|
|
@@ -6120,8 +6263,22 @@ const _Artalk = class {
|
|
|
6120
6263
|
}
|
|
6121
6264
|
});
|
|
6122
6265
|
}
|
|
6266
|
+
loadConfRemote() {
|
|
6267
|
+
return __async(this, null, function* () {
|
|
6268
|
+
showLoading(this.$root);
|
|
6269
|
+
let backendConf = {};
|
|
6270
|
+
try {
|
|
6271
|
+
backendConf = yield new Api(this.ctx).conf();
|
|
6272
|
+
} catch (err) {
|
|
6273
|
+
console.error("\u914D\u7F6E\u8FDC\u7A0B\u83B7\u53D6\u5931\u8D25", err);
|
|
6274
|
+
}
|
|
6275
|
+
this.ctx.conf = mergeDeep(this.ctx.conf, backendConf);
|
|
6276
|
+
hideLoading(this.$root);
|
|
6277
|
+
});
|
|
6278
|
+
}
|
|
6123
6279
|
initEventBind() {
|
|
6124
6280
|
window.addEventListener("hashchange", () => {
|
|
6281
|
+
this.list.goToCommentDelay = false;
|
|
6125
6282
|
this.list.checkGoToCommentByUrlHash();
|
|
6126
6283
|
});
|
|
6127
6284
|
this.ctx.on("check-admin-show-el", () => {
|