feat(branding): dark-mode logo variant
Add an optional dark-mode logo (branding_logo_url_dark) alongside the main logo. Upload/remove via the logo endpoint (?variant=dark) on the Branding settings page. Admin header (admin dark mode) and the public gallery (dark themes) pick the dark logo when active, falling back to the light logo when unset. PDFs keep using the light logo.
This commit is contained in:
@@ -544,9 +544,16 @@ router.post('/logo', adminAuth, requirePermission('settings.edit'), upload.singl
|
||||
return res.status(400).json({ error: 'No logo file uploaded' });
|
||||
}
|
||||
|
||||
// ?variant=dark stores a separate dark-mode logo (branding_logo_*_dark);
|
||||
// anything else is the default (light) logo. Consumers pick the dark
|
||||
// variant when the active theme is dark, falling back to the light one.
|
||||
const isDark = req.query.variant === 'dark' || req.body.variant === 'dark';
|
||||
const pathKey = isDark ? 'branding_logo_path_dark' : 'branding_logo_path';
|
||||
const urlKey = isDark ? 'branding_logo_url_dark' : 'branding_logo_url';
|
||||
|
||||
// Get old logo to delete
|
||||
const oldLogoSetting = await db('app_settings')
|
||||
.where('setting_key', 'branding_logo_path')
|
||||
.where('setting_key', pathKey)
|
||||
.first();
|
||||
|
||||
if (oldLogoSetting && oldLogoSetting.setting_value) {
|
||||
@@ -568,7 +575,7 @@ router.post('/logo', adminAuth, requirePermission('settings.edit'), upload.singl
|
||||
|
||||
await db('app_settings')
|
||||
.insert({
|
||||
setting_key: 'branding_logo_path',
|
||||
setting_key: pathKey,
|
||||
setting_value: JSON.stringify(logoPath),
|
||||
setting_type: 'branding',
|
||||
updated_at: new Date()
|
||||
@@ -582,7 +589,7 @@ router.post('/logo', adminAuth, requirePermission('settings.edit'), upload.singl
|
||||
// Save public URL
|
||||
await db('app_settings')
|
||||
.insert({
|
||||
setting_key: 'branding_logo_url',
|
||||
setting_key: urlKey,
|
||||
setting_value: JSON.stringify(publicPath),
|
||||
setting_type: 'branding',
|
||||
updated_at: new Date()
|
||||
@@ -603,6 +610,36 @@ router.post('/logo', adminAuth, requirePermission('settings.edit'), upload.singl
|
||||
}
|
||||
});
|
||||
|
||||
// Remove a logo. ?variant=dark clears the dark-mode logo
|
||||
// (branding_logo_*_dark); otherwise the default logo. Best-effort file
|
||||
// unlink, then blanks the url + path settings.
|
||||
router.delete('/logo', adminAuth, requirePermission('settings.edit'), async (req, res) => {
|
||||
try {
|
||||
const isDark = req.query.variant === 'dark';
|
||||
const pathKey = isDark ? 'branding_logo_path_dark' : 'branding_logo_path';
|
||||
const urlKey = isDark ? 'branding_logo_url_dark' : 'branding_logo_url';
|
||||
|
||||
const pathSetting = await db('app_settings').where('setting_key', pathKey).first();
|
||||
if (pathSetting && pathSetting.setting_value) {
|
||||
try {
|
||||
let p = pathSetting.setting_value;
|
||||
if (p.startsWith('"')) p = JSON.parse(p);
|
||||
await fs.unlink(p);
|
||||
} catch (error) {
|
||||
console.error('Failed to delete logo file:', error);
|
||||
}
|
||||
}
|
||||
await db('app_settings')
|
||||
.whereIn('setting_key', [pathKey, urlKey])
|
||||
.update({ setting_value: JSON.stringify(''), updated_at: new Date() });
|
||||
|
||||
res.json({ message: 'Logo removed' });
|
||||
} catch (error) {
|
||||
console.error('Logo delete error:', error);
|
||||
res.status(500).json({ error: 'Failed to remove logo' });
|
||||
}
|
||||
});
|
||||
|
||||
// Upload watermark logo
|
||||
router.post('/branding/watermark-logo', adminAuth, requirePermission('settings.edit'), upload.single('watermarkLogo'), async (req, res) => {
|
||||
try {
|
||||
|
||||
@@ -59,6 +59,7 @@ router.get('/', async (req, res) => {
|
||||
branding_watermark_size: settingsObject.branding_watermark_size || 15,
|
||||
branding_favicon_url: settingsObject.branding_favicon_url || '',
|
||||
branding_logo_url: settingsObject.branding_logo_url || '',
|
||||
branding_logo_url_dark: settingsObject.branding_logo_url_dark || '',
|
||||
branding_logo_size: settingsObject.branding_logo_size || 'medium',
|
||||
branding_logo_max_height: settingsObject.branding_logo_max_height || 48,
|
||||
branding_logo_position: settingsObject.branding_logo_position || 'left',
|
||||
|
||||
Reference in New Issue
Block a user