myagent-ai 1.7.3 → 1.7.4
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/package.json +1 -1
- package/web/ui/chat/chat.css +149 -1
- package/web/ui/chat/chat_container.html +3 -0
- package/web/ui/chat/chat_main.js +114 -7
- package/web/ui/chat/groupchat.js +8 -9
- package/web/ui/chat/middle_chat.html +3 -0
- package/web/ui/chat/right_agents.html +6 -1
- package/web/ui/index.html +43 -2
- package/agents/__pycache__/main_agent.cpython-312.pyc +0 -0
- package/web/__pycache__/api_server.cpython-312.pyc +0 -0
package/package.json
CHANGED
package/web/ui/chat/chat.css
CHANGED
|
@@ -588,6 +588,13 @@ input,textarea,select{font:inherit}
|
|
|
588
588
|
}
|
|
589
589
|
.rp-section-toggle:hover{background:var(--bg4);color:var(--text)}
|
|
590
590
|
.rp-section-toggle.expanded{transform:rotate(90deg)}
|
|
591
|
+
.rp-section-action-btn{
|
|
592
|
+
width:20px;height:20px;border-radius:3px;border:none;
|
|
593
|
+
background:transparent;color:var(--text3);
|
|
594
|
+
display:inline-grid;place-items:center;flex-shrink:0;
|
|
595
|
+
cursor:pointer;transition:var(--transition);
|
|
596
|
+
}
|
|
597
|
+
.rp-section-action-btn:hover{background:var(--bg4);color:var(--accent)}
|
|
591
598
|
|
|
592
599
|
/* Master Agent Card (全权Agent) */
|
|
593
600
|
.rp-master-card{
|
|
@@ -1204,8 +1211,9 @@ input,textarea,select{font:inherit}
|
|
|
1204
1211
|
opacity:0;position:absolute;right:8px;top:50%;transform:translateY(-50%);
|
|
1205
1212
|
width:24px;height:24px;border-radius:4px;display:grid;place-items:center;
|
|
1206
1213
|
background:var(--bg2);transition:var(--transition);font-size:12px;color:var(--text3);
|
|
1214
|
+
pointer-events:none;
|
|
1207
1215
|
}
|
|
1208
|
-
.group-item:hover .group-delete{opacity:1}
|
|
1216
|
+
.group-item:hover .group-delete{opacity:1;pointer-events:auto}
|
|
1209
1217
|
.group-delete:hover{background:var(--danger);color:#fff}
|
|
1210
1218
|
|
|
1211
1219
|
/* Group Chat Messages */
|
|
@@ -1643,3 +1651,143 @@ input,textarea,select{font:inherit}
|
|
|
1643
1651
|
font-family: inherit;
|
|
1644
1652
|
white-space: pre-wrap;
|
|
1645
1653
|
}
|
|
1654
|
+
|
|
1655
|
+
/* ══════════════════════════════════════════════════════
|
|
1656
|
+
── Mobile Responsive (≤768px) ──
|
|
1657
|
+
══════════════════════════════════════════════════════ */
|
|
1658
|
+
|
|
1659
|
+
/* ── Mobile Overlay Backdrop (placed outside media query so JS can always use it) ── */
|
|
1660
|
+
.mobile-overlay{
|
|
1661
|
+
position:fixed;inset:0;
|
|
1662
|
+
background:rgba(0,0,0,.4);
|
|
1663
|
+
z-index:45;
|
|
1664
|
+
opacity:0;visibility:hidden;
|
|
1665
|
+
transition:opacity .3s ease,visibility .3s ease;
|
|
1666
|
+
pointer-events:none;
|
|
1667
|
+
}
|
|
1668
|
+
.mobile-overlay.active{
|
|
1669
|
+
opacity:1;visibility:visible;
|
|
1670
|
+
pointer-events:auto;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
@media(max-width:768px){
|
|
1674
|
+
|
|
1675
|
+
/* ── Sidebar: Fixed overlay sliding from left ── */
|
|
1676
|
+
.sidebar{
|
|
1677
|
+
position:fixed;
|
|
1678
|
+
left:0;top:0;
|
|
1679
|
+
width:85vw;max-width:320px;
|
|
1680
|
+
height:100vh;
|
|
1681
|
+
z-index:50;
|
|
1682
|
+
transform:translateX(-100%);
|
|
1683
|
+
transition:transform .3s cubic-bezier(.4,0,.2,1);
|
|
1684
|
+
box-shadow:none;
|
|
1685
|
+
}
|
|
1686
|
+
.sidebar.mobile-open{
|
|
1687
|
+
transform:translateX(0);
|
|
1688
|
+
box-shadow:4px 0 24px rgba(0,0,0,.15);
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
/* ── Agent Panel: Fixed overlay sliding from right ── */
|
|
1692
|
+
.agent-panel{
|
|
1693
|
+
position:fixed;
|
|
1694
|
+
right:0;top:0;
|
|
1695
|
+
width:85vw;max-width:340px;
|
|
1696
|
+
height:100vh;
|
|
1697
|
+
z-index:50;
|
|
1698
|
+
transform:translateX(100%);
|
|
1699
|
+
transition:transform .3s cubic-bezier(.4,0,.2,1);
|
|
1700
|
+
box-shadow:none;
|
|
1701
|
+
}
|
|
1702
|
+
.agent-panel.mobile-open{
|
|
1703
|
+
transform:translateX(0);
|
|
1704
|
+
box-shadow:-4px 0 24px rgba(0,0,0,.15);
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
/* ── Hide desktop toggle buttons on mobile ── */
|
|
1708
|
+
.sidebar-toggle,
|
|
1709
|
+
.agent-toggle{
|
|
1710
|
+
display:none!important;
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
/* ── Header ── */
|
|
1714
|
+
.main-header{
|
|
1715
|
+
height:50px;min-height:50px;
|
|
1716
|
+
padding:0 12px;
|
|
1717
|
+
}
|
|
1718
|
+
.main-title{
|
|
1719
|
+
font-size:14px;
|
|
1720
|
+
white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
|
|
1721
|
+
min-width:0;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
/* ── Messages ── */
|
|
1725
|
+
.messages-container{
|
|
1726
|
+
padding:12px;
|
|
1727
|
+
}
|
|
1728
|
+
.messages-inner{
|
|
1729
|
+
max-width:100%;
|
|
1730
|
+
}
|
|
1731
|
+
.message-bubble{
|
|
1732
|
+
max-width:88%;
|
|
1733
|
+
}
|
|
1734
|
+
.message-bubble pre{
|
|
1735
|
+
font-size:12px;
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
/* ── Input Area ── */
|
|
1739
|
+
.input-area{
|
|
1740
|
+
padding:10px 12px;
|
|
1741
|
+
}
|
|
1742
|
+
.input-wrapper{
|
|
1743
|
+
max-width:100%;
|
|
1744
|
+
}
|
|
1745
|
+
.input-box textarea{
|
|
1746
|
+
min-height:60px;
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
/* ── Modals ── */
|
|
1750
|
+
.modal,
|
|
1751
|
+
.agent-modal,
|
|
1752
|
+
.platform-modal{
|
|
1753
|
+
width:95%;max-height:90vh;padding:20px;
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
/* ── Toast ── */
|
|
1757
|
+
.toast-container{
|
|
1758
|
+
top:12px;right:12px;left:12px;
|
|
1759
|
+
}
|
|
1760
|
+
.toast{
|
|
1761
|
+
max-width:100%;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
/* ── Welcome Card Capabilities ── */
|
|
1765
|
+
.capabilities{
|
|
1766
|
+
grid-template-columns:1fr 1fr;
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
/* ── Execution Timer ── */
|
|
1770
|
+
.exec-timer{
|
|
1771
|
+
max-width:100%;
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
/* ── Empty State ── */
|
|
1775
|
+
.empty-icon{
|
|
1776
|
+
font-size:40px;
|
|
1777
|
+
}
|
|
1778
|
+
.empty-title{
|
|
1779
|
+
font-size:16px;
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
/* ══════════════════════════════════════════════════════
|
|
1784
|
+
── Very Small Phones (≤480px) ──
|
|
1785
|
+
══════════════════════════════════════════════════════ */
|
|
1786
|
+
@media(max-width:480px){
|
|
1787
|
+
.message-bubble{
|
|
1788
|
+
max-width:92%;
|
|
1789
|
+
}
|
|
1790
|
+
.main-header{
|
|
1791
|
+
padding:0 8px;
|
|
1792
|
+
}
|
|
1793
|
+
}
|
package/web/ui/chat/chat_main.js
CHANGED
|
@@ -28,18 +28,119 @@ initTheme();
|
|
|
28
28
|
document.getElementById('themeToggle')?.addEventListener('click', toggleTheme);
|
|
29
29
|
|
|
30
30
|
// ── Sidebar Collapse ──
|
|
31
|
+
function isMobile() { return window.innerWidth <= 768; }
|
|
32
|
+
|
|
31
33
|
function toggleSidebar() {
|
|
32
34
|
const sidebar = document.getElementById('sidebar');
|
|
33
35
|
const toggleBtn = document.getElementById('sidebarToggle');
|
|
34
36
|
if (!sidebar) return;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
if (isMobile()) {
|
|
38
|
+
// Mobile: toggle as overlay
|
|
39
|
+
const overlay = document.getElementById('chatMobileOverlay');
|
|
40
|
+
const isOpen = sidebar.classList.contains('mobile-open');
|
|
41
|
+
if (isOpen) {
|
|
42
|
+
closeMobileSidebar();
|
|
43
|
+
} else {
|
|
44
|
+
sidebar.classList.add('mobile-open');
|
|
45
|
+
if (overlay) overlay.classList.add('active');
|
|
46
|
+
// Close agent panel if open
|
|
47
|
+
closeMobileAgentPanel();
|
|
48
|
+
}
|
|
49
|
+
} else {
|
|
50
|
+
// Desktop: collapse/expand
|
|
51
|
+
sidebar.classList.toggle('collapsed');
|
|
52
|
+
const isCollapsed = sidebar.classList.contains('collapsed');
|
|
53
|
+
if (toggleBtn) toggleBtn.textContent = isCollapsed ? '▶' : '◀';
|
|
54
|
+
localStorage.setItem('myagent-sidebar-collapsed', isCollapsed);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function closeMobileSidebar() {
|
|
59
|
+
const sidebar = document.getElementById('sidebar');
|
|
60
|
+
const overlay = document.getElementById('chatMobileOverlay');
|
|
61
|
+
if (sidebar) sidebar.classList.remove('mobile-open');
|
|
62
|
+
if (overlay) overlay.classList.remove('active');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function toggleMobileAgentPanel() {
|
|
66
|
+
const panel = document.getElementById('agentPanel');
|
|
67
|
+
const overlay = document.getElementById('chatMobileOverlay');
|
|
68
|
+
if (!panel) return;
|
|
69
|
+
const isOpen = panel.classList.contains('mobile-open');
|
|
70
|
+
if (isOpen) {
|
|
71
|
+
closeMobileAgentPanel();
|
|
72
|
+
} else {
|
|
73
|
+
panel.classList.add('mobile-open');
|
|
74
|
+
if (overlay) overlay.classList.add('active');
|
|
75
|
+
// Close sidebar if open
|
|
76
|
+
closeMobileSidebar();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function closeMobileAgentPanel() {
|
|
81
|
+
const panel = document.getElementById('agentPanel');
|
|
82
|
+
const overlay = document.getElementById('chatMobileOverlay');
|
|
83
|
+
if (panel) panel.classList.remove('mobile-open');
|
|
84
|
+
if (overlay) overlay.classList.remove('active');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Mobile overlay click closes both panels
|
|
88
|
+
document.addEventListener('click', function(e) {
|
|
89
|
+
if (e.target && e.target.id === 'chatMobileOverlay') {
|
|
90
|
+
closeMobileSidebar();
|
|
91
|
+
closeMobileAgentPanel();
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Show/hide mobile agents button based on screen size
|
|
96
|
+
function checkChatMobile() {
|
|
97
|
+
const btn = document.getElementById('mobileAgentsBtn');
|
|
98
|
+
if (btn) btn.style.display = isMobile() ? 'grid' : 'none';
|
|
39
99
|
}
|
|
40
|
-
|
|
100
|
+
window.addEventListener('resize', checkChatMobile);
|
|
101
|
+
// Run after DOM ready
|
|
102
|
+
if (document.readyState === 'loading') {
|
|
103
|
+
document.addEventListener('DOMContentLoaded', checkChatMobile);
|
|
104
|
+
} else {
|
|
105
|
+
checkChatMobile();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Override toggleAgentPanel for mobile (deferred since function is defined later)
|
|
109
|
+
var _origToggleAgentPanel = null;
|
|
110
|
+
(function() {
|
|
111
|
+
var origDef = toggleAgentPanel;
|
|
112
|
+
if (typeof origDef === 'function') {
|
|
113
|
+
_origToggleAgentPanel = origDef;
|
|
114
|
+
toggleAgentPanel = function() {
|
|
115
|
+
if (isMobile()) {
|
|
116
|
+
toggleMobileAgentPanel();
|
|
117
|
+
} else {
|
|
118
|
+
_origToggleAgentPanel();
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
})();
|
|
123
|
+
// Also override after definition via setTimeout (fallback)
|
|
124
|
+
setTimeout(function() {
|
|
125
|
+
if (!_origToggleAgentPanel && typeof toggleAgentPanel === 'function') {
|
|
126
|
+
// Check if it's already the mobile version
|
|
127
|
+
var testFn = toggleAgentPanel.toString();
|
|
128
|
+
if (testFn.indexOf('toggleMobileAgentPanel') === -1) {
|
|
129
|
+
_origToggleAgentPanel = toggleAgentPanel;
|
|
130
|
+
toggleAgentPanel = function() {
|
|
131
|
+
if (isMobile()) {
|
|
132
|
+
toggleMobileAgentPanel();
|
|
133
|
+
} else {
|
|
134
|
+
_origToggleAgentPanel();
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}, 0);
|
|
140
|
+
|
|
141
|
+
// Restore sidebar state (desktop only)
|
|
41
142
|
(function() {
|
|
42
|
-
if (localStorage.getItem('myagent-sidebar-collapsed') === 'true') {
|
|
143
|
+
if (localStorage.getItem('myagent-sidebar-collapsed') === 'true' && !isMobile()) {
|
|
43
144
|
const sidebar = document.getElementById('sidebar');
|
|
44
145
|
const toggleBtn = document.getElementById('sidebarToggle');
|
|
45
146
|
if (sidebar) sidebar.classList.add('collapsed');
|
|
@@ -966,6 +1067,7 @@ async function selectAgent(agentPath) {
|
|
|
966
1067
|
// 如果 loadSessions 已经 auto-selected 了 session,UI 已由 selectSession 设置好,不再覆盖
|
|
967
1068
|
|
|
968
1069
|
document.getElementById('userInput').focus();
|
|
1070
|
+
if (isMobile()) closeMobileAgentPanel();
|
|
969
1071
|
// Reload task plan if in exec mode
|
|
970
1072
|
if (state.chatMode === 'exec') loadTaskPlan();
|
|
971
1073
|
// Reset escalation and update exec mode UI
|
|
@@ -1434,9 +1536,13 @@ function newChat() {
|
|
|
1434
1536
|
async function selectSession(id) {
|
|
1435
1537
|
if (id === '__new__') {
|
|
1436
1538
|
newChat();
|
|
1539
|
+
if (isMobile()) closeMobileSidebar();
|
|
1540
|
+
return;
|
|
1541
|
+
}
|
|
1542
|
+
if (state.activeSessionId === id && state.messages.length > 0) {
|
|
1543
|
+
if (isMobile()) closeMobileSidebar();
|
|
1437
1544
|
return;
|
|
1438
1545
|
}
|
|
1439
|
-
if (state.activeSessionId === id && state.messages.length > 0) return;
|
|
1440
1546
|
|
|
1441
1547
|
// 重置生成状态,防止残留的 isGenerating=true 导致输入框锁定
|
|
1442
1548
|
state.isGenerating = false;
|
|
@@ -1470,6 +1576,7 @@ async function selectSession(id) {
|
|
|
1470
1576
|
}
|
|
1471
1577
|
renderMessages();
|
|
1472
1578
|
document.getElementById('userInput').focus();
|
|
1579
|
+
if (isMobile()) closeMobileSidebar();
|
|
1473
1580
|
}
|
|
1474
1581
|
|
|
1475
1582
|
async function deleteSession(id) {
|
package/web/ui/chat/groupchat.js
CHANGED
|
@@ -37,7 +37,7 @@ async function fetchGroups() {
|
|
|
37
37
|
async function createGroupApi(name, description, emoji, color, members) {
|
|
38
38
|
return await api('/api/groups', {
|
|
39
39
|
method: 'POST',
|
|
40
|
-
body: JSON.stringify({ name, description, emoji, color, members }),
|
|
40
|
+
body: JSON.stringify({ name, description, avatar_emoji: emoji, avatar_color: color, members }),
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -109,13 +109,12 @@ function renderGroups() {
|
|
|
109
109
|
var memberCount = (g.members || []).length;
|
|
110
110
|
var isActive = g.id === currentGroupId;
|
|
111
111
|
html += '<div class="group-item ' + (isActive ? 'active' : '') + '" onclick="selectGroup(\'' + escapeHtml(g.id) + '\')" title="' + escapeHtml(g.name) + '">';
|
|
112
|
-
html += '<div class="group-icon">' + escapeHtml(g.emoji || '👥') + '</div>';
|
|
112
|
+
html += '<div class="group-icon"' + (g.avatar_color ? ' style="background:' + escapeHtml(g.avatar_color) + ';color:#fff"' : '') + '>' + escapeHtml(g.avatar_emoji || g.emoji || '👥') + '</div>';
|
|
113
113
|
html += '<div class="group-info">';
|
|
114
114
|
html += '<div class="group-name">' + escapeHtml(g.name) + '</div>';
|
|
115
115
|
html += '<div class="group-preview">' + escapeHtml(g.description || memberCount + ' 位成员') + '</div>';
|
|
116
116
|
html += '</div>';
|
|
117
117
|
html += '<span class="group-badge">' + memberCount + '</span>';
|
|
118
|
-
html += '<button class="group-delete" onclick="event.stopPropagation();deleteGroupConfirm(\'' + escapeHtml(g.id) + '\')" title="删除">✕</button>';
|
|
119
118
|
html += '</div>';
|
|
120
119
|
}
|
|
121
120
|
listEl.innerHTML = html;
|
|
@@ -145,7 +144,7 @@ async function selectGroup(gid) {
|
|
|
145
144
|
var groupData = await getGroup(gid);
|
|
146
145
|
|
|
147
146
|
// Update header
|
|
148
|
-
document.getElementById('headerTitle').textContent = (groupData.emoji || '👥') + ' ' + groupData.name;
|
|
147
|
+
document.getElementById('headerTitle').textContent = (groupData.avatar_emoji || groupData.emoji || '👥') + ' ' + groupData.name;
|
|
149
148
|
document.getElementById('activeAgentBadge').style.display = 'none';
|
|
150
149
|
document.getElementById('groupBackBtn').style.display = '';
|
|
151
150
|
document.getElementById('groupSettingsBtn').style.display = '';
|
|
@@ -217,7 +216,7 @@ function renderGroupMessages() {
|
|
|
217
216
|
if (groupMessages.length === 0) {
|
|
218
217
|
var group = groups.find(function(g) { return g.id === currentGroupId; });
|
|
219
218
|
html = '<div class="welcome-card">'
|
|
220
|
-
+ '<h2><span class="emoji">' + escapeHtml((group && group.emoji) || '👥') + '</span>'
|
|
219
|
+
+ '<h2><span class="emoji">' + escapeHtml((group && (group.avatar_emoji || group.emoji)) || '👥') + '</span>'
|
|
221
220
|
+ ' <span>群聊: ' + escapeHtml((group && group.name) || '') + '</span></h2>'
|
|
222
221
|
+ '<p class="subtitle">向所有成员发送消息,每个 Agent 会分别回复</p>'
|
|
223
222
|
+ '</div>';
|
|
@@ -426,8 +425,8 @@ async function showGroupSettingsModal() {
|
|
|
426
425
|
+ '</div>'
|
|
427
426
|
+ '<div class="agent-form-group"><label>头像</label>'
|
|
428
427
|
+ '<div class="agent-avatar-picker" id="groupSettingsEmojiPicker">'
|
|
429
|
-
+ emojis.map(function(e) { return '<div class="agent-avatar-option ' + ((groupData.emoji || '👥') === e ? 'selected' : '') + '" onclick="pickGroupSettingsEmoji(this,\'' + e + '\')" data-emoji="' + e + '">' + e + '</div>'; }).join('')
|
|
430
|
-
+ '</div><input type="hidden" id="groupSettingsEmoji" value="' + escapeHtml(groupData.emoji || '👥') + '"></div>'
|
|
428
|
+
+ emojis.map(function(e) { return '<div class="agent-avatar-option ' + ((groupData.avatar_emoji || groupData.emoji || '👥') === e ? 'selected' : '') + '" onclick="pickGroupSettingsEmoji(this,\'' + e + '\')" data-emoji="' + e + '">' + e + '</div>'; }).join('')
|
|
429
|
+
+ '</div><input type="hidden" id="groupSettingsEmoji" value="' + escapeHtml(groupData.avatar_emoji || groupData.emoji || '👥') + '"></div>'
|
|
431
430
|
+ '<div class="agent-form-group"><label>成员 (' + members.length + ')</label>'
|
|
432
431
|
+ '<div style="margin-bottom:8px">'
|
|
433
432
|
+ '<button class="config-action-btn" onclick="showAddMemberToGroup()" style="font-size:12px;padding:6px 12px">'
|
|
@@ -463,14 +462,14 @@ async function saveGroupSettings() {
|
|
|
463
462
|
await updateGroup(currentGroupId, {
|
|
464
463
|
name: name,
|
|
465
464
|
description: document.getElementById('groupSettingsDesc').value.trim(),
|
|
466
|
-
|
|
465
|
+
avatar_emoji: document.getElementById('groupSettingsEmoji').value
|
|
467
466
|
});
|
|
468
467
|
toast('群聊设置已保存', 'success');
|
|
469
468
|
closeGroupModal();
|
|
470
469
|
await fetchGroups();
|
|
471
470
|
var group = groups.find(function(g) { return g.id === currentGroupId; });
|
|
472
471
|
if (group) {
|
|
473
|
-
document.getElementById('headerTitle').textContent = (group.emoji || '👥') + ' ' + group.name;
|
|
472
|
+
document.getElementById('headerTitle').textContent = (group.avatar_emoji || group.emoji || '👥') + ' ' + group.name;
|
|
474
473
|
}
|
|
475
474
|
} catch (e) {
|
|
476
475
|
toast('保存失败: ' + e.message, 'error');
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
</span>
|
|
13
13
|
</div>
|
|
14
14
|
<div class="header-actions">
|
|
15
|
+
<button class="header-btn" id="mobileAgentsBtn" onclick="toggleMobileAgentPanel()" title="Agents" style="display:none">
|
|
16
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
|
17
|
+
</button>
|
|
15
18
|
<button class="header-btn" id="groupBackBtn" onclick="exitGroupChat()" title="返回对话" style="display:none">
|
|
16
19
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"/></svg>
|
|
17
20
|
</button>
|
|
@@ -39,7 +39,12 @@
|
|
|
39
39
|
<div id="rpGroupSection">
|
|
40
40
|
<div class="rp-section-header" onclick="toggleRpSection('group')">
|
|
41
41
|
<span class="rp-section-title">👥 群聊</span>
|
|
42
|
-
<
|
|
42
|
+
<div style="display:flex;align-items:center;gap:4px">
|
|
43
|
+
<button class="rp-section-action-btn" onclick="event.stopPropagation();showCreateGroupModal()" title="创建群聊">
|
|
44
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:14px;height:14px"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
|
45
|
+
</button>
|
|
46
|
+
<span class="rp-section-toggle expanded" id="rpGroupToggle">▶</span>
|
|
47
|
+
</div>
|
|
43
48
|
</div>
|
|
44
49
|
<div class="rp-section-body" id="rpGroupBody">
|
|
45
50
|
<div class="group-list" id="groupList">
|
package/web/ui/index.html
CHANGED
|
@@ -151,6 +151,29 @@ tr:hover{background:var(--surface2)}
|
|
|
151
151
|
[data-theme="claude"] .badge-red{background:#c9444422}
|
|
152
152
|
[data-theme="claude"] .badge-yellow{background:#c4862b22}
|
|
153
153
|
[data-theme="claude"] .badge-blue{background:#4a7fc922}
|
|
154
|
+
/* ── Mobile Responsive ── */
|
|
155
|
+
@media(max-width:768px){
|
|
156
|
+
body{flex-direction:column}
|
|
157
|
+
.sidebar{position:fixed;left:0;top:0;height:100vh;width:260px;max-width:80vw;z-index:50;transform:translateX(-100%);transition:transform .3s ease;flex-shrink:0}
|
|
158
|
+
.sidebar.mobile-open{transform:translateX(0)}
|
|
159
|
+
.sidebar.collapsed{width:260px;transform:translateX(-100%)}
|
|
160
|
+
.sidebar.collapsed.mobile-open{transform:translateX(0)}
|
|
161
|
+
.sidebar-toggle{display:none!important}
|
|
162
|
+
.mobile-overlay{position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:45;display:none}
|
|
163
|
+
.mobile-overlay.active{display:block}
|
|
164
|
+
.header{padding:12px 16px}
|
|
165
|
+
.header h2{font-size:16px}
|
|
166
|
+
.content{padding:16px}
|
|
167
|
+
.grid{grid-template-columns:1fr}
|
|
168
|
+
.form-row{grid-template-columns:1fr}
|
|
169
|
+
.table-wrap{overflow-x:auto}
|
|
170
|
+
.modal{width:95%;max-height:90vh;padding:16px}
|
|
171
|
+
.modal-wide{max-width:95%}
|
|
172
|
+
.tabs{gap:0;overflow-x:auto}
|
|
173
|
+
.toast{left:16px;right:16px;bottom:16px}
|
|
174
|
+
.agent-card{flex-direction:column;align-items:flex-start}
|
|
175
|
+
.agent-card .flex.flex-col{flex-direction:row;gap:4px}
|
|
176
|
+
}
|
|
154
177
|
</style>
|
|
155
178
|
</head>
|
|
156
179
|
<body>
|
|
@@ -181,8 +204,9 @@ tr:hover{background:var(--surface2)}
|
|
|
181
204
|
· <a href="#" onclick="checkUpdate(true)" style="color:var(--primary)">检查更新</a>
|
|
182
205
|
</div>
|
|
183
206
|
</div>
|
|
207
|
+
<div class="mobile-overlay" id="adminMobileOverlay" onclick="closeMobileSidebar()"></div>
|
|
184
208
|
<div class="main">
|
|
185
|
-
<div class="header"><div style="display:flex;align-items:center;gap:12px"><h2 id="pageTitle">📊 仪表盘</h2><button class="header-btn" id="themeToggle" title="切换主题"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg></button></div><div style="display:flex;align-items:center;gap:8px"><span class="status-dot"></span>运行中</div></div>
|
|
209
|
+
<div class="header"><div style="display:flex;align-items:center;gap:12px"><button class="header-btn" id="mobileMenuBtn" onclick="toggleMobileSidebar()" style="display:none" title="菜单"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="20" height="20"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg></button><h2 id="pageTitle">📊 仪表盘</h2><button class="header-btn" id="themeToggle" title="切换主题"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg></button></div><div style="display:flex;align-items:center;gap:8px"><span class="status-dot"></span>运行中</div></div>
|
|
186
210
|
<div class="content" id="content"></div>
|
|
187
211
|
</div>
|
|
188
212
|
<div id="modalContainer"></div>
|
|
@@ -250,12 +274,28 @@ function initTheme(){const s=localStorage.getItem('myagent-theme')||'claude';doc
|
|
|
250
274
|
function toggleTheme(){const c=document.documentElement.getAttribute('data-theme')||'claude';const n=c==='claude'?'dark':'claude';document.documentElement.setAttribute('data-theme',n);localStorage.setItem('myagent-theme',n);updateThemeIcon(n)}
|
|
251
275
|
function updateThemeIcon(t){const b=document.getElementById('themeToggle');if(!b)return;if(t==='dark'){b.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>';b.title='切换到 Claude 风格'}else{b.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>';b.title='切换到夜间模式'}}
|
|
252
276
|
// ── Sidebar Collapse ──
|
|
253
|
-
function toggleSidebar(){const s=document.getElementById('adminSidebar');const t=document.getElementById('sidebarToggle');if(!s)return;s.classList.toggle('collapsed');const isCollapsed=s.classList.contains('collapsed');t.textContent=isCollapsed?'▶':'◀';localStorage.setItem('myagent-admin-sidebar-collapsed',isCollapsed)}
|
|
277
|
+
function toggleSidebar(){const s=document.getElementById('adminSidebar');const t=document.getElementById('sidebarToggle');if(!s)return;s.classList.toggle('collapsed');const isCollapsed=s.classList.contains('collapsed');t.textContent=isCollapsed?'▶':'◀';localStorage.setItem('myagent-admin-sidebar-collapsed',isCollapsed);closeMobileSidebar()}
|
|
254
278
|
// Initialize
|
|
255
279
|
initTheme();
|
|
256
280
|
document.getElementById('themeToggle')?.addEventListener('click',toggleTheme);
|
|
257
281
|
if(localStorage.getItem('myagent-admin-sidebar-collapsed')==='true'){document.getElementById('adminSidebar')?.classList.add('collapsed');const t=document.getElementById('sidebarToggle');if(t)t.textContent='▶'}
|
|
258
282
|
|
|
283
|
+
// ── Mobile Sidebar ──
|
|
284
|
+
function toggleMobileSidebar(){
|
|
285
|
+
const s=document.getElementById('adminSidebar');
|
|
286
|
+
const o=document.getElementById('adminMobileOverlay');
|
|
287
|
+
s.classList.toggle('mobile-open');
|
|
288
|
+
o.classList.toggle('active');
|
|
289
|
+
}
|
|
290
|
+
function closeMobileSidebar(){
|
|
291
|
+
document.getElementById('adminSidebar').classList.remove('mobile-open');
|
|
292
|
+
document.getElementById('adminMobileOverlay').classList.remove('active');
|
|
293
|
+
}
|
|
294
|
+
// Show hamburger on mobile
|
|
295
|
+
function checkMobile(){const btn=document.getElementById('mobileMenuBtn');if(btn)btn.style.display=window.innerWidth<=768?'grid':'none'}
|
|
296
|
+
window.addEventListener('resize',checkMobile);
|
|
297
|
+
checkMobile();
|
|
298
|
+
|
|
259
299
|
loadVersion();
|
|
260
300
|
setTimeout(()=>checkUpdate(false),30000);
|
|
261
301
|
function showConfirm(title,msg,onOk){
|
|
@@ -266,6 +306,7 @@ function showConfirm(title,msg,onOk){
|
|
|
266
306
|
}
|
|
267
307
|
|
|
268
308
|
function showPage(page){
|
|
309
|
+
closeMobileSidebar();
|
|
269
310
|
currentPage=page;
|
|
270
311
|
document.querySelectorAll('.nav-item').forEach((n,i)=>n.classList.toggle('active',Object.keys(pages)[i]===page));
|
|
271
312
|
$('pageTitle').textContent=pages[page]||page;
|
|
Binary file
|
|
Binary file
|