Skip to content

Commit

Permalink
feat: Add PWA installation button
Browse files Browse the repository at this point in the history
feat: Added file upload size limit
refactor: Optimize PWA file generation logic
doc: Modify app screenshot and add `NEXT_PUBLIC_UPLOAD_LIMIT` environment variable description
  • Loading branch information
Amery2010 committed May 28, 2024
1 parent 3d1ab1c commit 7e0b1fb
Show file tree
Hide file tree
Showing 32 changed files with 137 additions and 69 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ GEMINI_API_BASE_URL=
GEMINI_UPLOAD_BASE_URL=
NEXT_PUBLIC_GEMINI_MODEL_LIST=
NEXT_PUBLIC_ASSISTANT_INDEX_URL=
NEXT_PUBLIC_UPLOAD_LIMIT=
HEAD_SCRIPTS=
EXPORT_BASE_PATH=
32 changes: 17 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,13 @@ Simple interface, supports image recognition and voice conversation

简洁的界面,支持图片识别和语音对话

![cover](./public/screenshots/app.jpg)
![cover](./public/screenshots/screenshots.png)

Supports Gemini 1.5 and Gemini 1.5 Flash multimodal models

支持 Gemini 1.5 和 Gemini 1.5 Flash 多模态模型

![Gemini 1.5 Flash](./public/screenshots/gemini-1.5.jpg)

A new assistant market with hundreds of hand-picked system commands

全新的助理市场,拥有数百精选的系统指令

![Assistant Market](./public/screenshots/assistant-market.jpg)
![Gemini 1.5 Flash](./public/screenshots/pc-screenshot-1.png)

> Note: If you encounter problems during the use of the project, you can check the known problems and solutions of [FAQ](#FAQ).
Expand Down Expand Up @@ -156,15 +150,15 @@ Your Gemini api key. If you need to `enable` the server api, this is required.
> Examples: `http://your-gemini-proxy.com`
Override Gemini api request base url.
Override Gemini api request base url. **To avoid server-side proxy url leaks, links in front-end pages will not be overwritten. **

### `GEMINI_UPLOAD_BASE_URL` (optional)

> Default: `https://generativelanguage.googleapis.com`
> Example: `http://your-gemini-upload-proxy.com`
Override Gemini file upload api base url.
Override Gemini file upload api base url. **To avoid server-side proxy url leaks, links in front-end pages will not be overwritten. **

### `NEXT_PUBLIC_GEMINI_MODEL_LIST` (optional)

Expand All @@ -176,7 +170,11 @@ Custom model list, default: all.
> Examples: `http://your-assistant-market-proxy.com`
Override assistant market api request base url.
Override assistant market api request base url. The api link in the front-end interface will be adjusted synchronously.

### `NEXT_PUBLIC_UPLOAD_LIMIT` (optional)

File upload size limit. There is no file size limit by default.

### `ACCESS_PASSWORD` (optional)

Expand All @@ -202,15 +200,15 @@ Only used to set the page base path in [static deployment](#static-deployment) m
> 示例:`http://your-gemini-proxy.com`
覆盖 Gemini api 请求基本 url。
覆盖 Gemini api 请求基本 url。**为了避免服务端代理 url 泄漏,不会覆盖前端页面中的链接。**

### `GEMINI_UPLOAD_BASE_URL`(可选)

> 默认值:`https://generativelanguage.googleapis.com`
> 示例:`http://your-gemini-upload-proxy.com`
覆盖 Gemini 文件上传 api 基本 url。
覆盖 Gemini 文件上传 api 基本 url。**为了避免服务端代理 url 泄漏,不会覆盖前端页面中的链接。**

### `NEXT_PUBLIC_GEMINI_MODEL_LIST`(可选)

Expand All @@ -222,7 +220,11 @@ Only used to set the page base path in [static deployment](#static-deployment) m
> 示例:`http://your-assistant-market-proxy.com`
覆盖助理市场 api 请求基本 url。
覆盖助理市场 api 请求基本 url。会同步调整前端界面中的 api 链接。

### `NEXT_PUBLIC_UPLOAD_LIMIT`(可选)

文件上传大小限制。默认不限制文件大小。

### `ACCESS_PASSWORD`(可选)

Expand Down Expand Up @@ -328,7 +330,7 @@ docker run -d --name talk-with-gemini \

如果您需要指定其他环境变量,请自行在上述命令中增加 `-e 环境变量=环境变量值` 来指定。

### static deployment
### Static Deployment

You can also build a static page version directly, and then upload all files in the `out` directory to any website service that supports static pages, such as Github Page, Cloudflare, Vercel, etc..

Expand Down
1 change: 1 addition & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const metadata: Metadata = {
url: './logo.svg',
},
},
manifest: './manifest.json',
appleWebApp: {
capable: true,
statusBarStyle: 'default',
Expand Down
13 changes: 11 additions & 2 deletions app/sw.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defaultCache } from '@serwist/next/worker'
import type { PrecacheEntry, SerwistGlobalConfig } from 'serwist'
import { Serwist } from 'serwist'
import { Serwist, NetworkFirst } from 'serwist'

// This declares the value of `injectionPoint` to TypeScript.
// `injectionPoint` is the string that will be replaced by the
Expand All @@ -25,7 +25,16 @@ const serwist = new Serwist({
skipWaiting: true,
clientsClaim: true,
navigationPreload: true,
runtimeCaching: defaultCache,
disableDevLogs: true,
runtimeCaching:
defaultCache.length === 0
? [
{
matcher: () => true,
handler: new NetworkFirst(),
},
]
: defaultCache,
})

serwist.addEventListeners()
22 changes: 16 additions & 6 deletions components/Setting.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { memo, useEffect, useMemo, useState } from 'react'
import { EdgeSpeech } from '@xiangfa/polly'
import { useTranslation } from 'react-i18next'
import { MonitorDown } from 'lucide-react'
import { usePWAInstall } from 'react-use-pwa-install'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Input } from '@/components/ui/input'
Expand All @@ -25,6 +27,7 @@ const GEMINI_MODEL_LIST = process.env.NEXT_PUBLIC_GEMINI_MODEL_LIST

function Setting({ open, hiddenTalkPanel, onClose }: SettingProps) {
const { t } = useTranslation()
const pwaInstall = usePWAInstall()
const settingStore = useSettingStore()
const [password, setPassword] = useState<string>('')
const [apiKey, setApiKey] = useState<string>('')
Expand Down Expand Up @@ -170,7 +173,7 @@ function Setting({ open, hiddenTalkPanel, onClose }: SettingProps) {
</TabsTrigger>
</TabsList>
<TabsContent value="general">
<div className="grid w-full gap-4 px-4 py-4">
<div className="grid w-full gap-4 px-4 py-4 max-sm:px-0">
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="password" className="text-right">
{isProtected ? <span className="leading-12 mr-1 text-red-500">*</span> : null}
Expand Down Expand Up @@ -211,6 +214,17 @@ function Setting({ open, hiddenTalkPanel, onClose }: SettingProps) {
</SelectContent>
</Select>
</div>
{pwaInstall ? (
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="stt" className="text-right">
{t('language')}
</Label>
<Button className="col-span-3" variant="ghost" onClick={() => pwaInstall()}>
<MonitorDown className="mr-1.5 h-4 w-4" />
{t('pwaInstall')}
</Button>
</div>
) : null}
</div>
</TabsContent>
<TabsContent value="model">
Expand Down Expand Up @@ -367,14 +381,10 @@ function Setting({ open, hiddenTalkPanel, onClose }: SettingProps) {
<div className="col-span-3 flex h-10">
<RadioGroup
id="safety"
className="grid w-full grid-cols-5"
className="grid w-full grid-cols-4"
defaultValue={safety}
onValueChange={(value) => setSafety(value)}
>
<div className="flex items-center space-x-2">
<RadioGroupItem value="default" id="default" />
<Label htmlFor="default">{t('default')}</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="none" id="none" />
<Label htmlFor="none">{t('none')}</Label>
Expand Down
2 changes: 1 addition & 1 deletion components/SystemInstruction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ function SystemInstruction({ prompt, onClear }: Props) {
onClick={() => onClear()}
/>
</CardHeader>
<ScrollArea className="max-h-[130px] overflow-y-auto">
<ScrollArea className="max-h-[130px] overflow-y-auto max-sm:max-h-[90px]">
<CardContent className="p-4 pt-0">
<div
className="prose w-full overflow-hidden break-words text-sm leading-6"
Expand Down
3 changes: 2 additions & 1 deletion locales/ar-SA.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@
"none": "لا شيء",
"low": "منخفض",
"middle": "متوسط",
"high": "مرتفع"
"high": "مرتفع",
"pwaInstall": "تثبيت تطبيق المتصفح(PWA)"
}
3 changes: 2 additions & 1 deletion locales/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@
"none": "Nichts",
"low": "Niedrig",
"middle": "Mittel",
"high": "Hoch"
"high": "Hoch",
"pwaInstall": "Browser-App (PWA) installieren"
}
3 changes: 2 additions & 1 deletion locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,6 @@
"none": "None",
"low": "Low",
"middle": "Middle",
"high": "High"
"high": "High",
"pwaInstall": "Install browser application (PWA)"
}
3 changes: 2 additions & 1 deletion locales/es-ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@
"none": "Nada",
"low": "Bajo",
"middle": "Medio",
"high": "Alto"
"high": "Alto",
"pwaInstall": "Instalar aplicación de navegador (PWA)"
}
3 changes: 2 additions & 1 deletion locales/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@
"none": "Rien",
"low": "Bas",
"middle": "Milieu",
"high": "Haut"
"high": "Haut",
"pwaInstall": "Installer l'application de navigateur (PWA)"
}
3 changes: 2 additions & 1 deletion locales/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@
"none": "なし",
"low": "低い",
"middle": "中い",
"high": "高い"
"high": "高い",
"pwaInstall": "ブラウザアプリ(PWA)をインストールする"
}
3 changes: 2 additions & 1 deletion locales/ko-KR.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@
"none": "없음",
"low": "낮은",
"middle": "중간",
"high": "높은"
"high": "높은",
"pwaInstall": "브라우저 애플리케이션(PWA) 설치하기"
}
3 changes: 2 additions & 1 deletion locales/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@
"none": "Nada",
"low": "Baixo",
"middle": "Médio",
"high": "Alto"
"high": "Alto",
"pwaInstall": "Instalar aplicativo de navegador (PWA)"
}
3 changes: 2 additions & 1 deletion locales/ru-RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@
"none": "Ничего",
"low": "Низкий",
"middle": "Средний",
"high": "Высокий"
"high": "Высокий",
"pwaInstall": "Установить приложение браузера (PWA)"
}
3 changes: 2 additions & 1 deletion locales/zh-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@
"none": "",
"low": "",
"middle": "",
"high": ""
"high": "",
"pwaInstall": "安裝瀏覽器應用(PWA)"
}
10 changes: 1 addition & 9 deletions locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,5 @@
"edit": "编辑",
"delete": "删除",
"speak": "朗读",
"modelParams": "模型参数",
"temperature": "随机性",
"maxOutputTokens": "单次回复限制",
"safety": "屏蔽程度",
"default": "默认",
"none": "",
"low": "",
"middle": "",
"high": ""
"pwaInstall": "安装浏览器应用(PWA)"
}
21 changes: 8 additions & 13 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/** @type {import('next').NextConfig} */
const { PHASE_PRODUCTION_BUILD, PHASE_EXPORT } = require('next/constants')

const mode = process.env.NEXT_PUBLIC_BUILD_MODE
const basePath = process.env.EXPORT_BASE_PATH || ''
const apiKey = process.env.GEMINI_API_KEY || ''
const uploadProxyUrl = process.env.GEMINI_UPLOAD_BASE_URL || 'https://generativelanguage.googleapis.com'

/** @type {(phase: string, defaultConfig: import("next").NextConfig) => Promise<import("next").NextConfig>} */
module.exports = async (phase) => {
module.exports = async () => {
const nextConfig = {
transpilePackages: ['crypto-js'],
images: {
Expand Down Expand Up @@ -57,15 +56,11 @@ module.exports = async (phase) => {
}
}

if (phase === PHASE_PRODUCTION_BUILD || phase === PHASE_EXPORT) {
const withSerwist = (await import('@serwist/next')).default({
// Note: This is only an example. If you use Pages Router,
// use something else that works, such as "service-worker/index.ts".
swSrc: 'app/sw.ts',
swDest: 'public/sw.js',
})
return withSerwist(nextConfig)
}

return nextConfig
const withSerwist = (await import('@serwist/next')).default({
// Note: This is only an example. If you use Pages Router,
// use something else that works, such as "service-worker/index.ts".
swSrc: 'app/sw.ts',
swDest: 'public/sw.js',
})
return withSerwist(nextConfig)
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "talk-with-gemini",
"version": "0.10.7",
"version": "0.10.8",
"private": true,
"author": "Amery2010 <[email protected]>",
"license": "GPL-3.0-only",
Expand Down Expand Up @@ -52,6 +52,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^14.1.1",
"react-use-pwa-install": "^1.0.1",
"siriwave": "^2.4.0",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
Expand Down
Loading

0 comments on commit 7e0b1fb

Please sign in to comment.