BugFix bei Trainingsanzeige
This commit is contained in:
parent
576689a3ed
commit
f3cde1578e
|
|
@ -21,7 +21,9 @@
|
|||
<span class="text-gray-600">({{ deck.images.length }} Pics)</span>
|
||||
</div>
|
||||
<div class="text-sm text-gray-600">
|
||||
<div [ngClass]="{ 'text-blue-500 font-bold': isToday(getNextTrainingDate(deck)) }">Next training: {{ getNextTrainingString(deck) }}</div>
|
||||
<div [ngClass]="{ 'text-blue-500 font-bold': isToday(getNextTrainingDate(deck)), 'text-rose-500 font-bold': isBeforeToday(getNextTrainingDate(deck)) }">
|
||||
Next training: {{ getNextTrainingString(deck) }}
|
||||
</div>
|
||||
<div>Words to review: {{ getWordsToReview(deck) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -97,15 +99,14 @@
|
|||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="flex flex-row space-x-2">
|
||||
<button (click)="openTraining(activeDeck)" class="flex-1 bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600">Start Training</button>
|
||||
<div class="flex flex-row space-x-2 items-stretch">
|
||||
<button (click)="openTraining(activeDeck)" class="flex-1 bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600 flex items-center justify-center whitespace-nowrap">Start Training</button>
|
||||
<div class="flex-1">
|
||||
<div class="relative">
|
||||
<label for="imageFile" class="flex justify-center items-center bg-green-500 text-white py-2 px-4 rounded hover:bg-green-600 cursor-pointer">
|
||||
<div class="flex flex-col">
|
||||
<div>Add Image</div>
|
||||
<div class="text-xs">(from file)</div>
|
||||
<div class="relative h-full">
|
||||
<label for="imageFile" class="flex justify-center items-center bg-green-500 text-white py-2 px-4 rounded hover:bg-green-600 cursor-pointer h-full">
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="whitespace-nowrap">Add Image</div>
|
||||
<div class="text-xs whitespace-nowrap">(from file)</div>
|
||||
</div>
|
||||
</label>
|
||||
<input #imageFile type="file" id="imageFile" (change)="onFileChange($event)" accept="image/jpeg,image/png,image/gif,image/webp" required class="hidden" />
|
||||
|
|
@ -113,10 +114,10 @@
|
|||
</div>
|
||||
<!-- Neuer Button Paste Image -->
|
||||
<div class="flex-1">
|
||||
<button (click)="pasteImage()" class="w-full bg-purple-500 text-white py-2 px-4 rounded hover:bg-purple-600">
|
||||
<div class="flex flex-col">
|
||||
<div>Paste Image</div>
|
||||
<div class="text-xs">(from clipboard)</div>
|
||||
<button (click)="pasteImage()" class="w-full bg-purple-500 text-white py-2 px-4 rounded hover:bg-purple-600 flex items-center justify-center h-full">
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="whitespace-nowrap">Paste Image</div>
|
||||
<div class="text-xs whitespace-nowrap">(from clipboard)</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -493,31 +493,54 @@ export class DeckListComponent implements OnInit {
|
|||
}
|
||||
|
||||
// Methode zur Berechnung des nächsten Trainingsdatums
|
||||
getNextTrainingDate(deck: Deck): Date {
|
||||
const now = new Date();
|
||||
now.setHours(0, 0, 0, 0);
|
||||
const dueDates = deck.images.flatMap(image => image.boxes.map(box => (box.due ? new Date(box.due * 86400000) : null)));
|
||||
getNextTrainingDate(deck: Deck): number {
|
||||
const today = this.getTodayInDays();
|
||||
const dueDates = deck.images.flatMap(image => image.boxes.map(box => (box.due ? box.due : null)));
|
||||
if (dueDates.includes(null)) {
|
||||
return now;
|
||||
return today;
|
||||
}
|
||||
const futureDueDates = dueDates.filter(date => date && date >= now);
|
||||
if (futureDueDates.length > 0) {
|
||||
const nextDate = futureDueDates.reduce((a, b) => (a < b ? a : b));
|
||||
//const futureDueDates = dueDates.filter(date => date && date >= now);
|
||||
if (dueDates.length > 0) {
|
||||
const nextDate = dueDates.reduce((a, b) => (a < b ? a : b));
|
||||
return nextDate;
|
||||
}
|
||||
return now;
|
||||
return today;
|
||||
}
|
||||
getNextTrainingString(deck: Deck): string {
|
||||
return this.getNextTrainingDate(deck).toLocaleDateString();
|
||||
return this.daysSinceEpochToLocalDateString(this.getNextTrainingDate(deck));
|
||||
}
|
||||
// In deiner Component TypeScript Datei
|
||||
isToday(date: Date): boolean {
|
||||
const today = new Date();
|
||||
return date.getDate() === today.getDate() && date.getMonth() === today.getMonth() && date.getFullYear() === today.getFullYear();
|
||||
isToday(epochDays: number): boolean {
|
||||
return this.getTodayInDays() - epochDays === 0;
|
||||
}
|
||||
isBeforeToday(epochDays: number): boolean {
|
||||
return this.getTodayInDays() - epochDays > 0;
|
||||
}
|
||||
// Methode zur Berechnung der Anzahl der zu bearbeitenden Wörter
|
||||
getWordsToReview(deck: Deck): number {
|
||||
const nextTraining = this.getNextTrainingDate(deck);
|
||||
return deck.images.flatMap(image => image.boxes.filter(box => (box.due && new Date(box.due * 86400000) <= new Date(nextTraining)) || !box.due)).length;
|
||||
// const nextTraining = this.getNextTrainingDate(deck);
|
||||
// return deck.images.flatMap(image => image.boxes.filter(box => (box.due && new Date(box.due * 86400000) <= new Date(nextTraining)) || !box.due)).length;
|
||||
const today = this.getTodayInDays();
|
||||
return deck.images.flatMap(image => image.boxes.filter(box => (box.due && box.due <= today) || !box.due)).length;
|
||||
// this.currentImageData.boxes.filter(box => box.due === undefined || box.due <= today);
|
||||
}
|
||||
getTodayInDays(): number {
|
||||
const epoch = new Date(1970, 0, 1); // Anki uses UNIX epoch
|
||||
const today = new Date();
|
||||
return Math.floor((today.getTime() - epoch.getTime()) / (1000 * 60 * 60 * 24));
|
||||
}
|
||||
daysSinceEpochToLocalDateString(days: number): string {
|
||||
const msPerDay = 24 * 60 * 60 * 1000;
|
||||
// Erstelle ein Datum, das den exakten UTC-Zeitpunkt (Mitternacht UTC) repräsentiert:
|
||||
const utcDate = new Date(days * msPerDay);
|
||||
|
||||
// Formatiere das Datum: Mit timeZone: 'UTC' wird der UTC-Wert genutzt,
|
||||
// aber das Ausgabeformat (z. B. "4.2.2025" oder "2/4/2025") richtet sich nach der Locale.
|
||||
return new Intl.DateTimeFormat(undefined, {
|
||||
timeZone: 'UTC',
|
||||
day: 'numeric',
|
||||
month: 'numeric',
|
||||
year: 'numeric',
|
||||
}).format(utcDate);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,62 +1,33 @@
|
|||
<div class="mt-10">
|
||||
<div class="mt-10 mx-auto max-w-5xl">
|
||||
<h2 class="text-2xl font-bold mb-4">Training: {{ deck.name }}</h2>
|
||||
<div class="bg-white shadow rounded-lg p-6 flex flex-col items-center">
|
||||
<div class="rounded-lg p-6 flex flex-col items-center">
|
||||
<canvas #canvas class="mb-4 border max-h-[50vh]"></canvas>
|
||||
|
||||
<div class="flex space-x-4 mb-4">
|
||||
<!-- Show Button -->
|
||||
<button
|
||||
(click)="showText()"
|
||||
class="bg-green-500 disabled:bg-green-200 text-white py-2 px-4 rounded hover:bg-green-600"
|
||||
[disabled]="isShowingBox || currentBoxIndex >= boxesToReview.length"
|
||||
>
|
||||
Show
|
||||
</button>
|
||||
|
||||
<button (click)="showText()" class="bg-green-500 disabled:bg-green-200 text-white py-2 px-4 rounded hover:bg-green-600" [disabled]="isShowingBox || currentBoxIndex >= boxesToReview.length">Show</button>
|
||||
|
||||
<!-- Again Button -->
|
||||
<button
|
||||
(click)="markAgain()"
|
||||
class="bg-orange-500 disabled:bg-orange-200 text-white py-2 px-4 rounded hover:bg-orange-600"
|
||||
[disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length"
|
||||
>
|
||||
<button (click)="markAgain()" class="bg-orange-500 disabled:bg-orange-200 text-white py-2 px-4 rounded hover:bg-orange-600" [disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length">
|
||||
Again ({{ getNextInterval(currentBox, 'again') }})
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Good Button -->
|
||||
<button
|
||||
(click)="markGood()"
|
||||
class="bg-blue-500 disabled:bg-blue-200 text-white py-2 px-4 rounded hover:bg-blue-600"
|
||||
[disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length"
|
||||
>
|
||||
<button (click)="markGood()" class="bg-blue-500 disabled:bg-blue-200 text-white py-2 px-4 rounded hover:bg-blue-600" [disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length">
|
||||
Good ({{ getNextInterval(currentBox, 'good') }})
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Easy Button -->
|
||||
<button
|
||||
(click)="markEasy()"
|
||||
class="bg-green-500 disabled:bg-green-200 text-white py-2 px-4 rounded hover:bg-green-600"
|
||||
[disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length"
|
||||
>
|
||||
<button (click)="markEasy()" class="bg-green-500 disabled:bg-green-200 text-white py-2 px-4 rounded hover:bg-green-600" [disabled]="!isShowingBox || currentBoxIndex >= boxesToReview.length">
|
||||
Easy ({{ getNextInterval(currentBox, 'easy') }})
|
||||
</button>
|
||||
|
||||
<!-- Next Image Button -->
|
||||
<button
|
||||
(click)="skipToNextImage()"
|
||||
class="bg-yellow-500 disabled:bg-yellow-200 text-white py-2 px-4 rounded hover:bg-yellow-600"
|
||||
[disabled]="currentImageIndex >= deck.images.length"
|
||||
>
|
||||
Next Image
|
||||
</button>
|
||||
<button (click)="skipToNextImage()" class="bg-yellow-500 disabled:bg-yellow-200 text-white py-2 px-4 rounded hover:bg-yellow-600" [disabled]="currentImageIndex >= deck.images.length">Next Image</button>
|
||||
</div>
|
||||
|
||||
<p class="mt-2">{{ progress }}</p>
|
||||
|
||||
<button
|
||||
(click)="closeTraining()"
|
||||
class="mt-4 text-gray-500 hover:text-gray-700 underline"
|
||||
>
|
||||
End Training
|
||||
</button>
|
||||
<button (click)="closeTraining()" class="mt-4 text-gray-500 hover:text-gray-700 underline">End Training</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue