fixes + theme
This commit is contained in:
1 parent
5af49655d6
commit
22f73ab3b9
25 files changed
+1004
-206
No files matched your search
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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,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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 = '';
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;">
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
Reference in new issue
Block a user