Productivity features, UI translations, local email translation
- Snooze (with a Snoozed folder), keyboard shortcuts with a Settings section, mail templates (Compose > More > Templates), a Subscriptions folder with bulk unsubscribe/delete, and tracker blocking with a Privacy toggle (on by default) - Own dialogs instead of browser popups; emoji picker in compose; compose windows survive a visit to Settings - Sentence completion learned from the user's sent mail (no AI) - Interface in English and Polish (one file per language, English as the fallback), picked from the browser on first run, then kept - Email translation on the server via LibreTranslate: Translate button and "Translate to...", messages in several languages translated part by part, names/addresses/emoji/file names/phone numbers kept, an animated line while translating - Antispam "Mark as spam" loads with the message, not when the menu opens Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+30
-1
@@ -71,6 +71,8 @@ x-backend-env: &backend-env
|
||||
RSPAMD_CONTROLLER_PASSWORD: ${RSPAMD_CONTROLLER_PASSWORD}
|
||||
# Spelling and grammar check in the compose window. Empty turns it off.
|
||||
LANGUAGETOOL_URL: ${LANGUAGETOOL_URL-http://languagetool:8010}
|
||||
# Email translation; empty turns it off.
|
||||
LIBRETRANSLATE_URL: ${LIBRETRANSLATE_URL-http://libretranslate:5000}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-INFO}
|
||||
UNDO_SECONDS: ${UNDO_SECONDS:-10}
|
||||
SESSION_TTL_DAYS: ${SESSION_TTL_DAYS:-30}
|
||||
@@ -109,12 +111,13 @@ services:
|
||||
- |
|
||||
set -e
|
||||
mkdir -p /mnt/postgres /mnt/blobs /mnt/backups /mnt/redis /mnt/meili /mnt/state \
|
||||
/mnt/languagetool-ngrams
|
||||
/mnt/languagetool-ngrams /mnt/libretranslate
|
||||
# Only recurse when ownership is actually wrong: `chown -R` over a large
|
||||
# blob store on every start would be minutes of pointless disk churn.
|
||||
[ "$$(stat -c %u /mnt/blobs)" = "10001" ] || chown -R 10001:10001 /mnt/blobs
|
||||
[ "$$(stat -c %u /mnt/backups)" = "999" ] || chown -R 999:999 /mnt/backups
|
||||
[ "$$(stat -c %u /mnt/redis)" = "999" ] || chown -R 999:999 /mnt/redis
|
||||
[ "$$(stat -c %u /mnt/libretranslate)" = "1032" ] || chown -R 1032:65534 /mnt/libretranslate
|
||||
chmod 700 /mnt/backups
|
||||
echo "[init] data directories ready"
|
||||
volumes:
|
||||
@@ -313,6 +316,32 @@ services:
|
||||
cpus: ${LANGUAGETOOL_CPUS:-1.0}
|
||||
logging: *logging
|
||||
|
||||
# Email translation (app/translation.py), all on this server. The first
|
||||
# start downloads every language model (a few GB) into DATA_ROOT; later
|
||||
# starts reuse them. A model is loaded into memory the first time its
|
||||
# language is used.
|
||||
libretranslate:
|
||||
image: libretranslate/libretranslate:v1.9.6
|
||||
environment:
|
||||
LT_DISABLE_WEB_UI: "true"
|
||||
LT_UPDATE_MODELS: "false"
|
||||
LT_THREADS: ${LIBRETRANSLATE_THREADS:-2}
|
||||
TZ: ${TZ:-UTC}
|
||||
volumes:
|
||||
- ${DATA_ROOT:-/NO-.env-FOUND-RUN-deploy_webmail.sh-init-FIRST}/libretranslate:/home/libretranslate/.local
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://127.0.0.1:5000/languages', timeout=4)\""]
|
||||
interval: 30s
|
||||
timeout: 6s
|
||||
retries: 5
|
||||
start_period: 30m # the first start downloads the models
|
||||
depends_on:
|
||||
init: { condition: service_completed_successfully }
|
||||
restart: unless-stopped
|
||||
mem_limit: ${LIBRETRANSLATE_MEM_LIMIT:-6g}
|
||||
cpus: ${LIBRETRANSLATE_CPUS:-2.0}
|
||||
logging: *logging
|
||||
|
||||
# Bayes tokens and fuzzy hashes. Separate from the app's redis on purpose
|
||||
# (§C.2): this data is derived and retrainable, so it trades durability for
|
||||
# room to grow — RDB snapshots every 5 min, and an eviction policy, where the
|
||||
|
||||
Reference in New Issue
Block a user