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
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Trans } from "@lingui/react/macro";
import { useMutation, useQuery } from "@tanstack/react-query";
import { MicIcon, MicOffIcon, PauseIcon, PlayIcon, StopCircleIcon, Volume2Icon, VolumeOffIcon } from "lucide-react";
import { useState } from "react";
import { useState, useEffect } from "react";

import SoundIndicator from "@/components/sound-indicator";
import { useHypr } from "@/contexts";
Expand All @@ -14,6 +14,7 @@ import { Spinner } from "@hypr/ui/components/ui/spinner";
import { Tooltip, TooltipContent, TooltipTrigger } from "@hypr/ui/components/ui/tooltip";
import { cn } from "@hypr/ui/lib/utils";
import { useOngoingSession, useSession } from "@hypr/utils/contexts";
import { listen, emit } from "@tauri-apps/api/event";
import ShinyButton from "./shiny-button";

export default function ListenButton({ sessionId }: { sessionId: string }) {
Expand Down Expand Up @@ -321,3 +322,82 @@ function AudioControlButton({
</Button>
);
}

function useConsentManagement(isOnboarding: boolean) {
const ongoingSessionStore = useOngoingSession((s) => ({
hasShownConsent: s.hasShownConsent,
setHasShownConsent: s.setHasShownConsent,
}));

const effectiveHasShownConsent = isOnboarding ? true : ongoingSessionStore.hasShownConsent;
const showConsent = !effectiveHasShownConsent && !isOnboarding;

return {
showConsent,
setHasShownConsent: ongoingSessionStore.setHasShownConsent,
};
}

function useAudioControls() {
const { data: isMicMuted, refetch: refetchMicMuted } = useQuery({
queryKey: ["mic-muted"],
queryFn: () => listenerCommands.getMicMuted(),
});

const { data: isSpeakerMuted, refetch: refetchSpeakerMuted } = useQuery({
queryKey: ["speaker-muted"],
queryFn: () => listenerCommands.getSpeakerMuted(),
});

useEffect(() => {
const unsubscribeMicState = listen<{ muted: boolean }>("audio-mic-state-changed", ({ payload }) => {
console.log(`[Main Window] Received mic state change:`, payload);
refetchMicMuted();
});

const unsubscribeSpeakerState = listen<{ muted: boolean }>("audio-speaker-state-changed", ({ payload }) => {
console.log(`[Main Window] Received speaker state change:`, payload);
refetchSpeakerMuted();
});

return () => {
unsubscribeMicState.then(unlisten => unlisten());
unsubscribeSpeakerState.then(unlisten => unlisten());
};
}, [refetchMicMuted, refetchSpeakerMuted]);

const toggleMicMuted = useMutation({
mutationFn: async () => {
const newMuted = !isMicMuted;
await listenerCommands.setMicMuted(newMuted);
await emit("audio-mic-state-changed", { muted: newMuted });
return newMuted;
},
onSuccess: () => refetchMicMuted(),
onError: (error) => {
console.error('Failed to toggle microphone mute:', error);
},
});

const toggleSpeakerMuted = useMutation({
mutationFn: async () => {
const newMuted = !isSpeakerMuted;
await listenerCommands.setSpeakerMuted(newMuted);
await emit("audio-speaker-state-changed", { muted: newMuted });
return newMuted;
},
onSuccess: () => refetchSpeakerMuted(),
onError: (error) => {
console.error('Failed to toggle speaker mute:', error);
},
});

return {
isMicMuted,
isSpeakerMuted,
toggleMicMuted,
toggleSpeakerMuted,
refetchSpeakerMuted,
refetchMicMuted,
};
}
Comment on lines +326 to +403
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Consider integration with existing functionality or removal.

Both hooks provide functionality that either duplicates existing code or isn't being used. The useAudioControls hook overlaps with the audio control logic in the RecordingControls component (lines 243-254). Consider either:

  1. Integrating these hooks with the existing component
  2. Removing them if they're not needed
  3. Documenting their intended future use

Let me check if these hooks are used elsewhere in the codebase:


🏁 Script executed:

#!/bin/bash
# Search for usage of the new hooks across the codebase
echo "Searching for useConsentManagement usage..."
rg "useConsentManagement" --type tsx --type ts

echo "Searching for useAudioControls usage..."
rg "useAudioControls" --type tsx --type ts

Length of output: 331


Let’s retry the search across all TypeScript/TSX files with glob patterns:


🏁 Script executed:

#!/bin/bash
# Search across .ts and .tsx files for hook usage
rg "useConsentManagement" -g '*.ts' -g '*.tsx' -n
rg "useAudioControls" -g '*.ts' -g '*.tsx' -n

Length of output: 328


Review and consolidate unused hooks in listen-button.tsx

The useConsentManagement and useAudioControls hooks in
apps/desktop/src/components/editor-area/note-header/listen-button.tsx (lines 326–403) are never referenced elsewhere in the codebase. At the same time, the RecordingControls component in
apps/desktop/src/components/editor-area/note-header/recording-controls.tsx (around lines 243–254) already implements similar mic/speaker mute logic.

Consider one of the following actions:

  • Integrate the new hooks into the existing RecordingControls component so that the shared logic lives in one place.
  • Remove useConsentManagement and useAudioControls if they’re not needed today.
  • Document their intended future use if you plan to expose this functionality elsewhere.
🤖 Prompt for AI Agents
In apps/desktop/src/components/editor-area/note-header/listen-button.tsx around
lines 326 to 403, the hooks useConsentManagement and useAudioControls are
defined but never used anywhere else in the codebase, and their functionality
overlaps with existing logic in the RecordingControls component in
apps/desktop/src/components/editor-area/note-header/recording-controls.tsx
around lines 243 to 254. To fix this, either integrate these hooks into the
RecordingControls component to consolidate audio control logic, or remove these
hooks entirely if they are not currently needed, or add clear documentation
about their intended future use if you plan to keep them for upcoming features.

Loading
Loading