Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions apps/desktop/src/components/settings/views/sound.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Trans, useLingui } from "@lingui/react/macro";
import { useMutation, useQuery } from "@tanstack/react-query";
import { MicIcon, Volume2Icon } from "lucide-react";
import { useState } from "react";

import { commands as listenerCommands } from "@hypr/plugin-listener";
import { Button } from "@hypr/ui/components/ui/button";
Expand All @@ -16,6 +17,7 @@ interface PermissionItemProps {
done: boolean | undefined;
isPending: boolean;
onRequest: () => void;
buttonText: string;
}

function PermissionItem({
Expand All @@ -25,6 +27,7 @@ function PermissionItem({
done,
isPending,
onRequest,
buttonText,
}: PermissionItemProps) {
return (
<div
Expand Down Expand Up @@ -58,7 +61,7 @@ function PermissionItem({
<Trans>Requesting...</Trans>
</>
)
: <Trans>Enable</Trans>}
: <Trans>{buttonText}</Trans>}
</Button>
)}
</div>
Expand All @@ -69,6 +72,8 @@ function PermissionItem({
export default function Sound() {
const { t } = useLingui();

const [micPermissionRequested, setMicPermissionRequested] = useState(false);

const micPermissionStatus = useQuery({
queryKey: ["micPermission"],
queryFn: () => listenerCommands.checkMicrophoneAccess(),
Expand All @@ -84,11 +89,15 @@ export default function Sound() {
const micPermission = useMutation({
mutationFn: () => listenerCommands.requestMicrophoneAccess(),
onSuccess: () => {
setMicPermissionRequested(true);
setTimeout(() => {
micPermissionStatus.refetch();
}, 3000);
},
onError: console.error,
onError: (error) => {
setMicPermissionRequested(true);
console.error(error);
},
});

const capturePermission = useMutation({
Expand All @@ -102,6 +111,14 @@ export default function Sound() {
onError: console.error,
});

const handleMicPermissionAction = () => {
if (micPermissionRequested && !micPermissionStatus.data) {
listenerCommands.openMicrophoneAccessSettings();
} else {
micPermission.mutate();
}
};

return (
<div>
<div className="space-y-2">
Expand All @@ -111,7 +128,8 @@ export default function Sound() {
description={t`Required to transcribe your voice during meetings`}
done={micPermissionStatus.data}
isPending={micPermission.isPending}
onRequest={() => micPermission.mutate({})}
onRequest={handleMicPermissionAction}
buttonText={micPermissionRequested && !micPermissionStatus.data ? "Open Settings" : "Enable"}
/>

<PermissionItem
Expand All @@ -121,6 +139,7 @@ export default function Sound() {
done={systemAudioPermissionStatus.data}
isPending={capturePermission.isPending}
onRequest={() => capturePermission.mutate({})}
buttonText="Enable"
/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Spinner } from "@hypr/ui/components/ui/spinner";
import { cn } from "@hypr/ui/lib/utils";
import { message } from "@tauri-apps/plugin-dialog";
import { relaunch } from "@tauri-apps/plugin-process";
import { useState } from "react";

interface PermissionItemProps {
icon: React.ReactNode;
Expand All @@ -18,6 +19,7 @@ interface PermissionItemProps {
isPending: boolean;
onRequest: () => void;
showSystemSettings?: boolean;
buttonText: string;
}

function PermissionItem({
Expand All @@ -28,6 +30,7 @@ function PermissionItem({
isPending,
onRequest,
showSystemSettings = false,
buttonText,
}: PermissionItemProps) {
return (
<div
Expand Down Expand Up @@ -76,7 +79,7 @@ function PermissionItem({
<Trans>Requesting...</Trans>
</>
)
: <Trans>Enable</Trans>}
: <Trans>{buttonText}</Trans>}
</Button>
</>
)}
Expand All @@ -97,6 +100,8 @@ interface AudioPermissionsViewProps {
export function AudioPermissionsView({ onContinue }: AudioPermissionsViewProps) {
const { t } = useLingui();

const [micPermissionRequested, setMicPermissionRequested] = useState(false);

const micPermissionStatus = useQuery({
queryKey: ["micPermission"],
queryFn: () => listenerCommands.checkMicrophoneAccess(),
Expand All @@ -112,11 +117,15 @@ export function AudioPermissionsView({ onContinue }: AudioPermissionsViewProps)
const micPermission = useMutation({
mutationFn: () => listenerCommands.requestMicrophoneAccess(),
onSuccess: () => {
setMicPermissionRequested(true);
setTimeout(() => {
micPermissionStatus.refetch();
}, 3000);
},
onError: console.error,
onError: (error) => {
setMicPermissionRequested(true);
console.error(error);
},
});

const capturePermission = useMutation({
Expand All @@ -130,6 +139,14 @@ export function AudioPermissionsView({ onContinue }: AudioPermissionsViewProps)
onError: console.error,
});

const handleMicPermissionAction = () => {
if (micPermissionRequested && !micPermissionStatus.data) {
listenerCommands.openMicrophoneAccessSettings();
} else {
micPermission.mutate();
}
};

const allPermissionsGranted = micPermissionStatus.data && systemAudioPermissionStatus.data;

return (
Expand All @@ -149,7 +166,8 @@ export function AudioPermissionsView({ onContinue }: AudioPermissionsViewProps)
description={t`Required for meeting transcription`}
done={micPermissionStatus.data}
isPending={micPermission.isPending}
onRequest={() => micPermission.mutate({})}
onRequest={handleMicPermissionAction}
buttonText={micPermissionRequested && !micPermissionStatus.data ? "Open Settings" : "Enable"}
/>

<PermissionItem
Expand All @@ -159,6 +177,7 @@ export function AudioPermissionsView({ onContinue }: AudioPermissionsViewProps)
done={systemAudioPermissionStatus.data}
isPending={capturePermission.isPending}
onRequest={() => capturePermission.mutate({})}
buttonText="Enable"
/>
</div>

Expand Down
14 changes: 1 addition & 13 deletions apps/desktop/src/components/welcome-modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Particles } from "@hypr/ui/components/ui/particles";
import { commands as dbCommands } from "@hypr/plugin-db";
import { commands as localLlmCommands } from "@hypr/plugin-local-llm";
import { AudioPermissionsView } from "./audio-permissions-view";
import { CalendarPermissionsView } from "./calendar-permissions-view";
// import { CalendarPermissionsView } from "./calendar-permissions-view";
import { DownloadProgressView } from "./download-progress-view";
import { LanguageSelectionView } from "./language-selection-view";
import { ModelSelectionView } from "./model-selection-view";
Expand All @@ -35,7 +35,6 @@ export function WelcomeModal({ isOpen, onClose }: WelcomeModalProps) {
| "download-progress"
| "audio-permissions"
| "language-selection"
| "calendar-permissions"
>("welcome");
const [selectedSttModel, setSelectedSttModel] = useState<SupportedModel>("QuantizedSmall");
const [wentThroughDownloads, setWentThroughDownloads] = useState(false);
Expand Down Expand Up @@ -109,7 +108,6 @@ export function WelcomeModal({ isOpen, onClose }: WelcomeModalProps) {
};

const handleLanguageSelectionContinue = async (languages: string[]) => {
// Save the selected languages to the database
try {
const config = await dbCommands.getConfig();
await dbCommands.setConfig({
Expand All @@ -123,17 +121,12 @@ export function WelcomeModal({ isOpen, onClose }: WelcomeModalProps) {
console.error("Failed to save language preferences:", error);
}

setCurrentStep("calendar-permissions");
};

const handleCalendarPermissionsContinue = () => {
commands.setOnboardingNeeded(false);
onClose();
};

useEffect(() => {
if (!isOpen && wentThroughDownloads) {
// start servers for mockup & tutorial
localSttCommands.startServer();
localLlmCommands.startServer();

Expand Down Expand Up @@ -195,11 +188,6 @@ export function WelcomeModal({ isOpen, onClose }: WelcomeModalProps) {
onContinue={handleLanguageSelectionContinue}
/>
)}
{currentStep === "calendar-permissions" && (
<CalendarPermissionsView
onContinue={handleCalendarPermissionsContinue}
/>
)}
</div>

<Particles
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export function LanguageSelectionView({ onContinue }: LanguageSelectionViewProps
className="w-full max-w-sm"
disabled={selectedLanguages.length === 0}
>
<Trans>Continue</Trans>
<Trans>Finish Onboarding</Trans>
</PushableButton>
</div>
);
Expand Down
Loading
Loading