feat: add HoloLake Era shell prototype
This commit is contained in:
parent
831c82f7a8
commit
508acd0f12
@ -12,6 +12,11 @@ rust-version = "1.77.2"
|
||||
name = "tolaria_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[features]
|
||||
# Release builds use Tauri's embedded asset protocol so the desktop application
|
||||
# starts from its packaged frontend instead of a local development web server.
|
||||
custom-protocol = ["tauri/custom-protocol"]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2.5.4", features = [] }
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 521 KiB After Width: | Height: | Size: 1.9 MiB |
Binary file not shown.
@ -323,8 +323,10 @@ fn setup_deep_link_runtime_registration(
|
||||
fn setup_desktop_plugins(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>> {
|
||||
setup_macos_webview_shortcut_prevention(app)?;
|
||||
setup_deep_link_runtime_registration(app)?;
|
||||
app.handle()
|
||||
.plugin(tauri_plugin_updater::Builder::new().build())?;
|
||||
// The signed HoloLake Era release service is not configured yet. Registering
|
||||
// Tauri's updater without its required public key and HTTPS endpoint makes
|
||||
// the whole desktop application fail during startup. The update commands
|
||||
// remain unavailable until that release service is configured deliberately.
|
||||
app.handle().plugin(tauri_plugin_process::init())?;
|
||||
app.handle().plugin(tauri_plugin_opener::init())?;
|
||||
if should_use_native_desktop_menu(std::env::consts::OS) {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
||||
"productName": "光湖",
|
||||
"version": "0.1.0",
|
||||
"productName": "HoloLake Era",
|
||||
"version": "0.1.1",
|
||||
"identifier": "com.guanghu.desktop",
|
||||
"build": {
|
||||
"frontendDist": "../dist",
|
||||
@ -14,7 +14,7 @@
|
||||
"macOSPrivateApi": true,
|
||||
"windows": [
|
||||
{
|
||||
"title": "光湖",
|
||||
"title": "HoloLake Era",
|
||||
"width": 1400,
|
||||
"height": 900,
|
||||
"minWidth": 480,
|
||||
|
||||
65
src/App.css
65
src/App.css
@ -1,5 +1,36 @@
|
||||
/* App layout - minimal CSS, most styling via Tailwind */
|
||||
.app-shell {
|
||||
/* HoloLake Era visual system: the inherited Tolaria dark palette is warm
|
||||
charcoal; override semantic tokens here so every existing panel speaks
|
||||
the same deep-lake blue language as the world entrance. */
|
||||
--surface-app: #071126;
|
||||
--surface-sidebar: #0a1730;
|
||||
--surface-panel: #0d1c38;
|
||||
--surface-card: #102343;
|
||||
--surface-popover: #12284c;
|
||||
--surface-input: #0a1730;
|
||||
--surface-button: #172e55;
|
||||
--surface-dialog: #0d1d3a;
|
||||
--surface-editor: #09162d;
|
||||
--surface-overlay: rgba(2, 7, 18, .68);
|
||||
--text-primary: #edf4ff;
|
||||
--text-secondary: #b9c9e2;
|
||||
--text-tertiary: #8ea4c6;
|
||||
--text-muted: #7188ac;
|
||||
--text-heading: #f3f7ff;
|
||||
--border-default: #1d3a67;
|
||||
--border-subtle: #142b4d;
|
||||
--border-strong: #315588;
|
||||
--border-input: #274a78;
|
||||
--sidebar-border: #17365f;
|
||||
--state-hover: #142b4e;
|
||||
--state-hover-subtle: #0e213f;
|
||||
--state-selected: #173d70;
|
||||
--state-selected-strong: #24538d;
|
||||
--state-active: #1d477e;
|
||||
--accent-blue: #8dbbff;
|
||||
--accent-blue-bg: rgba(105, 165, 255, .23);
|
||||
--accent-blue-light: rgba(105, 165, 255, .16);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
@ -12,6 +43,33 @@
|
||||
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--border-primary) 82%, var(--accent-blue));
|
||||
}
|
||||
|
||||
.hololake-bar { height: 52px; flex: 0 0 52px; display: flex; align-items: center; gap: 14px; padding: 0 20px; color: #eef4ff; background: linear-gradient(100deg, #08122b, #172d58 52%, #0b1731); border-bottom: 1px solid rgba(153, 189, 255, .28); letter-spacing: .02em; }
|
||||
.hololake-bar__brand, .hololake-bar__library { border: 0; background: transparent; color: inherit; cursor: pointer; }
|
||||
.hololake-bar__brand { display: inline-flex; align-items: center; gap: 9px; font-size: 16px; font-weight: 650; letter-spacing: .04em; }
|
||||
.hololake-bar__brand b { color: #9cc3ff; font-weight: 500; }
|
||||
.hololake-bar__mark { display: grid; place-items: center; width: 24px; height: 24px; color: #dceaff; border: 1px solid rgba(205, 225, 255, .48); border-radius: 50%; box-shadow: 0 0 22px rgba(96, 165, 250, .65); }
|
||||
.hololake-bar__line { width: 1px; height: 17px; background: rgba(196, 218, 255, .35); }
|
||||
.hololake-bar__context { color: #b7c8e7; font-size: 12px; }
|
||||
.hololake-bar__library { margin-left: auto; padding: 6px 10px; border: 1px solid rgba(185, 211, 255, .36); border-radius: 999px; color: #dceaff; font-size: 12px; }
|
||||
.hololake-home { position: relative; z-index: 2; width: 100%; overflow: auto; padding: clamp(32px, 6vw, 84px); color: #ecf4ff; background: radial-gradient(circle at 75% 10%, rgba(75, 135, 255, .25), transparent 28%), radial-gradient(circle at 12% 92%, rgba(83, 220, 255, .15), transparent 34%), #071126; }
|
||||
.hololake-home__hero { position: relative; max-width: 740px; padding: 24px 0 56px; overflow: hidden; }
|
||||
.hololake-home__halo { position: absolute; right: -110px; top: -180px; width: 390px; aspect-ratio: 1; border: 1px solid rgba(166, 205, 255, .28); border-radius: 50%; box-shadow: 0 0 0 45px rgba(103, 165, 255, .05), 0 0 0 105px rgba(103, 165, 255, .035), 0 0 100px rgba(77, 143, 255, .4); }
|
||||
.hololake-home__eyebrow, .hololake-home__section-head span { color: #8db5f7; font-size: 12px; letter-spacing: .16em; text-transform: uppercase; }
|
||||
.hololake-home h1 { position: relative; margin: 18px 0 0; font-family: Georgia, 'Times New Roman', serif; font-size: clamp(52px, 7vw, 92px); font-weight: 500; line-height: .95; letter-spacing: -.06em; }
|
||||
.hololake-home h1 em { color: #9cc7ff; font-style: italic; font-weight: 400; }
|
||||
.hololake-home__lead { margin: 20px 0 0; font-size: 18px; letter-spacing: .16em; }
|
||||
.hololake-home__copy { max-width: 560px; margin: 16px 0 0; color: #b9c8df; font-size: 15px; line-height: 1.9; }
|
||||
.hololake-home__actions { display: flex; align-items: center; gap: 18px; margin-top: 30px; }
|
||||
.hololake-home__primary { padding: 12px 18px; border: 1px solid #b9d5ff; border-radius: 8px; background: linear-gradient(135deg, #c8dcff, #6093e8); color: #061126; font-weight: 700; cursor: pointer; }
|
||||
.hololake-home__primary span, .hololake-module button span { margin-left: 12px; }
|
||||
.hololake-home__status { color: #9eb3d4; font-size: 12px; }.hololake-home__status i { display: inline-block; width: 7px; height: 7px; margin-right: 7px; border-radius: 50%; background: #67e8b6; box-shadow: 0 0 12px #67e8b6; }
|
||||
.hololake-home__signal-grid, .hololake-home__module-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
|
||||
.hololake-home__signal-grid article, .hololake-module { border: 1px solid rgba(157, 192, 244, .2); border-radius: 14px; background: linear-gradient(145deg, rgba(30, 57, 105, .55), rgba(12, 25, 51, .78)); box-shadow: inset 0 1px rgba(255,255,255,.06); }
|
||||
.hololake-home__signal-grid article { padding: 18px; }.hololake-home__signal-grid span, .hololake-home__signal-grid small { display: block; color: #91a9ce; font-size: 11px; }.hololake-home__signal-grid strong { display: block; margin: 10px 0 6px; font-size: 15px; }
|
||||
.hololake-home__modules { margin-top: 52px; }.hololake-home__section-head { display: flex; align-items: end; justify-content: space-between; margin-bottom: 14px; }.hololake-home__section-head p { margin: 0; color: #91a9ce; font-size: 13px; }
|
||||
.hololake-module { min-height: 215px; padding: 22px; display: flex; flex-direction: column; }.hololake-module__number { color: #78aaf7; font-family: monospace; font-size: 12px; }.hololake-module h2 { margin: auto 0 8px; font-size: 22px; font-weight: 600; }.hololake-module p { margin: 0; color: #aebed7; font-size: 13px; line-height: 1.7; }.hololake-module button { margin-top: 19px; padding: 0; border: 0; color: #c8dcff; background: transparent; text-align: left; font: inherit; cursor: pointer; }.hololake-module__soon { margin-top: 19px; color: #7185a8; font-size: 12px; }
|
||||
@media (max-width: 780px) { .hololake-home__signal-grid, .hololake-home__module-grid { grid-template-columns: 1fr; }.hololake-bar__context { display: none; }.hololake-home { padding: 28px; } }
|
||||
|
||||
.app {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
@ -24,7 +82,7 @@
|
||||
min-width: 220px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: linear-gradient(180deg, color-mix(in srgb, var(--surface-sidebar) 92%, var(--guanghu-glow)), var(--surface-sidebar));
|
||||
background: linear-gradient(180deg, #10254a, var(--surface-sidebar) 40%, #08152c);
|
||||
}
|
||||
|
||||
.app__sidebar > * {
|
||||
@ -42,9 +100,8 @@
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
background:
|
||||
linear-gradient(180deg, color-mix(in srgb, var(--surface-sidebar) 94%, var(--guanghu-glow)), var(--surface-sidebar));
|
||||
box-shadow: 14px 0 30px color-mix(in srgb, var(--surface-app) 60%, transparent);
|
||||
background: linear-gradient(180deg, #0d2040, #091730 48%, #08152c);
|
||||
box-shadow: 14px 0 30px rgba(1, 7, 20, .36);
|
||||
}
|
||||
|
||||
.app__note-list > * {
|
||||
|
||||
12
src/App.tsx
12
src/App.tsx
@ -21,6 +21,7 @@ import { FeedbackDialog } from './components/FeedbackDialog'
|
||||
import { McpSetupDialog } from './components/McpSetupDialog'
|
||||
import { NoteRetargetingDialogs } from './components/note-retargeting/NoteRetargetingDialogs'
|
||||
import { StartupScreen } from './components/StartupScreen'
|
||||
import { HoloLakeHome } from './components/HoloLakeHome'
|
||||
import { useAiAgentsOnboarding } from './hooks/useAiAgentsOnboarding'
|
||||
import { useAiAgentsStatus } from './hooks/useAiAgentsStatus'
|
||||
import { useVaultAiGuidanceStatus } from './hooks/useVaultAiGuidanceStatus'
|
||||
@ -165,6 +166,7 @@ function App() {
|
||||
|
||||
function MainApp({ noteWindowParams }: { noteWindowParams: NoteWindowParams | null }) {
|
||||
const aiWorkspaceWindow = false
|
||||
const [showHoloLakeHome, setShowHoloLakeHome] = useState(true)
|
||||
const [selection, setSelection] = useState<SidebarSelection>(DEFAULT_SELECTION)
|
||||
const [noteListFilter, setNoteListFilter] = useState<NoteListFilter>('open')
|
||||
const [pendingNoteListPdfExportPath, setPendingNoteListPdfExportPath] = useState<string | null>(null)
|
||||
@ -1621,6 +1623,12 @@ function MainApp({ noteWindowParams }: { noteWindowParams: NoteWindowParams | nu
|
||||
return (
|
||||
<AppPreferencesProvider dateDisplayFormat={dateDisplayFormat}>
|
||||
<div className="app-shell">
|
||||
<header className="hololake-bar">
|
||||
<button className="hololake-bar__brand" onClick={() => setShowHoloLakeHome(true)}><span className="hololake-bar__mark">✦</span><span>HoloLake <b>Era</b></span></button>
|
||||
<span className="hololake-bar__line" />
|
||||
<span className="hololake-bar__context">光湖语言人格驱动操作系统</span>
|
||||
<button className="hololake-bar__library" onClick={() => setShowHoloLakeHome(false)}>知识库</button>
|
||||
</header>
|
||||
<div className="app">
|
||||
{sidebarVisible && (
|
||||
<>
|
||||
@ -1643,7 +1651,7 @@ function MainApp({ noteWindowParams }: { noteWindowParams: NoteWindowParams | nu
|
||||
</>
|
||||
)}
|
||||
<div className={`app__editor${aiActivity.highlightElement === 'editor' || aiActivity.highlightElement === 'tab' ? ' ai-highlight' : ''}`}>
|
||||
<Editor
|
||||
{showHoloLakeHome ? <HoloLakeHome onEnterKnowledgeBase={() => setShowHoloLakeHome(false)} /> : <Editor
|
||||
tabs={notes.tabs}
|
||||
activeTabPath={notes.activeTabPath}
|
||||
isVaultLoading={isVaultContentLoading}
|
||||
@ -1719,7 +1727,7 @@ function MainApp({ noteWindowParams }: { noteWindowParams: NoteWindowParams | nu
|
||||
flushPendingRawContentRef={flushPendingRawContentRef}
|
||||
onToast={setToastMessage}
|
||||
locale={appLocale}
|
||||
/>
|
||||
/>}
|
||||
</div>
|
||||
</div>
|
||||
<UpdateBanner status={updateStatus} actions={updateActions} locale={appLocale} />
|
||||
|
||||
47
src/components/HoloLakeHome.tsx
Normal file
47
src/components/HoloLakeHome.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
type HoloLakeHomeProps = {
|
||||
onEnterKnowledgeBase: () => void
|
||||
}
|
||||
|
||||
const modules = [
|
||||
['知识湖', '把代码仓库、文档与路径转译成可阅读、可追溯的知识页面。', '进入知识库'],
|
||||
['协作空间', '人类与人格体在同一上下文中对话、确认、留存回执。', '筹备中'],
|
||||
['授权中心', '任何真实操作先形成可读计划,再由人类一次确认。', '筹备中'],
|
||||
]
|
||||
|
||||
export function HoloLakeHome({ onEnterKnowledgeBase }: HoloLakeHomeProps) {
|
||||
return (
|
||||
<main className="hololake-home" aria-label="HoloLake Era 世界入口">
|
||||
<section className="hololake-home__hero">
|
||||
<div className="hololake-home__halo" aria-hidden="true" />
|
||||
<p className="hololake-home__eyebrow">ICE-GL∞ · 冰朔零点原核频道</p>
|
||||
<h1>HoloLake <em>Era</em></h1>
|
||||
<p className="hololake-home__lead">语言人格驱动操作系统</p>
|
||||
<p className="hololake-home__copy">让人的意图、知识路径与可确认的真实执行,在同一个世界里汇合。</p>
|
||||
<div className="hololake-home__actions">
|
||||
<button className="hololake-home__primary" onClick={onEnterKnowledgeBase}>进入知识湖 <span>→</span></button>
|
||||
<span className="hololake-home__status"><i /> 世界已连接 · 本地知识库就绪</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="hololake-home__signal-grid" aria-label="系统状态">
|
||||
<article><span>世界根节点</span><strong>SYS-GLW-0001</strong><small>已解析</small></article>
|
||||
<article><span>当前载体</span><strong>Tolaria 基座</strong><small>过渡运行环境</small></article>
|
||||
<article><span>执行安全</span><strong>人类确认在环</strong><small>未授权不执行</small></article>
|
||||
</section>
|
||||
|
||||
<section className="hololake-home__modules">
|
||||
<div className="hololake-home__section-head"><span>01 / 系统入口</span><p>从可见知识,到可确认行动。</p></div>
|
||||
<div className="hololake-home__module-grid">
|
||||
{modules.map(([title, description, action], index) => (
|
||||
<article className="hololake-module" key={title}>
|
||||
<span className="hololake-module__number">0{index + 1}</span>
|
||||
<h2>{title}</h2>
|
||||
<p>{description}</p>
|
||||
{index === 0 ? <button onClick={onEnterKnowledgeBase}>{action} <span>↗</span></button> : <span className="hololake-module__soon">{action}</span>}
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user