Add chat actions, channels/groups mgmt, directory + deadmans bots, network status
Profiles/bots (profiles.py, main.py): - Surface real send errors; fix group send and member-count staleness (refresh on view) - Group/channel actions: join, leave, owner delete; consistent member counts - Contacts: always-visible Chat, plus Clear chat and Delete contact - Support bot: OpenAI-compatible LLM backend (Grok/Ollama/OpenAI) per-bot config - Deadmans bot: check-in window, trigger message, recipients, owner - Directory bot: add-to-group registration, super-user /approve /reject /list, search, publishes listing.json in the website schema (directory.py registry module) - Profile edit (name/bio/avatar) + avatars on list pages - Global status + /network page (operators, SMP/XFTP servers) and Settings network info UI (templates): - Chat rooms; collapsible left sidebar with notifications + network widget - Per-directory-bot website generated on creation (name substituted) - Matrix theme; copy/hyperlink addresses; site footer Ignore runtime bot state and generated directory sites. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
63
manager/templates/notifications.html
Normal file
63
manager/templates/notifications.html
Normal file
@@ -0,0 +1,63 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Notifications — SimpleX Manager{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
<style>
|
||||
.notif-item { display: block; padding: 14px 18px; border-bottom: 1px solid var(--border);
|
||||
text-decoration: none; color: var(--text); border-left: 3px solid transparent; }
|
||||
.notif-item:last-child { border-bottom: none; }
|
||||
.notif-item:hover { background: var(--bg); }
|
||||
.notif-item.unread { border-left-color: var(--accent); }
|
||||
.notif-text { margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 540px; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="flex-between" style="margin-bottom: 24px;">
|
||||
<h1 style="margin:0;">Notifications</h1>
|
||||
{% if items %}
|
||||
<button class="btn btn-ghost" onclick="markAllRead()">Mark all read</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if items %}
|
||||
<div class="card" style="padding:0;">
|
||||
{% for n in items %}
|
||||
<a class="notif-item {% if not n.read %}unread{% endif %}"
|
||||
href="/profile/{{ n.profile_id }}/chat/{{ n.chat_type }}/{{ n.chat_id }}">
|
||||
<div class="flex-between">
|
||||
<div style="min-width:0;">
|
||||
<div><strong>{{ n.sender or 'Someone' }}</strong> <span class="muted">→ {{ n.profile_name }}</span></div>
|
||||
<div class="muted notif-text">{{ n.text }}</div>
|
||||
</div>
|
||||
<span class="muted notif-time" data-ts="{{ n.ts }}" style="flex-shrink:0;margin-left:12px;"></span>
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="card" style="text-align:center;padding:48px;color:var(--muted);">
|
||||
No notifications yet. Incoming messages across all accounts will appear here.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<script>
|
||||
function _ntoken(){ return document.cookie.match(/(?:^|;\s*)token=([^;]+)/)?.[1] || ''; }
|
||||
|
||||
async function markAllRead() {
|
||||
await fetch('/api/notifications/read', { method: 'POST', headers: { 'X-Token': _ntoken() } });
|
||||
location.reload();
|
||||
}
|
||||
|
||||
// Localize timestamps
|
||||
document.querySelectorAll('.notif-time').forEach(el => {
|
||||
const d = new Date(el.dataset.ts);
|
||||
if (!isNaN(d)) el.textContent = d.toLocaleString([], {month:'short', day:'numeric', hour:'2-digit', minute:'2-digit'});
|
||||
});
|
||||
|
||||
// Mark read shortly after viewing so the badge clears (keeps this view's highlights)
|
||||
setTimeout(() => {
|
||||
fetch('/api/notifications/read', { method: 'POST', headers: { 'X-Token': _ntoken() } });
|
||||
}, 1200);
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user