Landing page editor: logo/background/subtitle, markdown details page, editable disclaimer, photo shutter
This commit is contained in:
@@ -13,6 +13,7 @@ const PLAYLIST_LIVE = path.join(LIVE_DIR, 'playlist.live.json');
|
||||
const MODELS_LIVE = path.join(LIVE_DIR, 'models.live.json');
|
||||
const MODELS_SEED = path.join(DATA, 'models.json');
|
||||
const CHARS_LIVE = path.join(LIVE_DIR, 'characters.live.json');
|
||||
const LANDING_LIVE = path.join(LIVE_DIR, 'landing.live.json');
|
||||
|
||||
fs.mkdirSync(LIVE_DIR, { recursive: true });
|
||||
|
||||
@@ -32,6 +33,24 @@ let models = readJSON(MODELS_LIVE, null) || readJSON(MODELS_SEED, { models: [] }
|
||||
* faceTextureUrl, torsoTextureUrl, heightCm, scale } } } */
|
||||
let characters = readJSON(CHARS_LIVE, null) || { defaults: {}, byId: {} };
|
||||
|
||||
/* landing: end-user facing start screen + details page. All text is editable except
|
||||
* that the disclaimer is ALWAYS rendered (wording editable, presence is not). */
|
||||
const LANDING_DEFAULTS = {
|
||||
title: 'NEWBURY NIGHTS',
|
||||
subtitle: 'Point your phone at the Newbury Crests to reveal the hidden side of the town.',
|
||||
logoUrl: '',
|
||||
backgroundUrl: '',
|
||||
startButton: 'Start Ghost Watching',
|
||||
detailsButton: 'About this build',
|
||||
detailsTitle: 'About Newbury Nights',
|
||||
detailsMarkdown: 'Write about your build here.\n\nUse **bold**, *italic*, and blank lines for paragraphs.',
|
||||
disclaimer: 'Fan-made tribute experience. Not affiliated with, sponsored, or endorsed by the LEGO Group. LEGO® and Hidden Side™ are trademarks of the LEGO Group.',
|
||||
accent: '#51eaf1',
|
||||
textColor: '#e8ecff',
|
||||
overlay: 0.55,
|
||||
};
|
||||
let landing = Object.assign({}, LANDING_DEFAULTS, readJSON(LANDING_LIVE, null) || {});
|
||||
|
||||
const listeners = [];
|
||||
|
||||
function validateScene(s) {
|
||||
@@ -76,6 +95,17 @@ module.exports = {
|
||||
return scene;
|
||||
},
|
||||
getGhosts: () => ({ ghosts, gradients }),
|
||||
getLanding: () => landing,
|
||||
putLanding(l) {
|
||||
if (!l || typeof l !== 'object') throw new Error('landing must be object');
|
||||
const next = Object.assign({}, LANDING_DEFAULTS, l);
|
||||
// disclaimer may be reworded but never emptied — it protects the project
|
||||
if (!String(next.disclaimer || '').trim()) next.disclaimer = LANDING_DEFAULTS.disclaimer;
|
||||
landing = next;
|
||||
writeJSON(LANDING_LIVE, landing);
|
||||
listeners.forEach(f => f());
|
||||
return landing;
|
||||
},
|
||||
getCharacters: () => characters,
|
||||
putCharacters(c) {
|
||||
if (!c || typeof c !== 'object') throw new Error('characters must be object');
|
||||
|
||||
Reference in New Issue
Block a user