dsh-notify-tone 0.2.2 → 0.2.3

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.
Files changed (2) hide show
  1. package/lib/client.js +39 -2
  2. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -40,6 +40,10 @@ window.__ModuleLoader__.load({
40
40
  const FX_STYLE_ID = "dsh-notify-tone-fx-style";
41
41
  const KEY_POSITION = "dsh.notify-tone.ui.position"; // 🔔 按钮位置(JSON: {left, top})
42
42
 
43
+ // 菜单定位器:mountToggle 内注册 positionMenu,renderMenu 重建内容后可刷新位置。
44
+ // 用间接层是因为 renderMenu 与 positionMenu 不在同一函数作用域。
45
+ let menuPositioner = null;
46
+
43
47
  // ===================== 提示音预设 =====================
44
48
  const PRESETS = {
45
49
  classic: {
@@ -661,6 +665,12 @@ window.__ModuleLoader__.load({
661
665
  }
662
666
 
663
667
  menu.appendChild(el("div", "声音 / 视觉 / 系统通知 各自独立开关;颜色各功能独立", base + "color:rgba(255,255,255,0.45);font-size:11px;margin-top:8px;"));
668
+
669
+ // 内容重建后(如展开颜色面板导致宽度变化)若菜单正在显示,则重新定位,
670
+ // 确保水平/垂直方向始终适配屏幕边缘
671
+ if (menu.style.display !== "none" && typeof menuPositioner === "function") {
672
+ menuPositioner();
673
+ }
664
674
  }
665
675
 
666
676
  function mountToggle() {
@@ -689,14 +699,21 @@ window.__ModuleLoader__.load({
689
699
  let dragState = null;
690
700
  let suppressClick = false;
691
701
 
692
- // 根据按钮位置决定菜单弹出方向:上方空间不足则向下弹出
702
+ // 根据按钮位置决定菜单弹出方向:
703
+ // - 垂直:上方空间不足且下方更大 → 向下弹出,否则向上弹出
704
+ // - 水平:默认右对齐向左展开(right:0);若左侧空间不足以容纳菜单宽度,
705
+ // 则切换为左对齐向右展开(left:0),避免菜单被屏幕左边缘裁剪
693
706
  function positionMenu() {
694
707
  if (typeof window === "undefined") return;
708
+ const vw = window.innerWidth || 0;
695
709
  const vh = window.innerHeight || 0;
696
710
  const rect = typeof btn.getBoundingClientRect === "function" ? btn.getBoundingClientRect() : null;
697
711
  const spaceAbove = rect ? rect.top : vh;
698
712
  const spaceBelow = rect ? vh - rect.bottom : 0;
713
+ const spaceLeft = rect ? rect.left : vw;
714
+ const spaceRight = rect ? vw - rect.right : 0;
699
715
  const menuMaxH = (vh * 64) / 100; // 与 max-height 对齐
716
+ const menuW = menu.offsetWidth || 240; // 菜单真实宽度;隐藏时回退到 min-width
700
717
  if (spaceAbove < menuMaxH && spaceBelow > spaceAbove) {
701
718
  // 上方空间不足且下方更大 → 向下弹出
702
719
  menu.style.top = "calc(100% + 8px)";
@@ -706,8 +723,28 @@ window.__ModuleLoader__.load({
706
723
  menu.style.top = "auto";
707
724
  menu.style.bottom = "calc(100% + 8px)";
708
725
  }
726
+ if (spaceLeft >= menuW) {
727
+ // 左侧空间充足 → 右对齐向左展开(默认)
728
+ menu.style.left = "auto";
729
+ menu.style.right = "0";
730
+ } else if (spaceRight >= menuW) {
731
+ // 左侧不足但右侧充足 → 左对齐向右展开,避免被左边缘裁剪
732
+ menu.style.right = "auto";
733
+ menu.style.left = "0";
734
+ } else {
735
+ // 两侧都不足(极窄窗口)→ 选空间较大的一侧
736
+ if (spaceRight > spaceLeft) {
737
+ menu.style.right = "auto";
738
+ menu.style.left = "0";
739
+ } else {
740
+ menu.style.left = "auto";
741
+ menu.style.right = "0";
742
+ }
743
+ }
709
744
  }
710
745
 
746
+ menuPositioner = positionMenu; // 注册到间接层,供 renderMenu 重建内容后刷新位置
747
+
711
748
  // 恢复上次保存的位置(持久化)
712
749
  function applyStoredPosition() {
713
750
  try {
@@ -800,9 +837,9 @@ window.__ModuleLoader__.load({
800
837
 
801
838
  root.addEventListener("mouseenter", () => {
802
839
  clearTimeout(hideTimer);
803
- positionMenu(); // 先根据按钮位置决定弹出方向,再显示
804
840
  renderMenu(menu, btn);
805
841
  menu.style.display = "block";
842
+ positionMenu(); // 先显示再定位:此时 offsetWidth 为菜单真实宽度,水平/垂直方向判断更准确
806
843
  });
807
844
  root.addEventListener("mouseleave", () => {
808
845
  clearTimeout(hideTimer);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-notify-tone",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "dsh web GUI 提示音插件:AI 需要用户授权/选择时与每轮回答结束时播放提示音提醒用户。多套内置音色可选(经典双音/清脆叮咚/明亮三连/柔和轻音),悬停铃铛按钮可开关、选音色并试听,状态持久化。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",