Opzet businesslogica opzetten focus-stats
This commit is contained in:
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,49 @@
|
|||||||
|
import {FocusState} from "./focus-state";
|
||||||
|
import {state} from "@angular/animations";
|
||||||
|
|
||||||
export class FocusStats {
|
export class FocusStats {
|
||||||
focusCycles: number = 0;
|
private _focusCycles: number = 0;
|
||||||
focusMinutes: number = 0;
|
private _focusTimeInMs: number = 0;
|
||||||
shortBreakCycles: number = 0;
|
private _shortBreakCycles: number = 0;
|
||||||
longBreakCycles: number = 0;
|
private _longBreakCycles: number = 0;
|
||||||
breakMinutes: 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button (click)="stopTimer()" color="danger">
|
<ion-button (click)="stopTimer()" color="danger">
|
||||||
<ion-icon slot="start" name="close-circle"></ion-icon>
|
<ion-icon slot="start" name="close-circle"></ion-icon>
|
||||||
Give up
|
STOP
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -64,38 +64,10 @@
|
|||||||
</ion-button>
|
</ion-button>
|
||||||
</div>
|
</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()">-->
|
|
||||||
<!-- <!– Definieer de gradient –>-->
|
|
||||||
<!-- <defs>-->
|
|
||||||
<!-- <!– 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 –>-->
|
|
||||||
<!-- <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>-->
|
|
||||||
<!-- <!– TODO decide buttons to show on state –>-->
|
|
||||||
<!-- <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>
|
</app-tusha-page>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {Component, OnDestroy, OnInit, Renderer2} from "@angular/core";
|
|||||||
import {IonBreadcrumb, IonBreadcrumbs, IonButton, IonContent, IonIcon, IonProgressBar} from "@ionic/angular/standalone";
|
import {IonBreadcrumb, IonBreadcrumbs, IonButton, IonContent, IonIcon, IonProgressBar} from "@ionic/angular/standalone";
|
||||||
import {TushaPageComponent} from "../../../tusha/tusha-page/tusha-page.component";
|
import {TushaPageComponent} from "../../../tusha/tusha-page/tusha-page.component";
|
||||||
import {FocusState} from "./focus-state";
|
import {FocusState} from "./focus-state";
|
||||||
|
import {FocusService} from "./focus.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: 'focus.component.html',
|
templateUrl: 'focus.component.html',
|
||||||
@@ -16,6 +17,7 @@ export class FocusPage implements OnInit, OnDestroy {
|
|||||||
private interval: number | undefined;
|
private interval: number | undefined;
|
||||||
private timerStarted: number | null = null;
|
private timerStarted: number | null = null;
|
||||||
state: FocusState = FocusState.STOPPED;
|
state: FocusState = FocusState.STOPPED;
|
||||||
|
private focusRuns = 0;
|
||||||
|
|
||||||
private endOfTimerChime: HTMLAudioElement;
|
private endOfTimerChime: HTMLAudioElement;
|
||||||
|
|
||||||
@@ -23,7 +25,7 @@ export class FocusPage implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
dashOffset = 0;
|
dashOffset = 0;
|
||||||
|
|
||||||
constructor(private renderer: Renderer2) {
|
constructor(private renderer: Renderer2, private focusService: FocusService) {
|
||||||
this.endOfTimerChime = new Audio('../../../assets/race-start-beeps-125125.mp3');
|
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);
|
console.error('Error playing audio:', error);
|
||||||
});
|
});
|
||||||
clearInterval(this.interval);
|
clearInterval(this.interval);
|
||||||
|
this.timerStarted = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.renderer.setStyle(
|
this.renderer.setStyle(
|
||||||
@@ -87,10 +90,24 @@ export class FocusPage implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
startWhereWeAre() {
|
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() {
|
stopTimer() {
|
||||||
|
this.focusRuns = 0;
|
||||||
this.state = FocusState.STOPPED;
|
this.state = FocusState.STOPPED;
|
||||||
this.startTimer(0);
|
this.startTimer(0);
|
||||||
}
|
}
|
||||||
@@ -101,11 +118,17 @@ export class FocusPage implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
|
if (!!this.timerStarted) {
|
||||||
|
this.focusRuns = 0;
|
||||||
|
}
|
||||||
this.state = FocusState.SHORT_BREAK;
|
this.state = FocusState.SHORT_BREAK;
|
||||||
this.startTimer(0.5);
|
this.startTimer(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
recharge() {
|
recharge() {
|
||||||
|
if (!!this.timerStarted) {
|
||||||
|
this.focusRuns = 0;
|
||||||
|
}
|
||||||
this.state = FocusState.LONG_BREAK;
|
this.state = FocusState.LONG_BREAK;
|
||||||
this.startTimer(15);
|
this.startTimer(15);
|
||||||
}
|
}
|
||||||
|
|||||||
66
src/app/pages/modus/focus/focus.service.ts
Normal file
66
src/app/pages/modus/focus/focus.service.ts
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user