Skip to content

Commit 6127bde

Browse files
Update index.html
1 parent e490c8f commit 6127bde

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

src/index.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@
3939
.log-entry.warning{color:var(--warn)}
4040
.log-entry.error{color:var(--error)}
4141
.log-entry.info{color:var(--txt2)}
42-
#terminal{display:none;flex:1;background:var(--bg);border:1px solid var(--border);border-radius:0.5rem;padding:1rem;overflow-y:auto;font-family:'Courier New',monospace;color:var(--txt);font-size:0.875rem}
43-
#terminal.active{display:block}
42+
#desktop{display:none;flex:1;background:var(--bg);border:1px solid var(--border);border-radius:0.5rem;overflow:hidden;position:relative}
43+
#desktop.active{display:flex}
44+
#screen{width:100%;height:100%;border:none}
4445
.modal{position:fixed;inset:0;background:rgba(0,0,0,.8);display:none;align-items:center;justify-content:center;z-index:1000}
4546
.modal.active{display:flex}
4647
.modal-content{background:var(--bg2);border:1px solid var(--border);border-radius:0.5rem;padding:2rem;max-width:500px;width:90%;animation:slideUp .3s}
@@ -70,7 +71,7 @@
7071
</header>
7172
<div class="container">
7273
<div class="card" id="statusCard">
73-
<div class="status-text" id="statusText">Initializing GravelBox...</div>
74+
<div class="status-text" id="statusText">Initializing GravelBox Desktop...</div>
7475
<div class="progress-container">
7576
<div class="progress-bar" id="progressBar" style="width:0%"></div>
7677
<div class="progress-text" id="progressText">0%</div>
@@ -80,7 +81,7 @@
8081
<div class="card-header">System Console</div>
8182
<div class="console-output" id="consoleOutput"></div>
8283
</div>
83-
<div id="terminal"></div>
84+
<div id="desktop"><div id="screen"></div></div>
8485
</div>
8586
<div class="modal" id="exportModal">
8687
<div class="modal-content">
@@ -115,10 +116,9 @@
115116
const prog=(p,m)=>{el.bar.style.width=`${p}%`;el.pct.textContent=`${Math.floor(p)}%`;if(m){el.stat.textContent=m;log(m,'info')}};
116117
const exportWS=async(n)=>{try{log('Exporting...','info');const db=await new Promise((r,j)=>{const q=indexedDB.open(IDB);q.onsuccess=()=>r(q.result);q.onerror=()=>j(q.error)});const tx=db.transaction(['blocks'],'readonly');const st=tx.objectStore('blocks');const d=await new Promise((r,j)=>{const q=st.getAll();q.onsuccess=()=>r(q.result);q.onerror=()=>j(q.error)});const exp={v:1,ts:new Date().toISOString(),name:n,data:d};const blob=new Blob([JSON.stringify(exp)],{type:'application/json'});const a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download=`${n}.wolf`;document.body.appendChild(a);a.click();document.body.removeChild(a);URL.revokeObjectURL(a.href);log(`Exported: ${n}.wolf (${(blob.size/1024/1024).toFixed(2)}MB)`,'success');db.close()}catch(e){log(`Export failed: ${e.message}`,'error')}};
117118
const importWS=async(f)=>{try{log('Importing...','info');const txt=await f.text();const imp=JSON.parse(txt);if(!imp.v||!imp.data)throw new Error('Invalid .wolf file');log(`Importing: ${imp.name}`,'info');const db=await new Promise((r,j)=>{const q=indexedDB.open(IDB);q.onsuccess=()=>r(q.result);q.onerror=()=>j(q.error)});const tx=db.transaction(['blocks'],'readwrite');const st=tx.objectStore('blocks');await new Promise((r,j)=>{const q=st.clear();q.onsuccess=()=>r();q.onerror=()=>j(q.error)});for(const i of imp.data)await new Promise((r,j)=>{const q=st.add(i);q.onsuccess=()=>r();q.onerror=()=>j(q.error)});db.close();log('Imported. Reloading...','success');setTimeout(()=>window.location.reload(),2000)}catch(e){log(`Import failed: ${e.message}`,'error')}};
118-
const runCmd=async(c,d)=>{log(d,'info');try{await cx.run("/bin/bash",["-c",c],{env:["HOME=/root","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","DEBIAN_FRONTEND=noninteractive"],cwd:"/root",uid:0,gid:0})}catch(e){log(`Failed: ${e.message}`,'warning')}};
119119
const loadDisk=async()=>{const m=[{n:'WebSocket',t:30000,f:()=>CheerpX.CloudDevice.create("wss://disks.webvm.io/debian_large_20230522_5044875331.ext2")},{n:'HTTP',t:45000,f:()=>CheerpX.HttpBytesDevice.create("https://disks.webvm.io/debian_mini_20230519_5022088024.ext2")}];for(const x of m){try{log(`Connecting via ${x.n}...`,'warning');const d=await Promise.race([x.f(),new Promise((_,j)=>setTimeout(()=>j(new Error('timeout')),x.t))]);log(`${x.n} connected`,'success');return d}catch(e){log(`${x.n} failed: ${e.message}`,'error');if(x===m[m.length-1])throw e}}};
120-
const init=async()=>{try{log('Starting GravelBox','success');if(!window.crossOriginIsolated||typeof SharedArrayBuffer==='undefined'){log('Waiting for isolation...','warning');for(let i=0;i<20;i++){await new Promise(r=>setTimeout(r,500));if(window.crossOriginIsolated)break}if(!window.crossOriginIsolated)throw new Error('Isolation failed')}log('Isolation OK','success');prog(10,'Loading disk...');log('Creating storage...','info');idb=await CheerpX.IDBDevice.create(IDB);log('Storage ready','success');const disk=await loadDisk();prog(40,'Building filesystem...');log('Building overlay...','info');const ovr=await CheerpX.OverlayDevice.create(disk,idb);log('Overlay ready','success');const web=await CheerpX.WebDevice.create("");prog(60,'Starting VM...');log('Booting VM...','info');cx=await CheerpX.Linux.create({mounts:[{type:"ext2",path:"/",dev:ovr},{type:"dir",path:"/app",dev:web},{type:"devs",path:"/dev"}]});log('VM started','success');const oc=cx.console;cx.console={write:d=>{const t=new TextDecoder().decode(d);if(t.trim())log(t.trim(),'info')}};await runCmd("curl https://github.com/WolfTech-Innovations/WolfEther/releases/download/Node_x64_RL1.7-LINUX/wolfether-node -o wolfether","Downloading WolfEther");prog(95,'Installing...');await runCmd("cp wolfether /usr/local/bin/wolfether && chmod +x /usr/local/bin/wolfether","Installing WolfEther");cx.console=oc;prog(100,'Ready');log('Launching WolfEther...','success');el.exp.disabled=false;await new Promise(r=>setTimeout(r,1500));el.stc.classList.add('hidden');el.con.classList.add('hidden');el.term.classList.add('active');cx.setConsole(el.term);await cx.run("/usr/local/bin/wolfether",[],{env:["HOME=/root","USER=root","SHELL=/bin/bash","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],cwd:"/root",uid:0,gid:0})}catch(e){log(`Fatal: ${e.message}`,'error');prog(0,'Failed')}};
121-
document.addEventListener('DOMContentLoaded',()=>{el={stat:$('statusText'),bar:$('progressBar'),pct:$('progressText'),out:$('consoleOutput'),stc:$('statusCard'),con:$('consoleCard'),term:$('terminal'),exp:$('exportBtn'),imp:$('importBtn'),exM:$('exportModal'),imM:$('importModal'),exN:$('exportName'),imF:$('importFile')};el.exp.onclick=()=>el.exM.classList.add('active');el.imp.onclick=()=>el.imM.classList.add('active');$('cancelExport').onclick=()=>el.exM.classList.remove('active');$('cancelImport').onclick=()=>el.imM.classList.remove('active');$('confirmExport').onclick=async()=>{const n=el.exN.value.trim()||'workspace';el.exM.classList.remove('active');await exportWS(n)};$('confirmImport').onclick=async()=>{const f=el.imF.files[0];if(!f){log('Select a .wolf file','warning');return}el.imM.classList.remove('active');await importWS(f)};setTimeout(init,1000)});
120+
const init=async()=>{try{log('Starting GravelBox Desktop','success');if(!window.crossOriginIsolated||typeof SharedArrayBuffer==='undefined'){log('Waiting for isolation...','warning');for(let i=0;i<20;i++){await new Promise(r=>setTimeout(r,500));if(window.crossOriginIsolated)break}if(!window.crossOriginIsolated)throw new Error('Isolation failed')}log('Isolation OK','success');prog(10,'Loading disk...');log('Creating storage...','info');idb=await CheerpX.IDBDevice.create(IDB);log('Storage ready','success');const disk=await loadDisk();prog(40,'Building filesystem...');log('Building overlay...','info');const ovr=await CheerpX.OverlayDevice.create(disk,idb);log('Overlay ready','success');const web=await CheerpX.WebDevice.create("");prog(60,'Starting VM...');log('Booting VM...','info');cx=await CheerpX.Linux.create({mounts:[{type:"ext2",path:"/",dev:ovr},{type:"dir",path:"/app",dev:web},{type:"devs",path:"/dev"},{type:"devs",path:"/dev/shm"},{type:"proc",path:"/proc"}]});log('VM started','success');prog(80,'Starting Desktop...');el.exp.disabled=false;await new Promise(r=>setTimeout(r,1000));prog(100,'Desktop Ready');log('Launching Desktop Environment...','success');await new Promise(r=>setTimeout(r,500));el.stc.classList.add('hidden');el.con.classList.add('hidden');el.desk.classList.add('active');cx.setDisplay(el.screen);await cx.run("/bin/sh",["-c","startx"],{env:["HOME=/home/user","USER=user","DISPLAY=:0"],cwd:"/home/user",uid:1000,gid:1000})}catch(e){log(`Fatal: ${e.message}`,'error');prog(0,'Failed')}};
121+
document.addEventListener('DOMContentLoaded',()=>{el={stat:$('statusText'),bar:$('progressBar'),pct:$('progressText'),out:$('consoleOutput'),stc:$('statusCard'),con:$('consoleCard'),desk:$('desktop'),screen:$('screen'),exp:$('exportBtn'),imp:$('importBtn'),exM:$('exportModal'),imM:$('importModal'),exN:$('exportName'),imF:$('importFile')};el.exp.onclick=()=>el.exM.classList.add('active');el.imp.onclick=()=>el.imM.classList.add('active');$('cancelExport').onclick=()=>el.exM.classList.remove('active');$('cancelImport').onclick=()=>el.imM.classList.remove('active');$('confirmExport').onclick=async()=>{const n=el.exN.value.trim()||'workspace';el.exM.classList.remove('active');await exportWS(n)};$('confirmImport').onclick=async()=>{const f=el.imF.files[0];if(!f){log('Select a .wolf file','warning');return}el.imM.classList.remove('active');await importWS(f)};setTimeout(init,1000)});
122122
</script>
123123
</body>
124-
</html>
124+
</html>

0 commit comments

Comments
 (0)