Add configurable send behavior

This commit is contained in:
Mohamed Boudra
2026-04-09 09:56:04 +07:00
parent 83f540f10a
commit f83a4d08da
4 changed files with 105 additions and 30 deletions
+47 -13
View File
@@ -15,7 +15,6 @@ import {
RotateCw,
Trash2,
Server,
Palette,
Keyboard,
Stethoscope,
Info,
@@ -24,7 +23,7 @@ import {
Blocks,
Smartphone,
} from "lucide-react-native";
import { useAppSettings, type AppSettings } from "@/hooks/use-settings";
import { useAppSettings, type AppSettings, type SendBehavior } from "@/hooks/use-settings";
import type { HostProfile, HostConnection } from "@/types/host-connection";
import { useHosts, useHostMutations } from "@/runtime/host-runtime";
import { formatConnectionStatus, getConnectionStatusTone } from "@/utils/daemons";
@@ -77,7 +76,7 @@ import { StatusBadge } from "@/components/ui/status-badge";
type SettingsSectionId =
| "hosts"
| "appearance"
| "general"
| "shortcuts"
| "integrations"
| "providers"
@@ -96,7 +95,7 @@ interface SettingsSectionDef {
function getSettingsSections(context: { isDesktopApp: boolean }): SettingsSectionDef[] {
const sections: SettingsSectionDef[] = [
{ id: "hosts", label: "Hosts", icon: Server },
{ id: "appearance", label: "Appearance", icon: Palette },
{ id: "general", label: "General", icon: Settings },
{ id: "shortcuts", label: "Shortcuts", icon: Keyboard },
{ id: "permissions", label: "Permissions", icon: Shield },
];
@@ -386,15 +385,20 @@ function HostsSection(props: HostsSectionProps) {
);
}
interface AppearanceSectionProps {
interface GeneralSectionProps {
settings: AppSettings;
handleThemeChange: (theme: AppSettings["theme"]) => void;
handleSendBehaviorChange: (behavior: SendBehavior) => void;
}
function AppearanceSection({ settings, handleThemeChange }: AppearanceSectionProps) {
function GeneralSection({
settings,
handleThemeChange,
handleSendBehaviorChange,
}: GeneralSectionProps) {
return (
<View style={settingsStyles.section}>
<Text style={settingsStyles.sectionTitle}>Appearance</Text>
<Text style={settingsStyles.sectionTitle}>General</Text>
<View style={[settingsStyles.card, styles.audioCard]}>
<View style={styles.audioRow}>
<View style={styles.audioRowContent}>
@@ -424,6 +428,23 @@ function AppearanceSection({ settings, handleThemeChange }: AppearanceSectionPro
]}
/>
</View>
<View style={styles.audioRow}>
<View style={styles.audioRowContent}>
<Text style={styles.audioRowTitle}>Default send</Text>
<Text style={styles.audioRowSubtitle}>
What happens when you press Enter while the agent is running
</Text>
</View>
<SegmentedControl
size="sm"
value={settings.sendBehavior}
onValueChange={handleSendBehaviorChange}
options={[
{ value: "interrupt", label: "Interrupt" },
{ value: "queue", label: "Queue" },
]}
/>
</View>
</View>
</View>
);
@@ -614,7 +635,7 @@ function AboutSection({ appVersionText, isDesktopApp }: AboutSectionProps) {
interface SettingsSectionContentProps {
sectionId: SettingsSectionId;
hostsProps: HostsSectionProps;
appearanceProps: AppearanceSectionProps;
generalProps: GeneralSectionProps;
providersProps: ProvidersSectionProps;
diagnosticsProps: DiagnosticsSectionProps;
aboutProps: AboutSectionProps;
@@ -626,7 +647,7 @@ interface SettingsSectionContentProps {
function SettingsSectionContent({
sectionId,
hostsProps,
appearanceProps,
generalProps,
providersProps,
diagnosticsProps,
aboutProps,
@@ -637,8 +658,8 @@ function SettingsSectionContent({
switch (sectionId) {
case "hosts":
return <HostsSection {...hostsProps} />;
case "appearance":
return <AppearanceSection {...appearanceProps} />;
case "general":
return <GeneralSection {...generalProps} />;
case "shortcuts":
return <KeyboardShortcutsSection />;
case "providers":
@@ -1003,6 +1024,13 @@ export default function SettingsScreen() {
[updateSettings],
);
const handleSendBehaviorChange = useCallback(
(behavior: SendBehavior) => {
void updateSettings({ sendBehavior: behavior });
},
[updateSettings],
);
const handlePlaybackTest = useCallback(async () => {
if (!voiceAudioEngine || isPlaybackTestRunning) {
return;
@@ -1069,9 +1097,10 @@ export default function SettingsScreen() {
isMountedRef,
};
const appearanceProps: AppearanceSectionProps = {
const generalProps: GeneralSectionProps = {
settings,
handleThemeChange,
handleSendBehaviorChange,
};
const diagnosticsProps: DiagnosticsSectionProps = {
@@ -1092,7 +1121,7 @@ export default function SettingsScreen() {
const sectionContentProps: Omit<SettingsSectionContentProps, "sectionId"> = {
hostsProps,
appearanceProps,
generalProps,
providersProps,
diagnosticsProps,
aboutProps,
@@ -1901,6 +1930,11 @@ const styles = StyleSheet.create((theme) => ({
color: theme.colors.foreground,
fontSize: theme.fontSize.base,
},
audioRowSubtitle: {
color: theme.colors.mutedForeground,
fontSize: theme.fontSize.sm,
marginTop: theme.spacing[1],
},
providerActions: {
flexDirection: "row",
alignItems: "center",