mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat: add full-width dropzone state and tool branding to tool page
This commit is contained in:
@@ -0,0 +1,85 @@
|
|||||||
|
import type { Tool } from "@snapotter/shared";
|
||||||
|
import { FileImage, Lock } from "lucide-react";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
import { useTranslation } from "@/contexts/i18n-context";
|
||||||
|
import { format } from "@/lib/format";
|
||||||
|
import { ICON_MAP } from "@/lib/icon-map";
|
||||||
|
import { MULTI_FILE_TOOLS } from "@/lib/tool-display-modes";
|
||||||
|
import { getToolDescription, getToolName } from "@/lib/tool-i18n";
|
||||||
|
import { Dropzone } from "./dropzone";
|
||||||
|
|
||||||
|
interface ToolDropzoneProps {
|
||||||
|
tool: Tool;
|
||||||
|
accept?: string;
|
||||||
|
fileFilter?: (file: File) => boolean;
|
||||||
|
multiple?: boolean;
|
||||||
|
onFiles: (files: File[]) => void;
|
||||||
|
onUrlImport?: (file: File) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FORMATS_LIMIT = 8;
|
||||||
|
|
||||||
|
export function ToolDropzone({
|
||||||
|
tool,
|
||||||
|
accept,
|
||||||
|
fileFilter,
|
||||||
|
multiple,
|
||||||
|
onFiles,
|
||||||
|
onUrlImport,
|
||||||
|
}: ToolDropzoneProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const IconComponent =
|
||||||
|
(ICON_MAP[tool.icon] as React.ComponentType<{ className?: string }>) ?? FileImage;
|
||||||
|
|
||||||
|
const isMultiFile = MULTI_FILE_TOOLS.has(tool.id);
|
||||||
|
const resolvedMultiple = multiple ?? isMultiFile;
|
||||||
|
|
||||||
|
const formatsDisplay = useMemo(() => {
|
||||||
|
const inputs = tool.acceptedInputs;
|
||||||
|
if (!inputs || inputs.length === 0) return null;
|
||||||
|
const formatted = inputs.map((ext) => ext.replace(/^\./, "").toUpperCase());
|
||||||
|
if (formatted.length <= FORMATS_LIMIT) {
|
||||||
|
return formatted.join(", ");
|
||||||
|
}
|
||||||
|
const visible = formatted.slice(0, FORMATS_LIMIT).join(", ");
|
||||||
|
return `${visible} ${format(t.toolPage.andMore, { count: formatted.length - FORMATS_LIMIT })}`;
|
||||||
|
}, [tool.acceptedInputs, t.toolPage.andMore]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center gap-6 w-full max-w-lg px-4 py-8">
|
||||||
|
{/* Tool branding */}
|
||||||
|
<div className="flex flex-col items-center gap-3 text-center">
|
||||||
|
<div className="p-3 rounded-xl bg-primary/10">
|
||||||
|
<IconComponent className="h-8 w-8 text-primary" />
|
||||||
|
</div>
|
||||||
|
<h1 className="text-xl font-semibold text-foreground">
|
||||||
|
{getToolName(t, tool.id, tool.name)}
|
||||||
|
</h1>
|
||||||
|
<p className="text-sm text-muted-foreground max-w-sm">
|
||||||
|
{getToolDescription(t, tool.id, tool.description)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Dropzone */}
|
||||||
|
<Dropzone
|
||||||
|
onFiles={onFiles}
|
||||||
|
onUrlImport={onUrlImport}
|
||||||
|
accept={accept}
|
||||||
|
multiple={resolvedMultiple}
|
||||||
|
fileFilter={fileFilter}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Accepted formats */}
|
||||||
|
{formatsDisplay && (
|
||||||
|
<p className="text-xs text-muted-foreground text-center">{formatsDisplay}</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Privacy note */}
|
||||||
|
<p className="flex items-center gap-1.5 text-xs text-muted-foreground">
|
||||||
|
<Lock className="h-3 w-3 shrink-0" />
|
||||||
|
{t.toolPage.privacyNote}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ import { type BgPreviewState, ImageViewer } from "@/components/common/image-view
|
|||||||
import { ReviewPanel } from "@/components/common/review-panel";
|
import { ReviewPanel } from "@/components/common/review-panel";
|
||||||
import { SideBySideComparison } from "@/components/common/side-by-side-comparison";
|
import { SideBySideComparison } from "@/components/common/side-by-side-comparison";
|
||||||
import { ThumbnailStrip } from "@/components/common/thumbnail-strip";
|
import { ThumbnailStrip } from "@/components/common/thumbnail-strip";
|
||||||
|
import { ToolDropzone } from "@/components/common/tool-dropzone";
|
||||||
import { FeatureInstallPrompt } from "@/components/features/feature-install-prompt";
|
import { FeatureInstallPrompt } from "@/components/features/feature-install-prompt";
|
||||||
import { AppLayout } from "@/components/layout/app-layout";
|
import { AppLayout } from "@/components/layout/app-layout";
|
||||||
import { CropCanvas } from "@/components/tools/crop-canvas";
|
import { CropCanvas } from "@/components/tools/crop-canvas";
|
||||||
@@ -26,8 +27,8 @@ import type { PreviewTransform } from "@/components/tools/rotate-settings";
|
|||||||
import { useTranslation } from "@/contexts/i18n-context";
|
import { useTranslation } from "@/contexts/i18n-context";
|
||||||
import { useAuth } from "@/hooks/use-auth";
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
import { useMobile } from "@/hooks/use-mobile";
|
import { useMobile } from "@/hooks/use-mobile";
|
||||||
import { recordRecentTool } from "@/hooks/use-recent-tools";
|
|
||||||
import { usePageTitle } from "@/hooks/use-page-title";
|
import { usePageTitle } from "@/hooks/use-page-title";
|
||||||
|
import { recordRecentTool } from "@/hooks/use-recent-tools";
|
||||||
import { formatFileSize } from "@/lib/download";
|
import { formatFileSize } from "@/lib/download";
|
||||||
import { format } from "@/lib/format";
|
import { format } from "@/lib/format";
|
||||||
import { ICON_MAP } from "@/lib/icon-map";
|
import { ICON_MAP } from "@/lib/icon-map";
|
||||||
@@ -41,6 +42,7 @@ import { useFileStore } from "@/stores/file-store";
|
|||||||
import { useHtmlToImageStore } from "@/stores/html-to-image-store";
|
import { useHtmlToImageStore } from "@/stores/html-to-image-store";
|
||||||
import { usePdfToImageStore } from "@/stores/pdf-to-image-store";
|
import { usePdfToImageStore } from "@/stores/pdf-to-image-store";
|
||||||
import { useQrStore } from "@/stores/qr-store";
|
import { useQrStore } from "@/stores/qr-store";
|
||||||
|
import { useSettingsStore } from "@/stores/settings-store";
|
||||||
import { useSplitStore } from "@/stores/split-store";
|
import { useSplitStore } from "@/stores/split-store";
|
||||||
|
|
||||||
const MediaPlayerView = lazy(() =>
|
const MediaPlayerView = lazy(() =>
|
||||||
@@ -183,6 +185,7 @@ export function ToolPage() {
|
|||||||
usePageTitle(tool ? getToolName(t, tool.id, tool.name) : undefined);
|
usePageTitle(tool ? getToolName(t, tool.id, tool.name) : undefined);
|
||||||
const { hasPermission } = useAuth();
|
const { hasPermission } = useAuth();
|
||||||
const isAdmin = hasPermission("settings:write");
|
const isAdmin = hasPermission("settings:write");
|
||||||
|
const disabledTools = useSettingsStore((s) => s.disabledTools);
|
||||||
|
|
||||||
const breadcrumb = useMemo(() => {
|
const breadcrumb = useMemo(() => {
|
||||||
if (!tool) return undefined;
|
if (!tool) return undefined;
|
||||||
@@ -382,6 +385,22 @@ export function ToolPage() {
|
|||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
}, [batchZipBlob, batchZipFilename]);
|
}, [batchZipBlob, batchZipFilename]);
|
||||||
|
|
||||||
|
if (toolId && TOOLS.some((tt) => tt.id === toolId) && disabledTools.includes(toolId)) {
|
||||||
|
return (
|
||||||
|
<AppLayout>
|
||||||
|
<div className="flex flex-col items-center justify-center h-full gap-4 text-muted-foreground">
|
||||||
|
<p className="text-lg font-medium">{t.toolPage.disabledByAdmin}</p>
|
||||||
|
<Link
|
||||||
|
to="/"
|
||||||
|
className="px-4 py-2 rounded-lg bg-primary text-primary-foreground text-sm font-medium"
|
||||||
|
>
|
||||||
|
{t.toolPage.browseOtherTools}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</AppLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!tool || !registryEntry) {
|
if (!tool || !registryEntry) {
|
||||||
return (
|
return (
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
@@ -410,13 +429,15 @@ export function ToolPage() {
|
|||||||
|
|
||||||
if (isAiTool && !toolInstalled && featureBundle) {
|
if (isAiTool && !toolInstalled && featureBundle) {
|
||||||
return (
|
return (
|
||||||
<AppLayout>
|
<AppLayout breadcrumb={breadcrumb}>
|
||||||
|
<div className="flex-1 flex items-center justify-center overflow-y-auto bg-muted/20">
|
||||||
<FeatureInstallPrompt
|
<FeatureInstallPrompt
|
||||||
bundle={featureBundle}
|
bundle={featureBundle}
|
||||||
isAdmin={isAdmin}
|
isAdmin={isAdmin}
|
||||||
toolName={tool?.name}
|
toolName={tool?.name}
|
||||||
toolDescription={tool?.description}
|
toolDescription={tool?.description}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -849,6 +870,24 @@ export function ToolPage() {
|
|||||||
|
|
||||||
// Mobile layout: full-height image area with BottomSheet for settings
|
// Mobile layout: full-height image area with BottomSheet for settings
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
|
// Full-width dropzone when no file is loaded (non-generator tools)
|
||||||
|
if (!hasFile && !isNoDropzone) {
|
||||||
|
return (
|
||||||
|
<AppLayout breadcrumb={breadcrumb}>
|
||||||
|
<div className="flex-1 flex items-center justify-center overflow-y-auto bg-muted/20">
|
||||||
|
<ToolDropzone
|
||||||
|
tool={tool}
|
||||||
|
accept={toolAccept}
|
||||||
|
fileFilter={toolFileFilter}
|
||||||
|
multiple
|
||||||
|
onFiles={handleFiles}
|
||||||
|
onUrlImport={handleUrlImport}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</AppLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout breadcrumb={breadcrumb}>
|
<AppLayout breadcrumb={breadcrumb}>
|
||||||
<div className="flex flex-col w-full h-full">
|
<div className="flex flex-col w-full h-full">
|
||||||
@@ -905,6 +944,24 @@ export function ToolPage() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Desktop: full-width dropzone when no file is loaded (non-generator tools)
|
||||||
|
if (!hasFile && !isNoDropzone) {
|
||||||
|
return (
|
||||||
|
<AppLayout breadcrumb={breadcrumb}>
|
||||||
|
<div className="flex-1 flex items-center justify-center overflow-y-auto bg-muted/20">
|
||||||
|
<ToolDropzone
|
||||||
|
tool={tool}
|
||||||
|
accept={toolAccept}
|
||||||
|
fileFilter={toolFileFilter}
|
||||||
|
multiple
|
||||||
|
onFiles={handleFiles}
|
||||||
|
onUrlImport={handleUrlImport}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</AppLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Desktop layout: side-by-side
|
// Desktop layout: side-by-side
|
||||||
return (
|
return (
|
||||||
<AppLayout breadcrumb={breadcrumb}>
|
<AppLayout breadcrumb={breadcrumb}>
|
||||||
|
|||||||
@@ -2441,6 +2441,10 @@ export const ar: TranslationKeys = {
|
|||||||
downloadAllZip: "تحميل الكل (ZIP)",
|
downloadAllZip: "تحميل الكل (ZIP)",
|
||||||
hideSettings: "إخفاء الإعدادات",
|
hideSettings: "إخفاء الإعدادات",
|
||||||
imageArea: "منطقة الصورة",
|
imageArea: "منطقة الصورة",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "جاري إنشاء المعاينة...",
|
generatingPreview: "جاري إنشاء المعاينة...",
|
||||||
|
|||||||
@@ -2455,6 +2455,10 @@ export const de: TranslationKeys = {
|
|||||||
downloadAllZip: "Alle herunterladen (ZIP)",
|
downloadAllZip: "Alle herunterladen (ZIP)",
|
||||||
hideSettings: "Einstellungen ausblenden",
|
hideSettings: "Einstellungen ausblenden",
|
||||||
imageArea: "Bildbereich",
|
imageArea: "Bildbereich",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Vorschau wird generiert...",
|
generatingPreview: "Vorschau wird generiert...",
|
||||||
|
|||||||
@@ -2405,6 +2405,10 @@ export const en = {
|
|||||||
downloadAllZip: "Download All (ZIP)",
|
downloadAllZip: "Download All (ZIP)",
|
||||||
hideSettings: "Hide Settings",
|
hideSettings: "Hide Settings",
|
||||||
imageArea: "Image area",
|
imageArea: "Image area",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Generating preview...",
|
generatingPreview: "Generating preview...",
|
||||||
|
|||||||
@@ -2437,6 +2437,10 @@ export const es: TranslationKeys = {
|
|||||||
downloadAllZip: "Descargar todo (ZIP)",
|
downloadAllZip: "Descargar todo (ZIP)",
|
||||||
hideSettings: "Ocultar configuracion",
|
hideSettings: "Ocultar configuracion",
|
||||||
imageArea: "Area de imagen",
|
imageArea: "Area de imagen",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Generando vista previa...",
|
generatingPreview: "Generando vista previa...",
|
||||||
|
|||||||
@@ -2456,6 +2456,10 @@ export const fr: TranslationKeys = {
|
|||||||
downloadAllZip: "Tout telecharger (ZIP)",
|
downloadAllZip: "Tout telecharger (ZIP)",
|
||||||
hideSettings: "Masquer les parametres",
|
hideSettings: "Masquer les parametres",
|
||||||
imageArea: "Zone d'image",
|
imageArea: "Zone d'image",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Generation de l'apercu...",
|
generatingPreview: "Generation de l'apercu...",
|
||||||
|
|||||||
@@ -2438,6 +2438,10 @@ export const hi: TranslationKeys = {
|
|||||||
downloadAllZip: "सभी डाउनलोड करें (ZIP)",
|
downloadAllZip: "सभी डाउनलोड करें (ZIP)",
|
||||||
hideSettings: "सेटिंग्स छुपाएं",
|
hideSettings: "सेटिंग्स छुपाएं",
|
||||||
imageArea: "इमेज क्षेत्र",
|
imageArea: "इमेज क्षेत्र",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "प्रीव्यू जनरेट हो रहा है...",
|
generatingPreview: "प्रीव्यू जनरेट हो रहा है...",
|
||||||
|
|||||||
@@ -2450,6 +2450,10 @@ export const id: TranslationKeys = {
|
|||||||
downloadAllZip: "Unduh Semua (ZIP)",
|
downloadAllZip: "Unduh Semua (ZIP)",
|
||||||
hideSettings: "Sembunyikan Pengaturan",
|
hideSettings: "Sembunyikan Pengaturan",
|
||||||
imageArea: "Area gambar",
|
imageArea: "Area gambar",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Membuat pratinjau...",
|
generatingPreview: "Membuat pratinjau...",
|
||||||
|
|||||||
@@ -2449,6 +2449,10 @@ export const it: TranslationKeys = {
|
|||||||
downloadAllZip: "Scarica tutto (ZIP)",
|
downloadAllZip: "Scarica tutto (ZIP)",
|
||||||
hideSettings: "Nascondi impostazioni",
|
hideSettings: "Nascondi impostazioni",
|
||||||
imageArea: "Area immagine",
|
imageArea: "Area immagine",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Generazione anteprima...",
|
generatingPreview: "Generazione anteprima...",
|
||||||
|
|||||||
@@ -2408,6 +2408,10 @@ export const ja: TranslationKeys = {
|
|||||||
downloadAllZip: "一括ダウンロード(ZIP)",
|
downloadAllZip: "一括ダウンロード(ZIP)",
|
||||||
hideSettings: "設定を隠す",
|
hideSettings: "設定を隠す",
|
||||||
imageArea: "画像エリア",
|
imageArea: "画像エリア",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "プレビューを生成中...",
|
generatingPreview: "プレビューを生成中...",
|
||||||
|
|||||||
@@ -2393,6 +2393,10 @@ export const ko: TranslationKeys = {
|
|||||||
downloadAllZip: "전체 다운로드 (ZIP)",
|
downloadAllZip: "전체 다운로드 (ZIP)",
|
||||||
hideSettings: "설정 숨기기",
|
hideSettings: "설정 숨기기",
|
||||||
imageArea: "이미지 영역",
|
imageArea: "이미지 영역",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "미리보기 생성 중...",
|
generatingPreview: "미리보기 생성 중...",
|
||||||
|
|||||||
@@ -2452,6 +2452,10 @@ export const nl: TranslationKeys = {
|
|||||||
downloadAllZip: "Alles downloaden (ZIP)",
|
downloadAllZip: "Alles downloaden (ZIP)",
|
||||||
hideSettings: "Instellingen verbergen",
|
hideSettings: "Instellingen verbergen",
|
||||||
imageArea: "Afbeeldingsgebied",
|
imageArea: "Afbeeldingsgebied",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Preview genereren...",
|
generatingPreview: "Preview genereren...",
|
||||||
|
|||||||
@@ -2453,6 +2453,10 @@ export const pl: TranslationKeys = {
|
|||||||
downloadAllZip: "Pobierz wszystko (ZIP)",
|
downloadAllZip: "Pobierz wszystko (ZIP)",
|
||||||
hideSettings: "Ukryj ustawienia",
|
hideSettings: "Ukryj ustawienia",
|
||||||
imageArea: "Obszar obrazu",
|
imageArea: "Obszar obrazu",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Generowanie podglądu...",
|
generatingPreview: "Generowanie podglądu...",
|
||||||
|
|||||||
@@ -2449,6 +2449,10 @@ export const ptBR: TranslationKeys = {
|
|||||||
downloadAllZip: "Baixar tudo (ZIP)",
|
downloadAllZip: "Baixar tudo (ZIP)",
|
||||||
hideSettings: "Ocultar configuracoes",
|
hideSettings: "Ocultar configuracoes",
|
||||||
imageArea: "Area da imagem",
|
imageArea: "Area da imagem",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Gerando visualizacao...",
|
generatingPreview: "Gerando visualizacao...",
|
||||||
|
|||||||
@@ -2451,6 +2451,10 @@ export const ru: TranslationKeys = {
|
|||||||
downloadAllZip: "Скачать всё (ZIP)",
|
downloadAllZip: "Скачать всё (ZIP)",
|
||||||
hideSettings: "Скрыть настройки",
|
hideSettings: "Скрыть настройки",
|
||||||
imageArea: "Область изображения",
|
imageArea: "Область изображения",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Генерация предпросмотра...",
|
generatingPreview: "Генерация предпросмотра...",
|
||||||
|
|||||||
@@ -2448,6 +2448,10 @@ export const sv: TranslationKeys = {
|
|||||||
downloadAllZip: "Ladda ner alla (ZIP)",
|
downloadAllZip: "Ladda ner alla (ZIP)",
|
||||||
hideSettings: "Dolj installningar",
|
hideSettings: "Dolj installningar",
|
||||||
imageArea: "Bildomrade",
|
imageArea: "Bildomrade",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Genererar forhandsvisning...",
|
generatingPreview: "Genererar forhandsvisning...",
|
||||||
|
|||||||
@@ -2430,6 +2430,10 @@ export const th: TranslationKeys = {
|
|||||||
downloadAllZip: "ดาวน์โหลดทั้งหมด (ZIP)",
|
downloadAllZip: "ดาวน์โหลดทั้งหมด (ZIP)",
|
||||||
hideSettings: "ซ่อนการตั้งค่า",
|
hideSettings: "ซ่อนการตั้งค่า",
|
||||||
imageArea: "พื้นที่ภาพ",
|
imageArea: "พื้นที่ภาพ",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "กำลังสร้างตัวอย่าง...",
|
generatingPreview: "กำลังสร้างตัวอย่าง...",
|
||||||
|
|||||||
@@ -2453,6 +2453,10 @@ export const tr: TranslationKeys = {
|
|||||||
downloadAllZip: "Tümünü İndir (ZIP)",
|
downloadAllZip: "Tümünü İndir (ZIP)",
|
||||||
hideSettings: "Ayarları Gizle",
|
hideSettings: "Ayarları Gizle",
|
||||||
imageArea: "Görüntü alanı",
|
imageArea: "Görüntü alanı",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Önizleme oluşturuluyor...",
|
generatingPreview: "Önizleme oluşturuluyor...",
|
||||||
|
|||||||
@@ -2451,6 +2451,10 @@ export const uk: TranslationKeys = {
|
|||||||
downloadAllZip: "Завантажити все (ZIP)",
|
downloadAllZip: "Завантажити все (ZIP)",
|
||||||
hideSettings: "Сховати налаштування",
|
hideSettings: "Сховати налаштування",
|
||||||
imageArea: "Область зображення",
|
imageArea: "Область зображення",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Генерація попереднього перегляду...",
|
generatingPreview: "Генерація попереднього перегляду...",
|
||||||
|
|||||||
@@ -2450,6 +2450,10 @@ export const vi: TranslationKeys = {
|
|||||||
downloadAllZip: "Tải tất cả (ZIP)",
|
downloadAllZip: "Tải tất cả (ZIP)",
|
||||||
hideSettings: "Ẩn cài đặt",
|
hideSettings: "Ẩn cài đặt",
|
||||||
imageArea: "Vùng ảnh",
|
imageArea: "Vùng ảnh",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "Đang tạo bản xem trước...",
|
generatingPreview: "Đang tạo bản xem trước...",
|
||||||
|
|||||||
@@ -2383,6 +2383,10 @@ export const zhCN: TranslationKeys = {
|
|||||||
downloadAllZip: "全部下载(ZIP)",
|
downloadAllZip: "全部下载(ZIP)",
|
||||||
hideSettings: "隐藏设置",
|
hideSettings: "隐藏设置",
|
||||||
imageArea: "图片区域",
|
imageArea: "图片区域",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "正在生成预览...",
|
generatingPreview: "正在生成预览...",
|
||||||
|
|||||||
@@ -2381,6 +2381,10 @@ export const zhTW: TranslationKeys = {
|
|||||||
downloadAllZip: "全部下載(ZIP)",
|
downloadAllZip: "全部下載(ZIP)",
|
||||||
hideSettings: "隱藏設定",
|
hideSettings: "隱藏設定",
|
||||||
imageArea: "影像區域",
|
imageArea: "影像區域",
|
||||||
|
disabledByAdmin: "This tool has been disabled by your administrator",
|
||||||
|
browseOtherTools: "Browse other tools",
|
||||||
|
privacyNote: "Files are processed on your server and never leave your network",
|
||||||
|
andMore: "and {count} more",
|
||||||
},
|
},
|
||||||
homePage: {
|
homePage: {
|
||||||
generatingPreview: "正在產生預覽...",
|
generatingPreview: "正在產生預覽...",
|
||||||
|
|||||||
Reference in New Issue
Block a user