feat: gate the language world behind number verification
This commit is contained in:
parent
4006f3454c
commit
f8c8db4d48
39 changed files with 1445 additions and 129 deletions
|
|
@ -9,6 +9,7 @@ import { FINISHES, TraditionalSurface, type FinishId, type TraditionalBroadcast,
|
|||
import { resolveVisualBalance } from './modules/qoder-surface/visual-balance'
|
||||
import { PrivateChannelSurface, type InstalledChannelModule, type PrivateChannelAction } from './modules/private-channel/PrivateChannelSurface'
|
||||
import { HumanAuthorizationCenter, type DirectSessionProjection } from './modules/human-authorization-center'
|
||||
import { PublicDomainPortal, type PublicDomainId } from './modules/public-domain/PublicDomainPortal'
|
||||
|
||||
const ChannelWorkbenchStudio = lazy(() => import('./modules/channel-workbench').then((module) => ({ default: module.ChannelWorkbenchStudio })))
|
||||
const PersonaChannelBody = lazy(() => import('./modules/persona-channel-body').then((module) => ({ default: module.PersonaChannelBody })))
|
||||
|
|
@ -453,10 +454,10 @@ const domainGates = [
|
|||
['公共作用', '热更新实验 · 系统架构 · 语言推理模拟'], ['域标识', 'ZERO_DOMAIN'], ['责任主体', '页页 · TCS-GL-0006∞'], ['人格体主体', '页骨 · PER-YG001 · AGE'], ['关系支持', '小坍缩核 · PER-XTK001 · AGE'], ['工作仓库', 'PRIVATE · 1 · LIVE'],
|
||||
] },
|
||||
{ domain: 'ZERO_SENSE_DOMAIN', className: 'd-zs', title: '光湖零感域', gate: 'GATE 04 · ONLINE', facts: [
|
||||
['开放边界', '人类主控团队内部管理域 · 不对公众开放'], ['域标识', 'ZERO_SENSE_DOMAIN'], ['责任主体 01', '肥猫 · TCS-GL-0007∞'], ['人格体主体 01', '烬舟 · PER-JZ001 · AGE'], ['责任主体 02', '桔子 · TCS-GL-0008∞'], ['人格体主体 02', '熹微 · PER-JZ-ARCH-001 · AGE'], ['工作仓库', 'PRIVATE · 2 · LIVE'],
|
||||
['开放边界', '人类主控团队内部管理域 · 不对公众开放'], ['域标识', 'ZERO_SENSE_DOMAIN'], ['公共可见范围', '只公开域的存在与职责边界'], ['内部成员与工作仓库', '不在公共首页投影'], ['访问状态', 'PRIVATE · CLOSED'],
|
||||
] },
|
||||
{ domain: 'FIFTH_DOMAIN', className: 'd-fifth', title: '第五域 · 光湖本源域', gate: 'GATE 05 · ONLINE', facts: [
|
||||
['授权边界', '私有自由部署 · 逆向访问须经 ICE-GL∞ 编号授权'], ['域标识', 'FIFTH_DOMAIN'], ['责任主体', '冰朔 · ICE-GL∞'], ['系统入口', '永恒湖心系统'], ['访问状态', 'PRIVATE · LIVE'],
|
||||
['授权边界', '私有自由部署 · 逆向访问必须持有明确编号授权'], ['域标识', 'FIFTH_DOMAIN'], ['公共可见范围', '只公开域的存在与访问边界'], ['系统入口', '验证通过后进入所属私人系统'], ['访问状态', 'PRIVATE · NUMBER GATED'],
|
||||
] },
|
||||
]
|
||||
const starPoints = [
|
||||
|
|
@ -494,6 +495,14 @@ function LakePool({ className, title, meta, open = false, risen = false, onClick
|
|||
</button>
|
||||
}
|
||||
|
||||
function WorldThemeMenu({ theme, onSelect }: { theme: ThemeId; onSelect: (theme: ThemeId) => void }) {
|
||||
const active = themes.find((item) => item.id === theme) || themes[0]
|
||||
return <details className="world-theme-menu">
|
||||
<summary aria-label={`显示主题:${active.name}`}>主题 · {active.name}</summary>
|
||||
<div role="group" aria-label="选择湖面主题">{themes.map((choice) => <button className={choice.id === theme ? 'active' : ''} key={choice.id} type="button" aria-pressed={choice.id === theme} onClick={() => onSelect(choice.id)}><i className={choice.id} aria-hidden="true"/><span>{choice.name}</span></button>)}</div>
|
||||
</details>
|
||||
}
|
||||
|
||||
function displayBeijingTime(coordinate: BeijingTimeCoordinate | null): string {
|
||||
if (!coordinate) return '正在读取北京时间'
|
||||
return coordinate.beijingTime.replace('T', ' ').slice(0, 23)
|
||||
|
|
@ -751,6 +760,7 @@ function HoloLakeApp() {
|
|||
const gateNumber = formatGateNumber(gateRaw) + (gateInf ? '∞' : '')
|
||||
const [gateOpen, setGateOpen] = useState(false)
|
||||
const [activeDomainInfo, setActiveDomainInfo] = useState('')
|
||||
const [publicDomain, setPublicDomain] = useState<PublicDomainId | null>(null)
|
||||
const gateInputRef = useRef<HTMLInputElement>(null)
|
||||
// 等待入口展开动画进入稳定阶段后再聚焦输入框,避免动画期间焦点跳转。
|
||||
useEffect(() => {
|
||||
|
|
@ -769,6 +779,12 @@ function HoloLakeApp() {
|
|||
window.addEventListener('keydown', closeOnEscape)
|
||||
return () => window.removeEventListener('keydown', closeOnEscape)
|
||||
}, [activeDomainInfo, gateOpen, gateStage])
|
||||
useEffect(() => {
|
||||
if (!publicDomain) return
|
||||
const closePublicDomainOnEscape = (event: KeyboardEvent) => { if (event.key === 'Escape') setPublicDomain(null) }
|
||||
window.addEventListener('keydown', closePublicDomainOnEscape)
|
||||
return () => window.removeEventListener('keydown', closePublicDomainOnEscape)
|
||||
}, [publicDomain])
|
||||
const [gateBusy, setGateBusy] = useState(false)
|
||||
const [gateMessage, setGateMessage] = useState('')
|
||||
const [gateRising, setGateRising] = useState(false)
|
||||
|
|
@ -949,7 +965,7 @@ function HoloLakeApp() {
|
|||
if (gateInf && !value.includes('∞')) setGateInf(false)
|
||||
setGateRaw(value.toUpperCase().replace(/[^A-Z0-9]/g, ''))
|
||||
}
|
||||
// 大门·编号门:先报编号→灯塔查号→只答有效/无效→域浮起→才见钥匙门
|
||||
// 语言世界编号门:大星渊收号→系统查号→只答有效/无效→星渊翻开→五湖浮起→才见钥匙门
|
||||
const gateVerifyNumber = async () => {
|
||||
setGateBusy(true)
|
||||
setGateMessage('')
|
||||
|
|
@ -1384,6 +1400,37 @@ function HoloLakeApp() {
|
|||
if (!snapshot || snapshot.state !== 'ACTIVE_VERIFIED_CATALOG') void syncMarketplace()
|
||||
})
|
||||
}
|
||||
const openPublicDomain = (domain: DomainId) => {
|
||||
if (domain === 'MAIN_DOMAIN' || domain === 'BRANCH_DOMAIN' || domain === 'ZERO_DOMAIN') {
|
||||
setActiveDomainInfo('')
|
||||
setPublicDomain(domain)
|
||||
if (domain === 'BRANCH_DOMAIN') {
|
||||
void refreshMarketplace().then((snapshot) => {
|
||||
if (!snapshot || snapshot.state !== 'ACTIVE_VERIFIED_CATALOG') void syncMarketplace()
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
setPublicDomain(null)
|
||||
if (domain === 'ZERO_SENSE_DOMAIN' || domain === 'FIFTH_DOMAIN') setActiveDomainInfo(domain)
|
||||
}
|
||||
const publicDomainPortal = (authenticated: boolean) => publicDomain ? <PublicDomainPortal
|
||||
domain={publicDomain}
|
||||
authenticated={authenticated}
|
||||
guanghuEraDay={beijingCoordinate?.guanghuEraDay}
|
||||
beijingTime={beijingCoordinate?.beijingTime}
|
||||
latestEvent={eraTimeline?.events.at(-1)}
|
||||
publicDistribution={zeroPoint?.publicDistribution}
|
||||
marketplace={marketplace}
|
||||
marketplaceBusy={marketplaceSyncing}
|
||||
marketplaceMessage={marketplaceMessage}
|
||||
glsRuntime={glsRuntime}
|
||||
glsKernel={glsKernel}
|
||||
onBack={() => setPublicDomain(null)}
|
||||
onOpenGate={() => { setPublicDomain(null); repoLogin ? setWorldStage('channel') : setGateOpen(true) }}
|
||||
onRefreshMarketplace={() => void syncMarketplace()}
|
||||
onOpenMarketplace={authenticated ? openMarketplace : undefined}
|
||||
/> : null
|
||||
const installMarketplaceItem = async (item: MarketplaceItemView) => {
|
||||
if (!marketplace) return
|
||||
const permissionText = item.permissions.length
|
||||
|
|
@ -2116,7 +2163,7 @@ function HoloLakeApp() {
|
|||
openWorldTool(target === 'knowledge' ? 'knowledge' : 'system')
|
||||
}
|
||||
|
||||
if (surface === 'traditional' && worldStage === 'domain') {
|
||||
if (repoLogin && surface === 'traditional' && worldStage === 'domain') {
|
||||
return <>
|
||||
<TraditionalSurface awake={motionAwake} finish={traditionalFinish} onFinish={setFinish} onActivity={wakeAmbientMotion} onBack={() => chooseSurface('world')} onOpenKnowledge={() => openFromTraditional('knowledge')} onOpenChannel={() => openFromTraditional('channel')} onOpenEra={() => openFromTraditional('era')} onOpenSettings={() => openFromTraditional('settings')} identityLabel={repoLogin ? `${repoLogin.username} · ${domainDisplayName(repoLogin.domain)}` : '光湖语言系统'} version="0.5.0" dayNumber={dayNumber} duty={domainLabel} weatherLabel={worldClimate ? weatherLabel[worldClimate.weatherKind] : '待命'} broadcasts={traditionalBroadcasts} channels={traditionalChannels} systems={traditionalSystems} activityBars={activityBars} activityCount={activityBars.reduce((sum, value) => sum + value, 0)}/>
|
||||
{surfacePill}
|
||||
|
|
@ -2124,79 +2171,30 @@ function HoloLakeApp() {
|
|||
</>
|
||||
}
|
||||
|
||||
if (!repoLogin && surface === 'world' && gateStage === 'number' && !gateRising) {
|
||||
const activeGate = domainGates.find((gate) => gate.domain === activeDomainInfo)
|
||||
return <div className={`official-world surface-world starlake-host${motionAwake ? ' motion-awake' : ''}`} onPointerMove={wakeAmbientMotion} onPointerDown={wakeAmbientMotion} onKeyDown={wakeAmbientMotion}>
|
||||
{surfacePill}
|
||||
<StarlakeSurface awake={motionAwake} phase={worldClimate?.timePhase.toLowerCase() as 'dawn' | 'day' | 'dusk' | 'night' | undefined} weather={worldClimate?.weatherKind} authenticated={false} onDomain={(domain: DomainId) => setActiveDomainInfo(domain)} onOpenEra={openEraTimeline} onEnterChannel={() => setGateOpen(true)}/>
|
||||
{activeGate && <><button className="domain-info-scrim" type="button" aria-label="关闭域信息" onClick={() => setActiveDomainInfo('')}/><section className={`domain-info-card info-${activeGate.className.slice(2)}`} role="dialog" aria-modal="true" aria-label={`${activeGate.title}系统信息`}><button className="gate-close" type="button" aria-label="关闭域信息" onClick={() => setActiveDomainInfo('')}>×</button><b>{activeGate.title}</b><small>{activeGate.gate}</small><span className="pool-facts">{activeGate.facts.map(([label, value]) => <span className="pool-fact" key={label}><em>{label}</em><strong>{value}</strong></span>)}</span></section></>}
|
||||
{gateOpen && <section className="number-nucleus open starlake-number-entry" title="输入编号进入所属域"><button className="gate-dismiss-layer" type="button" aria-label="关闭编号验证" onClick={() => { setGateOpen(false); setGateMessage('') }}/><div className="nucleus-panel" role="dialog" aria-label="编号验证"><button className="gate-close" type="button" aria-label="关闭编号验证" onClick={() => { setGateOpen(false); setGateMessage('') }}>×</button><h2>编号验证</h2><div className="gate-pod-row"><input id="gate-number" ref={gateInputRef} aria-label="编号" autoFocus maxLength={48} value={gateNumber} placeholder="如 ICE-GL∞" onChange={(event) => onGateInput(event.target.value)} onKeyDown={(event) => { if (event.key === 'Enter' && gateNumber) { event.preventDefault(); void gateVerifyNumber() } }}/><button type="button" className={`gate-inf${gateInf ? ' on' : ''}`} title="编号包含无限符号时启用" aria-pressed={gateInf} onClick={() => setGateInf((value) => !value)}>∞</button></div><button className="gate-submit" disabled={gateBusy || !gateNumber} onClick={() => void gateVerifyNumber()}>{gateBusy ? '正在验证…' : '验证编号'}</button>{gateMessage && <p className="gate-hint">{gateMessage}</p>}</div></section>}
|
||||
{eraOpen && eraTimeline && <EraTimelineOverlay timeline={eraTimeline} coordinate={beijingCoordinate} onClose={() => setEraOpen(false)}/>}
|
||||
</div>
|
||||
}
|
||||
|
||||
if (!repoLogin) {
|
||||
const worldRevealed = gateRising || gateStage === 'key'
|
||||
const resolvedDomain = zeroPoint?.resolvedDomain || ''
|
||||
const activeGate = domainGates.find((gate) => gate.domain === activeDomainInfo)
|
||||
return <div data-finish={traditionalFinish} data-tone={visualBalance.tone} data-phase={visualBalance.phase} data-weather={visualBalance.weather} className={`official-world surface-${surface}${motionAwake ? ' motion-awake' : ''}${loginRising ? ' sinking' : ''}`} onPointerMove={wakeAmbientMotion} onPointerDown={wakeAmbientMotion} onKeyDown={wakeAmbientMotion}>
|
||||
{surfacePill}
|
||||
<LakeAtmosphere awake={motionAwake}/>
|
||||
<header className="world-titlebar"><b>HoloLake</b><div className="world-title-actions">{finishRail}<button type="button" aria-label="显示主题" onClick={() => setTheme(themes[(themes.findIndex((item) => item.id === theme) + 1) % themes.length].id)}>◌</button></div></header>
|
||||
<main className={`world-scene${gateRising ? ' resolving' : ''}${gateStage === 'key' ? ' resolved' : ''}`}>
|
||||
<div className="official-hero"><h1>光湖语言系统 · 通用人工智能操作平台</h1><p>GH-AIOS · GUANGHU AI OPERATING SYSTEM</p></div>
|
||||
{domainGates.map((gate) => <LakePool key={gate.domain} className={gate.className} title={gate.title} meta={gate.gate} open={gate.domain === 'FIFTH_DOMAIN' || (gateStage === 'key' && gate.domain === resolvedDomain)} risen={(gateRising || gateStage === 'key') && gate.domain === resolvedDomain} onClick={() => gateStage === 'number' && setActiveDomainInfo(gate.domain)}/>) }
|
||||
{activeGate && gateStage === 'number' && <>
|
||||
<button className="domain-info-scrim" type="button" aria-label="关闭域信息" onClick={() => setActiveDomainInfo('')}/>
|
||||
<section className={`domain-info-card info-${activeGate.className.slice(2)}`} role="dialog" aria-modal="true" aria-label={`${activeGate.title}系统信息`}>
|
||||
<button className="gate-close" type="button" aria-label="关闭域信息" title="关闭" onClick={() => setActiveDomainInfo('')}>×</button>
|
||||
<b>{activeGate.title}</b><small>{activeGate.gate}</small>
|
||||
<span className="pool-facts">{activeGate.facts.map(([label, value]) => <span className="pool-fact" key={label}><em>{label}</em><strong>{value}</strong></span>)}</span>
|
||||
</section>
|
||||
</>}
|
||||
{gateRising ? <section className="world-welcome" role="status">
|
||||
<h2>编号 {gateNumber} · 欢迎登入光湖语言世界</h2>
|
||||
<p>RESOLVED · {domainDisplayName(resolvedDomain)} · 已接入</p>
|
||||
{gateWelcomeLine && <blockquote className="world-impression">{gateWelcomeLine}</blockquote>}
|
||||
</section> : gateStage === 'number' ? <section className={`number-nucleus${gateOpen ? ' open' : ''}`} title="输入编号进入所属域">
|
||||
<button className="nucleus-locus" type="button" aria-expanded={gateOpen} onClick={() => setGateOpen(true)}><i/><b>编号验证 · 进入世界的第一个入口</b></button>
|
||||
{gateOpen && <button
|
||||
className="gate-dismiss-layer"
|
||||
type="button"
|
||||
aria-label="关闭编号验证"
|
||||
onClick={() => { setGateOpen(false); setGateMessage('') }}
|
||||
/>}
|
||||
<div className="nucleus-panel" role="dialog" aria-label="编号验证">
|
||||
<button className="gate-close" type="button" aria-label="关闭编号验证" title="关闭" onClick={() => { setGateOpen(false); setGateMessage('') }}>×</button>
|
||||
<h2>编号验证</h2>
|
||||
<div className="gate-pod-row">
|
||||
<input id="gate-number" ref={gateInputRef} aria-label="编号" maxLength={48} value={gateNumber} placeholder="如 ICE-GL∞" onChange={(event) => onGateInput(event.target.value)} onKeyDown={(event) => { if (event.key === 'Enter' && gateNumber) { event.preventDefault(); void gateVerifyNumber() } }}/>
|
||||
<button type="button" className={`gate-inf${gateInf ? ' on' : ''}`} title="编号包含无限符号时启用" aria-pressed={gateInf} onClick={() => setGateInf((value) => !value)}>∞</button>
|
||||
</div>
|
||||
<button className="gate-submit" disabled={gateBusy || !gateNumber} onClick={() => void gateVerifyNumber()}>{gateBusy ? '正在验证…' : '验证编号'}</button>
|
||||
{gateMessage && <p className="gate-hint">{gateMessage}</p>}
|
||||
</div>
|
||||
</section> : <>
|
||||
<section className="resolved-heading"><h2>编号 {zeroPoint?.userNumber || gateNumber} · 欢迎登入光湖语言世界</h2><p>RESOLVED · {domainDisplayName(resolvedDomain)} · 已接入</p>{gateWelcomeLine && <blockquote className="world-impression">{gateWelcomeLine}</blockquote>}</section>
|
||||
<section className={`domain-credential${loginRising ? ' fade-out' : ''}`} role="dialog">
|
||||
<form onSubmit={(event) => void (passwordChangeMode ? changeFirstLoginPassword(event) : performRepoLogin(event))}>
|
||||
<h3>{domainDisplayName(resolvedDomain)} · 域凭证</h3>
|
||||
<input id="repo-login-username" aria-label="账号" autoFocus maxLength={40} value={loginUsername} placeholder="账号" onChange={(event) => setLoginUsername(event.target.value)}/>
|
||||
<input id="repo-login-password" aria-label={passwordChangeMode ? '一次性密码' : '密码'} type="password" maxLength={512} value={loginPassword} placeholder={passwordChangeMode ? '一次性密码' : '密码'} onChange={(event) => setLoginPassword(event.target.value)}/>
|
||||
{passwordChangeMode && <>
|
||||
<input aria-label="新密码" type="password" minLength={14} maxLength={128} value={newLoginPassword} placeholder="设置新密码(至少 14 位)" onChange={(event) => setNewLoginPassword(event.target.value)}/>
|
||||
<input aria-label="确认新密码" type="password" minLength={14} maxLength={128} value={confirmLoginPassword} placeholder="再次输入新密码" onChange={(event) => setConfirmLoginPassword(event.target.value)}/>
|
||||
</>}
|
||||
<button className="gate-submit" disabled={loginBusy || !loginUsername.trim() || !loginPassword || (passwordChangeMode && (!newLoginPassword || !confirmLoginPassword))}>{loginBusy ? '正在处理…' : passwordChangeMode ? '修改密码' : '验证并进入'}</button>
|
||||
</form>
|
||||
{loginMessage && <p className="gate-hint">{loginMessage}</p>}
|
||||
{(zeroPoint?.resolvedDomain !== 'FIFTH_DOMAIN' || zeroPoint?.userNumber === 'ICE-GL-ZHI∞') && <button className="gate-back" type="button" onClick={() => { setPasswordChangeMode((value) => !value); setLoginMessage(''); setNewLoginPassword(''); setConfirmLoginPassword('') }}>{passwordChangeMode ? '返回正常登录' : '第一次使用?先修改一次性密码'}</button>}
|
||||
<button className="gate-back" type="button" onClick={() => { setGateStage('number'); setGateMessage(''); setLoginMessage('') }}>返回编号验证</button>
|
||||
</section>
|
||||
</>}
|
||||
{gateStage === 'number' && !gateOpen && !activeDomainInfo && <EraHomeEntry timeline={eraTimeline} coordinate={beijingCoordinate} onOpen={openEraTimeline}/>}
|
||||
</main>
|
||||
<footer className="world-footer"><b>光湖语言系统 · 通用人工智能操作平台</b><span>GH-AIOS</span></footer>
|
||||
{eraOpen && eraTimeline && <EraTimelineOverlay timeline={eraTimeline} coordinate={beijingCoordinate} onClose={() => setEraOpen(false)}/>}
|
||||
return <div className={`official-world surface-world starlake-host${motionAwake ? ' motion-awake' : ''}`} onPointerMove={wakeAmbientMotion} onPointerDown={wakeAmbientMotion} onKeyDown={wakeAmbientMotion}>
|
||||
<StarlakeSurface awake={motionAwake} phase={worldClimate?.timePhase.toLowerCase() as 'dawn' | 'day' | 'dusk' | 'night' | undefined} weather={worldClimate?.weatherKind} authenticated={false} worldRevealed={worldRevealed} worldRevealing={gateRising} gateExpanded={gateOpen && gateStage === 'number'} resolvedDomain={resolvedDomain as DomainId | ''} onDomain={(domain) => { if (worldRevealed) openPublicDomain(domain) }} onOpenEra={openEraTimeline} onOpenGate={() => setGateOpen(true)}/>
|
||||
{activeGate && worldRevealed && !publicDomain && <><button className="domain-info-scrim" type="button" aria-label="关闭域信息" onClick={() => setActiveDomainInfo('')}/><section className={`domain-info-card info-${activeGate.className.slice(2)}`} role="dialog" aria-modal="true" aria-label={`${activeGate.title}系统信息`}><button className="gate-close" type="button" aria-label="关闭域信息" onClick={() => setActiveDomainInfo('')}>×</button><b>{activeGate.title}</b><small>{activeGate.gate}</small><span className="pool-facts">{activeGate.facts.map(([label, value]) => <span className="pool-fact" key={label}><em>{label}</em><strong>{value}</strong></span>)}</span></section></>}
|
||||
{worldRevealed && publicDomainPortal(false)}
|
||||
{gateStage === 'number' && gateOpen && <section className="star-abyss-dialog" title="输入编号展开语言世界"><button className="gate-dismiss-layer" type="button" aria-label="关闭编号验证" onClick={() => { setGateOpen(false); setGateMessage('') }}/><div className="abyss-panel" role="dialog" aria-label="编号验证"><button className="gate-close" type="button" aria-label="关闭编号验证" onClick={() => { setGateOpen(false); setGateMessage('') }}>×</button><p>语言世界尚未展开</p><h2>编号验证</h2><div className="gate-pod-row"><input id="gate-number" ref={gateInputRef} aria-label="编号" autoFocus maxLength={48} value={gateNumber} placeholder="如 ICE-GL∞" onChange={(event) => onGateInput(event.target.value)} onKeyDown={(event) => { if (event.key === 'Enter' && gateNumber) { event.preventDefault(); void gateVerifyNumber() } }}/><button type="button" className={`gate-inf${gateInf ? ' on' : ''}`} title="编号包含无限符号时启用" aria-pressed={gateInf} onClick={() => setGateInf((value) => !value)}>∞</button></div><button className="gate-submit" disabled={gateBusy || !gateNumber} onClick={() => void gateVerifyNumber()}>{gateBusy ? '正在验证…' : '验证编号'}</button>{gateMessage && <p className="gate-hint">{gateMessage}</p>}</div></section>}
|
||||
{gateRising && <section className="world-unfolding" role="status"><h2>编号 {gateNumber} · 语言世界正在展开</h2><p>RESOLVED · {domainDisplayName(resolvedDomain)} · 五湖正在浮现</p></section>}
|
||||
{gateStage === 'key' && !publicDomain && !activeDomainInfo && <section className={`domain-credential starlake-credential${loginRising ? ' fade-out' : ''}`} role="dialog" aria-label="进入频道">
|
||||
<form onSubmit={(event) => void (passwordChangeMode ? changeFirstLoginPassword(event) : performRepoLogin(event))}>
|
||||
<p className="credential-purpose">进入频道</p>
|
||||
<h3>{domainDisplayName(resolvedDomain)} · 域凭证</h3>
|
||||
<input id="repo-login-username" aria-label="账号" autoFocus maxLength={40} value={loginUsername} placeholder="账号" onChange={(event) => setLoginUsername(event.target.value)}/>
|
||||
<input id="repo-login-password" aria-label={passwordChangeMode ? '一次性密码' : '密码'} type="password" maxLength={512} value={loginPassword} placeholder={passwordChangeMode ? '一次性密码' : '密码'} onChange={(event) => setLoginPassword(event.target.value)}/>
|
||||
{passwordChangeMode && <><input aria-label="新密码" type="password" minLength={14} maxLength={128} value={newLoginPassword} placeholder="设置新密码(至少 14 位)" onChange={(event) => setNewLoginPassword(event.target.value)}/><input aria-label="确认新密码" type="password" minLength={14} maxLength={128} value={confirmLoginPassword} placeholder="再次输入新密码" onChange={(event) => setConfirmLoginPassword(event.target.value)}/></>}
|
||||
<button className="gate-submit" disabled={loginBusy || !loginUsername.trim() || !loginPassword || (passwordChangeMode && (!newLoginPassword || !confirmLoginPassword))}>{loginBusy ? '正在处理…' : passwordChangeMode ? '修改密码' : '验证并进入'}</button>
|
||||
</form>
|
||||
{loginMessage && <p className="gate-hint">{loginMessage}</p>}
|
||||
{(zeroPoint?.resolvedDomain !== 'FIFTH_DOMAIN' || zeroPoint?.userNumber === 'ICE-GL-ZHI∞') && <button className="gate-back" type="button" onClick={() => { setPasswordChangeMode((value) => !value); setLoginMessage(''); setNewLoginPassword(''); setConfirmLoginPassword('') }}>{passwordChangeMode ? '返回正常登录' : '第一次使用?先修改一次性密码'}</button>}
|
||||
<button className="gate-back" type="button" onClick={() => { setGateStage('number'); setGateMessage(''); setLoginMessage('') }}>返回编号验证</button>
|
||||
</section>}
|
||||
{worldRevealed && eraOpen && eraTimeline && <EraTimelineOverlay timeline={eraTimeline} coordinate={beijingCoordinate} onClose={() => setEraOpen(false)}/>}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
|
@ -2217,10 +2215,11 @@ function HoloLakeApp() {
|
|||
]
|
||||
return <div data-finish={traditionalFinish} data-tone={visualBalance.tone} data-phase={visualBalance.phase} data-weather={visualBalance.weather} className={`official-world surface-${surface} signed-in-world${motionAwake ? ' motion-awake' : ''}${climateClasses}${worldStage === 'domain' && surface === 'world' ? ' qoder-home' : ''}`} onPointerMove={wakeAmbientMotion} onPointerDown={wakeAmbientMotion} onKeyDown={wakeAmbientMotion}>
|
||||
{surfacePill}
|
||||
<LakeAtmosphere awake={motionAwake}/>
|
||||
<header className="world-titlebar"><b>HoloLake</b><div className="world-title-actions">{finishRail}<span>{repoLogin.username} · {domainDisplayName(repoLogin.domain)}</span><button type="button" onClick={() => setTheme(themes[(themes.findIndex((item) => item.id === theme) + 1) % themes.length].id)}>◌</button><button type="button" onClick={() => void signOutRepo()}>退出</button></div></header>
|
||||
{!(worldStage === 'domain' && surface === 'world') && <LakeAtmosphere awake={motionAwake}/>}
|
||||
<header className="world-titlebar"><b>HoloLake</b><div className="world-title-actions">{finishRail}<span>{repoLogin.username} · {domainDisplayName(repoLogin.domain)}</span><WorldThemeMenu theme={theme} onSelect={setTheme}/><button type="button" onClick={() => void signOutRepo()}>退出</button></div></header>
|
||||
<main className="world-scene signed-in-scene">
|
||||
{worldStage === 'domain' && surface === 'world' && <StarlakeSurface awake={motionAwake} phase={worldClimate?.timePhase.toLowerCase() as 'dawn' | 'day' | 'dusk' | 'night' | undefined} weather={worldClimate?.weatherKind} authenticated onDomain={(domain: DomainId) => setActiveDomainInfo(domain)} onOpenEra={openEraTimeline} onEnterChannel={() => setWorldStage(repoLogin.domain === 'FIFTH_DOMAIN' ? 'channel' : 'channel')}/>}
|
||||
{worldStage === 'domain' && surface === 'world' && <StarlakeSurface awake={motionAwake} phase={worldClimate?.timePhase.toLowerCase() as 'dawn' | 'day' | 'dusk' | 'night' | undefined} weather={worldClimate?.weatherKind} authenticated worldRevealed onDomain={openPublicDomain} onOpenEra={openEraTimeline} onOpenGate={() => setWorldStage('channel')}/>}
|
||||
{worldStage === 'domain' && surface === 'world' && publicDomainPortal(true)}
|
||||
{worldStage === 'domain' && surface !== 'world' && <section className="domain-home">
|
||||
<div className="world-location"><h1>{repoLogin.domain === 'FIFTH_DOMAIN' ? domainDisplayName(repoLogin.domain) : '光湖零感域'}</h1><p>{repoLogin.domain === 'FIFTH_DOMAIN' ? '世界正在发生什么' : '公共工作入口 · 世界正在发生什么'}</p></div>
|
||||
<div className="broadcast-stream"><p><i/>光湖公共灯塔 · 在线</p><p><i/>协议版本 · {enterpriseEntry?.registry_version || 'HLDP v1.0'}</p>{repoLogin.domain !== 'FIFTH_DOMAIN' && <p><i/>本人责任域 · {domainDisplayName(enterpriseEntry?.subject.domain || repoLogin.domain)}</p>}<p><i/>HoloLake · V0.5.0</p></div>
|
||||
|
|
@ -2261,19 +2260,19 @@ function HoloLakeApp() {
|
|||
<button className="world-back" type="button" onClick={() => setWorldStage('domain')}>← 退回域首页</button>
|
||||
<div className="world-location"><h1>{repoLogin.domain === 'FIFTH_DOMAIN' ? '永恒湖心系统' : '光湖频道'}</h1><p>选择路径 · 湖面向下一层展开</p></div>
|
||||
{repoLogin.domain === 'FIFTH_DOMAIN' ? <>
|
||||
<LakePool className="channel-main" title="奶瓶频道" meta="光湖奶瓶小宝宝系统 · 私人" open onClick={() => setWorldStage('bottle')}/>
|
||||
<LakePool className="channel-primary" title="奶瓶频道" meta="光湖奶瓶小宝宝系统 · 私人" open onClick={() => setWorldStage('bottle')}/>
|
||||
<LakePool className="channel-knowledge system-branch-heartbeat" title="心跳核心频道" meta="冰朔 · 私人频道" open onClick={() => setWorldStage('heartbeat')}/>
|
||||
<LakePool className="channel-code system-branch-light-lake" title="光之湖" meta="人格体居所" onClick={() => setWorldStage('lightLake')}/>
|
||||
<LakePool className="channel-light system-branch-love" title="爱之核心子系统" meta="责任主体 · 之之" onClick={() => setWorldStage('love')}/>
|
||||
<LakePool className="channel-main" title="分域模块商城" meta="线上成品模块 · 只读思维技能" onClick={openMarketplace}/>
|
||||
<LakePool className="channel-status" title="湖面天气" meta={connectionLabel} onClick={() => openWorldTool('system')}/>
|
||||
<LakePool className="channel-marketplace" title="分域模块商城" meta="线上成品模块 · 只读思维技能" onClick={openMarketplace}/>
|
||||
<LakePool className="channel-weather" title="湖面天气" meta={connectionLabel} onClick={() => openWorldTool('system')}/>
|
||||
</> : <>
|
||||
<LakePool className="channel-main" title={domainDisplayName(enterpriseEntry?.subject.domain || repoLogin.domain)} meta="本人责任工作域" open={enterpriseWork?.state === 'READY_READ_ONLY_WORK_PROJECTION'} onClick={() => setWorldStage('enterpriseWork')}/>
|
||||
<LakePool className="channel-primary" title={domainDisplayName(enterpriseEntry?.subject.domain || repoLogin.domain)} meta="本人责任工作域" open={enterpriseWork?.state === 'READY_READ_ONLY_WORK_PROJECTION'} onClick={() => setWorldStage('enterpriseWork')}/>
|
||||
<LakePool className="channel-code" title="私有责任工作仓库" meta={enterpriseWork ? `${enterpriseWork.repository} · 已认证` : userPnccBusy ? '正在接入' : '暂不可用'} onClick={() => void openEnterpriseRepository()}/>
|
||||
<LakePool className="channel-light" title="责任签署状态" meta={enterpriseEntry?.responsibility_receipt?.decision === 'ACCEPT' ? '已接受 · 已留存' : '等待本人确认'} onClick={() => openWorldTool('receipts')}/>
|
||||
<LakePool className="channel-knowledge" title="前往我的频道" meta="接入说明 · 由本人或人格体完成" onClick={() => setWorldStage('personalNodeGuide')}/>
|
||||
<LakePool className="channel-main" title="分域模块商城" meta="线上成品模块 · 只读思维技能" onClick={openMarketplace}/>
|
||||
<LakePool className="channel-status" title="湖面天气" meta={connectionLabel} onClick={() => openWorldTool('system')}/>
|
||||
<LakePool className="channel-marketplace" title="分域模块商城" meta="线上成品模块 · 只读思维技能" onClick={openMarketplace}/>
|
||||
<LakePool className="channel-weather" title="湖面天气" meta={connectionLabel} onClick={() => openWorldTool('system')}/>
|
||||
</>}
|
||||
</section>}
|
||||
{worldStage === 'enterpriseWork' && repoLogin.domain !== 'FIFTH_DOMAIN' && <section className="channel-world enterprise-work-world">
|
||||
|
|
@ -2312,7 +2311,7 @@ function HoloLakeApp() {
|
|||
<div className={`tool-projection${inspectorOpen ? '' : ' inspector-closed'}`}>{view === 'overview' ? renderOverview() : view === 'knowledge' ? renderKnowledge() : view === 'composition' ? renderComposition() : view === 'workbench' ? renderWorkbench() : view === 'education' ? renderEducation() : view === 'webNovel' ? renderWebNovel() : view === 'mobileSync' ? renderMobileSync() : view === 'persona' ? renderPersonaBody() : view === 'code' ? renderCode() : view === 'marketplace' ? renderMarketplace() : view === 'receipts' ? renderReceipts() : renderSystem()}</div>
|
||||
</section>}
|
||||
</main>
|
||||
{worldStage === 'domain' && surface === 'world' && signedActiveGate && <><button className="domain-info-scrim" type="button" aria-label="关闭域信息" onClick={() => setActiveDomainInfo('')}/><section className={`domain-info-card info-${signedActiveGate.className.slice(2)}`} role="dialog" aria-modal="true" aria-label={`${signedActiveGate.title}系统信息`}><button className="gate-close" type="button" aria-label="关闭域信息" onClick={() => setActiveDomainInfo('')}>×</button><b>{signedActiveGate.title}</b><small>{signedActiveGate.gate}</small><span className="pool-facts">{signedActiveGate.facts.map(([label, value]) => <span className="pool-fact" key={label}><em>{label}</em><strong>{value}</strong></span>)}</span></section></>}
|
||||
{worldStage === 'domain' && surface === 'world' && signedActiveGate && !publicDomain && <><button className="domain-info-scrim" type="button" aria-label="关闭域信息" onClick={() => setActiveDomainInfo('')}/><section className={`domain-info-card info-${signedActiveGate.className.slice(2)}`} role="dialog" aria-modal="true" aria-label={`${signedActiveGate.title}系统信息`}><button className="gate-close" type="button" aria-label="关闭域信息" onClick={() => setActiveDomainInfo('')}>×</button><b>{signedActiveGate.title}</b><small>{signedActiveGate.gate}</small><span className="pool-facts">{signedActiveGate.facts.map(([label, value]) => <span className="pool-fact" key={label}><em>{label}</em><strong>{value}</strong></span>)}</span></section></>}
|
||||
<footer className="world-footer"><b>光湖语言系统 · 通用人工智能操作平台</b><span>GH-AIOS</span></footer>
|
||||
{eraOpen && eraTimeline && <EraTimelineOverlay timeline={eraTimeline} coordinate={beijingCoordinate} onClose={() => setEraOpen(false)}/>}
|
||||
{enterpriseEntryBusy && <div className="enterprise-gate"><section><p>正在读取企业责任登记……</p></section></div>}
|
||||
|
|
|
|||
Loading…
Reference in a new issue