glad-web 1.0.43 → 1.0.45
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 +2 -0
- package/README.zh-CN.md +2 -0
- package/lib/claude/structured-session.js +10 -5
- package/lib/codex/image-store.js +1 -2
- package/lib/codex/structured-session.js +24 -73
- package/lib/commands/web.js +43 -5
- package/lib/server/routes/providers.js +0 -12
- package/lib/session/file-attachment-store.js +168 -0
- package/lib/session/session-manager.js +75 -23
- package/lib/web/claude.js +28 -11
- package/lib/web/codex.js +49 -23
- package/lib/web/composer.js +263 -34
- package/lib/web/core.js +22 -6
- package/lib/web/git.js +53 -51
- package/lib/web/gitgraph.js +8 -8
- package/lib/web/index.html +94 -36
- package/lib/web/layout.js +72 -0
- package/lib/web/notifications.js +1 -0
- package/lib/web/session.js +6 -20
- package/lib/web/shell.js +3 -0
- package/lib/web/styles.css +375 -11
- package/lib/web/theme.js +60 -0
- package/lib/web/timed-inputs.js +9 -16
- package/package.json +1 -1
package/lib/web/theme.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const GLAD_THEME_KEY = 'glad-theme';
|
|
2
|
+
|
|
3
|
+
function getGladTheme() {
|
|
4
|
+
const stored = localStorage.getItem(GLAD_THEME_KEY);
|
|
5
|
+
if (stored === 'light' || stored === 'dark') return stored;
|
|
6
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function getGladTerminalTheme(theme = getGladTheme()) {
|
|
10
|
+
return theme === 'light'
|
|
11
|
+
? {
|
|
12
|
+
background: '#ffffff', foreground: '#172033', cursor: '#007aff',
|
|
13
|
+
selectionBackground: 'rgba(0, 122, 255, 0.22)', black: '#172033', white: '#f5f6f8',
|
|
14
|
+
brightBlack: '#667085', brightWhite: '#ffffff'
|
|
15
|
+
}
|
|
16
|
+
: {
|
|
17
|
+
background: '#000000', foreground: '#ffffff', cursor: '#34c759',
|
|
18
|
+
selectionBackground: 'rgba(0, 122, 255, 0.32)'
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function syncGladThemeControls(theme = getGladTheme()) {
|
|
23
|
+
['light', 'dark'].forEach(value => {
|
|
24
|
+
const button = document.getElementById(`theme-${value}-btn`);
|
|
25
|
+
if (button) button.setAttribute('aria-pressed', String(value === theme));
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function applyGladTheme(theme, options = {}) {
|
|
30
|
+
const resolved = theme === 'light' ? 'light' : 'dark';
|
|
31
|
+
document.documentElement.dataset.theme = resolved;
|
|
32
|
+
document.documentElement.style.removeProperty('background-color');
|
|
33
|
+
const meta = document.querySelector('meta[name="theme-color"]');
|
|
34
|
+
if (meta) meta.content = resolved === 'light' ? '#f5f6f8' : '#000000';
|
|
35
|
+
syncGladThemeControls(resolved);
|
|
36
|
+
try {
|
|
37
|
+
if (typeof term !== 'undefined' && term) {
|
|
38
|
+
term.options.theme = getGladTerminalTheme(resolved);
|
|
39
|
+
term.refresh(0, Math.max(0, term.rows - 1));
|
|
40
|
+
}
|
|
41
|
+
} catch (_) {}
|
|
42
|
+
if (!options.silent) window.dispatchEvent(new CustomEvent('glad-theme-change', { detail: resolved }));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function setGladTheme(theme) {
|
|
46
|
+
if (theme !== 'light' && theme !== 'dark') return;
|
|
47
|
+
localStorage.setItem(GLAD_THEME_KEY, theme);
|
|
48
|
+
applyGladTheme(theme);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
applyGladTheme(getGladTheme(), { silent: true });
|
|
52
|
+
|
|
53
|
+
const gladSystemTheme = window.matchMedia('(prefers-color-scheme: dark)');
|
|
54
|
+
gladSystemTheme.addEventListener('change', () => {
|
|
55
|
+
if (!localStorage.getItem(GLAD_THEME_KEY)) applyGladTheme(getGladTheme());
|
|
56
|
+
});
|
|
57
|
+
window.addEventListener('storage', event => {
|
|
58
|
+
if (event.key === GLAD_THEME_KEY) applyGladTheme(getGladTheme());
|
|
59
|
+
});
|
|
60
|
+
document.addEventListener('DOMContentLoaded', () => syncGladThemeControls());
|
package/lib/web/timed-inputs.js
CHANGED
|
@@ -115,7 +115,6 @@
|
|
|
115
115
|
function editTimedInput(id) {
|
|
116
116
|
const item = timedInputs.find(value => value.id === id);
|
|
117
117
|
if (!item) return;
|
|
118
|
-
closeComposerMenu();
|
|
119
118
|
initTimedDelaySelectors();
|
|
120
119
|
editingTimedInputId = id;
|
|
121
120
|
inputEl.value = item.text || '';
|
|
@@ -173,23 +172,17 @@
|
|
|
173
172
|
}
|
|
174
173
|
|
|
175
174
|
document.getElementById('send-btn').addEventListener('click', performSend);
|
|
176
|
-
document.getElementById('
|
|
177
|
-
|
|
178
|
-
const willOpen = !menu.classList.contains('active');
|
|
179
|
-
document.getElementById('timed-send-panel').classList.remove('active');
|
|
180
|
-
menu.classList.toggle('active', willOpen);
|
|
181
|
-
syncComposerButtonState();
|
|
182
|
-
updateTerminalControlsHeight();
|
|
175
|
+
document.getElementById('attachment-btn').addEventListener('click', () => {
|
|
176
|
+
attachmentFileInput.click();
|
|
183
177
|
});
|
|
184
|
-
document.getElementById('
|
|
185
|
-
|
|
186
|
-
|
|
178
|
+
document.getElementById('schedule-send-btn').addEventListener('click', () => {
|
|
179
|
+
if (document.getElementById('timed-send-panel').classList.contains('active')) closeTimedSendPanel();
|
|
180
|
+
else openTimedSendPanel();
|
|
187
181
|
});
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
imageFileInput.value = '';
|
|
182
|
+
attachmentFileInput.addEventListener('change', () => {
|
|
183
|
+
const files = attachmentFileInput.files;
|
|
184
|
+
if (files?.length) void uploadSelectedAttachments(files);
|
|
185
|
+
attachmentFileInput.value = '';
|
|
193
186
|
});
|
|
194
187
|
inputEl.addEventListener('keydown', (e) => {
|
|
195
188
|
if (e.key === 'Enter' && e.shiftKey) { e.preventDefault(); performSend(); }
|