fix: gemini key validation

Signed-off-by: Varun Raj <varun@skcript.com>
This commit is contained in:
Varun Raj
2024-12-28 18:25:06 +05:30
parent c0fec68e43
commit 9f2f0ef7a6
6 changed files with 61 additions and 24 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ export default function FindInput({ onSearch }: FindInputProps) {
control: 'w-full border border-gray-200 rounded-md p-2',
input: 'w-full border border-gray-200 rounded-md p-2 w-full',
}}
placeholder='Search for people or tags'
placeholder='Search for photos, use @ to search for people'
onKeyDown={(e) => {
if (e.key === 'Enter') {
onSearch(query);
+4 -1
View File
@@ -23,6 +23,7 @@ import Head from "next/head";
import { sidebarNavs } from "@/config/constants/sidebarNavs";
import { cn } from "@/lib/utils";
import { useRouter } from "next/router";
import clsx from "clsx";
interface IProps {
leftComponent?: React.ReactNode | string;
@@ -62,7 +63,9 @@ export default function Header({ leftComponent, rightComponent, title }: IProps)
<title>{pageTitle} - Immich Power Tools</title>
</Head>
)}
<header key="header" className="sticky z-10 top-0 w-full flex h-14 items-center gap-4 border-b bg-white dark:bg-black px-4 lg:h-[60px] lg:px-6">
<header key="header" className={
clsx("sticky z-10 top-0 w-full flex h-14 items-center gap-4 border-b bg-white dark:bg-black px-4 lg:h-[60px] lg:px-6")
}>
<Sheet>
<SheetTrigger asChild>
<Button variant="outline" size="icon" className="shrink-0 md:hidden">
+6 -5
View File
@@ -1,6 +1,11 @@
import { Album, GalleryHorizontal, GalleryVerticalEnd, Home, Image, LocateOff, MapPinX, Search, User } from "lucide-react";
export const sidebarNavs = [
{
title: "Find",
link: "/find",
icon: <Search className="h-4 w-4" />,
},
{
title: "Manage People",
link: "/",
@@ -26,9 +31,5 @@ export const sidebarNavs = [
link: "/albums",
icon: <GalleryHorizontal className="h-4 w-4" />,
},
{
title: "Find",
link: "/find",
icon: <Search className="h-4 w-4" />,
},
];
+3 -1
View File
@@ -1,15 +1,17 @@
import { createContext, useContext } from "react";
interface ConfigContextType {
export interface ConfigContextType {
immichURL: string;
exImmichUrl: string;
version?: string;
geminiEnabled: boolean;
}
const ConfigContext = createContext<ConfigContextType>({
immichURL: "",
exImmichUrl: "",
version: "",
geminiEnabled: false,
});
export default ConfigContext;
+4 -7
View File
@@ -3,14 +3,10 @@ import "@/styles/globals.scss";
import type { AppProps } from "next/app";
import { ThemeProvider } from "next-themes";
import { ENV } from "@/config/environment";
import ConfigContext from "@/contexts/ConfigContext";
import ConfigContext, { ConfigContextType } from "@/contexts/ConfigContext";
import { useRef } from "react";
interface AppPropsWithProps extends AppProps {
props: {
immichURL: string;
exImmichUrl: string;
version?: string;
};
props: ConfigContextType;
}
const App = ({ Component, pageProps, ...props }: AppPropsWithProps) => {
const intialData = useRef(props.props);
@@ -32,7 +28,8 @@ App.getInitialProps = async () => {
props: {
exImmichUrl: ENV.EXTERNAL_IMMICH_URL,
immichURL: ENV.IMMICH_URL,
version: ENV.VERSION
version: ENV.VERSION,
geminiEnabled: !!ENV.GEMINI_API_KEY?.length,
},
};
};
+43 -9
View File
@@ -3,16 +3,22 @@ import PageLayout from '@/components/layouts/PageLayout';
import Header from '@/components/shared/Header';
import Loader from '@/components/ui/loader';
import { ASSET_THUMBNAIL_PATH } from '@/config/routes';
import { useConfig } from '@/contexts/ConfigContext';
import { findAssets } from '@/handlers/api/asset.handler';
import { IAsset } from '@/types/asset';
import { Search, TriangleAlert, WandSparkles } from 'lucide-react';
import Image from 'next/image';
import React, { useState } from 'react'
export default function FindPage() {
const { geminiEnabled } = useConfig();
const [query, setQuery] = useState('');
const [assets, setAssets] = useState<IAsset[]>([]);
const [loading, setLoading] = useState(false);
const handleSearch = (query: string) => {
setQuery(query);
setLoading(true);
findAssets(query)
.then(({ assets }) => {
@@ -24,16 +30,25 @@ export default function FindPage() {
}
const renderContent = () => {
if (assets.length === 0) {
return <div className="flex justify-center items-center h-full">
No results found
</div>
}
else if (loading) {
if (loading) {
return <div className="flex justify-center items-center h-full">
<Loader />
</div>
}
else if (query.length === 0) {
return <div className="flex justify-center flex-col gap-2 items-center h-full">
<Search className='w-10 h-10 text-muted-foreground' />
<p className='text-lg font-bold'>Search for photos in natural language</p>
<p className='text-sm text-muted-foreground'>
Example: Sunset photos from last week. Use <kbd className='bg-zinc-200 text-black dark:text-white px-1 py-0.5 rounded-md dark:bg-zinc-500'>@</kbd> to search for photos of a specific person.
</p>
</div>
}
else if (assets.length === 0) {
return <div className="flex justify-center items-center h-full">
No results found
</div>
}
return (
<div className="grid grid-cols-5 gap-4 p-2">
{assets.map((asset) => (
@@ -58,10 +73,29 @@ export default function FindPage() {
return (
<PageLayout>
<Header leftComponent="Find" />
<div className="flex flex-col gap-4 p-2">
<FindInput onSearch={handleSearch} />
{geminiEnabled ? (
<div>
<div className="flex flex-col gap-4 p-2">
<FindInput onSearch={handleSearch} />
</div>
{renderContent()}
</div>
{renderContent()}
) : (
<div className="flex justify-center py-10 items-center h-full flex-col gap-2">
<WandSparkles className='w-10 h-10 text-muted-foreground' />
<p className='text-lg font-semibold'>Google Gemini is not enabled</p>
<p className='text-sm text-muted-foreground max-w-md text-center'>
Currently, the Power Tools Find is relying on Google Gemini for parsing the query.
Please enable Gemini by adding <kbd className='bg-zinc-200 text-black dark:text-white px-1 py-0.5 rounded-md dark:bg-zinc-500'>GEMINI_API_KEY</kbd> in the <kbd className='bg-zinc-200 text-black dark:text-white px-1 py-0.5 rounded-md dark:bg-zinc-500'>.env</kbd> file.
</p>
<div className="border border-l-4 border-zinc-200 dark:border-zinc-500 rounded-md p-2">
<p className='text-sm text-muted-foreground text-center flex gap-1 items-center'>
<TriangleAlert className='w-4 h-4' />
<span>Power tools uses Gemini only for parsing your query. None of your data is sent to Gemini.</span>
</p>
</div>
</div>
)}
</PageLayout>
)
}