Styling improvment
All checks were successful
Build and publish / Build Container (push) Successful in 1m41s

This commit is contained in:
2026-03-02 02:49:15 -05:00
parent c5c070ebc2
commit 8c2b80951b
15 changed files with 824 additions and 823 deletions

View File

@@ -0,0 +1,216 @@
import './btn.mjs';
class JukeboxComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.navi = window.navi;
this.navi.init();
this.unsubscribeWorld = this.navi.on('world:data', (data) => {
console.log(data, this.navi.world.data);
this.render()
});
this.playlist = [];
this.currentTrackIndex = 0;
this.bgMusic = null;
this.isMuted = false;
this.hasInteracted = false;
this.isPlaylistMode = false;
}
disconnectedCallback() {
if(this.unsubscribeWorld) this.unsubscribeWorld();
}
render() {
this.shadowRoot.innerHTML = `
<style>
:host { display: block; }
#simple-mute-btn {
position: fixed;
top: 20px;
right: 20px;
}
.audio-controls {
position: fixed;
display: flex;
top: 20px;
right: 20px;
background: ${this.navi.world.data.theme.colors.primary};
border: 3px solid ${this.navi.world.data.theme.colors.border};
border-radius: 8px;
padding: 12px;
z-index: 1000;
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
min-width: 200px;
}
.track-info {
display: flex;
align-items: center;
background: ${this.navi.world.data.theme.colors.background};
border: 2px solid ${this.navi.world.data.theme.colors.border};
color: ${this.navi.world.data.theme.colors.text};
padding: 8px;
border-radius: 4px;
margin: 0 8px;
overflow: hidden;
height: 24px;
width: 120px;
position: relative;
cursor: text;
}
.track-name {
white-space: nowrap;
display: inline-block;
padding-left: 100%;
animation: marquee 10s linear infinite;
font-weight: bold;
font-size: 14px;
}
@keyframes marquee {
0% { transform: translateX(0); }
100% { transform: translateX(-100%); }
}
.hidden {
display: none;
}
</style>
<btn-component id="simple-mute-btn" color="${this.navi.world.data.theme.colors.accent}">
<svg viewBox="0 0 24 24">
<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/>
</svg>
</btn-component>
<div class="audio-controls hidden" id="playlist-controls">
<btn-component id="prev-btn" color="${this.navi.world.data.theme.colors.accent}">
<svg viewBox="0 0 24 24">
<path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/>
</svg>
</btn-component>
<div class="track-info">
<span class="track-name" id="track-name">No track loaded</span>
</div>
<div style="display: flex; gap: 8px">
<btn-component id="next-btn" color="${this.navi.world.data.theme.colors.accent}">
<svg viewBox="0 0 24 24">
<path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/>
</svg>
</btn-component>
<btn-component id="mute-btn" color="#c0392b">
<svg viewBox="0 0 24 24">
<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/>
</svg>
</btn-component>
</div>
</div>
`;
this.shadowRoot.getElementById('simple-mute-btn').addEventListener('click', () => this.toggleMute());
this.shadowRoot.getElementById('mute-btn').addEventListener('click', () => this.toggleMute());
this.shadowRoot.getElementById('prev-btn').addEventListener('click', () => this.previousTrack());
this.shadowRoot.getElementById('next-btn').addEventListener('click', () => this.nextTrack());
this.loadMusic(this.navi.world.data.theme.music);
}
loadMusic(musicConfig) {
if(!musicConfig) return;
this.isPlaylistMode = Array.isArray(musicConfig);
this.playlist = Array.isArray(musicConfig) ? musicConfig : [musicConfig];
this.currentTrackIndex = 0;
if (this.isPlaylistMode) {
this.shadowRoot.getElementById('simple-mute-btn').classList.add('hidden');
this.shadowRoot.getElementById('playlist-controls').classList.remove('hidden');
} else {
this.shadowRoot.getElementById('simple-mute-btn').classList.remove('hidden');
this.shadowRoot.getElementById('playlist-controls').classList.add('hidden');
}
this.loadTrack(this.currentTrackIndex);
}
loadTrack(index) {
if (this.bgMusic) {
this.bgMusic.pause();
this.bgMusic = null;
}
if (index >= 0 && index < this.playlist.length) {
this.bgMusic = new Audio(this.playlist[index]);
this.bgMusic.volume = 0.5;
if (this.isPlaylistMode) {
this.bgMusic.addEventListener('ended', () => {
this.currentTrackIndex = (this.currentTrackIndex + 1) % this.playlist.length;
this.loadTrack(this.currentTrackIndex);
});
this.updateTrackDisplay();
} else {
this.bgMusic.loop = true;
}
this.setupAutoplayHandler();
if (this.hasInteracted && !this.isMuted) {
this.bgMusic.play();
}
}
}
updateTrackDisplay() {
const trackName = this.shadowRoot.getElementById('track-name');
const fileName = this.playlist[this.currentTrackIndex].split('/').pop();
const trackNum = String(this.currentTrackIndex + 1).padStart(2, '0');
trackName.textContent = `[${trackNum}] ${fileName}`;
}
setupAutoplayHandler() {
const startMusic = () => {
if (!this.hasInteracted && !this.isMuted && this.bgMusic) {
this.hasInteracted = true;
this.bgMusic.play();
}
};
const interactionEvents = ['click', 'keydown', 'touchstart'];
interactionEvents.forEach(event => {
document.addEventListener(event, startMusic, { once: true });
});
}
previousTrack() {
if (!this.isPlaylistMode) return;
this.currentTrackIndex = (this.currentTrackIndex - 1 + this.playlist.length) % this.playlist.length;
this.loadTrack(this.currentTrackIndex);
}
nextTrack() {
if (!this.isPlaylistMode) return;
this.currentTrackIndex = (this.currentTrackIndex + 1) % this.playlist.length;
this.loadTrack(this.currentTrackIndex);
}
toggleMute() {
this.isMuted = !this.isMuted;
const simpleMuteBtn = this.shadowRoot.getElementById('simple-mute-btn');
const muteBtn = this.shadowRoot.getElementById('mute-btn');
const mutedSVG = '<svg viewBox="0 0 24 24"><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/></svg>';
const unmutedSVG = '<svg viewBox="0 0 24 24"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg>';
if (this.bgMusic) {
if (this.isMuted) {
this.bgMusic.pause();
simpleMuteBtn.innerHTML = mutedSVG;
muteBtn.innerHTML = mutedSVG;
} else {
if (!this.hasInteracted) this.hasInteracted = true;
this.bgMusic.play();
simpleMuteBtn.innerHTML = unmutedSVG;
muteBtn.innerHTML = unmutedSVG;
}
}
}
}
customElements.define('jukebox-component', JukeboxComponent);