Add featured Dark House track with default landing ambient playback
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

Wire featured-dark-house-2025.mp3 as the default ambient source, enable BGM for first-time visitors, and attempt autoplay on Command Deck with gesture-unlock fallback. The ~57MB MP3 stays gitignored; copy instructions are in public/audio/.gitkeep.
This commit is contained in:
AetherForge
2026-06-07 03:56:47 -07:00
parent 5c6913dc5f
commit ab143fbfd2
7 changed files with 42 additions and 17 deletions

1
.gitignore vendored
View File

@@ -35,6 +35,7 @@
# Local media (not part of the product)
/music/
/server/web/public/audio/featured-dark-house-2025.mp3
# Temp downloads
*.crdownload

View File

@@ -1,2 +1,7 @@
# Drop your looping ambient track here as ambient.mp3 (MP3 preferred; OGG/WAV also work).
# Enable background music in Settings → Sound & Haptics after adding the file.
# Background music for the dashboard ambient player.
#
# Featured (default): featured-dark-house-2025.mp3 (~57MB — gitignored; copy locally)
# Copy-Item "music/DARK HOUSE 2025 Deep Hypnotic Electronic Experience.mp3" `
# "server/web/public/audio/featured-dark-house-2025.mp3"
#
# Legacy fallback: ambient.mp3 (smaller loops still work if you point AMBIENT_MUSIC_SRC at them).

View File

@@ -17,11 +17,16 @@ describe('ambientMusic prefs', () => {
localStorage.clear();
});
it('defaults music off and volume ~0.22', () => {
expect(loadBgmEnabled()).toBe(false);
it('defaults music on for first visit and volume ~0.22', () => {
expect(loadBgmEnabled()).toBe(true);
expect(loadBgmVolume()).toBeCloseTo(0.22);
});
it('respects explicit opt-out', () => {
localStorage.setItem(BGM_STORAGE_KEY, '0');
expect(loadBgmEnabled()).toBe(false);
});
it('persists enabled flag', () => {
const p = new AmbientMusicPlayer();
p.setEnabled(true);
@@ -38,8 +43,8 @@ describe('ambientMusic prefs', () => {
expect(localStorage.getItem(BGM_VOLUME_KEY)).toBe('0');
});
it('points at public audio path', () => {
expect(AMBIENT_MUSIC_SRC).toBe('/audio/ambient.mp3');
it('points at featured public audio path', () => {
expect(AMBIENT_MUSIC_SRC).toBe('/audio/featured-dark-house-2025.mp3');
});
it('ducks effective volume 30% while modal registered', () => {

View File

@@ -1,11 +1,14 @@
/**
* Looping background music — drop your MP3 at public/audio/ambient.mp3
* (MP3 preferred; OGG/WAV also work if you update AMBIENT_MUSIC_SRC).
* Looping background music — featured track at public/audio/featured-dark-house-2025.mp3
* (copy from repo music/; legacy ambient.mp3 still valid if you change AMBIENT_MUSIC_SRC).
*/
export const BGM_STORAGE_KEY = 'aetherforge-bgm';
export const BGM_VOLUME_KEY = 'aetherforge-bgm-volume';
/** Served from Vite public/ — place ambient.mp3 here before enabling in Settings. */
export const AMBIENT_MUSIC_SRC = '/audio/ambient.mp3';
/** Featured Command Deck landing track (gitignored when >15MB — copy locally from music/). */
export const FEATURED_MUSIC_SRC = '/audio/featured-dark-house-2025.mp3';
export const FEATURED_MUSIC_TITLE = 'Dark House 2025';
/** Default looping source for the global ambient player. */
export const AMBIENT_MUSIC_SRC = FEATURED_MUSIC_SRC;
/** Route → playback multiplier (01). User volume × intensity = effective output. */
export const PAGE_AMBIENT_INTENSITY: Record<string, number> = {
@@ -40,9 +43,10 @@ export function resolvePageAmbientIntensity(pathname: string): number {
export function loadBgmEnabled(): boolean {
try {
const v = localStorage.getItem(BGM_STORAGE_KEY);
if (v === null) return true;
return v === '1';
} catch {
return false;
return true;
}
}

View File

@@ -1,7 +1,7 @@
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { useAmbientMusic } from '../context/AmbientMusicContext';
import { resolvePageAmbientIntensity } from '../audio/ambientMusic';
import { ambientMusicPlayer, FEATURED_MUSIC_TITLE, resolvePageAmbientIntensity } from '../audio/ambientMusic';
import './GlobalMusicPlayer.css';
export default function GlobalMusicPlayer() {
@@ -14,13 +14,19 @@ export default function GlobalMusicPlayer() {
setPageIntensity(routeIntensity);
}, [routeIntensity, setPageIntensity]);
useEffect(() => {
const path = location.pathname.split('?')[0].replace(/\/$/, '') || '/';
if (path === '/dashboard') void ambientMusicPlayer.tryPlay();
}, [location.pathname]);
return (
<div
className={`global-music-player${isDim ? ' global-music-player--ambient-dim' : ''}`}
data-sfx="off"
data-ambient-intensity={pageIntensity.toFixed(2)}
role="region"
aria-label="Background music controls"
aria-label={`Background music ${FEATURED_MUSIC_TITLE}`}
title={FEATURED_MUSIC_TITLE}
>
<button
type="button"

View File

@@ -63,6 +63,10 @@ export function AmbientMusicProvider({ children }: { children: React.ReactNode }
return ambientMusicPlayer.subscribe(setPlaying);
}, []);
useEffect(() => {
if (enabled) void ambientMusicPlayer.tryPlay();
}, []);
useEffect(() => {
ambientMusicPlayer.setEnabled(enabled);
ambientMusicPlayer.setVolume(volume);

View File

@@ -21,7 +21,7 @@ import FleetRuntimePanel from '../components/Fleet/FleetRuntimePanel';
import { AuditLogStrip } from '../components/Fleet/FleetOpsWidgets';
import { useSound } from '../context/SoundContext';
import { useAmbientMusic } from '../context/AmbientMusicContext';
import { AMBIENT_MUSIC_SRC } from '../audio/ambientMusic';
import { AMBIENT_MUSIC_SRC, FEATURED_MUSIC_TITLE } from '../audio/ambientMusic';
import { useVisualEffects } from '../context/VisualEffectsContext';
import {
FORGE_SKIN_IDS,
@@ -732,9 +732,9 @@ export default function SettingsPage() {
<hr style={{ border: 'none', borderTop: '1px solid var(--border-dim)', margin: '1.25rem 0' }} />
<h3 className="font-tech" style={{ fontSize: '0.85rem', marginBottom: '0.35rem' }}>Background music</h3>
<p className="section-desc" style={{ marginBottom: '0.75rem' }}>
Optional looping ambient track served from <code className="mono-sm">{AMBIENT_MUSIC_SRC}</code>. Use the
mini player in the bottom-right corner on any page, or enable here. Defaults off browsers block autoplay
until you press play or toggle this on.
Featured track <strong>{FEATURED_MUSIC_TITLE}</strong> served from{' '}
<code className="mono-sm">{AMBIENT_MUSIC_SRC}</code>. On by default on Command Deck browsers may still
block autoplay until you click or press a key; use the mini player in the bottom-right or toggle here.
</p>
<div className="form-group checkbox-group">
<label className="checkbox-label">