@haluo/biz 2.0.41-next.0 → 2.0.42-next.0
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/haluo-biz.js +156 -14
- package/dist/haluo-biz.umd.cjs +156 -14
- package/package.json +1 -1
package/dist/haluo-biz.js
CHANGED
|
@@ -4445,6 +4445,9 @@ const _sfc_main$3 = {
|
|
|
4445
4445
|
hasMore: true,
|
|
4446
4446
|
searchPage: 1,
|
|
4447
4447
|
searchHasMore: true,
|
|
4448
|
+
// 用于增量更新的计数器
|
|
4449
|
+
newHotTopicsCount: 0,
|
|
4450
|
+
newSearchTopicsCount: 0,
|
|
4448
4451
|
// 保存原始的selection和range信息
|
|
4449
4452
|
originalRange: null,
|
|
4450
4453
|
originalSelection: null,
|
|
@@ -4484,7 +4487,6 @@ const _sfc_main$3 = {
|
|
|
4484
4487
|
// 话题输入处理
|
|
4485
4488
|
handleTopicInput(event) {
|
|
4486
4489
|
var _a;
|
|
4487
|
-
console.log("handleTopicInput", event.key);
|
|
4488
4490
|
const activeElement = document.activeElement;
|
|
4489
4491
|
if (activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA")) {
|
|
4490
4492
|
return;
|
|
@@ -4538,7 +4540,7 @@ const _sfc_main$3 = {
|
|
|
4538
4540
|
}
|
|
4539
4541
|
},
|
|
4540
4542
|
shouldTriggerSearch(key) {
|
|
4541
|
-
return key
|
|
4543
|
+
return key.length === 1 || key === "Backspace" || key === "Delete";
|
|
4542
4544
|
},
|
|
4543
4545
|
checkAndTriggerSearch(paragraph) {
|
|
4544
4546
|
const selection = window.getSelection();
|
|
@@ -4557,8 +4559,8 @@ const _sfc_main$3 = {
|
|
|
4557
4559
|
const beforeCursor = paragraphText.substring(0, cursorPosition);
|
|
4558
4560
|
const hashIndex = beforeCursor.lastIndexOf("#");
|
|
4559
4561
|
if (hashIndex !== -1) {
|
|
4560
|
-
const afterHash = beforeCursor.substring(hashIndex + 1);
|
|
4561
|
-
if (afterHash.
|
|
4562
|
+
const afterHash = beforeCursor.substring(hashIndex + 1).replace(/\u00A0/g, " ");
|
|
4563
|
+
if (afterHash.indexOf(" ") === -1) {
|
|
4562
4564
|
if (afterHash.length <= 15) {
|
|
4563
4565
|
const position = this.getCaretPosition();
|
|
4564
4566
|
const triggerInfo = {
|
|
@@ -4616,11 +4618,45 @@ const _sfc_main$3 = {
|
|
|
4616
4618
|
if (selection.rangeCount === 0)
|
|
4617
4619
|
return { top: 0, left: 0 };
|
|
4618
4620
|
const range = selection.getRangeAt(0);
|
|
4619
|
-
const
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4621
|
+
const tempElement = document.createElement("span");
|
|
4622
|
+
tempElement.style.position = "absolute";
|
|
4623
|
+
tempElement.style.visibility = "hidden";
|
|
4624
|
+
tempElement.style.pointerEvents = "none";
|
|
4625
|
+
tempElement.style.whiteSpace = "nowrap";
|
|
4626
|
+
tempElement.textContent = "|";
|
|
4627
|
+
try {
|
|
4628
|
+
const clonedRange = range.cloneRange();
|
|
4629
|
+
clonedRange.collapse(true);
|
|
4630
|
+
clonedRange.insertNode(tempElement);
|
|
4631
|
+
const rect = tempElement.getBoundingClientRect();
|
|
4632
|
+
tempElement.remove();
|
|
4633
|
+
const position = {
|
|
4634
|
+
top: rect.bottom,
|
|
4635
|
+
// 弹框显示在光标下方
|
|
4636
|
+
left: rect.left
|
|
4637
|
+
};
|
|
4638
|
+
const viewportWidth = window.innerWidth;
|
|
4639
|
+
const viewportHeight = window.innerHeight;
|
|
4640
|
+
const popoverWidth = 430;
|
|
4641
|
+
const popoverHeight = 286;
|
|
4642
|
+
if (position.left + popoverWidth > viewportWidth) {
|
|
4643
|
+
position.left = Math.max(10, viewportWidth - popoverWidth - 10);
|
|
4644
|
+
}
|
|
4645
|
+
if (position.top + popoverHeight > viewportHeight) {
|
|
4646
|
+
position.top = rect.top - popoverHeight;
|
|
4647
|
+
if (position.top < 0) {
|
|
4648
|
+
position.top = Math.min(rect.bottom, viewportHeight - popoverHeight - 10);
|
|
4649
|
+
}
|
|
4650
|
+
}
|
|
4651
|
+
return position;
|
|
4652
|
+
} catch (error) {
|
|
4653
|
+
console.warn("获取光标位置失败,使用fallback方法:", error);
|
|
4654
|
+
const rect = range.getBoundingClientRect();
|
|
4655
|
+
return {
|
|
4656
|
+
top: rect.bottom,
|
|
4657
|
+
left: Math.max(10, rect.left)
|
|
4658
|
+
};
|
|
4659
|
+
}
|
|
4624
4660
|
},
|
|
4625
4661
|
// 话题弹框相关方法
|
|
4626
4662
|
showTopicPopover(type, position, searchKeyword = "", triggerInfo = null) {
|
|
@@ -4690,7 +4726,8 @@ const _sfc_main$3 = {
|
|
|
4690
4726
|
} else {
|
|
4691
4727
|
const existingIds = new Set(this.topicPopover.hotTopics.map((t) => t.id));
|
|
4692
4728
|
const newTopics = topics.filter((t) => !existingIds.has(t.id));
|
|
4693
|
-
this.topicPopover.
|
|
4729
|
+
this.topicPopover.newHotTopicsCount = newTopics.length;
|
|
4730
|
+
this.topicPopover.hotTopics.push(...newTopics);
|
|
4694
4731
|
this.topicPopover.page++;
|
|
4695
4732
|
if (newTopics.length === 0) {
|
|
4696
4733
|
this.topicPopover.hasMore = false;
|
|
@@ -4705,7 +4742,7 @@ const _sfc_main$3 = {
|
|
|
4705
4742
|
this.topicPopover.hasMore = false;
|
|
4706
4743
|
} finally {
|
|
4707
4744
|
this.topicPopover.loading = false;
|
|
4708
|
-
this.
|
|
4745
|
+
this.appendHotTopicsToDOM();
|
|
4709
4746
|
}
|
|
4710
4747
|
},
|
|
4711
4748
|
async searchTopics(keyword) {
|
|
@@ -4746,6 +4783,45 @@ const _sfc_main$3 = {
|
|
|
4746
4783
|
this.updateGlobalTopicPopover();
|
|
4747
4784
|
}
|
|
4748
4785
|
},
|
|
4786
|
+
// 加载更多搜索话题
|
|
4787
|
+
async loadSearchTopics() {
|
|
4788
|
+
if (this.topicPopover.loading || !this.topicPopover.searchHasMore)
|
|
4789
|
+
return;
|
|
4790
|
+
this.topicPopover.loading = true;
|
|
4791
|
+
try {
|
|
4792
|
+
const response = await this.request.getTopic({
|
|
4793
|
+
action: "201023",
|
|
4794
|
+
title: this.topicPopover.searchKeyword,
|
|
4795
|
+
highlightTitle: "title",
|
|
4796
|
+
page: this.topicPopover.searchPage,
|
|
4797
|
+
limit: 50
|
|
4798
|
+
});
|
|
4799
|
+
if (response && response.data && response.data.code === 0) {
|
|
4800
|
+
const topics = response.data.data || [];
|
|
4801
|
+
if (topics.length === 0) {
|
|
4802
|
+
this.topicPopover.searchHasMore = false;
|
|
4803
|
+
} else {
|
|
4804
|
+
const existingIds = new Set(this.topicPopover.searchTopics.map((t) => t.id));
|
|
4805
|
+
const newTopics = topics.filter((t) => !existingIds.has(t.id));
|
|
4806
|
+
this.topicPopover.newSearchTopicsCount = newTopics.length;
|
|
4807
|
+
this.topicPopover.searchTopics.push(...newTopics);
|
|
4808
|
+
this.topicPopover.searchPage++;
|
|
4809
|
+
if (newTopics.length === 0 || topics.length < 50) {
|
|
4810
|
+
this.topicPopover.searchHasMore = false;
|
|
4811
|
+
}
|
|
4812
|
+
}
|
|
4813
|
+
} else {
|
|
4814
|
+
console.warn("加载更多搜索话题失败:", response);
|
|
4815
|
+
this.topicPopover.searchHasMore = false;
|
|
4816
|
+
}
|
|
4817
|
+
} catch (error) {
|
|
4818
|
+
console.error("加载更多搜索话题失败:", error);
|
|
4819
|
+
this.topicPopover.searchHasMore = false;
|
|
4820
|
+
} finally {
|
|
4821
|
+
this.topicPopover.loading = false;
|
|
4822
|
+
this.appendSearchTopicsToDOM();
|
|
4823
|
+
}
|
|
4824
|
+
},
|
|
4749
4825
|
loadRecentTopics() {
|
|
4750
4826
|
try {
|
|
4751
4827
|
const localTopics = JSON.parse(localStorage.getItem("localTopic") || "[]");
|
|
@@ -4816,6 +4892,72 @@ const _sfc_main$3 = {
|
|
|
4816
4892
|
this.topicPopover.globalContainer.innerHTML = this.createTopicPopoverContent();
|
|
4817
4893
|
this.bindTopicPopoverEvents();
|
|
4818
4894
|
},
|
|
4895
|
+
// 增量添加热门话题到DOM,避免重绘
|
|
4896
|
+
appendHotTopicsToDOM() {
|
|
4897
|
+
if (!this.topicPopover.globalContainer || this.topicPopover.newHotTopicsCount === 0)
|
|
4898
|
+
return;
|
|
4899
|
+
const topicList = this.topicPopover.globalContainer.querySelector(".topic-list");
|
|
4900
|
+
if (!topicList)
|
|
4901
|
+
return;
|
|
4902
|
+
const startIndex = this.topicPopover.hotTopics.length - this.topicPopover.newHotTopicsCount;
|
|
4903
|
+
const endIndex = this.topicPopover.hotTopics.length;
|
|
4904
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
4905
|
+
const topic = this.topicPopover.hotTopics[i];
|
|
4906
|
+
const topicElement = document.createElement("div");
|
|
4907
|
+
topicElement.className = "topic-item";
|
|
4908
|
+
topicElement.setAttribute("data-topic-id", topic.id);
|
|
4909
|
+
topicElement.textContent = `#${topic.title}`;
|
|
4910
|
+
topicElement.addEventListener("click", () => {
|
|
4911
|
+
this.insertTopicToEditor(topic);
|
|
4912
|
+
});
|
|
4913
|
+
topicList.appendChild(topicElement);
|
|
4914
|
+
}
|
|
4915
|
+
this.updateLoadingState(topicList, this.topicPopover.loading, this.topicPopover.hasMore);
|
|
4916
|
+
this.topicPopover.newHotTopicsCount = 0;
|
|
4917
|
+
},
|
|
4918
|
+
// 增量添加搜索话题到DOM,避免重绘
|
|
4919
|
+
appendSearchTopicsToDOM() {
|
|
4920
|
+
if (!this.topicPopover.globalContainer || this.topicPopover.newSearchTopicsCount === 0)
|
|
4921
|
+
return;
|
|
4922
|
+
const topicList = this.topicPopover.globalContainer.querySelector(".topic-list");
|
|
4923
|
+
if (!topicList)
|
|
4924
|
+
return;
|
|
4925
|
+
const startIndex = this.topicPopover.searchTopics.length - this.topicPopover.newSearchTopicsCount;
|
|
4926
|
+
const endIndex = this.topicPopover.searchTopics.length;
|
|
4927
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
4928
|
+
const topic = this.topicPopover.searchTopics[i];
|
|
4929
|
+
const topicElement = document.createElement("div");
|
|
4930
|
+
topicElement.className = "topic-item";
|
|
4931
|
+
topicElement.setAttribute("data-topic-id", topic.id);
|
|
4932
|
+
topicElement.textContent = `#${topic.exactlyMatchTitle || topic.title}`;
|
|
4933
|
+
topicElement.addEventListener("click", () => {
|
|
4934
|
+
this.insertTopicToEditor(topic);
|
|
4935
|
+
});
|
|
4936
|
+
topicList.appendChild(topicElement);
|
|
4937
|
+
}
|
|
4938
|
+
this.updateLoadingState(topicList, this.topicPopover.loading, this.topicPopover.searchHasMore);
|
|
4939
|
+
this.topicPopover.newSearchTopicsCount = 0;
|
|
4940
|
+
},
|
|
4941
|
+
// 更新加载状态显示
|
|
4942
|
+
updateLoadingState(topicList, loading, hasMore) {
|
|
4943
|
+
const existingLoading = topicList.querySelector(".topic-loading");
|
|
4944
|
+
const existingEmpty = topicList.querySelector(".topic-empty");
|
|
4945
|
+
if (existingLoading)
|
|
4946
|
+
existingLoading.remove();
|
|
4947
|
+
if (existingEmpty)
|
|
4948
|
+
existingEmpty.remove();
|
|
4949
|
+
if (loading) {
|
|
4950
|
+
const loadingElement = document.createElement("div");
|
|
4951
|
+
loadingElement.className = "topic-loading";
|
|
4952
|
+
loadingElement.textContent = "加载更多...";
|
|
4953
|
+
topicList.appendChild(loadingElement);
|
|
4954
|
+
} else if (!hasMore) {
|
|
4955
|
+
const emptyElement = document.createElement("div");
|
|
4956
|
+
emptyElement.className = "topic-empty";
|
|
4957
|
+
emptyElement.textContent = "没有更多了";
|
|
4958
|
+
topicList.appendChild(emptyElement);
|
|
4959
|
+
}
|
|
4960
|
+
},
|
|
4819
4961
|
// 创建话题弹框内容
|
|
4820
4962
|
createTopicPopoverContent() {
|
|
4821
4963
|
if (this.topicPopover.type === "hot") {
|
|
@@ -4934,7 +5076,7 @@ const _sfc_main$3 = {
|
|
|
4934
5076
|
if (listContainer) {
|
|
4935
5077
|
listContainer.addEventListener("scroll", (e) => {
|
|
4936
5078
|
if (this.topicPopover.type === "hot") {
|
|
4937
|
-
this.
|
|
5079
|
+
this.handleHotTopicScroll(e);
|
|
4938
5080
|
} else if (this.topicPopover.type === "search") {
|
|
4939
5081
|
this.handleSearchTopicScroll(e);
|
|
4940
5082
|
}
|
|
@@ -4954,7 +5096,7 @@ const _sfc_main$3 = {
|
|
|
4954
5096
|
return topic;
|
|
4955
5097
|
return null;
|
|
4956
5098
|
},
|
|
4957
|
-
|
|
5099
|
+
handleHotTopicScroll(event) {
|
|
4958
5100
|
if (this.topicPopover.activeTab !== "hot")
|
|
4959
5101
|
return;
|
|
4960
5102
|
const container = event.target;
|
|
@@ -4971,7 +5113,7 @@ const _sfc_main$3 = {
|
|
|
4971
5113
|
const scrollHeight = container.scrollHeight;
|
|
4972
5114
|
const clientHeight = container.clientHeight;
|
|
4973
5115
|
if (scrollTop + clientHeight >= scrollHeight - 10) {
|
|
4974
|
-
this.
|
|
5116
|
+
this.loadSearchTopics();
|
|
4975
5117
|
}
|
|
4976
5118
|
},
|
|
4977
5119
|
insertTopicToEditor(topic) {
|
package/dist/haluo-biz.umd.cjs
CHANGED
|
@@ -4444,6 +4444,9 @@
|
|
|
4444
4444
|
hasMore: true,
|
|
4445
4445
|
searchPage: 1,
|
|
4446
4446
|
searchHasMore: true,
|
|
4447
|
+
// 用于增量更新的计数器
|
|
4448
|
+
newHotTopicsCount: 0,
|
|
4449
|
+
newSearchTopicsCount: 0,
|
|
4447
4450
|
// 保存原始的selection和range信息
|
|
4448
4451
|
originalRange: null,
|
|
4449
4452
|
originalSelection: null,
|
|
@@ -4483,7 +4486,6 @@
|
|
|
4483
4486
|
// 话题输入处理
|
|
4484
4487
|
handleTopicInput(event) {
|
|
4485
4488
|
var _a;
|
|
4486
|
-
console.log("handleTopicInput", event.key);
|
|
4487
4489
|
const activeElement = document.activeElement;
|
|
4488
4490
|
if (activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA")) {
|
|
4489
4491
|
return;
|
|
@@ -4537,7 +4539,7 @@
|
|
|
4537
4539
|
}
|
|
4538
4540
|
},
|
|
4539
4541
|
shouldTriggerSearch(key) {
|
|
4540
|
-
return key
|
|
4542
|
+
return key.length === 1 || key === "Backspace" || key === "Delete";
|
|
4541
4543
|
},
|
|
4542
4544
|
checkAndTriggerSearch(paragraph) {
|
|
4543
4545
|
const selection = window.getSelection();
|
|
@@ -4556,8 +4558,8 @@
|
|
|
4556
4558
|
const beforeCursor = paragraphText.substring(0, cursorPosition);
|
|
4557
4559
|
const hashIndex = beforeCursor.lastIndexOf("#");
|
|
4558
4560
|
if (hashIndex !== -1) {
|
|
4559
|
-
const afterHash = beforeCursor.substring(hashIndex + 1);
|
|
4560
|
-
if (afterHash.
|
|
4561
|
+
const afterHash = beforeCursor.substring(hashIndex + 1).replace(/\u00A0/g, " ");
|
|
4562
|
+
if (afterHash.indexOf(" ") === -1) {
|
|
4561
4563
|
if (afterHash.length <= 15) {
|
|
4562
4564
|
const position = this.getCaretPosition();
|
|
4563
4565
|
const triggerInfo = {
|
|
@@ -4615,11 +4617,45 @@
|
|
|
4615
4617
|
if (selection.rangeCount === 0)
|
|
4616
4618
|
return { top: 0, left: 0 };
|
|
4617
4619
|
const range = selection.getRangeAt(0);
|
|
4618
|
-
const
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4620
|
+
const tempElement = document.createElement("span");
|
|
4621
|
+
tempElement.style.position = "absolute";
|
|
4622
|
+
tempElement.style.visibility = "hidden";
|
|
4623
|
+
tempElement.style.pointerEvents = "none";
|
|
4624
|
+
tempElement.style.whiteSpace = "nowrap";
|
|
4625
|
+
tempElement.textContent = "|";
|
|
4626
|
+
try {
|
|
4627
|
+
const clonedRange = range.cloneRange();
|
|
4628
|
+
clonedRange.collapse(true);
|
|
4629
|
+
clonedRange.insertNode(tempElement);
|
|
4630
|
+
const rect = tempElement.getBoundingClientRect();
|
|
4631
|
+
tempElement.remove();
|
|
4632
|
+
const position = {
|
|
4633
|
+
top: rect.bottom,
|
|
4634
|
+
// 弹框显示在光标下方
|
|
4635
|
+
left: rect.left
|
|
4636
|
+
};
|
|
4637
|
+
const viewportWidth = window.innerWidth;
|
|
4638
|
+
const viewportHeight = window.innerHeight;
|
|
4639
|
+
const popoverWidth = 430;
|
|
4640
|
+
const popoverHeight = 286;
|
|
4641
|
+
if (position.left + popoverWidth > viewportWidth) {
|
|
4642
|
+
position.left = Math.max(10, viewportWidth - popoverWidth - 10);
|
|
4643
|
+
}
|
|
4644
|
+
if (position.top + popoverHeight > viewportHeight) {
|
|
4645
|
+
position.top = rect.top - popoverHeight;
|
|
4646
|
+
if (position.top < 0) {
|
|
4647
|
+
position.top = Math.min(rect.bottom, viewportHeight - popoverHeight - 10);
|
|
4648
|
+
}
|
|
4649
|
+
}
|
|
4650
|
+
return position;
|
|
4651
|
+
} catch (error) {
|
|
4652
|
+
console.warn("获取光标位置失败,使用fallback方法:", error);
|
|
4653
|
+
const rect = range.getBoundingClientRect();
|
|
4654
|
+
return {
|
|
4655
|
+
top: rect.bottom,
|
|
4656
|
+
left: Math.max(10, rect.left)
|
|
4657
|
+
};
|
|
4658
|
+
}
|
|
4623
4659
|
},
|
|
4624
4660
|
// 话题弹框相关方法
|
|
4625
4661
|
showTopicPopover(type, position, searchKeyword = "", triggerInfo = null) {
|
|
@@ -4689,7 +4725,8 @@
|
|
|
4689
4725
|
} else {
|
|
4690
4726
|
const existingIds = new Set(this.topicPopover.hotTopics.map((t) => t.id));
|
|
4691
4727
|
const newTopics = topics.filter((t) => !existingIds.has(t.id));
|
|
4692
|
-
this.topicPopover.
|
|
4728
|
+
this.topicPopover.newHotTopicsCount = newTopics.length;
|
|
4729
|
+
this.topicPopover.hotTopics.push(...newTopics);
|
|
4693
4730
|
this.topicPopover.page++;
|
|
4694
4731
|
if (newTopics.length === 0) {
|
|
4695
4732
|
this.topicPopover.hasMore = false;
|
|
@@ -4704,7 +4741,7 @@
|
|
|
4704
4741
|
this.topicPopover.hasMore = false;
|
|
4705
4742
|
} finally {
|
|
4706
4743
|
this.topicPopover.loading = false;
|
|
4707
|
-
this.
|
|
4744
|
+
this.appendHotTopicsToDOM();
|
|
4708
4745
|
}
|
|
4709
4746
|
},
|
|
4710
4747
|
async searchTopics(keyword) {
|
|
@@ -4745,6 +4782,45 @@
|
|
|
4745
4782
|
this.updateGlobalTopicPopover();
|
|
4746
4783
|
}
|
|
4747
4784
|
},
|
|
4785
|
+
// 加载更多搜索话题
|
|
4786
|
+
async loadSearchTopics() {
|
|
4787
|
+
if (this.topicPopover.loading || !this.topicPopover.searchHasMore)
|
|
4788
|
+
return;
|
|
4789
|
+
this.topicPopover.loading = true;
|
|
4790
|
+
try {
|
|
4791
|
+
const response = await this.request.getTopic({
|
|
4792
|
+
action: "201023",
|
|
4793
|
+
title: this.topicPopover.searchKeyword,
|
|
4794
|
+
highlightTitle: "title",
|
|
4795
|
+
page: this.topicPopover.searchPage,
|
|
4796
|
+
limit: 50
|
|
4797
|
+
});
|
|
4798
|
+
if (response && response.data && response.data.code === 0) {
|
|
4799
|
+
const topics = response.data.data || [];
|
|
4800
|
+
if (topics.length === 0) {
|
|
4801
|
+
this.topicPopover.searchHasMore = false;
|
|
4802
|
+
} else {
|
|
4803
|
+
const existingIds = new Set(this.topicPopover.searchTopics.map((t) => t.id));
|
|
4804
|
+
const newTopics = topics.filter((t) => !existingIds.has(t.id));
|
|
4805
|
+
this.topicPopover.newSearchTopicsCount = newTopics.length;
|
|
4806
|
+
this.topicPopover.searchTopics.push(...newTopics);
|
|
4807
|
+
this.topicPopover.searchPage++;
|
|
4808
|
+
if (newTopics.length === 0 || topics.length < 50) {
|
|
4809
|
+
this.topicPopover.searchHasMore = false;
|
|
4810
|
+
}
|
|
4811
|
+
}
|
|
4812
|
+
} else {
|
|
4813
|
+
console.warn("加载更多搜索话题失败:", response);
|
|
4814
|
+
this.topicPopover.searchHasMore = false;
|
|
4815
|
+
}
|
|
4816
|
+
} catch (error) {
|
|
4817
|
+
console.error("加载更多搜索话题失败:", error);
|
|
4818
|
+
this.topicPopover.searchHasMore = false;
|
|
4819
|
+
} finally {
|
|
4820
|
+
this.topicPopover.loading = false;
|
|
4821
|
+
this.appendSearchTopicsToDOM();
|
|
4822
|
+
}
|
|
4823
|
+
},
|
|
4748
4824
|
loadRecentTopics() {
|
|
4749
4825
|
try {
|
|
4750
4826
|
const localTopics = JSON.parse(localStorage.getItem("localTopic") || "[]");
|
|
@@ -4815,6 +4891,72 @@
|
|
|
4815
4891
|
this.topicPopover.globalContainer.innerHTML = this.createTopicPopoverContent();
|
|
4816
4892
|
this.bindTopicPopoverEvents();
|
|
4817
4893
|
},
|
|
4894
|
+
// 增量添加热门话题到DOM,避免重绘
|
|
4895
|
+
appendHotTopicsToDOM() {
|
|
4896
|
+
if (!this.topicPopover.globalContainer || this.topicPopover.newHotTopicsCount === 0)
|
|
4897
|
+
return;
|
|
4898
|
+
const topicList = this.topicPopover.globalContainer.querySelector(".topic-list");
|
|
4899
|
+
if (!topicList)
|
|
4900
|
+
return;
|
|
4901
|
+
const startIndex = this.topicPopover.hotTopics.length - this.topicPopover.newHotTopicsCount;
|
|
4902
|
+
const endIndex = this.topicPopover.hotTopics.length;
|
|
4903
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
4904
|
+
const topic = this.topicPopover.hotTopics[i];
|
|
4905
|
+
const topicElement = document.createElement("div");
|
|
4906
|
+
topicElement.className = "topic-item";
|
|
4907
|
+
topicElement.setAttribute("data-topic-id", topic.id);
|
|
4908
|
+
topicElement.textContent = `#${topic.title}`;
|
|
4909
|
+
topicElement.addEventListener("click", () => {
|
|
4910
|
+
this.insertTopicToEditor(topic);
|
|
4911
|
+
});
|
|
4912
|
+
topicList.appendChild(topicElement);
|
|
4913
|
+
}
|
|
4914
|
+
this.updateLoadingState(topicList, this.topicPopover.loading, this.topicPopover.hasMore);
|
|
4915
|
+
this.topicPopover.newHotTopicsCount = 0;
|
|
4916
|
+
},
|
|
4917
|
+
// 增量添加搜索话题到DOM,避免重绘
|
|
4918
|
+
appendSearchTopicsToDOM() {
|
|
4919
|
+
if (!this.topicPopover.globalContainer || this.topicPopover.newSearchTopicsCount === 0)
|
|
4920
|
+
return;
|
|
4921
|
+
const topicList = this.topicPopover.globalContainer.querySelector(".topic-list");
|
|
4922
|
+
if (!topicList)
|
|
4923
|
+
return;
|
|
4924
|
+
const startIndex = this.topicPopover.searchTopics.length - this.topicPopover.newSearchTopicsCount;
|
|
4925
|
+
const endIndex = this.topicPopover.searchTopics.length;
|
|
4926
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
4927
|
+
const topic = this.topicPopover.searchTopics[i];
|
|
4928
|
+
const topicElement = document.createElement("div");
|
|
4929
|
+
topicElement.className = "topic-item";
|
|
4930
|
+
topicElement.setAttribute("data-topic-id", topic.id);
|
|
4931
|
+
topicElement.textContent = `#${topic.exactlyMatchTitle || topic.title}`;
|
|
4932
|
+
topicElement.addEventListener("click", () => {
|
|
4933
|
+
this.insertTopicToEditor(topic);
|
|
4934
|
+
});
|
|
4935
|
+
topicList.appendChild(topicElement);
|
|
4936
|
+
}
|
|
4937
|
+
this.updateLoadingState(topicList, this.topicPopover.loading, this.topicPopover.searchHasMore);
|
|
4938
|
+
this.topicPopover.newSearchTopicsCount = 0;
|
|
4939
|
+
},
|
|
4940
|
+
// 更新加载状态显示
|
|
4941
|
+
updateLoadingState(topicList, loading, hasMore) {
|
|
4942
|
+
const existingLoading = topicList.querySelector(".topic-loading");
|
|
4943
|
+
const existingEmpty = topicList.querySelector(".topic-empty");
|
|
4944
|
+
if (existingLoading)
|
|
4945
|
+
existingLoading.remove();
|
|
4946
|
+
if (existingEmpty)
|
|
4947
|
+
existingEmpty.remove();
|
|
4948
|
+
if (loading) {
|
|
4949
|
+
const loadingElement = document.createElement("div");
|
|
4950
|
+
loadingElement.className = "topic-loading";
|
|
4951
|
+
loadingElement.textContent = "加载更多...";
|
|
4952
|
+
topicList.appendChild(loadingElement);
|
|
4953
|
+
} else if (!hasMore) {
|
|
4954
|
+
const emptyElement = document.createElement("div");
|
|
4955
|
+
emptyElement.className = "topic-empty";
|
|
4956
|
+
emptyElement.textContent = "没有更多了";
|
|
4957
|
+
topicList.appendChild(emptyElement);
|
|
4958
|
+
}
|
|
4959
|
+
},
|
|
4818
4960
|
// 创建话题弹框内容
|
|
4819
4961
|
createTopicPopoverContent() {
|
|
4820
4962
|
if (this.topicPopover.type === "hot") {
|
|
@@ -4933,7 +5075,7 @@
|
|
|
4933
5075
|
if (listContainer) {
|
|
4934
5076
|
listContainer.addEventListener("scroll", (e) => {
|
|
4935
5077
|
if (this.topicPopover.type === "hot") {
|
|
4936
|
-
this.
|
|
5078
|
+
this.handleHotTopicScroll(e);
|
|
4937
5079
|
} else if (this.topicPopover.type === "search") {
|
|
4938
5080
|
this.handleSearchTopicScroll(e);
|
|
4939
5081
|
}
|
|
@@ -4953,7 +5095,7 @@
|
|
|
4953
5095
|
return topic;
|
|
4954
5096
|
return null;
|
|
4955
5097
|
},
|
|
4956
|
-
|
|
5098
|
+
handleHotTopicScroll(event) {
|
|
4957
5099
|
if (this.topicPopover.activeTab !== "hot")
|
|
4958
5100
|
return;
|
|
4959
5101
|
const container = event.target;
|
|
@@ -4970,7 +5112,7 @@
|
|
|
4970
5112
|
const scrollHeight = container.scrollHeight;
|
|
4971
5113
|
const clientHeight = container.clientHeight;
|
|
4972
5114
|
if (scrollTop + clientHeight >= scrollHeight - 10) {
|
|
4973
|
-
this.
|
|
5115
|
+
this.loadSearchTopics();
|
|
4974
5116
|
}
|
|
4975
5117
|
},
|
|
4976
5118
|
insertTopicToEditor(topic) {
|