- 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>
31 lines
780 B
Python
31 lines
780 B
Python
"""What email translation offers (app/translation.py), for the reading pane."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter
|
|
from pydantic import BaseModel
|
|
|
|
from app import translation
|
|
from app.identity.deps import CurrentUser
|
|
|
|
router = APIRouter(prefix="/translation", tags=["mail"])
|
|
|
|
|
|
class LanguageOut(BaseModel):
|
|
code: str
|
|
name: str
|
|
|
|
|
|
class TranslationInfoOut(BaseModel):
|
|
available: bool
|
|
languages: list[LanguageOut]
|
|
|
|
|
|
@router.get("/languages", response_model=TranslationInfoOut)
|
|
async def translation_languages(user: CurrentUser) -> TranslationInfoOut:
|
|
found = await translation.languages()
|
|
return TranslationInfoOut(
|
|
available=bool(found),
|
|
languages=[LanguageOut(code=x.code, name=x.name) for x in found],
|
|
)
|