feat(playlists): библиотека плейлистов приложения
CRUD в редакторе, read-only окно на пульте, отдельный аудиоканал, экспорт/импорт и маппинг из Foundry. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
.page {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
box-sizing: border-box;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.panel {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
|
||||
import { ipcChannels } from '../../shared/ipc/contracts';
|
||||
import { useEditorI18n } from '../editor/i18n/EditorI18nContext';
|
||||
import { getDndApi } from '../shared/dndApi';
|
||||
import {
|
||||
PlaylistsPanel,
|
||||
playlistsPanelLabelsFromT,
|
||||
} from '../shared/playlists/PlaylistsPanel';
|
||||
|
||||
import styles from './PlaylistsApp.module.css';
|
||||
|
||||
export function PlaylistsApp() {
|
||||
const { t } = useEditorI18n();
|
||||
const api = getDndApi();
|
||||
const labels = useMemo(() => playlistsPanelLabelsFromT(t), [t]);
|
||||
|
||||
useEffect(() => {
|
||||
const onKey = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape') {
|
||||
void api.invoke(ipcChannels.windows.closePlaylists, {});
|
||||
}
|
||||
};
|
||||
window.addEventListener('keydown', onKey);
|
||||
return () => window.removeEventListener('keydown', onKey);
|
||||
}, [api]);
|
||||
|
||||
return (
|
||||
<div className={styles.page} data-testid="playlists-app">
|
||||
<PlaylistsPanel labels={labels} className={styles.panel} readOnly />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
|
||||
import '../shared/ui/globals.css';
|
||||
import { EditorI18nProvider } from '../editor/i18n/EditorI18nContext';
|
||||
import { WindowErrorBoundary } from '../shared/ui/WindowErrorBoundary';
|
||||
|
||||
import { PlaylistsApp } from './PlaylistsApp';
|
||||
|
||||
const rootEl = document.getElementById('root');
|
||||
if (!rootEl) {
|
||||
throw new Error('Missing #root element');
|
||||
}
|
||||
|
||||
createRoot(rootEl).render(
|
||||
<React.StrictMode>
|
||||
<WindowErrorBoundary title="Playlists">
|
||||
<EditorI18nProvider>
|
||||
<PlaylistsApp />
|
||||
</EditorI18nProvider>
|
||||
</WindowErrorBoundary>
|
||||
</React.StrictMode>,
|
||||
);
|
||||
Reference in New Issue
Block a user