feat: i18n
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Slider, Badge } from '@olly/modern-sk';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Icon } from '../common/Icon';
|
||||
import { ArtTile } from '../common/ArtTile';
|
||||
import { useAppDispatch, useAppSelector } from '../../hooks/useAppDispatch';
|
||||
@@ -10,6 +11,7 @@ import {
|
||||
import { toggleQueue } from '../../store/slices/player';
|
||||
|
||||
export function QueuePanel() {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const queue = useAppSelector((s) => s.queue);
|
||||
const isOpen = useAppSelector((s) => s.player.isQueueOpen);
|
||||
@@ -27,13 +29,13 @@ export function QueuePanel() {
|
||||
<div className="qd-inner">
|
||||
<div className="qd-head">
|
||||
<div className="row">
|
||||
<h3>Play queue</h3>
|
||||
<h3>{t('queue.title')}</h3>
|
||||
<div style={{ flex: 1 }} />
|
||||
<button
|
||||
type="button"
|
||||
className="iconbtn sm"
|
||||
onClick={() => dispatch(clearQueue())}
|
||||
title="Clear queue"
|
||||
title={t('queue.clear')}
|
||||
>
|
||||
<Icon name="trash" />
|
||||
</button>
|
||||
@@ -41,7 +43,7 @@ export function QueuePanel() {
|
||||
type="button"
|
||||
className="iconbtn sm"
|
||||
onClick={() => dispatch(toggleQueue())}
|
||||
title="Close"
|
||||
title={t('queue.close')}
|
||||
>
|
||||
<Icon name="x" />
|
||||
</button>
|
||||
@@ -53,10 +55,10 @@ export function QueuePanel() {
|
||||
/>
|
||||
{isRadio ? (
|
||||
<span style={{ color: 'var(--lime)' }}>
|
||||
Radio · {sourceLabel}
|
||||
{t('queue.radio', { source: sourceLabel })}
|
||||
</span>
|
||||
) : (
|
||||
<span>From {sourceLabel}</span>
|
||||
<span>{t('queue.from', { source: sourceLabel })}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -68,7 +70,7 @@ export function QueuePanel() {
|
||||
className="msk-label"
|
||||
style={{ display: 'block', marginBottom: 8 }}
|
||||
>
|
||||
Now playing
|
||||
{t('queue.nowPlaying')}
|
||||
</span>
|
||||
<div className="qd-now">
|
||||
<ArtTile
|
||||
@@ -87,21 +89,14 @@ export function QueuePanel() {
|
||||
<div className="qd-radio">
|
||||
<div className="row">
|
||||
<Icon name="radio" />
|
||||
<span
|
||||
style={{
|
||||
fontSize: 13,
|
||||
fontWeight: 600,
|
||||
color: 'var(--fg-1)',
|
||||
}}
|
||||
>
|
||||
Radio active
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: 'var(--fg-1)' }}>
|
||||
{t('queue.radioActive')}
|
||||
</span>
|
||||
<div style={{ flex: 1 }} />
|
||||
<Badge variant="neutral">∞ mixing</Badge>
|
||||
<Badge variant="neutral">{t('queue.mixing')}</Badge>
|
||||
</div>
|
||||
{/* exploration balance — stub under the future ML contract */}
|
||||
<div className="expl">
|
||||
<span className="lab">Familiar</span>
|
||||
<span className="lab">{t('queue.familiar')}</span>
|
||||
<Slider
|
||||
className="expl-slider"
|
||||
min={0}
|
||||
@@ -110,7 +105,7 @@ export function QueuePanel() {
|
||||
defaultValue={[42]}
|
||||
aria-label="Exploration"
|
||||
/>
|
||||
<span className="lab">New</span>
|
||||
<span className="lab">{t('queue.new')}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -119,17 +114,17 @@ export function QueuePanel() {
|
||||
className="msk-label"
|
||||
style={{ display: 'block', margin: '4px 0 8px' }}
|
||||
>
|
||||
Next up
|
||||
{t('queue.nextUp')}
|
||||
</span>
|
||||
{upNext.length === 0 ? (
|
||||
<div className="qd-empty">Nothing queued next</div>
|
||||
<div className="qd-empty">{t('queue.nothingNext')}</div>
|
||||
) : (
|
||||
upNext.map(({ entry, index }) => (
|
||||
<div
|
||||
key={`${entry.trackId}-${index}`}
|
||||
className="qrow"
|
||||
onDoubleClick={() => dispatch(goToIndex(index))}
|
||||
title="Double-click to play"
|
||||
title={t('queue.doubleClickPlay')}
|
||||
>
|
||||
<span className="grip">
|
||||
<Icon name="dots-six-vertical" />
|
||||
@@ -147,7 +142,7 @@ export function QueuePanel() {
|
||||
type="button"
|
||||
className="iconbtn sm"
|
||||
onClick={() => dispatch(removeFromQueue(index))}
|
||||
title="Remove from queue"
|
||||
title={t('queue.removeFromQueue')}
|
||||
>
|
||||
<Icon name="x" />
|
||||
</button>
|
||||
@@ -156,11 +151,11 @@ export function QueuePanel() {
|
||||
)}
|
||||
|
||||
{isRadio && (
|
||||
<div className="qd-loadmore">Loading more from radio…</div>
|
||||
<div className="qd-loadmore">{t('queue.loadingMore')}</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="qd-empty">Queue is empty</div>
|
||||
<div className="qd-empty">{t('queue.empty')}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user