mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-31 01:52:30 +00:00
feat(imap): gap-fill missing-mail repair with live progress UI
This commit is contained in:
@@ -67,6 +67,35 @@ export interface AccountError {
|
||||
error: string;
|
||||
}
|
||||
|
||||
export interface GapFillFolderStats {
|
||||
downloaded: number;
|
||||
failed: number;
|
||||
candidate_count: number;
|
||||
message?: string | null;
|
||||
}
|
||||
|
||||
export enum GapFillStatus {
|
||||
Running = "Running",
|
||||
Success = "Success",
|
||||
Failed = "Failed",
|
||||
Cancelled = "Cancelled",
|
||||
}
|
||||
|
||||
export interface GapFillRun {
|
||||
started_at: number;
|
||||
finished_at: number | null;
|
||||
status: GapFillStatus;
|
||||
folders: Record<string, GapFillFolderStats>;
|
||||
downloaded: number;
|
||||
failed: number;
|
||||
}
|
||||
|
||||
export interface GapFillState {
|
||||
account_id: number;
|
||||
active: GapFillRun | null;
|
||||
history: GapFillRun[];
|
||||
}
|
||||
|
||||
export interface DownloadSession {
|
||||
start_time: number;
|
||||
end_time: number | null;
|
||||
@@ -168,6 +197,11 @@ export const download_state = async (account_id: number) => {
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const gap_fill_state = async (account_id: number) => {
|
||||
const response = await axiosInstance.get<GapFillState>(`api/v1/accounts/${account_id}/gap-fill-stats`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const create_account = async (data: Record<string, any>) => {
|
||||
const response = await axiosInstance.post("api/v1/account", data);
|
||||
return response.data;
|
||||
@@ -189,8 +223,8 @@ export const remove_account = async (account_id: number) => {
|
||||
};
|
||||
|
||||
|
||||
export const start_account_download = async (account_id: number) => {
|
||||
const response = await axiosInstance.post(`api/v1/accounts/${account_id}/start-download`);
|
||||
export const start_account_download = async (account_id: number, run_gap_fill = false) => {
|
||||
const response = await axiosInstance.post(`api/v1/accounts/${account_id}/start-download`, { run_gap_fill });
|
||||
return response.data;
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import { useState } from 'react'
|
||||
import { DotsHorizontalIcon } from '@radix-ui/react-icons'
|
||||
import { Row } from '@tanstack/react-table'
|
||||
import { IconEdit, IconPlayerPlay, IconPlayerStop, IconShieldLock, IconTrash } from '@tabler/icons-react'
|
||||
@@ -33,9 +34,10 @@ import { useAccountContext } from '../context'
|
||||
import { Mailbox, MessageSquareMore, Settings } from 'lucide-react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useCurrentUser } from '@/hooks/use-current-user'
|
||||
import { AccountModel, cancel_account_download, start_account_download } from '@/api/account/api'
|
||||
import { AccountModel, cancel_account_download } from '@/api/account/api'
|
||||
import { toast } from '@/hooks/use-toast'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import { StartDownloadDialog } from './start-download-dialog'
|
||||
|
||||
interface DataTableRowActionsProps {
|
||||
row: Row<AccountModel>
|
||||
@@ -45,6 +47,7 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) {
|
||||
const { t } = useTranslation()
|
||||
const { setOpen, setCurrentRow } = useAccountContext()
|
||||
const navigate = useNavigate()
|
||||
const [startDialogOpen, setStartDialogOpen] = useState(false)
|
||||
|
||||
const account_type = row.original.account_type;
|
||||
const { require_any_permission } = useCurrentUser()
|
||||
@@ -64,16 +67,7 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) {
|
||||
const showDownload = !isDeleting && account_type === 'IMAP' && hasPermission;
|
||||
|
||||
const handleStartDownload = async () => {
|
||||
try {
|
||||
await start_account_download(row.original.id);
|
||||
toast({ title: t('accounts.downloadStarted') });
|
||||
} catch (error: any) {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: t('accounts.downloadFailed'),
|
||||
description: error.response?.data?.message || error.message
|
||||
});
|
||||
}
|
||||
setStartDialogOpen(true)
|
||||
}
|
||||
|
||||
|
||||
@@ -198,6 +192,11 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) {
|
||||
</DropdownMenuItem>}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<StartDownloadDialog
|
||||
row={row.original}
|
||||
open={startDialogOpen}
|
||||
onOpenChange={setStartDialogOpen}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { download_state, DownloadStatus, AccountModel, FolderProgress } from '@/api/account/api'
|
||||
import { download_state, gap_fill_state, DownloadStatus, AccountModel, FolderProgress, GapFillRun, GapFillStatus } from '@/api/account/api'
|
||||
import { format } from 'date-fns'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
@@ -136,6 +136,62 @@ function FolderDetailItem({ f, t }: { f: FolderProgress, t: (key: string) => str
|
||||
)
|
||||
}
|
||||
|
||||
function GapFillRunDetail({ run, t }: { run: GapFillRun, t: (key: string) => string }) {
|
||||
const folderEntries = Object.entries(run.folders)
|
||||
if (folderEntries.length === 0) {
|
||||
return (
|
||||
<div className="text-center py-8 text-muted-foreground italic text-xs">
|
||||
{t('accounts.runningState.empty.no_gap_fill_folders')}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
const isActive = run.status === GapFillStatus.Running
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
{folderEntries.map(([name, stats]) => {
|
||||
const pct = stats.candidate_count > 0
|
||||
? Math.min(100, Math.round((stats.downloaded / stats.candidate_count) * 100))
|
||||
: 0
|
||||
return (
|
||||
<div key={name} className="py-1.5 border-b border-border/50 last:border-b-0">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span className="text-xs font-bold text-foreground truncate">{name}</span>
|
||||
<span className="text-[10px] font-bold text-muted-foreground whitespace-nowrap">
|
||||
{isActive && stats.candidate_count > 0 ? (
|
||||
<span className="text-blue-600">
|
||||
{stats.downloaded} <span className="opacity-50">/</span> {stats.candidate_count}
|
||||
</span>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-blue-600">{stats.downloaded} {t('accounts.runningState.gap_fill_downloaded_suffix')}</span>
|
||||
{stats.failed > 0 && (
|
||||
<>
|
||||
<span className="mx-1 opacity-30">·</span>
|
||||
<span className="text-destructive">{stats.failed} {t('accounts.runningState.gap_fill_failed_suffix')}</span>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
{isActive && stats.candidate_count > 0 && (
|
||||
<div className="mt-1.5 h-1.5 w-full rounded-full bg-muted overflow-hidden">
|
||||
<div className="h-full rounded-full bg-blue-500 transition-all duration-500" style={{ width: `${pct}%` }} />
|
||||
</div>
|
||||
)}
|
||||
{stats.message && (
|
||||
<div className="mt-1.5 flex items-start gap-1.5">
|
||||
<AlertTriangle className="w-3 h-3 text-amber-600 mt-0.5 shrink-0" />
|
||||
<p className="text-[10px] font-medium text-amber-700 leading-relaxed">{stats.message}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function RunningStateDialog({ currentRow, open, onOpenChange }: Props) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -149,6 +205,16 @@ export function RunningStateDialog({ currentRow, open, onOpenChange }: Props) {
|
||||
enabled: open && !!currentRow.id,
|
||||
})
|
||||
|
||||
const { data: gapFillData } = useQuery({
|
||||
queryKey: ['gap-fill-state', currentRow.id],
|
||||
queryFn: () => gap_fill_state(currentRow.id),
|
||||
refetchInterval: (query) => {
|
||||
const a = query.state.data?.active
|
||||
return a && a.status === GapFillStatus.Running ? 5000 : false
|
||||
},
|
||||
enabled: open && !!currentRow.id,
|
||||
})
|
||||
|
||||
const session = state?.active_session
|
||||
const history = state?.history || []
|
||||
const isRunning = !!session && session.status === DownloadStatus.Running
|
||||
@@ -199,6 +265,10 @@ export function RunningStateDialog({ currentRow, open, onOpenChange }: Props) {
|
||||
{t('accounts.runningState.tabs.history')}
|
||||
<Badge variant="secondary" className="ml-2 h-4 px-1 text-[10px] font-bold">{history.length}</Badge>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="gapfill" className="whitespace-nowrap data-[state=active]:border-b-2 data-[state=active]:border-primary rounded-none h-full bg-transparent shadow-none px-0 text-xs sm:text-sm font-bold">
|
||||
{t('accounts.runningState.tabs.gap_fill')}
|
||||
{gapFillData?.active && <Badge variant="secondary" className="ml-2 h-4 px-1 text-[10px] font-bold animate-pulse">{t('accounts.runningState.syncing')}</Badge>}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</div>
|
||||
|
||||
@@ -439,6 +509,55 @@ export function RunningStateDialog({ currentRow, open, onOpenChange }: Props) {
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</TabsContent>
|
||||
<TabsContent value="gapfill" className="h-full m-0 data-[state=active]:flex flex-col">
|
||||
<ScrollArea className="flex-1">
|
||||
<div className="p-4 sm:p-6 space-y-4">
|
||||
{gapFillData?.active && (
|
||||
<div className="rounded-xl border bg-card shadow-sm p-4">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<p className="text-[10px] font-bold text-muted-foreground uppercase">{t('accounts.runningState.gap_fill_active')}</p>
|
||||
<StatusBadge status={gapFillData.active.status} />
|
||||
</div>
|
||||
<GapFillRunDetail run={gapFillData.active} t={t} />
|
||||
</div>
|
||||
)}
|
||||
{(!gapFillData?.history || gapFillData.history.length === 0) ? (
|
||||
<div className="text-center py-20 text-muted-foreground italic text-sm">
|
||||
{t('accounts.runningState.empty.no_gap_fill_history')}
|
||||
</div>
|
||||
) : (
|
||||
<Accordion type="single" collapsible className="space-y-3">
|
||||
{[...gapFillData.history].reverse().map((run, i) => (
|
||||
<AccordionItem key={i} value={`gapfill-${i}`} className="border rounded-xl bg-card shadow-sm px-4 border-border overflow-hidden">
|
||||
<AccordionTrigger className="hover:no-underline py-4">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between w-full pr-4 gap-2">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="text-xs sm:text-xs font-bold font-mono text-foreground">
|
||||
{format(new Date(run.started_at), 'yyyy-MM-dd HH:mm:ss')}
|
||||
</div>
|
||||
<StatusBadge status={run.status} />
|
||||
</div>
|
||||
<span className="text-[10px] font-bold text-muted-foreground bg-muted px-2 py-0.5 rounded-full self-start sm:self-auto">
|
||||
<span className="text-blue-600">{run.downloaded} {t('accounts.runningState.gap_fill_downloaded_suffix')}</span>
|
||||
{run.failed > 0 && (
|
||||
<>
|
||||
<span className="mx-1 opacity-30">·</span>
|
||||
<span className="text-destructive">{run.failed} {t('accounts.runningState.gap_fill_failed_suffix')}</span>
|
||||
</>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent className="pb-4 border-t pt-4 mt-1 border-border">
|
||||
<GapFillRunDetail run={run} t={t} />
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
))}
|
||||
</Accordion>
|
||||
)}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</TabsContent>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// Copyright (c) 2025-2026 rustmailer.com (https://rustmailer.com)
|
||||
//
|
||||
// This file is part of the Bichon Email Archiving Project
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { toast } from '@/hooks/use-toast'
|
||||
import { start_account_download, AccountModel } from '@/api/account/api'
|
||||
|
||||
interface Props {
|
||||
row: AccountModel
|
||||
open: boolean
|
||||
onOpenChange: (open: boolean) => void
|
||||
}
|
||||
|
||||
export function StartDownloadDialog({ row, open, onOpenChange }: Props) {
|
||||
const { t } = useTranslation()
|
||||
const [runGapFill, setRunGapFill] = useState(false)
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
setRunGapFill(false)
|
||||
setSubmitting(false)
|
||||
}
|
||||
}, [open])
|
||||
|
||||
const handleConfirm = async () => {
|
||||
setSubmitting(true)
|
||||
try {
|
||||
await start_account_download(row.id, runGapFill)
|
||||
toast({ title: t('accounts.downloadStarted') })
|
||||
onOpenChange(false)
|
||||
} catch (error: any) {
|
||||
toast({
|
||||
variant: 'destructive',
|
||||
title: t('accounts.downloadFailed'),
|
||||
description: error.response?.data?.message || error.message,
|
||||
})
|
||||
} finally {
|
||||
setSubmitting(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('accounts.startDownload')}</DialogTitle>
|
||||
<DialogDescription>
|
||||
{t('accounts.startDownloadConfirmDesc')}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="flex items-center gap-2 py-2">
|
||||
<Checkbox id="run-gap-fill" checked={runGapFill} onCheckedChange={(v) => setRunGapFill(!!v)} />
|
||||
<Label htmlFor="run-gap-fill">{t('accounts.runGapFill')}</Label>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)} disabled={submitting}>
|
||||
{t('common.cancel')}
|
||||
</Button>
|
||||
<Button onClick={handleConfirm} disabled={submitting}>
|
||||
{t('accounts.startDownload')}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "مثال: 993",
|
||||
"imapProxy": "استخدم وكيل SOCKS5 لاتصالات IMAP.",
|
||||
"incDownload": "الفاصل",
|
||||
"incSync": "فترة التزامن",
|
||||
"lastSync": "آخر مزامنة",
|
||||
"leaveEmptyToKeepExisting": "اترك فارغًا للاحتفاظ بكلمة المرور الحالية، أو أدخل كلمة مرور جديدة لتحديثها.",
|
||||
"leaveEmptyToKeepPassword": "اترك فارغًا للاحتفاظ بكلمة المرور الحالية",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "رمز التحديث",
|
||||
"refreshTokenCopiedToClipboard": "تم نسخ رمز التحديث إلى الحافظة",
|
||||
"relative": "نسبي",
|
||||
"runGapFill": "فحص البريد الجديد وتنزيله، مع ملء الرسائل القديمة المفقودة محلياً تلقائياً",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "معرّف الحساب"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "لا يوجد تنزيل نشط",
|
||||
"no_errors_current": "لا توجد أخطاء في الجلسة الحالية",
|
||||
"no_errors_session": "لا توجد أخطاء في هذه الجلسة",
|
||||
"no_gap_fill_folders": "لا توجد مجلدات لمزامنة الرسائل المفقودة",
|
||||
"no_gap_fill_history": "لا يوجد سجل لاستكمال الرسائل",
|
||||
"no_global_errors": "لا توجد أخطاء عامة",
|
||||
"no_history": "لا يوجد سجل"
|
||||
},
|
||||
"folders": "صناديق البريد",
|
||||
"gap_fill_active": "عملية الاستكمال قيد التشغيل",
|
||||
"gap_fill_downloaded_suffix": "تم تنزيلها",
|
||||
"gap_fill_failed_suffix": "فشلت",
|
||||
"latest": "الأحدث",
|
||||
"loading": {
|
||||
"fetching_account_state": "جارٍ تحميل حالة الحساب..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "الجلسة النشطة",
|
||||
"errors": "أخطاء",
|
||||
"folders": "صناديق البريد",
|
||||
"gap_fill": "استكمال الرسائل الناقصة",
|
||||
"history": "السجل"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "تنزيل رسائل الفترة الأخيرة فقط (مثل آخر 3 أشهر). يتحرك تاريخ البدء تلقائياً مع مرور الوقت.",
|
||||
"sinceRelativeValue": "تنزيل رسائل البريد الإلكتروني من آخر",
|
||||
"startDownload": "بدء التنزيل",
|
||||
"startDownloadConfirmDesc": "بدء تنزيل بيانات الحسابات المحددة؟",
|
||||
"state": "الحالة",
|
||||
"status": "الحالة",
|
||||
"step": "الخطوة {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "f.eks. 993",
|
||||
"imapProxy": "Brug en SOCKS5-proxy til IMAP-forbindelser.",
|
||||
"incDownload": "Interval",
|
||||
"incSync": "Synk-interval",
|
||||
"lastSync": "Sidste synk.",
|
||||
"leaveEmptyToKeepExisting": "Lad stå tomt for at beholde den eksisterende adgangskode, eller indtast en ny for at opdatere den.",
|
||||
"leaveEmptyToKeepPassword": "Lad stå tomt for at beholde nuværende adgangskode",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "Opdateringstoken",
|
||||
"refreshTokenCopiedToClipboard": "Opdateringstoken kopieret til udklipsholderen",
|
||||
"relative": "Relativ",
|
||||
"runGapFill": "Tjek for nye e-mails og fyld automatisk op på ældre manglende e-mails",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "Konto-ID"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "Ingen aktiv download",
|
||||
"no_errors_current": "Ingen fejl i nuværende session",
|
||||
"no_errors_session": "Ingen fejl i denne session",
|
||||
"no_gap_fill_folders": "Ingen mapper med manglende e-mails",
|
||||
"no_gap_fill_history": "Ingen historik over backfill",
|
||||
"no_global_errors": "Ingen globale fejl",
|
||||
"no_history": "Ingen historik"
|
||||
},
|
||||
"folders": "postkasser",
|
||||
"gap_fill_active": "Kørende backfill-kørsel",
|
||||
"gap_fill_downloaded_suffix": "downloadet",
|
||||
"gap_fill_failed_suffix": "misllykkedes",
|
||||
"latest": "SENESTE",
|
||||
"loading": {
|
||||
"fetching_account_state": "Henter kontostatus..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "Aktiv session",
|
||||
"errors": "Fejl",
|
||||
"folders": "Postkasser",
|
||||
"gap_fill": "Udfyld manglende e-mails",
|
||||
"history": "Historik"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "Download kun e-mails fra den seneste periode (f.eks. de seneste 3 måneder). Startdatoen flyttes automatisk fremad.",
|
||||
"sinceRelativeValue": "Download e-mails fra de sidste",
|
||||
"startDownload": "Start download",
|
||||
"startDownloadConfirmDesc": "Start download for valgte konti?",
|
||||
"state": "Tilstand",
|
||||
"status": "Status",
|
||||
"step": "Trin {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "z.B. 993",
|
||||
"imapProxy": "SOCKS5-Proxy für IMAP-Verbindungen verwenden.",
|
||||
"incDownload": "Intervall",
|
||||
"incSync": "Synch.-Intervall",
|
||||
"lastSync": "Letzte Synchronisierung",
|
||||
"leaveEmptyToKeepExisting": "Leer lassen, um das bestehende Passwort beizubehalten, oder einen neuen Wert eingeben, um es zu aktualisieren.",
|
||||
"leaveEmptyToKeepPassword": "Leer lassen, um das aktuelle Passwort beizubehalten",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "Aktualisierungstoken",
|
||||
"refreshTokenCopiedToClipboard": "Aktualisierungstoken in die Zwischenablage kopiert",
|
||||
"relative": "Relativ",
|
||||
"runGapFill": "Neue Mails prüfen und ältere, lokal fehlende Mails automatisch nachladen",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "Konto-ID"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "Kein aktiver Download",
|
||||
"no_errors_current": "Keine Fehler in der aktuellen Sitzung",
|
||||
"no_errors_session": "Keine Fehler in dieser Sitzung",
|
||||
"no_gap_fill_folders": "Keine Ordner für den Abgleich fehlender Mails",
|
||||
"no_gap_fill_history": "Kein Backfill-Verlauf vorhanden",
|
||||
"no_global_errors": "Keine globalen Fehler",
|
||||
"no_history": "Kein Verlauf vorhanden"
|
||||
},
|
||||
"folders": "Postfächer",
|
||||
"gap_fill_active": "Laufender Backfill-Prozess",
|
||||
"gap_fill_downloaded_suffix": "heruntergeladen",
|
||||
"gap_fill_failed_suffix": "fehlgeschlagen",
|
||||
"latest": "NEU",
|
||||
"loading": {
|
||||
"fetching_account_state": "Kontostatus wird geladen..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "Aktive Sitzung",
|
||||
"errors": "Fehler",
|
||||
"folders": "Postfächer",
|
||||
"gap_fill": "Lückenfüllung",
|
||||
"history": "Verlauf"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "Nur E-Mails aus dem jüngsten Zeitraum herunterladen (z. B. letzte 3 Monate). Das Startdatum verschiebt sich automatisch.",
|
||||
"sinceRelativeValue": "E-Mails der letzten Zeit herunterladen",
|
||||
"startDownload": "Download starten",
|
||||
"startDownloadConfirmDesc": "E-Mail-Download für gewählte Konten starten?",
|
||||
"state": "Zustand",
|
||||
"status": "Status",
|
||||
"step": "Schritt {{index}}",
|
||||
|
||||
@@ -242,6 +242,7 @@
|
||||
"imapPortPlaceholder": "e.g 993",
|
||||
"imapProxy": "Use a proxy (http/socks5) for IMAP connections.",
|
||||
"incDownload": "Interval",
|
||||
"incSync": "Sync interval",
|
||||
"lastSync": "Last Sync",
|
||||
"leaveEmptyToKeepExisting": "Leave empty to keep the existing password, or enter a new password to update it.",
|
||||
"leaveEmptyToKeepPassword": "Leave empty to keep current password",
|
||||
@@ -273,6 +274,7 @@
|
||||
"refreshToken": "Refresh Token",
|
||||
"refreshTokenCopiedToClipboard": "Refresh token copied to clipboard",
|
||||
"relative": "Relative",
|
||||
"runGapFill": "Check new emails and automatically backfill older missing emails",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "Account ID"
|
||||
@@ -285,10 +287,15 @@
|
||||
"no_active_download": "No download in progress",
|
||||
"no_errors_current": "No errors in current session",
|
||||
"no_errors_session": "No errors in this session",
|
||||
"no_gap_fill_folders": "No folders syncing missing messages",
|
||||
"no_gap_fill_history": "No backfill history",
|
||||
"no_global_errors": "No global errors",
|
||||
"no_history": "No historical records found"
|
||||
},
|
||||
"folders": "mailboxes",
|
||||
"gap_fill_active": "Running backfill task",
|
||||
"gap_fill_downloaded_suffix": "downloaded",
|
||||
"gap_fill_failed_suffix": "failed",
|
||||
"latest": "LATEST",
|
||||
"loading": {
|
||||
"fetching_account_state": "Fetching account state..."
|
||||
@@ -307,6 +314,7 @@
|
||||
"active_session": "Active Session",
|
||||
"errors": "Errors",
|
||||
"folders": "Mailboxes",
|
||||
"gap_fill": "Backfill missing emails",
|
||||
"history": "History"
|
||||
}
|
||||
},
|
||||
@@ -355,6 +363,7 @@
|
||||
"sinceRelativeDesc": "Only download emails from the recent period (e.g. last 3 months). The start date automatically moves forward over time.",
|
||||
"sinceRelativeValue": "Download emails from the last",
|
||||
"startDownload": "Start download",
|
||||
"startDownloadConfirmDesc": "Start downloading mail data for selected accounts?",
|
||||
"state": "State",
|
||||
"status": "Status",
|
||||
"step": "Step {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "ej. 993",
|
||||
"imapProxy": "Usar proxy SOCKS5 para conexiones IMAP.",
|
||||
"incDownload": "Intervalo",
|
||||
"incSync": "Intervalo de sinc.",
|
||||
"lastSync": "Última sincronización",
|
||||
"leaveEmptyToKeepExisting": "Deja vacío para mantener la contraseña existente, o introduce un nuevo valor para actualizarla.",
|
||||
"leaveEmptyToKeepPassword": "Deja vacío para mantener la contraseña actual",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "Token de actualización",
|
||||
"refreshTokenCopiedToClipboard": "Token de actualización copiado al portapapeles",
|
||||
"relative": "Relativa",
|
||||
"runGapFill": "Verificar correos nuevos y rellenar automáticamente los faltantes antiguos",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "ID de cuenta"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "No hay descargas en curso",
|
||||
"no_errors_current": "Sin errores en la sesión actual",
|
||||
"no_errors_session": "Sin errores en esta sesión",
|
||||
"no_gap_fill_folders": "No hay carpetas sincronizando mensajes faltantes",
|
||||
"no_gap_fill_history": "Sin historial de backfill",
|
||||
"no_global_errors": "Sin errores globales",
|
||||
"no_history": "Sin historial"
|
||||
},
|
||||
"folders": "buzones",
|
||||
"gap_fill_active": "Tarea de backfill en ejecución",
|
||||
"gap_fill_downloaded_suffix": "descargados",
|
||||
"gap_fill_failed_suffix": "fallidos",
|
||||
"latest": "RECIENTE",
|
||||
"loading": {
|
||||
"fetching_account_state": "Obteniendo estado de la cuenta..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "Sesión activa",
|
||||
"errors": "Errores",
|
||||
"folders": "Buzones",
|
||||
"gap_fill": "Completar mensajes faltantes",
|
||||
"history": "Historial"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "Solo descargar correos del período reciente (ej. últimos 3 meses). La fecha de inicio avanza automáticamente.",
|
||||
"sinceRelativeValue": "Descargar correos de los últimos",
|
||||
"startDownload": "Iniciar descarga",
|
||||
"startDownloadConfirmDesc": "¿Iniciar descarga para las cuentas seleccionadas?",
|
||||
"state": "Estado",
|
||||
"status": "Estado",
|
||||
"step": "Paso {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "esim. 993",
|
||||
"imapProxy": "Käytä SOCKS5-välityspalvelinta IMAP-yhteyksiin.",
|
||||
"incDownload": "Väli",
|
||||
"incSync": "Synkronointiväli",
|
||||
"lastSync": "Viimeisin synkronointi",
|
||||
"leaveEmptyToKeepExisting": "Jätä tyhjäksi säilyttääksesi olemassa olevan salasanan, tai syötä uusi päivittääksesi sen.",
|
||||
"leaveEmptyToKeepPassword": "Jätä tyhjäksi säilyttääksesi nykyisen salasanan",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "Virheettömyystunnus",
|
||||
"refreshTokenCopiedToClipboard": "Virheettömyystunnus kopioitu leikepöydälle",
|
||||
"relative": "Suhteellinen",
|
||||
"runGapFill": "Tarkista uudet sähköpostit ja täydennä vanhat puuttuvat viestit automaattisesti",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "Tilin ID"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "Ei aktiivista latausta",
|
||||
"no_errors_current": "Ei virheitä nykyisessä istunnossa",
|
||||
"no_errors_session": "Ei virheitä tässä istunnossa",
|
||||
"no_gap_fill_folders": "Ei kansioita puuttuvien viestien täydennykseen",
|
||||
"no_gap_fill_history": "Ei täydennyshistoriaa",
|
||||
"no_global_errors": "Ei yleisiä virheitä",
|
||||
"no_history": "Ei historiaa"
|
||||
},
|
||||
"folders": "postilaatikot",
|
||||
"gap_fill_active": "Käynnissä oleva täydennys",
|
||||
"gap_fill_downloaded_suffix": "ladattu",
|
||||
"gap_fill_failed_suffix": "epäonnistui",
|
||||
"latest": "UUSIN",
|
||||
"loading": {
|
||||
"fetching_account_state": "Haetaan tilan tietoja..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "Aktiivinen istunto",
|
||||
"errors": "Virheet",
|
||||
"folders": "Postilaatikot",
|
||||
"gap_fill": "Puuttuvien täydennys",
|
||||
"history": "Historia"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "Lataa vain viimeaikaiset sähköpostit (esim. viimeiset 3 kuukautta). Aloituspäivämäärä siirtyy automaattisesti eteenpäin.",
|
||||
"sinceRelativeValue": "Lataa sähköpostit viimeisimmiltä",
|
||||
"startDownload": "Aloita lataus",
|
||||
"startDownloadConfirmDesc": "Aloitetaanko valittujen tilien lataus?",
|
||||
"state": "Tila",
|
||||
"status": "Tila",
|
||||
"step": "Vaihe {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "ex. 993",
|
||||
"imapProxy": "Utiliser un proxy SOCKS5 pour les connexions IMAP.",
|
||||
"incDownload": "Intervalle",
|
||||
"incSync": "Intervalle de synchro",
|
||||
"lastSync": "Dernière Synchronisation",
|
||||
"leaveEmptyToKeepExisting": "Laissez vide pour conserver le mot de passe existant, ou entrez-en un nouveau pour le mettre à jour.",
|
||||
"leaveEmptyToKeepPassword": "Laisser vide pour conserver le mot de passe actuel",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "Jeton de Rafraîchissement",
|
||||
"refreshTokenCopiedToClipboard": "Jeton de rafraîchissement copié dans le presse-papiers",
|
||||
"relative": "Relative",
|
||||
"runGapFill": "Vérifier les nouveaux e-mails et rattraper automatiquement les anciens messages manquants",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "ID du compte"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "Aucun téléchargement en cours",
|
||||
"no_errors_current": "Aucune erreur dans la session actuelle",
|
||||
"no_errors_session": "Aucune erreur dans cette session",
|
||||
"no_gap_fill_folders": "Aucun dossier en cours de synchronisation des messages manquants",
|
||||
"no_gap_fill_history": "Aucun historique de rattrapage",
|
||||
"no_global_errors": "Aucune erreur globale",
|
||||
"no_history": "Aucun historique disponible"
|
||||
},
|
||||
"folders": "boîtes mail",
|
||||
"gap_fill_active": "Tâche de rattrapage en cours",
|
||||
"gap_fill_downloaded_suffix": "téléchargés",
|
||||
"gap_fill_failed_suffix": "échec(s)",
|
||||
"latest": "RÉCENT",
|
||||
"loading": {
|
||||
"fetching_account_state": "Chargement de l'état du compte..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "Session active",
|
||||
"errors": "Erreurs",
|
||||
"folders": "Boîtes mail",
|
||||
"gap_fill": "Rattrapage des messages",
|
||||
"history": "Historique"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "Télécharger uniquement les e-mails récents (ex. 3 derniers mois). La date de début avance automatiquement.",
|
||||
"sinceRelativeValue": "Télécharger les e-mails des derniers",
|
||||
"startDownload": "Lancer le téléchargement",
|
||||
"startDownloadConfirmDesc": "Démarrer le téléchargement pour les comptes sélectionnés ?",
|
||||
"state": "État",
|
||||
"status": "Statut",
|
||||
"step": "Étape {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "es. 993",
|
||||
"imapProxy": "Usa un proxy SOCKS5 per le connessioni IMAP.",
|
||||
"incDownload": "Intervallo",
|
||||
"incSync": "Intervallo sinc.",
|
||||
"lastSync": "Ultima Sincronizzazione",
|
||||
"leaveEmptyToKeepExisting": "Lascia vuoto per mantenere la password esistente, o inseriscine una nuova per aggiornarla.",
|
||||
"leaveEmptyToKeepPassword": "Lascia vuoto per mantenere la password attuale",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "Token di Refresh",
|
||||
"refreshTokenCopiedToClipboard": "Token di refresh copiato negli appunti",
|
||||
"relative": "Relativa",
|
||||
"runGapFill": "Controlla le nuove email e recupera automaticamente i vecchi messaggi mancanti",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "ID account"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "Nessun download in corso",
|
||||
"no_errors_current": "Nessun errore nella sessione corrente",
|
||||
"no_errors_session": "Nessun errore in questa sessione",
|
||||
"no_gap_fill_folders": "Nessuna cartella con messaggi mancanti da scaricare",
|
||||
"no_gap_fill_history": "Nessuna cronologia di backfill",
|
||||
"no_global_errors": "Nessun errore globale",
|
||||
"no_history": "Nessuna cronologia disponibile"
|
||||
},
|
||||
"folders": "caselle di posta",
|
||||
"gap_fill_active": "Attività di backfill in esecuzione",
|
||||
"gap_fill_downloaded_suffix": "scaricati",
|
||||
"gap_fill_failed_suffix": "non riusciti",
|
||||
"latest": "RECENTE",
|
||||
"loading": {
|
||||
"fetching_account_state": "Caricamento stato account..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "Sessione attiva",
|
||||
"errors": "Errori",
|
||||
"folders": "Caselle di posta",
|
||||
"gap_fill": "Recupero messaggi mancanti",
|
||||
"history": "Cronologia"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "Scarica solo le email del periodo recente (es. ultimi 3 mesi). La data di inizio si aggiorna automaticamente.",
|
||||
"sinceRelativeValue": "Scarica email degli ultimi",
|
||||
"startDownload": "Avvia download",
|
||||
"startDownloadConfirmDesc": "Avviare il download per gli account selezionati?",
|
||||
"state": "Stato",
|
||||
"status": "Stato",
|
||||
"step": "Passo {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "例: 993",
|
||||
"imapProxy": "IMAP接続にSOCKS5プロキシを使用します。",
|
||||
"incDownload": "間隔",
|
||||
"incSync": "同期間隔",
|
||||
"lastSync": "最終同期",
|
||||
"leaveEmptyToKeepExisting": "既存のパスワードを保持する場合は空欄にしてください。更新する場合は新しいパスワードを入力してください。",
|
||||
"leaveEmptyToKeepPassword": "現在のパスワードを保持する場合は空欄にしてください",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "リフレッシュトークン",
|
||||
"refreshTokenCopiedToClipboard": "リフレッシュトークンをクリップボードにコピーしました",
|
||||
"relative": "相対",
|
||||
"runGapFill": "新着メールを確認してダウンロードし、過去の未取得メールも自動的に差分補填します",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "アカウントID"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "現在ダウンロード中のタスクはありません",
|
||||
"no_errors_current": "現在のタスクにエラーはありません",
|
||||
"no_errors_session": "このタスクにエラーはありません",
|
||||
"no_gap_fill_folders": "未取得メールを同期中のフォルダーはありません",
|
||||
"no_gap_fill_history": "差分補填の履歴はありません",
|
||||
"no_global_errors": "全体エラーはありません",
|
||||
"no_history": "履歴がありません"
|
||||
},
|
||||
"folders": "メールボックス",
|
||||
"gap_fill_active": "実行中の差分補填タスク",
|
||||
"gap_fill_downloaded_suffix": "件ダウンロード済み",
|
||||
"gap_fill_failed_suffix": "件失敗",
|
||||
"latest": "最新",
|
||||
"loading": {
|
||||
"fetching_account_state": "アカウント状態を取得中..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "実行中タスク",
|
||||
"errors": "エラー",
|
||||
"folders": "メールボックス",
|
||||
"gap_fill": "差分メール補填",
|
||||
"history": "履歴"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "直近の期間(例:過去3ヶ月)のメールのみをダウンロードします。開始日は時間経過に伴い自動的に更新されます。",
|
||||
"sinceRelativeValue": "直近の期間のメールをダウンロード",
|
||||
"startDownload": "ダウンロードを開始",
|
||||
"startDownloadConfirmDesc": "選択したアカウントのメールデータをダウンロードしますか?",
|
||||
"state": "状態",
|
||||
"status": "ステータス",
|
||||
"step": "ステップ {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "예: 993",
|
||||
"imapProxy": "IMAP 연결에 SOCKS5 프록시를 사용합니다.",
|
||||
"incDownload": "간격",
|
||||
"incSync": "동기화 간격",
|
||||
"lastSync": "최종 동기화",
|
||||
"leaveEmptyToKeepExisting": "기존 비밀번호를 유지하려면 비워 두십시오. 업데이트할 경우에만 새 비밀번호를 입력하십시오.",
|
||||
"leaveEmptyToKeepPassword": "현재 비밀번호를 유지하려면 비워 두십시오",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "새로 고침 토큰",
|
||||
"refreshTokenCopiedToClipboard": "새로 고침 토큰이 클립보드에 복사되었습니다",
|
||||
"relative": "상대적",
|
||||
"runGapFill": "새 메일을 확인하여 다운로드하고, 누락된 과거 메일도 자동으로 백필합니다",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "계정 ID"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "진행 중인 다운로드가 없습니다",
|
||||
"no_errors_current": "현재 작업에 오류가 없습니다",
|
||||
"no_errors_session": "이 작업에 오류가 없습니다",
|
||||
"no_gap_fill_folders": "누락된 메일을 동기화 중인 메일함이 없습니다",
|
||||
"no_gap_fill_history": "백필 기록 없음",
|
||||
"no_global_errors": "전체 오류가 없습니다",
|
||||
"no_history": "기록이 없습니다"
|
||||
},
|
||||
"folders": "메일함",
|
||||
"gap_fill_active": "실행 중인 백필 작업",
|
||||
"gap_fill_downloaded_suffix": "개 다운로드됨",
|
||||
"gap_fill_failed_suffix": "개 실패",
|
||||
"latest": "최신",
|
||||
"loading": {
|
||||
"fetching_account_state": "계정 상태를 불러오는 중..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "현재 작업",
|
||||
"errors": "오류",
|
||||
"folders": "메일함",
|
||||
"gap_fill": "누락 메일 백필",
|
||||
"history": "기록"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "최근 기간(예: 지난 3개월)의 이메일만 다운로드합니다. 시작 날짜는 시간이 지남에 따라 자동으로 이동합니다.",
|
||||
"sinceRelativeValue": "최근 기간의 이메일 다운로드",
|
||||
"startDownload": "다운로드 시작",
|
||||
"startDownloadConfirmDesc": "선택한 계정의 메일 데이터를 다운로드할까요?",
|
||||
"state": "상태",
|
||||
"status": "상태",
|
||||
"step": "단계 {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "bv. 993",
|
||||
"imapProxy": "Gebruik een SOCKS5-proxy voor IMAP-verbindingen.",
|
||||
"incDownload": "Interval",
|
||||
"incSync": "Synch.-interval",
|
||||
"lastSync": "Laatste Sync",
|
||||
"leaveEmptyToKeepExisting": "Laat leeg om het bestaande wachtwoord te behouden, of voer een nieuw wachtwoord in om het bij te werken.",
|
||||
"leaveEmptyToKeepPassword": "Laat leeg om huidig wachtwoord te behouden",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "Vernieuwingstoken (Refresh Token)",
|
||||
"refreshTokenCopiedToClipboard": "Vernieuwingstoken naar klembord gekopieerd",
|
||||
"relative": "Relatief",
|
||||
"runGapFill": "Controleer op nieuwe e-mails en vul oudere ontbrekende e-mails automatisch aan",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "Account-ID"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "Geen actieve download",
|
||||
"no_errors_current": "Geen fouten in huidige sessie",
|
||||
"no_errors_session": "Geen fouten in deze sessie",
|
||||
"no_gap_fill_folders": "Geen mappen die ontbrekende berichten synchroniseren",
|
||||
"no_gap_fill_history": "Geen backfill-geschiedenis",
|
||||
"no_global_errors": "Geen globale fouten",
|
||||
"no_history": "Geen geschiedenis beschikbaar"
|
||||
},
|
||||
"folders": "mailboxen",
|
||||
"gap_fill_active": "Lopende backfill-taak",
|
||||
"gap_fill_downloaded_suffix": "Gedownload",
|
||||
"gap_fill_failed_suffix": "mislukt",
|
||||
"latest": "RECENT",
|
||||
"loading": {
|
||||
"fetching_account_state": "Accountstatus ophalen..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "Actieve sessie",
|
||||
"errors": "Fouten",
|
||||
"folders": "Mailboxen",
|
||||
"gap_fill": "Ontbrekende berichten aanvullen",
|
||||
"history": "Geschiedenis"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "Download alleen e-mails uit de afgelopen periode (bijv. laatste 3 maanden). De startdatum verschuift automatisch mee.",
|
||||
"sinceRelativeValue": "Download e-mails van de laatste",
|
||||
"startDownload": "Download starten",
|
||||
"startDownloadConfirmDesc": "Download starten voor geselecteerde accounts?",
|
||||
"state": "Status",
|
||||
"status": "Status",
|
||||
"step": "Stap {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "f.eks. 993",
|
||||
"imapProxy": "Bruk en SOCKS5-proxy for IMAP-tilkoblinger.",
|
||||
"incDownload": "Intervall",
|
||||
"incSync": "Synk-intervall",
|
||||
"lastSync": "Siste synkronisering",
|
||||
"leaveEmptyToKeepExisting": "La stå tomt for å beholde det eksisterende passordet, eller skriv inn et nytt passord for å oppdatere det.",
|
||||
"leaveEmptyToKeepPassword": "La stå tomt for å beholde nåværende passord",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "Oppfriskningstoken",
|
||||
"refreshTokenCopiedToClipboard": "Oppfriskningstoken kopiert til utklippstavlen",
|
||||
"relative": "Relativ",
|
||||
"runGapFill": "Sjekk etter nye e-poster og fyll automatisk inn eldre manglende e-poster",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "Konto-ID"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "Ingen aktiv nedlasting",
|
||||
"no_errors_current": "Ingen feil i gjeldende økt",
|
||||
"no_errors_session": "Ingen feil i denne økten",
|
||||
"no_gap_fill_folders": "Ingen mapper med manglende e-poster",
|
||||
"no_gap_fill_history": "Ingen backfill-historikk",
|
||||
"no_global_errors": "Ingen globale feil",
|
||||
"no_history": "Ingen historikk"
|
||||
},
|
||||
"folders": "postbokser",
|
||||
"gap_fill_active": "Kjørende backfill-oppgave",
|
||||
"gap_fill_downloaded_suffix": "lastet ned",
|
||||
"gap_fill_failed_suffix": "mislyktes",
|
||||
"latest": "NYEST",
|
||||
"loading": {
|
||||
"fetching_account_state": "Henter kontostatus..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "Aktiv økt",
|
||||
"errors": "Feil",
|
||||
"folders": "Postbokser",
|
||||
"gap_fill": "Fyll inn manglende e-poster",
|
||||
"history": "Historikk"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "Last bare ned e-poster fra den siste perioden (f.eks. siste 3 måneder). Startdatoen flyttes automatisk fremover.",
|
||||
"sinceRelativeValue": "Last ned e-poster fra de siste",
|
||||
"startDownload": "Start nedlasting",
|
||||
"startDownloadConfirmDesc": "Start nedlasting for valgte kontoer?",
|
||||
"state": "Tilstand",
|
||||
"status": "Status",
|
||||
"step": "Trinn {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "np. 993 (szyfrowany TLS/SSL) lub 143 (bez szyfrowania)",
|
||||
"imapProxy": "Użyj proxy gniazda SOCKS5 dla połączeń IMAP.",
|
||||
"incDownload": "Interwał",
|
||||
"incSync": "Interwał synch.",
|
||||
"lastSync": "OStatnia synchronizacja",
|
||||
"leaveEmptyToKeepExisting": "Pozostaw to pole puste, jeśli chcesz zachować dotychczasowe hasło lub wpisz nowe, aby zaktualizować.",
|
||||
"leaveEmptyToKeepPassword": "Pozostaw to pole puste, jeśli chcesz zachować dotychczasowe hasło",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "Odśwież token",
|
||||
"refreshTokenCopiedToClipboard": "Token odśwież skopiowany do schowka",
|
||||
"relative": "Wzglednie",
|
||||
"runGapFill": "Sprawdzaj nowe e-maile i automatycznie uzupełniaj starsze, brakujące wiadomości",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "ID konta"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "Brak aktywnego pobierania",
|
||||
"no_errors_current": "Brak błędów w bieżącej sesji",
|
||||
"no_errors_session": "Brak błędów w tej sesji",
|
||||
"no_gap_fill_folders": "Brak folderów z brakującymi wiadomościami do pobrania",
|
||||
"no_gap_fill_history": "Brak historii uzupełniania",
|
||||
"no_global_errors": "Brak błędów globalnych",
|
||||
"no_history": "Brak historii"
|
||||
},
|
||||
"folders": "skrzynki",
|
||||
"gap_fill_active": "Trwające uzupełnianie",
|
||||
"gap_fill_downloaded_suffix": "pobrano",
|
||||
"gap_fill_failed_suffix": "niepowodzenie",
|
||||
"latest": "NAJNOWSZE",
|
||||
"loading": {
|
||||
"fetching_account_state": "Pobieranie stanu konta..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "Aktywna sesja",
|
||||
"errors": "Błędy",
|
||||
"folders": "Skrzynki",
|
||||
"gap_fill": "Uzupełnianie braków",
|
||||
"history": "Historia"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "Pobieraj tylko wiadomości z ostatniego okresu (np. ostatnie 3 miesiące). Data początkowa automatycznie przesuwa się w czasie.",
|
||||
"sinceRelativeValue": "Pobierz e-maile z ostatnich",
|
||||
"startDownload": "Uruchom pobieranie",
|
||||
"startDownloadConfirmDesc": "Rozpocząć pobieranie dla wybranych kont?",
|
||||
"state": "Status",
|
||||
"status": "Status",
|
||||
"step": "Krok {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "Ex: 993",
|
||||
"imapProxy": "Usar proxy SOCKS5 para conexão IMAP.",
|
||||
"incDownload": "Intervalo",
|
||||
"incSync": "Intervalo de sinc.",
|
||||
"lastSync": "Última Sincronização",
|
||||
"leaveEmptyToKeepExisting": "Deixe vazio para manter a senha existente. Insira a nova senha apenas se estiver atualizando.",
|
||||
"leaveEmptyToKeepPassword": "Deixe vazio para manter a senha atual",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "Token de Atualização",
|
||||
"refreshTokenCopiedToClipboard": "Token de atualização copiado para a área de transferência",
|
||||
"relative": "Relativo",
|
||||
"runGapFill": "Verifique novos e-mails e preencha automaticamente e-mails antigos ausentes",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "ID da conta"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "Nenhum download em andamento",
|
||||
"no_errors_current": "Sem erros na sessão atual",
|
||||
"no_errors_session": "Sem erros nesta sessão",
|
||||
"no_gap_fill_folders": "Nenhuma pasta sincronizando mensagens ausentes",
|
||||
"no_gap_fill_history": "Nenhum histórico de backfill",
|
||||
"no_global_errors": "Sem erros globais",
|
||||
"no_history": "Sem histórico"
|
||||
},
|
||||
"folders": "caixas de correio",
|
||||
"gap_fill_active": "Tarefa de backfill em execução",
|
||||
"gap_fill_downloaded_suffix": "baixados",
|
||||
"gap_fill_failed_suffix": "falharam",
|
||||
"latest": "RECENTE",
|
||||
"loading": {
|
||||
"fetching_account_state": "Obtendo estado da conta..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "Sessão ativa",
|
||||
"errors": "Erros",
|
||||
"folders": "Caixas de correio",
|
||||
"gap_fill": "Preenchimento de lacunas",
|
||||
"history": "Histórico"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "Baixar apenas e-mails do período recente (ex: últimos 3 meses). A data de início avança automaticamente com o tempo.",
|
||||
"sinceRelativeValue": "Baixar e-mails dos últimos",
|
||||
"startDownload": "Iniciar download",
|
||||
"startDownloadConfirmDesc": "Iniciar download para as contas selecionadas?",
|
||||
"state": "Estado",
|
||||
"status": "Status",
|
||||
"step": "Passo {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "например, 993",
|
||||
"imapProxy": "Использовать SOCKS5 прокси для соединений IMAP.",
|
||||
"incDownload": "Интервал",
|
||||
"incSync": "Интервал синхр.",
|
||||
"lastSync": "Посл. синхр.",
|
||||
"leaveEmptyToKeepExisting": "Оставьте пустым, чтобы сохранить существующий пароль, или введите новый для обновления.",
|
||||
"leaveEmptyToKeepPassword": "Оставьте пустым, чтобы сохранить текущий пароль",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "Refresh Token",
|
||||
"refreshTokenCopiedToClipboard": "Refresh token скопирован в буфер обмена",
|
||||
"relative": "Относительная",
|
||||
"runGapFill": "Проверять новые письма и автоматически восполнять старые недостающие сообщения",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "ID аккаунта"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "Нет активных загрузок",
|
||||
"no_errors_current": "Нет ошибок в текущей сессии",
|
||||
"no_errors_session": "Нет ошибок в этой сессии",
|
||||
"no_gap_fill_folders": "Нет папок для загрузки недостающих писем",
|
||||
"no_gap_fill_history": "История восполнения отсутствует",
|
||||
"no_global_errors": "Нет глобальных ошибок",
|
||||
"no_history": "Нет истории"
|
||||
},
|
||||
"folders": "почтовые ящики",
|
||||
"gap_fill_active": "Выполняемый запуск восполнения",
|
||||
"gap_fill_downloaded_suffix": "скачано",
|
||||
"gap_fill_failed_suffix": "ошибок",
|
||||
"latest": "ПОСЛЕДНЕЕ",
|
||||
"loading": {
|
||||
"fetching_account_state": "Загрузка состояния аккаунта..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "Активная сессия",
|
||||
"errors": "Ошибки",
|
||||
"folders": "Почтовые ящики",
|
||||
"gap_fill": "Восполнение пропусков",
|
||||
"history": "История"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "Скачивать письма только за последний период (напр., за 3 месяца). Дата начала автоматически сдвигается со временем.",
|
||||
"sinceRelativeValue": "Скачать письма за последние",
|
||||
"startDownload": "Запустить загрузку",
|
||||
"startDownloadConfirmDesc": "Начать загрузку почты для выбранных аккаунтов?",
|
||||
"state": "Состояние",
|
||||
"status": "Статус",
|
||||
"step": "Шаг {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "t.ex. 993",
|
||||
"imapProxy": "Använd en SOCKS5-proxy för IMAP-anslutningar.",
|
||||
"incDownload": "Intervall",
|
||||
"incSync": "Synkintervall",
|
||||
"lastSync": "Senaste synk",
|
||||
"leaveEmptyToKeepExisting": "Lämna tomt för att behålla det befintliga lösenordet, eller ange ett nytt för att uppdatera det.",
|
||||
"leaveEmptyToKeepPassword": "Lämna tomt för att behålla nuvarande lösenord",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "Uppdateringstoken",
|
||||
"refreshTokenCopiedToClipboard": "Uppdateringstoken kopierad till urklipp",
|
||||
"relative": "Relativ",
|
||||
"runGapFill": "Kontrollera nya e-postmeddelanden och komplettera automatiskt äldre saknade meddelanden",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "Kontots ID"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "Ingen aktiv nedladdning",
|
||||
"no_errors_current": "Inga fel i aktuell session",
|
||||
"no_errors_session": "Inga fel i denna session",
|
||||
"no_gap_fill_folders": "Inga mappar för synkning av saknade meddelanden",
|
||||
"no_gap_fill_history": "Ingen kompletteringshistorik",
|
||||
"no_global_errors": "Inga globala fel",
|
||||
"no_history": "Ingen historik"
|
||||
},
|
||||
"folders": "postlådor",
|
||||
"gap_fill_active": "Pågående kompletteringskörning",
|
||||
"gap_fill_downloaded_suffix": "nedladdade",
|
||||
"gap_fill_failed_suffix": "misslyckades",
|
||||
"latest": "SENASTE",
|
||||
"loading": {
|
||||
"fetching_account_state": "Hämtar kontostatus..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "Aktiv session",
|
||||
"errors": "Fel",
|
||||
"folders": "Postlådor",
|
||||
"gap_fill": "Komplettera saknade meddelanden",
|
||||
"history": "Historik"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "Ladda endast ner e-postmeddelanden från den senaste perioden (t.ex. senaste 3 månaderna). Startdatumet flyttas automatiskt framåt.",
|
||||
"sinceRelativeValue": "Ladda ner e-post från de senaste",
|
||||
"startDownload": "Starta hämtning",
|
||||
"startDownloadConfirmDesc": "Starta nedladdning för valda konton?",
|
||||
"state": "Tillstånd",
|
||||
"status": "Status",
|
||||
"step": "Steg {{index}}",
|
||||
|
||||
@@ -240,6 +240,7 @@
|
||||
"imapPortPlaceholder": "例如:993",
|
||||
"imapProxy": "使用 SOCKS5 代理進行 IMAP 連線。",
|
||||
"incDownload": "間隔",
|
||||
"incSync": "同步間隔",
|
||||
"lastSync": "上次同步",
|
||||
"leaveEmptyToKeepExisting": "保留現有密碼請留空。若要更新,請輸入新密碼。",
|
||||
"leaveEmptyToKeepPassword": "保留現有密碼請留空",
|
||||
@@ -271,6 +272,7 @@
|
||||
"refreshToken": "更新權杖 (Refresh Token)",
|
||||
"refreshTokenCopiedToClipboard": "更新權杖已複製到剪貼簿",
|
||||
"relative": "相對",
|
||||
"runGapFill": "檢查並下載新郵件,同時自動補全本地缺失的歷史舊郵件",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "帳戶 ID"
|
||||
@@ -283,10 +285,15 @@
|
||||
"no_active_download": "目前沒有下載任務",
|
||||
"no_errors_current": "目前任務沒有錯誤",
|
||||
"no_errors_session": "此任務沒有錯誤",
|
||||
"no_gap_fill_folders": "暫無需要補充缺失郵件的郵件資料夾",
|
||||
"no_gap_fill_history": "暫無查漏補缺歷史記錄",
|
||||
"no_global_errors": "沒有全域錯誤",
|
||||
"no_history": "沒有歷史記錄"
|
||||
},
|
||||
"folders": "個郵件夾",
|
||||
"gap_fill_active": "執行中的查漏補缺任務",
|
||||
"gap_fill_downloaded_suffix": "已下載",
|
||||
"gap_fill_failed_suffix": "失敗",
|
||||
"latest": "最新",
|
||||
"loading": {
|
||||
"fetching_account_state": "正在取得帳戶狀態..."
|
||||
@@ -305,6 +312,7 @@
|
||||
"active_session": "目前任務",
|
||||
"errors": "錯誤",
|
||||
"folders": "郵件夾",
|
||||
"gap_fill": "缺失郵件查漏補缺",
|
||||
"history": "歷史記錄"
|
||||
}
|
||||
},
|
||||
@@ -345,6 +353,7 @@
|
||||
"sinceRelativeDesc": "僅下載最近一段時間(如過去 3 個月)的郵件。開始日期會隨時間推移自動向前滾動。",
|
||||
"sinceRelativeValue": "下載最近一段時期的郵件",
|
||||
"startDownload": "啟動下載",
|
||||
"startDownloadConfirmDesc": "確定開始下載所選帳號的郵件資料?",
|
||||
"state": "狀態",
|
||||
"status": "狀態",
|
||||
"step": "步驟 {{index}}",
|
||||
|
||||
@@ -242,6 +242,7 @@
|
||||
"imapPortPlaceholder": "例如:993",
|
||||
"imapProxy": "为 IMAP 连接使用 SOCKS5 代理。",
|
||||
"incDownload": "间隔",
|
||||
"incSync": "同步间隔",
|
||||
"lastSync": "最后同步",
|
||||
"leaveEmptyToKeepExisting": "留空以保持现有密码,或输入新密码进行更新。",
|
||||
"leaveEmptyToKeepPassword": "留空以保持当前密码",
|
||||
@@ -273,6 +274,7 @@
|
||||
"refreshToken": "刷新令牌",
|
||||
"refreshTokenCopiedToClipboard": "刷新令牌已复制到剪贴板",
|
||||
"relative": "相对",
|
||||
"runGapFill": "检查并下载新邮件,同时自动补全本地缺失的历史老邮件",
|
||||
"runningState": {
|
||||
"account": {
|
||||
"id": "账户 ID"
|
||||
@@ -285,10 +287,15 @@
|
||||
"no_active_download": "当前没有下载任务",
|
||||
"no_errors_current": "当前任务无错误",
|
||||
"no_errors_session": "该任务无错误",
|
||||
"no_gap_fill_folders": "暂无需要补充缺失邮件的邮件夹",
|
||||
"no_gap_fill_history": "暂无查漏补缺历史记录",
|
||||
"no_global_errors": "暂无全局错误",
|
||||
"no_history": "暂无历史记录"
|
||||
},
|
||||
"folders": "个文件夹",
|
||||
"gap_fill_active": "运行中的查漏补缺任务",
|
||||
"gap_fill_downloaded_suffix": "已下载",
|
||||
"gap_fill_failed_suffix": "失败",
|
||||
"latest": "最新",
|
||||
"loading": {
|
||||
"fetching_account_state": "正在获取账户状态..."
|
||||
@@ -307,6 +314,7 @@
|
||||
"active_session": "当前任务",
|
||||
"errors": "错误",
|
||||
"folders": "邮件夹",
|
||||
"gap_fill": "缺失邮件查漏补缺",
|
||||
"history": "历史记录"
|
||||
}
|
||||
},
|
||||
@@ -355,6 +363,7 @@
|
||||
"sinceRelativeDesc": "仅下载最近一段时间(如过去 3 个月)的邮件。开始日期会随时间推移自动向后滚动。",
|
||||
"sinceRelativeValue": "下载最近一段时期的邮件",
|
||||
"startDownload": "启动下载",
|
||||
"startDownloadConfirmDesc": "确定开始下载所选账号的邮件数据?",
|
||||
"state": "状态",
|
||||
"status": "状态",
|
||||
"step": "步骤 {{index}}",
|
||||
|
||||
Reference in New Issue
Block a user