Add fixed bottom player embed option

Introduced a new 'Fixed Bottom Player' embed code and corresponding i18n strings, providing an always-visible player fixed at the bottom of the page similar to MetingJS fixed mode. Also improved CSS transitions and refactored toggle logic for the floating player embed.
This commit is contained in:
Sora 2026-01-20 13:26:18 +08:00
parent 1c1299d9dd
commit 0f0a33655b
2 changed files with 44 additions and 11 deletions

View File

@ -572,6 +572,8 @@
"embedTip": "Tip: Copy this code and paste it into your webpage HTML to use", "embedTip": "Tip: Copy this code and paste it into your webpage HTML to use",
"floatingPlayerLeft": "Bottom Left Floating Player", "floatingPlayerLeft": "Bottom Left Floating Player",
"floatingPlayerLeftDesc": "Collapsible floating player in bottom left corner, users can click to expand/collapse", "floatingPlayerLeftDesc": "Collapsible floating player in bottom left corner, users can click to expand/collapse",
"fixedBottomPlayer": "Fixed Bottom Player",
"fixedBottomPlayerDesc": "Fixed at bottom of page, always visible (similar to MetingJS fixed mode)",
"basicIframe": "Basic iframe", "basicIframe": "Basic iframe",
"basicIframeDesc": "Simple iframe embed, suitable for fixed position display", "basicIframeDesc": "Simple iframe embed, suitable for fixed position display",
"responsiveIframe": "Responsive iframe", "responsiveIframe": "Responsive iframe",

View File

@ -79,7 +79,7 @@ export const EmbedCodeField = ({ url, title = 'Music Player' }) => {
<iframe src="${url}" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" frameborder="0" allowfullscreen></iframe> <iframe src="${url}" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" frameborder="0" allowfullscreen></iframe>
</div>` </div>`
// // - MetingJS
const floatingPlayerEmbed = `<!-- Navidrome 悬浮播放器 --> const floatingPlayerEmbed = `<!-- Navidrome 悬浮播放器 -->
<div id="navidrome-floating-player"> <div id="navidrome-floating-player">
<div id="nav-player-container" class="nav-collapsed"> <div id="nav-player-container" class="nav-collapsed">
@ -106,7 +106,7 @@ export const EmbedCodeField = ({ url, title = 'Music Player' }) => {
border-radius: 12px; border-radius: 12px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
overflow: hidden; overflow: hidden;
transition: all 0.3s ease; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@ -130,7 +130,7 @@ export const EmbedCodeField = ({ url, title = 'Music Player' }) => {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
flex-shrink: 0; flex-shrink: 0;
} }
@ -150,7 +150,7 @@ export const EmbedCodeField = ({ url, title = 'Music Player' }) => {
#nav-toggle-icon { #nav-toggle-icon {
font-size: 28px; font-size: 28px;
color: white; color: white;
transition: transform 0.3s ease; transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
user-select: none; user-select: none;
} }
@ -194,13 +194,8 @@ export const EmbedCodeField = ({ url, title = 'Music Player' }) => {
<script> <script>
function toggleNavPlayer() { function toggleNavPlayer() {
const container = document.getElementById('nav-player-container'); const container = document.getElementById('nav-player-container');
if (container.classList.contains('nav-collapsed')) { container.classList.toggle('nav-collapsed');
container.classList.remove('nav-collapsed'); container.classList.toggle('nav-expanded');
container.classList.add('nav-expanded');
} else {
container.classList.remove('nav-expanded');
container.classList.add('nav-collapsed');
}
} }
// //
@ -215,6 +210,37 @@ document.addEventListener('click', function(event) {
}); });
</script>` </script>`
// - MetingJS fixed
const fixedBottomEmbed = `<!-- Navidrome 固定底部播放器 -->
<div id="navidrome-fixed-player">
<iframe src="${url}" frameborder="0" allowfullscreen></iframe>
</div>
<style>
#navidrome-fixed-player {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 80px;
z-index: 9999;
box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.1);
background: white;
}
#navidrome-fixed-player iframe {
width: 100%;
height: 100%;
border: none;
display: block;
}
/* 为页面内容添加底部边距,避免被播放器遮挡 */
body {
padding-bottom: 80px;
}
</style>`
// //
const floatingPlayerRightEmbed = floatingPlayerEmbed const floatingPlayerRightEmbed = floatingPlayerEmbed
.replace('left: 20px;', 'right: 20px;') .replace('left: 20px;', 'right: 20px;')
@ -226,6 +252,11 @@ document.addEventListener('click', function(event) {
code: floatingPlayerEmbed, code: floatingPlayerEmbed,
description: translate('message.floatingPlayerLeftDesc'), description: translate('message.floatingPlayerLeftDesc'),
}, },
{
label: translate('message.fixedBottomPlayer'),
code: fixedBottomEmbed,
description: translate('message.fixedBottomPlayerDesc'),
},
{ {
label: translate('message.basicIframe'), label: translate('message.basicIframe'),
code: iframeEmbed, code: iframeEmbed,