Onboarding Flow for First-Time Users in Meetily: Steps and State Management
Meetily guides first-time users through a four-step onboarding wizard—Welcome, Setup Overview, Model Downloads, and macOS Permissions—that is fully state-managed by the OnboardingContext React context and persisted via Tauri commands.
The first-time user onboarding flow in Meetily prepares the local environment before any meeting can be processed. According to the Zackriya-Solutions/meetily source code, the frontend orchestrates this setup through a deterministic wizard that initializes the database, downloads required AI models, and requests system permissions. All progression and status flags are centralized in a single React context to ensure consistent state across steps and app restarts.
Meetily Onboarding Steps for First-Time Users
The wizard is rendered by [OnboardingFlow.tsx](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/components/onboarding/OnboardingFlow.tsx), which mounts the appropriate step component based on the currentStep value from context.
Welcome Step
The WelcomeStep is the entry point for every new installation. It introduces Meetily’s core features and offers a single call-to-action that advances the user to the next stage.
Setup Overview Step
The SetupOverviewStep handles database initialization. It detects existing legacy databases, checks for a Homebrew-managed database on macOS, or creates a fresh SQLite database if none are found. The step surfaces real-time status so the user knows whether the environment is ready.
Download Progress Step
The DownloadProgressStep starts background downloads of the speech-recognition model Parakeet and the selected summarisation model. These downloads are recommended by the built-in AI helper defined in [frontend/src/lib/onboarding-summary-model.ts](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/lib/onboarding-summary-model.ts). Progress bars reflect live percentages and detailed metrics such as downloaded megabytes and transfer speed.
Permissions Step (macOS Only)
The final PermissionsStep is gated behind a platform check and only renders when currentStep === 4 on macOS. It requests microphone, system-audio, and screen-recording permissions. The step can also be skipped, which sets the permissionsSkipped flag in context.
State Management with OnboardingContext
All onboarding state lives inside [frontend/src/contexts/OnboardingContext.tsx](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/contexts/OnboardingContext.tsx). The provider wraps the entire application in [frontend/src/app/layout.tsx](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/app/layout.tsx), making the state available anywhere via the useOnboarding() hook.
Core State Variables
The context tracks progression and resource readiness through several key flags:
- currentStep — An integer from 1 to 4 that drives which step component is visible.
- databaseExists — A boolean that becomes true once the local SQLite database is verified or created via
checkDatabaseStatus. - parakeetDownloaded and summaryModelDownloaded — Booleans that signal whether each AI model is present locally.
- parakeetProgress and summaryModelProgress — Numeric percentages from 0 to 100 used for download bars.
- parakeetProgressInfo and summaryModelProgressInfo — Detailed metadata including downloaded megabytes, total megabytes, and speed in Mbps.
- selectedSummaryModel and recommendedSummaryModel — Strings managed with help from the onboarding-summary-model helper to decide which summarisation engine to pull.
- permissions — An object shaped
{ microphone, systemAudio, screenRecording }with status values such asgranted,denied, ornot_determined. - permissionsSkipped — A boolean set when the user elects to bypass the permissions screen.
- isBackgroundDownloading — A boolean that stays true while any model download is active in the background.
Navigation API
Step components never mutate state directly. Instead they call navigation utilities exposed by the context:
goNext()— Advances currentStep by one without exceeding 4.goPrevious()— Moves currentStep back by one without dropping below 1.goToStep(stepNumber)— Jumps to an explicit step index for targeted navigation.
These helpers update setCurrentStep safely so the UI always stays in sync.
Lifecycle and Side Effects
A mount-time useEffect inside the context performs three critical tasks:
- Loads any previously saved onboarding status by calling the Tauri command
loadOnboardingStatus. - Checks whether a database already exists through
checkDatabaseStatus. - Begins silent background preparation via
initializeDatabaseInBackgroundso the Setup Overview step is not blocked.
Additional listeners subscribe to Tauri events such as parakeet-model-download-progress and builtin-ai-download-progress. As the Rust backend emits progress payloads, the context updates the corresponding React state for live UI feedback.
Persistence and Auto-Save
React state is mirrored to disk through the Tauri command save_onboarding_status_cmd. The write is debounced to roughly one second and is deliberately suppressed while the completion routine is running. This prevents race conditions caused by rapid state churn during large downloads.
Completing the Onboarding Flow
When the user finishes the wizard, completeOnboarding() is invoked from the Permissions step or a final action handler. The routine:
- Sets an
isCompletingRefflag to halt the auto-save loop. - Ensures the selected summarisation model is ready, triggering a download if necessary.
- Calls the
complete_onboardingTauri command with the chosen model name. - Persists the final status with
completed: trueand clears the completion flag.
Code Examples
Wrapping the Application with OnboardingProvider
The context provider is imported and applied at the root layout so every page can access onboarding state:
// frontend/src/app/layout.tsx
import { OnboardingProvider } from '@/contexts/OnboardingContext';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<OnboardingProvider>{children}</OnboardingProvider>
</body>
</html>
);
}
Navigating Steps with goNext
Individual step components consume the context to move the user forward:
import { useOnboarding } from '@/contexts/OnboardingContext';
export function WelcomeStep() {
const { goNext } = useOnboarding();
return (
<div>
<h2>Welcome to Meetily</h2>
<button onClick={goNext}>Get Started</button>
</div>
);
}
Triggering Background Model Downloads
The Download Progress step initiates fetches for both the Parakeet and summarisation models:
const { startBackgroundDownloads, recommendedSummaryModel } = useOnboarding();
useEffect(() => {
startBackgroundDownloads({
includeParakeet: true,
includeSummary: true,
summaryModel: recommendedSummaryModel,
});
}, []);
Listening to Download Progress
Inside [OnboardingContext.tsx](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/contexts/OnboardingContext.tsx), progress events from the Tauri backend update the UI state in real time:
useEffect(() => {
const unlisten = listen('builtin-ai-download-progress', (e) => {
// Updates `summaryModelProgress` and `summaryModelProgressInfo`
});
return () => unlisten.then(fn => fn());
}, [selectedSummaryModel]);
Summary
- Meetily exposes a four-step onboarding wizard—Welcome, Setup Overview, Download Progress, and macOS Permissions—rendered by
OnboardingFlow. - All state is owned by
OnboardingContext, including the current step index, database existence flags, model-download metrics, and permission statuses. - Navigation is handled through
goNext,goPrevious, andgoToStepso step components remain stateless UI layers. - State is auto-saved to disk via debounced Tauri commands, and completion is finalized by calling
complete_onboardingon the Rust backend. - The provider is mounted once in
layout.tsx, making onboarding progress available throughout the React tree.
Frequently Asked Questions
What are the exact steps in the Meetily onboarding flow?
The flow contains four sequential stages: a Welcome screen, a Setup Overview that initializes the local database, a Download Progress screen that fetches the Parakeet and summarisation models, and a Permissions screen that requests microphone, system-audio, and screen-recording access on macOS.
How does OnboardingContext persist state across app restarts?
OnboardingContext loads saved progress on mount through the loadOnboardingStatus Tauri command and continuously mirrors React state back to disk with save_onboarding_status_cmd. A one-second debounce prevents excessive writes, and an isCompletingRef guard blocks saves during the final completion routine.
Why is the permissions step limited to macOS?
The Permissions step renders only when currentStep === 4 and the host platform is macOS, because the required microphone, system-audio, and screen-recording entitlements are handled through macOS-specific Tauri APIs. Other platforms skip this stage entirely.
How does Meetily handle background model downloads during onboarding?
When the user reaches the Download Progress step, the context calls startBackgroundDownloads to fetch the Parakeet speech-recognition model and the chosen summarisation model in parallel. Tauri emits progress events that update parakeetProgress, summaryModelProgress, and their associated metadata objects in real time.
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 →