- Package sidebar condensation into plugins/ChromeLayout.plugin.js
- Promotes channel creation, joining, and temp channels to prominent header action menu
- Docks DMs and People in footer with unread badges and sliding drawer
- Equips channel rows with voice controls (join/leave)
- Adds quick settings menu to home server icon
- Full height channel section with category group dividers
- Conforms to the Layout picker contract in docs/theme-authoring.md
- Adds test suite in test/chromeLayout.test.js and entry in GUIDE.md
* Themes: Glassy Neon and seasonal themes (Christmas, Halloween, Thanksgiving)
- Add themes/glassy-neon.theme.css: Tron-inspired cyberpunk glassmorphism with perspective neon floor grid, laser glow borders, and rotating identity disc.
- Add themes/christmas.theme.css: Festive evergreen pine with twinkling string lights, falling snow, candy-cane borders, and glowing Christmas tree (@section Seasonal).
- Add themes/halloween.theme.css: Eerie gothic midnight with drifting ghostly mist, flying witch moon, carved jack-o'-lantern, blinking black cat, and dripping toxic slime borders (@section Seasonal).
- Add themes/thanksgiving.theme.css: Warm autumn harvest with tumbling fall leaves, waddling turkey watermark, harvest garland, and striped borders (@section Seasonal).
- Parse optional @section and @category metadata tags in src/themeMetadata.js.
- Organize theme pickers and admin settings so seasonal themes appear in a dedicated 'Seasonal' group.
- Support prefers-reduced-motion in all four new themes.
- Document bundled additions in GUIDE.md.
* Themes: rebuild Glassy Neon and the seasonal themes as full scenes
Restyle every surface of the four themes (server rail, sidebars, header,
topic bar, message list, composer, buttons, inputs, scrollbars, modals,
theme popup and the login page) and give each a layered, animated scene
drawn with self-contained SVG data URIs.
- Glassy Neon: Haven on the Grid. Opaque holo-glass panels with lit cyan
and orange edge rails, circuit traces, data streams running down the
rails, light-cycle trails along the header and composer, a perspective
light floor that races toward the viewer, horizon ridges, a scan sweep,
counter-rotating identity disc rings and glitch hover accents.
- Christmas: a cozy cabin looking out on a moonlit pine forest. Plaid
walls, a fireplace with stockings and flickering flames, a decorated tree
with twinkling lights and presents, garland and string lights on the
header, snow caps, frosted window corners and three parallax snow layers.
- Halloween: a cartoony haunted night. Bats crossing a big moon, graveyard
fog, a floating ghost, flickering jack-o'-lanterns, a black cat with
glowing eyes and a swishing tail, a bubbling cauldron, cobwebs, a
dangling spider and green goo that drips from the header and composer.
- Thanksgiving: a harvest evening. Two parallax layers of falling leaves,
swaying maple trees, a farmstead sunset, a leaf garland, flannel and
barn-wood panels, hay bales, corn shocks, pumpkins, and two turkeys that
wobble, gobble and strut.
Decorations use pointer-events: none and sit behind content in negative
z-index layers, the message column keeps a dark veil so message text stays
above WCAG AA, animations only change transform and opacity, and
prefers-reduced-motion stops every animation. Pseudo-element rules raise
their specificity so the effects overlay system does not strip them.
Move the seasonal-theme check into HavenThemeCompat.isSeasonalTheme so the
theme bar, plugin loader and admin list share one implementation, and test
it.
The Braid and Compact switches become a single picker: Original (Haven's
own layout) and every <Name>Layout.plugin.js on the server, one at a time.
A new layout plugin shows up without any change to Haven, so alternative
sidebars can ship as layouts while Original stays the default. The picker
shows the chosen layout even while it waits (Compact needs a wide window,
Braid waits for Mod Mode), and follows Braid's own shortcut and menu.
theme-authoring.md says what a plugin needs to appear there.
The first page of the setup wizard now offers Restore from a backup next to
Get Started. It takes a backup made with Messages ticked and brings back the
accounts, channels, messages, settings and (when included) uploaded files,
so there is no new admin to create and then import over. Data already on the
computer is kept as .pre-restore copies, a bad or partial backup is refused
before anything is touched, and the new .env names the restored admin. The
restore itself is installer/restore-backup.js, using the same extractor as a
restore from Settings.
For servers that can only reach the internet through a proxy: set
https_proxy, http_proxy and no_proxy in .env and Haven's outgoing requests
(link previews, the media proxy, bot callbacks, push notifications, update and
DDNS checks) go through it. Only http:// proxy addresses are supported, and
voice is unaffected.
With no proxy set, nothing changes. With one set, Haven warns at startup that
the proxy becomes part of its security: requests through it cannot be pinned
to the address Haven checked, so the proxy should be limited to the
destinations Haven needs. .env.example and GUIDE.md ("Outgoing Proxy") explain
it. Proxy passwords are hidden in the log, HTTPS certificates are checked
against the real target, and proxied requests time out and can be cancelled.
The entrypoint handed /data to the node user only when the folder itself
belonged to someone else. Files copied in from another machine, or made by
running Haven once outside the container, could belong to another user inside
a folder that looked fine, so the database could not be opened and the
container restarted in a loop with a bare SQLITE_CANTOPEN. It now checks the
database, its WAL files, .env, the certificates and uploads too, and says so
when it cannot fix them. The server's own error names the folder and the
command that fixes it. The guide has a short Podman section (SELinux :Z,
ports below 1024, file owners).
Files from deleted messages and channels were parked in deleted-attachments and only ever removed when auto-cleanup was enabled with a max age set, and even then only from the folder's top level, so on most servers they sat there forever. They now expire on their own clock, a week after deletion by default, with a Keep deleted files for (days) setting under Auto-Cleanup (1 to 3650, validated on the server). The move stamps the file's time so the window counts from the deletion rather than the upload, and the sweep walks sub-folders and prunes the empty ones.
4.5.0 taught the server to make its certificate itself, but Start Haven.bat, Install Haven.ps1 and the web installer still went looking for openssl.exe first and reported a skipped certificate as done. They now call the same generator through scripts/gen-cert.js, the certificate carries the CA and server-auth flags phones expect when you import it, and the guide and support page stop telling people to install OpenSSL. Reported by MutantRabbit767.
Dropping, pasting or picking several files at once used to keep the first
and drop the rest, and the queue stopped at a fixed five. Every file now
queues, in the main composer, threads and the DM PiP alike, up to a new
Max Attachments per Message setting under Uploads & Limits (1 to 50,
default 10) that counts images and other files together. A batch that
has nowhere to go, or runs past the cap, gets one toast instead of one
per file. The per-minute upload allowance follows the setting (twice it,
never under the old ten) so a full drop is not cut off part way.
Also bumps the cache busters for the modules touched today and adds the
Unreleased CHANGELOG entries for #5561, #5426 and #5574.
Requested by Sheoji.
A forum is a regular channel where every top-level message is a topic.
Replies go in the message's thread, the topic shows its reply count, and a
reply bumps the topic to the newest end of the channel, so old topics
resurface instead of sinking. Toggle it in Channel Functions or tick Forum
when creating a channel.
The history query orders topics by their latest activity, with cursors
resolved to activity stamps so paging keeps working, and topics never
compact into each other so a bump can move the node in place. Covered by an
integration test that boots a scratch server.
5472 preferred Tenor because GIPHY looked dead. That was backwards: GIPHY still works, and Tenor is no longer offered for new setup. Existing Tenor keys still serve if no GIPHY key is set.
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: ancsemi <ancsemi@gmail.com>
The NAT section assumed coturn, and the recurring report is that coturn behind
a home router is where people give up. Several running Haven at home have
landed on eturnal instead and got it working, so the guide should say it is an
option rather than reading as though coturn is the only one.
The useful part is that the mistake is identical in both: eturnal's
relay_ipv4_addr is coturn's external-ip, its autodetection does not find the
public address behind NAT either, and everything else on the page carries over
unchanged. Haven only ever sees the TURN_URL, so it does not care which is
running. (#5542)