refactor: enhance DesktopContent and HotkeysContent components with improved loading states, updated styling, and consistent use of separators

This commit is contained in:
Anish Sarkar 2026-05-19 18:22:30 +05:30
parent e47e9accbb
commit ee3a6dc45f
2 changed files with 63 additions and 39 deletions

View file

@ -2,7 +2,6 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { import {
Select, Select,
@ -11,7 +10,8 @@ import {
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "@/components/ui/select"; } from "@/components/ui/select";
import { Spinner } from "@/components/ui/spinner"; import { Separator } from "@/components/ui/separator";
import { Skeleton } from "@/components/ui/skeleton";
import { Switch } from "@/components/ui/switch"; import { Switch } from "@/components/ui/switch";
import type { SearchSpace } from "@/contracts/types/search-space.types"; import type { SearchSpace } from "@/contracts/types/search-space.types";
import { useElectronAPI } from "@/hooks/use-platform"; import { useElectronAPI } from "@/hooks/use-platform";
@ -77,8 +77,27 @@ export function DesktopContent() {
if (loading) { if (loading) {
return ( return (
<div className="flex items-center justify-center py-12"> <div className="flex flex-col gap-4 md:gap-6">
<Spinner size="md" className="text-muted-foreground" /> <section>
<div className="flex flex-col gap-2 pb-2 md:pb-3">
<Skeleton className="h-6 w-48 bg-accent" />
<Skeleton className="h-4 w-full max-w-2xl bg-accent" />
</div>
<Skeleton className="h-10 w-full bg-accent" />
</section>
<Separator className="bg-border" />
<section>
<div className="flex flex-col gap-2 pb-2 md:pb-3">
<Skeleton className="h-6 w-44 bg-accent" />
<Skeleton className="h-4 w-full max-w-3xl bg-accent" />
</div>
<div className="flex flex-col gap-3">
<Skeleton className="h-20 w-full bg-accent" />
<Skeleton className="h-20 w-full bg-accent" />
</div>
</section>
</div> </div>
); );
} }
@ -124,16 +143,16 @@ export function DesktopContent() {
}; };
return ( return (
<div className="space-y-4 md:space-y-6"> <div className="flex flex-col gap-4 md:gap-6">
<Card> <section>
<CardHeader className="px-3 md:px-6 pt-3 md:pt-6 pb-2 md:pb-3"> <div className="pb-2 md:pb-3">
<CardTitle className="text-base md:text-lg">Default Search Space</CardTitle> <h2 className="text-base md:text-lg font-semibold">Default Search Space</h2>
<CardDescription className="text-xs md:text-sm"> <p className="text-xs md:text-sm text-muted-foreground">
Choose which search space General Assist, Screenshot Assist, and Quick Assist use by Choose which search space General Assist, Screenshot Assist, and Quick Assist use by
default. default.
</CardDescription> </p>
</CardHeader> </div>
<CardContent className="px-3 md:px-6 pb-3 md:pb-6"> <div>
{searchSpaces.length > 0 ? ( {searchSpaces.length > 0 ? (
<Select value={activeSpaceId ?? undefined} onValueChange={handleSearchSpaceChange}> <Select value={activeSpaceId ?? undefined} onValueChange={handleSearchSpaceChange}>
<SelectTrigger className="w-full"> <SelectTrigger className="w-full">
@ -152,21 +171,23 @@ export function DesktopContent() {
No search spaces found. Create one first. No search spaces found. Create one first.
</p> </p>
)} )}
</CardContent> </div>
</Card> </section>
<Card> <Separator className="bg-border" />
<CardHeader className="px-3 md:px-6 pt-3 md:pt-6 pb-2 md:pb-3">
<CardTitle className="text-base md:text-lg flex items-center gap-2"> <section>
<div className="pb-2 md:pb-3">
<h2 className="text-base md:text-lg font-semibold flex items-center gap-2">
Launch on Startup Launch on Startup
</CardTitle> </h2>
<CardDescription className="text-xs md:text-sm"> <p className="text-xs md:text-sm text-muted-foreground">
Automatically start SurfSense when you sign in to your computer so global shortcuts and Automatically start SurfSense when you sign in to your computer so global shortcuts and
folder sync are always available. folder sync are always available.
</CardDescription> </p>
</CardHeader> </div>
<CardContent className="px-3 md:px-6 pb-3 md:pb-6 space-y-3"> <div className="flex flex-col gap-3">
<div className="flex items-center justify-between rounded-lg border p-4"> <div className="flex items-center justify-between rounded-lg bg-accent p-4">
<div className="space-y-0.5"> <div className="space-y-0.5">
<Label htmlFor="auto-launch-toggle" className="text-sm font-medium cursor-pointer"> <Label htmlFor="auto-launch-toggle" className="text-sm font-medium cursor-pointer">
Open SurfSense at login Open SurfSense at login
@ -184,7 +205,7 @@ export function DesktopContent() {
disabled={!autoLaunchSupported} disabled={!autoLaunchSupported}
/> />
</div> </div>
<div className="flex items-center justify-between rounded-lg border p-4"> <div className="flex items-center justify-between rounded-lg bg-accent p-4">
<div className="space-y-0.5"> <div className="space-y-0.5">
<Label <Label
htmlFor="auto-launch-hidden-toggle" htmlFor="auto-launch-hidden-toggle"
@ -193,7 +214,7 @@ export function DesktopContent() {
Start minimized to tray Start minimized to tray
</Label> </Label>
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
Skip the main window on boot SurfSense lives in the system tray until you need it. Skip the main window on boot. SurfSense lives in the system tray until you need it.
</p> </p>
</div> </div>
<Switch <Switch
@ -203,8 +224,8 @@ export function DesktopContent() {
disabled={!autoLaunchSupported || !autoLaunchEnabled} disabled={!autoLaunchSupported || !autoLaunchEnabled}
/> />
</div> </div>
</CardContent> </div>
</Card> </section>
</div> </div>
); );
} }

View file

@ -5,6 +5,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
import { DEFAULT_SHORTCUTS, keyEventToAccelerator } from "@/components/desktop/shortcut-recorder"; import { DEFAULT_SHORTCUTS, keyEventToAccelerator } from "@/components/desktop/shortcut-recorder";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { ShortcutKbd } from "@/components/ui/shortcut-kbd"; import { ShortcutKbd } from "@/components/ui/shortcut-kbd";
import { Spinner } from "@/components/ui/spinner"; import { Spinner } from "@/components/ui/spinner";
import { useElectronAPI } from "@/hooks/use-platform"; import { useElectronAPI } from "@/hooks/use-platform";
@ -78,7 +79,7 @@ function HotkeyRow({
); );
return ( return (
<div className="flex items-center justify-between gap-2.5 border-border/60 border-b py-3 last:border-b-0"> <div className="flex items-center justify-between gap-2.5 py-3">
<div className="flex items-center gap-2.5 min-w-0"> <div className="flex items-center gap-2.5 min-w-0">
<div className="flex size-7 shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary"> <div className="flex size-7 shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary">
<Icon className="size-3.5" /> <Icon className="size-3.5" />
@ -179,9 +180,9 @@ export function HotkeysContent() {
return shortcutsLoaded ? ( return shortcutsLoaded ? (
<div className="flex flex-col gap-3"> <div className="flex flex-col gap-3">
<div> <div>
{HOTKEY_ROWS.map((row) => ( {HOTKEY_ROWS.map((row, index) => (
<div key={row.key}>
<HotkeyRow <HotkeyRow
key={row.key}
label={row.label} label={row.label}
value={shortcuts[row.key]} value={shortcuts[row.key]}
defaultValue={DEFAULT_SHORTCUTS[row.key]} defaultValue={DEFAULT_SHORTCUTS[row.key]}
@ -190,6 +191,8 @@ export function HotkeysContent() {
onChange={(accel) => updateShortcut(row.key, accel)} onChange={(accel) => updateShortcut(row.key, accel)}
onReset={() => resetShortcut(row.key)} onReset={() => resetShortcut(row.key)}
/> />
{index < HOTKEY_ROWS.length - 1 ? <Separator className="bg-border" /> : null}
</div>
))} ))}
</div> </div>
</div> </div>