feat(web): polish catalog motion, empty states, and mobile now-playing
release / desktop (Linux и Windows в релиз) (push) Successful in 16m22s
release / prune (старые файлы и прогоны) (push) Successful in 6s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m23s
release / release (версия и заметки) (push) Successful in 6s
ci / ts / ts (packages + web) (push) Failing after 5m25s
release / android (APK в релиз) (push) Successful in 4m18s
release / desktop (Linux и Windows в релиз) (push) Successful in 16m22s
release / prune (старые файлы и прогоны) (push) Successful in 6s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m23s
release / release (версия и заметки) (push) Successful in 6s
ci / ts / ts (packages + web) (push) Failing after 5m25s
release / android (APK в релиз) (push) Successful in 4m18s
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
39aaaed969
commit
72567acd28
31 files changed
+939
-131
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import { queueIcon } from '../shared/ui/icons';
|
||||
import { unwrap } from '@pipu/core';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Link, Outlet, useNavigate } from '@tanstack/react-router';
|
||||
import { Link, Outlet, useNavigate, useRouterState } from '@tanstack/react-router';
|
||||
import { Suspense, useCallback, useState, type ReactNode } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
chevronRightIcon,
|
||||
storageFillIcon,
|
||||
storageIcon, inboxFillIcon, inboxIcon, myUploadsFillIcon, myUploadsIcon, uploadFillIcon, uploadIcon, tuneFillIcon, tuneIcon} from '../shared/ui/icons';
|
||||
import { Avatar, cx, Dialog, Icon, Logo, Menu } from '../shared/ui/ui';
|
||||
import { Avatar, cx, Dialog, Icon, Logo, Menu, PageSkeleton } from '../shared/ui/ui';
|
||||
import { LanguageSwitch } from './LanguageSwitch';
|
||||
import { PlayerProvider, usePlayer, usePlayerState } from '../player/context';
|
||||
import { Ambient } from './Ambient';
|
||||
@@ -226,6 +226,9 @@ function Shell() {
|
||||
return (
|
||||
<div className={cx(s.shell, island && s.island)}>
|
||||
{user.ui_prefs.ambient !== false && <ShellAmbient />}
|
||||
<a href="#content" className={s.skip}>
|
||||
{t('nav.skip')}
|
||||
</a>
|
||||
<header className={s.top}>
|
||||
<div className={s.topLeft}>
|
||||
<Link to="/" className={s.logoLink}>
|
||||
@@ -284,17 +287,26 @@ function Shell() {
|
||||
</Dialog>
|
||||
)}
|
||||
|
||||
<main className={s.content}>
|
||||
<Suspense fallback={null}>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
</main>
|
||||
<ShellMain />
|
||||
|
||||
<PlayerBar variant={island ? 'island' : 'bar'} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ShellMain() {
|
||||
const key = useRouterState({ select: (st) => st.location.pathname });
|
||||
return (
|
||||
<main id="content" className={s.content} tabIndex={-1}>
|
||||
<div key={key} className={s.routeIn}>
|
||||
<Suspense fallback={<PageSkeleton />}>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
/** Третье пятно фона — в цвете обложки текущего трека. */
|
||||
function ShellAmbient() {
|
||||
const player = usePlayer();
|
||||
|
||||
Reference in new issue
Block a user