Show a progress bar for the probability of completing the proof of work challenge (#87)
Since the challenge is done off of the main thread, there is no simple way to report the progress done towards completing it. This change adds a callback parameter, `progressCallback`, which is called with the most recently attempted nonce every ~1024 iterations (should this be configurable?). For the single-threaded "slow" algorithm, this is exactly every 1024 iterations. For the multi-threaded "fast" algorithm, threads take turns reporting in a round-robin as then notice they have passed a multiple of 1024. This complexity is to avoid individual threads falling behind their siblings due to the overhead of messaging the main thread. To minimize this overhead as much as possible, a regular number is sent instead of an object. With the new information provided by the callback, a hash rate display is added to the challenge page. This display is updated at most once per second and set with tabular numbers to avoid the constantly changing value being too visually distracting. * web: show a progress bar based on completion probability To provide more feedback to the user, the spinner is replaced with a progress bar of the probability the challenge is complete. Since it looks a little weird that a progress bar would fill up a quarter of the way and then jump to the end (even though the probability would make that happen 1 in 4 times), the bar is mapped with a quadratic easing function to move faster at the beginning and then slow down as the probability of redirection increases. If the probability exceeds 90%, a message appears letting the user know things are taking longer than expected and to continue being patient. Signed-off-by: Xe Iaso <me@xeiaso.net>
This commit is contained in:
parent
3683f95933
commit
3771a3b627
6 changed files with 119 additions and 144 deletions
139
web/index.templ
139
web/index.templ
|
|
@ -27,120 +27,28 @@ templ base(title string, body templ.Component) {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.lds-roller,
|
||||
.lds-roller div,
|
||||
.lds-roller div:after {
|
||||
box-sizing: border-box;
|
||||
#status {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.lds-roller {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
#progress {
|
||||
display: none;
|
||||
width: min(20rem, 90%);
|
||||
height: 2rem;
|
||||
border-radius: 1rem;
|
||||
overflow: hidden;
|
||||
margin: 1rem 0 2rem;
|
||||
outline-color: #b16286;
|
||||
outline-offset: 2px;
|
||||
outline-style: solid;
|
||||
outline-width: 4px;
|
||||
}
|
||||
|
||||
.lds-roller div {
|
||||
animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
transform-origin: 40px 40px;
|
||||
}
|
||||
|
||||
.lds-roller div:after {
|
||||
content: " ";
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 7.2px;
|
||||
height: 7.2px;
|
||||
border-radius: 50%;
|
||||
background: currentColor;
|
||||
margin: -3.6px 0 0 -3.6px;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(1) {
|
||||
animation-delay: -0.036s;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(1):after {
|
||||
top: 62.62742px;
|
||||
left: 62.62742px;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(2) {
|
||||
animation-delay: -0.072s;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(2):after {
|
||||
top: 67.71281px;
|
||||
left: 56px;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(3) {
|
||||
animation-delay: -0.108s;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(3):after {
|
||||
top: 70.90963px;
|
||||
left: 48.28221px;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(4) {
|
||||
animation-delay: -0.144s;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(4):after {
|
||||
top: 72px;
|
||||
left: 40px;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(5) {
|
||||
animation-delay: -0.18s;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(5):after {
|
||||
top: 70.90963px;
|
||||
left: 31.71779px;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(6) {
|
||||
animation-delay: -0.216s;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(6):after {
|
||||
top: 67.71281px;
|
||||
left: 24px;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(7) {
|
||||
animation-delay: -0.252s;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(7):after {
|
||||
top: 62.62742px;
|
||||
left: 17.37258px;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(8) {
|
||||
animation-delay: -0.288s;
|
||||
}
|
||||
|
||||
.lds-roller div:nth-child(8):after {
|
||||
top: 56px;
|
||||
left: 12.28719px;
|
||||
}
|
||||
|
||||
.mx-auto {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
@keyframes lds-roller {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
.bar-inner {
|
||||
background-color: #b16286;
|
||||
height: 100%;
|
||||
width: 0;
|
||||
transition: width 0.25s ease-in;
|
||||
}
|
||||
</style>
|
||||
@templ.JSONScript("anubis_version", anubis.Version)
|
||||
|
|
@ -181,15 +89,8 @@ templ index() {
|
|||
/>
|
||||
<p id="status">Loading...</p>
|
||||
<script async type="module" src={ "/.within.website/x/cmd/anubis/static/js/main.mjs?cacheBuster=" + anubis.Version }></script>
|
||||
<div id="spinner" class="lds-roller mx-auto" style="display:none;">
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div id="progress" role="progressbar" aria-labelledby="status">
|
||||
<div class="bar-inner"></div>
|
||||
</div>
|
||||
<details>
|
||||
<summary>Why am I seeing this?</summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue