@wendongfly/myhi 1.3.185 → 1.3.187
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/chat.html +4 -6
- package/dist/index.html +83 -58
- package/dist/index.js +1 -1
- package/dist/index.min.js +127 -127
- package/package.json +1 -1
package/dist/chat.html
CHANGED
|
@@ -1112,11 +1112,9 @@
|
|
|
1112
1112
|
const ansi = new AnsiUp();
|
|
1113
1113
|
ansi.use_classes = false;
|
|
1114
1114
|
|
|
1115
|
-
let _myRole = 'admin'; // 成员(operator)@ 只能浏览本项目/绑定目录,不提示项目外用法
|
|
1116
1115
|
fetch('/api/me').then(r => r.json()).then(data => {
|
|
1117
1116
|
// 服务端没有桌面(headless 部署):「打开当前文件夹」必然无效,直接藏掉,只留文件面板
|
|
1118
1117
|
if (data?.desktop === false) document.body.classList.add('no-desktop');
|
|
1119
|
-
_myRole = data?.role || 'admin';
|
|
1120
1118
|
// 打包默认快捷栏预设:用户没自定义过勾选(skVisible 为 null)时采用服务端 config.json 的 skMode
|
|
1121
1119
|
if (data?.skMode && settings.skVisible == null) {
|
|
1122
1120
|
settings.skVisible = data.skMode === 'normal' ? skPresetNormal() : skPresetAll();
|
|
@@ -3324,8 +3322,7 @@
|
|
|
3324
3322
|
if (b && !b.err) {
|
|
3325
3323
|
const tips = [];
|
|
3326
3324
|
if (_mention.items.some(f => f.nav)) tips.push('回车进入文件夹 · Tab 直接引用文件夹');
|
|
3327
|
-
if (!b.dir
|
|
3328
|
-
else if (!b.dir) tips.push('打字搜索本项目 · 项目外打 ' + (b.win ? '@D: 或 @\\' : '@/') + '、@~/ 逐层浏览');
|
|
3325
|
+
if (!b.dir) tips.push('打字搜索本项目 · 项目外打 ' + (b.win ? '@D: 或 @\\' : '@/') + '、@~/ 逐层浏览');
|
|
3329
3326
|
if (tips.length) html += `<div class="mi-tip">${escHtml(tips.join(' · '))}</div>`;
|
|
3330
3327
|
}
|
|
3331
3328
|
_mentionBox.innerHTML = html;
|
|
@@ -3589,9 +3586,10 @@
|
|
|
3589
3586
|
const d = await r.json();
|
|
3590
3587
|
if (d.ok) {
|
|
3591
3588
|
closeFilePanel();
|
|
3592
|
-
addStatusMessage(
|
|
3589
|
+
addStatusMessage('📂 已在本机打开文件夹 ' + (d.cwd || ''));
|
|
3593
3590
|
} else {
|
|
3594
|
-
|
|
3591
|
+
if (d.error?.includes('后台服务')) document.body.classList.add('no-desktop'); // 页面开着时服务换成了后台模式:顺手把按钮藏掉
|
|
3592
|
+
addStatusMessage('打开失败:' + (d.error || '') + (d.error?.includes('后台服务') ? '' : '(若你是远程访问本面板,此按钮本就不生效)'));
|
|
3595
3593
|
}
|
|
3596
3594
|
} catch (e) { addStatusMessage('打开出错: ' + e.message); }
|
|
3597
3595
|
};
|
package/dist/index.html
CHANGED
|
@@ -98,7 +98,15 @@
|
|
|
98
98
|
width: auto; white-space: nowrap; flex-shrink: 0;
|
|
99
99
|
}
|
|
100
100
|
.hd-btn:hover { color: var(--text); border-color: var(--border2); }
|
|
101
|
-
#user-name { max-width: 7rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
101
|
+
#user-name { display: inline-block; max-width: 7rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; margin-left: 0.2rem; }
|
|
102
|
+
/* 用户菜单:顶栏 👤 点开,修改密码 / 退出登录 */
|
|
103
|
+
#user-menu { display: none; position: fixed; z-index: 40; min-width: 11rem; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 28px rgba(0,0,0,0.4); padding: 0.3rem; }
|
|
104
|
+
#user-menu.open { display: block; }
|
|
105
|
+
#user-menu .um-who { padding: 0.45rem 0.6rem 0.5rem; font-size: 0.72rem; color: var(--muted); border-bottom: 1px solid var(--border); margin-bottom: 0.25rem; }
|
|
106
|
+
#user-menu .um-who b { display: block; color: var(--text); font-size: 0.85rem; margin-top: 0.1rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
107
|
+
#user-menu button { display: block; width: 100%; text-align: left; background: none; border: none; color: var(--text); font-size: 0.82rem; padding: 0.5rem 0.6rem; border-radius: 7px; cursor: pointer; }
|
|
108
|
+
#user-menu button:hover { background: var(--bg); }
|
|
109
|
+
#user-menu button.danger { color: var(--red); }
|
|
102
110
|
/* 顶栏放不下一行时逐级收紧(fitHeader 按实际宽度判断,大字号/窄窗口都适用):先藏用户名,再只留图标 */
|
|
103
111
|
#header.hd-fit1 #user-name { display: none; }
|
|
104
112
|
#header.hd-fit2 .hd-btn .hd-txt { display: none; }
|
|
@@ -110,39 +118,48 @@
|
|
|
110
118
|
#set-sheet { display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 31; max-width: 640px; margin: 0 auto;
|
|
111
119
|
background: var(--surface); border-radius: 16px 16px 0 0; padding: 0 1rem calc(1rem + env(safe-area-inset-bottom)); max-height: 88vh; overflow-y: auto; }
|
|
112
120
|
#set-sheet.open, #set-backdrop.open { display: block; }
|
|
113
|
-
/*
|
|
114
|
-
.set-top { position: sticky; top: 0; z-index: 1; background: var(--surface); padding-bottom: 0.
|
|
121
|
+
/* 分组卡片(仿系统设置):一行一项,左名称右控件;说明只留一行小字 */
|
|
122
|
+
.set-top { position: sticky; top: 0; z-index: 1; background: var(--surface); padding-bottom: 0.2rem; }
|
|
115
123
|
.set-top .sheet-handle { margin: 0.6rem auto 0.5rem; }
|
|
116
124
|
.set-head { display: flex; align-items: center; justify-content: space-between; }
|
|
117
125
|
.set-head b { font-size: 1.05rem; }
|
|
118
126
|
.set-x { background: none; border: none; color: var(--muted); font-size: 1.1rem; cursor: pointer; padding: 0.2rem 0.4rem; border-radius: 6px; }
|
|
119
127
|
.set-x:hover { color: var(--text); background: var(--bg); }
|
|
120
|
-
.set-group-t { font-size: 0.72rem; color: var(--muted); margin: 1rem 0.
|
|
121
|
-
.set-group-t small { font-size: 0.68rem; opacity: 0.8; margin-left: 0.3rem; }
|
|
128
|
+
.set-group-t { font-size: 0.72rem; color: var(--muted); margin: 1.1rem 0.25rem 0.4rem; }
|
|
122
129
|
.set-card { background: var(--bg); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
|
|
123
|
-
.set-item { padding: 0.
|
|
124
|
-
.set-
|
|
125
|
-
.set-lbl { font-size: 0.84rem; color: var(--text);
|
|
130
|
+
.set-item { padding: 0.65rem 0.8rem; display: flex; align-items: center; gap: 0.75rem; }
|
|
131
|
+
.set-card > :not(:first-child) { border-top: 1px solid var(--border); }
|
|
132
|
+
.set-lbl { flex: 1; min-width: 0; font-size: 0.84rem; color: var(--text); }
|
|
126
133
|
.set-lbl small { display: block; font-size: 0.68rem; color: var(--muted); margin-top: 0.1rem; }
|
|
127
|
-
.set-
|
|
128
|
-
.set-
|
|
129
|
-
.set-status { font-size: 0.72rem; color: var(--muted); }
|
|
134
|
+
.set-ctl { flex: 0 1 15rem; min-width: 0; display: flex; gap: 0.35rem; }
|
|
135
|
+
.set-status { font-size: 0.7rem; color: var(--muted); padding: 0 0.8rem 0.55rem; margin-top: -0.3rem; }
|
|
130
136
|
.set-status:empty { display: none; }
|
|
131
|
-
.set-
|
|
132
|
-
.set-
|
|
137
|
+
.set-card > .set-status { border-top: none; }
|
|
138
|
+
.set-lbl.nw { flex: none; white-space: nowrap; }
|
|
139
|
+
.set-lbl.nw + .set-seg { margin-left: auto; }
|
|
140
|
+
/* 手机:带输入框的项改成名称在上、输入框整行;分段条占满剩余宽度 */
|
|
141
|
+
@media (max-width: 540px) {
|
|
142
|
+
.set-item.inp { flex-direction: column; align-items: stretch; gap: 0.4rem; }
|
|
143
|
+
.set-item.inp .set-ctl { flex: none; }
|
|
144
|
+
.set-lbl small { display: inline; margin-left: 0.4rem; }
|
|
145
|
+
.set-seg { flex: 1; }
|
|
146
|
+
}
|
|
147
|
+
.set-inp { flex: 1; min-width: 0; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; color: var(--text); font-size: 0.8rem; padding: 0.4rem 0.55rem; outline: none; }
|
|
133
148
|
.set-inp:focus { border-color: var(--accent); }
|
|
134
149
|
.set-inp:disabled { opacity: 0.6; }
|
|
135
|
-
/*
|
|
136
|
-
.set-btn { flex-shrink: 0; white-space: nowrap; background: var(--
|
|
137
|
-
.set-btn.dirty {
|
|
138
|
-
|
|
139
|
-
.set-seg
|
|
140
|
-
.set-seg button
|
|
141
|
-
.set-
|
|
150
|
+
/* 保存按钮只在改了内容后出现(回车也能保存) */
|
|
151
|
+
.set-btn { display: none; flex-shrink: 0; white-space: nowrap; background: var(--accent); color: #fff; border: none; border-radius: 8px; padding: 0.4rem 0.7rem; font-size: 0.76rem; cursor: pointer; }
|
|
152
|
+
.set-btn.dirty { display: block; }
|
|
153
|
+
/* 一体式分段选择条 */
|
|
154
|
+
.set-seg { flex: 0 1 17rem; display: flex; background: var(--surface); border: 1px solid var(--border); border-radius: 9px; padding: 2px; }
|
|
155
|
+
.set-seg button { flex: 1; background: none; color: var(--muted); border: none; border-radius: 7px; padding: 0.35rem 0.2rem; font-size: 0.76rem; cursor: pointer; white-space: nowrap; }
|
|
156
|
+
.set-seg button:hover { color: var(--text); }
|
|
157
|
+
.set-seg button.on { background: var(--accent); color: #fff; }
|
|
158
|
+
.set-link { display: flex; align-items: center; gap: 0.5rem; width: 100%; background: none; border: none; color: var(--text); font-size: 0.84rem; padding: 0.72rem 0.8rem; cursor: pointer; text-align: left; text-decoration: none; }
|
|
142
159
|
.set-link:hover { background: var(--surface); }
|
|
160
|
+
.set-link small { color: var(--muted); font-size: 0.7rem; }
|
|
143
161
|
.set-link::after { content: '›'; margin-left: auto; color: var(--muted); font-size: 1rem; }
|
|
144
|
-
.set-
|
|
145
|
-
.set-foot { font-size: 0.7rem; color: var(--muted); line-height: 1.5; margin: 0.9rem 0.2rem 0.2rem; }
|
|
162
|
+
.set-foot { font-size: 0.7rem; color: var(--muted); line-height: 1.5; margin: 0.9rem 0.25rem 0.2rem; text-align: center; }
|
|
146
163
|
/* 手机(≤540px):藏用户名、文字标签只留图标,一行放下且不憋屈 */
|
|
147
164
|
@media (max-width: 540px) {
|
|
148
165
|
#user-name { display: none; }
|
|
@@ -568,12 +585,12 @@
|
|
|
568
585
|
<div id="header">
|
|
569
586
|
<div class="logo">my<span>hi</span></div>
|
|
570
587
|
<div class="hd-actions">
|
|
571
|
-
<span id="user-name" style="font-size:0.8rem;color:var(--muted)"></span>
|
|
572
588
|
<button id="grid-btn" class="hd-btn" onclick="location.href='/grid'" title="分屏工作台(多任务并排)">▦<span class="hd-txt"> 分屏</span></button>
|
|
573
589
|
<button id="doctor-btn" class="hd-btn" onclick="openDoctor()" title="会话体检">🩺<span class="hd-txt"> 体检</span></button>
|
|
574
590
|
<button id="usage-btn" class="hd-btn" onclick="showUsage()" title="用量">📊<span class="hd-txt"> 用量</span></button>
|
|
575
591
|
<button id="help-btn" class="hd-btn" onclick="openHelpSheet()" title="使用说明 / 快速上手">❓<span class="hd-txt"> 帮助</span></button>
|
|
576
|
-
<button id="settings-btn" class="hd-btn" onclick="openSettings()" title="设置(外观 / 本机名称 / 语音 /
|
|
592
|
+
<button id="settings-btn" class="hd-btn" onclick="openSettings()" title="设置(外观 / 本机名称 / 语音 / 服务)">⚙<span class="hd-txt"> 设置</span></button>
|
|
593
|
+
<button id="user-btn" class="hd-btn" onclick="toggleUserMenu(event)" title="账户:修改密码 / 退出登录" style="display:none">👤<span id="user-name" class="hd-txt"></span></button>
|
|
577
594
|
<div id="conn-dot"></div>
|
|
578
595
|
</div>
|
|
579
596
|
</div>
|
|
@@ -671,55 +688,51 @@
|
|
|
671
688
|
</div>
|
|
672
689
|
|
|
673
690
|
<!-- 设置 sheet:首页是全局设置的唯一入口(会话页 ⚙ 只管本设备的聊天显示/快捷栏) -->
|
|
691
|
+
<div id="user-menu">
|
|
692
|
+
<div class="um-who">已登录<b id="um-name"></b></div>
|
|
693
|
+
<button id="passwd-btn" onclick="closeUserMenu();openPasswdSheet()" style="display:none">🔑 修改密码</button>
|
|
694
|
+
<button id="logout-btn" class="danger" onclick="closeUserMenu();doLogout()">↩ 退出登录</button>
|
|
695
|
+
</div>
|
|
674
696
|
<div id="set-backdrop" onclick="closeSettings()"></div>
|
|
675
697
|
<div id="set-sheet">
|
|
676
698
|
<div class="set-top">
|
|
677
699
|
<div class="sheet-handle"></div>
|
|
678
|
-
<div class="set-head"><b
|
|
700
|
+
<div class="set-head"><b>设置</b><button class="set-x" onclick="closeSettings()" title="关闭 (Esc)">✕</button></div>
|
|
679
701
|
</div>
|
|
680
702
|
|
|
681
|
-
<div class="set-group-t"
|
|
703
|
+
<div class="set-group-t">本设备</div>
|
|
682
704
|
<div class="set-card">
|
|
683
|
-
<div class="set-item"><div class="set-lbl">主题</div><div class="set-seg" id="set-theme"></div></div>
|
|
684
|
-
<div class="set-item"><div class="set-lbl">字号</div><div class="set-seg" id="set-font"></div></div>
|
|
705
|
+
<div class="set-item"><div class="set-lbl nw">主题</div><div class="set-seg" id="set-theme"></div></div>
|
|
706
|
+
<div class="set-item"><div class="set-lbl nw">字号</div><div class="set-seg" id="set-font"></div></div>
|
|
685
707
|
</div>
|
|
686
708
|
|
|
687
|
-
<div class="set-group-t"
|
|
709
|
+
<div class="set-group-t">这台电脑 · 所有设备生效</div>
|
|
688
710
|
<div class="set-card">
|
|
689
|
-
<div class="set-item
|
|
690
|
-
<div class="set-lbl">本机名称<small
|
|
691
|
-
<div class="set-
|
|
711
|
+
<div class="set-item inp">
|
|
712
|
+
<div class="set-lbl">本机名称<small>显示在浏览器标签上</small></div>
|
|
713
|
+
<div class="set-ctl">
|
|
692
714
|
<input id="set-machine-name" class="set-inp" maxlength="32" autocomplete="off" data-save="saveMachineName">
|
|
693
715
|
<button class="set-btn" onclick="saveMachineName()">保存</button>
|
|
694
716
|
</div>
|
|
695
|
-
<div id="set-machine-status" class="set-status"></div>
|
|
696
717
|
</div>
|
|
697
|
-
<div
|
|
698
|
-
|
|
699
|
-
<div class="set-
|
|
700
|
-
|
|
718
|
+
<div id="set-machine-status" class="set-status"></div>
|
|
719
|
+
<div class="set-item inp">
|
|
720
|
+
<div class="set-lbl">语音识别<small>留空 = 不用语音输入</small></div>
|
|
721
|
+
<div class="set-ctl">
|
|
722
|
+
<input id="set-asr-url" class="set-inp" placeholder="http://IP:8765" autocomplete="off" data-save="saveAsrUrl">
|
|
701
723
|
<button class="set-btn" onclick="saveAsrUrl()">保存</button>
|
|
702
724
|
</div>
|
|
703
|
-
<div id="set-asr-status" class="set-status"></div>
|
|
704
|
-
</div>
|
|
705
|
-
</div>
|
|
706
|
-
|
|
707
|
-
<div id="set-account" style="display:none">
|
|
708
|
-
<div class="set-group-t">账户</div>
|
|
709
|
-
<div class="set-card">
|
|
710
|
-
<div class="set-item"><div class="set-lbl">当前用户</div><span id="set-account-name" class="set-val"></span></div>
|
|
711
|
-
<button id="passwd-btn" class="set-link" onclick="closeSettings();openPasswdSheet()" style="display:none">🔑 修改密码</button>
|
|
712
|
-
<button id="logout-btn" class="set-link danger" onclick="doLogout()" style="display:none">退出登录</button>
|
|
713
725
|
</div>
|
|
726
|
+
<div id="set-asr-status" class="set-status"></div>
|
|
714
727
|
</div>
|
|
715
728
|
|
|
716
729
|
<div class="set-group-t">服务</div>
|
|
717
730
|
<div class="set-card">
|
|
718
|
-
<a id="set-admin-link" class="set-link" href="/admin" style="display:none">🛠
|
|
719
|
-
<button class="set-link
|
|
731
|
+
<a id="set-admin-link" class="set-link" href="/admin" style="display:none">🛠 管理后台 <small>用户 · 网关 · 密钥 · 升级</small></a>
|
|
732
|
+
<button class="set-link" onclick="restartMyhi()">🔄 重启 myhi</button>
|
|
720
733
|
</div>
|
|
721
|
-
<div id="set-restart-status" class="set-status" style="
|
|
722
|
-
<div class="set-foot"
|
|
734
|
+
<div id="set-restart-status" class="set-status" style="padding:0.45rem 0.25rem 0;margin:0"></div>
|
|
735
|
+
<div class="set-foot">聊天显示、回车键、快捷栏在会话页右上角 ⚙ 设置</div>
|
|
723
736
|
</div>
|
|
724
737
|
|
|
725
738
|
<!-- 修改密码 sheet(成员用户自助改密;管理员改密码在 /admin) -->
|
|
@@ -848,17 +861,14 @@
|
|
|
848
861
|
fetch('/api/me').then(r => r.json()).then(data => {
|
|
849
862
|
if ((data.exclusive || data.hasUsers) && data.name) {
|
|
850
863
|
document.getElementById('user-name').textContent = data.name;
|
|
851
|
-
document.getElementById('
|
|
864
|
+
document.getElementById('um-name').textContent = data.name;
|
|
865
|
+
document.getElementById('user-btn').style.display = '';
|
|
852
866
|
fitHeader();
|
|
853
|
-
document.getElementById('set-account').style.display = '';
|
|
854
|
-
document.getElementById('logout-btn').style.display = '';
|
|
855
867
|
}
|
|
856
868
|
// 成员用户(users.json 登录)才显示自助改密入口;管理员改密码在 /admin
|
|
857
869
|
if (data.role === 'admin') document.getElementById('set-admin-link').style.display = '';
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
document.getElementById('passwd-btn').style.display = '';
|
|
861
|
-
}
|
|
870
|
+
else document.getElementById('set-admin-link').remove(); // 别留个隐藏首项,免得下一项顶部多一道分隔线
|
|
871
|
+
if (data.hasUsers && data.role === 'operator') document.getElementById('passwd-btn').style.display = '';
|
|
862
872
|
if (data.dir) {
|
|
863
873
|
_userDir = data.dir;
|
|
864
874
|
// 默认填入绑定目录,隐藏盘符栏,保留最近目录
|
|
@@ -962,6 +972,21 @@
|
|
|
962
972
|
} catch { msg.textContent = '连接失败'; }
|
|
963
973
|
};
|
|
964
974
|
|
|
975
|
+
// 顶栏 👤 用户菜单:贴在按钮下方右对齐,点外面/Esc 关闭
|
|
976
|
+
window.toggleUserMenu = function(e) {
|
|
977
|
+
e.stopPropagation();
|
|
978
|
+
const m = document.getElementById('user-menu');
|
|
979
|
+
if (m.classList.contains('open')) return closeUserMenu();
|
|
980
|
+
const r = document.getElementById('user-btn').getBoundingClientRect();
|
|
981
|
+
m.style.top = (r.bottom + 6) + 'px';
|
|
982
|
+
m.style.right = Math.max(8, window.innerWidth - r.right) + 'px';
|
|
983
|
+
m.classList.add('open');
|
|
984
|
+
};
|
|
985
|
+
window.closeUserMenu = function() { document.getElementById('user-menu').classList.remove('open'); };
|
|
986
|
+
document.addEventListener('click', (e) => { if (!e.target.closest('#user-menu')) closeUserMenu(); });
|
|
987
|
+
document.addEventListener('keydown', (e) => { if (e.key === 'Escape') closeUserMenu(); });
|
|
988
|
+
window.addEventListener('resize', closeUserMenu);
|
|
989
|
+
|
|
965
990
|
function doLogout() {
|
|
966
991
|
if (!confirm('确定退出登录?')) return;
|
|
967
992
|
fetch('/logout', { method: 'POST' }).finally(() => {
|