feat: add tracking of bootup progress and show a loading bar
This commit is contained in:
parent
ea4a9505f5
commit
0ddd5f5cff
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
await swarmClient.addRelay(
|
BOOT_FUNCTIONS.push(
|
||||||
"2d7ae1517caf4aae4de73c6d6f400765d2dd00b69d65277a29151437ef1c7d1d",
|
async () =>
|
||||||
);
|
await swarmClient.addRelay(
|
||||||
// IRC
|
"2d7ae1517caf4aae4de73c6d6f400765d2dd00b69d65277a29151437ef1c7d1d",
|
||||||
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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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>
|
||||||
|
);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue