不再沿用旧 im_webapp 的技术栈(webpack + class组件 + 15000行全局CSS + 手搓History路由), 按业务重新选型:Vite/React Router/Zustand预留/TanStack Query/保留tinode-sdk真实依赖 (协议客户端本身没有重写的业务理由)。新代码放在 web/ 子目录,旧代码原样保留在仓库根目录, 两者共存到重写完成。 这一步先验证布局壳本身:NavRail(消息/通讯录/收藏/文件助手/通话记录/设置)+ 会话列表 + 主区域 + 详情栏,按设计稿的四档断点(<640/640-959/960-1279/≥1280)用真实浏览器宽度逐档验证 过——两列及以下"列表/主区域二选一+返回键"、三列"详情栏抽屉化"、四列"详情栏常驻"均已用 真实点击/返回验证正确,不是只看了截图。会话列表和聊天内容目前是占位数据,业务数据接入和 Tinode连接是下一步。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
29 lines
928 B
TypeScript
29 lines
928 B
TypeScript
import { Outlet } from 'react-router-dom';
|
|
|
|
import { BottomTabBar } from './BottomTabBar';
|
|
import { NavRail } from './NavRail';
|
|
|
|
/**
|
|
* Top-level chrome: persistent icon rail (>=640px) or bottom tab bar (<640px), wrapping whichever
|
|
* feature section is active. Each feature section owns its own list/main/detail responsive split
|
|
* internally (see e.g. features/messages) -- this shell only decides "rail vs tabs", nothing about
|
|
* columns within a section.
|
|
*/
|
|
export function AppShell() {
|
|
return (
|
|
<div className="flex h-dvh w-full overflow-hidden bg-surface-page">
|
|
<div className="hidden sm:flex sm:h-full">
|
|
<NavRail />
|
|
</div>
|
|
<div className="flex min-w-0 flex-1 flex-col overflow-hidden">
|
|
<div className="min-h-0 flex-1 overflow-hidden">
|
|
<Outlet />
|
|
</div>
|
|
<div className="sm:hidden">
|
|
<BottomTabBar />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|