anentrypoint-design 0.0.121 → 0.0.124
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/README.md +253 -253
- package/app-shell.css +931 -594
- package/colors_and_type.css +226 -226
- package/community.css +817 -1222
- package/dist/247420.css +2202 -2084
- package/dist/247420.js +13 -13
- package/package.json +80 -80
- package/src/bootstrap.js +25 -25
- package/src/components/chat.js +199 -199
- package/src/components/community.js +190 -208
- package/src/components/content.js +269 -269
- package/src/components/editor-primitives.js +100 -0
- package/src/components/files-modals.js +107 -107
- package/src/components/files.js +118 -118
- package/src/components/freddie/helpers.js +50 -50
- package/src/components/freddie.js +33 -33
- package/src/components/shell.js +117 -117
- package/src/components/theme-toggle.js +70 -70
- package/src/components.js +59 -57
- package/src/debug.js +30 -30
- package/src/deck-stage.js +21 -21
- package/src/highlight.js +65 -32
- package/src/index.js +86 -86
- package/src/kits/os/about-app.js +52 -52
- package/src/kits/os/app-panes.css +152 -152
- package/src/kits/os/browser-app.js +58 -58
- package/src/kits/os/files-app.js +44 -44
- package/src/kits/os/freddie/helpers.js +59 -59
- package/src/kits/os/freddie/pages-chat.js +143 -143
- package/src/kits/os/freddie/pages-core.js +101 -101
- package/src/kits/os/freddie/pages-os.js +51 -51
- package/src/kits/os/freddie/pages-tools.js +183 -183
- package/src/kits/os/freddie/routes.js +24 -24
- package/src/kits/os/freddie-dashboard.css +51 -51
- package/src/kits/os/freddie-dashboard.js +101 -101
- package/src/kits/os/icons.js +17 -17
- package/src/kits/os/index.js +17 -17
- package/src/kits/os/launcher.css +61 -61
- package/src/kits/os/launcher.js +79 -79
- package/src/kits/os/monitor-app.js +34 -34
- package/src/kits/os/shell.js +214 -214
- package/src/kits/os/terminal-app.js +45 -45
- package/src/kits/os/theme.css +450 -450
- package/src/kits/os/validate.css +19 -19
- package/src/kits/os/validator-app.js +55 -55
- package/src/kits/os/wm.css +115 -115
- package/src/kits/os/wm.js +111 -111
- package/src/markdown.js +39 -39
- package/src/motion.js +35 -35
- package/src/page-html.js +196 -196
- package/src/styles.js +25 -25
- package/src/theme.js +99 -99
- package/src/web-components/ds-chat.js +116 -116
- package/dist/.nojekyll +0 -0
- package/dist/app-shell.css +0 -594
- package/dist/colors_and_type.css +0 -197
- package/dist/favicon.svg +0 -1
- package/dist/index.html +0 -308
- package/dist/preview/buttons.html +0 -28
- package/dist/preview/colors-core.html +0 -45
- package/dist/preview/colors-lore.html +0 -28
- package/dist/preview/colors-semantic.html +0 -34
- package/dist/preview/dateline.html +0 -19
- package/dist/preview/dropzone.html +0 -30
- package/dist/preview/file-grid.html +0 -19
- package/dist/preview/file-row.html +0 -20
- package/dist/preview/file-toolbar.html +0 -40
- package/dist/preview/file-viewer.html +0 -31
- package/dist/preview/header.html +0 -24
- package/dist/preview/icons-unicode.html +0 -26
- package/dist/preview/index-row.html +0 -25
- package/dist/preview/inputs.html +0 -22
- package/dist/preview/manifesto.html +0 -52
- package/dist/preview/motion-default.js +0 -106
- package/dist/preview/rules.html +0 -16
- package/dist/preview/spacing.html +0 -18
- package/dist/preview/stamps-lore.html +0 -20
- package/dist/preview/stamps.html +0 -14
- package/dist/preview/theme-ink.html +0 -15
- package/dist/preview/type-display.html +0 -16
- package/dist/preview/type-mono.html +0 -15
- package/dist/preview/type-prose.html +0 -11
- package/dist/preview/type-scale.html +0 -20
- package/dist/preview/wordmarks.html +0 -28
- package/dist/robots.txt +0 -8
- package/dist/site/content/globals/navigation.yaml +0 -5
- package/dist/site/content/globals/site.yaml +0 -16
- package/dist/site/content/pages/freddie.yaml +0 -88
- package/dist/site/content/pages/home.yaml +0 -190
- package/dist/site/theme.mjs +0 -368
- package/dist/sitemap.xml +0 -31
- package/dist/slides/deck-stage-overlay.js +0 -63
- package/dist/slides/deck-stage-state.js +0 -81
- package/dist/slides/deck-stage-style.js +0 -117
- package/dist/slides/deck-stage.js +0 -159
- package/dist/slides/index.html +0 -276
- package/dist/src/bootstrap.js +0 -25
- package/dist/src/components/chat.js +0 -199
- package/dist/src/components/community.js +0 -167
- package/dist/src/components/content.js +0 -213
- package/dist/src/components/files-modals.js +0 -107
- package/dist/src/components/files.js +0 -118
- package/dist/src/components/freddie/helpers.js +0 -50
- package/dist/src/components/freddie.js +0 -33
- package/dist/src/components/shell.js +0 -117
- package/dist/src/components/theme-toggle.js +0 -70
- package/dist/src/components.js +0 -52
- package/dist/src/debug.js +0 -30
- package/dist/src/deck-stage.js +0 -21
- package/dist/src/highlight.js +0 -32
- package/dist/src/index.js +0 -86
- package/dist/src/kits/os/about-app.js +0 -52
- package/dist/src/kits/os/app-panes.css +0 -152
- package/dist/src/kits/os/browser-app.js +0 -58
- package/dist/src/kits/os/files-app.js +0 -44
- package/dist/src/kits/os/freddie/helpers.js +0 -59
- package/dist/src/kits/os/freddie/pages-chat.js +0 -143
- package/dist/src/kits/os/freddie/pages-core.js +0 -101
- package/dist/src/kits/os/freddie/pages-os.js +0 -51
- package/dist/src/kits/os/freddie/pages-tools.js +0 -183
- package/dist/src/kits/os/freddie/routes.js +0 -24
- package/dist/src/kits/os/freddie-dashboard.css +0 -51
- package/dist/src/kits/os/freddie-dashboard.js +0 -101
- package/dist/src/kits/os/icons.js +0 -17
- package/dist/src/kits/os/index.js +0 -5
- package/dist/src/kits/os/launcher.css +0 -61
- package/dist/src/kits/os/launcher.js +0 -79
- package/dist/src/kits/os/monitor-app.js +0 -34
- package/dist/src/kits/os/shell.js +0 -214
- package/dist/src/kits/os/terminal-app.js +0 -45
- package/dist/src/kits/os/theme.css +0 -412
- package/dist/src/kits/os/validate.css +0 -19
- package/dist/src/kits/os/validator-app.js +0 -55
- package/dist/src/kits/os/wm.css +0 -115
- package/dist/src/kits/os/wm.js +0 -111
- package/dist/src/markdown.js +0 -39
- package/dist/src/motion.js +0 -35
- package/dist/src/page-html.js +0 -196
- package/dist/src/styles.js +0 -25
- package/dist/src/theme.js +0 -99
- package/dist/src/web-components/ds-chat.js +0 -45
- package/dist/ui_kits/aicat/README.md +0 -7
- package/dist/ui_kits/aicat/app.js +0 -156
- package/dist/ui_kits/aicat/index.html +0 -26
- package/dist/ui_kits/aicat/sample-square.png +0 -0
- package/dist/ui_kits/aicat/sample-svg.svg +0 -1
- package/dist/ui_kits/aicat/sample.pdf +0 -32
- package/dist/ui_kits/blog/README.md +0 -3
- package/dist/ui_kits/blog/index.html +0 -90
- package/dist/ui_kits/chat/README.md +0 -5
- package/dist/ui_kits/chat/app.js +0 -110
- package/dist/ui_kits/chat/index.html +0 -26
- package/dist/ui_kits/chat/sample-square.png +0 -0
- package/dist/ui_kits/chat/sample-svg.svg +0 -1
- package/dist/ui_kits/chat/sample.pdf +0 -32
- package/dist/ui_kits/community/app.js +0 -134
- package/dist/ui_kits/community/index.html +0 -24
- package/dist/ui_kits/dashboard/app.js +0 -92
- package/dist/ui_kits/dashboard/index.html +0 -26
- package/dist/ui_kits/docs/README.md +0 -3
- package/dist/ui_kits/docs/index.html +0 -123
- package/dist/ui_kits/error_404/app.js +0 -56
- package/dist/ui_kits/error_404/index.html +0 -26
- package/dist/ui_kits/file_browser/README.md +0 -48
- package/dist/ui_kits/file_browser/app.js +0 -231
- package/dist/ui_kits/file_browser/index.html +0 -33
- package/dist/ui_kits/gallery/app.js +0 -121
- package/dist/ui_kits/gallery/index.html +0 -26
- package/dist/ui_kits/homepage/README.md +0 -7
- package/dist/ui_kits/homepage/app.js +0 -167
- package/dist/ui_kits/homepage/index.html +0 -46
- package/dist/ui_kits/project_page/README.md +0 -3
- package/dist/ui_kits/project_page/app.js +0 -154
- package/dist/ui_kits/project_page/index.html +0 -45
- package/dist/ui_kits/search/app.js +0 -107
- package/dist/ui_kits/search/index.html +0 -26
- package/dist/ui_kits/settings/app.js +0 -133
- package/dist/ui_kits/settings/index.html +0 -26
- package/dist/ui_kits/signin/app.js +0 -115
- package/dist/ui_kits/signin/index.html +0 -26
- package/dist/ui_kits/slide_deck/app.js +0 -174
- package/dist/ui_kits/slide_deck/index.html +0 -26
- package/dist/ui_kits/system_primer/app.js +0 -152
- package/dist/ui_kits/system_primer/index.html +0 -26
- package/dist/ui_kits/terminal/app.js +0 -150
- package/dist/ui_kits/terminal/index.html +0 -26
- package/dist/vendor/webjsx/applyDiff.js +0 -182
- package/dist/vendor/webjsx/attributes.js +0 -154
- package/dist/vendor/webjsx/constants.js +0 -4
- package/dist/vendor/webjsx/createDOMElement.js +0 -52
- package/dist/vendor/webjsx/createElement.js +0 -75
- package/dist/vendor/webjsx/elementTags.js +0 -115
- package/dist/vendor/webjsx/factory.js +0 -6
- package/dist/vendor/webjsx/index.js +0 -6
- package/dist/vendor/webjsx/jsx-dev-runtime.js +0 -2
- package/dist/vendor/webjsx/jsx-runtime.js +0 -30
- package/dist/vendor/webjsx/jsx.js +0 -2
- package/dist/vendor/webjsx/package.json +0 -39
- package/dist/vendor/webjsx/renderSuspension.js +0 -25
- package/dist/vendor/webjsx/types.js +0 -5
- package/dist/vendor/webjsx/utils.js +0 -84
- package/src/components/overlays.js +0 -151
|
@@ -1,208 +1,190 @@
|
|
|
1
|
-
// Community surface — matches upstream signatures.
|
|
2
|
-
|
|
3
|
-
import * as webjsx from '../../vendor/webjsx/index.js';
|
|
4
|
-
const h = webjsx.createElement;
|
|
5
|
-
|
|
6
|
-
export function ServerIcon({ id, name, icon, active, badge, onClick } = {}) {
|
|
7
|
-
const initials = (name || '?').slice(0, 2).toUpperCase();
|
|
8
|
-
return h('div', { class: 'cm-server-icon' + (active ? ' active' : ''), onclick: onClick, title: name, 'data-id': id },
|
|
9
|
-
h('span', { class: 'cm-server-pill' }),
|
|
10
|
-
icon ? h('img', { src: icon, alt: name }) : h('span', {}, initials),
|
|
11
|
-
badge ? h('span', { class: 'cm-server-badge' }, badge > 99 ? '99+' : String(badge)) : null
|
|
12
|
-
);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function ServerRail({ servers = [], activeId, onSelect, onAdd } = {}) {
|
|
16
|
-
return h('div', { class: 'cm-server-rail' },
|
|
17
|
-
h('a', { class: 'cm-server-back', href: '../', title: 'Back' }, '◰'),
|
|
18
|
-
h('div', { class: 'cm-server-sep' }),
|
|
19
|
-
...servers.map(s => ServerIcon({ ...s, active: s.id === activeId, onClick: () => onSelect && onSelect(s.id) })),
|
|
20
|
-
onAdd ? h('button', { class: 'cm-server-add', onclick: onAdd, title: 'Add server' }, '+') : null
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function ChannelItem({ id, name, type = 'text', active, voiceActive, voiceConnecting, badge, draggable, actions = [], participants = [], onClick, onContext } = {}) {
|
|
25
|
-
const icon = type === 'voice' ? '🔊' : type === 'forum' ? '◻' : type === 'threaded' ? '◉' : type === 'announcement' ? '📣' : type === 'page' ? '📄' : type === 'thread' ? '🧵' : '#';
|
|
26
|
-
return h('div', { class: 'cm-channel-item-wrap', 'data-channel-wrap': id },
|
|
27
|
-
h('div', {
|
|
28
|
-
class: 'cm-channel-item' + (active ? ' active' : '') + (voiceActive ? ' voice-active' : '') + (voiceConnecting ? ' voice-connecting' : ''),
|
|
29
|
-
'data-id': id,
|
|
30
|
-
'data-type': type,
|
|
31
|
-
draggable: draggable ? 'true' : null,
|
|
32
|
-
onclick: onClick,
|
|
33
|
-
oncontextmenu: (e) => { e.preventDefault(); onContext && onContext(id, e.clientX, e.clientY); }
|
|
34
|
-
},
|
|
35
|
-
h('span', { class: 'cm-ch-icon' }, icon),
|
|
36
|
-
voiceConnecting ? h('span', { class: 'cm-ch-spinner', title: 'Connecting…' }) : null,
|
|
37
|
-
h('span', { class: 'cm-ch-name' }, name),
|
|
38
|
-
badge ? h('span', { class: 'cm-ch-badge' }, badge > 99 ? '99+' : String(badge)) : null,
|
|
39
|
-
actions.length ? h('div', { class: 'cm-ch-actions' },
|
|
40
|
-
...actions.map(a => h('button', {
|
|
41
|
-
class: 'cm-ch-action-btn',
|
|
42
|
-
title: a.title || '',
|
|
43
|
-
'data-action': a.id || '',
|
|
44
|
-
onclick: (e) => { e.stopPropagation(); a.onClick && a.onClick(id, e); }
|
|
45
|
-
}, a.icon || a.label || '⋯'))
|
|
46
|
-
) : null
|
|
47
|
-
),
|
|
48
|
-
voiceActive && participants.length ? h('div', { class: 'cm-ch-voice-users' },
|
|
49
|
-
...participants.map(p => h('div', { class: 'cm-ch-voice-user' + (p.speaking ? ' speaking' : '') },
|
|
50
|
-
h('div', { class: 'cm-ch-voice-user-avatar', style: p.color ? `background:${p.color}` : '' }, (p.identity || '?').slice(0, 1).toUpperCase()),
|
|
51
|
-
h('span', { class: 'cm-ch-voice-user-name' }, p.identity)
|
|
52
|
-
))
|
|
53
|
-
) : null
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function ChannelCategory({ id, name, channels = [], collapsed, activeId, onToggle, onAddChannel, onChannelClick, onChannelContext, onContextMenu, extraButton, channelDraggable } = {}) {
|
|
58
|
-
return h('div', { class: 'cm-channel-category', 'data-category': id },
|
|
59
|
-
h('div', {
|
|
60
|
-
class: 'cm-category-header' + (collapsed ? ' collapsed' : ''),
|
|
61
|
-
onclick: () => onToggle && onToggle(id),
|
|
62
|
-
oncontextmenu: onContextMenu ? (e) => { e.preventDefault(); onContextMenu(id, e.clientX, e.clientY); } : null
|
|
63
|
-
},
|
|
64
|
-
h('svg', { class: 'cm-cat-arrow', viewBox: '0 0 24 24' }, h('path', { d: 'M7 10l5 5 5-5z' })),
|
|
65
|
-
h('span', { class: 'cm-cat-name' }, name),
|
|
66
|
-
extraButton ? h('button', { class: 'cm-cat-extra', onclick: (e) => { e.stopPropagation(); extraButton.onClick && extraButton.onClick(id, e); }, title: extraButton.title || '' }, extraButton.icon || extraButton.label || '+') : null,
|
|
67
|
-
onAddChannel ? h('button', { class: 'cm-cat-add', onclick: (e) => { e.stopPropagation(); onAddChannel(id); }, title: 'Add channel' }, '+') : null
|
|
68
|
-
),
|
|
69
|
-
collapsed ? null : h('div', { class: 'cm-cat-channels' },
|
|
70
|
-
...channels.map(c => ChannelItem({
|
|
71
|
-
...c,
|
|
72
|
-
draggable: channelDraggable,
|
|
73
|
-
active: c.id === activeId,
|
|
74
|
-
onClick: () => onChannelClick && onChannelClick(c),
|
|
75
|
-
onContext: onChannelContext
|
|
76
|
-
}))
|
|
77
|
-
)
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export function VoiceUser({ identity, speaking, color
|
|
82
|
-
const initial = (identity || '?').slice(0, 1).toUpperCase();
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
h('div', { class: 'cm-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
),
|
|
166
|
-
h('
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export function
|
|
171
|
-
return h('div', { class: 'cm-
|
|
172
|
-
|
|
173
|
-
h('
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
h('span', { class: 'cm-vs-channel' }, '🔊 ' + (channelName || 'voice')),
|
|
192
|
-
h('span', { class: 'cm-vs-status' }, status || 'connected')
|
|
193
|
-
),
|
|
194
|
-
h('button', { class: 'cm-vs-btn', onclick: onMute, title: 'Mute' }, muted ? '🔇' : '🎤'),
|
|
195
|
-
h('button', { class: 'cm-vs-btn', onclick: onDeafen, title: 'Deafen' }, deafened ? '🔕' : '🎧'),
|
|
196
|
-
h('button', { class: 'cm-vs-btn danger', onclick: onLeave, title: 'Leave' }, '✕')
|
|
197
|
-
);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
export function CommunityShell({ serverRailProps, sidebarProps, children, memberListProps, voiceStripProps } = {}) {
|
|
201
|
-
return h('div', { class: 'cm-shell' },
|
|
202
|
-
serverRailProps ? ServerRail(serverRailProps) : null,
|
|
203
|
-
sidebarProps ? ChannelSidebar(sidebarProps) : null,
|
|
204
|
-
h('div', { class: 'cm-main' }, ...(Array.isArray(children) ? children : [children])),
|
|
205
|
-
memberListProps ? MemberList(memberListProps) : null,
|
|
206
|
-
voiceStripProps ? VoiceStrip(voiceStripProps) : null
|
|
207
|
-
);
|
|
208
|
-
}
|
|
1
|
+
// Community surface — matches upstream signatures.
|
|
2
|
+
|
|
3
|
+
import * as webjsx from '../../vendor/webjsx/index.js';
|
|
4
|
+
const h = webjsx.createElement;
|
|
5
|
+
|
|
6
|
+
export function ServerIcon({ id, name, icon, active, badge, onClick } = {}) {
|
|
7
|
+
const initials = (name || '?').slice(0, 2).toUpperCase();
|
|
8
|
+
return h('div', { class: 'cm-server-icon' + (active ? ' active' : ''), onclick: onClick, title: name, 'data-id': id },
|
|
9
|
+
h('span', { class: 'cm-server-pill' }),
|
|
10
|
+
icon ? h('img', { src: icon, alt: name }) : h('span', {}, initials),
|
|
11
|
+
badge ? h('span', { class: 'cm-server-badge' }, badge > 99 ? '99+' : String(badge)) : null
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function ServerRail({ servers = [], activeId, onSelect, onAdd } = {}) {
|
|
16
|
+
return h('div', { class: 'cm-server-rail' },
|
|
17
|
+
h('a', { class: 'cm-server-back', href: '../', title: 'Back' }, '◰'),
|
|
18
|
+
h('div', { class: 'cm-server-sep' }),
|
|
19
|
+
...servers.map(s => ServerIcon({ ...s, active: s.id === activeId, onClick: () => onSelect && onSelect(s.id) })),
|
|
20
|
+
onAdd ? h('button', { class: 'cm-server-add', onclick: onAdd, title: 'Add server' }, '+') : null
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function ChannelItem({ id, name, type = 'text', active, voiceActive, voiceConnecting, badge, draggable, actions = [], participants = [], onClick, onContext } = {}) {
|
|
25
|
+
const icon = type === 'voice' ? '🔊' : type === 'forum' ? '◻' : type === 'threaded' ? '◉' : type === 'announcement' ? '📣' : type === 'page' ? '📄' : type === 'thread' ? '🧵' : '#';
|
|
26
|
+
return h('div', { class: 'cm-channel-item-wrap', 'data-channel-wrap': id },
|
|
27
|
+
h('div', {
|
|
28
|
+
class: 'cm-channel-item' + (active ? ' active' : '') + (voiceActive ? ' voice-active' : '') + (voiceConnecting ? ' voice-connecting' : ''),
|
|
29
|
+
'data-id': id,
|
|
30
|
+
'data-type': type,
|
|
31
|
+
draggable: draggable ? 'true' : null,
|
|
32
|
+
onclick: onClick,
|
|
33
|
+
oncontextmenu: (e) => { e.preventDefault(); onContext && onContext(id, e.clientX, e.clientY); }
|
|
34
|
+
},
|
|
35
|
+
h('span', { class: 'cm-ch-icon' }, icon),
|
|
36
|
+
voiceConnecting ? h('span', { class: 'cm-ch-spinner', title: 'Connecting…' }) : null,
|
|
37
|
+
h('span', { class: 'cm-ch-name' }, name),
|
|
38
|
+
badge ? h('span', { class: 'cm-ch-badge' }, badge > 99 ? '99+' : String(badge)) : null,
|
|
39
|
+
actions.length ? h('div', { class: 'cm-ch-actions' },
|
|
40
|
+
...actions.map(a => h('button', {
|
|
41
|
+
class: 'cm-ch-action-btn',
|
|
42
|
+
title: a.title || '',
|
|
43
|
+
'data-action': a.id || '',
|
|
44
|
+
onclick: (e) => { e.stopPropagation(); a.onClick && a.onClick(id, e); }
|
|
45
|
+
}, a.icon || a.label || '⋯'))
|
|
46
|
+
) : null
|
|
47
|
+
),
|
|
48
|
+
voiceActive && participants.length ? h('div', { class: 'cm-ch-voice-users' },
|
|
49
|
+
...participants.map(p => h('div', { class: 'cm-ch-voice-user' + (p.speaking ? ' speaking' : '') },
|
|
50
|
+
h('div', { class: 'cm-ch-voice-user-avatar', style: p.color ? `background:${p.color}` : '' }, (p.identity || '?').slice(0, 1).toUpperCase()),
|
|
51
|
+
h('span', { class: 'cm-ch-voice-user-name' }, p.identity)
|
|
52
|
+
))
|
|
53
|
+
) : null
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function ChannelCategory({ id, name, channels = [], collapsed, activeId, onToggle, onAddChannel, onChannelClick, onChannelContext, onContextMenu, extraButton, channelDraggable } = {}) {
|
|
58
|
+
return h('div', { class: 'cm-channel-category', 'data-category': id },
|
|
59
|
+
h('div', {
|
|
60
|
+
class: 'cm-category-header' + (collapsed ? ' collapsed' : ''),
|
|
61
|
+
onclick: () => onToggle && onToggle(id),
|
|
62
|
+
oncontextmenu: onContextMenu ? (e) => { e.preventDefault(); onContextMenu(id, e.clientX, e.clientY); } : null
|
|
63
|
+
},
|
|
64
|
+
h('svg', { class: 'cm-cat-arrow', viewBox: '0 0 24 24' }, h('path', { d: 'M7 10l5 5 5-5z' })),
|
|
65
|
+
h('span', { class: 'cm-cat-name' }, name),
|
|
66
|
+
extraButton ? h('button', { class: 'cm-cat-extra', onclick: (e) => { e.stopPropagation(); extraButton.onClick && extraButton.onClick(id, e); }, title: extraButton.title || '' }, extraButton.icon || extraButton.label || '+') : null,
|
|
67
|
+
onAddChannel ? h('button', { class: 'cm-cat-add', onclick: (e) => { e.stopPropagation(); onAddChannel(id); }, title: 'Add channel' }, '+') : null
|
|
68
|
+
),
|
|
69
|
+
collapsed ? null : h('div', { class: 'cm-cat-channels' },
|
|
70
|
+
...channels.map(c => ChannelItem({
|
|
71
|
+
...c,
|
|
72
|
+
draggable: channelDraggable,
|
|
73
|
+
active: c.id === activeId,
|
|
74
|
+
onClick: () => onChannelClick && onChannelClick(c),
|
|
75
|
+
onContext: onChannelContext
|
|
76
|
+
}))
|
|
77
|
+
)
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function VoiceUser({ identity, speaking, color } = {}) {
|
|
82
|
+
const initial = (identity || '?').slice(0, 1).toUpperCase();
|
|
83
|
+
return h('div', { class: 'cm-voice-user' + (speaking ? ' speaking' : '') },
|
|
84
|
+
h('div', { class: 'cm-voice-user-avatar', style: color ? `background:${color}` : '' }, initial),
|
|
85
|
+
h('span', { class: 'cm-voice-user-name' }, identity)
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function UserPanel({ name, tag, color, muted, deafened, onMute, onDeafen, onSettings } = {}) {
|
|
90
|
+
const initial = (name || '?').slice(0, 1).toUpperCase();
|
|
91
|
+
return h('div', { class: 'cm-user-panel' },
|
|
92
|
+
h('div', { class: 'cm-user-avatar', style: color ? `background:${color}` : '' },
|
|
93
|
+
h('span', { class: 'cm-user-status-dot' }),
|
|
94
|
+
initial
|
|
95
|
+
),
|
|
96
|
+
h('div', { class: 'cm-user-info' },
|
|
97
|
+
h('div', { class: 'cm-user-name' }, name || 'You'),
|
|
98
|
+
tag ? h('div', { class: 'cm-user-tag' }, tag) : null
|
|
99
|
+
),
|
|
100
|
+
h('div', { class: 'cm-user-controls' },
|
|
101
|
+
h('button', { class: 'cm-user-btn' + (muted ? ' muted' : ''), onclick: onMute, title: muted ? 'Unmute' : 'Mute' }, muted ? '🔇' : '🎤'),
|
|
102
|
+
h('button', { class: 'cm-user-btn' + (deafened ? ' deafened' : ''), onclick: onDeafen, title: deafened ? 'Undeafen' : 'Deafen' }, deafened ? '🔕' : '🎧'),
|
|
103
|
+
h('button', { class: 'cm-user-btn', onclick: onSettings, title: 'Settings' }, '⚙')
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function ChannelSidebar({ serverName, channels = [], categories = [], activeId, collapsedCats, onChannelClick, onCategoryToggle, onAddChannel, onChannelContext, userPanelProps } = {}) {
|
|
109
|
+
const collapsed = collapsedCats || new Set();
|
|
110
|
+
const uncategorized = channels.filter(c => !c.categoryId || !categories.find(cat => cat.id === c.categoryId));
|
|
111
|
+
const sorted = [...categories].sort((a, b) => (a.position || 0) - (b.position || 0));
|
|
112
|
+
return h('div', { class: 'cm-channel-sidebar' },
|
|
113
|
+
h('div', { class: 'cm-server-header' },
|
|
114
|
+
h('span', { class: 'cm-server-header-name' }, serverName || 'Server'),
|
|
115
|
+
),
|
|
116
|
+
h('div', { class: 'cm-channel-list' },
|
|
117
|
+
...sorted.map(cat => ChannelCategory({
|
|
118
|
+
id: cat.id,
|
|
119
|
+
name: cat.name,
|
|
120
|
+
channels: channels.filter(c => c.categoryId === cat.id).sort((a, b) => (a.position || 0) - (b.position || 0)),
|
|
121
|
+
collapsed: collapsed.has && collapsed.has(cat.id),
|
|
122
|
+
activeId,
|
|
123
|
+
onToggle: onCategoryToggle,
|
|
124
|
+
onAddChannel,
|
|
125
|
+
onChannelClick,
|
|
126
|
+
onChannelContext
|
|
127
|
+
})),
|
|
128
|
+
uncategorized.length ? ChannelCategory({
|
|
129
|
+
id: 'uncategorized',
|
|
130
|
+
name: 'CHANNELS',
|
|
131
|
+
channels: uncategorized,
|
|
132
|
+
activeId,
|
|
133
|
+
onChannelClick,
|
|
134
|
+
onChannelContext
|
|
135
|
+
}) : null
|
|
136
|
+
),
|
|
137
|
+
userPanelProps ? UserPanel(userPanelProps) : null
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function MemberItem({ identity, name, color, status = 'online' } = {}) {
|
|
142
|
+
const initial = (name || identity || '?').slice(0, 1).toUpperCase();
|
|
143
|
+
return h('div', { class: 'cm-member-item' },
|
|
144
|
+
h('div', { class: 'cm-member-avatar', style: color ? `background:${color}` : '' },
|
|
145
|
+
h('span', { class: 'cm-member-status' + (status === 'online' ? ' online' : '') }),
|
|
146
|
+
initial
|
|
147
|
+
),
|
|
148
|
+
h('span', { class: 'cm-member-name' }, name || identity)
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function MemberList({ categories = [], open } = {}) {
|
|
153
|
+
return h('div', { class: 'cm-member-list' + (open ? ' open' : '') },
|
|
154
|
+
...categories.flatMap(cat => [
|
|
155
|
+
h('div', { class: 'cm-member-category', key: cat.label }, `${cat.label} — ${cat.members.length}`),
|
|
156
|
+
...cat.members.map((m, i) => MemberItem({ ...m, key: m.identity || i }))
|
|
157
|
+
])
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function ChatHeader({ icon = '#', name, topic, toolbar = [] } = {}) {
|
|
162
|
+
return h('div', { class: 'cm-chat-header' },
|
|
163
|
+
h('span', { class: 'cm-chat-header-icon' }, icon),
|
|
164
|
+
h('span', { class: 'cm-chat-header-name' }, name),
|
|
165
|
+
topic ? h('span', { class: 'cm-chat-header-topic' }, topic) : null,
|
|
166
|
+
h('div', { class: 'cm-chat-header-toolbar' }, ...toolbar)
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function VoiceStrip({ channelName, status, muted, deafened, onMute, onDeafen, onLeave, open } = {}) {
|
|
171
|
+
return h('div', { class: 'cm-voice-strip' + (open ? ' open' : '') },
|
|
172
|
+
h('div', { class: 'cm-vs-label' },
|
|
173
|
+
h('span', { class: 'cm-vs-channel' }, '🔊 ' + (channelName || 'voice')),
|
|
174
|
+
h('span', { class: 'cm-vs-status' }, status || 'connected')
|
|
175
|
+
),
|
|
176
|
+
h('button', { class: 'cm-vs-btn', onclick: onMute, title: 'Mute' }, muted ? '🔇' : '🎤'),
|
|
177
|
+
h('button', { class: 'cm-vs-btn', onclick: onDeafen, title: 'Deafen' }, deafened ? '🔕' : '🎧'),
|
|
178
|
+
h('button', { class: 'cm-vs-btn danger', onclick: onLeave, title: 'Leave' }, '✕')
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function CommunityShell({ serverRailProps, sidebarProps, children, memberListProps, voiceStripProps } = {}) {
|
|
183
|
+
return h('div', { class: 'cm-shell' },
|
|
184
|
+
serverRailProps ? ServerRail(serverRailProps) : null,
|
|
185
|
+
sidebarProps ? ChannelSidebar(sidebarProps) : null,
|
|
186
|
+
h('div', { class: 'cm-main' }, ...(Array.isArray(children) ? children : [children])),
|
|
187
|
+
memberListProps ? MemberList(memberListProps) : null,
|
|
188
|
+
voiceStripProps ? VoiceStrip(voiceStripProps) : null
|
|
189
|
+
);
|
|
190
|
+
}
|