Anzeige des nächsten Intervals

This commit is contained in:
aknuth 2024-12-12 18:26:01 +01:00
parent d5ac4d6f26
commit 05bfd4f3eb
2 changed files with 71 additions and 21 deletions

View File

@ -20,7 +20,7 @@
class="bg-orange-500 disabled:bg-orange-200 text-white py-2 px-4 rounded hover:bg-orange-600" class="bg-orange-500 disabled:bg-orange-200 text-white py-2 px-4 rounded hover:bg-orange-600"
[disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length" [disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length"
> >
Nochmal Nochmal ({{ getNextInterval(currentBox, 'again') }})
</button> </button>
<!-- Gut Button --> <!-- Gut Button -->
@ -29,7 +29,7 @@
class="bg-blue-500 disabled:bg-blue-200 text-white py-2 px-4 rounded hover:bg-blue-600" class="bg-blue-500 disabled:bg-blue-200 text-white py-2 px-4 rounded hover:bg-blue-600"
[disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length" [disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length"
> >
Gut Gut ({{ getNextInterval(currentBox, 'good') }})
</button> </button>
<!-- Einfach Button --> <!-- Einfach Button -->
@ -38,7 +38,7 @@
class="bg-green-500 disabled:bg-green-200 text-white py-2 px-4 rounded hover:bg-green-600" class="bg-green-500 disabled:bg-green-200 text-white py-2 px-4 rounded hover:bg-green-600"
[disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length" [disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length"
> >
Einfach Einfach ({{ getNextInterval(currentBox, 'easy') }})
</button> </button>
<!-- Nächstes Bild Button --> <!-- Nächstes Bild Button -->

View File

@ -2,9 +2,7 @@
import { Component, Input, Output, EventEmitter, OnInit, ViewChild, ElementRef } from '@angular/core'; import { Component, Input, Output, EventEmitter, OnInit, ViewChild, ElementRef } from '@angular/core';
import { Deck, DeckImage, DeckService, Box } from '../deck.service'; import { Deck, DeckImage, DeckService, Box } from '../deck.service';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { switchMap } from 'rxjs/operators'; import { lastValueFrom } from 'rxjs';
import { forkJoin } from 'rxjs';
import { lastValueFrom } from 'rxjs'; // Import für toPromise-Alternative
@Component({ @Component({
selector: 'app-training', selector: 'app-training',
@ -30,18 +28,17 @@ export class TrainingComponent implements OnInit {
constructor(private deckService: DeckService) { } constructor(private deckService: DeckService) { }
ngOnInit(): void { ngOnInit(): void {
// Initialisierung wurde in ngAfterViewInit durchgeführt
} }
ngAfterViewInit(){ ngAfterViewInit(){
// Die Initialisierung wurde bereits in ngOnInit durchgeführt // Initialisiere das erste Bild und die dazugehörigen Boxen
// Initialisiere die erste Bild und die dazugehörigen Boxen if (this.deck && this.deck.images.length > 0) {
if (this.deck && this.deck.images.length > 0) { this.loadImage(this.currentImageIndex);
this.loadImage(this.currentImageIndex); } else {
} else { alert('Kein Deck oder keine Bilder vorhanden.');
alert('Kein Deck oder keine Bilder vorhanden.'); this.close.emit();
this.close.emit(); }
}
} }
/** /**
@ -126,15 +123,15 @@ export class TrainingComponent implements OnInit {
this.boxesToReview.forEach((box, index) => { this.boxesToReview.forEach((box, index) => {
ctx.beginPath(); ctx.beginPath();
ctx.rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); 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; return;
// } else if (this.boxRevealed[index]) {
} else if (this.currentBoxIndex === index && !this.isShowingBox) { } else if (this.currentBoxIndex === index && !this.isShowingBox) {
// Box ist enthüllt // 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 { } else {
// Box ist verdeckt // 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.fill();
ctx.lineWidth = 2; ctx.lineWidth = 2;
@ -236,13 +233,14 @@ export class TrainingComponent implements OnInit {
switch(action) { switch(action) {
case 'again': case 'again':
newIvl = 1 / 1440; // weniger als ein Tag, z.B., 1 Minute in Tagen newIvl = 1 / 1440; // 1 Minute in Tagen
newReps = 0; newReps = 0;
newLapses += 1; newLapses += 1;
break; break;
case 'good': case 'good':
if (newReps === 0) { 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 { } else {
newIvl = newIvl * newFactor; 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". * Gibt den Fortschritt des Trainings an, z.B. "Bild 2 von 5".
*/ */