allow configuration for noise isolation and fix UI layout issue

This commit is contained in:
Hoan HL
2026-04-03 14:01:54 +07:00
parent 9fee6fb787
commit 0196d332d5
5 changed files with 110 additions and 51 deletions
+4
View File
@@ -62,6 +62,10 @@ export interface AppSettings {
accountSid?: string; accountSid?: string;
apiKey?: string; apiKey?: string;
apiServer?: string; apiServer?: string;
noiseIsolationVendor?: string;
noiseIsolationLevel?: number;
noiseIsolationModel?: string;
} }
export interface IAppSettings { export interface IAppSettings {
+8 -4
View File
@@ -110,16 +110,20 @@ export const WindowApp = () => {
setCallHistories(getCallHistories(sipUsername)); setCallHistories(getCallHistories(sipUsername));
}; };
return ( return (
<Grid h="100vh" templateRows="1fr auto"> <Grid h="100vh" templateRows="1fr auto" overflow="hidden">
<Box p={2}> <Box p={2} minH={0} display="flex" flexDirection="column" overflow="hidden">
<Tabs <Tabs
isFitted isFitted
variant="enclosed" variant="enclosed"
colorScheme={DEFAULT_COLOR_SCHEME} colorScheme={DEFAULT_COLOR_SCHEME}
onChange={onTabsChange} onChange={onTabsChange}
index={tabIndex} index={tabIndex}
display="flex"
flexDirection="column"
flex="1"
minH={0}
> >
<TabList mb="1em" gap={1}> <TabList mb="1em" gap={1} flexShrink={0}>
{tabsSettings.map((s, i) => ( {tabsSettings.map((s, i) => (
<Tab <Tab
_selected={{ color: "white", bg: "jambonz.500" }} _selected={{ color: "white", bg: "jambonz.500" }}
@@ -131,7 +135,7 @@ export const WindowApp = () => {
))} ))}
</TabList> </TabList>
<TabPanels> <TabPanels flex="1" minH={0} overflowY="auto">
{tabsSettings.map((s, i) => ( {tabsSettings.map((s, i) => (
<TabPanel key={i}>{s.content}</TabPanel> <TabPanel key={i}>{s.content}</TabPanel>
))} ))}
-2
View File
@@ -41,8 +41,6 @@ export const Recents = ({
{callHistories.length > 0 ? ( {callHistories.length > 0 ? (
<UnorderedList <UnorderedList
w="full" w="full"
maxH="calc(100vh - 21em)"
overflowY="auto"
spacing={2} spacing={2}
mt={2} mt={2}
> >
+48 -45
View File
@@ -528,7 +528,14 @@ export const Phone = ({
activeCall.disableNoiseIsolation(); activeCall.disableNoiseIsolation();
setIsNoiseIsolation(false); setIsNoiseIsolation(false);
} else { } else {
activeCall.enableNoiseIsolation(); const settings = advancedSettings?.decoded;
activeCall.enableNoiseIsolation({
vendor: settings?.noiseIsolationVendor || "krisp",
level: settings?.noiseIsolationLevel ?? 0.3,
...(settings?.noiseIsolationModel
? { model: settings.noiseIsolationModel }
: {}),
});
setIsNoiseIsolation(true); setIsNoiseIsolation(true);
} }
} }
@@ -817,51 +824,20 @@ export const Phone = ({
Call Call
</Button> </Button>
) : ( ) : (
<VStack w="full" spacing={2}> <HStack w="full">
<HStack w="full"> <Tooltip label={isHeld ? "UnHold" : "Hold"}>
<Tooltip label={isHeld ? "UnHold" : "Hold"}>
<IconButton
aria-label="Place call onhold"
icon={
<FontAwesomeIcon icon={isHeld ? faPlay : faPause} />
}
w="33%"
variant="unstyled"
display="flex"
alignItems="center"
justifyContent="center"
onClick={handleCallOnHold}
/>
</Tooltip>
<Spacer />
<IconButton <IconButton
aria-label="Hangup" aria-label="Place call onhold"
icon={<FontAwesomeIcon icon={faPhoneSlash} />} icon={
w="70px" <FontAwesomeIcon icon={isHeld ? faPlay : faPause} />
h="70px" }
borderRadius="100%" variant="unstyled"
colorScheme="jambonz" display="flex"
onClick={handleHangup} alignItems="center"
justifyContent="center"
onClick={handleCallOnHold}
/> />
<Spacer /> </Tooltip>
<Tooltip label={isMuted ? "Unmute" : "Mute"}>
<IconButton
aria-label="Mute"
icon={
<FontAwesomeIcon
icon={isMuted ? faMicrophone : faMicrophoneSlash}
/>
}
w="33%"
variant="unstyled"
display="flex"
alignItems="center"
justifyContent="center"
onClick={handleCallMute}
/>
</Tooltip>
</HStack>
{isSipClientAnswered(callState) && ( {isSipClientAnswered(callState) && (
<Tooltip <Tooltip
label={ label={
@@ -886,7 +862,34 @@ export const Phone = ({
/> />
</Tooltip> </Tooltip>
)} )}
</VStack>
<Spacer />
<IconButton
aria-label="Hangup"
icon={<FontAwesomeIcon icon={faPhoneSlash} />}
w="70px"
h="70px"
borderRadius="100%"
colorScheme="jambonz"
onClick={handleHangup}
/>
<Spacer />
<Tooltip label={isMuted ? "Unmute" : "Mute"}>
<IconButton
aria-label="Mute"
icon={
<FontAwesomeIcon
icon={isMuted ? faMicrophone : faMicrophoneSlash}
/>
}
variant="unstyled"
display="flex"
alignItems="center"
justifyContent="center"
onClick={handleCallMute}
/>
</Tooltip>
</HStack>
)} )}
</VStack> </VStack>
)} )}
+50
View File
@@ -48,6 +48,9 @@ function AccountForm({
const [accountSid, setAccountSid] = useState<string | undefined>(""); const [accountSid, setAccountSid] = useState<string | undefined>("");
const [isCredentialOk, setIsCredentialOk] = useState<boolean>(false); const [isCredentialOk, setIsCredentialOk] = useState<boolean>(false);
const [isAdvancedMode, setIsAdvancedMode] = useState<boolean>(false); const [isAdvancedMode, setIsAdvancedMode] = useState<boolean>(false);
const [noiseIsolationVendor, setNoiseIsolationVendor] = useState("krisp");
const [noiseIsolationLevel, setNoiseIsolationLevel] = useState("0.3");
const [noiseIsolationModel, setNoiseIsolationModel] = useState("");
const toast = useToast(); const toast = useToast();
useEffect( useEffect(
@@ -62,6 +65,13 @@ function AccountForm({
setAccountSid(formData.decoded.accountSid); setAccountSid(formData.decoded.accountSid);
setApiKey(formData.decoded.apiKey || ""); setApiKey(formData.decoded.apiKey || "");
setApiServer(formData.decoded.apiServer); setApiServer(formData.decoded.apiServer);
setNoiseIsolationVendor(formData.decoded.noiseIsolationVendor || "krisp");
setNoiseIsolationLevel(
formData.decoded.noiseIsolationLevel !== undefined
? String(formData.decoded.noiseIsolationLevel)
: "0.3"
);
setNoiseIsolationModel(formData.decoded.noiseIsolationModel || "");
if ( if (
formData.decoded.accountSid || formData.decoded.accountSid ||
@@ -101,6 +111,9 @@ function AccountForm({
accountSid, accountSid,
apiKey, apiKey,
apiServer: apiServer ? normalizeUrl(apiServer) : "", apiServer: apiServer ? normalizeUrl(apiServer) : "",
noiseIsolationVendor: noiseIsolationVendor || "krisp",
noiseIsolationLevel: parseFloat(noiseIsolationLevel) || 0.3,
noiseIsolationModel: noiseIsolationModel || undefined,
}; };
formData ? editSettings(settings, formData.id) : saveSettings(settings); formData ? editSettings(settings, formData.id) : saveSettings(settings);
@@ -146,6 +159,9 @@ function AccountForm({
setApiServer(""); setApiServer("");
setAccountSid(""); setAccountSid("");
setIsAdvancedMode(false); setIsAdvancedMode(false);
setNoiseIsolationVendor("krisp");
setNoiseIsolationLevel("0.3");
setNoiseIsolationModel("");
if (formData) { if (formData) {
handleClose && handleClose(); handleClose && handleClose();
@@ -282,6 +298,40 @@ function AccountForm({
)} )}
</HStack> </HStack>
)} )}
<Text fontSize="13px" fontWeight="bold" mt={2}>
Noise Isolation
</Text>
<FormControl id={`noise_vendor${inputUniqueId}`}>
<FormLabel>Vendor</FormLabel>
<Input
type="text"
placeholder="krisp"
value={noiseIsolationVendor}
onChange={(e) => setNoiseIsolationVendor(e.target.value)}
/>
</FormControl>
<FormControl id={`noise_level${inputUniqueId}`}>
<FormLabel>Level</FormLabel>
<Input
type="number"
step="0.1"
min="0"
max="1"
placeholder="0.3"
value={noiseIsolationLevel}
onChange={(e) => setNoiseIsolationLevel(e.target.value)}
/>
</FormControl>
<FormControl id={`noise_model${inputUniqueId}`}>
<FormLabel>Model (Optional)</FormLabel>
<Input
type="text"
placeholder="Model name"
value={noiseIsolationModel}
onChange={(e) => setNoiseIsolationModel(e.target.value)}
/>
</FormControl>
</VStack> </VStack>
</AnimateOnShow> </AnimateOnShow>
)} )}