Merge branch 'main' of github.com:monochrome-music/monochrome
This commit is contained in:
commit
0662796d73
10 changed files with 154 additions and 101 deletions
20
index.html
20
index.html
|
|
@ -124,7 +124,20 @@
|
||||||
<div id="visualizer-container">
|
<div id="visualizer-container">
|
||||||
<canvas id="visualizer-canvas"></canvas>
|
<canvas id="visualizer-canvas"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<div id="fullscreen-video-container" style="display: none; position: absolute; inset: 0; width: 100%; height: 100%; justify-content: center; align-items: center; background: black; z-index: 0;"></div>
|
<div
|
||||||
|
id="fullscreen-video-container"
|
||||||
|
style="
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: black;
|
||||||
|
z-index: 0;
|
||||||
|
"
|
||||||
|
></div>
|
||||||
<button id="toggle-ui-btn" class="fullscreen-ui-toggle" title="Toggle UI">
|
<button id="toggle-ui-btn" class="fullscreen-ui-toggle" title="Toggle UI">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|
@ -168,7 +181,6 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="fullscreen-track-info">
|
<div class="fullscreen-track-info">
|
||||||
|
|
||||||
<h2 id="fullscreen-track-title"></h2>
|
<h2 id="fullscreen-track-title"></h2>
|
||||||
<h3 id="fullscreen-track-artist"></h3>
|
<h3 id="fullscreen-track-artist"></h3>
|
||||||
<div class="fullscreen-actions">
|
<div class="fullscreen-actions">
|
||||||
|
|
@ -3771,8 +3783,8 @@
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<span class="label">Visualizer Brightness</span>
|
<span class="label">Visualizer Brightness</span>
|
||||||
<span class="description"
|
<span class="description"
|
||||||
>Adjust the brightness of the visualizer. Lower this if the visualizer
|
>Adjust the brightness of the visualizer. Lower this if the visualizer is
|
||||||
is too bright for you.</span
|
too bright for you.</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; align-items: center; gap: 10px">
|
<div style="display: flex; align-items: center; gap: 10px">
|
||||||
|
|
|
||||||
|
|
@ -585,7 +585,9 @@ const syncManager = {
|
||||||
id: playlist.id,
|
id: playlist.id,
|
||||||
name: playlist.name,
|
name: playlist.name,
|
||||||
cover: playlist.cover || null,
|
cover: playlist.cover || null,
|
||||||
tracks: playlist.tracks ? playlist.tracks.map((t) => this._minifyItem(t.type || 'track', t)) : [],
|
tracks: playlist.tracks
|
||||||
|
? playlist.tracks.map((t) => this._minifyItem(t.type || 'track', t))
|
||||||
|
: [],
|
||||||
createdAt: playlist.createdAt || Date.now(),
|
createdAt: playlist.createdAt || Date.now(),
|
||||||
updatedAt: playlist.updatedAt || Date.now(),
|
updatedAt: playlist.updatedAt || Date.now(),
|
||||||
numberOfTracks: playlist.tracks ? playlist.tracks.length : 0,
|
numberOfTracks: playlist.tracks ? playlist.tracks.length : 0,
|
||||||
|
|
|
||||||
12
js/api.js
12
js/api.js
|
|
@ -894,7 +894,7 @@ export class LosslessAPI {
|
||||||
const itemArtistId = item.artist?.id;
|
const itemArtistId = item.artist?.id;
|
||||||
const matchesArtist =
|
const matchesArtist =
|
||||||
itemArtistId === numericArtistId ||
|
itemArtistId === numericArtistId ||
|
||||||
(Array.isArray(item.artists) && item.artists.some(a => a.id === numericArtistId));
|
(Array.isArray(item.artists) && item.artists.some((a) => a.id === numericArtistId));
|
||||||
|
|
||||||
if (matchesArtist && !videoMap.has(item.id)) {
|
if (matchesArtist && !videoMap.has(item.id)) {
|
||||||
videoMap.set(item.id, item);
|
videoMap.set(item.id, item);
|
||||||
|
|
@ -918,8 +918,9 @@ export class LosslessAPI {
|
||||||
.sort((a, b) => (b.popularity || 0) - (a.popularity || 0))
|
.sort((a, b) => (b.popularity || 0) - (a.popularity || 0))
|
||||||
.slice(0, 15);
|
.slice(0, 15);
|
||||||
|
|
||||||
const videos = Array.from(videoMap.values())
|
const videos = Array.from(videoMap.values()).sort(
|
||||||
.sort((a, b) => new Date(b.releaseDate || 0) - new Date(a.releaseDate || 0));
|
(a, b) => new Date(b.releaseDate || 0) - new Date(a.releaseDate || 0)
|
||||||
|
);
|
||||||
|
|
||||||
// Enrich tracks with album release dates
|
// Enrich tracks with album release dates
|
||||||
const tracks = options.lightweight ? topTracks : await this.enrichTracksWithAlbumDates(topTracks);
|
const tracks = options.lightweight ? topTracks : await this.enrichTracksWithAlbumDates(topTracks);
|
||||||
|
|
@ -1282,7 +1283,7 @@ export class LosslessAPI {
|
||||||
};
|
};
|
||||||
|
|
||||||
const manifest = isVideo
|
const manifest = isVideo
|
||||||
? (findValue(lookup, 'manifest') || findValue(lookup, 'Manifest'))
|
? findValue(lookup, 'manifest') || findValue(lookup, 'Manifest')
|
||||||
: lookup.info?.manifest;
|
: lookup.info?.manifest;
|
||||||
|
|
||||||
if (!manifest) {
|
if (!manifest) {
|
||||||
|
|
@ -1325,7 +1326,8 @@ export class LosslessAPI {
|
||||||
console.error('HLS download failed:', hlsError);
|
console.error('HLS download failed:', hlsError);
|
||||||
throw hlsError;
|
throw hlsError;
|
||||||
}
|
}
|
||||||
} else { const response = await fetch(streamUrl, {
|
} else {
|
||||||
|
const response = await fetch(streamUrl, {
|
||||||
cache: 'no-store',
|
cache: 'no-store',
|
||||||
signal: options.signal,
|
signal: options.signal,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1074,7 +1074,10 @@ export async function handleTrackAction(
|
||||||
trackDataStore.set(newEl, item);
|
trackDataStore.set(newEl, item);
|
||||||
ui.updateLikeState(newEl, 'video', item.id);
|
ui.updateLikeState(newEl, 'video', item.id);
|
||||||
newEl.addEventListener('click', (e) => {
|
newEl.addEventListener('click', (e) => {
|
||||||
if (e.target.closest('.card-play-btn') || e.target.closest('.card-image-container')) {
|
if (
|
||||||
|
e.target.closest('.card-play-btn') ||
|
||||||
|
e.target.closest('.card-image-container')
|
||||||
|
) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
player.playVideo(item);
|
player.playVideo(item);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ export class MusicAPI {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
const result = {
|
const result = {
|
||||||
videoUrl: data.videoUrl || null,
|
videoUrl: data.videoUrl || null,
|
||||||
hlsUrl: data.animated || null
|
hlsUrl: data.animated || null,
|
||||||
};
|
};
|
||||||
this.videoArtworkCache.set(cacheKey, result);
|
this.videoArtworkCache.set(cacheKey, result);
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,8 @@ export class Player {
|
||||||
|
|
||||||
if (coverEl) {
|
if (coverEl) {
|
||||||
const videoCoverUrl = track.videoUrl || track.videoCoverUrl || track.album?.videoCoverUrl || null;
|
const videoCoverUrl = track.videoUrl || track.videoCoverUrl || track.album?.videoCoverUrl || null;
|
||||||
const coverUrl = videoCoverUrl || this.api.getCoverUrl(track.image || track.cover || track.album?.cover);
|
const coverUrl =
|
||||||
|
videoCoverUrl || this.api.getCoverUrl(track.image || track.cover || track.album?.cover);
|
||||||
|
|
||||||
if (videoCoverUrl) {
|
if (videoCoverUrl) {
|
||||||
if (coverEl.tagName === 'IMG') {
|
if (coverEl.tagName === 'IMG') {
|
||||||
|
|
@ -453,7 +454,7 @@ export class Player {
|
||||||
...video,
|
...video,
|
||||||
type: 'video',
|
type: 'video',
|
||||||
artist: video.artist || (video.artists && video.artists[0]) || 'Unknown Artist',
|
artist: video.artist || (video.artists && video.artists[0]) || 'Unknown Artist',
|
||||||
album: video.album || { title: 'Video', cover: video.image || video.cover }
|
album: video.album || { title: 'Video', cover: video.image || video.cover },
|
||||||
};
|
};
|
||||||
this.setQueue([videoTrack], 0);
|
this.setQueue([videoTrack], 0);
|
||||||
await this.playTrackFromQueue();
|
await this.playTrackFromQueue();
|
||||||
|
|
|
||||||
|
|
@ -2143,9 +2143,7 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
||||||
const newDimming = parseFloat(e.target.value);
|
const newDimming = parseFloat(e.target.value);
|
||||||
visualizerSettings.setDimAmount(newDimming);
|
visualizerSettings.setDimAmount(newDimming);
|
||||||
visualizerDimmingValue.textContent = `${(newDimming * 100).toFixed(0)}%`;
|
visualizerDimmingValue.textContent = `${(newDimming * 100).toFixed(0)}%`;
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(new CustomEvent('visualizer-dim-change', { detail: { dimAmount: newDimming } }));
|
||||||
new CustomEvent('visualizer-dim-change', { detail: { dimAmount: newDimming } })
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
62
js/ui.js
62
js/ui.js
|
|
@ -351,7 +351,12 @@ export class UIRenderer {
|
||||||
} else if (isVideo && (this.currentPage === 'search' || this.currentPage === 'library')) {
|
} else if (isVideo && (this.currentPage === 'search' || this.currentPage === 'library')) {
|
||||||
trackImageHTML = `<div class="track-item-cover video-icon-placeholder" style="display: flex; align-items: center; justify-content: center; background: var(--secondary);"><svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="opacity: 0.7;"><path d="M8 5v14l11-7z"/></svg></div>`;
|
trackImageHTML = `<div class="track-item-cover video-icon-placeholder" style="display: flex; align-items: center; justify-content: center; background: var(--secondary);"><svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="opacity: 0.7;"><path d="M8 5v14l11-7z"/></svg></div>`;
|
||||||
} else {
|
} else {
|
||||||
trackImageHTML = this.getCoverHTML(track.image || track.cover || track.album?.cover, 'Track Cover', 'track-item-cover', 'lazy');
|
trackImageHTML = this.getCoverHTML(
|
||||||
|
track.image || track.cover || track.album?.cover,
|
||||||
|
'Track Cover',
|
||||||
|
'track-item-cover',
|
||||||
|
'lazy'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -365,7 +370,9 @@ export class UIRenderer {
|
||||||
displayIndex = index + 1;
|
displayIndex = index + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const videoIcon = isVideo ? '<span class="video-item-icon" title="Music Video" style="display: inline-flex; align-items: center; margin-right: 4px; color: var(--muted-foreground);"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m22 8-6 4 6 4V8Z"/><rect width="14" height="12" x="2" y="6" rx="2" ry="2"/></svg></span>' : '';
|
const videoIcon = isVideo
|
||||||
|
? '<span class="video-item-icon" title="Music Video" style="display: inline-flex; align-items: center; margin-right: 4px; color: var(--muted-foreground);"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m22 8-6 4 6 4V8Z"/><rect width="14" height="12" x="2" y="6" rx="2" ry="2"/></svg></span>'
|
||||||
|
: '';
|
||||||
const trackNumberHTML = `<div class="track-number">${showCover ? trackImageHTML : displayIndex}</div>`;
|
const trackNumberHTML = `<div class="track-number">${showCover ? trackImageHTML : displayIndex}</div>`;
|
||||||
const explicitBadge = hasExplicitContent(track) ? this.createExplicitBadge() : '';
|
const explicitBadge = hasExplicitContent(track) ? this.createExplicitBadge() : '';
|
||||||
const qualityBadge = createQualityBadgeHTML(track);
|
const qualityBadge = createQualityBadgeHTML(track);
|
||||||
|
|
@ -638,7 +645,13 @@ export class UIRenderer {
|
||||||
href: `/album/${album.id}`,
|
href: `/album/${album.id}`,
|
||||||
title: `${escapeHtml(album.title)} ${explicitBadge} ${qualityBadge}`,
|
title: `${escapeHtml(album.title)} ${explicitBadge} ${qualityBadge}`,
|
||||||
subtitle: `${escapeHtml(artistName)} • ${yearDisplay}${typeLabel}`,
|
subtitle: `${escapeHtml(artistName)} • ${yearDisplay}${typeLabel}`,
|
||||||
imageHTML: this.getCoverHTML(album.cover, escapeHtml(album.title), 'card-image', 'lazy', album.videoCoverUrl),
|
imageHTML: this.getCoverHTML(
|
||||||
|
album.cover,
|
||||||
|
escapeHtml(album.title),
|
||||||
|
'card-image',
|
||||||
|
'lazy',
|
||||||
|
album.videoCoverUrl
|
||||||
|
),
|
||||||
actionButtonsHTML: `
|
actionButtonsHTML: `
|
||||||
<button class="like-btn card-like-btn" data-action="toggle-like" data-type="album" title="Add to Liked">
|
<button class="like-btn card-like-btn" data-action="toggle-like" data-type="album" title="Add to Liked">
|
||||||
${this.createHeartIcon(false)}
|
${this.createHeartIcon(false)}
|
||||||
|
|
@ -998,7 +1011,8 @@ export class UIRenderer {
|
||||||
if (image) image.style.display = 'block';
|
if (image) image.style.display = 'block';
|
||||||
if (visualizerContainer) visualizerContainer.style.display = 'block';
|
if (visualizerContainer) visualizerContainer.style.display = 'block';
|
||||||
|
|
||||||
const videoCoverUrl = track.videoUrl || track.videoCoverUrl || track.album?.videoCoverUrl || null; const coverUrl = videoCoverUrl || this.api.getCoverUrl(track.album?.cover, '1280');
|
const videoCoverUrl = track.videoUrl || track.videoCoverUrl || track.album?.videoCoverUrl || null;
|
||||||
|
const coverUrl = videoCoverUrl || this.api.getCoverUrl(track.album?.cover, '1280');
|
||||||
|
|
||||||
const fsLikeBtn = document.getElementById('fs-like-btn');
|
const fsLikeBtn = document.getElementById('fs-like-btn');
|
||||||
if (fsLikeBtn) {
|
if (fsLikeBtn) {
|
||||||
|
|
@ -1752,7 +1766,9 @@ export class UIRenderer {
|
||||||
|
|
||||||
if (myPlaylistsContainer) {
|
if (myPlaylistsContainer) {
|
||||||
if (visiblePlaylists.length) {
|
if (visiblePlaylists.length) {
|
||||||
myPlaylistsContainer.innerHTML = visiblePlaylists.map((p) => this.createUserPlaylistCardHTML(p)).join('');
|
myPlaylistsContainer.innerHTML = visiblePlaylists
|
||||||
|
.map((p) => this.createUserPlaylistCardHTML(p))
|
||||||
|
.join('');
|
||||||
visiblePlaylists.forEach((playlist) => {
|
visiblePlaylists.forEach((playlist) => {
|
||||||
const el = myPlaylistsContainer.querySelector(`[data-user-playlist-id="${playlist.id}"]`);
|
const el = myPlaylistsContainer.querySelector(`[data-user-playlist-id="${playlist.id}"]`);
|
||||||
if (el) {
|
if (el) {
|
||||||
|
|
@ -2231,7 +2247,13 @@ export class UIRenderer {
|
||||||
href: `/track/${track.id}`,
|
href: `/track/${track.id}`,
|
||||||
title: `${escapeHtml(getTrackTitle(track))} ${explicitBadge} ${qualityBadge}`,
|
title: `${escapeHtml(getTrackTitle(track))} ${explicitBadge} ${qualityBadge}`,
|
||||||
subtitle: escapeHtml(getTrackArtists(track)),
|
subtitle: escapeHtml(getTrackArtists(track)),
|
||||||
imageHTML: this.getCoverHTML(track.album?.cover, escapeHtml(track.title), 'card-image', 'lazy', track.videoUrl || track.album?.videoCoverUrl),
|
imageHTML: this.getCoverHTML(
|
||||||
|
track.album?.cover,
|
||||||
|
escapeHtml(track.title),
|
||||||
|
'card-image',
|
||||||
|
'lazy',
|
||||||
|
track.videoUrl || track.album?.videoCoverUrl
|
||||||
|
),
|
||||||
actionButtonsHTML: `
|
actionButtonsHTML: `
|
||||||
<button class="like-btn card-like-btn" data-action="toggle-like" data-type="track" title="Add to Liked">
|
<button class="like-btn card-like-btn" data-action="toggle-like" data-type="track" title="Add to Liked">
|
||||||
${this.createHeartIcon(false)}
|
${this.createHeartIcon(false)}
|
||||||
|
|
@ -2634,14 +2656,18 @@ export class UIRenderer {
|
||||||
video.replaceWith(img);
|
video.replaceWith(img);
|
||||||
};
|
};
|
||||||
|
|
||||||
video.addEventListener('error', (e) => {
|
video.addEventListener(
|
||||||
|
'error',
|
||||||
|
(e) => {
|
||||||
if (video.src === result.videoUrl && result.hlsUrl) {
|
if (video.src === result.videoUrl && result.hlsUrl) {
|
||||||
this.setupHlsVideo(video, { videoUrl: null, hlsUrl: result.hlsUrl }, img);
|
this.setupHlsVideo(video, { videoUrl: null, hlsUrl: result.hlsUrl }, img);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.warn('Video decoding error:', e);
|
console.warn('Video decoding error:', e);
|
||||||
video.replaceWith(img);
|
video.replaceWith(img);
|
||||||
}, true);
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
img.replaceWith(video);
|
img.replaceWith(video);
|
||||||
|
|
||||||
|
|
@ -2932,7 +2958,8 @@ export class UIRenderer {
|
||||||
|
|
||||||
this.setupHlsVideo(video, result, currentImageEl);
|
this.setupHlsVideo(video, result, currentImageEl);
|
||||||
currentImageEl.replaceWith(video);
|
currentImageEl.replaceWith(video);
|
||||||
} }
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3696,7 +3723,8 @@ export class UIRenderer {
|
||||||
// Try to get cover from first track album
|
// Try to get cover from first track album
|
||||||
if (tracks.length > 0 && tracks[0].album?.cover) {
|
if (tracks.length > 0 && tracks[0].album?.cover) {
|
||||||
const firstTrack = tracks[0];
|
const firstTrack = tracks[0];
|
||||||
let videoCoverUrl = firstTrack.videoUrl || firstTrack.videoCoverUrl || firstTrack.album?.videoCoverUrl || null;
|
let videoCoverUrl =
|
||||||
|
firstTrack.videoUrl || firstTrack.videoCoverUrl || firstTrack.album?.videoCoverUrl || null;
|
||||||
|
|
||||||
if (!videoCoverUrl && (firstTrack.album || firstTrack.type === 'video')) {
|
if (!videoCoverUrl && (firstTrack.album || firstTrack.type === 'video')) {
|
||||||
const fetchArtwork = () => {
|
const fetchArtwork = () => {
|
||||||
|
|
@ -3727,14 +3755,17 @@ export class UIRenderer {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (firstTrack.type === 'video') {
|
if (firstTrack.type === 'video') {
|
||||||
this.api.getVideoStreamUrl(firstTrack.id).then((url) => {
|
this.api
|
||||||
|
.getVideoStreamUrl(firstTrack.id)
|
||||||
|
.then((url) => {
|
||||||
if (url) {
|
if (url) {
|
||||||
firstTrack.videoUrl = url;
|
firstTrack.videoUrl = url;
|
||||||
this.renderMixPage(mixId);
|
this.renderMixPage(mixId);
|
||||||
} else {
|
} else {
|
||||||
fetchArtwork();
|
fetchArtwork();
|
||||||
}
|
}
|
||||||
}).catch(fetchArtwork);
|
})
|
||||||
|
.catch(fetchArtwork);
|
||||||
} else {
|
} else {
|
||||||
fetchArtwork();
|
fetchArtwork();
|
||||||
}
|
}
|
||||||
|
|
@ -4833,14 +4864,17 @@ export class UIRenderer {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (track.type === 'video') {
|
if (track.type === 'video') {
|
||||||
this.api.getVideoStreamUrl(track.id).then((url) => {
|
this.api
|
||||||
|
.getVideoStreamUrl(track.id)
|
||||||
|
.then((url) => {
|
||||||
if (url) {
|
if (url) {
|
||||||
track.videoUrl = url;
|
track.videoUrl = url;
|
||||||
this.renderTrackPage(trackId, provider);
|
this.renderTrackPage(trackId, provider);
|
||||||
} else {
|
} else {
|
||||||
fetchArtwork();
|
fetchArtwork();
|
||||||
}
|
}
|
||||||
}).catch(fetchArtwork);
|
})
|
||||||
|
.catch(fetchArtwork);
|
||||||
} else {
|
} else {
|
||||||
fetchArtwork();
|
fetchArtwork();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
21
styles.css
21
styles.css
|
|
@ -5348,7 +5348,7 @@ img[src=''] {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
padding: 2rem 2rem 6rem;
|
padding: 2rem 2rem 6rem;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
background: linear-gradient(to top, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.2) 15%, transparent 40%);
|
background: linear-gradient(to top, rgb(0, 0, 0, 0.6) 0%, rgb(0, 0, 0, 0.2) 15%, transparent 40%);
|
||||||
}
|
}
|
||||||
|
|
||||||
#fullscreen-cover-overlay.is-video-mode .fullscreen-track-info {
|
#fullscreen-cover-overlay.is-video-mode .fullscreen-track-info {
|
||||||
|
|
@ -5366,13 +5366,13 @@ img[src=''] {
|
||||||
#fullscreen-cover-overlay.is-video-mode #fullscreen-track-title {
|
#fullscreen-cover-overlay.is-video-mode #fullscreen-track-title {
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
text-shadow: 0 1px 3px rgba(0,0,0,0.8);
|
text-shadow: 0 1px 3px rgb(0, 0, 0, 0.8);
|
||||||
margin-bottom: 0.1rem;
|
margin-bottom: 0.1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#fullscreen-cover-overlay.is-video-mode #fullscreen-track-artist {
|
#fullscreen-cover-overlay.is-video-mode #fullscreen-track-artist {
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
|
text-shadow: 0 1px 2px rgb(0, 0, 0, 0.8);
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5383,13 +5383,15 @@ img[src=''] {
|
||||||
right: 2rem;
|
right: 2rem;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
background: rgba(15, 15, 15, 0.5);
|
background: rgb(15, 15, 15, 0.5);
|
||||||
backdrop-filter: blur(12px);
|
backdrop-filter: blur(12px);
|
||||||
padding: 0.6rem 1rem;
|
padding: 0.6rem 1rem;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
border: 1px solid rgb(255, 255, 255, 0.05);
|
||||||
box-shadow: 0 4px 20px rgba(0,0,0,0.4);
|
box-shadow: 0 4px 20px rgb(0, 0, 0, 0.4);
|
||||||
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s ease;
|
transition:
|
||||||
|
transform 0.4s cubic-bezier(0.4, 0, 0.2, 1),
|
||||||
|
opacity 0.4s ease;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
@ -5427,7 +5429,6 @@ img[src=''] {
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#fullscreen-cover-overlay.ui-hidden .fullscreen-main-view,
|
#fullscreen-cover-overlay.ui-hidden .fullscreen-main-view,
|
||||||
#fullscreen-cover-overlay.ui-hidden .fullscreen-controls,
|
#fullscreen-cover-overlay.ui-hidden .fullscreen-controls,
|
||||||
#fullscreen-cover-overlay.ui-hidden #fullscreen-next-track,
|
#fullscreen-cover-overlay.ui-hidden #fullscreen-next-track,
|
||||||
|
|
@ -8150,7 +8151,7 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 8px;
|
bottom: 8px;
|
||||||
right: 8px;
|
right: 8px;
|
||||||
background: rgba(0, 0, 0, 0.7);
|
background: rgb(0, 0, 0, 0.7);
|
||||||
color: white;
|
color: white;
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
@ -8178,7 +8179,7 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-tab[data-tab="videos"] {
|
.search-tab[data-tab='videos'] {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue