Skip to content

Commit ca8e7f4

Browse files
coderabbit and chores
1 parent 0c1e4fe commit ca8e7f4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+547
-523
lines changed

apps/desktop/src/components/chat/body/empty.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ export function ChatBodyEmpty({ isModelConfigured = true }: { isModelConfigured?
77
};
88

99
const quickActions = [
10-
"Summarize my latest note",
11-
"Help me brainstorm ideas",
12-
"Explain this concept",
13-
"Draft an email",
10+
"Make a 1-paragraph summary",
11+
"Draft a follow-up mail for others",
12+
"What are the next steps for me",
1413
];
1514

1615
const handleQuickAction = (action: string) => {
@@ -48,14 +47,14 @@ export function ChatBodyEmpty({ isModelConfigured = true }: { isModelConfigured?
4847
<span className="text-sm font-medium text-neutral-800">Hyprnote AI</span>
4948
</div>
5049
<p className="text-sm text-neutral-700 mb-2">
51-
Hey! I can help you a lot of cool stuff :)
50+
Hey! I can help you with a lot of cool stuff :)
5251
</p>
53-
<div className="flex flex-wrap gap-1.5 pb-1">
52+
<div className="flex flex-col gap-1 pb-1">
5453
{quickActions.map((action) => (
5554
<button
5655
key={action}
5756
onClick={() => handleQuickAction(action)}
58-
className="px-3 py-1.5 text-xs bg-white hover:bg-neutral-50 text-neutral-700 rounded-full transition-colors border border-neutral-200"
57+
className="px-3 py-2 text-sm bg-white hover:bg-neutral-50 text-neutral-700 rounded-lg transition-colors border border-neutral-200 text-left"
5958
>
6059
{action}
6160
</button>

apps/desktop/src/components/main/body/shared.tsx

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -112,34 +112,24 @@ export function TabItemBase(
112112
isHovered ? "opacity-100" : "opacity-0",
113113
)}
114114
>
115-
{active
116-
? (
117-
<button
118-
onClick={(e) => {
119-
e.stopPropagation();
120-
handleCloseThis();
121-
}}
122-
className="flex items-center justify-center text-red-600 hover:text-red-700"
123-
>
124-
<span className="w-3 h-3 bg-red-600 hover:bg-red-700 rounded-none transition-colors" />
125-
</button>
126-
)
127-
: (
128-
<button
129-
onClick={(e) => {
130-
e.stopPropagation();
131-
handleCloseThis();
132-
}}
133-
className={cn(
134-
"flex items-center justify-center transition-colors",
135-
selected
136-
? "text-neutral-700 hover:text-neutral-900"
137-
: "text-neutral-500 hover:text-neutral-700",
138-
)}
139-
>
140-
<X size={16} />
141-
</button>
115+
<button
116+
onClick={(e) => {
117+
e.stopPropagation();
118+
handleCloseThis();
119+
}}
120+
className={cn(
121+
[
122+
"flex items-center justify-center transition-colors",
123+
active
124+
? "text-red-600 hover:text-red-700"
125+
: selected
126+
? "text-neutral-700 hover:text-neutral-900"
127+
: "text-neutral-500 hover:text-neutral-700",
128+
],
142129
)}
130+
>
131+
<X size={16} />
132+
</button>
143133
</div>
144134
</div>
145135
<span className="truncate">{title}</span>

apps/desktop/src/components/main/sidebar/profile/index.tsx

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -250,23 +250,27 @@ function ProfileButton(
250250
return (
251251
<button
252252
className={cn(
253-
"flex w-full items-center gap-2.5",
254-
"px-4 py-2",
255-
"text-left",
256-
"transition-all duration-300",
257-
"hover:bg-neutral-100",
258-
isExpanded && "bg-neutral-50 border-t border-neutral-100",
253+
[
254+
"flex w-full items-center gap-2.5",
255+
"px-4 py-2",
256+
"text-left",
257+
"transition-all duration-300",
258+
"hover:bg-neutral-100",
259+
isExpanded && "bg-neutral-50 border-t border-neutral-100",
260+
],
259261
)}
260262
onClick={onClick}
261263
>
262264
<div
263265
className={cn(
264-
"flex size-8 flex-shrink-0 items-center justify-center",
265-
"overflow-hidden rounded-full",
266-
"border border-white/60 border-t border-neutral-400",
267-
"bg-gradient-to-br from-indigo-400 to-purple-500",
268-
"shadow-sm",
269-
"transition-transform duration-300",
266+
[
267+
"flex size-8 flex-shrink-0 items-center justify-center",
268+
"overflow-hidden rounded-full",
269+
"border border-white/60 border-t border-neutral-400",
270+
"bg-gradient-to-br from-indigo-400 to-purple-500",
271+
"shadow-sm",
272+
"transition-transform duration-300",
273+
],
270274
)}
271275
>
272276
<img
@@ -281,9 +285,11 @@ function ProfileButton(
281285
<div className="flex items-center gap-1.5">
282286
<ChevronUpIcon
283287
className={cn(
284-
"h-4 w-4",
285-
"transition-transform duration-300",
286-
isExpanded ? "rotate-180 text-neutral-500" : "text-neutral-400",
288+
[
289+
"h-4 w-4",
290+
"transition-transform duration-300",
291+
isExpanded ? "rotate-180 text-neutral-500" : "text-neutral-400",
292+
],
287293
)}
288294
/>
289295
</div>

apps/desktop/src/components/main/sidebar/profile/ota/index.tsx

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { clsx } from "clsx";
2-
import { AlertCircle, CheckCircle, Download, RefreshCw, X } from "lucide-react";
3-
41
import { Spinner } from "@hypr/ui/components/ui/spinner";
52
import { cn } from "@hypr/utils";
3+
4+
import { AlertCircle, CheckCircle, Download, RefreshCw, X } from "lucide-react";
5+
66
import { MenuItem } from "../shared";
77
import { useOTA } from "./task";
88

@@ -50,12 +50,8 @@ export function UpdateChecker() {
5050
e.stopPropagation();
5151
handleCheckForUpdate();
5252
}}
53-
className={clsx(
54-
"rounded-full",
55-
"px-2 py-0.5",
56-
"bg-red-50",
57-
"text-xs font-semibold text-red-600",
58-
"hover:bg-red-100",
53+
className={cn(
54+
["rounded-full", "px-2 py-0.5", "bg-red-50", "text-xs font-semibold text-red-600", "hover:bg-red-100"],
5955
)}
6056
>
6157
Retry
@@ -163,10 +159,12 @@ function MenuItemLikeContainer({ children }: { children: React.ReactNode }) {
163159
return (
164160
<div
165161
className={cn(
166-
"flex w-full items-center gap-2.5 rounded-lg",
167-
"px-4 py-1.5",
168-
"text-sm text-black",
169-
"transition-colors hover:bg-neutral-100",
162+
[
163+
"flex w-full items-center gap-2.5 rounded-lg",
164+
"px-4 py-1.5",
165+
"text-sm text-black",
166+
"transition-colors hover:bg-neutral-100",
167+
],
170168
)}
171169
>
172170
{children}

apps/desktop/src/components/onboarding/permissions.tsx

Lines changed: 62 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,47 @@ import { AlertCircleIcon, ArrowRightIcon, CheckIcon } from "lucide-react";
66
import { usePermissions } from "../../hooks/use-permissions";
77
import { OnboardingContainer, type OnboardingNext } from "./shared";
88

9+
type PermissionBlockProps = {
10+
name: string;
11+
status: string | undefined;
12+
description: { authorized: string; unauthorized: string };
13+
isPending: boolean;
14+
onAction: () => void;
15+
};
16+
17+
function PermissionBlock({ name, status, description, isPending, onAction }: PermissionBlockProps) {
18+
const isAuthorized = status === "authorized";
19+
20+
return (
21+
<div className="flex items-center justify-between">
22+
<div className="flex flex-col gap-2">
23+
<div
24+
className={cn([
25+
"flex items-center gap-2",
26+
!isAuthorized ? "text-red-500" : "text-neutral-900",
27+
])}
28+
>
29+
{!isAuthorized && <AlertCircleIcon className="size-4" />}
30+
<span className="text-base font-medium">{name}</span>
31+
</div>
32+
<p className="text-sm text-neutral-500">
33+
{isAuthorized ? description.authorized : description.unauthorized}
34+
</p>
35+
</div>
36+
<Button
37+
variant={isAuthorized ? "outline" : "default"}
38+
size="icon"
39+
onClick={onAction}
40+
disabled={isPending || isAuthorized}
41+
className={cn(["size-8", isAuthorized && "bg-stone-100 text-stone-800"])}
42+
aria-label={isAuthorized ? `${name} permission granted` : `Request ${name.toLowerCase()} permission`}
43+
>
44+
{isAuthorized ? <CheckIcon className="size-5" /> : <ArrowRightIcon className="size-5" />}
45+
</Button>
46+
</div>
47+
);
48+
}
49+
950
type PermissionsProps = {
1051
onNext: OnboardingNext;
1152
};
@@ -30,99 +71,29 @@ export function Permissions({ onNext }: PermissionsProps) {
3071
return (
3172
<OnboardingContainer title="Quick permissions before we begin">
3273
<div className="flex flex-col gap-4">
33-
<div className="flex items-center justify-between">
34-
<div className="gap-2">
35-
<div
36-
className={cn([
37-
"flex items-center gap-2",
38-
micPermissionStatus.data !== "authorized" ? "text-red-500" : "text-neutral-900",
39-
])}
40-
>
41-
{micPermissionStatus.data !== "authorized" && <AlertCircleIcon className="size-4" />}
42-
<span className="text-base font-medium">Microphone</span>
43-
</div>
44-
<p className="text-sm text-neutral-500">
45-
{micPermissionStatus.data === "authorized" ? "Good to go :)" : "To capture your voice"}
46-
</p>
47-
</div>
48-
<Button
49-
variant={micPermissionStatus.data === "authorized" ? "outline" : "default"}
50-
size="icon"
51-
onClick={handleMicPermissionAction}
52-
disabled={micPermission.isPending || micPermissionStatus.data === "authorized"}
53-
className={cn(["size-8", micPermissionStatus.data === "authorized" && "bg-stone-100 text-stone-800"])}
54-
>
55-
{micPermissionStatus.data === "authorized"
56-
? <CheckIcon className="size-5" />
57-
: <ArrowRightIcon className="size-5" />}
58-
</Button>
59-
</div>
74+
<PermissionBlock
75+
name="Microphone"
76+
status={micPermissionStatus.data}
77+
description={{ authorized: "Good to go :)", unauthorized: "To capture your voice" }}
78+
isPending={micPermission.isPending}
79+
onAction={handleMicPermissionAction}
80+
/>
6081

61-
<div className="flex items-center justify-between">
62-
<div className="gap-2">
63-
<div
64-
className={cn([
65-
"flex items-center gap-2",
66-
systemAudioPermissionStatus.data !== "authorized" ? "text-red-500" : "text-neutral-900",
67-
])}
68-
>
69-
{systemAudioPermissionStatus.data !== "authorized" && <AlertCircleIcon className="size-4" />}
70-
<span className="text-base font-medium">System audio</span>
71-
</div>
72-
<p className="text-sm text-neutral-500">
73-
{systemAudioPermissionStatus.data === "authorized"
74-
? "Good to go :)"
75-
: "To capture what other people are saying"}
76-
</p>
77-
</div>
78-
<Button
79-
variant={systemAudioPermissionStatus.data === "authorized" ? "outline" : "default"}
80-
size="icon"
81-
onClick={handleSystemAudioPermissionAction}
82-
disabled={systemAudioPermission.isPending || systemAudioPermissionStatus.data === "authorized"}
83-
className={cn([
84-
"size-8",
85-
systemAudioPermissionStatus.data === "authorized" && "bg-stone-100 text-stone-800",
86-
])}
87-
>
88-
{systemAudioPermissionStatus.data === "authorized"
89-
? <CheckIcon className="size-5" />
90-
: <ArrowRightIcon className="size-5" />}
91-
</Button>
92-
</div>
82+
<PermissionBlock
83+
name="System audio"
84+
status={systemAudioPermissionStatus.data}
85+
description={{ authorized: "Good to go :)", unauthorized: "To capture what other people are saying" }}
86+
isPending={systemAudioPermission.isPending}
87+
onAction={handleSystemAudioPermissionAction}
88+
/>
9389

94-
<div className="flex items-center justify-between">
95-
<div className="gap-2">
96-
<div
97-
className={cn([
98-
"flex items-center gap-2",
99-
accessibilityPermissionStatus.data !== "authorized" ? "text-red-500" : "text-neutral-900",
100-
])}
101-
>
102-
{accessibilityPermissionStatus.data !== "authorized" && <AlertCircleIcon className="size-4" />}
103-
<span className="text-base font-medium">Accessibility</span>
104-
</div>
105-
<p className="text-sm text-neutral-500">
106-
{accessibilityPermissionStatus.data === "authorized"
107-
? "Good to go :)"
108-
: "To sync mic inputs & mute from meetings"}
109-
</p>
110-
</div>
111-
<Button
112-
variant={accessibilityPermissionStatus.data === "authorized" ? "outline" : "default"}
113-
size="icon"
114-
onClick={handleAccessibilityPermissionAction}
115-
disabled={accessibilityPermission.isPending || accessibilityPermissionStatus.data === "authorized"}
116-
className={cn([
117-
"size-8",
118-
accessibilityPermissionStatus.data === "authorized" && "bg-stone-100 text-stone-800",
119-
])}
120-
>
121-
{accessibilityPermissionStatus.data === "authorized"
122-
? <CheckIcon className="size-5" />
123-
: <ArrowRightIcon className="size-5" />}
124-
</Button>
125-
</div>
90+
<PermissionBlock
91+
name="Accessibility"
92+
status={accessibilityPermissionStatus.data}
93+
description={{ authorized: "Good to go :)", unauthorized: "To sync mic inputs & mute from meetings" }}
94+
isPending={accessibilityPermission.isPending}
95+
onAction={handleAccessibilityPermissionAction}
96+
/>
12697
</div>
12798

12899
<Button onClick={() => onNext()} className="w-full" disabled={!allPermissionsGranted}>

apps/desktop/src/components/settings/billing.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export function SettingsBilling() {
2424
{PLANS.map((plan, index) => (
2525
<div
2626
key={plan.id}
27-
className={cn(index === 0 && "border-r border-neutral-200")}
27+
className={cn([index === 0 && "border-r border-neutral-200"])}
2828
>
2929
<BillingPlanCard
3030
plan={plan}

apps/desktop/src/components/settings/general/permissions.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ function PermissionRow({
2424
const isDenied = status === "denied";
2525

2626
const displayMessage = isAuthorized
27-
? "Good to go :)"
27+
? "Permission granted"
2828
: isDenied
29-
? "You should toggle in the Settings manually"
29+
? "Please enable this permission in System Settings"
3030
: description;
3131

3232
const buttonText = isAuthorized
@@ -38,7 +38,7 @@ function PermissionRow({
3838
return (
3939
<div className="flex items-start justify-between gap-4">
4040
<div className="flex-1">
41-
<div className={cn("flex items-center gap-2 mb-1", !isAuthorized && "text-red-500")}>
41+
<div className={cn(["flex items-center gap-2 mb-1", !isAuthorized && "text-red-500"])}>
4242
{!isAuthorized && <AlertCircleIcon className="size-4" />}
4343
<h3 className="text-sm font-medium">
4444
{title}

0 commit comments

Comments
 (0)