Skip to content

Commit 2a539ec

Browse files
committed
Frontend - Web Node Loading Screen Improvements
1 parent 3f18c5e commit 2a539ec

File tree

8 files changed

+185
-146
lines changed

8 files changed

+185
-146
lines changed

.idea/vcs.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"install:deps": "npm install",
66
"start": "npm install && ng serve --configuration local --open",
77
"start:dev": "ng serve --configuration development",
8+
"start:dev:mobile": "ng serve --configuration development --host 0.0.0.0",
89
"build": "ng build",
910
"build:prod": "ng build --configuration production",
1011
"tests": "npx cypress open --config baseUrl=http://localhost:4200",

frontend/src/app/app.module.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export class AppGlobalErrorhandler implements ErrorHandler {
4444
constructor(private errorHandlerService: GlobalErrorHandlerService) {}
4545

4646
handleError(error: any): void {
47+
console.log(123123123);
4748
Sentry.captureException(error);
4849
this.errorHandlerService.handleError(error);
4950
console.error(error);

frontend/src/app/core/services/web-node.service.ts

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
import { Inject, Injectable } from '@angular/core';
2-
import { BehaviorSubject, catchError, filter, from, fromEvent, map, merge, Observable, of, switchMap, tap } from 'rxjs';
2+
import {
3+
BehaviorSubject,
4+
catchError,
5+
EMPTY,
6+
filter,
7+
from,
8+
fromEvent,
9+
map,
10+
merge,
11+
Observable,
12+
of,
13+
switchMap,
14+
tap,
15+
} from 'rxjs';
316
import base from 'base-x';
417
import { any } from '@openmina/shared';
518
import { HttpClient } from '@angular/common/http';
@@ -55,16 +68,15 @@ export class WebNodeService {
5568
}
5669

5770
loadWasm$(): Observable<void> {
58-
this.loadWebnodeJs();
59-
sendSentryEvent('Loading WebNode JS');
71+
this.webNodeStartTime = Date.now();
72+
// this.loadWebnodeJs();
6073
return merge(
6174
of(any(window).webnode).pipe(filter(Boolean)),
6275
fromEvent(window, 'webNodeLoaded'),
6376
).pipe(
6477
switchMap(() => this.http.get<{ publicKey: string, privateKey: string }>('assets/webnode/web-node-secrets.json')),
6578
tap(data => {
6679
this.webNodeKeyPair = data;
67-
sendSentryEvent('WebNode JS Loaded. Loading WebNode Wasm');
6880
}),
6981
map(() => void 0),
7082
);
@@ -75,19 +87,16 @@ export class WebNodeService {
7587
.pipe(
7688
switchMap((wasm: any) => from(wasm.default('assets/webnode/pkg/openmina_node_web_bg.wasm')).pipe(map(() => wasm))),
7789
switchMap((wasm) => {
78-
sendSentryEvent('WebNode Wasm loaded. Starting WebNode');
7990
this.webnodeProgress$.next('Loaded');
8091
return from(wasm.run(this.webNodeKeyPair.privateKey));
8192
}),
8293
tap((webnode: any) => {
83-
sendSentryEvent('WebNode Started');
84-
this.webNodeStartTime = Date.now();
8594
(window as any)['webnode'] = webnode;
8695
this.webnode$.next(webnode);
8796
this.webnodeProgress$.next('Started');
8897
}),
8998
catchError((error) => {
90-
sendSentryEvent('WebNode failed to start');
99+
sendSentryEvent('WebNode failed to start: ' + error.message);
91100
console.error(error);
92101
return of(null);
93102
}),
@@ -115,18 +124,16 @@ export class WebNodeService {
115124
filter(Boolean),
116125
switchMap(handle => from(any(handle).state().peers())),
117126
tap((peers) => {
118-
if (!this.sentryEvents.sentNoPeersEvent && Date.now() - this.webNodeStartTime >= 5000 && peers.length === 0) {
119-
sendSentryEvent('WebNode has no peers after 5 seconds from startup.');
120-
this.sentryEvents.sentNoPeersEvent = true;
121-
}
122-
if (!this.sentryEvents.sentPeersEvent && peers.length > 0) {
123-
const seconds = (Date.now() - this.webNodeStartTime) / 1000;
124-
sendSentryEvent(`WebNode found its first peer after ${seconds}s`);
125-
this.sentryEvents.sentPeersEvent = true;
126-
}
127+
// if (!this.sentryEvents.sentNoPeersEvent && Date.now() - this.webNodeStartTime >= 5000 && peers.length === 0) {
128+
// sendSentryEvent('WebNode has no peers after 5 seconds from startup.');
129+
// this.sentryEvents.sentNoPeersEvent = true;
130+
// }
131+
// if (!this.sentryEvents.sentPeersEvent && peers.length > 0) {
132+
// this.sentryEvents.sentPeersEvent = true;
133+
// }
127134
if (!this.sentryEvents.firstPeerConnected && peers.some((p: any) => p.connection_status === DashboardPeerStatus.CONNECTED)) {
128135
const seconds = (Date.now() - this.webNodeStartTime) / 1000;
129-
sendSentryEvent(`WebNode connected to its first peer after ${seconds}s`);
136+
sendSentryEvent(`WebNode connected in ${seconds.toFixed(1)}s`);
130137
this.sentryEvents.firstPeerConnected = true;
131138
this.webnodeProgress$.next('Connected');
132139
}

frontend/src/app/features/webnode/web-node-demo-dashboard/web-node-demo-dashboard.component.html

Lines changed: 36 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,61 @@
11
<div class="logo-header w-100 border-bottom fx-row-full-cent">
22
<img ngSrc="assets/images/logo/logo-text.svg" height="40" width="136"/>
33
</div>
4-
<div class="data-wrapper fx-col-full-cent">
5-
<div class="header flex-column align-center mb-16 pb-12 pl-10 pr-10 text-center">
6-
<div class="loading-webnode f-500">
7-
Produce blocks,
8-
<span>&nbsp;right in your browser</span>
9-
</div>
4+
<div class="data-wrapper flex-column w-100 overflow-auto align-center">
5+
<div class="loading-content h-100 flex-column flex-around align-center">
6+
<div class="header flex-column align-center pl-10 pr-10 text-center mb-16">
7+
<div class="loading-webnode f-500 mb-8">
8+
Produce blocks,
9+
<span>right in your browser</span>
10+
</div>
1011

11-
<div class="font-16 tertiary mt-16 font-16 f-300">
12-
@if (!loading[loading.length - 1].loaded) {
13-
@if (loading[0].status === WebNodeStepStatus.LOADING) {
14-
Downloading...
15-
} @else {
16-
~7 seconds left
17-
}
18-
} @else {
19-
Web Node is ready
20-
}
12+
<div class="font-16 tertiary f-300">{{ loadingMessage }}</div>
2113
</div>
22-
</div>
2314

24-
<div #progress class="progress w-100"></div>
15+
<div #progress class="progress w-100 fx-row-full-cent"></div>
2516

26-
<div class="mt-16 flex-column w-100 pl-10 pr-10">
27-
@for (item of loading; track $index) {
28-
<div class="fx-row-vert-cent h-xl font-16">
29-
@if (item.status === WebNodeStepStatus.LOADING) {
30-
<mina-loading-spinner [size]="20" [borderWidth]="2"></mina-loading-spinner>
31-
} @else {
32-
<span [ngClass]="item.status === WebNodeStepStatus.DONE ? 'success-primary' : 'tertiary'"
33-
class="circle-check mina-icon icon-200">check_circle</span>
34-
}
35-
<div [ngClass]="item.status === WebNodeStepStatus.PENDING ? 'tertiary' : 'primary'"
36-
class="ml-8 f-400">{{ item.name }}
37-
</div>
38-
@if (item.data) {
39-
@if (item.data.total) {
40-
<span class="tertiary ml-5">{{ item.data.downloaded }} of {{ item.data.total }} MB</span>
17+
<div class="mt-16 flex-column pl-10 pr-10">
18+
@for (item of loading; track $index) {
19+
<div class="fx-row-vert-cent h-xl font-16">
20+
@if (item.status === WebNodeStepStatus.LOADING) {
21+
<mina-loading-spinner [size]="20" [borderWidth]="2"></mina-loading-spinner>
4122
} @else {
42-
<span class="tertiary ml-5">{{ item.data.est }}</span>
23+
<span [ngClass]="item.status === WebNodeStepStatus.DONE ? 'success-primary' : 'tertiary'"
24+
class="circle-check mina-icon icon-200">check_circle</span>
4325
}
44-
}
45-
</div>
46-
}
26+
<div [ngClass]="item.status === WebNodeStepStatus.PENDING ? 'tertiary' : 'primary'"
27+
class="ml-8 f-400">{{ item.name }}
28+
</div>
29+
</div>
30+
}
31+
</div>
4732
</div>
4833

4934
@if (!loading[loading.length - 1].loaded && errors.length) {
50-
<div class="flex-column w-100 bg-surface p-12 mt-10 border-rad-6">
51-
<div class="font-16 flex-row flex-column-md flex-between align-center flex-start-md"
52-
[ngClass]="errors.length ? 'warn-primary' : 'aware-primary'">
53-
<div>It appears there are some errors.</div>
54-
</div>
55-
<div class="flex-column border-rad-8 warn-secondary monospace break-word">
56-
@for (error of errors; track $index) {
57-
<div class="lh-sm">{{ error }}</div>
58-
}
35+
<div class="flex-column w-100 pl-10 pr-10 mt-10">
36+
<div class="flex-column w-100 bg-surface p-12 border-rad-6">
37+
<div class="w-100 font-16 flex-row flex-column-md flex-between align-center flex-start-md"
38+
[ngClass]="errors.length ? 'warn-primary' : 'aware-primary'">
39+
<div>It appears there are some errors.</div>
40+
</div>
41+
<div class="flex-column border-rad-8 warn-secondary monospace break-word">
42+
@for (error of errors; track $index) {
43+
<div class="lh-sm">{{ error }}</div>
44+
}
45+
</div>
5946
</div>
6047
</div>
6148
}
6249
</div>
6350
<div class="footer border-top fx-row-vert-cent flex-between w-100 pl-10 pr-10">
64-
<div class="fx-row-vert-cent">
51+
<div class="fx-row-vert-cent mr-10">
6552
<span class="mina-icon icon-300 selected-primary mr-5">lightbulb</span>
6653
<div class="selected-primary f-big f-500">
6754
You can run the Web Node from your phone
6855
</div>
6956
</div>
70-
<button class="border-rad-8 fx-row-full-cent font-16 ml-10"
71-
[class.disabled]="!loading[loading.length - 1].loaded"
57+
<button class="border-rad-8 fx-row-full-cent font-16"
58+
[class.disabled]="!ready"
7259
(click)="goToDashboard()">
7360
<span>Continue</span>
7461
</button>

frontend/src/app/features/webnode/web-node-demo-dashboard/web-node-demo-dashboard.component.scss

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,43 @@ $white: #000000;
1212

1313
.logo-header {
1414
height: 56px;
15+
16+
img {
17+
opacity: 0.5;
18+
}
1519
}
1620

1721
.data-wrapper {
1822
height: calc(100% - 56px - 72px);
19-
max-width: 568px;
2023

21-
.header {
22-
margin-bottom: 56px;
24+
.loading-content {
25+
max-width: 568px;
2326

24-
.loading-webnode {
25-
font-size: 24px;
26-
line-height: 32px;
27+
.header {
28+
.loading-webnode {
29+
font-size: 20px;
30+
line-height: 30px;
31+
}
2732
}
28-
}
2933

30-
mina-loading-spinner {
31-
margin: 0 2px;
32-
}
34+
mina-loading-spinner {
35+
margin: 0 2px;
36+
}
3337

34-
.mina-icon.circle-check {
35-
font-variation-settings: 'FILL' 1, 'wght' 300 !important;
36-
}
38+
.mina-icon.circle-check {
39+
font-variation-settings: 'FILL' 1, 'wght' 300 !important;
40+
}
3741

38-
.mina-icon.aware-primary {
39-
animation: fadeIn 1500ms ease-in-out infinite;
40-
}
42+
.mina-icon.aware-primary {
43+
animation: fadeIn 1500ms ease-in-out infinite;
44+
}
4145

42-
.progress {
43-
height: 380px;
44-
margin: 64px 0;
46+
.progress {
47+
min-height: 256px;
48+
@media (max-width: 768px) {
49+
min-height: 30vh;
50+
}
51+
}
4552
}
4653
}
4754

@@ -53,6 +60,7 @@ $white: #000000;
5360
width: 158px;
5461
height: 48px !important;
5562
background-color: $cta-container;
63+
color: $base-background;
5664

5765
&.disabled {
5866
opacity: 0.25;
@@ -63,6 +71,15 @@ $white: #000000;
6371
background-color: $selected-primary;
6472
}
6573
}
74+
75+
@media (max-width: 768px) {
76+
> div {
77+
display: none;
78+
}
79+
button {
80+
width: 100%;
81+
}
82+
}
6683
}
6784

6885
@keyframes fadeIn {
@@ -80,10 +97,7 @@ $white: #000000;
8097
}
8198
}
8299

83-
@media (max-width: 768px) {
84-
.font-16 {
85-
font-size: 15px;
86-
}
100+
@media (max-width: 568px) {
87101
.loading-webnode span {
88102
display: block;
89103
}

0 commit comments

Comments
 (0)