mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-03 04:40:09 +00:00
95e63dfc36
Introduce ROOTLESS_CONTAINER env to opt out of gosu (replace /proc uid_map detection) and update entrypoint messaging; adjust app-start.sh and redis-start.sh to skip gosu when ROOTLESS_CONTAINER=true and warn on UID/GID mismatch only when applicable. Backend: include audiobook audibleAsin in admin requests response (mapped to asin) and pass baseUrl through test-flaresolverr endpoint to the FlareSolverr tester. Frontend: RecentRequestsTable and RequestActionsDropdown now surface asin, accept/passthrough annasArchiveBaseUrl, and add a "View Details" flow using AudiobookDetailsModal; admin page passes ebook baseUrl from settings. InteractiveTorrentSearchModal refactor: improved UX/UI, keyboard handling, portal/modal mounting, skeleton/loading states, formatting helpers, and richer result display. Tests updated to match changes.
122 lines
3.5 KiB
TypeScript
122 lines
3.5 KiB
TypeScript
/**
|
|
* Component: E-book Settings Tab - Custom Hook
|
|
* Documentation: documentation/settings-pages.md
|
|
*/
|
|
|
|
'use client';
|
|
|
|
import { useState } from 'react';
|
|
import { fetchWithAuth } from '@/lib/utils/api';
|
|
import type { EbookSettings, TestResult } from '../../lib/types';
|
|
|
|
interface UseEbookSettingsProps {
|
|
ebook: EbookSettings;
|
|
onChange: (ebook: EbookSettings) => void;
|
|
onSuccess: (message: string) => void;
|
|
onError: (message: string) => void;
|
|
markAsSaved: () => void;
|
|
}
|
|
|
|
export function useEbookSettings({ ebook, onChange, onSuccess, onError, markAsSaved }: UseEbookSettingsProps) {
|
|
const [saving, setSaving] = useState(false);
|
|
const [testingFlaresolverr, setTestingFlaresolverr] = useState(false);
|
|
const [flaresolverrTestResult, setFlaresolverrTestResult] = useState<TestResult | null>(null);
|
|
|
|
/**
|
|
* Update a single ebook field
|
|
*/
|
|
const updateEbook = (field: keyof EbookSettings, value: string | boolean) => {
|
|
onChange({ ...ebook, [field]: value });
|
|
if (field === 'flaresolverrUrl') {
|
|
setFlaresolverrTestResult(null);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Test FlareSolverr connection
|
|
*/
|
|
const testFlaresolverrConnection = async () => {
|
|
if (!ebook.flaresolverrUrl) {
|
|
setFlaresolverrTestResult({
|
|
success: false,
|
|
message: 'Please enter a FlareSolverr URL first',
|
|
});
|
|
return;
|
|
}
|
|
|
|
setTestingFlaresolverr(true);
|
|
setFlaresolverrTestResult(null);
|
|
|
|
try {
|
|
const response = await fetchWithAuth('/api/admin/settings/ebook/test-flaresolverr', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
url: ebook.flaresolverrUrl,
|
|
baseUrl: ebook.baseUrl || 'https://annas-archive.li',
|
|
}),
|
|
});
|
|
|
|
const result = await response.json();
|
|
setFlaresolverrTestResult(result);
|
|
} catch (error) {
|
|
setFlaresolverrTestResult({
|
|
success: false,
|
|
message: error instanceof Error ? error.message : 'Test failed',
|
|
});
|
|
} finally {
|
|
setTestingFlaresolverr(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Save e-book settings to API
|
|
*/
|
|
const saveSettings = async () => {
|
|
setSaving(true);
|
|
|
|
try {
|
|
const response = await fetchWithAuth('/api/admin/settings/ebook', {
|
|
method: 'PUT',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
annasArchiveEnabled: ebook.annasArchiveEnabled || false,
|
|
indexerSearchEnabled: ebook.indexerSearchEnabled || false,
|
|
format: ebook.preferredFormat || 'epub',
|
|
baseUrl: ebook.baseUrl || 'https://annas-archive.li',
|
|
flaresolverrUrl: ebook.flaresolverrUrl || '',
|
|
autoGrabEnabled: ebook.autoGrabEnabled ?? true,
|
|
kindleFixEnabled: ebook.kindleFixEnabled ?? false,
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error('Failed to save e-book settings');
|
|
}
|
|
|
|
onSuccess('E-book sidecar settings saved successfully!');
|
|
markAsSaved();
|
|
setTimeout(() => onSuccess(''), 3000);
|
|
} catch (error) {
|
|
onError(error instanceof Error ? error.message : 'Failed to save e-book settings');
|
|
} finally {
|
|
setSaving(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Helper to check if any ebook source is enabled
|
|
*/
|
|
const isAnySourceEnabled = ebook.annasArchiveEnabled || ebook.indexerSearchEnabled;
|
|
|
|
return {
|
|
saving,
|
|
testingFlaresolverr,
|
|
flaresolverrTestResult,
|
|
updateEbook,
|
|
testFlaresolverrConnection,
|
|
saveSettings,
|
|
isAnySourceEnabled,
|
|
};
|
|
}
|