diff --git a/playwright.config.ts b/playwright.config.ts
index 6cd95e5..07b27bb 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -16,6 +16,7 @@ if (process.env.CI === 'true') {
*/
export default defineConfig({
testDir: './tests',
+ testIgnore: '**/unit/**',
tsconfig: './tsconfig.json',
timeout: 30 * 1000,
outputDir: './tests/results',
@@ -60,7 +61,6 @@ export default defineConfig({
{
name: 'firefox',
- testIgnore: '**/unit/**',
use: {
...devices['Desktop Firefox'],
extraHTTPHeaders: { 'x-openreader-test-namespace': 'firefox' },
@@ -69,7 +69,6 @@ export default defineConfig({
{
name: 'webkit',
- testIgnore: '**/unit/**',
use: {
...devices['Desktop Safari'],
extraHTTPHeaders: { 'x-openreader-test-namespace': 'webkit' },
diff --git a/src/components/HomeContent.tsx b/src/components/HomeContent.tsx
index 8e9240f..e548230 100644
--- a/src/components/HomeContent.tsx
+++ b/src/components/HomeContent.tsx
@@ -1,7 +1,8 @@
'use client';
+import { useState } from 'react';
import { DocumentList } from '@/components/doclist/DocumentList';
-import { SettingsModal } from '@/components/SettingsModal';
+import { SettingsModal, SettingsTrigger } from '@/components/SettingsModal';
import { UserMenu } from '@/components/auth/UserMenu';
const Brand = () => (
@@ -14,20 +15,24 @@ const Brand = () => (
);
-const AppActions = () => (
-
-
-
-
-);
-
export function HomeContent() {
+ const [settingsOpen, setSettingsOpen] = useState(false);
+
+ const appActions = (
+
+ setSettingsOpen(true)}
+ />
+
+
+ );
+
return (
-
} appActions={
} />
+
} appActions={appActions} />
+
);
}
diff --git a/src/components/SettingsModal.tsx b/src/components/SettingsModal.tsx
index 50fee42..330f452 100644
--- a/src/components/SettingsModal.tsx
+++ b/src/components/SettingsModal.tsx
@@ -130,19 +130,42 @@ const SIDEBAR_SECTIONS: SidebarSection[] = [
type AdminSubTab = 'providers' | 'features';
-export function SettingsModal({
+export function SettingsTrigger({
className = '',
triggerLabel,
+ onOpen,
}: {
className?: string;
triggerLabel?: string;
+ onOpen: () => void;
+}) {
+ return (
+
+ );
+}
+
+export function SettingsModal({
+ open,
+ onOpenChange,
+}: {
+ open: boolean;
+ onOpenChange: (open: boolean) => void;
}) {
const runtimeConfig = useRuntimeConfig();
const enableDestructiveDelete = runtimeConfig.enableDestructiveDeleteActions;
const showAllProviderModels = runtimeConfig.showAllProviderModels;
const enableTTSProvidersTab = runtimeConfig.enableTtsProvidersTab;
const restrictUserApiKeys = runtimeConfig.restrictUserApiKeys;
- const [isOpen, setIsOpen] = useState(false);
+ const isOpen = open;
+ const setIsOpen = onOpenChange;
const [isChangelogOpen, setIsChangelogOpen] = useState(false);
const [activeSection, setActiveSection] = useState(enableTTSProvidersTab ? 'api' : 'theme');
@@ -215,7 +238,7 @@ export function SettingsModal({
if (changelogOpenSignal <= 0) return;
setIsOpen(true);
setIsChangelogOpen(true);
- }, [changelogOpenSignal]);
+ }, [changelogOpenSignal, setIsOpen]);
useEffect(() => {
setLocalApiKey(apiKey);
@@ -409,7 +432,7 @@ export function SettingsModal({
} else {
setCustomModelInput('');
}
- }, [apiKey, baseUrl, providerRef, providerType, ttsModel, ttsInstructions, ttsModels]);
+ }, [apiKey, baseUrl, providerRef, providerType, ttsModel, ttsInstructions, ttsModels, setIsOpen]);
const [systemIsDark, setSystemIsDark] = useState(
typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches
@@ -489,19 +512,6 @@ export function SettingsModal({
return (
<>
-
-