UI mejorada

This commit is contained in:
2025-08-10 00:45:59 -06:00
parent 2f878a857a
commit 493d236dc4
8 changed files with 56 additions and 25 deletions

View File

@@ -201,7 +201,7 @@ onMounted(() => {
left: 0;
width: 100%;
height: 100%;
z-index: -1;
z-index: 0; /* Render above body background but below main content */
overflow: hidden;
pointer-events: none;
}

View File

@@ -56,7 +56,15 @@ const hasActiveTrack = computed(() => !!props.currentTrack)
<style scoped>
.main-container {
height: 90vh;
/* Parametrized viewport sizing */
--app-vertical-margin: 10px; /* Top/bottom margin between both components */
--playback-controls-height: 60px; /* Adjustable height for PlaybackControls */
--tracklist-height: calc(100vh - (var(--app-vertical-margin) * 2) - var(--playback-controls-height));
/* Container takes full viewport minus vertical margins */
height: calc(100vh - (var(--app-vertical-margin) * 2));
margin-top: var(--app-vertical-margin);
margin-bottom: var(--app-vertical-margin);
display: flex;
flex-direction: column;
max-width: 1200px;
@@ -64,7 +72,9 @@ const hasActiveTrack = computed(() => !!props.currentTrack)
padding: 20px;
padding-bottom: 0;
position: relative;
overflow: hidden;
/* Keep shadows visible and allow backdrop to show through */
overflow: visible;
z-index: 1; /* Ensure content sits above Aurora background */
}
.app-header {
@@ -186,7 +196,8 @@ const hasActiveTrack = computed(() => !!props.currentTrack)
.main-container {
padding: 15px;
padding-bottom: 0;
height: 92vh;
/* Keep same parametrized behavior on mobile */
height: calc(100vh - (var(--app-vertical-margin) * 2));
}
.header-content {

View File

@@ -65,6 +65,8 @@ const cycleRepeat = () => {
<style scoped>
.playback-controls {
/* Allow parent to control overall height budget */
height: var(--playback-controls-height, auto);
display: flex;
gap: 10px;
align-items: center;

View File

@@ -78,6 +78,8 @@ const handleTrackClick = (track, index) => {
<style scoped>
.track-list {
/* Cap height so sum with PlaybackControls fits 100vh; flex handles actual sizing */
max-height: var(--tracklist-height, none);
padding: 20px;
margin-bottom: 0;
background: rgba(255, 255, 255, 0.05);

View File

@@ -4,7 +4,7 @@ services:
container_name: repodructor
restart: unless-stopped
volumes:
# Mount manually mounted NAS directory
# Mount music directory from server
- /srv/repodructor/musica:/app/public/music:ro
environment:
- NODE_ENV=production

View File

@@ -15,8 +15,8 @@ export default defineNuxtConfig({
// Server configuration for proxy compatibility
devServer: {
host: '0.0.0.0',
port: 3000,
host: process.env.NUXT_HOST || '0.0.0.0',
port: process.env.NUXT_PORT ? Number(process.env.NUXT_PORT) : 3000,
https: false
},
@@ -26,13 +26,12 @@ export default defineNuxtConfig({
// Vite configuration for HMR through proxy
vite: {
server: {
hmr: {
// Use proxy host instead of direct connection
host: 'musica.nucleoriofrio.com',
// Use default HTTPS port (443) through proxy
clientPort: 443,
protocol: 'wss'
}
// Configure HMR via env when developing behind HTTPS proxy
hmr: process.env.NODE_ENV !== 'production' ? {
host: process.env.HMR_HOST || undefined,
clientPort: process.env.HMR_CLIENT_PORT ? Number(process.env.HMR_CLIENT_PORT) : undefined,
protocol: process.env.HMR_PROTOCOL || undefined
} : undefined
}
},
@@ -139,7 +138,7 @@ export default defineNuxtConfig({
// Runtime configuration
runtimeConfig: {
public: {
musicPath: '/music'
musicPath: process.env.NUXT_PUBLIC_MUSIC_PATH || '/music'
}
},
})

View File

@@ -16,18 +16,23 @@ export default defineEventHandler(async (event) => {
const headers = getHeaders(event)
const realIP = headers['x-real-ip'] || headers['x-forwarded-for'] || 'unknown'
console.log(`[MUSIC API] Request from ${realIP} for file: ${filename}`)
console.log('Original filename bytes:', [...filename].map(c => c.charCodeAt(0)))
// Decode the filename
try {
filename = decodeURIComponent(filename)
console.log('Decoded filename:', filename)
console.log('Decoded filename bytes:', [...filename].map(c => c.charCodeAt(0)))
} catch (error) {
console.error('Error decoding filename:', error)
// If decoding fails, use original filename
}
try {
const musicDir = join(process.cwd(), 'public', 'music')
const config = useRuntimeConfig()
const defaultPublicPath = config.public?.musicPath || '/music'
const publicRel = defaultPublicPath.replace(/^\//, '')
const musicDir = process.env.MUSIC_DIR || join(process.cwd(), 'public', publicRel)
const filePath = join(musicDir, filename)
// Security check: ensure the file is within the music directory
@@ -41,7 +46,16 @@ export default defineEventHandler(async (event) => {
// Check if file exists
try {
await fs.access(filePath)
} catch {
console.log('File found successfully:', filePath)
} catch (error) {
console.log('File NOT found:', filePath)
console.log('Directory contents:')
try {
const files = await fs.readdir(musicDir)
files.forEach(file => console.log(' -', file))
} catch (e) {
console.log('Cannot read directory:', e)
}
throw createError({
statusCode: 404,
statusMessage: 'File not found'

View File

@@ -8,7 +8,10 @@ export default defineEventHandler(async (event) => {
const realIP = headers['x-real-ip'] || headers['x-forwarded-for'] || 'unknown'
console.log(`[MUSIC API] Music list request from ${realIP}`)
const musicDir = join(process.cwd(), 'public', 'music')
const config = useRuntimeConfig()
const defaultPublicPath = config.public?.musicPath || '/music'
const publicRel = defaultPublicPath.replace(/^\//, '')
const musicDir = process.env.MUSIC_DIR || join(process.cwd(), 'public', publicRel)
// Check if music directory exists
try {