Commit Graph
173 Commits
Author SHA1 Message Date
ancsemi 096ad7cf8e Show invites, joins and leaves in group DMs; mark existing members in the invite list 2026-10-14 01:23:13 -04:00
ancsemi fb3666e27c Server mute with an except @mentions option, and Mute for me 2026-10-14 01:12:43 -04:00
ancsemi 7f3df332d7 Arrange your own channel order, kept on your account (#5779) 2026-10-14 00:43:14 -04:00
ancsemi 39c80fc9a5 Closed forum topics take replies only from moderators and admins 2026-10-14 00:10:31 -04:00
ancsemi 45140c1ef2 Discord import puts threads in their channel and forum posts in a forum (#5772) 2026-10-13 19:20:11 -04:00
ancsemi 05f329a563 Ferry keeps Discord ids and carries replies from chat threads (#5773) 2026-10-13 19:20:11 -04:00
ancsemi e593481956 Imported Discord messages belong to no Haven account (#5771) 2026-10-13 19:12:49 -04:00
ancsemi 2d12bb6039 Markdown tables keep their rows instead of showing them as text 2026-10-13 19:11:01 -04:00
ancsemi f71ba50d78 Moderation history: warnings, notes and a record of every action (#5759) 2026-10-13 17:42:11 -04:00
ancsemi 8c60827c7a Text size keeps the density and DM PiP message sizes as its base (#5775) 2026-10-13 17:09:52 -04:00
Amnibroandancsemi f0202c4373 Settings: an Accessibility section for text size, spacing, fonts, contrast and motion (#5775)
Zoom moves into a new Accessibility section (the section keeps its
section-zoom id, which layout plugins anchor to) next to:

- Message text size, 80 to 200 %, separate from Zoom: messages, threads,
  forum posts, code blocks and the message boxes.
- Line spacing (normal, relaxed, loose) and letter spacing (normal, wide).
- Font: the theme's, the system's, Atkinson Hyperlegible or OpenDyslexic,
  self-hosted under SIL OFL 1.1 with their licenses in /fonts.
- High contrast: secondary text and borders pulled toward each theme's own
  text color, and a thick focus ring.
- Reduce motion: follow system, on or off. One html.reduce-motion class now
  covers every animation, the theme effects, the shimmering role colors,
  smooth scrolling, and GIFs, animated emoji and profile pictures, which
  wait for hover or tap. The old prefers-reduced-motion rules use it too.
- Underline links, and larger click targets.

Everything is per device and applied by theme-init.js before first paint,
which hands the same read/apply functions to the settings page.

Also: keyboard focus rings, keyboard-reachable settings nav rows,
aria-labels on the icon buttons in the channel header and message box, and
aria-pressed on the picker buttons.

Co-authored-by: ancsemi <ancsemi@gmail.com>
2026-10-13 17:06:23 -04:00
Amnibro c8659a1cc7 Official messages: keep official mode on, and choose how they look (#5758)
All opt-in; nothing changes until someone picks a setting.

- Keep official mode on (Settings > Chat, saved on the account as
  users.official_mode, every device follows through set-official-mode /
  official-mode-changed). The megaphone then rests armed, so staff don't
  re-arm it for every message; pressing it sends just the next message
  plain. The client still sends highlight: true per message, so the wire
  format and the server's checks are unchanged.
- Official messages look (Settings > Chat, per device): Badge (the default,
  as before), Colored text (the text and a lighter wash in the role's color,
  a thinner bar, no badge; text mixed with the theme's own text color, more
  of it on light themes), or Off.
- With Colored text, consecutive official messages from one person group
  into one block. Badge keeps every official message's own header.
- session-info carries features: ['highlight_messages', 'official_mode'] and
  officialMode, so apps can tell what a server supports.
2026-10-12 17:14:57 -04:00
ancsemi fc9bafa47f Auto-Mod: blocked links are strikes only for accounts under a week old 2026-10-10 21:40:27 -04:00
ancsemi eb21adae08 Auto-Mod no longer bans on its own by default 2026-10-10 18:32:22 -04:00
ancsemi 69c260ebd1 Limit new DMs per hour and apply the new-account wait to them 2026-10-10 18:32:22 -04:00
ancsemi 26a2d37962 Remove internal planning docs from the repo 2026-10-10 18:08:54 -04:00
ancsemi 70adbee04b Replace em dashes in test comments and names 2026-10-10 16:08:55 -04:00
ancsemi e7eef3fba6 Add tests for the Channel Tabs layout (#5749)
Cover the Layout picker contract, the unread dots (DMs vs channels, muted
channels, Haven's server counts), hooking and unhooking Haven's methods,
restoring the Join and Create sections without undoing Haven's changes,
the tab kept in plugin data, guests, the Create Temp Channel row and the
translated labels.
2026-10-10 16:01:17 -04:00
ancsemi f409f6fc36 Forum topics that are only a link show the link's title and picture (#5745)
A forum post whose text is just a YouTube link used the raw link as its
title and had no thumbnail, and the open topic showed only the link.

The topic card now takes the title and picture from the link's preview when
the post opens with a bare link and has no typed title, and the picture goes
through the media proxy like every other remote image (posted image
thumbnails did not before). The open topic gets the same video player or
link card the post gets in chat. A typed title still wins.

YouTube previews come from YouTube's oEmbed endpoint, since the watch page
is too large for the generic scrape to reach its title and image.
2026-10-09 23:34:36 -04:00
Amnibro 936e89cb84 Default Theme and the shared new-member theme are one setting (#5747) (#5748)
Default Theme in Appearance & Welcome and the theme in Defaults for New
Members were stored separately, so a new member saw one on the sign-in page
and the other once the shared defaults applied. Sharing a theme now also sets
the Default Theme (when it is a built-in or a published custom theme),
changing the Default Theme updates the shared theme, choosing None removes it
from the shared set, and unpublishing a custom default drops it from both.
The shared version is untouched, so nobody is re-sent defaults.
2026-10-09 23:24:08 -04:00
ancsemi 0d96d9858c Server side of Blog mode for forums (#5742)
A new forum_blog switch on channels (off by default), turned on and off
through the same channel permission toggle as Forum mode and NSFW, so only
someone who can change the channel's settings can flip it. The channel list
carries it.

With it on, a topic belongs to its author. A reply in the topic's thread is
part of the post when the topic author's own account wrote it (and it is not
a bot or relayed message); everything else is a comment. Nothing is stored
per message, so turning it on or off needs no migration and changes nothing
on disk. The rule lives in src/forumBlog.js.

The server works the answer out and sends it: thread history marks each reply
post_part and says the topic is a blog post, a new reply carries post_part,
and topic cards and live thread updates carry a comments count alongside the
reply count. user_id comes from the signed-in socket, so nobody can make
their reply count as the author's, and bot replies are always comments.
2026-10-09 13:23:19 -04:00
ancsemi 9687bddc08 In the Desktop app, removing a server or changing its name or icon from Manage Servers is marked as the user's own, so the app can tell it apart from routine syncing and asks only about these 2026-10-09 13:12:31 -04:00
ancsemi fcf45cc1b3 Add likes and dislikes on forum posts (#5742)
A new Channel Functions row for forums, "Votes on posts", picks Off (the
default), Likes, or Likes and dislikes. Anyone who can change the channel's
settings can set it.

When votes are on, every topic shows a like button with its count, plus a
dislike button when dislikes are allowed, in the list, gallery and feed views
and in the bar above an open topic. Each member has one vote per topic:
clicking it again takes it back, and liking replaces a dislike (and the other
way round). Counts update live for everyone viewing the forum without saying
who voted. Only members who can see the forum can vote, muted members cannot,
and votes are refused while the setting is Off (stored votes are kept and come
back if it is turned on again). The forum's sort menu gains "Most liked" while
votes are on.

Votes live in a new forum_votes table set up by src/forumVotes.js; the socket
handlers are in src/socketHandlers/forumVotes.js and the client side in a new
app-forum-votes.js module. Reactions are unchanged.
2026-10-09 11:24:54 -04:00
ancsemi d9591eba7e Let admins make new accounts wait before posting (#5742)
A new Auto-Mod setting, "New accounts must wait before posting (minutes)",
sits next to the new-account link rule. 0 (the default) turns it off; the
maximum is 10080 minutes (one week).

While an account is younger than that, the server refuses channel messages,
forum topics, attachments, thread replies, polls, scheduled messages and DMs
to other people. A DM with yourself is allowed. Admins and members at or above
the Auto-Mod exempt role level are not held back. If the check itself fails,
the post is refused rather than let through.

The refusal says how long is left, and the app puts the message (or the
forum post being written) back so nothing is lost.
2026-10-09 11:24:39 -04:00
ancsemi 1318501445 Server side of defaults for new members (#5739)
An admin can store a snapshot of cosmetic settings as the server setting
member_defaults, with an allowlist of keys and value checks. Each member
receives the theme and effects part once, only where they never saved
that setting themselves or still have what an earlier set put there.
Apply to everyone raises a version so members get the set once more.
Server templates carry the snapshot without the version.
2026-10-09 11:17:45 -04:00
ancsemi af48e56f4a Only one channel or DM menu is open at a time (#5744) 2026-10-09 10:34:37 -04:00
ancsemi 558a8a1494 In a Haven Desktop that asks you itself before a server page changes your server list, the page no longer asks a second time, waits for your answer there before removing or renaming a server, and stops handing the app automatic changes 2026-10-06 21:00:28 -04:00
ancsemi 52b572bd75 The person who started a group DM can now remove people from it with Remove from group in the member menu, after a confirm: the removed person loses the group at once on every device and the members still in it switch to a new key, the same as a moderator's kick. Only the group's creator gets this and not on themselves; once they have removed everyone, leaving as the last member deletes the group (#5740) 2026-10-06 20:54:14 -04:00
ancsemi ddbeffd8cd The server admin can now delete a group DM for everyone in it from the DM menu: the group goes away at once for every member and pending invitee, the pop-out DM window included, along with its messages, keys and the members' attachments. Moderators and the group's creator cannot do this, and an admin outside a group can do the same through Delete DM (#5740) 2026-10-06 20:54:14 -04:00
ancsemi 229ca512e2 Template unit test: a temp folder Windows still holds no longer fails the test file 2026-10-06 20:02:07 -04:00
ancsemi 732bd6c671 Someone kicked from a channel is told which channel they were kicked from, instead of a message that reads like they were kicked from the server 2026-10-06 19:59:54 -04:00
ancsemi 710c01e953 The last member left in a group DM can now delete it from the DM menu, which removes it with its messages and attachments; the menu and Leave group both check who is still in the group with the server first, so leaving last after others left also takes the group's attachments with it (#5740) 2026-10-06 19:59:54 -04:00
ancsemi 06baaea64a Kicking someone from a group DM now removes the group from their app straight away and tells the members still in it, so their member list updates and they switch to a new key the kicked person does not have; the kicked person is told they were removed from the group, and a group that goes away also closes in the pop-out DM window (#5740) 2026-10-06 19:59:54 -04:00
ancsemi 25eca4642c An old one to one DM whose partner left is no longer turned into notes to self by the 4.19.0 upgrade: only a DM nobody else ever wrote in counts, and servers already upgraded to 4.19.0 get those DMs corrected once 2026-10-06 19:59:54 -04:00
ancsemi bd4a1ce266 A server name you type when adding a server, or one you gave a server before 4.19, is kept instead of being replaced by the server's own name at the next status check, and in Haven Desktop it is shared as your own name with the other servers 2026-10-06 19:59:54 -04:00
ancsemi 09c47b1345 Sync in Manage Servers now reconciles the list with the Desktop app, your encrypted backup and each server's name, then says what it did (up to date, or how many servers were added, removed and renamed) and only reports a failure when something actually failed 2026-10-06 01:39:38 -04:00
ancsemi 4eac343574 When a server template creates or changes roles, members online who hold them get their new permissions straight away, the same way editing a role in Settings pushes them; the role refresh helpers now live in roleRefresh.js so both paths share them (#5732) 2026-10-05 18:44:29 -04:00
ancsemi 90f8ea223d Applying a server template now updates each changed setting live and sets off what saving it in Settings would (the new server name, the link policy, the member list), and the audit log records what the template created, each changed setting, and each role with its permissions (#5732) 2026-10-05 18:44:29 -04:00
ancsemi 88244097f5 Server template imports now keep emojis and stickers within the server's size limits, copy only the images the template uses, and are refused when the server is low on disk space, like uploads (#5732) 2026-10-05 18:44:19 -04:00
ancsemi 9c723cc9ea Exporting a server template now tidies names and values saved under older rules (channel and role names, categories, webhook and post author names, forum layouts, link rules, emoji names, role menus) and keeps within the import's size limits, so a file exported from any server can be imported again (#5732) 2026-10-05 18:44:19 -04:00
ancsemi 69632ed668 Role menus from a server template are now posted with the standard menu text instead of text from the file, so a template cannot post its own words under the admin's name, and their emojis follow the same rules as a menu posted by hand (#5732) 2026-10-05 18:44:19 -04:00
ancsemi b31a759b2b Server templates can no longer hand out power through roles: admin-only permissions are left out of imported roles, the Admin role is never exported or changed, and a role that carries more than the Member role has is not given to new members, offered on a role menu or given to everyone who joins a channel; Replace layout leaves such roles as they are (#5732) 2026-10-05 18:44:19 -04:00
ancsemi 695d9c89fa Server templates can no longer set level thresholds for admin-only permissions, so an imported file cannot hand every member powers like transfer_admin or manage_server; the admin's own thresholds for those stay as they are (#5732) 2026-10-05 18:44:19 -04:00
ancsemi 889ef88e77 The server template API test now waits for its server to exit before removing the data folder, so it passes on Windows (#5732) 2026-10-05 18:44:19 -04:00
ancsemi 6b28ea97a9 Notes to self (a DM with yourself) are no longer deleted by the 15 minute orphan DM cleanup 2026-10-05 18:30:22 -04:00
ancsemi fce3426b64 Sending in a group DM no longer refetches the member list and keys every time (#5733)
Every group message made two extra round trips first. The member list
and keys are now kept until membership changes, a new key is published,
a key is re-shared, someone's keys are trusted, or the connection drops.
2026-10-05 18:28:50 -04:00
ancsemi e856d5229c Deleting a group DM as an admin who is not in it also removes its keys and invites (#5733)
Only the last-member-leaves path cleaned up a group's key, epoch, invite
and rewrap rows. That cleanup now lives in the shared DM delete, so every
way a group is deleted removes them.
2026-10-05 18:28:49 -04:00
ancsemi 7327d5627a Group DMs only share the group key with keys this device has pinned, and only accept keys a member signed (#5733)
The server relays every group key, so it could forge a rewrap request and
collect the group key from everyone online, or plant an epoch key of its
own. Now a device wraps the group key only for the encryption key it has
pinned for that person (the same pins 1:1 DMs use), accepts a wrapped key
only from a sender whose pinned key opens it, and requires each epoch to
carry a statement signed by the member who published it, naming the key,
the group, the epoch and exactly who it was shared with. Signing keys are
pinned on first sight too. When someone's keys change, Haven asks before
trusting them, as 1:1 DMs do, and until then the group key is not shared
with the new keys and messages signed with them stay hidden. Groups whose
current key predates this are rotated to a signed one automatically.
2026-10-05 18:28:49 -04:00
ancsemi af3316c327 Group messages stay readable after the sender resets their encryption keys (#5733)
Only the sender's current signing key was tried, so a key reset turned
everything they had sent before into "could not be verified". The server
now keeps every signing key a person has published, and a message shows
when it verifies under any of them. A message that verifies under none of
its author's recorded keys is still hidden.
2026-10-05 18:28:49 -04:00
ancsemi b5341b8772 Group DM signing keys are set up once per connection, so a first-time user no longer ends up with mismatched keys (#5733)
Setup ran twice at once on every connect and each run accepted any
published reply, so a new account could save one key to its backup while
the server kept another, and everyone then saw that person's group
messages as unverifiable. Setup is now shared by every caller, replies
carry a request id, and the key and its backup are stored in one step.
Another device racing on a new account adopts the winner's key.
2026-10-05 18:28:49 -04:00