mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
feat(autodj): configurable overlap cap (auto or 2–30 s) (#1173)
This commit is contained in:
@@ -2,6 +2,10 @@ import React from 'react';
|
||||
import type { TFunction } from 'i18next';
|
||||
import { useAuthStore } from '../../../store/authStore';
|
||||
import { useOrbitStore } from '../../../store/orbitStore';
|
||||
import {
|
||||
AUTODJ_OVERLAP_CAP_MAX_SEC,
|
||||
AUTODJ_OVERLAP_CAP_MIN_SEC,
|
||||
} from '../../../utils/playback/autodjOverlapCap';
|
||||
import {
|
||||
getTransitionMode,
|
||||
setTransitionMode,
|
||||
@@ -21,8 +25,7 @@ interface Props {
|
||||
* transition-mode helper.
|
||||
*
|
||||
* Classic crossfade exposes the seconds slider; AutoDJ is content-driven and
|
||||
* has no duration to configure (just a short explainer + the smooth-skip
|
||||
* toggle).
|
||||
* exposes an optional overlap cap (auto vs manual limit).
|
||||
*
|
||||
* Rendered as its own top-level "Track transitions" category in the Audio tab,
|
||||
* so the boxed `SettingsGroup` is title-less — the `SettingsSubSection` header
|
||||
@@ -89,6 +92,50 @@ export function TrackTransitionsBlock({ t }: Props) {
|
||||
<div style={{ paddingLeft: '1rem', fontSize: 12, color: 'var(--text-muted)', marginTop: '0.7rem' }}>
|
||||
{t('settings.autoDjDesc')}
|
||||
</div>
|
||||
<div style={{ paddingLeft: '1rem', marginTop: '0.9rem' }}>
|
||||
<p className="settings-row-label" style={{ marginBottom: '0.45rem' }}>
|
||||
{t('settings.autodjOverlapCapTitle')}
|
||||
</p>
|
||||
<p className="settings-row-desc" style={{ marginBottom: '0.6rem' }}>
|
||||
{t('settings.autodjOverlapCapDesc')}
|
||||
</p>
|
||||
<div className="settings-segmented" style={{ marginBottom: auth.autodjOverlapCapMode === 'limit' ? '0.65rem' : 0 }}>
|
||||
<button
|
||||
type="button"
|
||||
className={`btn ${auth.autodjOverlapCapMode === 'auto' ? 'btn-primary' : 'btn-ghost'}`}
|
||||
disabled={hostControlled}
|
||||
onClick={() => auth.setAutodjOverlapCapMode('auto')}
|
||||
>
|
||||
{t('settings.autodjOverlapCapAuto')}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`btn ${auth.autodjOverlapCapMode === 'limit' ? 'btn-primary' : 'btn-ghost'}`}
|
||||
disabled={hostControlled}
|
||||
onClick={() => auth.setAutodjOverlapCapMode('limit')}
|
||||
>
|
||||
{t('settings.autodjOverlapCapLimit')}
|
||||
</button>
|
||||
</div>
|
||||
{auth.autodjOverlapCapMode === 'limit' && (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem', flexWrap: 'wrap' }}>
|
||||
<input
|
||||
type="range"
|
||||
min={AUTODJ_OVERLAP_CAP_MIN_SEC}
|
||||
max={AUTODJ_OVERLAP_CAP_MAX_SEC}
|
||||
step={1}
|
||||
value={auth.autodjOverlapCapSec}
|
||||
disabled={hostControlled}
|
||||
onChange={e => auth.setAutodjOverlapCapSec(parseInt(e.target.value, 10))}
|
||||
style={{ flex: 1, minWidth: 80, maxWidth: 200 }}
|
||||
id="autodj-overlap-cap-slider"
|
||||
/>
|
||||
<span style={{ fontSize: 13, color: 'var(--text-secondary)', minWidth: 48 }}>
|
||||
{t('settings.autodjOverlapCapSecs', { n: auth.autodjOverlapCapSec })}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div style={{ paddingLeft: '1rem', marginTop: '0.7rem' }}>
|
||||
<SettingsToggle
|
||||
label={t('settings.autodjSmoothSkip')}
|
||||
|
||||
Reference in New Issue
Block a user