功能:大屏 APK 原生播报及项目入口

具体项目页由 APK 原生轮询并播报三次,总览页不播报。总览项目卡片通过项目编码进入对应大屏。
This commit is contained in:
2026-08-11 00:58:17 +08:00
parent 5ad8bfcd03
commit e4e3e6a735
27 changed files with 728 additions and 236 deletions

View File

@@ -5,10 +5,11 @@ import type { AdminProjectDto, CallBatchDto } from "../types";
interface ProjectScreenTileProps {
project: AdminProjectDto;
standalone?: boolean;
displayHref?: string;
onFullscreen?: (projectId: string) => Promise<void>;
}
export function ProjectScreenTile({ project, standalone = false, onFullscreen }: ProjectScreenTileProps) {
export function ProjectScreenTile({ project, standalone = false, displayHref, onFullscreen }: ProjectScreenTileProps) {
const current = project.current_batch && typeof project.current_batch === "object"
? project.current_batch as CallBatchDto
: null;
@@ -50,8 +51,9 @@ export function ProjectScreenTile({ project, standalone = false, onFullscreen }:
hour12: false,
}).format(now);
return (
<article className={`screen-tile${standalone ? " screen-tile--standalone" : ""}`} data-project-screen={project.id}>
const className = `screen-tile${standalone ? " screen-tile--standalone" : ""}${displayHref ? " screen-tile--link" : ""}`;
const content = (
<>
<header className="screen-tile__header">
<div className="screen-tile__clock" aria-label={`当前时间 ${dateLabel} ${timeLabel}`}>
<img className="screen-tile__logo" src="/xiaoqikong-logo.jpg" alt="" aria-hidden="true" />
@@ -63,7 +65,9 @@ export function ProjectScreenTile({ project, standalone = false, onFullscreen }:
<div className="screen-tile__project">
<h2>{project.name}</h2>
</div>
{!standalone && onFullscreen ? (
{displayHref ? (
<span className="button button--primary screen-tile__fullscreen" aria-hidden="true"></span>
) : !standalone && onFullscreen ? (
<button className="button button--primary screen-tile__fullscreen" onClick={() => void onFullscreen(project.id)}></button>
) : null}
</header>
@@ -83,6 +87,21 @@ export function ProjectScreenTile({ project, standalone = false, onFullscreen }:
<ol>{visible.map((item) => <li key={item.range}><strong>{item.range}</strong><span>{item.wait}</span></li>)}</ol>
) : <p></p>}
</section>
</article>
</>
);
if (displayHref) {
return (
<a
className={className}
href={displayHref}
aria-label={`进入${project.name}项目大屏`}
data-project-screen={project.id}
>
{content}
</a>
);
}
return <article className={className} data-project-screen={project.id}>{content}</article>;
}