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;
apiKey?: string;
apiServer?: string;
noiseIsolationVendor?: string;
noiseIsolationLevel?: number;
noiseIsolationModel?: string;
}
export interface IAppSettings {
+8 -4
View File
@@ -110,16 +110,20 @@ export const WindowApp = () => {
setCallHistories(getCallHistories(sipUsername));
};
return (
<Grid h="100vh" templateRows="1fr auto">
<Box p={2}>
<Grid h="100vh" templateRows="1fr auto" overflow="hidden">
<Box p={2} minH={0} display="flex" flexDirection="column" overflow="hidden">
<Tabs
isFitted
variant="enclosed"
colorScheme={DEFAULT_COLOR_SCHEME}
onChange={onTabsChange}
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) => (
<Tab
_selected={{ color: "white", bg: "jambonz.500" }}
@@ -131,7 +135,7 @@ export const WindowApp = () => {
))}
</TabList>
<TabPanels>
<TabPanels flex="1" minH={0} overflowY="auto">
{tabsSettings.map((s, i) => (
<TabPanel key={i}>{s.content}</TabPanel>
))}
-2
View File
@@ -41,8 +41,6 @@ export const Recents = ({
{callHistories.length > 0 ? (
<UnorderedList
w="full"
maxH="calc(100vh - 21em)"
overflowY="auto"
spacing={2}
mt={2}
>
+48 -45
View File
@@ -528,7 +528,14 @@ export const Phone = ({
activeCall.disableNoiseIsolation();
setIsNoiseIsolation(false);
} 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);
}
}
@@ -817,51 +824,20 @@ export const Phone = ({
Call
</Button>
) : (
<VStack w="full" spacing={2}>
<HStack w="full">
<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 />
<HStack w="full">
<Tooltip label={isHeld ? "UnHold" : "Hold"}>
<IconButton
aria-label="Hangup"
icon={<FontAwesomeIcon icon={faPhoneSlash} />}
w="70px"
h="70px"
borderRadius="100%"
colorScheme="jambonz"
onClick={handleHangup}
aria-label="Place call onhold"
icon={
<FontAwesomeIcon icon={isHeld ? faPlay : faPause} />
}
variant="unstyled"
display="flex"
alignItems="center"
justifyContent="center"
onClick={handleCallOnHold}
/>
<Spacer />
<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>
</Tooltip>
{isSipClientAnswered(callState) && (
<Tooltip
label={
@@ -886,7 +862,34 @@ export const Phone = ({
/>
</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>
)}
+50
View File
@@ -48,6 +48,9 @@ function AccountForm({
const [accountSid, setAccountSid] = useState<string | undefined>("");
const [isCredentialOk, setIsCredentialOk] = 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();
useEffect(
@@ -62,6 +65,13 @@ function AccountForm({
setAccountSid(formData.decoded.accountSid);
setApiKey(formData.decoded.apiKey || "");
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 (
formData.decoded.accountSid ||
@@ -101,6 +111,9 @@ function AccountForm({
accountSid,
apiKey,
apiServer: apiServer ? normalizeUrl(apiServer) : "",
noiseIsolationVendor: noiseIsolationVendor || "krisp",
noiseIsolationLevel: parseFloat(noiseIsolationLevel) || 0.3,
noiseIsolationModel: noiseIsolationModel || undefined,
};
formData ? editSettings(settings, formData.id) : saveSettings(settings);
@@ -146,6 +159,9 @@ function AccountForm({
setApiServer("");
setAccountSid("");
setIsAdvancedMode(false);
setNoiseIsolationVendor("krisp");
setNoiseIsolationLevel("0.3");
setNoiseIsolationModel("");
if (formData) {
handleClose && handleClose();
@@ -282,6 +298,40 @@ function AccountForm({
)}
</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>
</AnimateOnShow>
)}