feat: add tracking of bootup progress and show a loading bar

This commit is contained in:
Derrick Hammer 2023-08-03 14:55:09 -04:00
parent ea4a9505f5
commit 0ddd5f5cff
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
6 changed files with 136 additions and 14 deletions

View File

@ -27,3 +27,13 @@ export async function waitForConnected(cb?: Function) {
await swarmClient.ready(); await swarmClient.ready();
await cb?.(); await cb?.();
} }
export async function listenBootStatus(cb: (percent: number) => void) {
const port = browser.runtime.connect();
port.onMessage.addListener((data: any) => {
if (data?.method === "bootStatus") {
cb(data.data);
}
});
}

View File

@ -1,7 +1,7 @@
import tldEnum from "@lumeweb/tld-enum"; import tldEnum from "@lumeweb/tld-enum";
import { handleKernelMessage } from "./kernel.js"; import { handleKernelMessage } from "./kernel.js";
import browser from "webextension-polyfill"; import browser from "webextension-polyfill";
import { bridgeListener } from "./bridge.js"; import { bridgeListener, broadcastToBridges } from "./bridge.js";
import WebEngine from "../../webEngine.js"; import WebEngine from "../../webEngine.js";
import InternalProvider from "../../contentProviders/internalProvider.js"; import InternalProvider from "../../contentProviders/internalProvider.js";
import IpfsProvider from "../../contentProviders/ipfsProvider.js"; import IpfsProvider from "../../contentProviders/ipfsProvider.js";
@ -27,6 +27,8 @@ import type { KernelAuthStatus } from "@lumeweb/libweb";
let engine: WebEngine; let engine: WebEngine;
const BOOT_FUNCTIONS: (() => Promise<any>)[] = [];
export async function boot() { export async function boot() {
tldEnum.list.push("localhost"); tldEnum.list.push("localhost");
window.addEventListener("message", handleKernelMessage); window.addEventListener("message", handleKernelMessage);
@ -54,19 +56,29 @@ export async function doInit() {
engine.registerContentProvider(new IpfsProvider(engine)); engine.registerContentProvider(new IpfsProvider(engine));
engine.registerContentProvider(new ServerProvider(engine)); engine.registerContentProvider(new ServerProvider(engine));
BOOT_FUNCTIONS.push(
async () =>
await swarmClient.addRelay( await swarmClient.addRelay(
"2d7ae1517caf4aae4de73c6d6f400765d2dd00b69d65277a29151437ef1c7d1d", "2d7ae1517caf4aae4de73c6d6f400765d2dd00b69d65277a29151437ef1c7d1d",
); ),
// IRC
await peerDiscoveryClient.register(
"zduL5de7GC5DVpf92FkShUZZrTpUi6hki2BaTaVwjs9cnmCmKWNywBWyHR",
); );
await networkRegistryClient.registerType("content"); // IRC
await networkRegistryClient.registerType("blockchain"); BOOT_FUNCTIONS.push(
await handshakeClient.register(); async () =>
await ethClient.register(); await peerDiscoveryClient.register(
await ipfsClient.register(); "zduL5de7GC5DVpf92FkShUZZrTpUi6hki2BaTaVwjs9cnmCmKWNywBWyHR",
),
);
BOOT_FUNCTIONS.push(
async () => await networkRegistryClient.registerType("content"),
);
BOOT_FUNCTIONS.push(
async () => await networkRegistryClient.registerType("blockchain"),
);
BOOT_FUNCTIONS.push(async () => await handshakeClient.register());
BOOT_FUNCTIONS.push(async () => await ethClient.register());
BOOT_FUNCTIONS.push(async () => await ipfsClient.register());
const resolvers = [ const resolvers = [
"zduRfyhiAu871qg14RUapxxsBS4gaFxnWXs1jxf3guk2vVAhSx6vJp1kxo", // CID "zduRfyhiAu871qg14RUapxxsBS4gaFxnWXs1jxf3guk2vVAhSx6vJp1kxo", // CID
@ -75,8 +87,25 @@ export async function doInit() {
]; ];
for (const resolver of resolvers) { for (const resolver of resolvers) {
await dnsClient.registerResolver(resolver); BOOT_FUNCTIONS.push(async () => dnsClient.registerResolver(resolver));
} }
await bootup();
weAreBooted(); weAreBooted();
} }
async function bootup() {
for (const entry of Object.entries(BOOT_FUNCTIONS)) {
await entry[1]();
const decPercent = (parseInt(entry[0]) + 1) / BOOT_FUNCTIONS.length;
broadcastBootStatus(decPercent * 100);
}
}
function broadcastBootStatus(percent: number) {
broadcastToBridges({
method: "bootStatus",
data: percent,
});
}

View File

@ -54,3 +54,9 @@ export function bridgeListener(port: any) {
}); });
}); });
} }
export function broadcastToBridges(data: any) {
for (const port of Object.entries(getOpenPorts())) {
(port[1] as any).postMessage(data);
}
}

View File

@ -2,11 +2,12 @@ import "./App.scss";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import Header from "./components/Header.jsx"; import Header from "./components/Header.jsx";
import Art from "./components/Art.jsx"; import Art from "./components/Art.jsx";
import { waitForConnected } from "../../../shared/util.ts"; import { listenBootStatus, waitForConnected } from "../../../shared/util.ts";
import { createClient } from "@lumeweb/kernel-network-registry-client"; import { createClient } from "@lumeweb/kernel-network-registry-client";
import Network from "./components/Network.jsx"; import Network from "./components/Network.jsx";
import Footer from "./components/Footer.jsx"; import Footer from "./components/Footer.jsx";
import classNames from "classnames"; import classNames from "classnames";
import Progress from "./components/Progress.jsx";
const networkClient = createClient(); const networkClient = createClient();
@ -29,6 +30,7 @@ export default function App() {
let [networks, setNetworks] = useState({}); let [networks, setNetworks] = useState({});
let [showConnected, setShowConnected] = useState(false); let [showConnected, setShowConnected] = useState(false);
let [artPulse, setArtPulse] = useState(false); let [artPulse, setArtPulse] = useState(false);
let [bootPercent, setBootPercent] = useState(0);
useEffect(() => { useEffect(() => {
getNetworks().then((networks) => { getNetworks().then((networks) => {
@ -51,10 +53,17 @@ export default function App() {
} }
}, [connected]); }, [connected]);
useEffect(() => {
listenBootStatus((percent) => {
setBootPercent(percent);
});
});
return ( return (
<main> <main>
<Header connected={connected} /> <Header connected={connected} />
<Art connected={showConnected} pulse={artPulse} /> <Art connected={showConnected} pulse={artPulse} />
{!showConnected && <Progress percent={bootPercent} />}
<div className={classNames("content", { connected: showConnected })}> <div className={classNames("content", { connected: showConnected })}>
<h3>All set.</h3> <h3>All set.</h3>
<div className="content-grid"> <div className="content-grid">

View File

@ -0,0 +1,13 @@
import "./Progress.scss";
export default function Progress({ percent }) {
return (
<div className="progress">
<progress value={percent} min="0" max="100" />
<div className="status">
<div className="status-text">Loading Network</div>
<div className="status-percent">{percent}%</div>
</div>
</div>
);
}

View File

@ -0,0 +1,55 @@
.progress {
padding-top: 19.5em;
border-radius: 1.75em;
min-width: 38em;
margin-top: 1em;
margin-left: 41vw;
margin-right: auto;
text-align: center;
display: flex;
flex-direction: column;
progress {
border-radius: 1.75em;
height: 24px;
background: #131313;
border: none;
width: 100%;
max-width: 100%;
&::-webkit-progress-bar, &::-moz-progress-bar {
background: #62C554;
box-shadow: inset 0 0 1em 1px black;
border-radius: 1.75em;
}
}
.status {
margin-top: 3em;
display: flex;
width: 100%;
max-width: 100%;
.status-text {
flex: 1;
color: #656565;
font-size: 10px;
line-height: 12.1px;
font-family: Inter;
font-weight: 700;
text-transform: uppercase;
text-align: left;
}
.status-percent {
flex: 1;
color: #D9D9D9;
font-size: 10px;
line-height: 12.1px;
font-family: Inter;
font-weight: 700;
text-align: right;
}
}
}