feat(tools)!: SnapOtter 2.0 phase 4 wave 1: 45 core tools across all modalities (#219)

This commit is contained in:
SnapOtter
2026-06-13 10:18:49 +08:00
parent d647d8ed19
commit ae1337901d
115 changed files with 10026 additions and 924 deletions
+116 -1
View File
@@ -4,6 +4,8 @@
* Maps each toolId to its settings component, display mode, and capabilities.
* Adding a new tool means adding one entry here instead of editing a 750-line file.
*/
import { AUDIO_INPUTS, VIDEO_INPUTS } from "@snapotter/shared";
import type React from "react";
import { lazy } from "react";
import type { Crop } from "react-image-crop";
@@ -342,6 +344,91 @@ const ColorBlindnessSettings = lazy(() =>
default: m.ColorBlindnessSettings,
})),
);
const ConvertVideoSettings = lazy(() =>
import("@/components/tools/convert-video-settings").then((m) => ({
default: m.ConvertVideoSettings,
})),
);
const CompressVideoSettings = lazy(() =>
import("@/components/tools/compress-video-settings").then((m) => ({
default: m.CompressVideoSettings,
})),
);
const TrimVideoSettings = lazy(() =>
import("@/components/tools/trim-video-settings").then((m) => ({
default: m.TrimVideoSettings,
})),
);
const MuteVideoSettings = lazy(() =>
import("@/components/tools/mute-video-settings").then((m) => ({
default: m.MuteVideoSettings,
})),
);
const VideoToGifSettings = lazy(() =>
import("@/components/tools/video-to-gif-settings").then((m) => ({
default: m.VideoToGifSettings,
})),
);
const ConvertAudioSettings = lazy(() =>
import("@/components/tools/convert-audio-settings").then((m) => ({
default: m.ConvertAudioSettings,
})),
);
const TrimAudioSettings = lazy(() =>
import("@/components/tools/trim-audio-settings").then((m) => ({
default: m.TrimAudioSettings,
})),
);
const ExtractAudioSettings = lazy(() =>
import("@/components/tools/extract-audio-settings").then((m) => ({
default: m.ExtractAudioSettings,
})),
);
const MergePdfSettings = lazy(() =>
import("@/components/tools/merge-pdf-settings").then((m) => ({
default: m.MergePdfSettings,
})),
);
const SplitPdfSettings = lazy(() =>
import("@/components/tools/split-pdf-settings").then((m) => ({
default: m.SplitPdfSettings,
})),
);
const CompressPdfSettings = lazy(() =>
import("@/components/tools/compress-pdf-settings").then((m) => ({
default: m.CompressPdfSettings,
})),
);
const RotatePdfSettings = lazy(() =>
import("@/components/tools/rotate-pdf-settings").then((m) => ({
default: m.RotatePdfSettings,
})),
);
const WordToPdfSettings = lazy(() =>
import("@/components/tools/word-to-pdf-settings").then((m) => ({
default: m.WordToPdfSettings,
})),
);
const CsvExcelSettings = lazy(() =>
import("@/components/tools/csv-excel-settings").then((m) => ({
default: m.CsvExcelSettings,
})),
);
const CsvJsonSettings = lazy(() =>
import("@/components/tools/csv-json-settings").then((m) => ({
default: m.CsvJsonSettings,
})),
);
const JsonXmlSettings = lazy(() =>
import("@/components/tools/json-xml-settings").then((m) => ({
default: m.JsonXmlSettings,
})),
);
const SplitCsvSettings = lazy(() =>
import("@/components/tools/split-csv-settings").then((m) => ({
default: m.SplitCsvSettings,
})),
);
// ── Color tool wrapper ─────────────────────────────────────────────
// Color tools share a single component but differ by toolId.
@@ -428,7 +515,10 @@ const ENTRY_CONFIG: ReadonlyArray<[string, RegistryEntryConfig]> = [
["favicon", { Settings: FaviconSettings }],
["image-to-pdf", { Settings: ImageToPdfSettings }],
["optimize-for-web", { Settings: OptimizeForWebSettings }],
["pdf-to-image", { Settings: PdfToImageSettings, ResultsPanel: PdfToImagePreview }],
[
"pdf-to-image",
{ accept: ".pdf", Settings: PdfToImageSettings, ResultsPanel: PdfToImagePreview },
],
// Adjustments extra
["replace-color", { Settings: ReplaceColorSettings }],
@@ -451,6 +541,31 @@ const ENTRY_CONFIG: ReadonlyArray<[string, RegistryEntryConfig]> = [
["transparency-fixer", { Settings: TransparencyFixerSettings }],
["content-aware-resize", { Settings: ContentAwareResizeSettings }],
["ai-canvas-expand", { Settings: AiCanvasExpandSettings }],
// Video tools
["convert-video", { accept: VIDEO_INPUTS.join(","), Settings: ConvertVideoSettings }],
["compress-video", { accept: VIDEO_INPUTS.join(","), Settings: CompressVideoSettings }],
["trim-video", { accept: VIDEO_INPUTS.join(","), Settings: TrimVideoSettings }],
["mute-video", { accept: VIDEO_INPUTS.join(","), Settings: MuteVideoSettings }],
["video-to-gif", { accept: VIDEO_INPUTS.join(","), Settings: VideoToGifSettings }],
// Audio tools
["convert-audio", { accept: AUDIO_INPUTS.join(","), Settings: ConvertAudioSettings }],
["trim-audio", { accept: AUDIO_INPUTS.join(","), Settings: TrimAudioSettings }],
["extract-audio", { accept: VIDEO_INPUTS.join(","), Settings: ExtractAudioSettings }],
// PDF & Document tools
["merge-pdf", { accept: ".pdf", Settings: MergePdfSettings }],
["split-pdf", { accept: ".pdf", Settings: SplitPdfSettings }],
["compress-pdf", { accept: ".pdf", Settings: CompressPdfSettings }],
["rotate-pdf", { accept: ".pdf", Settings: RotatePdfSettings }],
["word-to-pdf", { accept: ".docx,.doc,.odt,.rtf,.txt", Settings: WordToPdfSettings }],
// Data tools
["csv-excel", { accept: ".csv,.xlsx", Settings: CsvExcelSettings }],
["csv-json", { accept: ".csv,.json", Settings: CsvJsonSettings }],
["json-xml", { accept: ".json,.xml", Settings: JsonXmlSettings }],
["split-csv", { accept: ".csv", Settings: SplitCsvSettings }],
];
export const toolRegistry = new Map<string, ToolRegistryEntry>(