myYouTube/frontend/src/App.tsx
vrubelroman 252f38597d Split shorts from regular videos with a vertical shorts feed
- Detect shorts by duration (SHORTS_MAX_DURATION_SECONDS, default 180)
  and expose is_short in feed, video and channel-activity DTOs.
- Feed gains type=all|long|short and anchor; lists show a two-mode
  'Обычные | Shorts' filter (no 'Все') persisted in the URL.
- Clicking a short opens /shorts/🆔 a vertical scroll-snap feed with
  autoplay for the active slide, context-aware endpoints and infinite
  loading.
- Keep the sound choice across swipes, syncing with the player's own
  mute control and guarding against the widget's stale isMuted() reads.
2026-09-28 09:33:35 +00:00

42 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useQuery } from '@tanstack/react-query'
import { Link, Navigate, Route, Routes } from 'react-router-dom'
import { getAuthStatus } from './api/client'
import AppShell from './components/AppShell'
import Connect from './pages/Connect'
import Feed from './pages/Feed'
import Channels from './pages/Channels'
import ChannelVideos from './pages/ChannelVideos'
import VideoPage from './pages/VideoPage'
import ShortsFeed from './pages/ShortsFeed'
import Categories from './pages/Categories'
import Settings from './pages/Settings'
import './App.css'
function App() {
const { data, isLoading, isError } = useQuery({ queryKey: ['auth-status'], queryFn: getAuthStatus })
if (isLoading) return <div className="app-loading"><span className="brand-mark">▶</span><p>Открываем MyTube…</p></div>
if (isError) return <div className="app-loading"><h1>Не удалось открыть MyTube</h1><p>Проверь подключение к серверу и обнови страницу.</p><button onClick={() => window.location.reload()}>Повторить</button></div>
if (!data?.authenticated) return <Connect />
return <AppShell>
<Routes>
<Route path="/" element={<Feed />} />
<Route path="/category/:categoryId" element={<Feed />} />
<Route path="/uncategorized" element={<Feed />} />
<Route path="/local" element={<Feed />} />
<Route path="/search" element={<Feed />} />
<Route path="/saved" element={<Navigate to="/local" replace />} />
<Route path="/channels" element={<Channels />} />
<Route path="/channels/:channelId/videos" element={<ChannelVideos />} />
<Route path="/video/:youtubeVideoId" element={<VideoPage />} />
<Route path="/shorts/:youtubeVideoId" element={<ShortsFeed />} />
<Route path="/settings" element={<Settings email={data.email} />} />
<Route path="/settings/categories" element={<Categories />} />
<Route path="/categories" element={<Navigate to="/settings/categories" replace />} />
<Route path="*" element={<div className="empty-state"><h1>Страница не найдена</h1><Link to="/">Вернуться к ленте</Link></div>} />
</Routes>
</AppShell>
}
export default App