mirror of
https://github.com/ancsemi/Haven.git
synced 2026-10-27 17:15:24 +00:00
* Rework message search into a persistent overlay panel Search results now open as an overlay on the right side over the member list, the way Discord does it. The panel stays open across channel switches and only closes when you close it yourself. Public channels share one panel while each DM keeps its own. Results paginate at 25 per page. The panel clears and asks you to refresh when a channel or one of your roles changes, so it never shows messages you can no longer see. A collapsed sidebar expands automatically while the panel is open. * Make message search global with SQLite full text search Search now spans every channel you can see instead of just the current one, backed by an FTS5 index that stays in sync with messages through triggers. Results are scoped to your channel memberships on every query, so you never see anything you don't have access to. in:#channel narrows to one channel, from: and has: still work. The tokenizer is admin configurable through HAVEN_SEARCH_TOKENIZER and reconciled at boot: unicode61 by default (closest to Discord), with porter for stemming and trigram for substring matching. Changing it rebuilds the index once on the next restart. Results come back 25 per page with a total count, sorted newest first. * Add a filter picker and cross-channel results to search Clicking the search box opens a filter popover with from:, in: and has: pickers. Each lists what you can see (members, channels, media types), rendered client side with a prefix filter box, and clicking one appends the filter to the search box. A filter button next to the box toggles the popover so you can reopen it without closing search. Channel names are not unique, so in:#code selects a channel by its code while in:name still matches by name. The picker fills the code form so duplicate names are never ambiguous. Search results now show the channel each message came from as #name (code) above the author, and clicking a result switches to that channel before jumping to the message so cross-channel results work. * Add date, pinned, and audio filters plus a sort control to search The filter popover gains before:, after: and during: date pickers, a pinned toggle, and audio in the has: list. before/after take a boundary date and during matches a single day. A sort row lets you order results by newest, oldest, or most relevant, which the search engine already supported but the UI never exposed. All of these run server side against the message index, so they stay scoped to the channels you can see. * Guard against stale search results, add a loading state and recents Each search request carries a sequence token that the server echoes back, and the client only renders the response matching its latest request. A slow earlier query can no longer overwrite newer results. A spinner shows while a request is in flight. Recent searches are kept in local storage and offered at the top of the filter popover when the box is empty. They save on Enter, so the list holds real searches rather than the partials typed on the way there. * Render search results as real messages and rate limit search Search results now render through the message formatter, so images, uploaded video and audio, spoilers, mentions and links look the same as they do in chat. Audio uses preload=none so nothing loads until play. Page links are not unfurled automatically. Each link gets a Load button that renders just that embed through the existing preview scheduler and cache, so a page of results never fires a burst of preview fetches. Right clicking a result opens a Copy link and Delete menu. Delete targets the result's own channel, and the row is removed only once the server confirms the delete. Results that head a thread show a reply count badge. The bottom pager gains a page number input so you can jump straight to a page instead of clicking through the arrows one fetch at a time. Search also gets its own per account rate limit of 10 requests per 10 seconds. When it trips the client keeps its current results and shows a toast.
49 lines
2.7 KiB
YAML
49 lines
2.7 KiB
YAML
# ── Haven Docker Compose ─────────────────────────────────
|
|
# Quick start: docker compose up -d
|
|
# Stop: docker compose down
|
|
# View logs: docker compose logs -f haven
|
|
# Update: docker compose pull && docker compose up -d --force-recreate
|
|
# Shell: docker compose exec haven sh
|
|
# ─────────────────────────────────────────────────────────
|
|
|
|
services:
|
|
haven:
|
|
image: ghcr.io/ancsemi/haven:latest
|
|
# build: . # Uncomment to build from source instead of using the pre-built image
|
|
container_name: haven
|
|
ports:
|
|
- "${PORT:-3000}:${PORT:-3000}" # Main HTTPS port
|
|
- "${REDIRECT_PORT:-3001}:${REDIRECT_PORT:-3001}" # HTTP → HTTPS redirect
|
|
volumes:
|
|
- haven_data:/data
|
|
# ── Or use a local folder instead (good for NAS / Synology): ──
|
|
# - ./haven-data:/data
|
|
environment:
|
|
- PORT=${PORT:-3000}
|
|
- HOST=0.0.0.0
|
|
# - SERVER_NAME=My Haven # Name shown in the UI
|
|
# - ADMIN_USERNAME=admin # First account to register becomes admin
|
|
# - GIPHY_API_KEY= # Optional: enable GIF search
|
|
# - VAPID_EMAIL=mailto:you@example # Optional: email for push notifications
|
|
# - TURN_URL=turn:your-server:3478 # Optional: TURN relay for voice over internet
|
|
# - TURN_SECRET=your-secret # Shared secret (coturn --use-auth-secret)
|
|
# - OIDC_CLIENT_SECRET=client-secret # The client secret as defined by your OIDC provider.
|
|
# Full text search tokenizer. Controls how message text is matched.
|
|
# Takes effect on restart; changing it triggers a one time reindex.
|
|
# trigram Matches text anywhere inside words, so apple finds apple,
|
|
# applesauce and pineapple. Most flexible for partial matches.
|
|
# Largest index (about 3 to 4x the message text) and needs
|
|
# queries of at least 3 characters.
|
|
# unicode61 Whole word and prefix matching, so apple finds apple and
|
|
# apple* but not applesauce. Smallest and fastest, best ranking.
|
|
# porter Like unicode61 plus English stemming, so run also finds
|
|
# running and ran. Small index, English focused, no substrings.
|
|
# Default is unicode61, the closest match to how Discord search behaves.
|
|
# - HAVEN_SEARCH_TOKENIZER=unicode61
|
|
# Uncomment to load settings from a .env file:
|
|
# env_file: .env
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
haven_data:
|