@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 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("handleTopicInput", event.key);
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 !== " " && key.length === 1 || key === "Backspace" || key === "Delete";
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
- if (afterHash.replace(/\u00A0/g, " ").indexOf(" ") === -1) {
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 rect = range.getBoundingClientRect();
4620
- return {
4621
- top: rect.bottom + window.scrollY,
4622
- left: rect.left + window.scrollX
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.hotTopics = [...this.topicPopover.hotTopics, ...newTopics];
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.updateGlobalTopicPopover();
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.handleTopicScroll(e);
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
- handleTopicScroll(event) {
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.searchTopics(this.topicPopover.searchKeyword);
5123
+ this.loadSearchTopics();
4975
5124
  }
4976
5125
  },
4977
5126
  insertTopicToEditor(topic) {
@@ -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("handleTopicInput", event.key);
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 !== " " && key.length === 1 || key === "Backspace" || key === "Delete";
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
- if (afterHash.replace(/\u00A0/g, " ").indexOf(" ") === -1) {
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 rect = range.getBoundingClientRect();
4619
- return {
4620
- top: rect.bottom + window.scrollY,
4621
- left: rect.left + window.scrollX
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.hotTopics = [...this.topicPopover.hotTopics, ...newTopics];
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.updateGlobalTopicPopover();
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.handleTopicScroll(e);
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
- handleTopicScroll(event) {
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.searchTopics(this.topicPopover.searchKeyword);
5122
+ this.loadSearchTopics();
4974
5123
  }
4975
5124
  },
4976
5125
  insertTopicToEditor(topic) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@haluo/biz",
3
3
  "description": "rich text",
4
- "version": "2.0.41-next.0",
4
+ "version": "2.0.42-next.1",
5
5
  "type": "module",
6
6
  "module": "./dist/haluo-biz.js",
7
7
  "main": "./dist/haluo-biz.umd.cjs",