mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-25 00:36:31 +02:00
feat: add desktop app section to README files
- Introduced a new section in the README files for the Desktop App, highlighting its features: General Assist, Quick Assist, and Extreme Assist. - Updated all language-specific README files to include details about the desktop app's capabilities and download instructions.
This commit is contained in:
parent
f20540f60c
commit
1a6251eaaa
7 changed files with 522 additions and 0 deletions
14
README.es.md
14
README.es.md
|
|
@ -41,6 +41,7 @@ NotebookLM es una de las mejores y más útiles plataformas de IA que existen, p
|
||||||
- **Sin Dependencia de Proveedores** - Configura cualquier modelo LLM, de imagen, TTS y STT.
|
- **Sin Dependencia de Proveedores** - Configura cualquier modelo LLM, de imagen, TTS y STT.
|
||||||
- **25+ Fuentes de Datos Externas** - Agrega tus fuentes desde Google Drive, OneDrive, Dropbox, Notion y muchos otros servicios externos.
|
- **25+ Fuentes de Datos Externas** - Agrega tus fuentes desde Google Drive, OneDrive, Dropbox, Notion y muchos otros servicios externos.
|
||||||
- **Soporte Multijugador en Tiempo Real** - Trabaja fácilmente con los miembros de tu equipo en un notebook compartido.
|
- **Soporte Multijugador en Tiempo Real** - Trabaja fácilmente con los miembros de tu equipo en un notebook compartido.
|
||||||
|
- **Aplicación de Escritorio** - Obtén asistencia de IA en cualquier aplicación con Quick Assist, General Assist y Extreme Assist.
|
||||||
|
|
||||||
...y más por venir.
|
...y más por venir.
|
||||||
|
|
||||||
|
|
@ -130,6 +131,18 @@ El script de instalación configura [Watchtower](https://github.com/nicholas-fed
|
||||||
|
|
||||||
Para Docker Compose, instalación manual y otras opciones de despliegue, consulta la [documentación](https://www.surfsense.com/docs/).
|
Para Docker Compose, instalación manual y otras opciones de despliegue, consulta la [documentación](https://www.surfsense.com/docs/).
|
||||||
|
|
||||||
|
### Aplicación de Escritorio
|
||||||
|
|
||||||
|
SurfSense también ofrece una aplicación de escritorio que lleva la asistencia de IA a cada aplicación en tu computadora. Descárgala desde la [última versión](https://github.com/MODSetter/SurfSense/releases/latest).
|
||||||
|
|
||||||
|
La aplicación de escritorio incluye tres potentes funciones:
|
||||||
|
|
||||||
|
- **General Assist** — Lanza SurfSense al instante desde cualquier aplicación con un atajo global.
|
||||||
|
- **Quick Assist** — Selecciona texto en cualquier lugar, luego pide a la IA que lo explique, reescriba o actúe sobre él.
|
||||||
|
- **Extreme Assist** — Obtén sugerencias de escritura en línea impulsadas por tu base de conocimiento mientras escribes en cualquier aplicación.
|
||||||
|
|
||||||
|
Las tres funciones operan contra tu espacio de búsqueda elegido, por lo que tus respuestas siempre están basadas en tus propios datos.
|
||||||
|
|
||||||
### Cómo Colaborar en Tiempo Real (Beta)
|
### Cómo Colaborar en Tiempo Real (Beta)
|
||||||
|
|
||||||
1. Ve a la página de Gestión de Miembros y crea una invitación.
|
1. Ve a la página de Gestión de Miembros y crea una invitación.
|
||||||
|
|
@ -174,6 +187,7 @@ Para Docker Compose, instalación manual y otras opciones de despliegue, consult
|
||||||
| **Generación de Videos** | Resúmenes en video cinemáticos vía Veo 3 (solo Ultra) | Disponible (NotebookLM es mejor aquí, mejorando activamente) |
|
| **Generación de Videos** | Resúmenes en video cinemáticos vía Veo 3 (solo Ultra) | Disponible (NotebookLM es mejor aquí, mejorando activamente) |
|
||||||
| **Generación de Presentaciones** | Diapositivas más atractivas pero no editables | Crea presentaciones editables basadas en diapositivas |
|
| **Generación de Presentaciones** | Diapositivas más atractivas pero no editables | Crea presentaciones editables basadas en diapositivas |
|
||||||
| **Generación de Podcasts** | Resúmenes de audio con hosts e idiomas personalizables | Disponible con múltiples proveedores TTS (NotebookLM es mejor aquí, mejorando activamente) |
|
| **Generación de Podcasts** | Resúmenes de audio con hosts e idiomas personalizables | Disponible con múltiples proveedores TTS (NotebookLM es mejor aquí, mejorando activamente) |
|
||||||
|
| **Aplicación de Escritorio** | No | Aplicación nativa con General Assist, Quick Assist y Extreme Assist — asistencia de IA en cualquier aplicación |
|
||||||
| **Extensión de Navegador** | No | Extensión multi-navegador para guardar cualquier página web, incluyendo páginas protegidas por autenticación |
|
| **Extensión de Navegador** | No | Extensión multi-navegador para guardar cualquier página web, incluyendo páginas protegidas por autenticación |
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
|
||||||
14
README.hi.md
14
README.hi.md
|
|
@ -41,6 +41,7 @@ NotebookLM वहाँ उपलब्ध सबसे अच्छे और
|
||||||
- **कोई विक्रेता लॉक-इन नहीं** - किसी भी LLM, इमेज, TTS और STT मॉडल को कॉन्फ़िगर करें।
|
- **कोई विक्रेता लॉक-इन नहीं** - किसी भी LLM, इमेज, TTS और STT मॉडल को कॉन्फ़िगर करें।
|
||||||
- **25+ बाहरी डेटा स्रोत** - Google Drive, OneDrive, Dropbox, Notion और कई अन्य बाहरी सेवाओं से अपने स्रोत जोड़ें।
|
- **25+ बाहरी डेटा स्रोत** - Google Drive, OneDrive, Dropbox, Notion और कई अन्य बाहरी सेवाओं से अपने स्रोत जोड़ें।
|
||||||
- **रीयल-टाइम मल्टीप्लेयर सपोर्ट** - एक साझा notebook में अपनी टीम के सदस्यों के साथ आसानी से काम करें।
|
- **रीयल-टाइम मल्टीप्लेयर सपोर्ट** - एक साझा notebook में अपनी टीम के सदस्यों के साथ आसानी से काम करें।
|
||||||
|
- **डेस्कटॉप ऐप** - Quick Assist, General Assist और Extreme Assist के साथ किसी भी एप्लिकेशन में AI सहायता प्राप्त करें।
|
||||||
|
|
||||||
...और भी बहुत कुछ आने वाला है।
|
...और भी बहुत कुछ आने वाला है।
|
||||||
|
|
||||||
|
|
@ -130,6 +131,18 @@ irm https://raw.githubusercontent.com/MODSetter/SurfSense/main/docker/scripts/in
|
||||||
|
|
||||||
Docker Compose, मैनुअल इंस्टॉलेशन और अन्य डिप्लॉयमेंट विकल्पों के लिए, [डॉक्स](https://www.surfsense.com/docs/) देखें।
|
Docker Compose, मैनुअल इंस्टॉलेशन और अन्य डिप्लॉयमेंट विकल्पों के लिए, [डॉक्स](https://www.surfsense.com/docs/) देखें।
|
||||||
|
|
||||||
|
### डेस्कटॉप ऐप
|
||||||
|
|
||||||
|
SurfSense एक डेस्कटॉप ऐप भी प्रदान करता है जो आपके कंप्यूटर पर हर एप्लिकेशन में AI सहायता लाता है। इसे [नवीनतम रिलीज़](https://github.com/MODSetter/SurfSense/releases/latest) से डाउनलोड करें।
|
||||||
|
|
||||||
|
डेस्कटॉप ऐप में तीन शक्तिशाली सुविधाएं शामिल हैं:
|
||||||
|
|
||||||
|
- **General Assist** — एक ग्लोबल शॉर्टकट से किसी भी एप्लिकेशन से तुरंत SurfSense लॉन्च करें।
|
||||||
|
- **Quick Assist** — कहीं भी टेक्स्ट चुनें, फिर AI से समझाने, फिर से लिखने या उस पर कार्रवाई करने को कहें।
|
||||||
|
- **Extreme Assist** — किसी भी ऐप में टाइप करते समय अपनी नॉलेज बेस से संचालित इनलाइन लेखन सुझाव प्राप्त करें।
|
||||||
|
|
||||||
|
तीनों सुविधाएं आपके चुने हुए सर्च स्पेस पर काम करती हैं, ताकि आपके उत्तर हमेशा आपके अपने डेटा पर आधारित हों।
|
||||||
|
|
||||||
### रीयल-टाइम सहयोग कैसे करें (बीटा)
|
### रीयल-टाइम सहयोग कैसे करें (बीटा)
|
||||||
|
|
||||||
1. सदस्य प्रबंधन पेज पर जाएं और एक आमंत्रण बनाएं।
|
1. सदस्य प्रबंधन पेज पर जाएं और एक आमंत्रण बनाएं।
|
||||||
|
|
@ -174,6 +187,7 @@ Docker Compose, मैनुअल इंस्टॉलेशन और अन
|
||||||
| **वीडियो जनरेशन** | Veo 3 के माध्यम से सिनेमैटिक वीडियो ओवरव्यू (केवल Ultra) | उपलब्ध (NotebookLM यहाँ बेहतर है, सक्रिय रूप से सुधार हो रहा है) |
|
| **वीडियो जनरेशन** | Veo 3 के माध्यम से सिनेमैटिक वीडियो ओवरव्यू (केवल Ultra) | उपलब्ध (NotebookLM यहाँ बेहतर है, सक्रिय रूप से सुधार हो रहा है) |
|
||||||
| **प्रेजेंटेशन जनरेशन** | बेहतर दिखने वाली स्लाइड्स लेकिन संपादन योग्य नहीं | संपादन योग्य, स्लाइड आधारित प्रेजेंटेशन बनाएं |
|
| **प्रेजेंटेशन जनरेशन** | बेहतर दिखने वाली स्लाइड्स लेकिन संपादन योग्य नहीं | संपादन योग्य, स्लाइड आधारित प्रेजेंटेशन बनाएं |
|
||||||
| **पॉडकास्ट जनरेशन** | कस्टमाइज़ेबल होस्ट और भाषाओं के साथ ऑडियो ओवरव्यू | कई TTS प्रदाताओं के साथ उपलब्ध (NotebookLM यहाँ बेहतर है, सक्रिय रूप से सुधार हो रहा है) |
|
| **पॉडकास्ट जनरेशन** | कस्टमाइज़ेबल होस्ट और भाषाओं के साथ ऑडियो ओवरव्यू | कई TTS प्रदाताओं के साथ उपलब्ध (NotebookLM यहाँ बेहतर है, सक्रिय रूप से सुधार हो रहा है) |
|
||||||
|
| **डेस्कटॉप ऐप** | नहीं | General Assist, Quick Assist और Extreme Assist के साथ नेटिव ऐप — किसी भी एप्लिकेशन में AI सहायता |
|
||||||
| **ब्राउज़र एक्सटेंशन** | नहीं | किसी भी वेबपेज को सहेजने के लिए क्रॉस-ब्राउज़र एक्सटेंशन, प्रमाणीकरण सुरक्षित पेज सहित |
|
| **ब्राउज़र एक्सटेंशन** | नहीं | किसी भी वेबपेज को सहेजने के लिए क्रॉस-ब्राउज़र एक्सटेंशन, प्रमाणीकरण सुरक्षित पेज सहित |
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
|
||||||
14
README.md
14
README.md
|
|
@ -41,6 +41,7 @@ NotebookLM is one of the best and most useful AI platforms out there, but once y
|
||||||
- **No Vendor Lock-in** - Configure any LLM, image, TTS, and STT models to use.
|
- **No Vendor Lock-in** - Configure any LLM, image, TTS, and STT models to use.
|
||||||
- **25+ External Data Sources** - Add your sources from Google Drive, OneDrive, Dropbox, Notion, and many other external services.
|
- **25+ External Data Sources** - Add your sources from Google Drive, OneDrive, Dropbox, Notion, and many other external services.
|
||||||
- **Real-Time Multiplayer Support** - Work easily with your team members in a shared notebook.
|
- **Real-Time Multiplayer Support** - Work easily with your team members in a shared notebook.
|
||||||
|
- **Desktop App** - Get AI assistance in any application with Quick Assist, General Assist, and Extreme Assist.
|
||||||
|
|
||||||
...and more to come.
|
...and more to come.
|
||||||
|
|
||||||
|
|
@ -131,6 +132,18 @@ The install script sets up [Watchtower](https://github.com/nicholas-fedor/watcht
|
||||||
|
|
||||||
For Docker Compose, manual installation, and other deployment options, see the [docs](https://www.surfsense.com/docs/).
|
For Docker Compose, manual installation, and other deployment options, see the [docs](https://www.surfsense.com/docs/).
|
||||||
|
|
||||||
|
### Desktop App
|
||||||
|
|
||||||
|
SurfSense also ships a desktop app that brings AI assistance to every application on your computer. Download it from the [latest release](https://github.com/MODSetter/SurfSense/releases/latest).
|
||||||
|
|
||||||
|
The desktop app includes three powerful features:
|
||||||
|
|
||||||
|
- **General Assist** — Launch SurfSense instantly from any application with a global shortcut.
|
||||||
|
- **Quick Assist** — Select text anywhere, then ask AI to explain, rewrite, or act on it.
|
||||||
|
- **Extreme Assist** — Get inline writing suggestions powered by your knowledge base as you type in any app.
|
||||||
|
|
||||||
|
All three features operate against your chosen search space, so your answers are always grounded in your own data.
|
||||||
|
|
||||||
### How to Realtime Collaborate (Beta)
|
### How to Realtime Collaborate (Beta)
|
||||||
|
|
||||||
1. Go to Manage Members page and create an invite.
|
1. Go to Manage Members page and create an invite.
|
||||||
|
|
@ -175,6 +188,7 @@ For Docker Compose, manual installation, and other deployment options, see the [
|
||||||
| **Video Generation** | Cinematic Video Overviews via Veo 3 (Ultra only) | Available (NotebookLM is better here, actively improving) |
|
| **Video Generation** | Cinematic Video Overviews via Veo 3 (Ultra only) | Available (NotebookLM is better here, actively improving) |
|
||||||
| **Presentation Generation** | Better looking slides but not editable | Create editable, slide-based presentations |
|
| **Presentation Generation** | Better looking slides but not editable | Create editable, slide-based presentations |
|
||||||
| **Podcast Generation** | Audio Overviews with customizable hosts and languages | Available with multiple TTS providers (NotebookLM is better here, actively improving) |
|
| **Podcast Generation** | Audio Overviews with customizable hosts and languages | Available with multiple TTS providers (NotebookLM is better here, actively improving) |
|
||||||
|
| **Desktop App** | No | Native app with General Assist, Quick Assist, and Extreme Assist — AI help in any application |
|
||||||
| **Browser Extension** | No | Cross-browser extension to save any webpage, including auth-protected pages |
|
| **Browser Extension** | No | Cross-browser extension to save any webpage, including auth-protected pages |
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ O NotebookLM é uma das melhores e mais úteis plataformas de IA disponíveis, m
|
||||||
- **Sem Dependência de Fornecedor** - Configure qualquer modelo LLM, de imagem, TTS e STT.
|
- **Sem Dependência de Fornecedor** - Configure qualquer modelo LLM, de imagem, TTS e STT.
|
||||||
- **25+ Fontes de Dados Externas** - Adicione suas fontes do Google Drive, OneDrive, Dropbox, Notion e muitos outros serviços externos.
|
- **25+ Fontes de Dados Externas** - Adicione suas fontes do Google Drive, OneDrive, Dropbox, Notion e muitos outros serviços externos.
|
||||||
- **Suporte Multiplayer em Tempo Real** - Trabalhe facilmente com os membros da sua equipe em um notebook compartilhado.
|
- **Suporte Multiplayer em Tempo Real** - Trabalhe facilmente com os membros da sua equipe em um notebook compartilhado.
|
||||||
|
- **Aplicativo Desktop** - Obtenha assistência de IA em qualquer aplicativo com Quick Assist, General Assist e Extreme Assist.
|
||||||
|
|
||||||
...e mais por vir.
|
...e mais por vir.
|
||||||
|
|
||||||
|
|
@ -130,6 +131,18 @@ O script de instalação configura o [Watchtower](https://github.com/nicholas-fe
|
||||||
|
|
||||||
Para Docker Compose, instalação manual e outras opções de implantação, consulte a [documentação](https://www.surfsense.com/docs/).
|
Para Docker Compose, instalação manual e outras opções de implantação, consulte a [documentação](https://www.surfsense.com/docs/).
|
||||||
|
|
||||||
|
### Aplicativo Desktop
|
||||||
|
|
||||||
|
O SurfSense também oferece um aplicativo desktop que traz assistência de IA para cada aplicativo no seu computador. Baixe-o na [última versão](https://github.com/MODSetter/SurfSense/releases/latest).
|
||||||
|
|
||||||
|
O aplicativo desktop inclui três recursos poderosos:
|
||||||
|
|
||||||
|
- **General Assist** — Abra o SurfSense instantaneamente de qualquer aplicativo com um atalho global.
|
||||||
|
- **Quick Assist** — Selecione texto em qualquer lugar, depois peça à IA para explicar, reescrever ou agir sobre ele.
|
||||||
|
- **Extreme Assist** — Receba sugestões de escrita em linha alimentadas pela sua base de conhecimento enquanto digita em qualquer aplicativo.
|
||||||
|
|
||||||
|
Os três recursos operam no espaço de busca escolhido, para que suas respostas sejam sempre baseadas nos seus próprios dados.
|
||||||
|
|
||||||
### Como Colaborar em Tempo Real (Beta)
|
### Como Colaborar em Tempo Real (Beta)
|
||||||
|
|
||||||
1. Acesse a página de Gerenciar Membros e crie um convite.
|
1. Acesse a página de Gerenciar Membros e crie um convite.
|
||||||
|
|
@ -174,6 +187,7 @@ Para Docker Compose, instalação manual e outras opções de implantação, con
|
||||||
| **Geração de Vídeos** | Visões gerais cinemáticas via Veo 3 (apenas Ultra) | Disponível (NotebookLM é melhor aqui, melhorando ativamente) |
|
| **Geração de Vídeos** | Visões gerais cinemáticas via Veo 3 (apenas Ultra) | Disponível (NotebookLM é melhor aqui, melhorando ativamente) |
|
||||||
| **Geração de Apresentações** | Slides mais bonitos mas não editáveis | Cria apresentações editáveis baseadas em slides |
|
| **Geração de Apresentações** | Slides mais bonitos mas não editáveis | Cria apresentações editáveis baseadas em slides |
|
||||||
| **Geração de Podcasts** | Visões gerais em áudio com hosts e idiomas personalizáveis | Disponível com múltiplos provedores TTS (NotebookLM é melhor aqui, melhorando ativamente) |
|
| **Geração de Podcasts** | Visões gerais em áudio com hosts e idiomas personalizáveis | Disponível com múltiplos provedores TTS (NotebookLM é melhor aqui, melhorando ativamente) |
|
||||||
|
| **Aplicativo Desktop** | Não | Aplicativo nativo com General Assist, Quick Assist e Extreme Assist — assistência de IA em qualquer aplicativo |
|
||||||
| **Extensão de Navegador** | Não | Extensão multi-navegador para salvar qualquer página web, incluindo páginas protegidas por autenticação |
|
| **Extensão de Navegador** | Não | Extensão multi-navegador para salvar qualquer página web, incluindo páginas protegidas por autenticação |
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ NotebookLM 是目前最好、最实用的 AI 平台之一,但当你开始经
|
||||||
- **无供应商锁定** - 配置任何 LLM、图像、TTS 和 STT 模型。
|
- **无供应商锁定** - 配置任何 LLM、图像、TTS 和 STT 模型。
|
||||||
- **25+ 外部数据源** - 从 Google Drive、OneDrive、Dropbox、Notion 和许多其他外部服务添加你的来源。
|
- **25+ 外部数据源** - 从 Google Drive、OneDrive、Dropbox、Notion 和许多其他外部服务添加你的来源。
|
||||||
- **实时多人协作支持** - 在共享笔记本中轻松与团队成员协作。
|
- **实时多人协作支持** - 在共享笔记本中轻松与团队成员协作。
|
||||||
|
- **桌面应用** - 通过 Quick Assist、General Assist 和 Extreme Assist 在任何应用程序中获得 AI 助手。
|
||||||
|
|
||||||
...更多功能即将推出。
|
...更多功能即将推出。
|
||||||
|
|
||||||
|
|
@ -130,6 +131,18 @@ irm https://raw.githubusercontent.com/MODSetter/SurfSense/main/docker/scripts/in
|
||||||
|
|
||||||
如需 Docker Compose、手动安装及其他部署方式,请查看[文档](https://www.surfsense.com/docs/)。
|
如需 Docker Compose、手动安装及其他部署方式,请查看[文档](https://www.surfsense.com/docs/)。
|
||||||
|
|
||||||
|
### 桌面应用
|
||||||
|
|
||||||
|
SurfSense 还提供桌面应用,将 AI 助手带到您计算机上的每个应用程序中。从[最新版本](https://github.com/MODSetter/SurfSense/releases/latest)下载。
|
||||||
|
|
||||||
|
桌面应用包含三个强大功能:
|
||||||
|
|
||||||
|
- **General Assist** — 通过全局快捷键从任何应用程序即时启动 SurfSense。
|
||||||
|
- **Quick Assist** — 在任何位置选中文本,然后让 AI 解释、改写或对其执行操作。
|
||||||
|
- **Extreme Assist** — 在任何应用中输入时,获得基于您知识库的内联写作建议。
|
||||||
|
|
||||||
|
三个功能均基于您选择的搜索空间运行,确保回答始终以您自己的数据为依据。
|
||||||
|
|
||||||
### 如何实时协作(Beta)
|
### 如何实时协作(Beta)
|
||||||
|
|
||||||
1. 前往成员管理页面并创建邀请。
|
1. 前往成员管理页面并创建邀请。
|
||||||
|
|
@ -174,6 +187,7 @@ irm https://raw.githubusercontent.com/MODSetter/SurfSense/main/docker/scripts/in
|
||||||
| **视频生成** | 通过 Veo 3 的电影级视频概览(仅 Ultra) | 可用(NotebookLM 在此方面更好,正在积极改进) |
|
| **视频生成** | 通过 Veo 3 的电影级视频概览(仅 Ultra) | 可用(NotebookLM 在此方面更好,正在积极改进) |
|
||||||
| **演示文稿生成** | 更美观的幻灯片但不可编辑 | 创建可编辑的幻灯片式演示文稿 |
|
| **演示文稿生成** | 更美观的幻灯片但不可编辑 | 创建可编辑的幻灯片式演示文稿 |
|
||||||
| **播客生成** | 可自定义主持人和语言的音频概览 | 可用,支持多种 TTS 提供商(NotebookLM 在此方面更好,正在积极改进) |
|
| **播客生成** | 可自定义主持人和语言的音频概览 | 可用,支持多种 TTS 提供商(NotebookLM 在此方面更好,正在积极改进) |
|
||||||
|
| **桌面应用** | 否 | 原生应用,包含 General Assist、Quick Assist 和 Extreme Assist — 在任何应用程序中获得 AI 助手 |
|
||||||
| **浏览器扩展** | 否 | 跨浏览器扩展,保存任何网页,包括需要身份验证的页面 |
|
| **浏览器扩展** | 否 | 跨浏览器扩展,保存任何网页,包括需要身份验证的页面 |
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,11 @@ import { useEffect } from "react";
|
||||||
import { HeroSection } from "@/components/homepage/hero-section";
|
import { HeroSection } from "@/components/homepage/hero-section";
|
||||||
import { getBearerToken } from "@/lib/auth-utils";
|
import { getBearerToken } from "@/lib/auth-utils";
|
||||||
|
|
||||||
|
const WhySurfSense = dynamic(
|
||||||
|
() => import("@/components/homepage/why-surfsense").then((m) => ({ default: m.WhySurfSense })),
|
||||||
|
{ ssr: false }
|
||||||
|
);
|
||||||
|
|
||||||
const FeaturesCards = dynamic(
|
const FeaturesCards = dynamic(
|
||||||
() => import("@/components/homepage/features-card").then((m) => ({ default: m.FeaturesCards })),
|
() => import("@/components/homepage/features-card").then((m) => ({ default: m.FeaturesCards })),
|
||||||
{ ssr: false }
|
{ ssr: false }
|
||||||
|
|
@ -40,6 +45,7 @@ export default function HomePage() {
|
||||||
return (
|
return (
|
||||||
<main className="min-h-screen bg-gradient-to-b from-gray-50 to-gray-100 text-gray-900 dark:from-black dark:to-gray-900 dark:text-white">
|
<main className="min-h-screen bg-gradient-to-b from-gray-50 to-gray-100 text-gray-900 dark:from-black dark:to-gray-900 dark:text-white">
|
||||||
<HeroSection />
|
<HeroSection />
|
||||||
|
<WhySurfSense />
|
||||||
<FeaturesCards />
|
<FeaturesCards />
|
||||||
<FeaturesBentoGrid />
|
<FeaturesBentoGrid />
|
||||||
<ExternalIntegrations />
|
<ExternalIntegrations />
|
||||||
|
|
|
||||||
446
surfsense_web/components/homepage/why-surfsense.tsx
Normal file
446
surfsense_web/components/homepage/why-surfsense.tsx
Normal file
|
|
@ -0,0 +1,446 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useRef, useState } from "react";
|
||||||
|
import { motion, useInView } from "motion/react";
|
||||||
|
import { IconPointerFilled } from "@tabler/icons-react";
|
||||||
|
import { Check, X } from "lucide-react";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { Separator } from "@/components/ui/separator";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const cards = [
|
||||||
|
{
|
||||||
|
title: "Unlimited & Self-Hosted",
|
||||||
|
description:
|
||||||
|
"No caps on sources, notebooks, or file sizes. Deploy on your own infra and your data never leaves your control.",
|
||||||
|
skeleton: <UnlimitedSkeleton />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "100+ LLMs, Zero Lock-in",
|
||||||
|
description:
|
||||||
|
"Swap between 100+ LLMs via OpenAI spec and LiteLLM, or run fully private with vLLM, Ollama, and more.",
|
||||||
|
skeleton: <LLMFlexibilitySkeleton />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Real-Time Multiplayer",
|
||||||
|
description:
|
||||||
|
"RBAC with Owner, Admin, Editor, and Viewer roles plus real-time chat and comment threads. Built for teams.",
|
||||||
|
skeleton: <MultiplayerSkeleton />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export function WhySurfSense() {
|
||||||
|
return (
|
||||||
|
<section className="px-4 py-10 md:px-8 md:py-24 lg:px-16 lg:py-32">
|
||||||
|
<div className="mx-auto mb-10 max-w-3xl text-center md:mb-16">
|
||||||
|
<p className="mb-3 text-sm font-semibold uppercase tracking-widest text-brand">
|
||||||
|
Why SurfSense
|
||||||
|
</p>
|
||||||
|
<h2 className="text-balance text-3xl font-bold tracking-tight text-foreground sm:text-4xl lg:text-5xl">
|
||||||
|
Everything NotebookLM should have been
|
||||||
|
</h2>
|
||||||
|
<p className="mx-auto mt-4 max-w-2xl text-base text-muted-foreground">
|
||||||
|
Open source. No data limits. No vendor lock-in. Built for teams that
|
||||||
|
care about privacy and flexibility.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mx-auto grid w-full max-w-6xl grid-cols-1 divide-x-0 divide-y divide-border overflow-hidden rounded-2xl shadow-sm ring-1 ring-border md:grid-cols-3 md:divide-x md:divide-y-0">
|
||||||
|
{cards.map((card) => (
|
||||||
|
<FeatureCard key={card.title} {...card} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ComparisonStrip />
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function UnlimitedSkeleton({ className }: { className?: string }) {
|
||||||
|
const ref = useRef(null);
|
||||||
|
const isInView = useInView(ref, { once: true, margin: "-50px" });
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{ label: "Sources", notebookLm: "50-600", surfSense: "Unlimited", icon: "📄" },
|
||||||
|
{ label: "Notebooks", notebookLm: "100-500", surfSense: "Unlimited", icon: "📓" },
|
||||||
|
{ label: "File size", notebookLm: "200 MB", surfSense: "No limit", icon: "📦" },
|
||||||
|
{ label: "Self-host", notebookLm: "No", surfSense: "Yes", icon: "🏠" },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn("flex h-full flex-col justify-center gap-2.5", className)}
|
||||||
|
>
|
||||||
|
{items.map((item, index) => (
|
||||||
|
<motion.div
|
||||||
|
key={item.label}
|
||||||
|
initial={{ opacity: 0, x: -16 }}
|
||||||
|
animate={isInView ? { opacity: 1, x: 0 } : {}}
|
||||||
|
transition={{ duration: 0.35, delay: index * 0.15 }}
|
||||||
|
className="flex items-center gap-2 rounded-lg bg-background px-3 py-2 shadow-sm ring-1 ring-border"
|
||||||
|
>
|
||||||
|
<span className="text-sm">{item.icon}</span>
|
||||||
|
<span className="min-w-[60px] text-xs font-medium text-foreground">
|
||||||
|
{item.label}
|
||||||
|
</span>
|
||||||
|
<div className="ml-auto flex items-center gap-2">
|
||||||
|
<span className="text-[10px] text-muted-foreground line-through">
|
||||||
|
{item.notebookLm}
|
||||||
|
</span>
|
||||||
|
<motion.div
|
||||||
|
initial={{ scale: 0.8 }}
|
||||||
|
animate={isInView ? { scale: 1 } : {}}
|
||||||
|
transition={{
|
||||||
|
duration: 0.3,
|
||||||
|
delay: index * 0.15 + 0.2,
|
||||||
|
type: "spring",
|
||||||
|
stiffness: 300,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Badge variant="secondary" className="text-[10px] px-1.5 py-0">
|
||||||
|
{item.surfSense}
|
||||||
|
</Badge>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function LLMFlexibilitySkeleton({ className }: { className?: string }) {
|
||||||
|
const ref = useRef(null);
|
||||||
|
const isInView = useInView(ref, { once: true, margin: "-50px" });
|
||||||
|
const [selected, setSelected] = useState(0);
|
||||||
|
|
||||||
|
const models = [
|
||||||
|
{ name: "GPT-4o", provider: "OpenAI", color: "bg-green-500" },
|
||||||
|
{ name: "Claude 4", provider: "Anthropic", color: "bg-orange-500" },
|
||||||
|
{ name: "Gemini 2.5", provider: "Google", color: "bg-blue-500" },
|
||||||
|
{ name: "Llama 4", provider: "Local", color: "bg-purple-500" },
|
||||||
|
{ name: "DeepSeek R1", provider: "DeepSeek", color: "bg-cyan-500" },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-full flex-col items-center justify-center gap-3",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 8 }}
|
||||||
|
animate={isInView ? { opacity: 1, y: 0 } : {}}
|
||||||
|
transition={{ duration: 0.3 }}
|
||||||
|
className="flex w-full max-w-[180px] flex-col gap-1.5"
|
||||||
|
>
|
||||||
|
{models.map((model, index) => (
|
||||||
|
<motion.button
|
||||||
|
key={model.name}
|
||||||
|
type="button"
|
||||||
|
onClick={() => setSelected(index)}
|
||||||
|
initial={{ opacity: 0, x: 12 }}
|
||||||
|
animate={isInView ? { opacity: 1, x: 0 } : {}}
|
||||||
|
transition={{ duration: 0.3, delay: 0.1 + index * 0.1 }}
|
||||||
|
className={cn(
|
||||||
|
"flex w-full cursor-pointer items-center gap-2 rounded-lg px-2.5 py-1.5 text-left transition-all",
|
||||||
|
selected === index
|
||||||
|
? "bg-background shadow-sm ring-1 ring-border"
|
||||||
|
: "hover:bg-accent",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className={cn("size-2 shrink-0 rounded-full", model.color)} />
|
||||||
|
<div className="min-w-0">
|
||||||
|
<p className="truncate text-xs font-medium text-foreground">
|
||||||
|
{model.name}
|
||||||
|
</p>
|
||||||
|
<p className="text-[10px] text-muted-foreground">
|
||||||
|
{model.provider}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{selected === index && (
|
||||||
|
<motion.div
|
||||||
|
layoutId="model-check"
|
||||||
|
className="ml-auto"
|
||||||
|
transition={{ type: "spring", stiffness: 400, damping: 25 }}
|
||||||
|
>
|
||||||
|
<Check className="size-3 text-brand" />
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</motion.button>
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function MultiplayerSkeleton({ className }: { className?: string }) {
|
||||||
|
const ref = useRef(null);
|
||||||
|
const isInView = useInView(ref, { once: true, margin: "-50px" });
|
||||||
|
|
||||||
|
const collaborators = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Alice",
|
||||||
|
role: "Editor",
|
||||||
|
color: "#3b82f6",
|
||||||
|
path: [
|
||||||
|
{ x: 15, y: 10 },
|
||||||
|
{ x: 80, y: 40 },
|
||||||
|
{ x: 40, y: 80 },
|
||||||
|
{ x: 15, y: 10 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Bob",
|
||||||
|
role: "Viewer",
|
||||||
|
color: "#10b981",
|
||||||
|
path: [
|
||||||
|
{ x: 115, y: 70 },
|
||||||
|
{ x: 55, y: 20 },
|
||||||
|
{ x: 95, y: 50 },
|
||||||
|
{ x: 115, y: 70 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const codeLines = [
|
||||||
|
{ indent: 0, width: "60%", color: "bg-chart-4/60" },
|
||||||
|
{ indent: 1, width: "75%", color: "bg-muted-foreground/20" },
|
||||||
|
{ indent: 1, width: "50%", color: "bg-chart-1/60" },
|
||||||
|
{ indent: 2, width: "80%", color: "bg-muted-foreground/20" },
|
||||||
|
{ indent: 2, width: "45%", color: "bg-chart-2/60" },
|
||||||
|
{ indent: 1, width: "30%", color: "bg-muted-foreground/20" },
|
||||||
|
{ indent: 0, width: "20%", color: "bg-chart-4/60" },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex h-full items-center justify-center overflow-visible",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<motion.div
|
||||||
|
className="relative w-full max-w-[160px] rounded-lg bg-background p-3 shadow-sm ring-1 ring-border"
|
||||||
|
initial={{ opacity: 0, y: 10 }}
|
||||||
|
animate={isInView ? { opacity: 1, y: 0 } : {}}
|
||||||
|
transition={{ duration: 0.4 }}
|
||||||
|
>
|
||||||
|
<div className="mb-2 flex items-center gap-1.5">
|
||||||
|
<div className="flex gap-1">
|
||||||
|
<div className="size-1.5 rounded-full bg-red-400" />
|
||||||
|
<div className="size-1.5 rounded-full bg-yellow-400" />
|
||||||
|
<div className="size-1.5 rounded-full bg-green-400" />
|
||||||
|
</div>
|
||||||
|
<div className="ml-2 h-1.5 w-12 rounded-full bg-muted" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{codeLines.map((line, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="my-1.5 flex items-center"
|
||||||
|
style={{ paddingLeft: line.indent * 8 }}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={cn("h-1.5 rounded-full", line.color)}
|
||||||
|
style={{ width: line.width }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{collaborators.map((collaborator, index) => (
|
||||||
|
<motion.div
|
||||||
|
key={collaborator.id}
|
||||||
|
className="absolute"
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={
|
||||||
|
isInView
|
||||||
|
? {
|
||||||
|
opacity: 1,
|
||||||
|
x: collaborator.path.map((p) => p.x),
|
||||||
|
y: collaborator.path.map((p) => p.y),
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
transition={{
|
||||||
|
opacity: { duration: 0.3, delay: 0.5 + index * 0.2 },
|
||||||
|
x: {
|
||||||
|
duration: 6,
|
||||||
|
delay: 0.5 + index * 0.3,
|
||||||
|
repeat: Infinity,
|
||||||
|
ease: "easeInOut",
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
duration: 6,
|
||||||
|
delay: 0.5 + index * 0.3,
|
||||||
|
repeat: Infinity,
|
||||||
|
ease: "easeInOut",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<IconPointerFilled
|
||||||
|
className="size-5 drop-shadow-sm"
|
||||||
|
style={{ color: collaborator.color }}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className="absolute top-5 left-3 z-50 flex w-max items-center gap-1.5 rounded-full py-1 pr-2.5 pl-1 shadow-sm"
|
||||||
|
style={{ backgroundColor: collaborator.color }}
|
||||||
|
>
|
||||||
|
<div className="flex size-5 items-center justify-center rounded-full bg-white/20 text-[9px] font-bold text-white">
|
||||||
|
{collaborator.name[0]}
|
||||||
|
</div>
|
||||||
|
<span className="shrink-0 text-[10px] font-medium text-white">
|
||||||
|
{collaborator.name}
|
||||||
|
</span>
|
||||||
|
<span className="rounded bg-white/20 px-1 py-px text-[8px] text-white/80">
|
||||||
|
{collaborator.role}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function FeatureCard({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
skeleton,
|
||||||
|
}: {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
skeleton: React.ReactNode;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="flex h-full flex-col justify-between bg-card p-10 first:rounded-l-2xl last:rounded-r-2xl">
|
||||||
|
<div className="h-60 w-full overflow-visible rounded-md">{skeleton}</div>
|
||||||
|
<div className="mt-4">
|
||||||
|
<h3 className="text-base font-bold tracking-tight text-card-foreground">
|
||||||
|
{title}
|
||||||
|
</h3>
|
||||||
|
<p className="mt-2 text-sm leading-relaxed tracking-tight text-muted-foreground">
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const comparisonRows: {
|
||||||
|
feature: string;
|
||||||
|
notebookLm: string | boolean;
|
||||||
|
surfSense: string | boolean;
|
||||||
|
}[] = [
|
||||||
|
{
|
||||||
|
feature: "Sources per Notebook",
|
||||||
|
notebookLm: "50-600",
|
||||||
|
surfSense: "Unlimited",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
feature: "LLM Support",
|
||||||
|
notebookLm: "Gemini only",
|
||||||
|
surfSense: "100+ LLMs",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
feature: "Self-Hostable",
|
||||||
|
notebookLm: false,
|
||||||
|
surfSense: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
feature: "Open Source",
|
||||||
|
notebookLm: false,
|
||||||
|
surfSense: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
feature: "External Connectors",
|
||||||
|
notebookLm: "Limited",
|
||||||
|
surfSense: "27+",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
feature: "Desktop App",
|
||||||
|
notebookLm: false,
|
||||||
|
surfSense: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
feature: "Agentic Architecture",
|
||||||
|
notebookLm: false,
|
||||||
|
surfSense: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function ComparisonStrip() {
|
||||||
|
const ref = useRef(null);
|
||||||
|
const isInView = useInView(ref, { once: true, margin: "-80px" });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
ref={ref}
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={isInView ? { opacity: 1, y: 0 } : {}}
|
||||||
|
transition={{ duration: 0.5, delay: 0.1 }}
|
||||||
|
className="mx-auto mt-12 w-full max-w-4xl overflow-hidden rounded-2xl bg-card shadow-sm ring-1 ring-border"
|
||||||
|
>
|
||||||
|
<div className="grid grid-cols-3 px-4 py-3 sm:px-6">
|
||||||
|
<span className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
||||||
|
Feature
|
||||||
|
</span>
|
||||||
|
<span className="text-center text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
||||||
|
NotebookLM
|
||||||
|
</span>
|
||||||
|
<span className="text-center text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
||||||
|
SurfSense
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Separator />
|
||||||
|
|
||||||
|
{comparisonRows.map((row, index) => (
|
||||||
|
<motion.div
|
||||||
|
key={row.feature}
|
||||||
|
initial={{ opacity: 0, x: -10 }}
|
||||||
|
animate={isInView ? { opacity: 1, x: 0 } : {}}
|
||||||
|
transition={{ duration: 0.3, delay: 0.15 + index * 0.06 }}
|
||||||
|
>
|
||||||
|
<div className="grid grid-cols-3 items-center px-4 py-2.5 text-sm sm:px-6">
|
||||||
|
<span className="font-medium text-card-foreground">
|
||||||
|
{row.feature}
|
||||||
|
</span>
|
||||||
|
<span className="flex justify-center">
|
||||||
|
{typeof row.notebookLm === "boolean" ? (
|
||||||
|
row.notebookLm ? (
|
||||||
|
<Check className="size-4 text-brand" />
|
||||||
|
) : (
|
||||||
|
<X className="size-4 text-muted-foreground/40" />
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<span className="text-muted-foreground">
|
||||||
|
{row.notebookLm}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<span className="flex justify-center">
|
||||||
|
{typeof row.surfSense === "boolean" ? (
|
||||||
|
row.surfSense ? (
|
||||||
|
<Check className="size-4 text-brand" />
|
||||||
|
) : (
|
||||||
|
<X className="size-4 text-muted-foreground/40" />
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<Badge variant="secondary">{row.surfSense}</Badge>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{index !== comparisonRows.length - 1 && (
|
||||||
|
<Separator />
|
||||||
|
)}
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue