@yushaw/sanqian-chat 0.2.11 → 0.2.13

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.
@@ -792,7 +792,7 @@ interface UseChatPanelReturn {
792
792
  show: () => Promise<void>;
793
793
  hide: () => Promise<void>;
794
794
  toggle: () => Promise<void>;
795
- setWidth: (width: number, animate?: boolean) => Promise<void>;
795
+ setWidth: (width: number, animate?: boolean) => void;
796
796
  onResizeEnd: () => Promise<void>;
797
797
  }
798
798
  declare function useChatPanel(): UseChatPanelReturn;
@@ -792,7 +792,7 @@ interface UseChatPanelReturn {
792
792
  show: () => Promise<void>;
793
793
  hide: () => Promise<void>;
794
794
  toggle: () => Promise<void>;
795
- setWidth: (width: number, animate?: boolean) => Promise<void>;
795
+ setWidth: (width: number, animate?: boolean) => void;
796
796
  onResizeEnd: () => Promise<void>;
797
797
  }
798
798
  declare function useChatPanel(): UseChatPanelReturn;
@@ -5188,11 +5188,11 @@ function useChatPanel() {
5188
5188
  await api.toggle();
5189
5189
  setVisible((v) => !v);
5190
5190
  }, []);
5191
- const setWidth = (0, import_react10.useCallback)(async (newWidth, animate) => {
5191
+ const setWidth = (0, import_react10.useCallback)((newWidth, animate) => {
5192
5192
  const api = getChatPanelApi();
5193
5193
  if (!api?.setWidth) return;
5194
- await api.setWidth(newWidth, animate);
5195
5194
  setWidthState(newWidth);
5195
+ api.setWidth(newWidth, animate);
5196
5196
  }, []);
5197
5197
  const onResizeEnd = (0, import_react10.useCallback)(async () => {
5198
5198
  const api = getChatPanelApi();
@@ -8917,6 +8917,31 @@ function AttachButton({ className, locale = "en" }) {
8917
8917
  // src/renderer/components/Resizer.tsx
8918
8918
  var import_react31 = require("react");
8919
8919
  var import_jsx_runtime20 = require("react/jsx-runtime");
8920
+ function useRafThrottle(fn) {
8921
+ const rafRef = (0, import_react31.useRef)(null);
8922
+ const argsRef = (0, import_react31.useRef)(null);
8923
+ const fnRef = (0, import_react31.useRef)(fn);
8924
+ fnRef.current = fn;
8925
+ const throttledFn = (0, import_react31.useCallback)((...args) => {
8926
+ argsRef.current = args;
8927
+ if (rafRef.current === null) {
8928
+ rafRef.current = requestAnimationFrame(() => {
8929
+ rafRef.current = null;
8930
+ if (argsRef.current) {
8931
+ fnRef.current(...argsRef.current);
8932
+ }
8933
+ });
8934
+ }
8935
+ }, []);
8936
+ (0, import_react31.useEffect)(() => {
8937
+ return () => {
8938
+ if (rafRef.current !== null) {
8939
+ cancelAnimationFrame(rafRef.current);
8940
+ }
8941
+ };
8942
+ }, []);
8943
+ return throttledFn;
8944
+ }
8920
8945
  var DEFAULT_WIDTH = 360;
8921
8946
  function Resizer({
8922
8947
  position = "left",
@@ -8930,24 +8955,27 @@ function Resizer({
8930
8955
  const [isDragging, setIsDragging] = (0, import_react31.useState)(false);
8931
8956
  const startX = (0, import_react31.useRef)(0);
8932
8957
  const startWidth = (0, import_react31.useRef)(0);
8958
+ const widthRef = (0, import_react31.useRef)(width);
8959
+ widthRef.current = width;
8960
+ const throttledSetWidth = useRafThrottle(setWidth);
8933
8961
  const handleDoubleClick = (0, import_react31.useCallback)(() => {
8934
8962
  setWidth(defaultWidth, true);
8935
8963
  }, [defaultWidth, setWidth]);
8936
8964
  const handleMouseDown = (0, import_react31.useCallback)((e) => {
8937
8965
  e.preventDefault();
8938
8966
  setIsDragging(true);
8939
- startX.current = e.clientX;
8940
- startWidth.current = width;
8967
+ startX.current = e.screenX;
8968
+ startWidth.current = widthRef.current;
8941
8969
  document.body.style.cursor = "col-resize";
8942
8970
  document.body.style.userSelect = "none";
8943
- }, [width]);
8971
+ }, []);
8944
8972
  (0, import_react31.useEffect)(() => {
8945
8973
  if (!isDragging) return;
8946
8974
  const handleMouseMove = (e) => {
8947
- const deltaX = e.clientX - startX.current;
8975
+ const deltaX = e.screenX - startX.current;
8948
8976
  const newWidth = position === "left" ? startWidth.current - deltaX : startWidth.current + deltaX;
8949
8977
  const clampedWidth = Math.min(maxWidth, Math.max(minWidth, newWidth));
8950
- setWidth(clampedWidth);
8978
+ throttledSetWidth(clampedWidth);
8951
8979
  };
8952
8980
  const handleMouseUp = () => {
8953
8981
  setIsDragging(false);
@@ -8961,7 +8989,7 @@ function Resizer({
8961
8989
  document.removeEventListener("mousemove", handleMouseMove);
8962
8990
  document.removeEventListener("mouseup", handleMouseUp);
8963
8991
  };
8964
- }, [isDragging, position, minWidth, maxWidth, setWidth, onResizeEnd]);
8992
+ }, [isDragging, position, minWidth, maxWidth, throttledSetWidth, onResizeEnd]);
8965
8993
  if (!isEmbedded) return null;
8966
8994
  const isActive = isHovered || isDragging;
8967
8995
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
@@ -9952,7 +9980,7 @@ var CompactChat = (0, import_react36.memo)(function CompactChat2({
9952
9980
  "data-chat-font-size": resolvedConfig?.fontSize || "normal",
9953
9981
  children: [
9954
9982
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PanelResizer, {}),
9955
- !hideHeader && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("header", { className: "flex h-9 flex-shrink-0 items-center px-2 border-b chat-divider-border", style: { WebkitAppRegion: "drag" }, children: isEmbedded ? (
9983
+ !hideHeader && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("header", { className: "flex flex-shrink-0 items-center px-2 border-b chat-divider-border", style: { height: 42, WebkitAppRegion: "drag" }, children: isEmbedded ? (
9956
9984
  // Embedded mode: left-aligned buttons (collapse, float, history, new chat)
9957
9985
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-0.5", style: { WebkitAppRegion: "no-drag" }, children: [
9958
9986
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "chat-tooltip-wrapper", children: [
@@ -5101,11 +5101,11 @@ function useChatPanel() {
5101
5101
  await api.toggle();
5102
5102
  setVisible((v) => !v);
5103
5103
  }, []);
5104
- const setWidth = useCallback6(async (newWidth, animate) => {
5104
+ const setWidth = useCallback6((newWidth, animate) => {
5105
5105
  const api = getChatPanelApi();
5106
5106
  if (!api?.setWidth) return;
5107
- await api.setWidth(newWidth, animate);
5108
5107
  setWidthState(newWidth);
5108
+ api.setWidth(newWidth, animate);
5109
5109
  }, []);
5110
5110
  const onResizeEnd = useCallback6(async () => {
5111
5111
  const api = getChatPanelApi();
@@ -8846,6 +8846,31 @@ function AttachButton({ className, locale = "en" }) {
8846
8846
  // src/renderer/components/Resizer.tsx
8847
8847
  import { useCallback as useCallback17, useRef as useRef14, useEffect as useEffect21, useState as useState19 } from "react";
8848
8848
  import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
8849
+ function useRafThrottle(fn) {
8850
+ const rafRef = useRef14(null);
8851
+ const argsRef = useRef14(null);
8852
+ const fnRef = useRef14(fn);
8853
+ fnRef.current = fn;
8854
+ const throttledFn = useCallback17((...args) => {
8855
+ argsRef.current = args;
8856
+ if (rafRef.current === null) {
8857
+ rafRef.current = requestAnimationFrame(() => {
8858
+ rafRef.current = null;
8859
+ if (argsRef.current) {
8860
+ fnRef.current(...argsRef.current);
8861
+ }
8862
+ });
8863
+ }
8864
+ }, []);
8865
+ useEffect21(() => {
8866
+ return () => {
8867
+ if (rafRef.current !== null) {
8868
+ cancelAnimationFrame(rafRef.current);
8869
+ }
8870
+ };
8871
+ }, []);
8872
+ return throttledFn;
8873
+ }
8849
8874
  var DEFAULT_WIDTH = 360;
8850
8875
  function Resizer({
8851
8876
  position = "left",
@@ -8859,24 +8884,27 @@ function Resizer({
8859
8884
  const [isDragging, setIsDragging] = useState19(false);
8860
8885
  const startX = useRef14(0);
8861
8886
  const startWidth = useRef14(0);
8887
+ const widthRef = useRef14(width);
8888
+ widthRef.current = width;
8889
+ const throttledSetWidth = useRafThrottle(setWidth);
8862
8890
  const handleDoubleClick = useCallback17(() => {
8863
8891
  setWidth(defaultWidth, true);
8864
8892
  }, [defaultWidth, setWidth]);
8865
8893
  const handleMouseDown = useCallback17((e) => {
8866
8894
  e.preventDefault();
8867
8895
  setIsDragging(true);
8868
- startX.current = e.clientX;
8869
- startWidth.current = width;
8896
+ startX.current = e.screenX;
8897
+ startWidth.current = widthRef.current;
8870
8898
  document.body.style.cursor = "col-resize";
8871
8899
  document.body.style.userSelect = "none";
8872
- }, [width]);
8900
+ }, []);
8873
8901
  useEffect21(() => {
8874
8902
  if (!isDragging) return;
8875
8903
  const handleMouseMove = (e) => {
8876
- const deltaX = e.clientX - startX.current;
8904
+ const deltaX = e.screenX - startX.current;
8877
8905
  const newWidth = position === "left" ? startWidth.current - deltaX : startWidth.current + deltaX;
8878
8906
  const clampedWidth = Math.min(maxWidth, Math.max(minWidth, newWidth));
8879
- setWidth(clampedWidth);
8907
+ throttledSetWidth(clampedWidth);
8880
8908
  };
8881
8909
  const handleMouseUp = () => {
8882
8910
  setIsDragging(false);
@@ -8890,7 +8918,7 @@ function Resizer({
8890
8918
  document.removeEventListener("mousemove", handleMouseMove);
8891
8919
  document.removeEventListener("mouseup", handleMouseUp);
8892
8920
  };
8893
- }, [isDragging, position, minWidth, maxWidth, setWidth, onResizeEnd]);
8921
+ }, [isDragging, position, minWidth, maxWidth, throttledSetWidth, onResizeEnd]);
8894
8922
  if (!isEmbedded) return null;
8895
8923
  const isActive = isHovered || isDragging;
8896
8924
  return /* @__PURE__ */ jsxs15(
@@ -9881,7 +9909,7 @@ var CompactChat = memo17(function CompactChat2({
9881
9909
  "data-chat-font-size": resolvedConfig?.fontSize || "normal",
9882
9910
  children: [
9883
9911
  /* @__PURE__ */ jsx25(PanelResizer, {}),
9884
- !hideHeader && /* @__PURE__ */ jsx25("header", { className: "flex h-9 flex-shrink-0 items-center px-2 border-b chat-divider-border", style: { WebkitAppRegion: "drag" }, children: isEmbedded ? (
9912
+ !hideHeader && /* @__PURE__ */ jsx25("header", { className: "flex flex-shrink-0 items-center px-2 border-b chat-divider-border", style: { height: 42, WebkitAppRegion: "drag" }, children: isEmbedded ? (
9885
9913
  // Embedded mode: left-aligned buttons (collapse, float, history, new chat)
9886
9914
  /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-0.5", style: { WebkitAppRegion: "no-drag" }, children: [
9887
9915
  /* @__PURE__ */ jsxs20("div", { className: "chat-tooltip-wrapper", children: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yushaw/sanqian-chat",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "Floating chat window SDK for Sanqian AI Assistant",
5
5
  "main": "./dist/main/index.js",
6
6
  "types": "./dist/main/index.d.ts",