How to Implement Recording Start/Stop Notifications in Meetily
Meetily implements recording notifications through a Rust Tauri backend that emits Tauri events and displays OS-level notifications via the NotificationManager, while respecting user preferences stored in the local database.
Meetily is an open-source meeting assistant built with Tauri and React that requires real-time user feedback when recording sessions change state. Implementing recording start/stop notifications involves coordinating the audio command layer, a dedicated notification manager, and user preference settings. This guide walks through the exact implementation using the actual source code from the Zackriya-Solutions/meetily repository.
How Meetily's Notification Architecture Works
The notification system spans both the Rust backend and React frontend. According to the Meetily source code, the NotificationManager in frontend/src-tauri/src/notifications/manager.rs acts as the central authority for displaying OS notifications. When recording commands execute in frontend/src-tauri/src/audio/recording_commands.rs, they emit Tauri events and simultaneously trigger the notification manager to show alerts.
Core Components
- NotificationManager: Handles OS notification display via
tauri-plugin-notification - Recording Commands: Emit lifecycle events (
recording-started,recording-stopped, etc.) - User Settings: Control which notifications appear via
frontend/src-tauri/src/notifications/settings.rs - Frontend Listeners: React hooks consume events for UI updates
Triggering Notifications from Recording Commands
Recording lifecycle events originate in frontend/src-tauri/src/audio/recording_commands.rs. After successfully starting, stopping, pausing, or resuming a recording, the command emits a Tauri event and invokes the notification manager.
// frontend/src-tauri/src/audio/recording_commands.rs
pub async fn start_recording(app: &AppHandle) -> Result<()> {
// ... audio pipeline start logic ...
let meeting = current_meeting_name().await; // e.g., Some("Team Sync")
// Emit event for frontend consumption
app.emit_all("recording-started", &meeting)?;
// Show OS notification (respects user settings)
let notif_mgr = NotificationManager::new(app.clone()).await?;
notif_mgr.show_recording_started(meeting).await?;
Ok(())
}
The same pattern applies to stop_recording, pause_recording, and resume_recording, emitting recording-stopped, recording-paused, and recording-resumed events respectively.
Creating Notification Payloads
The Notification enum in frontend/src-tauri/src/notifications/types.rs defines the structure of alerts. Helper constructors format user-friendly messages that optionally include the meeting name.
// frontend/src-tauri/src/notifications/types.rs
pub enum Notification {
RecordingStarted { meeting_name: Option<String> },
RecordingStopped { meeting_name: Option<String> },
RecordingPaused { meeting_name: Option<String> },
RecordingResumed { meeting_name: Option<String> },
}
impl Notification {
pub fn recording_started(meeting_name: Option<String>) -> Self {
Self::RecordingStarted { meeting_name }
}
// Returns title and body for the OS notification
pub fn title(&self) -> String {
match self {
Self::RecordingStarted { .. } => "Recording Started".to_string(),
Self::RecordingStopped { .. } => "Recording Stopped".to_string(),
_ => "Recording Update".to_string(),
}
}
pub fn body(&self) -> String {
match self {
Self::RecordingStarted { meeting_name } => {
match meeting_name {
Some(name) => format!("Meeting: {}", name),
None => "Recording has begun".to_string(),
}
}
// ... additional variants
}
}
}
Respecting User Preferences
Before displaying any notification, the NotificationManager checks user settings defined in frontend/src-tauri/src/notifications/settings.rs. Users can disable the entire notification system or specific event types.
Key settings structure:
recording_notifications: Master toggle for all recording alertsshow_recording_started: Specific toggle for start eventsshow_recording_stopped: Specific toggle for stop eventsshow_recording_pausedandshow_recording_resumed: Granular controls for pause/resume
// frontend/src-tauri/src/notifications/manager.rs
pub async fn show_recording_started(&self, meeting_name: Option<String>) -> Result<()> {
let settings = self.settings.lock().await;
// Check if user disabled this specific notification
if !settings.notification_preferences.show_recording_started {
return Ok(()); // Silently skip
}
let notification = Notification::recording_started(meeting_name);
self.send(notification).await
}
Frontend Integration
The React frontend listens for Tauri events to update UI state (such as showing toast badges) while the backend handles OS-level notifications. Listen for events in components like src/components/Sidebar/SidebarProvider.tsx.
// Frontend React component
import { listen } from '@tauri-apps/api/event';
useEffect(() => {
const unlisten = await listen<string>('recording-started', (event) => {
toast.success(`Recording started${event.payload ? `: ${event.payload}` : ''}`);
// Update sidebar state or recording indicator
});
return () => { unlisten(); };
}, []);
To trigger recording from the frontend and initiate the notification flow:
import { invoke } from '@tauri-apps/api/tauri';
await invoke('start_recording', {
mic_device_name: selectedMic,
system_device_name: selectedSystem,
meeting_name: "Team Sync"
});
Complete Implementation Checklist
To add notification support for recording events in Meetily:
- Emit Tauri events from
frontend/src-tauri/src/audio/recording_commands.rsusingapp.emit_all() - Call notification methods such as
NotificationManager::show_recording_started()immediately after successful command execution - Define notification payloads in
frontend/src-tauri/src/notifications/types.rswith clear titles and optional meeting context - Check user preferences in
frontend/src-tauri/src/notifications/settings.rsbefore displaying any OS notification - Listen for events in the frontend using Tauri's
listenAPI to update React state and display in-app toasts
Summary
- Meetily uses a Rust-based
NotificationManagerto display OS notifications for recording events - Recording commands in
frontend/src-tauri/src/audio/recording_commands.rsemit Tauri events (recording-started,recording-stopped, etc.) and trigger notification methods - User preferences in
frontend/src-tauri/src/notifications/settings.rscontrol which notifications appear via granular toggles - The React frontend listens for Tauri events to synchronize UI state with recording status
- Notification payloads are constructed in
frontend/src-tauri/src/notifications/types.rswith meeting-specific context
Frequently Asked Questions
Where does Meetily store notification preferences?
Notification preferences are persisted in the local database via the settings repository at frontend/src-tauri/src/database/repositories/setting.rs. The NotificationSettings struct in frontend/src-tauri/src/notifications/settings.rs defines the available toggles, including recording_notifications as the master switch and specific flags like show_recording_started for individual events.
Can I customize the notification message content?
Yes. Modify the Notification enum constructors in frontend/src-tauri/src/notifications/types.rs. The recording_started and recording_stopped helper methods accept an optional meeting_name parameter and format the notification title and body. You can extend these constructors to include additional context such as timestamps or participant counts.
What events trigger notifications in Meetily?
The system emits notifications for four recording lifecycle events: recording-started, recording-stopped, recording-paused, and recording-resumed. Each event corresponds to a command in frontend/src-tauri/src/audio/recording_commands.rs and has dedicated methods in the NotificationManager (e.g., show_recording_started(), show_recording_stopped()).
How do I disable notifications for specific recording events only?
Users can disable specific event types without turning off all notifications. The NotificationManager checks individual boolean flags from settings.notification_preferences (such as show_recording_started or show_recording_stopped) before displaying each notification type. Set these flags to false in the settings UI to suppress specific alerts while keeping others active.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →