@haluo/biz 2.0.41-next.0 → 2.0.42-next.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/haluo-biz.js +163 -14
- package/dist/haluo-biz.umd.cjs +163 -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,7 @@ const _sfc_main$3 = {
|
|
|
4484
4487
|
// 话题输入处理
|
|
4485
4488
|
handleTopicInput(event) {
|
|
4486
4489
|
var _a;
|
|
4487
|
-
console.log(
|
|
4490
|
+
console.log(111);
|
|
4488
4491
|
const activeElement = document.activeElement;
|
|
4489
4492
|
if (activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA")) {
|
|
4490
4493
|
return;
|
|
@@ -4530,6 +4533,7 @@ const _sfc_main$3 = {
|
|
|
4530
4533
|
this.showTopicPopover("hot", position, "", triggerInfo);
|
|
4531
4534
|
}, 10);
|
|
4532
4535
|
} else if (this.shouldTriggerSearch(event.key)) {
|
|
4536
|
+
console.log(222);
|
|
4533
4537
|
setTimeout(() => {
|
|
4534
4538
|
this.checkAndTriggerSearch(paragraph);
|
|
4535
4539
|
}, 10);
|
|
@@ -4538,12 +4542,13 @@ const _sfc_main$3 = {
|
|
|
4538
4542
|
}
|
|
4539
4543
|
},
|
|
4540
4544
|
shouldTriggerSearch(key) {
|
|
4541
|
-
return key
|
|
4545
|
+
return key.length === 1 || key === "Backspace" || key === "Delete";
|
|
4542
4546
|
},
|
|
4543
4547
|
checkAndTriggerSearch(paragraph) {
|
|
4544
4548
|
const selection = window.getSelection();
|
|
4545
4549
|
if (selection.rangeCount === 0)
|
|
4546
4550
|
return;
|
|
4551
|
+
console.log(333);
|
|
4547
4552
|
const range = selection.getRangeAt(0);
|
|
4548
4553
|
let currentNode = range.startContainer;
|
|
4549
4554
|
while (currentNode && currentNode !== paragraph) {
|
|
@@ -4556,9 +4561,11 @@ const _sfc_main$3 = {
|
|
|
4556
4561
|
const { textContent: paragraphText, cursorPosition } = this.getParagraphTextExcludingTopics(paragraph, range);
|
|
4557
4562
|
const beforeCursor = paragraphText.substring(0, cursorPosition);
|
|
4558
4563
|
const hashIndex = beforeCursor.lastIndexOf("#");
|
|
4564
|
+
console.log("search content", beforeCursor, beforeCursor.substring(hashIndex + 1));
|
|
4559
4565
|
if (hashIndex !== -1) {
|
|
4560
|
-
const afterHash = beforeCursor.substring(hashIndex + 1);
|
|
4561
|
-
|
|
4566
|
+
const afterHash = beforeCursor.substring(hashIndex + 1).replace(/\u00A0/g, " ");
|
|
4567
|
+
console.log(444);
|
|
4568
|
+
if (afterHash.indexOf(" ") === -1) {
|
|
4562
4569
|
if (afterHash.length <= 15) {
|
|
4563
4570
|
const position = this.getCaretPosition();
|
|
4564
4571
|
const triggerInfo = {
|
|
@@ -4566,6 +4573,7 @@ const _sfc_main$3 = {
|
|
|
4566
4573
|
hashIndex,
|
|
4567
4574
|
cursorPosition
|
|
4568
4575
|
};
|
|
4576
|
+
console.log(555);
|
|
4569
4577
|
if (afterHash.length === 0) {
|
|
4570
4578
|
this.showTopicPopover("hot", position, "", triggerInfo);
|
|
4571
4579
|
} else {
|
|
@@ -4616,14 +4624,49 @@ const _sfc_main$3 = {
|
|
|
4616
4624
|
if (selection.rangeCount === 0)
|
|
4617
4625
|
return { top: 0, left: 0 };
|
|
4618
4626
|
const range = selection.getRangeAt(0);
|
|
4619
|
-
const
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4627
|
+
const tempElement = document.createElement("span");
|
|
4628
|
+
tempElement.style.position = "absolute";
|
|
4629
|
+
tempElement.style.visibility = "hidden";
|
|
4630
|
+
tempElement.style.pointerEvents = "none";
|
|
4631
|
+
tempElement.style.whiteSpace = "nowrap";
|
|
4632
|
+
tempElement.textContent = "|";
|
|
4633
|
+
try {
|
|
4634
|
+
const clonedRange = range.cloneRange();
|
|
4635
|
+
clonedRange.collapse(true);
|
|
4636
|
+
clonedRange.insertNode(tempElement);
|
|
4637
|
+
const rect = tempElement.getBoundingClientRect();
|
|
4638
|
+
tempElement.remove();
|
|
4639
|
+
const position = {
|
|
4640
|
+
top: rect.bottom,
|
|
4641
|
+
// 弹框显示在光标下方
|
|
4642
|
+
left: rect.left
|
|
4643
|
+
};
|
|
4644
|
+
const viewportWidth = window.innerWidth;
|
|
4645
|
+
const viewportHeight = window.innerHeight;
|
|
4646
|
+
const popoverWidth = 430;
|
|
4647
|
+
const popoverHeight = 286;
|
|
4648
|
+
if (position.left + popoverWidth > viewportWidth) {
|
|
4649
|
+
position.left = Math.max(10, viewportWidth - popoverWidth - 10);
|
|
4650
|
+
}
|
|
4651
|
+
if (position.top + popoverHeight > viewportHeight) {
|
|
4652
|
+
position.top = rect.top - popoverHeight;
|
|
4653
|
+
if (position.top < 0) {
|
|
4654
|
+
position.top = Math.min(rect.bottom, viewportHeight - popoverHeight - 10);
|
|
4655
|
+
}
|
|
4656
|
+
}
|
|
4657
|
+
return position;
|
|
4658
|
+
} catch (error) {
|
|
4659
|
+
console.warn("获取光标位置失败,使用fallback方法:", error);
|
|
4660
|
+
const rect = range.getBoundingClientRect();
|
|
4661
|
+
return {
|
|
4662
|
+
top: rect.bottom,
|
|
4663
|
+
left: Math.max(10, rect.left)
|
|
4664
|
+
};
|
|
4665
|
+
}
|
|
4624
4666
|
},
|
|
4625
4667
|
// 话题弹框相关方法
|
|
4626
4668
|
showTopicPopover(type, position, searchKeyword = "", triggerInfo = null) {
|
|
4669
|
+
console.log(666);
|
|
4627
4670
|
if (!this.request || !this.request.getTopic) {
|
|
4628
4671
|
console.warn("话题功能需要提供 request.getTopic 方法");
|
|
4629
4672
|
return;
|
|
@@ -4690,7 +4733,8 @@ const _sfc_main$3 = {
|
|
|
4690
4733
|
} else {
|
|
4691
4734
|
const existingIds = new Set(this.topicPopover.hotTopics.map((t) => t.id));
|
|
4692
4735
|
const newTopics = topics.filter((t) => !existingIds.has(t.id));
|
|
4693
|
-
this.topicPopover.
|
|
4736
|
+
this.topicPopover.newHotTopicsCount = newTopics.length;
|
|
4737
|
+
this.topicPopover.hotTopics.push(...newTopics);
|
|
4694
4738
|
this.topicPopover.page++;
|
|
4695
4739
|
if (newTopics.length === 0) {
|
|
4696
4740
|
this.topicPopover.hasMore = false;
|
|
@@ -4705,7 +4749,7 @@ const _sfc_main$3 = {
|
|
|
4705
4749
|
this.topicPopover.hasMore = false;
|
|
4706
4750
|
} finally {
|
|
4707
4751
|
this.topicPopover.loading = false;
|
|
4708
|
-
this.
|
|
4752
|
+
this.appendHotTopicsToDOM();
|
|
4709
4753
|
}
|
|
4710
4754
|
},
|
|
4711
4755
|
async searchTopics(keyword) {
|
|
@@ -4746,6 +4790,45 @@ const _sfc_main$3 = {
|
|
|
4746
4790
|
this.updateGlobalTopicPopover();
|
|
4747
4791
|
}
|
|
4748
4792
|
},
|
|
4793
|
+
// 加载更多搜索话题
|
|
4794
|
+
async loadSearchTopics() {
|
|
4795
|
+
if (this.topicPopover.loading || !this.topicPopover.searchHasMore)
|
|
4796
|
+
return;
|
|
4797
|
+
this.topicPopover.loading = true;
|
|
4798
|
+
try {
|
|
4799
|
+
const response = await this.request.getTopic({
|
|
4800
|
+
action: "201023",
|
|
4801
|
+
title: this.topicPopover.searchKeyword,
|
|
4802
|
+
highlightTitle: "title",
|
|
4803
|
+
page: this.topicPopover.searchPage,
|
|
4804
|
+
limit: 50
|
|
4805
|
+
});
|
|
4806
|
+
if (response && response.data && response.data.code === 0) {
|
|
4807
|
+
const topics = response.data.data || [];
|
|
4808
|
+
if (topics.length === 0) {
|
|
4809
|
+
this.topicPopover.searchHasMore = false;
|
|
4810
|
+
} else {
|
|
4811
|
+
const existingIds = new Set(this.topicPopover.searchTopics.map((t) => t.id));
|
|
4812
|
+
const newTopics = topics.filter((t) => !existingIds.has(t.id));
|
|
4813
|
+
this.topicPopover.newSearchTopicsCount = newTopics.length;
|
|
4814
|
+
this.topicPopover.searchTopics.push(...newTopics);
|
|
4815
|
+
this.topicPopover.searchPage++;
|
|
4816
|
+
if (newTopics.length === 0 || topics.length < 50) {
|
|
4817
|
+
this.topicPopover.searchHasMore = false;
|
|
4818
|
+
}
|
|
4819
|
+
}
|
|
4820
|
+
} else {
|
|
4821
|
+
console.warn("加载更多搜索话题失败:", response);
|
|
4822
|
+
this.topicPopover.searchHasMore = false;
|
|
4823
|
+
}
|
|
4824
|
+
} catch (error) {
|
|
4825
|
+
console.error("加载更多搜索话题失败:", error);
|
|
4826
|
+
this.topicPopover.searchHasMore = false;
|
|
4827
|
+
} finally {
|
|
4828
|
+
this.topicPopover.loading = false;
|
|
4829
|
+
this.appendSearchTopicsToDOM();
|
|
4830
|
+
}
|
|
4831
|
+
},
|
|
4749
4832
|
loadRecentTopics() {
|
|
4750
4833
|
try {
|
|
4751
4834
|
const localTopics = JSON.parse(localStorage.getItem("localTopic") || "[]");
|
|
@@ -4816,6 +4899,72 @@ const _sfc_main$3 = {
|
|
|
4816
4899
|
this.topicPopover.globalContainer.innerHTML = this.createTopicPopoverContent();
|
|
4817
4900
|
this.bindTopicPopoverEvents();
|
|
4818
4901
|
},
|
|
4902
|
+
// 增量添加热门话题到DOM,避免重绘
|
|
4903
|
+
appendHotTopicsToDOM() {
|
|
4904
|
+
if (!this.topicPopover.globalContainer || this.topicPopover.newHotTopicsCount === 0)
|
|
4905
|
+
return;
|
|
4906
|
+
const topicList = this.topicPopover.globalContainer.querySelector(".topic-list");
|
|
4907
|
+
if (!topicList)
|
|
4908
|
+
return;
|
|
4909
|
+
const startIndex = this.topicPopover.hotTopics.length - this.topicPopover.newHotTopicsCount;
|
|
4910
|
+
const endIndex = this.topicPopover.hotTopics.length;
|
|
4911
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
4912
|
+
const topic = this.topicPopover.hotTopics[i];
|
|
4913
|
+
const topicElement = document.createElement("div");
|
|
4914
|
+
topicElement.className = "topic-item";
|
|
4915
|
+
topicElement.setAttribute("data-topic-id", topic.id);
|
|
4916
|
+
topicElement.textContent = `#${topic.title}`;
|
|
4917
|
+
topicElement.addEventListener("click", () => {
|
|
4918
|
+
this.insertTopicToEditor(topic);
|
|
4919
|
+
});
|
|
4920
|
+
topicList.appendChild(topicElement);
|
|
4921
|
+
}
|
|
4922
|
+
this.updateLoadingState(topicList, this.topicPopover.loading, this.topicPopover.hasMore);
|
|
4923
|
+
this.topicPopover.newHotTopicsCount = 0;
|
|
4924
|
+
},
|
|
4925
|
+
// 增量添加搜索话题到DOM,避免重绘
|
|
4926
|
+
appendSearchTopicsToDOM() {
|
|
4927
|
+
if (!this.topicPopover.globalContainer || this.topicPopover.newSearchTopicsCount === 0)
|
|
4928
|
+
return;
|
|
4929
|
+
const topicList = this.topicPopover.globalContainer.querySelector(".topic-list");
|
|
4930
|
+
if (!topicList)
|
|
4931
|
+
return;
|
|
4932
|
+
const startIndex = this.topicPopover.searchTopics.length - this.topicPopover.newSearchTopicsCount;
|
|
4933
|
+
const endIndex = this.topicPopover.searchTopics.length;
|
|
4934
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
4935
|
+
const topic = this.topicPopover.searchTopics[i];
|
|
4936
|
+
const topicElement = document.createElement("div");
|
|
4937
|
+
topicElement.className = "topic-item";
|
|
4938
|
+
topicElement.setAttribute("data-topic-id", topic.id);
|
|
4939
|
+
topicElement.textContent = `#${topic.exactlyMatchTitle || topic.title}`;
|
|
4940
|
+
topicElement.addEventListener("click", () => {
|
|
4941
|
+
this.insertTopicToEditor(topic);
|
|
4942
|
+
});
|
|
4943
|
+
topicList.appendChild(topicElement);
|
|
4944
|
+
}
|
|
4945
|
+
this.updateLoadingState(topicList, this.topicPopover.loading, this.topicPopover.searchHasMore);
|
|
4946
|
+
this.topicPopover.newSearchTopicsCount = 0;
|
|
4947
|
+
},
|
|
4948
|
+
// 更新加载状态显示
|
|
4949
|
+
updateLoadingState(topicList, loading, hasMore) {
|
|
4950
|
+
const existingLoading = topicList.querySelector(".topic-loading");
|
|
4951
|
+
const existingEmpty = topicList.querySelector(".topic-empty");
|
|
4952
|
+
if (existingLoading)
|
|
4953
|
+
existingLoading.remove();
|
|
4954
|
+
if (existingEmpty)
|
|
4955
|
+
existingEmpty.remove();
|
|
4956
|
+
if (loading) {
|
|
4957
|
+
const loadingElement = document.createElement("div");
|
|
4958
|
+
loadingElement.className = "topic-loading";
|
|
4959
|
+
loadingElement.textContent = "加载更多...";
|
|
4960
|
+
topicList.appendChild(loadingElement);
|
|
4961
|
+
} else if (!hasMore) {
|
|
4962
|
+
const emptyElement = document.createElement("div");
|
|
4963
|
+
emptyElement.className = "topic-empty";
|
|
4964
|
+
emptyElement.textContent = "没有更多了";
|
|
4965
|
+
topicList.appendChild(emptyElement);
|
|
4966
|
+
}
|
|
4967
|
+
},
|
|
4819
4968
|
// 创建话题弹框内容
|
|
4820
4969
|
createTopicPopoverContent() {
|
|
4821
4970
|
if (this.topicPopover.type === "hot") {
|
|
@@ -4934,7 +5083,7 @@ const _sfc_main$3 = {
|
|
|
4934
5083
|
if (listContainer) {
|
|
4935
5084
|
listContainer.addEventListener("scroll", (e) => {
|
|
4936
5085
|
if (this.topicPopover.type === "hot") {
|
|
4937
|
-
this.
|
|
5086
|
+
this.handleHotTopicScroll(e);
|
|
4938
5087
|
} else if (this.topicPopover.type === "search") {
|
|
4939
5088
|
this.handleSearchTopicScroll(e);
|
|
4940
5089
|
}
|
|
@@ -4954,7 +5103,7 @@ const _sfc_main$3 = {
|
|
|
4954
5103
|
return topic;
|
|
4955
5104
|
return null;
|
|
4956
5105
|
},
|
|
4957
|
-
|
|
5106
|
+
handleHotTopicScroll(event) {
|
|
4958
5107
|
if (this.topicPopover.activeTab !== "hot")
|
|
4959
5108
|
return;
|
|
4960
5109
|
const container = event.target;
|
|
@@ -4971,7 +5120,7 @@ const _sfc_main$3 = {
|
|
|
4971
5120
|
const scrollHeight = container.scrollHeight;
|
|
4972
5121
|
const clientHeight = container.clientHeight;
|
|
4973
5122
|
if (scrollTop + clientHeight >= scrollHeight - 10) {
|
|
4974
|
-
this.
|
|
5123
|
+
this.loadSearchTopics();
|
|
4975
5124
|
}
|
|
4976
5125
|
},
|
|
4977
5126
|
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,7 @@
|
|
|
4483
4486
|
// 话题输入处理
|
|
4484
4487
|
handleTopicInput(event) {
|
|
4485
4488
|
var _a;
|
|
4486
|
-
console.log(
|
|
4489
|
+
console.log(111);
|
|
4487
4490
|
const activeElement = document.activeElement;
|
|
4488
4491
|
if (activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA")) {
|
|
4489
4492
|
return;
|
|
@@ -4529,6 +4532,7 @@
|
|
|
4529
4532
|
this.showTopicPopover("hot", position, "", triggerInfo);
|
|
4530
4533
|
}, 10);
|
|
4531
4534
|
} else if (this.shouldTriggerSearch(event.key)) {
|
|
4535
|
+
console.log(222);
|
|
4532
4536
|
setTimeout(() => {
|
|
4533
4537
|
this.checkAndTriggerSearch(paragraph);
|
|
4534
4538
|
}, 10);
|
|
@@ -4537,12 +4541,13 @@
|
|
|
4537
4541
|
}
|
|
4538
4542
|
},
|
|
4539
4543
|
shouldTriggerSearch(key) {
|
|
4540
|
-
return key
|
|
4544
|
+
return key.length === 1 || key === "Backspace" || key === "Delete";
|
|
4541
4545
|
},
|
|
4542
4546
|
checkAndTriggerSearch(paragraph) {
|
|
4543
4547
|
const selection = window.getSelection();
|
|
4544
4548
|
if (selection.rangeCount === 0)
|
|
4545
4549
|
return;
|
|
4550
|
+
console.log(333);
|
|
4546
4551
|
const range = selection.getRangeAt(0);
|
|
4547
4552
|
let currentNode = range.startContainer;
|
|
4548
4553
|
while (currentNode && currentNode !== paragraph) {
|
|
@@ -4555,9 +4560,11 @@
|
|
|
4555
4560
|
const { textContent: paragraphText, cursorPosition } = this.getParagraphTextExcludingTopics(paragraph, range);
|
|
4556
4561
|
const beforeCursor = paragraphText.substring(0, cursorPosition);
|
|
4557
4562
|
const hashIndex = beforeCursor.lastIndexOf("#");
|
|
4563
|
+
console.log("search content", beforeCursor, beforeCursor.substring(hashIndex + 1));
|
|
4558
4564
|
if (hashIndex !== -1) {
|
|
4559
|
-
const afterHash = beforeCursor.substring(hashIndex + 1);
|
|
4560
|
-
|
|
4565
|
+
const afterHash = beforeCursor.substring(hashIndex + 1).replace(/\u00A0/g, " ");
|
|
4566
|
+
console.log(444);
|
|
4567
|
+
if (afterHash.indexOf(" ") === -1) {
|
|
4561
4568
|
if (afterHash.length <= 15) {
|
|
4562
4569
|
const position = this.getCaretPosition();
|
|
4563
4570
|
const triggerInfo = {
|
|
@@ -4565,6 +4572,7 @@
|
|
|
4565
4572
|
hashIndex,
|
|
4566
4573
|
cursorPosition
|
|
4567
4574
|
};
|
|
4575
|
+
console.log(555);
|
|
4568
4576
|
if (afterHash.length === 0) {
|
|
4569
4577
|
this.showTopicPopover("hot", position, "", triggerInfo);
|
|
4570
4578
|
} else {
|
|
@@ -4615,14 +4623,49 @@
|
|
|
4615
4623
|
if (selection.rangeCount === 0)
|
|
4616
4624
|
return { top: 0, left: 0 };
|
|
4617
4625
|
const range = selection.getRangeAt(0);
|
|
4618
|
-
const
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4626
|
+
const tempElement = document.createElement("span");
|
|
4627
|
+
tempElement.style.position = "absolute";
|
|
4628
|
+
tempElement.style.visibility = "hidden";
|
|
4629
|
+
tempElement.style.pointerEvents = "none";
|
|
4630
|
+
tempElement.style.whiteSpace = "nowrap";
|
|
4631
|
+
tempElement.textContent = "|";
|
|
4632
|
+
try {
|
|
4633
|
+
const clonedRange = range.cloneRange();
|
|
4634
|
+
clonedRange.collapse(true);
|
|
4635
|
+
clonedRange.insertNode(tempElement);
|
|
4636
|
+
const rect = tempElement.getBoundingClientRect();
|
|
4637
|
+
tempElement.remove();
|
|
4638
|
+
const position = {
|
|
4639
|
+
top: rect.bottom,
|
|
4640
|
+
// 弹框显示在光标下方
|
|
4641
|
+
left: rect.left
|
|
4642
|
+
};
|
|
4643
|
+
const viewportWidth = window.innerWidth;
|
|
4644
|
+
const viewportHeight = window.innerHeight;
|
|
4645
|
+
const popoverWidth = 430;
|
|
4646
|
+
const popoverHeight = 286;
|
|
4647
|
+
if (position.left + popoverWidth > viewportWidth) {
|
|
4648
|
+
position.left = Math.max(10, viewportWidth - popoverWidth - 10);
|
|
4649
|
+
}
|
|
4650
|
+
if (position.top + popoverHeight > viewportHeight) {
|
|
4651
|
+
position.top = rect.top - popoverHeight;
|
|
4652
|
+
if (position.top < 0) {
|
|
4653
|
+
position.top = Math.min(rect.bottom, viewportHeight - popoverHeight - 10);
|
|
4654
|
+
}
|
|
4655
|
+
}
|
|
4656
|
+
return position;
|
|
4657
|
+
} catch (error) {
|
|
4658
|
+
console.warn("获取光标位置失败,使用fallback方法:", error);
|
|
4659
|
+
const rect = range.getBoundingClientRect();
|
|
4660
|
+
return {
|
|
4661
|
+
top: rect.bottom,
|
|
4662
|
+
left: Math.max(10, rect.left)
|
|
4663
|
+
};
|
|
4664
|
+
}
|
|
4623
4665
|
},
|
|
4624
4666
|
// 话题弹框相关方法
|
|
4625
4667
|
showTopicPopover(type, position, searchKeyword = "", triggerInfo = null) {
|
|
4668
|
+
console.log(666);
|
|
4626
4669
|
if (!this.request || !this.request.getTopic) {
|
|
4627
4670
|
console.warn("话题功能需要提供 request.getTopic 方法");
|
|
4628
4671
|
return;
|
|
@@ -4689,7 +4732,8 @@
|
|
|
4689
4732
|
} else {
|
|
4690
4733
|
const existingIds = new Set(this.topicPopover.hotTopics.map((t) => t.id));
|
|
4691
4734
|
const newTopics = topics.filter((t) => !existingIds.has(t.id));
|
|
4692
|
-
this.topicPopover.
|
|
4735
|
+
this.topicPopover.newHotTopicsCount = newTopics.length;
|
|
4736
|
+
this.topicPopover.hotTopics.push(...newTopics);
|
|
4693
4737
|
this.topicPopover.page++;
|
|
4694
4738
|
if (newTopics.length === 0) {
|
|
4695
4739
|
this.topicPopover.hasMore = false;
|
|
@@ -4704,7 +4748,7 @@
|
|
|
4704
4748
|
this.topicPopover.hasMore = false;
|
|
4705
4749
|
} finally {
|
|
4706
4750
|
this.topicPopover.loading = false;
|
|
4707
|
-
this.
|
|
4751
|
+
this.appendHotTopicsToDOM();
|
|
4708
4752
|
}
|
|
4709
4753
|
},
|
|
4710
4754
|
async searchTopics(keyword) {
|
|
@@ -4745,6 +4789,45 @@
|
|
|
4745
4789
|
this.updateGlobalTopicPopover();
|
|
4746
4790
|
}
|
|
4747
4791
|
},
|
|
4792
|
+
// 加载更多搜索话题
|
|
4793
|
+
async loadSearchTopics() {
|
|
4794
|
+
if (this.topicPopover.loading || !this.topicPopover.searchHasMore)
|
|
4795
|
+
return;
|
|
4796
|
+
this.topicPopover.loading = true;
|
|
4797
|
+
try {
|
|
4798
|
+
const response = await this.request.getTopic({
|
|
4799
|
+
action: "201023",
|
|
4800
|
+
title: this.topicPopover.searchKeyword,
|
|
4801
|
+
highlightTitle: "title",
|
|
4802
|
+
page: this.topicPopover.searchPage,
|
|
4803
|
+
limit: 50
|
|
4804
|
+
});
|
|
4805
|
+
if (response && response.data && response.data.code === 0) {
|
|
4806
|
+
const topics = response.data.data || [];
|
|
4807
|
+
if (topics.length === 0) {
|
|
4808
|
+
this.topicPopover.searchHasMore = false;
|
|
4809
|
+
} else {
|
|
4810
|
+
const existingIds = new Set(this.topicPopover.searchTopics.map((t) => t.id));
|
|
4811
|
+
const newTopics = topics.filter((t) => !existingIds.has(t.id));
|
|
4812
|
+
this.topicPopover.newSearchTopicsCount = newTopics.length;
|
|
4813
|
+
this.topicPopover.searchTopics.push(...newTopics);
|
|
4814
|
+
this.topicPopover.searchPage++;
|
|
4815
|
+
if (newTopics.length === 0 || topics.length < 50) {
|
|
4816
|
+
this.topicPopover.searchHasMore = false;
|
|
4817
|
+
}
|
|
4818
|
+
}
|
|
4819
|
+
} else {
|
|
4820
|
+
console.warn("加载更多搜索话题失败:", response);
|
|
4821
|
+
this.topicPopover.searchHasMore = false;
|
|
4822
|
+
}
|
|
4823
|
+
} catch (error) {
|
|
4824
|
+
console.error("加载更多搜索话题失败:", error);
|
|
4825
|
+
this.topicPopover.searchHasMore = false;
|
|
4826
|
+
} finally {
|
|
4827
|
+
this.topicPopover.loading = false;
|
|
4828
|
+
this.appendSearchTopicsToDOM();
|
|
4829
|
+
}
|
|
4830
|
+
},
|
|
4748
4831
|
loadRecentTopics() {
|
|
4749
4832
|
try {
|
|
4750
4833
|
const localTopics = JSON.parse(localStorage.getItem("localTopic") || "[]");
|
|
@@ -4815,6 +4898,72 @@
|
|
|
4815
4898
|
this.topicPopover.globalContainer.innerHTML = this.createTopicPopoverContent();
|
|
4816
4899
|
this.bindTopicPopoverEvents();
|
|
4817
4900
|
},
|
|
4901
|
+
// 增量添加热门话题到DOM,避免重绘
|
|
4902
|
+
appendHotTopicsToDOM() {
|
|
4903
|
+
if (!this.topicPopover.globalContainer || this.topicPopover.newHotTopicsCount === 0)
|
|
4904
|
+
return;
|
|
4905
|
+
const topicList = this.topicPopover.globalContainer.querySelector(".topic-list");
|
|
4906
|
+
if (!topicList)
|
|
4907
|
+
return;
|
|
4908
|
+
const startIndex = this.topicPopover.hotTopics.length - this.topicPopover.newHotTopicsCount;
|
|
4909
|
+
const endIndex = this.topicPopover.hotTopics.length;
|
|
4910
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
4911
|
+
const topic = this.topicPopover.hotTopics[i];
|
|
4912
|
+
const topicElement = document.createElement("div");
|
|
4913
|
+
topicElement.className = "topic-item";
|
|
4914
|
+
topicElement.setAttribute("data-topic-id", topic.id);
|
|
4915
|
+
topicElement.textContent = `#${topic.title}`;
|
|
4916
|
+
topicElement.addEventListener("click", () => {
|
|
4917
|
+
this.insertTopicToEditor(topic);
|
|
4918
|
+
});
|
|
4919
|
+
topicList.appendChild(topicElement);
|
|
4920
|
+
}
|
|
4921
|
+
this.updateLoadingState(topicList, this.topicPopover.loading, this.topicPopover.hasMore);
|
|
4922
|
+
this.topicPopover.newHotTopicsCount = 0;
|
|
4923
|
+
},
|
|
4924
|
+
// 增量添加搜索话题到DOM,避免重绘
|
|
4925
|
+
appendSearchTopicsToDOM() {
|
|
4926
|
+
if (!this.topicPopover.globalContainer || this.topicPopover.newSearchTopicsCount === 0)
|
|
4927
|
+
return;
|
|
4928
|
+
const topicList = this.topicPopover.globalContainer.querySelector(".topic-list");
|
|
4929
|
+
if (!topicList)
|
|
4930
|
+
return;
|
|
4931
|
+
const startIndex = this.topicPopover.searchTopics.length - this.topicPopover.newSearchTopicsCount;
|
|
4932
|
+
const endIndex = this.topicPopover.searchTopics.length;
|
|
4933
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
4934
|
+
const topic = this.topicPopover.searchTopics[i];
|
|
4935
|
+
const topicElement = document.createElement("div");
|
|
4936
|
+
topicElement.className = "topic-item";
|
|
4937
|
+
topicElement.setAttribute("data-topic-id", topic.id);
|
|
4938
|
+
topicElement.textContent = `#${topic.exactlyMatchTitle || topic.title}`;
|
|
4939
|
+
topicElement.addEventListener("click", () => {
|
|
4940
|
+
this.insertTopicToEditor(topic);
|
|
4941
|
+
});
|
|
4942
|
+
topicList.appendChild(topicElement);
|
|
4943
|
+
}
|
|
4944
|
+
this.updateLoadingState(topicList, this.topicPopover.loading, this.topicPopover.searchHasMore);
|
|
4945
|
+
this.topicPopover.newSearchTopicsCount = 0;
|
|
4946
|
+
},
|
|
4947
|
+
// 更新加载状态显示
|
|
4948
|
+
updateLoadingState(topicList, loading, hasMore) {
|
|
4949
|
+
const existingLoading = topicList.querySelector(".topic-loading");
|
|
4950
|
+
const existingEmpty = topicList.querySelector(".topic-empty");
|
|
4951
|
+
if (existingLoading)
|
|
4952
|
+
existingLoading.remove();
|
|
4953
|
+
if (existingEmpty)
|
|
4954
|
+
existingEmpty.remove();
|
|
4955
|
+
if (loading) {
|
|
4956
|
+
const loadingElement = document.createElement("div");
|
|
4957
|
+
loadingElement.className = "topic-loading";
|
|
4958
|
+
loadingElement.textContent = "加载更多...";
|
|
4959
|
+
topicList.appendChild(loadingElement);
|
|
4960
|
+
} else if (!hasMore) {
|
|
4961
|
+
const emptyElement = document.createElement("div");
|
|
4962
|
+
emptyElement.className = "topic-empty";
|
|
4963
|
+
emptyElement.textContent = "没有更多了";
|
|
4964
|
+
topicList.appendChild(emptyElement);
|
|
4965
|
+
}
|
|
4966
|
+
},
|
|
4818
4967
|
// 创建话题弹框内容
|
|
4819
4968
|
createTopicPopoverContent() {
|
|
4820
4969
|
if (this.topicPopover.type === "hot") {
|
|
@@ -4933,7 +5082,7 @@
|
|
|
4933
5082
|
if (listContainer) {
|
|
4934
5083
|
listContainer.addEventListener("scroll", (e) => {
|
|
4935
5084
|
if (this.topicPopover.type === "hot") {
|
|
4936
|
-
this.
|
|
5085
|
+
this.handleHotTopicScroll(e);
|
|
4937
5086
|
} else if (this.topicPopover.type === "search") {
|
|
4938
5087
|
this.handleSearchTopicScroll(e);
|
|
4939
5088
|
}
|
|
@@ -4953,7 +5102,7 @@
|
|
|
4953
5102
|
return topic;
|
|
4954
5103
|
return null;
|
|
4955
5104
|
},
|
|
4956
|
-
|
|
5105
|
+
handleHotTopicScroll(event) {
|
|
4957
5106
|
if (this.topicPopover.activeTab !== "hot")
|
|
4958
5107
|
return;
|
|
4959
5108
|
const container = event.target;
|
|
@@ -4970,7 +5119,7 @@
|
|
|
4970
5119
|
const scrollHeight = container.scrollHeight;
|
|
4971
5120
|
const clientHeight = container.clientHeight;
|
|
4972
5121
|
if (scrollTop + clientHeight >= scrollHeight - 10) {
|
|
4973
|
-
this.
|
|
5122
|
+
this.loadSearchTopics();
|
|
4974
5123
|
}
|
|
4975
5124
|
},
|
|
4976
5125
|
insertTopicToEditor(topic) {
|