@wendongfly/myhi 1.3.184 → 1.3.185
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 +168 -72
- package/dist/index.html +83 -162
- package/dist/index.js +10 -10
- package/dist/index.min.js +123 -121
- package/package.json +1 -1
package/dist/index.html
CHANGED
|
@@ -105,32 +105,44 @@
|
|
|
105
105
|
#header.hd-fit2 .hd-actions { gap: 0.4rem; }
|
|
106
106
|
#header.hd-fit2 .hd-btn { padding: 0.32rem 0.48rem; }
|
|
107
107
|
|
|
108
|
-
/* ── 设置 sheet(全局设置收口:外观 / 本机名称 /
|
|
108
|
+
/* ── 设置 sheet(全局设置收口:外观 / 本机名称 / 语音 / 账户 / 服务)── */
|
|
109
109
|
#set-backdrop { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.55); z-index: 30; }
|
|
110
110
|
#set-sheet { display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 31; max-width: 640px; margin: 0 auto;
|
|
111
111
|
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
112
|
#set-sheet.open, #set-backdrop.open { display: block; }
|
|
113
|
-
|
|
114
|
-
.
|
|
115
|
-
.set-
|
|
116
|
-
.set-
|
|
117
|
-
.set-
|
|
118
|
-
.set-
|
|
113
|
+
/* 分组卡片(仿系统设置):组标题说明作用范围,卡片内一行一项,说明文字收成一行小字 */
|
|
114
|
+
.set-top { position: sticky; top: 0; z-index: 1; background: var(--surface); padding-bottom: 0.35rem; }
|
|
115
|
+
.set-top .sheet-handle { margin: 0.6rem auto 0.5rem; }
|
|
116
|
+
.set-head { display: flex; align-items: center; justify-content: space-between; }
|
|
117
|
+
.set-head b { font-size: 1.05rem; }
|
|
118
|
+
.set-x { background: none; border: none; color: var(--muted); font-size: 1.1rem; cursor: pointer; padding: 0.2rem 0.4rem; border-radius: 6px; }
|
|
119
|
+
.set-x:hover { color: var(--text); background: var(--bg); }
|
|
120
|
+
.set-group-t { font-size: 0.72rem; color: var(--muted); margin: 1rem 0.2rem 0.35rem; }
|
|
121
|
+
.set-group-t small { font-size: 0.68rem; opacity: 0.8; margin-left: 0.3rem; }
|
|
122
|
+
.set-card { background: var(--bg); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
|
|
123
|
+
.set-item { padding: 0.7rem 0.8rem; display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
|
|
124
|
+
.set-item + .set-item, .set-card > * + .set-link, .set-item + .set-link { border-top: 1px solid var(--border); }
|
|
125
|
+
.set-lbl { font-size: 0.84rem; color: var(--text); min-width: 4.5rem; }
|
|
126
|
+
.set-lbl small { display: block; font-size: 0.68rem; color: var(--muted); margin-top: 0.1rem; }
|
|
127
|
+
.set-item.stack { flex-direction: column; align-items: stretch; gap: 0.45rem; }
|
|
128
|
+
.set-val { margin-left: auto; font-size: 0.8rem; color: var(--muted); }
|
|
129
|
+
.set-status { font-size: 0.72rem; color: var(--muted); }
|
|
130
|
+
.set-status:empty { display: none; }
|
|
119
131
|
.set-row { display: flex; gap: 0.4rem; }
|
|
120
|
-
.set-inp { flex: 1; min-width: 0; background: var(--
|
|
132
|
+
.set-inp { flex: 1; min-width: 0; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; color: var(--text); font-size: 0.82rem; padding: 0.45rem 0.6rem; outline: none; }
|
|
121
133
|
.set-inp:focus { border-color: var(--accent); }
|
|
122
|
-
.set-
|
|
123
|
-
|
|
124
|
-
.set-btn
|
|
125
|
-
.set-
|
|
126
|
-
.set-seg
|
|
134
|
+
.set-inp:disabled { opacity: 0.6; }
|
|
135
|
+
/* 保存按钮平时是淡的,改了内容才亮起来(回车也能保存) */
|
|
136
|
+
.set-btn { flex-shrink: 0; white-space: nowrap; background: var(--surface); color: var(--muted); border: 1px solid var(--border); border-radius: 8px; padding: 0.45rem 0.85rem; font-size: 0.78rem; cursor: pointer; }
|
|
137
|
+
.set-btn.dirty { background: var(--accent); border-color: var(--accent); color: #fff; }
|
|
138
|
+
.set-seg { flex: 1; display: flex; gap: 0.3rem; min-width: 12rem; }
|
|
139
|
+
.set-seg button { flex: 1; background: var(--surface); color: var(--muted); border: 1px solid var(--border); border-radius: 8px; padding: 0.4rem 0.3rem; font-size: 0.78rem; cursor: pointer; white-space: nowrap; }
|
|
127
140
|
.set-seg button.on { background: var(--accent); border-color: var(--accent); color: #fff; }
|
|
128
|
-
.set-
|
|
129
|
-
.
|
|
130
|
-
.
|
|
131
|
-
.
|
|
132
|
-
.
|
|
133
|
-
.dr-btn { flex-shrink: 0; white-space: nowrap; padding: 0.28rem 0.7rem; font-size: 0.72rem; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--text2); cursor: pointer; }
|
|
141
|
+
.set-link { display: flex; align-items: center; width: 100%; background: none; border: none; color: var(--text); font-size: 0.84rem; padding: 0.75rem 0.8rem; cursor: pointer; text-align: left; text-decoration: none; }
|
|
142
|
+
.set-link:hover { background: var(--surface); }
|
|
143
|
+
.set-link::after { content: '›'; margin-left: auto; color: var(--muted); font-size: 1rem; }
|
|
144
|
+
.set-link.danger { color: var(--red); }
|
|
145
|
+
.set-foot { font-size: 0.7rem; color: var(--muted); line-height: 1.5; margin: 0.9rem 0.2rem 0.2rem; }
|
|
134
146
|
/* 手机(≤540px):藏用户名、文字标签只留图标,一行放下且不憋屈 */
|
|
135
147
|
@media (max-width: 540px) {
|
|
136
148
|
#user-name { display: none; }
|
|
@@ -561,7 +573,7 @@
|
|
|
561
573
|
<button id="doctor-btn" class="hd-btn" onclick="openDoctor()" title="会话体检">🩺<span class="hd-txt"> 体检</span></button>
|
|
562
574
|
<button id="usage-btn" class="hd-btn" onclick="showUsage()" title="用量">📊<span class="hd-txt"> 用量</span></button>
|
|
563
575
|
<button id="help-btn" class="hd-btn" onclick="openHelpSheet()" title="使用说明 / 快速上手">❓<span class="hd-txt"> 帮助</span></button>
|
|
564
|
-
<button id="settings-btn" class="hd-btn" onclick="openSettings()" title="设置(外观 / 本机名称 /
|
|
576
|
+
<button id="settings-btn" class="hd-btn" onclick="openSettings()" title="设置(外观 / 本机名称 / 语音 / 账户)">⚙<span class="hd-txt"> 设置</span></button>
|
|
565
577
|
<div id="conn-dot"></div>
|
|
566
578
|
</div>
|
|
567
579
|
</div>
|
|
@@ -661,72 +673,53 @@
|
|
|
661
673
|
<!-- 设置 sheet:首页是全局设置的唯一入口(会话页 ⚙ 只管本设备的聊天显示/快捷栏) -->
|
|
662
674
|
<div id="set-backdrop" onclick="closeSettings()"></div>
|
|
663
675
|
<div id="set-sheet">
|
|
664
|
-
<div class="
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
<h4>外观 <span class="set-scope">本设备</span></h4>
|
|
668
|
-
<div class="set-sub">主题</div>
|
|
669
|
-
<div class="set-seg" id="set-theme"></div>
|
|
670
|
-
<div class="set-sub">字号</div>
|
|
671
|
-
<div class="set-seg" id="set-font"></div>
|
|
676
|
+
<div class="set-top">
|
|
677
|
+
<div class="sheet-handle"></div>
|
|
678
|
+
<div class="set-head"><b>⚙ 设置</b><button class="set-x" onclick="closeSettings()" title="关闭 (Esc)">✕</button></div>
|
|
672
679
|
</div>
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
<div class="set-
|
|
677
|
-
|
|
678
|
-
<button class="set-btn" onclick="saveMachineName()">保存</button>
|
|
679
|
-
</div>
|
|
680
|
-
<div id="set-machine-status" class="set-status"></div>
|
|
680
|
+
|
|
681
|
+
<div class="set-group-t">本设备<small>只影响这台手机 / 电脑的浏览器</small></div>
|
|
682
|
+
<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>
|
|
681
685
|
</div>
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
<div
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
<button id="atpick-up" class="dr-btn" onclick="atPickUp()" title="上一级">⬆ 上一级</button>
|
|
691
|
-
<span id="atpick-cur" style="flex:1;min-width:0;font-size:0.72rem;color:var(--text2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;direction:rtl;text-align:left"></span>
|
|
692
|
-
</div>
|
|
693
|
-
<div id="atpick-list" style="max-height:200px;overflow-y:auto;scrollbar-width:thin"></div>
|
|
694
|
-
<div style="display:flex;gap:0.4rem;padding:0.45rem 0.5rem;border-top:1px solid var(--border)">
|
|
695
|
-
<button class="set-btn ghost" onclick="closeAtPicker()" style="flex:1">取消</button>
|
|
696
|
-
<button class="set-btn" onclick="addAtPicked()" style="flex:2">✓ 添加当前文件夹</button>
|
|
686
|
+
|
|
687
|
+
<div class="set-group-t">这台电脑<small>运行 myhi 的电脑,所有访问设备都生效</small></div>
|
|
688
|
+
<div class="set-card">
|
|
689
|
+
<div class="set-item stack">
|
|
690
|
+
<div class="set-lbl">本机名称<small>显示在浏览器标签上,好区分多台电脑;留空用主机名</small></div>
|
|
691
|
+
<div class="set-row">
|
|
692
|
+
<input id="set-machine-name" class="set-inp" maxlength="32" autocomplete="off" data-save="saveMachineName">
|
|
693
|
+
<button class="set-btn" onclick="saveMachineName()">保存</button>
|
|
697
694
|
</div>
|
|
695
|
+
<div id="set-machine-status" class="set-status"></div>
|
|
698
696
|
</div>
|
|
699
|
-
<
|
|
700
|
-
<
|
|
701
|
-
<div class="set-row"
|
|
702
|
-
<input id="
|
|
703
|
-
<button class="set-btn" onclick="
|
|
697
|
+
<div class="set-item stack">
|
|
698
|
+
<div class="set-lbl">语音识别服务<small>SenseVoice 等服务地址;留空 = 不用语音输入</small></div>
|
|
699
|
+
<div class="set-row">
|
|
700
|
+
<input id="set-asr-url" class="set-inp" placeholder="http://192.168.x.x:8765" autocomplete="off" data-save="saveAsrUrl">
|
|
701
|
+
<button class="set-btn" onclick="saveAsrUrl()">保存</button>
|
|
704
702
|
</div>
|
|
705
|
-
|
|
706
|
-
<div id="atroot-status" class="set-status"></div>
|
|
707
|
-
</div>
|
|
708
|
-
<div class="set-sec">
|
|
709
|
-
<h4>语音识别 (ASR) <span class="set-scope">全局</span></h4>
|
|
710
|
-
<div class="set-hint">SenseVoice 或兼容服务的地址,留空表示禁用语音。</div>
|
|
711
|
-
<div class="set-row">
|
|
712
|
-
<input id="set-asr-url" class="set-inp" placeholder="http://192.168.x.x:8765" autocomplete="off">
|
|
713
|
-
<button class="set-btn" onclick="saveAsrUrl()">保存</button>
|
|
703
|
+
<div id="set-asr-status" class="set-status"></div>
|
|
714
704
|
</div>
|
|
715
|
-
<div id="set-asr-status" class="set-status"></div>
|
|
716
705
|
</div>
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
<div class="set-
|
|
720
|
-
|
|
721
|
-
<
|
|
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>
|
|
722
713
|
</div>
|
|
723
714
|
</div>
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
<
|
|
728
|
-
<
|
|
715
|
+
|
|
716
|
+
<div class="set-group-t">服务</div>
|
|
717
|
+
<div class="set-card">
|
|
718
|
+
<a id="set-admin-link" class="set-link" href="/admin" style="display:none">🛠 管理后台(用户 / 大模型网关 / 密钥库 / 升级)</a>
|
|
719
|
+
<button class="set-link danger" onclick="restartMyhi()">🔄 重启 myhi</button>
|
|
729
720
|
</div>
|
|
721
|
+
<div id="set-restart-status" class="set-status" style="margin:0.4rem 0.2rem 0"></div>
|
|
722
|
+
<div class="set-foot">聊天显示、回车键、快捷栏按钮在会话页右上角 ⚙ 里设置。</div>
|
|
730
723
|
</div>
|
|
731
724
|
|
|
732
725
|
<!-- 修改密码 sheet(成员用户自助改密;管理员改密码在 /admin) -->
|
|
@@ -861,6 +854,7 @@
|
|
|
861
854
|
document.getElementById('logout-btn').style.display = '';
|
|
862
855
|
}
|
|
863
856
|
// 成员用户(users.json 登录)才显示自助改密入口;管理员改密码在 /admin
|
|
857
|
+
if (data.role === 'admin') document.getElementById('set-admin-link').style.display = '';
|
|
864
858
|
if (data.hasUsers && data.role === 'operator') {
|
|
865
859
|
document.getElementById('set-account').style.display = '';
|
|
866
860
|
document.getElementById('passwd-btn').style.display = '';
|
|
@@ -1029,8 +1023,8 @@
|
|
|
1029
1023
|
|
|
1030
1024
|
window.openSettings = function() {
|
|
1031
1025
|
renderAppearance();
|
|
1032
|
-
['set-machine-status', '
|
|
1033
|
-
|
|
1026
|
+
['set-machine-status', 'set-asr-status', 'set-restart-status'].forEach(id => setStatus(id, ''));
|
|
1027
|
+
document.querySelectorAll('#set-sheet .set-btn').forEach(b => b.classList.remove('dirty'));
|
|
1034
1028
|
document.getElementById('set-backdrop').classList.add('open');
|
|
1035
1029
|
document.getElementById('set-sheet').classList.add('open');
|
|
1036
1030
|
fetch('/api/machine-name').then(readJson).then(d => {
|
|
@@ -1043,8 +1037,14 @@
|
|
|
1043
1037
|
fetch('/api/server-config').then(readJson).then(d => {
|
|
1044
1038
|
document.getElementById('set-asr-url').value = d.asrUrl || '';
|
|
1045
1039
|
}).catch(() => {});
|
|
1046
|
-
loadAtRoots();
|
|
1047
1040
|
};
|
|
1041
|
+
// 输入框改了内容 → 保存按钮亮起;回车 = 保存
|
|
1042
|
+
document.querySelectorAll('#set-sheet input[data-save]').forEach(inp => {
|
|
1043
|
+
const btn = inp.nextElementSibling;
|
|
1044
|
+
inp.addEventListener('input', () => btn.classList.add('dirty'));
|
|
1045
|
+
inp.addEventListener('keydown', (e) => { if (e.key === 'Enter' && !e.isComposing) { e.preventDefault(); window[inp.dataset.save](); } });
|
|
1046
|
+
});
|
|
1047
|
+
const _savedOk = (inp) => document.getElementById(inp).nextElementSibling.classList.remove('dirty');
|
|
1048
1048
|
window.closeSettings = function() {
|
|
1049
1049
|
document.getElementById('set-backdrop').classList.remove('open');
|
|
1050
1050
|
document.getElementById('set-sheet').classList.remove('open');
|
|
@@ -1062,7 +1062,8 @@
|
|
|
1062
1062
|
const d = await readJson(r);
|
|
1063
1063
|
if (!d.ok) throw new Error(d.error || '未知错误');
|
|
1064
1064
|
window.myhiSetMachineName?.(d.name);
|
|
1065
|
-
|
|
1065
|
+
_savedOk('set-machine-name');
|
|
1066
|
+
setStatus('set-machine-status', `✓ 已保存为「${d.name}」,其他已打开的页面刷新后生效`, 'green');
|
|
1066
1067
|
} catch (e) { setStatus('set-machine-status', '保存失败:' + e.message, 'red'); }
|
|
1067
1068
|
};
|
|
1068
1069
|
|
|
@@ -1075,7 +1076,8 @@
|
|
|
1075
1076
|
});
|
|
1076
1077
|
const d = await readJson(r);
|
|
1077
1078
|
if (!d.ok) throw new Error(d.error || '未知错误');
|
|
1078
|
-
|
|
1079
|
+
_savedOk('set-asr-url');
|
|
1080
|
+
setStatus('set-asr-status', url ? '✓ 已保存,重启 myhi 后生效(设了 ASR_URL 环境变量时以环境变量为准)' : '✓ 已清空,语音输入关闭', 'green');
|
|
1079
1081
|
} catch (e) { setStatus('set-asr-status', '保存失败:' + e.message, 'red'); }
|
|
1080
1082
|
};
|
|
1081
1083
|
|
|
@@ -1085,87 +1087,6 @@
|
|
|
1085
1087
|
setStatus('set-restart-status', '服务重启中,请稍候…');
|
|
1086
1088
|
};
|
|
1087
1089
|
|
|
1088
|
-
// @ 引用范围(项目外目录):@ 补全可引用这些目录
|
|
1089
|
-
let _atRoots = [];
|
|
1090
|
-
function renderAtRoots() {
|
|
1091
|
-
document.getElementById('atroots-list').innerHTML = _atRoots.length
|
|
1092
|
-
? _atRoots.map((r, i) => `<div class="atr-row"><span title="${esc(r)}">📁 ${esc(r)}</span><button class="dr-btn" onclick="delAtRoot(${i})">删</button></div>`).join('')
|
|
1093
|
-
: '<div class="set-hint" style="margin:0">(未配置——@ 只搜任务目录)</div>';
|
|
1094
|
-
}
|
|
1095
|
-
function loadAtRoots() {
|
|
1096
|
-
fetch('/api/atroots').then(readJson).then(d => { _atRoots = d.roots || []; renderAtRoots(); }).catch(() => {});
|
|
1097
|
-
}
|
|
1098
|
-
async function saveAtRoots(roots) {
|
|
1099
|
-
try {
|
|
1100
|
-
const r = await fetch('/api/atroots', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ roots }) });
|
|
1101
|
-
const d = await readJson(r);
|
|
1102
|
-
if (!d.ok) throw new Error(d.error || '未知错误');
|
|
1103
|
-
_atRoots = d.roots; renderAtRoots(); setStatus('atroot-status', '已保存', 'green');
|
|
1104
|
-
return true;
|
|
1105
|
-
} catch (e) { setStatus('atroot-status', '保存失败:' + e.message, 'red'); return false; }
|
|
1106
|
-
}
|
|
1107
|
-
window.addAtRoot = function() {
|
|
1108
|
-
const inp = document.getElementById('atroot-new');
|
|
1109
|
-
const v = inp.value.trim();
|
|
1110
|
-
if (v) saveAtRoots([..._atRoots, v]).then(ok => { if (ok) inp.value = ''; });
|
|
1111
|
-
};
|
|
1112
|
-
window.delAtRoot = function(i) { saveAtRoots(_atRoots.filter((_, j) => j !== i)); };
|
|
1113
|
-
|
|
1114
|
-
// 文件夹点选(复用 /api/dirs 目录浏览):普通用户不会敲绝对路径,点进去选中即可
|
|
1115
|
-
let _atPick = { current: '', parent: null };
|
|
1116
|
-
window.openAtPicker = function() {
|
|
1117
|
-
document.getElementById('atpick').style.display = '';
|
|
1118
|
-
document.getElementById('atpick-open').style.display = 'none';
|
|
1119
|
-
atPickGo('');
|
|
1120
|
-
};
|
|
1121
|
-
window.closeAtPicker = function() {
|
|
1122
|
-
document.getElementById('atpick').style.display = 'none';
|
|
1123
|
-
document.getElementById('atpick-open').style.display = '';
|
|
1124
|
-
};
|
|
1125
|
-
window.atPickGo = async function(path) {
|
|
1126
|
-
const list = document.getElementById('atpick-list');
|
|
1127
|
-
list.innerHTML = '<div class="set-hint" style="padding:0.6rem;margin:0">读取中…</div>';
|
|
1128
|
-
try {
|
|
1129
|
-
const r = await fetch('/api/dirs' + (path ? '?path=' + encodeURIComponent(path) : ''));
|
|
1130
|
-
const d = await readJson(r);
|
|
1131
|
-
if (!r.ok) throw new Error(d.error || r.status);
|
|
1132
|
-
_atPick = d;
|
|
1133
|
-
const cur = document.getElementById('atpick-cur');
|
|
1134
|
-
cur.textContent = '\u200e' + d.current; // rtl 截断时保留路径尾部;LRM 防标点跑位
|
|
1135
|
-
cur.title = d.current;
|
|
1136
|
-
const up = document.getElementById('atpick-up');
|
|
1137
|
-
up.disabled = !d.parent; up.style.opacity = d.parent ? '' : '0.4';
|
|
1138
|
-
const dv = document.getElementById('atpick-drives');
|
|
1139
|
-
dv.style.display = (d.drives || []).length ? 'flex' : 'none';
|
|
1140
|
-
dv.innerHTML = '';
|
|
1141
|
-
(d.drives || []).forEach(dr => {
|
|
1142
|
-
const b = document.createElement('button');
|
|
1143
|
-
b.className = 'dr-btn';
|
|
1144
|
-
b.textContent = '💽 ' + dr.replace(/\\$/, '');
|
|
1145
|
-
if (d.current.toUpperCase().startsWith(dr.toUpperCase())) b.style.cssText = 'background:var(--accent);color:#fff;border-color:var(--accent)';
|
|
1146
|
-
b.onclick = () => atPickGo(dr);
|
|
1147
|
-
dv.appendChild(b);
|
|
1148
|
-
});
|
|
1149
|
-
list.innerHTML = d.dirs.length ? '' : '<div class="set-hint" style="padding:0.6rem;margin:0">(没有子文件夹)</div>';
|
|
1150
|
-
d.dirs.forEach(x => {
|
|
1151
|
-
const row = document.createElement('div');
|
|
1152
|
-
row.className = 'atpick-row';
|
|
1153
|
-
row.textContent = '📁 ' + x.name;
|
|
1154
|
-
row.onclick = () => atPickGo(x.path);
|
|
1155
|
-
list.appendChild(row);
|
|
1156
|
-
});
|
|
1157
|
-
} catch (e) {
|
|
1158
|
-
list.innerHTML = '<div style="padding:0.6rem;color:var(--red);font-size:0.75rem">读取失败:' + esc(String(e.message || e)) +
|
|
1159
|
-
(String(e.message).includes('权限') ? '(仅管理员可浏览目录,可展开下方「手动输入路径」)' : '') + '</div>';
|
|
1160
|
-
}
|
|
1161
|
-
};
|
|
1162
|
-
window.atPickUp = function() { if (_atPick.parent) atPickGo(_atPick.parent); };
|
|
1163
|
-
window.addAtPicked = async function() {
|
|
1164
|
-
const p = _atPick.current;
|
|
1165
|
-
if (!p) return;
|
|
1166
|
-
if (_atRoots.includes(p)) { setStatus('atroot-status', '这个文件夹已经在列表里了'); return; }
|
|
1167
|
-
if (await saveAtRoots([..._atRoots, p])) closeAtPicker();
|
|
1168
|
-
};
|
|
1169
1090
|
// 会话页「更多 → 全局设置」跳过来:/?settings=1 直接打开
|
|
1170
1091
|
if (new URLSearchParams(location.search).get('settings')) {
|
|
1171
1092
|
history.replaceState(null, '', location.pathname);
|