144 lines
5 KiB
JavaScript
144 lines
5 KiB
JavaScript
import { trackCloseSidePanel, trackCloseQueue, trackCloseLyrics } from './analytics.js';
|
|
|
|
export class SidePanelManager {
|
|
constructor() {
|
|
this.panel = document.getElementById('side-panel');
|
|
this.titleElement = document.getElementById('side-panel-title');
|
|
this.controlsElement = document.getElementById('side-panel-controls');
|
|
this.contentElement = document.getElementById('side-panel-content');
|
|
this.resizerElement = document.getElementById('side-panel-resizer');
|
|
this.currentView = null; // 'queue' or 'lyrics'
|
|
this.isResizing = false;
|
|
|
|
if (this.resizerElement) {
|
|
this.initResizer();
|
|
}
|
|
}
|
|
|
|
initResizer() {
|
|
this.resizerElement.addEventListener('mousedown', this.startResize.bind(this));
|
|
|
|
// Restore saved width if available
|
|
const savedWidth = localStorage.getItem('side-panel-width');
|
|
if (savedWidth) {
|
|
this.panel.style.setProperty('--side-panel-width', savedWidth + 'px');
|
|
}
|
|
}
|
|
|
|
startResize(e) {
|
|
e.preventDefault();
|
|
this.isResizing = true;
|
|
this.panel.style.transition = 'none'; // Disable transition for smooth resizing
|
|
document.body.style.cursor = 'ew-resize';
|
|
|
|
this.resizeBind = this.resize.bind(this);
|
|
this.stopResizeBind = this.stopResize.bind(this);
|
|
|
|
document.addEventListener('mousemove', this.resizeBind);
|
|
document.addEventListener('mouseup', this.stopResizeBind);
|
|
}
|
|
|
|
resize(e) {
|
|
if (!this.isResizing) return;
|
|
// The panel is on the right side. Screen width - mouse X = desired width.
|
|
const minWidth = 300;
|
|
const maxWidth = window.innerWidth * 0.9;
|
|
let newWidth = window.innerWidth - e.clientX;
|
|
|
|
if (newWidth < minWidth) newWidth = minWidth;
|
|
if (newWidth > maxWidth) newWidth = maxWidth;
|
|
|
|
this.panel.style.setProperty('--side-panel-width', `${newWidth}px`);
|
|
}
|
|
|
|
stopResize() {
|
|
this.isResizing = false;
|
|
this.panel.style.transition = ''; // Restore transitions
|
|
document.body.style.cursor = '';
|
|
|
|
document.removeEventListener('mousemove', this.resizeBind);
|
|
document.removeEventListener('mouseup', this.stopResizeBind);
|
|
|
|
// Save the width
|
|
const currentWidth = this.panel.style.getPropertyValue('--side-panel-width').replace('px', '');
|
|
if (currentWidth) {
|
|
localStorage.setItem('side-panel-width', currentWidth);
|
|
}
|
|
}
|
|
|
|
open(view, title, renderControlsCallback, renderContentCallback, forceOpen = false) {
|
|
// If clicking the same view that is already open, close it
|
|
if (!forceOpen && this.currentView === view && this.panel.classList.contains('active')) {
|
|
this.close();
|
|
return;
|
|
}
|
|
|
|
this.currentView = view;
|
|
this.panel.dataset.view = view;
|
|
this.titleElement.textContent = title;
|
|
|
|
// Clear previous content
|
|
this.controlsElement.innerHTML = '';
|
|
this.contentElement.innerHTML = '';
|
|
|
|
// Render new content
|
|
if (renderControlsCallback) renderControlsCallback(this.controlsElement);
|
|
if (renderContentCallback) renderContentCallback(this.contentElement);
|
|
|
|
this.panel.classList.add('active');
|
|
}
|
|
|
|
close() {
|
|
// Track side panel close
|
|
if (this.currentView) {
|
|
trackCloseSidePanel();
|
|
if (this.currentView === 'queue') {
|
|
trackCloseQueue();
|
|
} else if (this.currentView === 'lyrics') {
|
|
// Get current track from audio player context
|
|
const audioPlayer = document.getElementById('audio-player');
|
|
if (audioPlayer && audioPlayer._currentTrack) {
|
|
trackCloseLyrics(audioPlayer._currentTrack);
|
|
}
|
|
}
|
|
}
|
|
|
|
this.panel.classList.remove('active');
|
|
this.currentView = null;
|
|
// Optionally clear content after transition
|
|
setTimeout(() => {
|
|
if (!this.panel.classList.contains('active')) {
|
|
this.controlsElement.innerHTML = '';
|
|
this.contentElement.innerHTML = '';
|
|
}
|
|
}, 300);
|
|
}
|
|
|
|
isActive(view) {
|
|
return this.currentView === view && this.panel.classList.contains('active');
|
|
}
|
|
|
|
refresh(view, renderControlsCallback, renderContentCallback, options = {}) {
|
|
if (this.isActive(view)) {
|
|
if (renderControlsCallback) {
|
|
this.controlsElement.innerHTML = '';
|
|
renderControlsCallback(this.controlsElement);
|
|
}
|
|
if (renderContentCallback) {
|
|
if (!options.noClear) {
|
|
this.contentElement.innerHTML = '';
|
|
}
|
|
renderContentCallback(this.contentElement);
|
|
}
|
|
}
|
|
}
|
|
|
|
updateContent(view, renderContentCallback) {
|
|
if (this.isActive(view)) {
|
|
this.contentElement.innerHTML = '';
|
|
renderContentCallback(this.contentElement);
|
|
}
|
|
}
|
|
}
|
|
|
|
export const sidePanelManager = new SidePanelManager();
|