Update Site source

This commit is contained in:
Codex committed 2026-09-25 21:49:02 -05:00
1 parent 997859434e
commit bcd4667205
2 files changed
+46 -4

No files matched your search

+11 -1
View File
@@ -14,9 +14,19 @@ const ZH={'LIFE OS / PERSONAL DESKTOP':'LIFE OS / 人生操作系统','TODAY':'
Object.assign(ZH,{
'INITIALIZING PERSONAL SYSTEM...':'正在初始化个人系统…','GOOD MORNING':'早上好','GOOD AFTERNOON':'下午好','GOOD EVENING':'晚上好','Open':'打开','Minimize':'最小化','Maximize':'最大化','Close':'关闭','Refresh desktop':'刷新桌面','New today entry':'新建今日记录','System settings':'系统设置','CLEAR':'晴朗','LIGHT':'微光','CLOUDY':'多云','RAIN':'雨天','STORM':'风暴','Clear':'晴朗','Light':'微光','Cloudy':'多云','Rain':'雨天','Storm':'风暴','DARK':'深色','LIGHT':'浅色','AUTO':'自动','Version 0.1 · Schema v1':'版本 0.1 · 架构 v1','MONDAY':'星期一','TUESDAY':'星期二','WEDNESDAY':'星期三','THURSDAY':'星期四','FRIDAY':'星期五','SATURDAY':'星期六','SUNDAY':'星期日','Monday':'星期一','Tuesday':'星期二','Wednesday':'星期三','Thursday':'星期四','Friday':'星期五','Saturday':'星期六','Sunday':'星期日','No written note.':'尚未写下记录。','EDITING AS TODAY — SAVE TO UPDATE':'正在以今日记录编辑 — 保存即可更新','MEMORY PRESERVED':'记忆已珍藏','MEMORY REMOVED':'记忆已删除','No entries yet':'暂无记录','Longest streak:':'最长连续记录:','days':'天','DAYS':'天','ENERGY':'能量','Local Storage':'本地存储','memories':'条记忆','museum items':'件博物馆藏品','Approx.':'约','KB':'KB','Life OS Backup':'Life OS 备份','Ready to restore':'准备恢复','Exported:':'导出时间:','Memories:':'记忆:','Museum Items:':'博物馆藏品:','MERGE':'合并','REPLACE ALL DATA':'替换全部数据','FINAL CONFIRMATION':'最终确认','Replace all Life OS data?':'替换全部 Life OS 数据?','This will replace all current Life OS data.':'这将覆盖当前所有 Life OS 数据。','REPLACE DATA':'替换数据','Reset all local data?':'重置所有本地数据?','Export a backup first if you want to keep it.':'如需保留数据,请先导出备份。','RESET DATA':'重置数据','Following browser language: English':'已跟随浏览器语言:English'
});
// "LIGHT" is a weather state (微光), while a light colour scheme is 浅色.
// Keep the two meanings separate; translating visible strings by themselves
// cannot distinguish them reliably.
ZH.LIGHT='微光';
Object.assign(ZH,{
'THEME_DARK':'深色','THEME_LIGHT':'浅色','THEME_AUTO':'跟随系统',
'LANGUAGE_AUTO':'跟随浏览器','LANGUAGE_DETECTED_ZH':'当前识别:中文',
'LANGUAGE_DETECTED_EN':'Detected: English',
'MINIMIZED_RESTORE':'已最小化 — 点击任务栏图标即可恢复',
'MINIMIZED_RESTORE_EN':'MINIMIZED — TAP THE APP ICON TO RESTORE'
});
ZH['Restore window']='恢复窗口';
function browserLanguage(){let ls=navigator.languages?.length?navigator.languages:[navigator.language||'en'];return ls.some(x=>String(x).toLowerCase().startsWith('zh'))?'zh':'en'}function lang(){let s=settings();return s.languageMode==='manual'&&['en','zh'].includes(s.language)?s.language:browserLanguage()}function localizeDynamicText(zh){if(!zh)return;let walker=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT),nodes=[];while(walker.nextNode())nodes.push(walker.currentNode);nodes.forEach(node=>{let v=node.nodeValue.trim(),r,section=node.parentElement?.closest('section')?.querySelector('.eyebrow')?.textContent||'';if(v==='微光'&&section.includes('外观'))node.nodeValue=node.nodeValue.replace(v,'浅色');else if(v==='Local Storage')node.nodeValue=node.nodeValue.replace(v,'本地存储');else if(v==='Life OS')node.nodeValue=node.nodeValue.replace(v,'人生操作系统');else if(r=v.match(/^(\d+) (?:MEMORY|MEMORIES) ARCHIVED$/))node.nodeValue=node.nodeValue.replace(v,`${r[1]} 条记忆已归档`);else if(r=v.match(/^(\d+) DAYS$/))node.nodeValue=node.nodeValue.replace(v,`${r[1]} 天`);else if(r=v.match(/^Longest streak: (\d+) days$/))node.nodeValue=node.nodeValue.replace(v,`最长连续记录:${r[1]} 天`);else if(r=v.match(/^(\d+) memories · (\d+) preserved$/))node.nodeValue=node.nodeValue.replace(v,`${r[1]} 条记忆 · ${r[2]} 件已珍藏`);else if(r=v.match(/^Exported: (.+)$/))node.nodeValue=node.nodeValue.replace(v,`导出时间:${r[1]}`);else if(r=v.match(/^Memories: (\d+)$/))node.nodeValue=node.nodeValue.replace(v,`记忆:${r[1]}`);else if(r=v.match(/^Museum Items: (\d+)$/))node.nodeValue=node.nodeValue.replace(v,`博物馆藏品:${r[1]}`);else if(r=v.match(/^LAST BACKUP · (.+)$/))node.nodeValue=node.nodeValue.replace(v,`上次备份 · ${r[1]}`);else if(r=v.match(/^(\d+) memories · (\d+) museum items · Approx\. (\d+) KB$/))node.nodeValue=node.nodeValue.replace(v,`${r[1]} 条记忆 · ${r[2]} 件博物馆藏品 · 约 ${r[3]} KB`)})}function applyLanguage(){let zh=lang()==='zh';document.documentElement.lang=zh?'zh-CN':'en';document.title=zh?'Life OS / 人生操作系统':'Life OS';let map=zh?ZH:Object.fromEntries(Object.entries(ZH).map(([a,b])=>[b,a]));let walker=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT);let n=[];while(walker.nextNode())n.push(walker.currentNode);n.forEach(x=>{let v=x.nodeValue.trim();if(map[v])x.nodeValue=x.nodeValue.replace(v,map[v])});document.querySelectorAll('[placeholder]').forEach(x=>{if(zh&&ZH[x.placeholder])x.placeholder=ZH[x.placeholder];if(!zh){let k=Object.entries(ZH).find(([,v])=>v===x.placeholder)?.[0];if(k)x.placeholder=k}});localizeDynamicText(zh)}function setLanguage(v){let s=settings();s.language=v;s.languageMode=v==='auto'?'auto':'manual';save('lifeos_settings',s);renderIcons();renderAll();applyLanguage();toast(v==='auto'?(lang()==='zh'?'已跟随浏览器语言:中文':'Following browser language: English'):v==='zh'?'语言已切换为中文':'Language set to English')}
function browserLanguage(){let ls=navigator.languages?.length?navigator.languages:[navigator.language||'en'];return ls.some(x=>String(x).toLowerCase().startsWith('zh'))?'zh':'en'}function lang(){let s=settings();return s.languageMode==='manual'&&['en','zh'].includes(s.language)?s.language:browserLanguage()}function localizeDynamicText(zh){if(!zh)return;let walker=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT),nodes=[];while(walker.nextNode())nodes.push(walker.currentNode);nodes.forEach(node=>{if(node.parentElement?.closest('textarea,input,.entry,.snippet,.mtitle,.film-title,.film-copy'))return;let v=node.nodeValue.trim(),r,section=node.parentElement?.closest('section')?.querySelector('.eyebrow')?.textContent||'';if(v==='微光'&&section.includes('外观'))node.nodeValue=node.nodeValue.replace(v,'浅色');else if(v==='Local Storage')node.nodeValue=node.nodeValue.replace(v,'本地存储');else if(v==='Life OS')node.nodeValue=node.nodeValue.replace(v,'人生操作系统');else if(r=v.match(/^(\d+) (?:MEMORY|MEMORIES) ARCHIVED$/))node.nodeValue=node.nodeValue.replace(v,`${r[1]} 条记忆已归档`);else if(r=v.match(/^(\d+) DAYS$/))node.nodeValue=node.nodeValue.replace(v,`${r[1]} 天`);else if(r=v.match(/^Longest streak: (\d+) days$/))node.nodeValue=node.nodeValue.replace(v,`最长连续记录:${r[1]} 天`);else if(r=v.match(/^(\d+) memories · (\d+) preserved$/))node.nodeValue=node.nodeValue.replace(v,`${r[1]} 条记忆 · ${r[2]} 件已珍藏`);else if(r=v.match(/^Exported: (.+)$/))node.nodeValue=node.nodeValue.replace(v,`导出时间:${r[1]}`);else if(r=v.match(/^Memories: (\d+)$/))node.nodeValue=node.nodeValue.replace(v,`记忆:${r[1]}`);else if(r=v.match(/^Museum Items: (\d+)$/))node.nodeValue=node.nodeValue.replace(v,`博物馆藏品:${r[1]}`);else if(r=v.match(/^LAST BACKUP · (.+)$/))node.nodeValue=node.nodeValue.replace(v,`上次备份 · ${r[1]}`);else if(r=v.match(/^(\d+) memories · (\d+) museum items · Approx\. (\d+) KB$/))node.nodeValue=node.nodeValue.replace(v,`${r[1]} 条记忆 · ${r[2]} 件博物馆藏品 · 约 ${r[3]} KB`)})}function applyLanguage(){let zh=lang()==='zh';document.documentElement.lang=zh?'zh-CN':'en';document.title=zh?'Life OS / 人生操作系统':'Life OS';let map=zh?ZH:Object.fromEntries(Object.entries(ZH).map(([a,b])=>[b,a]));let walker=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT);let n=[];while(walker.nextNode())n.push(walker.currentNode);n.forEach(x=>{if(x.parentElement?.closest('textarea,input,.entry,.snippet,.mtitle,.film-title,.film-copy'))return;let v=x.nodeValue.trim();if(map[v])x.nodeValue=x.nodeValue.replace(v,map[v])});document.querySelectorAll('[placeholder]').forEach(x=>{if(zh&&ZH[x.placeholder])x.placeholder=ZH[x.placeholder];if(!zh){let k=Object.entries(ZH).find(([,v])=>v===x.placeholder)?.[0];if(k)x.placeholder=k}});localizeDynamicText(zh)}function setLanguage(v){let s=settings();s.language=v;s.languageMode=v==='auto'?'auto':'manual';save('lifeos_settings',s);renderIcons();renderAll();applyLanguage();toast(v==='auto'?(lang()==='zh'?'已跟随浏览器语言:中文':'Following browser language: English'):v==='zh'?'语言已切换为中文':'Language set to English')}
function i18n(key,fallback=key){return lang()==='zh'?(ZH[key]||key):fallback}function appName(id){return i18n(APPS[id][1])}function moodName(m){return i18n(m.toUpperCase(),cap(m))}function day(){return new Date().toISOString().slice(0,10)}function fmtDate(d){return new Date(d+'T12:00:00').toLocaleDateString(lang()==='zh'?'zh-CN':'en-US',{weekday:'long',month:'long',day:'numeric',year:'numeric'})}function shortDate(d){return new Date(d+'T12:00:00').toLocaleDateString(lang()==='zh'?'zh-CN':'en-US',lang()==='zh'?{month:'numeric',day:'numeric'}:{month:'short',day:'numeric'}).toUpperCase()}function cap(x){return x[0].toUpperCase()+x.slice(1)}function esc(s){return (s||'').replace(/[&<>]/g,x=>({'&':'&amp;','<':'&lt;','>':'&gt;'}[x]))}
function applyWallpaper(w){if(!w?.url)return;desktop.style.backgroundImage=`linear-gradient(120deg,color-mix(in srgb,var(--bg) 68%,transparent),color-mix(in srgb,var(--bg) 36%,transparent)),url('${w.url}')`;desktop.style.backgroundSize='cover';desktop.style.backgroundPosition='center';desktop.title=`Bing daily image: ${w.title||'Daily image'}`}async function loadBingWallpaper(){let s=settings();if(s.wallpaper?.date===day()&&s.wallpaper?.source==='lifeos-proxy'){applyWallpaper(s.wallpaper);return}try{let r=await fetch('/api/bing-wallpaper'),d=await r.json();if(!r.ok||!d.url)throw Error(d.error||'No Bing image');s.wallpaper={date:day(),url:'/api/bing-wallpaper-image?date='+day(),title:d.title||'Bing daily image',source:'lifeos-proxy'};save('lifeos_settings',s);applyWallpaper(s.wallpaper)}catch(e){console.info('Bing wallpaper unavailable; using the calm fallback.',e)}}function init(){let s=settings();document.documentElement.dataset.theme=s.theme==='auto'?(matchMedia('(prefers-color-scheme:light)').matches?'light':'dark'):s.theme;renderIcons();renderTaskbar();loadBingWallpaper();setInterval(clock,1000);clock();setTimeout(applyLanguage,0);setTimeout(()=>boot.remove(),650)}
function desktopIconClick(id,e){if(innerWidth<650){openApp(id);return}selectedIcon=id;document.querySelectorAll('.app-icon').forEach(x=>x.classList.remove('selected'));e.currentTarget.classList.add('selected')}function desktopIconKey(id,e){if(e.key==='Enter'||e.key===' '){e.preventDefault();openApp(id)}}function renderIcons(){icons.innerHTML=Object.entries(APPS).map(([id,[g,n]])=>`<button class="app-icon ${selectedIcon===id?'selected':''}" onclick="desktopIconClick('${id}',event)" ondblclick="openApp('${id}')" onkeydown="desktopIconKey('${id}',event)" oncontextmenu="showContext(event,'${id}')" title="${appName(id)}"><span class="glyph">${g}</span><span>${appName(id)}</span></button>`).join('')}function taskClick(id){let w=windows[id];if(!w){openApp(id);return}if(w.classList.contains('min')){openApp(id);return}if(activeWindow===id){minWin(id);return}focus(w)}function renderTaskbar(){let ids=innerWidth<650?Object.keys(windows):['today','timeline','museum','insights'];tasks.innerHTML=ids.map(id=>{let w=windows[id],min=w?.classList.contains('min'),fg=activeWindow===id&&!min;return`<button class="taskapp ${w?'active running':''} ${min?'minimized':''} ${fg?'foreground':''}" title="${min?i18n('Restore window','Restore window'):appName(id)}" aria-label="${min?i18n('Restore window','Restore window'):i18n('Open')} ${appName(id)}" onclick="taskClick('${id}')">${APPS[id][0]}</button>`}).join('')}