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:
Jon
2026-06-03 21:26:16 +01:00
parent ecce417f6d
commit c1bb9cb955
13 changed files with 1446 additions and 29 deletions

View File

@@ -133,6 +133,21 @@
</div>
</div>
<div class="card settings-section">
<h2>Network</h2>
{% if network %}
<table>
<tr><td style="color:var(--muted);width:45%;">SMP proxy mode</td><td>{{ network.smpProxyMode | default('—', true) }}</td></tr>
<tr><td style="color:var(--muted);">SMP proxy fallback</td><td>{{ network.smpProxyFallback | default('—', true) }}</td></tr>
<tr><td style="color:var(--muted);">Host mode</td><td>{{ network.hostMode | default('—', true) }}</td></tr>
<tr><td style="color:var(--muted);">Session mode</td><td>{{ network.sessionMode | default('—', true) }}</td></tr>
</table>
<p class="muted" style="margin-top:12px;">Read-only here. <a href="/network" style="color:var(--accent);">View full server list →</a></p>
{% else %}
<p class="muted">Start a profile to view network configuration.</p>
{% endif %}
</div>
<script>
function currentTheme() {
return localStorage.getItem('theme') ||