装饰
This commit is contained in:
@@ -174,7 +174,10 @@ function useSongQueue(preview: boolean, language: string, stream?: ComponentStre
|
||||
const itemId = String(payload.itemId ?? '')
|
||||
const item = normalizeSongRequestItem(payload.item)
|
||||
const current = normalizeSongRequestItem(payload.current)
|
||||
let queued = previous.queued.filter(entry => entry.id !== itemId && entry.id !== current?.id)
|
||||
let queued =
|
||||
operation === 'cleared'
|
||||
? []
|
||||
: previous.queued.filter(entry => entry.id !== itemId && entry.id !== current?.id)
|
||||
if (item?.status === 'queued') queued.push(item)
|
||||
if (operation === 'promoted' && item) {
|
||||
queued = queued.map(entry =>
|
||||
@@ -229,6 +232,9 @@ function useBounceScroll(
|
||||
let direction = 1
|
||||
let last = performance.now()
|
||||
let pausedUntil = last + pauseSeconds * 1000
|
||||
// OBS can ship an older Chromium that rounds scrollTop to whole pixels.
|
||||
// Keep fractional movement here so low configured speeds still advance.
|
||||
let pendingPixels = 0
|
||||
|
||||
const resize = new ResizeObserver(() => {
|
||||
container.scrollTop = Math.min(
|
||||
@@ -244,14 +250,21 @@ function useBounceScroll(
|
||||
last = now
|
||||
if (maximum === 0) container.scrollTop = 0
|
||||
else if (now >= pausedUntil) {
|
||||
container.scrollTop += direction * Math.max(5, speed) * (elapsed / 1000)
|
||||
pendingPixels += Math.max(5, speed) * (elapsed / 1000)
|
||||
const wholePixels = Math.floor(pendingPixels)
|
||||
if (wholePixels > 0) {
|
||||
container.scrollTop += direction * wholePixels
|
||||
pendingPixels -= wholePixels
|
||||
}
|
||||
if (container.scrollTop >= maximum - 0.5) {
|
||||
container.scrollTop = maximum
|
||||
direction = -1
|
||||
pendingPixels = 0
|
||||
pausedUntil = now + pauseSeconds * 1000
|
||||
} else if (container.scrollTop <= 0.5) {
|
||||
container.scrollTop = 0
|
||||
direction = 1
|
||||
pendingPixels = 0
|
||||
pausedUntil = now + pauseSeconds * 1000
|
||||
}
|
||||
}
|
||||
@@ -309,8 +322,12 @@ export function SongRequestOverlay({
|
||||
{
|
||||
...themeCssVariables(theme),
|
||||
...typographyVariables(settings.fontFamily, settings.fontBrightness),
|
||||
['--component-song-requester-color' as string]: settings.requesterColor || undefined,
|
||||
['--component-song-title-color' as string]: settings.songTitleColor || undefined,
|
||||
['--song-font-size' as string]: `${Math.min(22, Math.max(11, Math.min(bounds.width, bounds.height) * 0.024)) * (settings.fontScale / 100)}px`,
|
||||
['--song-current-min' as string]: `${Math.min(72, Math.max(48, bounds.height * 0.08))}px`,
|
||||
['--song-moonlit-font-size' as string]: `${Math.min(26, Math.max(14, Math.min(bounds.width * 0.045, bounds.height * 0.032))) * (settings.fontScale / 100)}px`,
|
||||
['--song-moonlit-current-min' as string]: `${Math.min(118, Math.max(74, bounds.height * 0.135))}px`,
|
||||
} as CSSProperties
|
||||
}
|
||||
>
|
||||
@@ -321,7 +338,8 @@ export function SongRequestOverlay({
|
||||
>
|
||||
<SongParticles theme={theme} />
|
||||
<div className="song-current-mark" aria-hidden="true">
|
||||
{translate('song.overlay.sing_mark')}
|
||||
<span className="song-current-mark-label">{translate('song.overlay.sing_mark')}</span>
|
||||
<span className="song-current-mark-note">♫</span>
|
||||
</div>
|
||||
{queue.current ? (
|
||||
<div className="song-current-copy">
|
||||
@@ -339,6 +357,11 @@ export function SongRequestOverlay({
|
||||
<div className="song-score">
|
||||
<b>{score(queue.current)}</b>
|
||||
<small>{translate('song.overlay.rate_help')}</small>
|
||||
<div className="song-waveform" aria-hidden="true">
|
||||
{Array.from({ length: 8 }, (_, index) => (
|
||||
<i key={index} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="song-queue" aria-label={translate('song.overlay.queue_aria')}>
|
||||
@@ -355,8 +378,10 @@ export function SongRequestOverlay({
|
||||
style={{ ['--song-row-delay' as string]: `${Math.min(index, 6) * 35}ms` }}
|
||||
>
|
||||
<span className="song-index">{String(index + 1).padStart(2, '0')}</span>
|
||||
<strong>{item.title}</strong>
|
||||
<span className="song-requester">{item.requester.name}</span>
|
||||
<div className="song-row-copy">
|
||||
<span className="song-requester">{item.requester.name}</span>
|
||||
<strong>{item.title}</strong>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
{queue.queued.length === 0 && (
|
||||
|
||||
Reference in New Issue
Block a user