Skip to content

Commit

Permalink
🚀 Show elapsed and total time for guess
Browse files Browse the repository at this point in the history
  • Loading branch information
brathis committed Apr 22, 2024
1 parent 681bb31 commit f9217a6
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 59 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"editor.formatOnSave": true
}
10 changes: 6 additions & 4 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
<div class="header">
<h1>Fuel Gage Trainer</h1>
<h3>for Robinson R44</h3>
<p>Practice makes perfect! If you are like me and reading the fuel gages on the R44
takes a lot longer than it should, this tool is for you.
<p>
Practice makes perfect! If you are like me and reading the fuel gages on
the R44 takes a lot longer than it should, this tool is for you.
</p>
<p>The gages assume R44s with bladder tanks.</p>
</div>
Expand All @@ -12,8 +13,9 @@ <h3>for Robinson R44</h3>
class="controls"
[totalCapacity]="totalCapacity"
[state]="fuelGagesState"
[totalQuantity$]="totalQuantity$"
[guess$]="guess$"
[totalQuantity]="totalQuantity"
[guess]="guess"
[time]="time"
(restartButtonClicked$)="restartButtonClicked()"
(guessSubmitted$)="guessSubmitted($event)"
></app-controls>
Expand Down
39 changes: 18 additions & 21 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { FuelTank } from './fuel-gages/fuel-tank.model';
import {
BehaviorSubject,
Observable,
Subject,
combineLatest,
map,
timer,
} from 'rxjs';
import { Subscription, combineLatest, interval, timer } from 'rxjs';
import { FuelGagesState } from './fuel-gages/fuel-gages.state';

@Component({
Expand All @@ -21,25 +14,24 @@ export class AppComponent implements OnInit {
.map((tank) => tank.getCapacity())
.reduce((a, b) => a + b, 0);

totalQuantity$: Observable<number>;
guess$: Subject<number>;
totalQuantity: number = 0;
guess: number = 0;
fuelGagesState = FuelGagesState.HIDDEN;
time = 0;
timeSubscription: Subscription | null = null;

constructor() {
const quantityObservables = [];
for (const tank of this.tanks) {
quantityObservables.push(tank.getQuantity$());
}
this.totalQuantity$ = combineLatest(quantityObservables).pipe(
map((quantities) => {
let sum = 0;
for (let quantity of quantities) {
sum += quantity;
}
return sum;
}),
);
this.guess$ = new BehaviorSubject(0);
combineLatest(quantityObservables).subscribe((quantities) => {
let sum = 0;
for (let quantity of quantities) {
sum += quantity;
}
this.totalQuantity = sum;
});
}

ngOnInit(): void {
Expand All @@ -60,12 +52,17 @@ export class AppComponent implements OnInit {
// FIXME: Instead of a timer, can we get an event when the CSS transition has completed?
timer(2000).subscribe((_value) => {
this.fuelGagesState = FuelGagesState.HIDDEN;
this.time = 0;
this.timeSubscription = interval(1000).subscribe((_value) => {
++this.time;
});
});
}

private reveal(guess: number): void {
this.timeSubscription?.unsubscribe();
this.fuelGagesState = FuelGagesState.VISIBLE;
this.guess$.next(guess);
this.guess = guess;
}

guessSubmitted(guess: number): void {
Expand Down
10 changes: 9 additions & 1 deletion src/app/controls/controls.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
color: var(--beige-dark);
}

.result-guess .value,
.result-total .value {
font-weight: 400;
}

.button {
display: flex;
flex-direction: row;
Expand Down Expand Up @@ -64,7 +69,10 @@
color: var(--beige);
}

.guess {
.timer {
color: var(--beige-dark);
font-weight: 600;
font-size: 24px;
}

.guess > .inputs {
Expand Down
19 changes: 14 additions & 5 deletions src/app/controls/controls.component.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
<div class="controls">
<div class="result" *ngIf="state === 'VISIBLE'">
<div class="result-guess">
<span class="label">Your Guess</span>
<span class="value">{{ guess | number: "1.0-0" }} l</span>
</div>
<div class="result-total">
<span class="label">Total</span>
<span> {{ totalQuantity$ | async | number: "1.0-0" }} l </span>
<span class="value">{{ totalQuantity | number: "1.0-0" }} l</span>
</div>
<div class="result-guess">
<span class="label">Your Guess</span>
<span> {{ guess$ | async | number: "1.0-0" }} l </span>
<div class="result-error">
<span class="label">Error</span>
<span class="value">{{ error | number: "1.0-0" }} l</span>
</div>
<div class="result-time">
<span class="label">Time Taken</span>
<span class="value">{{ time }} s</span>
</div>
</div>
<div class="button">
<button *ngIf="state === 'VISIBLE'" (click)="restartButtonClicked()">
Start over
</button>
</div>
<div class="timer" *ngIf="state === 'HIDDEN'">{{ time }} s</div>
<div class="guess" *ngIf="state === 'RESETTING' || state === 'HIDDEN'">
<div class="label">
{{ state === "RESETTING" ? "Resetting..." : "Enter your guess:" }}
Expand All @@ -22,7 +31,7 @@
<input
type="number"
(keydown.enter)="guessSubmitted()"
[(ngModel)]="guess"
[(ngModel)]="guessModel"
[disabled]="state === 'RESETTING'"
#guessInput
/>
Expand Down
22 changes: 0 additions & 22 deletions src/app/controls/controls.component.spec.ts

This file was deleted.

17 changes: 11 additions & 6 deletions src/app/controls/controls.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
ViewChild,
} from '@angular/core';
import { FuelGagesState } from '../fuel-gages/fuel-gages.state';
import { Observable, of } from 'rxjs';

@Component({
selector: 'app-controls',
Expand All @@ -21,34 +20,40 @@ import { Observable, of } from 'rxjs';
export class ControlsComponent implements OnChanges {
@Input() totalCapacity: number = 0;
@Input() state: FuelGagesState = FuelGagesState.RESETTING;
@Input() totalQuantity$: Observable<number> = of(0);
@Input() guess$: Observable<number> = of(0);
@Input() totalQuantity: number = 0;
@Input() guess: number = 0;
@Input() time: number = 0;
@Output() restartButtonClicked$: EventEmitter<void> = new EventEmitter();
@Output() guessSubmitted$: EventEmitter<number> = new EventEmitter();
@ViewChild('guessInput') guessInput: ElementRef<HTMLInputElement> =
{} as ElementRef;
guess = '';
guessModel = '';
error = 0;

ngOnChanges(changes: SimpleChanges): void {
if (changes['state']) {
switch (changes['state'].currentValue) {
case FuelGagesState.RESETTING:
this.guess = '';
this.guessModel = '';
break;
case FuelGagesState.HIDDEN:
// TODO: what is the correct lifecycle method to use to avoid setTimeout?
setTimeout(() => this.guessInput.nativeElement.focus(), 0);
break;
}
}

if (changes['totalQuantity'] || changes['guess']) {
this.error = this.guess - this.totalQuantity;
}
}

restartButtonClicked(): void {
this.restartButtonClicked$.emit();
}

guessSubmitted(): void {
const guess = Number.parseInt(this.guess);
const guess = Number.parseInt(this.guessModel);
if (!Number.isNaN(guess) && 0 <= guess && guess <= this.totalCapacity) {
this.guessSubmitted$.emit(guess);
}
Expand Down

0 comments on commit f9217a6

Please sign in to comment.