Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions apps/desktop/src/components/main/sidebar/banner/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,18 @@ export function Banner({
</Button>
)}

{banner.icon && (
{(banner.icon || banner.title) && (
<div className="flex items-center gap-2">
{banner.icon}
<h3 className="text-lg font-bold text-neutral-900">
{banner.title}
</h3>
{banner.title && (
<h3 className="text-lg font-bold text-neutral-900">
{banner.title}
</h3>
)}
</div>
)}

{!banner.icon && (
<h3 className="text-lg font-bold text-neutral-900">{banner.title}</h3>
)}

<p className="text-sm">{banner.description}</p>
<div className="text-sm">{banner.description}</div>

<div className="flex flex-col gap-2 mt-1">
{banner.primaryAction && (
Expand Down
19 changes: 17 additions & 2 deletions apps/desktop/src/components/main/sidebar/banner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,28 @@ export function BannerArea({
const hasLLMConfigured = !!(current_llm_provider && current_llm_model);
const hasSttConfigured = !!(current_stt_provider && current_stt_model);

const currentTab = useTabs((state) => state.currentTab);
const isAiTranscriptionTabActive =
currentTab?.type === "ai" && currentTab.state?.tab === "transcription";
const isAiIntelligenceTabActive =
currentTab?.type === "ai" && currentTab.state?.tab === "intelligence";

const openNew = useTabs((state) => state.openNew);
const updateAiTabState = useTabs((state) => state.updateAiTabState);

const handleSignIn = useCallback(async () => {
await auth?.signIn();
}, [auth]);

const openAiTab = useCallback(
(tab: "intelligence" | "transcription") => {
openNew({ type: "ai", state: { tab } });
if (currentTab?.type === "ai") {
updateAiTabState(currentTab, { tab });
} else {
openNew({ type: "ai", state: { tab } });
}
},
[openNew],
[currentTab, openNew, updateAiTabState],
);

const handleOpenLLMSettings = useCallback(() => {
Expand All @@ -56,6 +67,8 @@ export function BannerArea({
isAuthenticated,
hasLLMConfigured,
hasSttConfigured,
isAiTranscriptionTabActive,
isAiIntelligenceTabActive,
onSignIn: handleSignIn,
onOpenLLMSettings: handleOpenLLMSettings,
onOpenSTTSettings: handleOpenSTTSettings,
Expand All @@ -64,6 +77,8 @@ export function BannerArea({
isAuthenticated,
hasLLMConfigured,
hasSttConfigured,
isAiTranscriptionTabActive,
isAiIntelligenceTabActive,
handleSignIn,
handleOpenLLMSettings,
handleOpenSTTSettings,
Expand Down
35 changes: 21 additions & 14 deletions apps/desktop/src/components/main/sidebar/banner/registry.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { AudioLinesIcon, SparklesIcon } from "lucide-react";

import type { BannerCondition, BannerType } from "./types";

type BannerRegistryEntry = {
Expand All @@ -11,6 +9,8 @@ type BannerRegistryParams = {
isAuthenticated: boolean;
hasLLMConfigured: boolean;
hasSttConfigured: boolean;
isAiTranscriptionTabActive: boolean;
isAiIntelligenceTabActive: boolean;
onSignIn: () => void | Promise<void>;
onOpenLLMSettings: () => void;
onOpenSTTSettings: () => void;
Expand All @@ -20,6 +20,8 @@ export function createBannerRegistry({
isAuthenticated,
hasLLMConfigured,
hasSttConfigured,
isAiTranscriptionTabActive,
isAiIntelligenceTabActive,
onSignIn,
onOpenLLMSettings,
onOpenSTTSettings,
Expand All @@ -29,32 +31,37 @@ export function createBannerRegistry({
{
banner: {
id: "missing-stt",
icon: <AudioLinesIcon className="size-5" />,
title: "Missing AI model",
description:
"A transcription model is needed to make Hyprnote listen to your conversations.",
description: (
<>
<strong className="font-mono">Transcription model</strong> is needed
to make Hyprnote listen to your conversations.
</>
),
primaryAction: {
label: "Go to settings",
label: "Configure transcription",
onClick: onOpenSTTSettings,
},
dismissible: false,
},
condition: () => !hasSttConfigured,
condition: () => !hasSttConfigured && !isAiTranscriptionTabActive,
},
{
banner: {
id: "missing-llm",
icon: <SparklesIcon className="size-5" />,
title: "Add intelligence",
description:
"Language model is needed to make Hyprnote summarize and chat about your conversations",
description: (
<>
<strong className="font-mono">Language model</strong> is needed to
make Hyprnote summarize and chat about your conversations.
</>
),
primaryAction: {
label: "Go to settings",
label: "Add intelligence",
onClick: onOpenLLMSettings,
},
dismissible: false,
},
condition: () => !hasLLMConfigured,
condition: () =>
hasSttConfigured && !hasLLMConfigured && !isAiIntelligenceTabActive,
},
{
banner: {
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/src/components/main/sidebar/banner/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export type BannerAction = {
export type BannerType = {
id: string;
icon?: ReactNode;
title: string;
description: string;
title?: string;
description: ReactNode;
primaryAction?: BannerAction;
secondaryAction?: BannerAction;
dismissible: boolean;
Expand Down
Loading