Skip to content

Commit a9d29bb

Browse files
authored
Merge pull request #570 from OpenWhispr/feature/unified-provider-layout
Unified provider layout with four inference modes
2 parents d1b4857 + 1c76eba commit a9d29bb

26 files changed

Lines changed: 1545 additions & 574 deletions

src/components/ControlPanel.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,9 @@ export default function ControlPanel() {
399399
cloudTranscriptionBaseUrl: s.cloudTranscriptionBaseUrl,
400400
parakeetModel: s.parakeetModel,
401401
whisperModel: s.whisperModel,
402+
transcriptionMode: s.transcriptionMode,
403+
remoteTranscriptionType: s.remoteTranscriptionType,
404+
remoteTranscriptionUrl: s.remoteTranscriptionUrl,
402405
});
403406
if (result.success && result.transcription) {
404407
const rawText = result.transcription.text;

src/components/ReasoningModelSelector.tsx

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ interface ReasoningModelSelectorProps {
4949
setGroqApiKey: (key: string) => void;
5050
customReasoningApiKey?: string;
5151
setCustomReasoningApiKey?: (key: string) => void;
52+
mode?: "cloud" | "local";
5253
}
5354

5455
function GpuStatusBadge() {
@@ -319,9 +320,10 @@ export default function ReasoningModelSelector({
319320
setGroqApiKey,
320321
customReasoningApiKey = "",
321322
setCustomReasoningApiKey,
323+
mode,
322324
}: ReasoningModelSelectorProps) {
323325
const { t } = useTranslation();
324-
const [selectedMode, setSelectedMode] = useState<"cloud" | "local">("cloud");
326+
const [selectedMode, setSelectedMode] = useState<"cloud" | "local">(mode || "cloud");
325327
const [selectedCloudProvider, setSelectedCloudProvider] = useState("openai");
326328
const [selectedLocalProvider, setSelectedLocalProvider] = useState("qwen");
327329
const [customModelOptions, setCustomModelOptions] = useState<CloudModelOption[]>([]);
@@ -492,6 +494,8 @@ export default function ReasoningModelSelector({
492494
return customModelOptions;
493495
}, [isCustomBaseDirty, customModelOptions]);
494496

497+
const effectiveMode = mode || selectedMode;
498+
495499
const cloudProviderIds = ["openai", "anthropic", "gemini", "groq", "custom"];
496500
const cloudProviders = cloudProviderIds.map((id) => ({
497501
id,
@@ -729,22 +733,24 @@ export default function ReasoningModelSelector({
729733

730734
return (
731735
<div className="space-y-4">
732-
<div className="space-y-2">
733-
<ProviderTabs
734-
providers={MODE_TABS}
735-
selectedId={selectedMode}
736-
onSelect={(id) => handleModeChange(id as "cloud" | "local")}
737-
renderIcon={renderModeIcon}
738-
colorScheme="purple"
739-
/>
740-
<p className="text-xs text-muted-foreground text-center">
741-
{selectedMode === "local"
742-
? t("reasoning.mode.localDescription")
743-
: t("reasoning.mode.cloudDescription")}
744-
</p>
745-
</div>
736+
{!mode && (
737+
<div className="space-y-2">
738+
<ProviderTabs
739+
providers={MODE_TABS}
740+
selectedId={effectiveMode}
741+
onSelect={(id) => handleModeChange(id as "cloud" | "local")}
742+
renderIcon={renderModeIcon}
743+
colorScheme="purple"
744+
/>
745+
<p className="text-xs text-muted-foreground text-center">
746+
{effectiveMode === "local"
747+
? t("reasoning.mode.localDescription")
748+
: t("reasoning.mode.cloudDescription")}
749+
</p>
750+
</div>
751+
)}
746752

747-
{selectedMode === "cloud" ? (
753+
{effectiveMode === "cloud" ? (
748754
<div className="space-y-2">
749755
<div className="border border-border rounded-lg overflow-hidden">
750756
<ProviderTabs

src/components/SelfHostedPanel.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useTranslation } from "react-i18next";
2+
import { Input } from "./ui/input";
3+
4+
interface SelfHostedPanelProps {
5+
service: "transcription" | "reasoning";
6+
url: string;
7+
onUrlChange: (url: string) => void;
8+
}
9+
10+
export default function SelfHostedPanel({ service, url, onUrlChange }: SelfHostedPanelProps) {
11+
const { t } = useTranslation();
12+
13+
const placeholderUrl =
14+
service === "transcription" ? "http://192.168.1.126:8178" : "http://192.168.1.126:8080";
15+
16+
return (
17+
<div className="border border-border rounded-lg p-3 space-y-2.5">
18+
<div className="space-y-1.5">
19+
<label className="block text-xs font-medium text-foreground">
20+
{t("settingsPage.selfHosted.serverUrl")}
21+
</label>
22+
<Input
23+
value={url}
24+
onChange={(e) => onUrlChange(e.target.value)}
25+
placeholder={placeholderUrl}
26+
className="h-8 text-sm"
27+
/>
28+
</div>
29+
<p className="text-xs text-muted-foreground/70">{t("settingsPage.selfHosted.lanHint")}</p>
30+
</div>
31+
);
32+
}

0 commit comments

Comments
 (0)