From 05bfd4f3eb3a2c7dd123cd5f79dd8f07bd42c001 Mon Sep 17 00:00:00 2001 From: aknuth Date: Thu, 12 Dec 2024 18:26:01 +0100 Subject: [PATCH] =?UTF-8?q?Anzeige=20des=20n=C3=A4chsten=20Intervals?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/training/training.component.html | 6 +- src/app/training/training.component.ts | 86 +++++++++++++++++++----- 2 files changed, 71 insertions(+), 21 deletions(-) diff --git a/src/app/training/training.component.html b/src/app/training/training.component.html index 53b30c0..67d8a23 100644 --- a/src/app/training/training.component.html +++ b/src/app/training/training.component.html @@ -20,7 +20,7 @@ class="bg-orange-500 disabled:bg-orange-200 text-white py-2 px-4 rounded hover:bg-orange-600" [disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length" > - Nochmal + Nochmal ({{ getNextInterval(currentBox, 'again') }}) @@ -29,7 +29,7 @@ class="bg-blue-500 disabled:bg-blue-200 text-white py-2 px-4 rounded hover:bg-blue-600" [disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length" > - Gut + Gut ({{ getNextInterval(currentBox, 'good') }}) @@ -38,7 +38,7 @@ class="bg-green-500 disabled:bg-green-200 text-white py-2 px-4 rounded hover:bg-green-600" [disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length" > - Einfach + Einfach ({{ getNextInterval(currentBox, 'easy') }}) diff --git a/src/app/training/training.component.ts b/src/app/training/training.component.ts index fe0ba9e..af7566f 100644 --- a/src/app/training/training.component.ts +++ b/src/app/training/training.component.ts @@ -2,9 +2,7 @@ import { Component, Input, Output, EventEmitter, OnInit, ViewChild, ElementRef } from '@angular/core'; import { Deck, DeckImage, DeckService, Box } from '../deck.service'; import { CommonModule } from '@angular/common'; -import { switchMap } from 'rxjs/operators'; -import { forkJoin } from 'rxjs'; -import { lastValueFrom } from 'rxjs'; // Import für toPromise-Alternative +import { lastValueFrom } from 'rxjs'; @Component({ selector: 'app-training', @@ -30,18 +28,17 @@ export class TrainingComponent implements OnInit { constructor(private deckService: DeckService) { } ngOnInit(): void { - + // Initialisierung wurde in ngAfterViewInit durchgeführt } ngAfterViewInit(){ - // Die Initialisierung wurde bereits in ngOnInit durchgeführt - // Initialisiere die erste Bild und die dazugehörigen Boxen - if (this.deck && this.deck.images.length > 0) { - this.loadImage(this.currentImageIndex); - } else { - alert('Kein Deck oder keine Bilder vorhanden.'); - this.close.emit(); - } + // Initialisiere das erste Bild und die dazugehörigen Boxen + if (this.deck && this.deck.images.length > 0) { + this.loadImage(this.currentImageIndex); + } else { + alert('Kein Deck oder keine Bilder vorhanden.'); + this.close.emit(); + } } /** @@ -126,15 +123,15 @@ export class TrainingComponent implements OnInit { this.boxesToReview.forEach((box, index) => { ctx.beginPath(); ctx.rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - if (this.currentBoxIndex === index && this.isShowingBox){ + if (this.currentBoxIndex === index && this.isShowingBox) { + // Box ist aktuell enthüllt, keine Überlagerung return; - // } else if (this.boxRevealed[index]) { } else if (this.currentBoxIndex === index && !this.isShowingBox) { // Box ist enthüllt - ctx.fillStyle = 'rgba(0, 255, 0, 1)'; // Transparente grüne Überlagerung + ctx.fillStyle = 'rgba(0, 255, 0, 1)'; // Undurchsichtige grüne Überlagerung } else { // Box ist verdeckt - ctx.fillStyle = 'rgba(255, 0, 0, 1)'; // Transparente rote Überlagerung + ctx.fillStyle = 'rgba(255, 0, 0, 1)'; // Undurchsichtige rote Überlagerung } ctx.fill(); ctx.lineWidth = 2; @@ -236,13 +233,14 @@ export class TrainingComponent implements OnInit { switch(action) { case 'again': - newIvl = 1 / 1440; // weniger als ein Tag, z.B., 1 Minute in Tagen + newIvl = 1 / 1440; // 1 Minute in Tagen newReps = 0; newLapses += 1; break; case 'good': if (newReps === 0) { - newIvl = 1; // nächste Wiederholung am nächsten Tag + newIvl = 10 / 1440; // 10 Minuten in Tagen + // newIvl = 1; // nächste Wiederholung am nächsten Tag } else { newIvl = newIvl * newFactor; } @@ -341,6 +339,58 @@ export class TrainingComponent implements OnInit { } } + /** + * Berechnet das nächste Intervall basierend auf der Aktion und gibt es als String zurück. + * @param box Die aktuelle Box + * @param action Die Aktion ('again', 'good', 'easy') + * @returns Das nächste Intervall als String (z.B. "10 min", "2 d") + */ + getNextInterval(box: Box | null, action: 'again' | 'good' | 'easy'): string { + if (!box) + return ''; + + let ivl = box.ivl || 0; + let factor = box.factor || 2.5; + let reps = box.reps || 0; + + switch(action) { + case 'again': + ivl = 1 / 1440; // 1 Minuten in Tagen + break; + case 'good': + if (reps === 0) { + ivl = 10 / 1440; // 10 Minuten in Tagen + } else { + ivl = ivl * factor; + } + break; + case 'easy': + if (reps === 0) { + ivl = 4; // 4 Tage + } else { + ivl = ivl * factor * 1.3; + } + break; + } + + return this.formatInterval(ivl); + } + + /** + * Formatiert das Intervall als String, entweder in Minuten oder Tagen. + * @param ivl Das Intervall in Tagen + * @returns Das formatierte Intervall als String + */ + formatInterval(ivl: number): string { + if (ivl < 1) { + const minutes = Math.round(ivl * 1440); + return `${minutes} min`; + } else { + const days = Math.floor(ivl); + return `${days} d`; + } + } + /** * Gibt den Fortschritt des Trainings an, z.B. "Bild 2 von 5". */