Opzet businesslogica opzetten focus-stats

This commit is contained in:
2024-11-26 20:56:43 +01:00
parent a168fa31c0
commit 7c457ba8c7
5 changed files with 143 additions and 80 deletions

View File

@@ -1,40 +0,0 @@
import {FocusStats} from "./focus-stats";
export class FocusService {
stats: FocusStats = new FocusStats();
registerFocus(minutes: number) {
this.stats.focusCycles++;
this.stats.focusMinutes += minutes;
}
registerShortBreak(minutes: number) {
this.stats.shortBreakCycles++;
this.stats.breakMinutes += minutes;
}
registerLongBreak(minutes: number) {
this.stats.longBreakCycles++;
this.stats.breakMinutes += minutes;
}
getFocusCycles(): number {
return this.stats.focusCycles;
}
getFocusMinutes(): number {
return this.stats.focusMinutes;
}
getShortBreakCycles(): number {
return this.stats.shortBreakCycles;
}
getLongBreakCycles(): number {
return this.stats.longBreakCycles;
}
getBreakMinutes(): number {
return this.stats.breakMinutes;
}
}

View File

@@ -1,7 +1,49 @@
import {FocusState} from "./focus-state";
import {state} from "@angular/animations";
export class FocusStats {
focusCycles: number = 0;
focusMinutes: number = 0;
shortBreakCycles: number = 0;
longBreakCycles: number = 0;
breakMinutes: number = 0;
private _focusCycles: number = 0;
private _focusTimeInMs: number = 0;
private _shortBreakCycles: number = 0;
private _longBreakCycles: number = 0;
private _breakTimeInMs: number = 0;
inc(state: FocusState, deltaInMs?: number): void {
switch (state) {
case FocusState.FOCUS:
this._focusCycles++;
this._focusTimeInMs += !!deltaInMs ? deltaInMs : 0;
break;
case FocusState.SHORT_BREAK:
this._shortBreakCycles++;
this._breakTimeInMs += !!deltaInMs ? deltaInMs : 0;
break;
case FocusState.LONG_BREAK:
this._longBreakCycles++;
this._breakTimeInMs += !!deltaInMs ? deltaInMs : 0;
break;
default:
// nothing
}
}
get focusCycles(): number {
return this._focusCycles;
}
get focusTimeInMs(): number {
return this._focusTimeInMs;
}
get shortBreakCycles(): number {
return this._shortBreakCycles;
}
get longBreakCycles(): number {
return this._longBreakCycles;
}
get breakTimeInMs(): number {
return this._breakTimeInMs;
}
}

View File

@@ -24,7 +24,7 @@
</ion-button>
<ion-button (click)="stopTimer()" color="danger">
<ion-icon slot="start" name="close-circle"></ion-icon>
Give up
STOP
</ion-button>
</div>
@@ -64,38 +64,10 @@
</ion-button>
</div>
<div class="focus-stats">
hier komen de stats
</div>
<!-- <div class="timer">-->
<!-- <div class="countdown focusmode">-->
<!-- <svg class="focustimer" width="100%" height="100%" viewBox="0 0 200 200" style="background-color: lavender;" (click)="startWhereWeAre()">-->
<!-- &lt;!&ndash; Definieer de gradient &ndash;&gt;-->
<!-- <defs>-->
<!-- &lt;!&ndash; have the gradient follow the path is possible but too difficult for now - can be read at https://stackoverflow.com/questions/14633363/can-i-apply-a-gradient-along-an-svg-path &ndash;&gt;-->
<!-- <linearGradient id="grad1" x1="1" y1="0" x2="0" y2="0">-->
<!-- <stop offset="0%" stop-color="blue"></stop>-->
<!-- <stop offset="80%" stop-color="green"></stop>-->
<!-- <stop offset="100%" stop-color="red"></stop>-->
<!-- </linearGradient>-->
<!-- </defs>-->
<!-- <path id="1stPath" [attr.d]="pathD"-->
<!-- fill="none" stroke="url(#grad1)" stroke-width="30" stroke-dasharray="0" [attr.stroke-dashoffset]="dashOffset" />-->
<!-- </svg>-->
<!-- <div class="countdown-text">{{ minutesText }}:{{ secondsText }}</div>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="state state-{{state}}">{{state}}</div>-->
<!-- &lt;!&ndash; TODO decide buttons to show on state &ndash;&gt;-->
<!-- <div class="buttonBar">-->
<!-- <ion-button (click)="startTimer(25)">Focus</ion-button>-->
<!-- <ion-button (click)="stopTimer()">Give up</ion-button>-->
<!-- </div>-->
<!-- <div class="buttonBar">-->
<!-- <ion-button (click)="startTimer(5)">Reload</ion-button>-->
<!-- <ion-button (click)="startTimer(15)">Recharge</ion-button>-->
<!-- </div>-->
</app-tusha-page>

View File

@@ -2,6 +2,7 @@ import {Component, OnDestroy, OnInit, Renderer2} from "@angular/core";
import {IonBreadcrumb, IonBreadcrumbs, IonButton, IonContent, IonIcon, IonProgressBar} from "@ionic/angular/standalone";
import {TushaPageComponent} from "../../../tusha/tusha-page/tusha-page.component";
import {FocusState} from "./focus-state";
import {FocusService} from "./focus.service";
@Component({
templateUrl: 'focus.component.html',
@@ -16,6 +17,7 @@ export class FocusPage implements OnInit, OnDestroy {
private interval: number | undefined;
private timerStarted: number | null = null;
state: FocusState = FocusState.STOPPED;
private focusRuns = 0;
private endOfTimerChime: HTMLAudioElement;
@@ -23,7 +25,7 @@ export class FocusPage implements OnInit, OnDestroy {
dashOffset = 0;
constructor(private renderer: Renderer2) {
constructor(private renderer: Renderer2, private focusService: FocusService) {
this.endOfTimerChime = new Audio('../../../assets/race-start-beeps-125125.mp3');
}
@@ -62,6 +64,7 @@ export class FocusPage implements OnInit, OnDestroy {
console.error('Error playing audio:', error);
});
clearInterval(this.interval);
this.timerStarted = null;
}
this.renderer.setStyle(
@@ -87,10 +90,24 @@ export class FocusPage implements OnInit, OnDestroy {
}
startWhereWeAre() {
this.startTimer(25);
switch (this.state) {
case FocusState.FOCUS:
this.focusRuns++;
if (this.focusRuns > 3) {
this.focusRuns = 0;
this.recharge();
} else {
this.reload();
}
break;
default:
this.focus();
break;
}
}
stopTimer() {
this.focusRuns = 0;
this.state = FocusState.STOPPED;
this.startTimer(0);
}
@@ -101,11 +118,17 @@ export class FocusPage implements OnInit, OnDestroy {
}
reload() {
if (!!this.timerStarted) {
this.focusRuns = 0;
}
this.state = FocusState.SHORT_BREAK;
this.startTimer(0.5);
this.startTimer(5);
}
recharge() {
if (!!this.timerStarted) {
this.focusRuns = 0;
}
this.state = FocusState.LONG_BREAK;
this.startTimer(15);
}

View File

@@ -0,0 +1,66 @@
import {FocusStats} from "./focus-stats";
import {FocusState} from "./focus-state";
import {Injectable} from "@angular/core";
@Injectable({ providedIn: 'root',})
export class FocusService {
current: {state: FocusState, start: Date} = {state: FocusState.STOPPED, start: new Date()};
stats: FocusStats = new FocusStats();
private startState(state: FocusState) {
this.current.state = state;
this.current.start = new Date();
}
startFocus(): void {
this.startState(FocusState.FOCUS);
}
startShortBreak(): void {
this.startState(FocusState.SHORT_BREAK);
}
startLongBreak(): void {
this.startState(FocusState.LONG_BREAK);
}
stopCurrent(forced: boolean) {
if (!forced) {
const deltaInMs = new Date().getTime() - this.current.start.getTime();
this.stats.inc(this.current.state, deltaInMs);
} else {
this.stats.inc(this.current.state);
}
}
private formatDelta(deltaInMs: number) {
const totalSeconds = Math.floor(deltaInMs / 1000);
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
const padZero = (num: number) => num.toString().padStart(2, '0');
return `${padZero(hours)}:${padZero(minutes)}:${padZero(seconds)}`;
}
getFocusCycles(): number {
return this.stats.focusCycles;
}
getFocusTime(): string {
return this.formatDelta(this.stats.focusTimeInMs);
}
getShortBreakCycles(): number {
return this.stats.shortBreakCycles;
}
getLongBreakCycles(): number {
return this.stats.longBreakCycles;
}
getBreakTime(): string {
return this.formatDelta(this.stats.breakTimeInMs);
}
}