mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-12-18 20:04:17 +01:00
remove unused configs, add others
This commit is contained in:
parent
d70ec668f1
commit
82cf8cfde4
@ -440,21 +440,9 @@ public class ApplicationProperties {
|
||||
|
||||
@Data
|
||||
public static class Ui {
|
||||
private String appName;
|
||||
private String homeDescription;
|
||||
private String appNameNavbar;
|
||||
private List<String> languages;
|
||||
|
||||
public String getAppName() {
|
||||
return appName != null && appName.trim().length() > 0 ? appName : null;
|
||||
}
|
||||
|
||||
public String getHomeDescription() {
|
||||
return homeDescription != null && homeDescription.trim().length() > 0
|
||||
? homeDescription
|
||||
: null;
|
||||
}
|
||||
|
||||
public String getAppNameNavbar() {
|
||||
return appNameNavbar != null && appNameNavbar.trim().length() > 0
|
||||
? appNameNavbar
|
||||
|
||||
@ -72,14 +72,6 @@ public class SettingsController {
|
||||
// Update UI settings
|
||||
if (settings.containsKey("ui")) {
|
||||
Map<String, String> ui = (Map<String, String>) settings.get("ui");
|
||||
if (ui.containsKey("appName")) {
|
||||
GeneralUtils.saveKeyToSettings("ui.appName", ui.get("appName"));
|
||||
applicationProperties.getUi().setAppName(ui.get("appName"));
|
||||
}
|
||||
if (ui.containsKey("homeDescription")) {
|
||||
GeneralUtils.saveKeyToSettings("ui.homeDescription", ui.get("homeDescription"));
|
||||
applicationProperties.getUi().setHomeDescription(ui.get("homeDescription"));
|
||||
}
|
||||
if (ui.containsKey("appNameNavbar")) {
|
||||
GeneralUtils.saveKeyToSettings("ui.appNameNavbar", ui.get("appNameNavbar"));
|
||||
applicationProperties.getUi().setAppNameNavbar(ui.get("appNameNavbar"));
|
||||
|
||||
@ -51,9 +51,7 @@ public class ConfigController {
|
||||
configData.put("serverPort", appConfig.getServerPort());
|
||||
|
||||
// Extract values from ApplicationProperties
|
||||
configData.put("appName", applicationProperties.getUi().getAppName());
|
||||
configData.put("appNameNavbar", applicationProperties.getUi().getAppNameNavbar());
|
||||
configData.put("homeDescription", applicationProperties.getUi().getHomeDescription());
|
||||
configData.put("languages", applicationProperties.getUi().getLanguages());
|
||||
|
||||
// Security settings
|
||||
|
||||
@ -153,8 +153,6 @@ system:
|
||||
cleanupSystemTemp: false # Whether to clean broader system temp directory
|
||||
|
||||
ui:
|
||||
appName: '' # application's visible name
|
||||
homeDescription: '' # short description or tagline shown on the homepage
|
||||
appNameNavbar: '' # name displayed on the navigation bar
|
||||
languages: [] # If empty, all languages are enabled. To display only German and Polish ["de_DE", "pl_PL"]. British English is always enabled.
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import { SidebarProvider } from "./contexts/SidebarContext";
|
||||
import { PreferencesProvider } from "./contexts/PreferencesContext";
|
||||
import ErrorBoundary from "./components/shared/ErrorBoundary";
|
||||
import HomePage from "./pages/HomePage";
|
||||
import AppConfigLoader from "./components/shared/AppConfigLoader";
|
||||
|
||||
// Import global styles
|
||||
import "./styles/tailwind.css";
|
||||
@ -43,6 +44,7 @@ export default function App() {
|
||||
<PreferencesProvider>
|
||||
<RainbowThemeProvider>
|
||||
<ErrorBoundary>
|
||||
<AppConfigLoader />
|
||||
<FileContextProvider enableUrlSync={true} enablePersistence={true}>
|
||||
<NavigationProvider>
|
||||
<FilesModalProvider>
|
||||
|
||||
@ -6,6 +6,7 @@ import { useFileHandler } from '../../hooks/useFileHandler';
|
||||
import { useFileState } from '../../contexts/FileContext';
|
||||
import { useNavigationState, useNavigationActions } from '../../contexts/NavigationContext';
|
||||
import { useViewer } from '../../contexts/ViewerContext';
|
||||
import { useAppConfig } from '../../hooks/useAppConfig';
|
||||
import './Workbench.css';
|
||||
|
||||
import TopControls from '../shared/TopControls';
|
||||
@ -20,6 +21,7 @@ import DismissAllErrorsButton from '../shared/DismissAllErrorsButton';
|
||||
// No props needed - component uses contexts directly
|
||||
export default function Workbench() {
|
||||
const { isRainbowMode } = useRainbowThemeContext();
|
||||
const { config } = useAppConfig();
|
||||
|
||||
// Use context-based hooks to eliminate all prop drilling
|
||||
const { selectors } = useFileState();
|
||||
@ -180,7 +182,14 @@ export default function Workbench() {
|
||||
{renderMainContent()}
|
||||
</Box>
|
||||
|
||||
<Footer analyticsEnabled />
|
||||
<Footer
|
||||
analyticsEnabled={config?.enableAnalytics}
|
||||
termsAndConditions={config?.termsAndConditions}
|
||||
privacyPolicy={config?.privacyPolicy}
|
||||
cookiePolicy={config?.cookiePolicy}
|
||||
impressum={config?.impressum}
|
||||
accessibilityStatement={config?.accessibilityStatement}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
24
frontend/src/components/shared/AppConfigLoader.tsx
Normal file
24
frontend/src/components/shared/AppConfigLoader.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useAppConfig } from '../../hooks/useAppConfig';
|
||||
import { updateSupportedLanguages } from '../../i18n';
|
||||
|
||||
/**
|
||||
* Component that loads app configuration and applies it to the application.
|
||||
* This includes:
|
||||
* - Filtering available languages based on config.languages
|
||||
*
|
||||
* Place this component high in the component tree, after i18n has initialized.
|
||||
*/
|
||||
export default function AppConfigLoader() {
|
||||
const { config, loading } = useAppConfig();
|
||||
|
||||
useEffect(() => {
|
||||
if (!loading && config) {
|
||||
// Update supported languages if config specifies a language filter
|
||||
updateSupportedLanguages(config.languages);
|
||||
}
|
||||
}, [config, loading]);
|
||||
|
||||
// This component doesn't render anything
|
||||
return null;
|
||||
}
|
||||
@ -12,14 +12,19 @@ interface FooterProps {
|
||||
}
|
||||
|
||||
export default function Footer({
|
||||
privacyPolicy = '/privacy',
|
||||
termsAndConditions = '/terms',
|
||||
accessibilityStatement = 'accessibility',
|
||||
privacyPolicy,
|
||||
termsAndConditions,
|
||||
accessibilityStatement,
|
||||
cookiePolicy,
|
||||
impressum,
|
||||
analyticsEnabled = false
|
||||
}: FooterProps) {
|
||||
const { t } = useTranslation();
|
||||
const { showCookiePreferences } = useCookieConsent({ analyticsEnabled });
|
||||
|
||||
// Helper to check if a value is valid (not null/undefined/empty string)
|
||||
const isValidLink = (link?: string) => link && link.trim().length > 0;
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
height: 'var(--footer-height)',
|
||||
@ -43,7 +48,7 @@ export default function Footer({
|
||||
>
|
||||
{t('survey.nav', 'Survey')}
|
||||
</a>
|
||||
{privacyPolicy && (
|
||||
{isValidLink(privacyPolicy) && (
|
||||
<a
|
||||
className="footer-link px-3"
|
||||
target="_blank"
|
||||
@ -53,7 +58,7 @@ export default function Footer({
|
||||
{t('legal.privacy', 'Privacy Policy')}
|
||||
</a>
|
||||
)}
|
||||
{termsAndConditions && (
|
||||
{isValidLink(termsAndConditions) && (
|
||||
<a
|
||||
className="footer-link px-3"
|
||||
target="_blank"
|
||||
@ -63,7 +68,7 @@ export default function Footer({
|
||||
{t('legal.terms', 'Terms and Conditions')}
|
||||
</a>
|
||||
)}
|
||||
{accessibilityStatement && (
|
||||
{isValidLink(accessibilityStatement) && (
|
||||
<a
|
||||
className="footer-link px-3"
|
||||
target="_blank"
|
||||
@ -73,6 +78,26 @@ export default function Footer({
|
||||
{t('legal.accessibility', 'Accessibility')}
|
||||
</a>
|
||||
)}
|
||||
{isValidLink(cookiePolicy) && (
|
||||
<a
|
||||
className="footer-link px-3"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href={cookiePolicy}
|
||||
>
|
||||
{t('legal.cookiePolicy', 'Cookie Policy')}
|
||||
</a>
|
||||
)}
|
||||
{isValidLink(impressum) && (
|
||||
<a
|
||||
className="footer-link px-3"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href={impressum}
|
||||
>
|
||||
{t('legal.impressum', 'Impressum')}
|
||||
</a>
|
||||
)}
|
||||
{analyticsEnabled && (
|
||||
<button
|
||||
className="footer-link px-3"
|
||||
|
||||
@ -7,8 +7,6 @@ import { useRestartServer } from '../useRestartServer';
|
||||
|
||||
interface GeneralSettingsData {
|
||||
ui: {
|
||||
appName?: string;
|
||||
homeDescription?: string;
|
||||
appNameNavbar?: string;
|
||||
languages?: string[];
|
||||
};
|
||||
|
||||
@ -34,7 +34,6 @@ const Overview: React.FC = () => {
|
||||
};
|
||||
|
||||
const basicConfig = config ? {
|
||||
appName: config.appName,
|
||||
appNameNavbar: config.appNameNavbar,
|
||||
baseUrl: config.baseUrl,
|
||||
contextPath: config.contextPath,
|
||||
|
||||
@ -4,9 +4,7 @@ export interface AppConfig {
|
||||
baseUrl?: string;
|
||||
contextPath?: string;
|
||||
serverPort?: number;
|
||||
appName?: string;
|
||||
appNameNavbar?: string;
|
||||
homeDescription?: string;
|
||||
languages?: string[];
|
||||
enableLogin?: boolean;
|
||||
enableAlphaFunctionality?: boolean;
|
||||
|
||||
@ -104,4 +104,34 @@ i18n.on('languageChanged', (lng) => {
|
||||
document.documentElement.lang = lng;
|
||||
});
|
||||
|
||||
/**
|
||||
* Updates the supported languages list dynamically based on config
|
||||
* If configLanguages is null/empty, all languages remain available
|
||||
* Otherwise, only specified languages plus 'en-GB' fallback are enabled
|
||||
*/
|
||||
export function updateSupportedLanguages(configLanguages?: string[] | null) {
|
||||
if (!configLanguages || configLanguages.length === 0) {
|
||||
// No filter specified - keep all languages
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure fallback language is always included
|
||||
const languagesToSupport = new Set(['en-GB', ...configLanguages]);
|
||||
|
||||
// Filter to only valid language codes that exist in our translations
|
||||
const validLanguages = Array.from(languagesToSupport).filter(
|
||||
lang => lang in supportedLanguages
|
||||
);
|
||||
|
||||
if (validLanguages.length > 0) {
|
||||
i18n.options.supportedLngs = validLanguages;
|
||||
|
||||
// If current language is not in the new supported list, switch to fallback
|
||||
const currentLang = i18n.language;
|
||||
if (currentLang && !validLanguages.includes(currentLang)) {
|
||||
i18n.changeLanguage('en-GB');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default i18n;
|
||||
|
||||
@ -42,6 +42,7 @@ export default function HomePage() {
|
||||
|
||||
const { openFilesModal } = useFilesModalContext();
|
||||
const { colorScheme } = useMantineColorScheme();
|
||||
const { config } = useAppConfig();
|
||||
const isMobile = useMediaQuery("(max-width: 1024px)");
|
||||
const sliderRef = useRef<HTMLDivElement | null>(null);
|
||||
const [activeMobileView, setActiveMobileView] = useState<MobileView>("tools");
|
||||
@ -138,10 +139,11 @@ export default function HomePage() {
|
||||
const baseUrl = getBaseUrl();
|
||||
|
||||
// Update document meta when tool changes
|
||||
const appName = config?.appNameNavbar || 'Stirling PDF';
|
||||
useDocumentMeta({
|
||||
title: selectedTool ? `${selectedTool.name} - Stirling PDF` : 'Stirling PDF',
|
||||
title: selectedTool ? `${selectedTool.name} - ${appName}` : appName,
|
||||
description: selectedTool?.description || t('app.description', 'The Free Adobe Acrobat alternative (10M+ Downloads)'),
|
||||
ogTitle: selectedTool ? `${selectedTool.name} - Stirling PDF` : 'Stirling PDF',
|
||||
ogTitle: selectedTool ? `${selectedTool.name} - ${appName}` : appName,
|
||||
ogDescription: selectedTool?.description || t('app.description', 'The Free Adobe Acrobat alternative (10M+ Downloads)'),
|
||||
ogImage: selectedToolKey ? `${baseUrl}/og_images/${selectedToolKey}.png` : `${baseUrl}/og_images/home.png`,
|
||||
ogUrl: selectedTool ? `${baseUrl}${window.location.pathname}` : baseUrl
|
||||
|
||||
Loading…
Reference in New Issue
Block a user