feat: add lofi radios

This commit is contained in:
MAZE 2024-08-31 18:15:24 +03:30
parent 76fdc74710
commit bb39b4ba98
6 changed files with 159 additions and 0 deletions

View file

@ -5,3 +5,4 @@ export { Source as SourceItem } from './source';
export { Presets as PresetsItem } from './presets';
export { Shortcuts as ShortcutsItem } from './shortcuts';
export { SleepTimer as SleepTimerItem } from './sleep-timer';
export { Lofi as LofiItem } from './lofi';

View file

@ -0,0 +1,18 @@
import { IoIosMusicalNotes } from 'react-icons/io/index';
import { Item } from '../item';
interface LofiProps {
open: () => void;
}
export function Lofi({ open }: LofiProps) {
return (
<Item
icon={<IoIosMusicalNotes />}
label="Lofi Radios"
shortcut="Shift + L"
onClick={open}
/>
);
}

View file

@ -12,12 +12,14 @@ import {
PresetsItem,
ShortcutsItem,
SleepTimerItem,
LofiItem,
} from './items';
import { Divider } from './divider';
import { ShareLinkModal } from '@/components/modals/share-link';
import { PresetsModal } from '@/components/modals/presets';
import { ShortcutsModal } from '@/components/modals/shortcuts';
import { SleepTimerModal } from '@/components/modals/sleep-timer';
import { LofiModal } from '../modals/lofi';
import { fade, mix, slideY } from '@/lib/motion';
import { useSoundStore } from '@/stores/sound';
@ -32,6 +34,7 @@ export function Menu() {
const initial = useMemo(
() => ({
lofi: false,
presets: false,
shareLink: false,
shortcuts: false,
@ -63,6 +66,7 @@ export function Menu() {
useHotkeys('shift+h', () => open('shortcuts'));
useHotkeys('shift+s', () => open('shareLink'), { enabled: !noSelected });
useHotkeys('shift+t', () => open('sleepTimer'));
useHotkeys('shift+l', () => open('lofi'));
useCloseListener(closeAll);
@ -99,6 +103,7 @@ export function Menu() {
<ShareItem open={() => open('shareLink')} />
<ShuffleItem />
<SleepTimerItem open={() => open('sleepTimer')} />
<LofiItem open={() => open('lofi')} />
<Divider />
<ShortcutsItem open={() => open('shortcuts')} />
@ -122,6 +127,7 @@ export function Menu() {
show={modals.shortcuts}
onClose={() => close('shortcuts')}
/>
<LofiModal show={modals.lofi} onClose={() => close('lofi')} />
<PresetsModal show={modals.presets} onClose={() => close('presets')} />
<SleepTimerModal
show={modals.sleepTimer}

View file

@ -0,0 +1 @@
export { LofiModal } from './lofi';

View file

@ -0,0 +1,88 @@
.title {
margin-bottom: 4px;
font-family: var(--font-heading);
font-size: var(--font-md);
font-weight: 600;
}
.desc {
color: var(--color-foreground-subtle);
}
.radios {
margin-top: 28px;
& .radio {
position: relative;
width: 100%;
padding: 24px 12px 12px;
background-color: var(--color-neutral-50);
border: 1px solid var(--color-neutral-200);
border-radius: 12px;
&:not(:last-of-type) {
margin-bottom: 24px;
}
&::before {
position: absolute;
bottom: -1px;
left: 50%;
width: 80%;
height: 1px;
content: '';
background: linear-gradient(
90deg,
transparent,
var(--color-neutral-400),
transparent
);
transform: translateX(-50%);
}
& .label {
position: absolute;
top: 0;
left: 16px;
display: flex;
align-items: center;
justify-content: center;
height: 25px;
padding: 0 16px;
font-size: var(--font-2xsm);
font-weight: 500;
color: var(--color-foreground-subtle);
background: linear-gradient(
var(--color-neutral-50),
var(--color-neutral-100)
);
border: 1px solid var(--color-neutral-200);
border-radius: 100px;
transform: translateY(-50%);
&::before {
position: absolute;
bottom: -1px;
left: 50%;
width: 70%;
height: 1px;
content: '';
background: linear-gradient(
90deg,
transparent,
var(--color-neutral-400),
transparent
);
transform: translateX(-50%);
}
}
& iframe {
width: 100%;
aspect-ratio: 560 / 315;
margin: 0;
border: none;
border-radius: 8px;
}
}
}

View file

@ -0,0 +1,45 @@
import { Modal } from '@/components/modal';
import { padNumber } from '@/helpers/number';
import styles from './lofi.module.css';
interface LofiModalProps {
onClose: () => void;
show: boolean;
}
export function LofiModal({ onClose, show }: LofiModalProps) {
const radios = [
{
src: 'https://www.youtube.com/embed/jfKfPfyJRdk?si=UiaAY0C8Rk6iBIsd',
},
{
src: 'https://www.youtube.com/embed/4xDzrJKXOOY?si=zyZlOXnoMKr_MWfW',
},
{
src: 'https://www.youtube.com/embed/S_MOd40zlYU?si=rf1_S-MMiAEIKJoi',
},
];
return (
<Modal persist show={show} onClose={onClose}>
<h2 className={styles.title}>Lofi Radios</h2>
<p className={styles.desc}>A curated list of Lofi radios.</p>
<div className={styles.radios}>
{radios.map((radio, index) => (
<div className={styles.radio} key={radio.src}>
<div className={styles.label}>Radio {padNumber(index + 1)}</div>
<iframe
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerPolicy="strict-origin-when-cross-origin"
src={radio.src}
title="YouTube video player"
/>
</div>
))}
</div>
</Modal>
);
}