relay UI overhaul, favicon, settings, admin last-seen, fixes
Relay:
- Inbox/shared/sent split into own view-inbox (nav button + poll).
Compose is now single-column, centered.
- Header logo links to compose. Inbox badge stays fresh on all
views via a quiet loadInbox on every view switch.
- Mobile menu: full-height sheet below header, larger buttons
(15px font, 14px padding), full width.
- Login form wrapped in <form> with name attributes + for/id on
labels so password managers can autofill.
- Admin user list shows "last seen <relative time>" per user.
last_seen_at column on tenants, updated on every authenticated
request (session + client API).
- Cache-busting on style.css + app.js via filemtime.
- View persistence in localStorage (survives reload).
- Shared-bucket cards show title only (preview line removed).
Favicon:
- favicon.svg added to project root + copied to public/, relay/,
website/. Linked via <link rel="icon" type="image/svg+xml"> in
all three <head> sections.
Settings:
- New toggle: "Show shopping list items in task collector"
(default off). collectTasks skips #einkauf/#shopping cards when
disabled.
Fixes:
- card-spinner gets display:inline-block so it rotates outside
flex containers (shopping save spinner).
- Tim tab test opens the plugin before checking active state.
- Compose view centered with margin:auto on desktop.
Bumps to 1.9.29.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
8e738ed9d4
commit
d50f9fe789
19 files changed
+209
-101
No files matched your search
+35
-27
@@ -7,6 +7,7 @@ if (!defined('RELAY_BOOTSTRAPPED')) { http_response_code(404); exit; }
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="theme-color" content="#1e293b">
|
||||
<title>hyprcrd relay</title>
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg">
|
||||
<link rel="stylesheet" href="fonts/phosphor.css">
|
||||
<link rel="stylesheet" href="ui/style.css?v=<?= filemtime(__DIR__ . '/style.css') ?>">
|
||||
</head>
|
||||
@@ -14,14 +15,17 @@ if (!defined('RELAY_BOOTSTRAPPED')) { http_response_code(404); exit; }
|
||||
|
||||
<header>
|
||||
<span class="dot"></span>
|
||||
<i class="ph ph-broadcast brand-icon"></i>
|
||||
<h1>hyprcrd relay</h1>
|
||||
<a onclick="showView('compose')" style="display:flex;align-items:center;gap:8px;text-decoration:none;cursor:pointer;">
|
||||
<i class="ph ph-broadcast brand-icon"></i>
|
||||
<h1>hyprcrd relay</h1>
|
||||
</a>
|
||||
<button id="header-status" class="header-status pixel" onclick="jumpToInbox()" title="jump to inbox"></button>
|
||||
<span class="spacer"></span>
|
||||
<button id="nav-burger" class="nav-btn hidden" aria-label="menu" onclick="toggleNavMenu()"><i class="ph ph-list"></i></button>
|
||||
<div id="nav-buttons" class="hidden">
|
||||
<span id="nav-user" class="user"></span>
|
||||
<button id="nav-compose" class="nav-btn active" onclick="showView('compose')"><i class="ph ph-pencil-line"></i> compose</button>
|
||||
<button id="nav-inbox" class="nav-btn" onclick="showView('inbox')"><i class="ph ph-tray"></i> inbox</button>
|
||||
<button id="nav-chat" class="nav-btn" onclick="showView('chat')"><i class="ph ph-chat-circle-dots"></i> chat</button>
|
||||
<button id="nav-shopping" class="nav-btn" onclick="showView('shopping')"><i class="ph ph-shopping-cart"></i> shopping</button>
|
||||
<button id="nav-account" class="nav-btn" onclick="showView('account')"><i class="ph ph-user-circle"></i> account</button>
|
||||
@@ -58,15 +62,17 @@ if (!defined('RELAY_BOOTSTRAPPED')) { http_response_code(404); exit; }
|
||||
<div id="view-login" class="auth-form hidden">
|
||||
<i class="ph ph-key auth-icon"></i>
|
||||
<h2>login</h2>
|
||||
<div class="field">
|
||||
<label>username</label>
|
||||
<input type="text" id="login-username" autocomplete="username">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>password</label>
|
||||
<input type="password" id="login-password" autocomplete="current-password">
|
||||
</div>
|
||||
<button class="btn btn-primary" onclick="doLogin()"><i class="ph ph-sign-in"></i> unlock</button>
|
||||
<form id="login-form" autocomplete="on" onsubmit="event.preventDefault(); doLogin();">
|
||||
<div class="field">
|
||||
<label for="login-username">username</label>
|
||||
<input type="text" id="login-username" name="username" autocomplete="username">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="login-password">password</label>
|
||||
<input type="password" id="login-password" name="password" autocomplete="current-password">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary"><i class="ph ph-sign-in"></i> unlock</button>
|
||||
</form>
|
||||
<div id="login-err" class="err"></div>
|
||||
</div>
|
||||
|
||||
@@ -106,22 +112,24 @@ if (!defined('RELAY_BOOTSTRAPPED')) { http_response_code(404); exit; }
|
||||
</div>
|
||||
<div id="compose-status" class="compose-status-bar"></div>
|
||||
</div>
|
||||
<div id="compose-sidebar" class="compose-sidebar">
|
||||
<div id="inbox-section" class="section">
|
||||
<h2><i class="ph ph-tray"></i> your inbox <span class="count" id="inbox-count">0</span>
|
||||
<span style="flex:1"></span>
|
||||
<button id="inbox-delete-all" class="btn btn-danger hidden" style="padding:3px 10px;font-size:9px;" onclick="deleteAllMessages()"><i class="ph ph-trash"></i> delete all</button>
|
||||
</h2>
|
||||
<div id="inbox-list"></div>
|
||||
</div>
|
||||
<div id="shared-section" class="section">
|
||||
<h2><i class="ph ph-users-three"></i> shared buckets <span class="count" id="shared-count">0</span></h2>
|
||||
<div id="shared-list"></div>
|
||||
</div>
|
||||
<div id="outbox-section" class="section">
|
||||
<h2><i class="ph ph-paper-plane-tilt"></i> sent <span class="count" id="outbox-count">0</span></h2>
|
||||
<div id="outbox-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Inbox view (inbox + shared buckets + sent) ── -->
|
||||
<div id="view-inbox" class="hidden">
|
||||
<div id="inbox-section" class="section">
|
||||
<h2><i class="ph ph-tray"></i> your inbox <span class="count" id="inbox-count">0</span>
|
||||
<span style="flex:1"></span>
|
||||
<button id="inbox-delete-all" class="btn btn-danger hidden" style="padding:3px 10px;font-size:9px;" onclick="deleteAllMessages()"><i class="ph ph-trash"></i> delete all</button>
|
||||
</h2>
|
||||
<div id="inbox-list"></div>
|
||||
</div>
|
||||
<div id="shared-section" class="section">
|
||||
<h2><i class="ph ph-users-three"></i> shared buckets <span class="count" id="shared-count">0</span></h2>
|
||||
<div id="shared-list"></div>
|
||||
</div>
|
||||
<div id="outbox-section" class="section">
|
||||
<h2><i class="ph ph-paper-plane-tilt"></i> sent <span class="count" id="outbox-count">0</span></h2>
|
||||
<div id="outbox-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in new issue
Block a user