fixes + theme

This commit is contained in:
th committed 2026-04-11 13:01:27 +02:00
1 parent 5af49655d6
commit 22f73ab3b9
25 files changed
+1004 -206

No files matched your search

+8 -2
View File
@@ -132,7 +132,8 @@ PluginManager::instance()->onApiRoute(function (string $route, string $method) {
}
$envelope = chatEncrypt($body, $r['key']);
$ch = curl_init(rtrim($r['url'], '/') . '/api/chat');
$relayChatUrl = rtrim($r['url'], '/') . '/api/chat';
$ch = curl_init($relayChatUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
@@ -152,7 +153,12 @@ PluginManager::instance()->onApiRoute(function (string $route, string $method) {
$relayErr = '';
$decoded = json_decode($response, true);
if (is_array($decoded) && !empty($decoded['error'])) $relayErr = ' — ' . $decoded['error'];
chatJson(['ok' => false, 'error' => "relay returned HTTP $status$relayErr"]);
chatJson([
'ok' => false,
'error' => "relay returned HTTP $status$relayErr",
'url' => $relayChatUrl,
'response_body' => is_string($response) ? substr($response, 0, 500) : null,
]);
}
$resData = json_decode($response, true);
+3 -1
View File
@@ -9,7 +9,8 @@
max-height: calc(100vh - 100px);
background: var(--t-surface);
border: 1px solid var(--t-border);
box-shadow: 0 8px 32px rgba(0,0,0,0.5);
border-radius: var(--ui-radius-modal);
box-shadow: var(--ui-shadow-modal);
z-index: 100;
display: flex;
flex-direction: column;
@@ -277,6 +278,7 @@
padding: 4px 10px;
font-size: 12px;
border: 1px solid var(--t-border);
border-radius: var(--ui-radius-button);
color: var(--t-muted);
background: transparent;
cursor: pointer;
+1 -1
View File
@@ -15,7 +15,7 @@
<div id="chat-empty" class="hidden chat-empty">
<i class="ph ph-chats text-2xl text-t-dim mb-2"></i>
<p class="font-pixel text-[10px] text-t-dim">no conversations yet</p>
<button id="chat-empty-start" class="mt-3 px-2 py-1 text-[10px] font-pixel border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors">start chat</button>
<button id="chat-empty-start" class="mt-3 px-2 py-1 text-[10px] font-pixel border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors">Start chat</button>
</div>
</div>
+19 -2
View File
@@ -235,14 +235,31 @@ async function sendMessage(e) {
body: { peer: currentPeer, body },
});
if (!res.ok) {
alert('Send failed: ' + (res.error || 'unknown'));
const detail = [
res.error || 'unknown',
res.url ? `URL: ${res.url}` : null,
res.response_body ? `Body: ${res.response_body}` : null,
].filter(Boolean).join('\n');
await hyprcrd.dialog.show({
title: 'send failed',
message: detail,
danger: true,
okLabel: 'Ok',
cancelLabel: '',
});
return;
}
input.value = '';
await loadThread(currentPeer);
await loadConversations();
} catch (err) {
alert('Send error: ' + err.message);
await hyprcrd.dialog.show({
title: 'send error',
message: String(err?.message || err),
danger: true,
okLabel: 'Ok',
cancelLabel: '',
});
} finally {
sendBtn.disabled = false;
input.disabled = false;
+10 -10
View File
@@ -10,8 +10,8 @@
<button id="email-refresh" class="toolbar-btn" title="Refresh"><i class="ph ph-arrows-clockwise text-sm"></i></button>
<span id="email-status" class="text-[10px] text-t-dim font-pixel"></span>
<div class="flex-1"></div>
<button id="email-show-settings" class="flex items-center gap-1.5 px-2 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors" title="Manage accounts in settings"><i class="ph ph-gear text-sm"></i><span class="font-pixel text-[10px]">accounts</span></button>
<button id="email-close" class="flex items-center gap-1.5 px-2 py-1 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">close</span></button>
<button id="email-show-settings" class="flex items-center gap-1.5 px-2 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors" title="Manage accounts in settings"><i class="ph ph-gear text-sm"></i><span class="font-pixel text-[10px]">Accounts</span></button>
<button id="email-close" class="flex items-center gap-1.5 px-2 py-1 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">Close</span></button>
</div>
<!-- ── Welcome view (shown when no accounts) ── -->
@@ -27,7 +27,7 @@
</p>
<button id="email-welcome-configure" class="inline-flex items-center gap-2 px-4 py-2 text-xs bg-t-accent text-t-bg border border-t-accent hover:brightness-110 transition-all">
<i class="ph ph-gear text-sm"></i>
<span class="font-pixel text-[11px]">configure accounts</span>
<span class="font-pixel text-[11px]">Configure accounts</span>
</button>
<p class="text-[10px] text-t-dim mt-4 font-pixel">settings → mail</p>
</div>
@@ -55,13 +55,13 @@
<span id="email-selection-count" class="font-pixel text-[10px] text-t-accent">0 selected</span>
<div class="flex-1"></div>
<button id="email-selection-mark-spam" class="flex items-center gap-1 px-2 py-0.5 text-xs border border-t-danger text-t-danger hover:bg-t-danger/10 transition-colors" title="Mark sender as spam (future mail from same sender will be flagged)">
<i class="ph ph-warning-octagon text-sm"></i><span class="font-pixel text-[9px]">spam</span>
<i class="ph ph-warning-octagon text-sm"></i><span class="font-pixel text-[9px]">Spam</span>
</button>
<button id="email-selection-mark-ham" class="flex items-center gap-1 px-2 py-0.5 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors" title="Mark sender as not spam (allowlist)">
<i class="ph ph-check-circle text-sm"></i><span class="font-pixel text-[9px]">not spam</span>
<i class="ph ph-check-circle text-sm"></i><span class="font-pixel text-[9px]">Not spam</span>
</button>
<button id="email-selection-delete" class="flex items-center gap-1 px-2 py-0.5 text-xs border border-t-danger text-t-danger hover:bg-t-danger/10 transition-colors" title="Delete selected on server">
<i class="ph ph-trash text-sm"></i><span class="font-pixel text-[9px]">delete</span>
<i class="ph ph-trash text-sm"></i><span class="font-pixel text-[9px]">Delete</span>
</button>
<button id="email-selection-clear" class="flex items-center gap-1 px-2 py-0.5 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors" title="Clear selection">
<i class="ph ph-x text-sm"></i>
@@ -90,10 +90,10 @@
<span><span class="text-t-muted">date:</span> <span id="email-msg-date" class="text-t-text"></span></span>
</div>
<div class="mt-3 flex items-center gap-2 flex-wrap">
<button id="email-extract-btn" class="flex items-center gap-1.5 px-3 py-1 text-xs bg-t-accent text-t-bg border border-t-accent hover:brightness-110 transition-all"><i class="ph ph-scissors text-sm"></i><span class="font-pixel text-[10px]">extract as card</span></button>
<button id="email-view-html" class="hidden items-center gap-1.5 px-3 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors" title="Show HTML rendered version (external images blocked by default)"><i class="ph ph-code text-sm"></i><span class="font-pixel text-[10px]">view as html</span></button>
<button id="email-view-text" class="hidden items-center gap-1.5 px-3 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors" title="Switch back to plain text"><i class="ph ph-text-aa text-sm"></i><span class="font-pixel text-[10px]">view as text</span></button>
<button id="email-load-images" class="hidden items-center gap-1.5 px-3 py-1 text-xs border border-t-accent2 text-t-accent2 hover:bg-t-accent2/10 transition-colors" title="Load external images (privacy: tracking pixels may be loaded)"><i class="ph ph-image text-sm"></i><span class="font-pixel text-[10px]">load images (<span id="email-blocked-count">0</span>)</span></button>
<button id="email-extract-btn" class="flex items-center gap-1.5 px-3 py-1 text-xs bg-t-accent text-t-bg border border-t-accent hover:brightness-110 transition-all"><i class="ph ph-scissors text-sm"></i><span class="font-pixel text-[10px]">Extract as card</span></button>
<button id="email-view-html" class="hidden items-center gap-1.5 px-3 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors" title="Show HTML rendered version (external images blocked by default)"><i class="ph ph-code text-sm"></i><span class="font-pixel text-[10px]">View as html</span></button>
<button id="email-view-text" class="hidden items-center gap-1.5 px-3 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors" title="Switch back to plain text"><i class="ph ph-text-aa text-sm"></i><span class="font-pixel text-[10px]">View as text</span></button>
<button id="email-load-images" class="hidden items-center gap-1.5 px-3 py-1 text-xs border border-t-accent2 text-t-accent2 hover:bg-t-accent2/10 transition-colors" title="Load external images (privacy: tracking pixels may be loaded)"><i class="ph ph-image text-sm"></i><span class="font-pixel text-[10px]">Load images (<span id="email-blocked-count">0</span>)</span></button>
<span id="email-extract-status" class="font-pixel text-[9px] text-t-dim"></span>
</div>
</div>
+7 -7
View File
@@ -165,9 +165,9 @@ function buildSettingsPanel(panelEl) {
<input id="email-acc-password" type="password" autocomplete="off" class="w-full bg-t-bg border border-t-border text-t-bright px-2 py-1.5 text-xs focus:border-t-accent focus:outline-none font-mono">
</label>
<div class="flex items-center gap-2 pt-1">
<button type="submit" id="email-acc-save" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors"><i class="ph ph-floppy-disk text-sm"></i><span class="font-pixel text-[10px]">save</span></button>
<button type="button" id="email-acc-test" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors"><i class="ph ph-plug text-sm"></i><span class="font-pixel text-[10px]">test</span></button>
<button type="button" id="email-acc-cancel" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">cancel</span></button>
<button type="submit" id="email-acc-save" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors"><i class="ph ph-floppy-disk text-sm"></i><span class="font-pixel text-[10px]">Save</span></button>
<button type="button" id="email-acc-test" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors"><i class="ph ph-plug text-sm"></i><span class="font-pixel text-[10px]">Test</span></button>
<button type="button" id="email-acc-cancel" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">Cancel</span></button>
</div>
<div id="email-acc-status" class="hidden mt-1 px-3 py-2 text-[10px] font-mono break-words border border-t-border bg-t-bg"></div>
</form>
@@ -297,7 +297,7 @@ async function deleteAccount(id) {
if (!acc) return;
const ok = await hyprcrd.dialog.confirm(
`Delete email account "${acc.name}"? Stored credentials will be removed but no mail is deleted from the server.`,
{ title: 'delete account', okLabel: 'delete', cancelLabel: 'cancel', danger: true }
{ title: 'delete account', okLabel: 'Delete', cancelLabel: 'Cancel', danger: true }
);
if (!ok) return;
await hyprcrd.api(`api/email/accounts/${id}`, { method: 'DELETE' });
@@ -573,7 +573,7 @@ async function markSelectedAs(action) {
const verb = action === 'spam' ? 'as spam' : 'as not spam';
const ok = await hyprcrd.dialog.confirm(
`Mark ${n} sender${n === 1 ? '' : 's'} ${verb}? This adds ${action === 'spam' ? 'block' : 'allow'} rules that affect all future messages from the same senders.`,
{ title: `mark ${verb}`, okLabel: 'mark', cancelLabel: 'cancel', danger: action === 'spam' }
{ title: `mark ${verb}`, okLabel: 'Mark', cancelLabel: 'Cancel', danger: action === 'spam' }
);
if (!ok) return;
@@ -609,7 +609,7 @@ async function deleteSelected({ skipConfirm = false } = {}) {
if (!skipConfirm) {
const ok = await hyprcrd.dialog.confirm(
`Permanently delete ${n} message${n === 1 ? '' : 's'} from the server? This cannot be undone.`,
{ title: 'delete mail', okLabel: 'delete', cancelLabel: 'cancel', danger: true }
{ title: 'delete mail', okLabel: 'Delete', cancelLabel: 'Cancel', danger: true }
);
if (!ok) return;
}
@@ -861,7 +861,7 @@ function injectHeaderButton() {
const btn = document.createElement('button');
btn.id = 'email-btn';
btn.className = 'flex items-center gap-2 px-2.5 py-1.5 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors';
btn.innerHTML = '<i class="ph ph-envelope text-sm"></i><span class="font-pixel text-[10px]">mail</span>';
btn.innerHTML = '<i class="ph ph-envelope text-sm"></i><span class="font-pixel text-[10px]">Mail</span>';
btn.addEventListener('click', openEmail);
const addBtn = document.getElementById('add-btn');
if (addBtn) header.insertBefore(btn, addBtn);
+15 -15
View File
@@ -9,8 +9,8 @@
<select id="gitea-account-select" class="bg-t-bg border border-t-border text-t-bright text-xs font-pixel px-2 py-1 rounded-sm focus:border-t-accent focus:outline-none cursor-pointer min-w-32"></select>
<span id="gitea-status" class="text-[10px] text-t-dim font-pixel"></span>
<div class="flex-1"></div>
<button id="gitea-show-settings" class="flex items-center gap-1.5 px-2 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors" title="Manage accounts in settings"><i class="ph ph-gear text-sm"></i><span class="font-pixel text-[10px]">accounts</span></button>
<button id="gitea-close" class="flex items-center gap-1.5 px-2 py-1 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">close</span></button>
<button id="gitea-show-settings" class="flex items-center gap-1.5 px-2 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors" title="Manage accounts in settings"><i class="ph ph-gear text-sm"></i><span class="font-pixel text-[10px]">Accounts</span></button>
<button id="gitea-close" class="flex items-center gap-1.5 px-2 py-1 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">Close</span></button>
</div>
<!-- ── Welcome view (shown when no accounts) ── -->
@@ -26,7 +26,7 @@
</p>
<button id="gitea-welcome-configure" class="inline-flex items-center gap-2 px-4 py-2 text-xs bg-t-accent text-t-bg border border-t-accent hover:brightness-110 transition-all">
<i class="ph ph-gear text-sm"></i>
<span class="font-pixel text-[11px]">configure accounts</span>
<span class="font-pixel text-[11px]">Configure accounts</span>
</button>
<p class="text-[10px] text-t-dim mt-4 font-pixel">settings → gitea</p>
</div>
@@ -126,8 +126,8 @@
<p class="text-[9px] text-t-dim mt-1 italic">project: not supported by gitea api on issue create — set it manually on gitea after creation</p>
</div>
<div class="mt-4 flex items-center gap-2">
<button id="gitea-create-submit" class="flex items-center gap-1.5 px-3 py-1.5 text-xs bg-t-accent text-t-bg border border-t-accent hover:brightness-110 transition-all"><i class="ph ph-paper-plane-tilt text-sm"></i><span class="font-pixel text-[10px]">create issue</span></button>
<button id="gitea-create-cancel-2" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">cancel</span></button>
<button id="gitea-create-submit" class="flex items-center gap-1.5 px-3 py-1.5 text-xs bg-t-accent text-t-bg border border-t-accent hover:brightness-110 transition-all"><i class="ph ph-paper-plane-tilt text-sm"></i><span class="font-pixel text-[10px]">Create issue</span></button>
<button id="gitea-create-cancel-2" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">Cancel</span></button>
</div>
<div id="gitea-create-status" class="hidden mt-2 px-3 py-2 text-[10px] font-mono break-words border border-t-border bg-t-bg"></div>
</div>
@@ -164,8 +164,8 @@
<div id="gitea-labels-warning" class="hidden mb-2 px-2 py-1 text-[10px] font-mono break-words border border-amber-500 text-amber-400 bg-t-bg"></div>
<div id="gitea-labels-checkboxes" class="space-y-1 max-h-48 overflow-y-auto"></div>
<div class="flex items-center gap-2 mt-2 pt-2 border-t border-t-border">
<button id="gitea-labels-save" class="flex items-center gap-1.5 px-2 py-0.5 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors"><i class="ph ph-floppy-disk text-sm"></i><span class="font-pixel text-[10px]">save</span></button>
<button id="gitea-labels-cancel" class="flex items-center gap-1.5 px-2 py-0.5 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">cancel</span></button>
<button id="gitea-labels-save" class="flex items-center gap-1.5 px-2 py-0.5 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors"><i class="ph ph-floppy-disk text-sm"></i><span class="font-pixel text-[10px]">Save</span></button>
<button id="gitea-labels-cancel" class="flex items-center gap-1.5 px-2 py-0.5 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">Cancel</span></button>
</div>
</div>
<!-- Metadata row: assignees + milestone + due date with inline editor -->
@@ -198,14 +198,14 @@
</div>
</div>
<div class="flex items-center gap-2 mt-3 pt-2 border-t border-t-border">
<button id="gitea-meta-save" class="flex items-center gap-1.5 px-2 py-0.5 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors"><i class="ph ph-floppy-disk text-sm"></i><span class="font-pixel text-[10px]">save</span></button>
<button id="gitea-meta-cancel" class="flex items-center gap-1.5 px-2 py-0.5 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">cancel</span></button>
<button id="gitea-meta-save" class="flex items-center gap-1.5 px-2 py-0.5 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors"><i class="ph ph-floppy-disk text-sm"></i><span class="font-pixel text-[10px]">Save</span></button>
<button id="gitea-meta-cancel" class="flex items-center gap-1.5 px-2 py-0.5 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">Cancel</span></button>
</div>
</div>
<div class="mt-3 flex items-center gap-2 flex-wrap">
<button id="gitea-extract-btn" class="flex items-center gap-1.5 px-3 py-1 text-xs bg-t-accent text-t-bg border border-t-accent hover:brightness-110 transition-all"><i class="ph ph-scissors text-sm"></i><span class="font-pixel text-[10px]">extract as card</span></button>
<button id="gitea-state-toggle" class="flex items-center gap-1.5 px-3 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors"><i class="ph ph-check-circle text-sm"></i><span class="font-pixel text-[10px]">close</span></button>
<a id="gitea-open-link" href="#" target="_blank" rel="noopener" class="inline-flex items-center gap-1.5 px-3 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors"><i class="ph ph-arrow-square-out text-sm"></i><span class="font-pixel text-[10px]">open on gitea</span></a>
<button id="gitea-extract-btn" class="flex items-center gap-1.5 px-3 py-1 text-xs bg-t-accent text-t-bg border border-t-accent hover:brightness-110 transition-all"><i class="ph ph-scissors text-sm"></i><span class="font-pixel text-[10px]">Extract as card</span></button>
<button id="gitea-state-toggle" class="flex items-center gap-1.5 px-3 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors"><i class="ph ph-check-circle text-sm"></i><span class="font-pixel text-[10px]">Close</span></button>
<a id="gitea-open-link" href="#" target="_blank" rel="noopener" class="inline-flex items-center gap-1.5 px-3 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors"><i class="ph ph-arrow-square-out text-sm"></i><span class="font-pixel text-[10px]">Open on gitea</span></a>
</div>
<div id="gitea-extract-status" class="hidden mt-2 px-3 py-2 text-[10px] font-mono break-words border border-t-border bg-t-bg"></div>
</div>
@@ -218,8 +218,8 @@
<div id="gitea-body-edit" class="hidden">
<textarea id="gitea-body-input" class="w-full bg-t-bg border border-t-accent text-t-text px-3 py-2 text-xs focus:outline-none font-mono leading-relaxed" rows="10"></textarea>
<div class="flex items-center gap-2 mt-2">
<button id="gitea-body-save" class="flex items-center gap-1.5 px-3 py-1 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors"><i class="ph ph-floppy-disk text-sm"></i><span class="font-pixel text-[10px]">save</span></button>
<button id="gitea-body-cancel" class="flex items-center gap-1.5 px-3 py-1 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">cancel</span></button>
<button id="gitea-body-save" class="flex items-center gap-1.5 px-3 py-1 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors"><i class="ph ph-floppy-disk text-sm"></i><span class="font-pixel text-[10px]">Save</span></button>
<button id="gitea-body-cancel" class="flex items-center gap-1.5 px-3 py-1 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">Cancel</span></button>
</div>
</div>
<div id="gitea-detail-comments-section" class="mt-6 hidden">
@@ -231,7 +231,7 @@
<div class="font-pixel text-[10px] uppercase tracking-wider text-t-dim mb-2"><i class="ph ph-chat-text text-xs"></i> add comment</div>
<textarea id="gitea-comment-input" rows="3" placeholder="markdown supported..." class="w-full bg-t-bg border border-t-border text-t-text px-3 py-2 text-xs focus:border-t-accent focus:outline-none font-mono leading-relaxed"></textarea>
<div class="flex items-center gap-2 mt-2">
<button id="gitea-comment-post" class="flex items-center gap-1.5 px-3 py-1 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors"><i class="ph ph-paper-plane-tilt text-sm"></i><span class="font-pixel text-[10px]">post</span></button>
<button id="gitea-comment-post" class="flex items-center gap-1.5 px-3 py-1 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors"><i class="ph ph-paper-plane-tilt text-sm"></i><span class="font-pixel text-[10px]">Post</span></button>
<span id="gitea-comment-status" class="font-pixel text-[9px] text-t-dim"></span>
</div>
</div>
+7 -7
View File
@@ -114,9 +114,9 @@ function buildSettingsPanel(panelEl) {
<input id="gitea-acc-token" type="password" autocomplete="off" class="w-full bg-t-bg border border-t-border text-t-bright px-2 py-1.5 text-xs focus:border-t-accent focus:outline-none font-mono">
</label>
<div class="flex items-center gap-2 pt-1">
<button type="submit" id="gitea-acc-save" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors"><i class="ph ph-floppy-disk text-sm"></i><span class="font-pixel text-[10px]">save</span></button>
<button type="button" id="gitea-acc-test" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors"><i class="ph ph-plug text-sm"></i><span class="font-pixel text-[10px]">test</span></button>
<button type="button" id="gitea-acc-cancel" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">cancel</span></button>
<button type="submit" id="gitea-acc-save" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-accent text-t-accent hover:bg-t-accent/10 transition-colors"><i class="ph ph-floppy-disk text-sm"></i><span class="font-pixel text-[10px]">Save</span></button>
<button type="button" id="gitea-acc-test" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors"><i class="ph ph-plug text-sm"></i><span class="font-pixel text-[10px]">Test</span></button>
<button type="button" id="gitea-acc-cancel" class="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors"><i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">Cancel</span></button>
</div>
<div id="gitea-acc-status" class="hidden mt-1 px-3 py-2 text-[10px] font-mono break-words border border-t-border bg-t-bg"></div>
</form>
@@ -224,7 +224,7 @@ async function deleteAccount(id) {
if (!acc) return;
const ok = await hyprcrd.dialog.confirm(
`Delete gitea account "${acc.name}"? Stored token will be removed but no issues are deleted on the server.`,
{ title: 'delete account', okLabel: 'delete', cancelLabel: 'cancel', danger: true }
{ title: 'delete account', okLabel: 'Delete', cancelLabel: 'Cancel', danger: true }
);
if (!ok) return;
await hyprcrd.api(`api/gitea/accounts/${id}`, { method: 'DELETE' });
@@ -1169,9 +1169,9 @@ function renderStateToggleButton() {
const btn = $('gitea-state-toggle');
if (!btn || !currentIssue) return;
if (currentIssue.state === 'open') {
btn.innerHTML = '<i class="ph ph-check-circle text-sm"></i><span class="font-pixel text-[10px]">close</span>';
btn.innerHTML = '<i class="ph ph-check-circle text-sm"></i><span class="font-pixel text-[10px]">Close</span>';
} else {
btn.innerHTML = '<i class="ph ph-arrow-counter-clockwise text-sm"></i><span class="font-pixel text-[10px]">reopen</span>';
btn.innerHTML = '<i class="ph ph-arrow-counter-clockwise text-sm"></i><span class="font-pixel text-[10px]">Reopen</span>';
}
}
@@ -1447,7 +1447,7 @@ function injectHeaderButton() {
const btn = document.createElement('button');
btn.id = 'gitea-btn';
btn.className = 'flex items-center gap-2 px-2.5 py-1.5 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors';
btn.innerHTML = '<i class="ph ph-git-pull-request text-sm"></i><span class="font-pixel text-[10px]">gitea</span>';
btn.innerHTML = '<i class="ph ph-git-pull-request text-sm"></i><span class="font-pixel text-[10px]">Gitea</span>';
btn.addEventListener('click', openGitea);
const addBtn = document.getElementById('add-btn');
if (addBtn) header.insertBefore(btn, addBtn);
@@ -26,7 +26,7 @@ function injectFooterButton() {
const btn = document.createElement('button');
btn.id = 'logseq-import-btn';
btn.className = 'flex items-center gap-1.5 px-2.5 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors';
btn.innerHTML = '<i class="ph ph-graph text-sm"></i><span class="font-pixel text-[10px]">logseq import</span>';
btn.innerHTML = '<i class="ph ph-graph text-sm"></i><span class="font-pixel text-[10px]">Logseq import</span>';
group.insertBefore(btn, settingsBtn || null);
btn.addEventListener('click', () => fileInput.click());
@@ -47,14 +47,14 @@ function injectFooterButton() {
await hyprcrd.dialog.show({
title: 'logseq import',
message: `${data.imported} cards, ${data.assets} images imported`,
okLabel: 'ok',
okLabel: 'Ok',
});
} catch (err) {
await hyprcrd.dialog.show({
title: 'logseq import failed',
message: String(err?.message || err) || 'unknown error',
danger: true,
okLabel: 'ok',
okLabel: 'Ok',
});
}
e.target.value = '';
+19
View File
@@ -164,6 +164,25 @@
border-color: var(--t-accent);
}
/* ── Detail-sidebar button (icon-only, sits next to the "group" label) ── */
#detail-sidebar .slideshow-present-btn-sidebar {
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
margin-left: 4px;
color: var(--t-muted);
border: 1px solid var(--t-border);
background: transparent;
cursor: pointer;
transition: all 0.15s;
}
#detail-sidebar .slideshow-present-btn-sidebar:hover {
color: var(--t-accent);
border-color: var(--t-accent);
}
/* ── Hotspot editor ── */
#slideshow-editor.hidden { display: none; }
#slideshow-editor[disabled], #slideshow-editor [disabled] { opacity: 0.4; pointer-events: none; }
+5 -5
View File
@@ -60,11 +60,11 @@
<span id="slideshow-gp-count" class="font-pixel text-[9px] text-t-dim"></span>
<div class="flex-1"></div>
<button id="slideshow-gp-upload" class="flex items-center gap-1.5 px-2.5 py-1 text-xs border border-t-border text-t-muted hover:border-t-accent hover:text-t-accent transition-colors">
<i class="ph ph-upload-simple text-sm"></i><span class="font-pixel text-[10px]">upload</span>
<i class="ph ph-upload-simple text-sm"></i><span class="font-pixel text-[10px]">Upload</span>
</button>
<input type="file" id="slideshow-gp-file" accept="image/*" multiple class="hidden">
<button id="slideshow-gp-cancel" class="flex items-center gap-1.5 px-2.5 py-1 text-xs border border-t-border text-t-muted hover:border-t-danger hover:text-t-danger transition-colors">
<i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">cancel</span>
<i class="ph ph-x text-sm"></i><span class="font-pixel text-[10px]">Cancel</span>
</button>
</div>
<div id="slideshow-gp-grid" class="flex-1 min-h-0 p-4 grid gap-3 content-start select-none" style="overflow:auto;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));"></div>
@@ -79,9 +79,9 @@
<span class="font-pixel text-[10px] text-t-accent">hotspot target</span>
</div>
<div class="flex flex-col gap-1 p-3 border-b border-t-border shrink-0">
<button data-pick-target="slide:next" class="slideshow-pick-row"><i class="ph ph-caret-right text-sm"></i><span>next slide</span></button>
<button data-pick-target="slide:prev" class="slideshow-pick-row"><i class="ph ph-caret-left text-sm"></i><span>previous slide</span></button>
<button data-pick-target="slide:first" class="slideshow-pick-row"><i class="ph ph-skip-back text-sm"></i><span>first slide</span></button>
<button data-pick-target="slide:next" class="slideshow-pick-row"><i class="ph ph-caret-right text-sm"></i><span>Next slide</span></button>
<button data-pick-target="slide:prev" class="slideshow-pick-row"><i class="ph ph-caret-left text-sm"></i><span>Previous slide</span></button>
<button data-pick-target="slide:first" class="slideshow-pick-row"><i class="ph ph-skip-back text-sm"></i><span>First slide</span></button>
</div>
<div class="px-3 py-2 shrink-0 border-b border-t-border">
<input id="slideshow-pick-search" type="text" placeholder="search cards…" class="w-full bg-t-bg border border-t-border text-t-text text-xs" style="padding:4px 8px;border-radius:3px;">
+25
View File
@@ -306,6 +306,31 @@ if (groupBar) {
injectGroupBarButton();
}
// ── Detail-view sidebar button (shown when browsing a group card) ──
function injectDetailSidebarButton() {
const sidebar = $('detail-sidebar');
if (!sidebar) return;
if (sidebar.querySelector('.slideshow-present-btn')) return;
// Sidebar header is the first direct child div
const header = sidebar.firstElementChild;
if (!header) return;
const btn = document.createElement('button');
btn.className = 'slideshow-present-btn slideshow-present-btn-sidebar';
btn.type = 'button';
btn.title = 'present this group';
btn.innerHTML = '<i class="ph ph-projector-screen text-sm"></i>';
btn.addEventListener('click', async (e) => {
e.stopPropagation();
const pid = sidebar.dataset.groupId;
if (pid) await startPresentationForGroup(pid);
});
header.appendChild(btn);
}
if ($('detail-sidebar')) injectDetailSidebarButton();
else document.addEventListener('DOMContentLoaded', injectDetailSidebarButton, { once: true });
// ── Hotspot editor ───────────────────────────────────────────────
const ed = {