Merge pull request #757 from PicPeak/fix/hero-logo-global-inherit-756
fix(branding): make 'Show logo in hero' a true global toggle with per-event override (#756)
This commit is contained in:
@@ -95,7 +95,7 @@ module.exports = (router) => {
|
||||
body('css_template_id').optional({ nullable: true, checkFalsy: true }).isInt(),
|
||||
// Hero logo settings
|
||||
body('hero_logo_visible').optional().isBoolean(),
|
||||
body('hero_logo_size').optional().isIn(['small', 'medium', 'large', 'xlarge']),
|
||||
body('hero_logo_size').optional({ nullable: true }).isIn(['small', 'medium', 'large', 'xlarge']),
|
||||
body('hero_logo_position').optional().isIn(['top', 'center', 'bottom']),
|
||||
// Header style settings (decoupled from layout)
|
||||
body('header_style').optional().isIn(['hero', 'standard', 'banner', 'minimal', 'none']),
|
||||
@@ -339,8 +339,16 @@ module.exports = (router) => {
|
||||
|
||||
// Get branding defaults for hero logo settings (Feature 7: Branding Inheritance)
|
||||
const brandingDefaults = await getBrandingDefaults();
|
||||
const effectiveHeroLogoVisible = req.body.hero_logo_visible !== undefined ? hero_logo_visible : brandingDefaults.hero_logo_visible;
|
||||
const effectiveHeroLogoSize = req.body.hero_logo_size || brandingDefaults.hero_logo_size;
|
||||
// hero_logo_visible: store NULL ("inherit") unless the admin explicitly
|
||||
// set it, so the global branding_logo_display_hero toggle keeps
|
||||
// controlling this gallery afterwards (#756). Only an explicit per-event
|
||||
// choice overrides the global.
|
||||
const effectiveHeroLogoVisible = req.body.hero_logo_visible !== undefined
|
||||
? formatBoolean(hero_logo_visible)
|
||||
: null;
|
||||
// NULL = inherit the global branding_logo_size (#756), resolved at read
|
||||
// time. Only an explicit per-event size overrides it.
|
||||
const effectiveHeroLogoSize = req.body.hero_logo_size || null;
|
||||
const effectiveHeroLogoPosition = req.body.hero_logo_position || brandingDefaults.hero_logo_position;
|
||||
|
||||
// Inherit "Detect dev tools" from the global Image Security setting unless
|
||||
@@ -425,7 +433,8 @@ module.exports = (router) => {
|
||||
allow_presigned_download: formatBoolean(allow_presigned_download === true || allow_presigned_download === 'true'),
|
||||
require_password: formatBoolean(requirePassword),
|
||||
css_template_id: css_template_id || null,
|
||||
hero_logo_visible: formatBoolean(effectiveHeroLogoVisible),
|
||||
// Already formatBoolean-coerced above, or null = inherit global (#756).
|
||||
hero_logo_visible: effectiveHeroLogoVisible,
|
||||
hero_logo_size: effectiveHeroLogoSize,
|
||||
hero_logo_position: effectiveHeroLogoPosition,
|
||||
header_style: effectiveHeaderStyle || 'standard',
|
||||
@@ -1216,7 +1225,7 @@ module.exports = (router) => {
|
||||
body('css_template_id').optional({ nullable: true, checkFalsy: true }).isInt(),
|
||||
// Hero logo settings
|
||||
body('hero_logo_visible').optional().isBoolean(),
|
||||
body('hero_logo_size').optional().isIn(['small', 'medium', 'large', 'xlarge']),
|
||||
body('hero_logo_size').optional({ nullable: true }).isIn(['small', 'medium', 'large', 'xlarge']),
|
||||
body('hero_logo_position').optional().isIn(['top', 'center', 'bottom']),
|
||||
// Header style settings (decoupled from layout)
|
||||
body('header_style').optional().isIn(['hero', 'standard', 'banner', 'minimal', 'none']),
|
||||
@@ -1424,9 +1433,13 @@ module.exports = (router) => {
|
||||
updates.expires_at = null;
|
||||
}
|
||||
|
||||
// Format hero logo settings if provided
|
||||
// Format hero logo settings if provided. null = inherit the global
|
||||
// branding_logo_display_hero toggle (#756); only an explicit true/false
|
||||
// is a per-event override.
|
||||
if (Object.prototype.hasOwnProperty.call(updates, 'hero_logo_visible')) {
|
||||
updates.hero_logo_visible = formatBoolean(updates.hero_logo_visible);
|
||||
updates.hero_logo_visible = updates.hero_logo_visible === null
|
||||
? null
|
||||
: formatBoolean(updates.hero_logo_visible);
|
||||
}
|
||||
|
||||
// Per-event opt-in for hero-photo OG share image (#474). Coerce so
|
||||
|
||||
@@ -2,9 +2,21 @@ const express = require('express');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const { db } = require('../database/db');
|
||||
const { formatBoolean } = require('../utils/dbCompat');
|
||||
const { getAppSetting } = require('../utils/appSettings');
|
||||
const archiver = require('archiver');
|
||||
const path = require('path');
|
||||
const router = express.Router();
|
||||
|
||||
// #756: a NULL per-event hero_logo_visible means "inherit the global
|
||||
// branding_logo_display_hero toggle". Only an explicit true/false is a
|
||||
// per-gallery override. `globalDefault` is branding_logo_display_hero
|
||||
// (defaults true when unset).
|
||||
function resolveHeroLogoVisible(perEvent, globalDefault) {
|
||||
if (perEvent === null || perEvent === undefined) {
|
||||
return globalDefault !== false;
|
||||
}
|
||||
return perEvent !== false && perEvent !== 0 && perEvent !== '0';
|
||||
}
|
||||
const watermarkService = require('../services/watermarkService');
|
||||
const watermarkGeneratorService = require('../services/watermarkGeneratorService');
|
||||
const { verifyGalleryAccess, denySlideshowToken, isAdminPreview } = require('../middleware/gallery');
|
||||
@@ -182,6 +194,8 @@ router.get('/:slug/info', async (req, res) => {
|
||||
}
|
||||
|
||||
const requiresPassword = !(event.require_password === false || event.require_password === 0 || event.require_password === '0');
|
||||
const globalHeroLogoVisible = await getAppSetting('branding_logo_display_hero', true);
|
||||
const globalLogoSize = await getAppSetting('branding_logo_size', 'medium');
|
||||
|
||||
res.json({
|
||||
event_name: event.event_name,
|
||||
@@ -199,8 +213,9 @@ router.get('/:slug/info', async (req, res) => {
|
||||
watermark_text: event.watermark_text,
|
||||
enable_devtools_protection: event.enable_devtools_protection === true || event.enable_devtools_protection === 1 || event.enable_devtools_protection === '1',
|
||||
use_canvas_rendering: event.use_canvas_rendering === true || event.use_canvas_rendering === 1 || event.use_canvas_rendering === '1',
|
||||
hero_logo_visible: event.hero_logo_visible !== false && event.hero_logo_visible !== 0 && event.hero_logo_visible !== '0',
|
||||
hero_logo_size: event.hero_logo_size || 'medium',
|
||||
hero_logo_visible: resolveHeroLogoVisible(event.hero_logo_visible, globalHeroLogoVisible),
|
||||
// #756: NULL per-event size inherits the global branding_logo_size.
|
||||
hero_logo_size: event.hero_logo_size || globalLogoSize || 'medium',
|
||||
hero_logo_position: event.hero_logo_position || 'top',
|
||||
hero_logo_url: event.hero_logo_url || null,
|
||||
header_style: event.header_style || 'standard',
|
||||
@@ -635,7 +650,8 @@ router.get('/:slug/photos', verifyGalleryAccess, resolveGuest, async (req, res)
|
||||
// selection back to source files. Tied to the same toggle as downloads —
|
||||
// one switch controls both surfaces.
|
||||
const useOriginalFilenames = await getUseOriginalFilenames();
|
||||
|
||||
const globalHeroLogoVisible = await getAppSetting('branding_logo_display_hero', true);
|
||||
const globalLogoSize = await getAppSetting('branding_logo_size', 'medium');
|
||||
|
||||
res.json({
|
||||
event: {
|
||||
@@ -654,8 +670,8 @@ router.get('/:slug/photos', verifyGalleryAccess, resolveGuest, async (req, res)
|
||||
watermark_text: req.event.watermark_text,
|
||||
enable_devtools_protection: req.event.enable_devtools_protection === true,
|
||||
use_canvas_rendering: req.event.use_canvas_rendering === true,
|
||||
hero_logo_visible: req.event.hero_logo_visible !== false && req.event.hero_logo_visible !== 0 && req.event.hero_logo_visible !== '0',
|
||||
hero_logo_size: req.event.hero_logo_size || 'medium',
|
||||
hero_logo_visible: resolveHeroLogoVisible(req.event.hero_logo_visible, globalHeroLogoVisible),
|
||||
hero_logo_size: req.event.hero_logo_size || globalLogoSize || 'medium',
|
||||
hero_logo_position: req.event.hero_logo_position || 'top',
|
||||
hero_logo_url: req.event.hero_logo_url || null,
|
||||
header_style: req.event.header_style || 'standard',
|
||||
|
||||
Reference in New Issue
Block a user