Enhance OAuth event handling by notifying the renderer on provider disconnection. Update ConnectorsPopover to listen for OAuth state changes, and refine WelcomeStep component by removing feature highlights and adjusting layout for improved user experience.

This commit is contained in:
tusharmagar 2026-03-16 22:33:30 +05:30
parent ebc2b7b77d
commit e8457b1f54
3 changed files with 14 additions and 49 deletions

View file

@ -286,6 +286,8 @@ export async function disconnectProvider(provider: string): Promise<{ success: b
try {
const oauthRepo = getOAuthRepo();
await oauthRepo.delete(provider);
// Notify renderer so sidebar, voice, and billing re-check state
emitOAuthEvent({ provider, success: false });
return { success: true };
} catch (error) {
console.error('OAuth disconnect failed:', error);

View file

@ -422,10 +422,10 @@ export function ConnectorsPopover({ children, tooltip, open: openProp, onOpenCha
}
}, [open, providers, refreshAllStatuses])
// Listen for OAuth completion events
// Listen for OAuth state change events (connect + disconnect)
useEffect(() => {
const cleanup = window.ipc.on('oauth:didConnect', async (event) => {
const { provider, success, error } = event
const { provider, success } = event
setProviderStates(prev => ({
...prev,
@ -464,9 +464,9 @@ export function ConnectorsPopover({ children, tooltip, open: openProp, onOpenCha
// Refresh status to ensure consistency
refreshAllStatuses()
} else {
toast.error(error || `Failed to connect to ${provider}`)
}
// Note: error toasts for failed connections are handled by startConnect/handleConnect.
// Disconnect events (success: false) are handled by handleDisconnect which shows its own toast.
})
return cleanup

View file

@ -1,4 +1,4 @@
import { Loader2, CheckCircle2, Brain, Plug, ShieldCheck } from "lucide-react"
import { Loader2, CheckCircle2 } from "lucide-react"
import { motion } from "motion/react"
import { Button } from "@/components/ui/button"
import type { OnboardingState } from "../use-onboarding-state"
@ -7,24 +7,6 @@ interface WelcomeStepProps {
state: OnboardingState
}
const features = [
{
icon: Brain,
label: "Memory",
desc: "Builds a knowledge graph from your work",
},
{
icon: Plug,
label: "Connected",
desc: "Syncs email, calendar, and meetings",
},
{
icon: ShieldCheck,
label: "Private",
desc: "Your data stays local on your machine",
},
]
export function WelcomeStep({ state }: WelcomeStepProps) {
const rowboatState = state.providerStates['rowboat'] || { isConnected: false, isLoading: false, isConnecting: false }
@ -35,10 +17,10 @@ export function WelcomeStep({ state }: WelcomeStepProps) {
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.5, ease: [0.16, 1, 0.3, 1] }}
className="relative mb-6"
className="relative mb-8"
>
<div className="absolute inset-0 size-14 rounded-2xl bg-primary/10 blur-xl scale-[2]" />
<img src="/logo-only.png" alt="Rowboat" className="relative size-14" />
<div className="absolute inset-0 size-16 rounded-2xl bg-primary/10 blur-xl scale-[2.5]" />
<img src="/logo-only.png" alt="Rowboat" className="relative size-16" />
</motion.div>
{/* Tagline badge */}
@ -65,35 +47,16 @@ export function WelcomeStep({ state }: WelcomeStepProps) {
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.3 }}
className="text-base text-muted-foreground leading-relaxed max-w-sm mb-8"
className="text-base text-muted-foreground leading-relaxed max-w-sm mb-10"
>
Connect your Rowboat account for instant access to all models through our gateway no API keys needed.
Rowboat connects to your work, builds a knowledge graph, and uses that context to help you get things done. Private and on your machine.
</motion.p>
{/* Feature highlights */}
<div className="grid grid-cols-3 gap-3 w-full max-w-md mb-8">
{features.map((f, i) => (
<motion.div
key={f.label}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.35 + i * 0.08 }}
className="flex flex-col items-center gap-2 rounded-xl border bg-muted/30 p-4"
>
<div className="size-9 rounded-lg bg-primary/10 flex items-center justify-center">
<f.icon className="size-4.5 text-primary/80" />
</div>
<span className="text-xs font-semibold">{f.label}</span>
<span className="text-[11px] leading-tight text-muted-foreground">{f.desc}</span>
</motion.div>
))}
</div>
{/* Sign in / connected state */}
<motion.div
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.6 }}
transition={{ delay: 0.4 }}
className="w-full max-w-xs"
>
{rowboatState.isConnected ? (
@ -143,7 +106,7 @@ export function WelcomeStep({ state }: WelcomeStepProps) {
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.7 }}
transition={{ delay: 0.5 }}
className="mt-8"
>
<button