Skip to content

Commit

Permalink
timeline
Browse files Browse the repository at this point in the history
  • Loading branch information
WolfyWin committed Nov 27, 2023
1 parent d56d32c commit 7032efc
Show file tree
Hide file tree
Showing 23 changed files with 378 additions and 143 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ public function updateProgressionAction(Flashcard $card, User $user, Request $re
$node = $deck->getResourceNode();
$resourceUserEvaluation = $this->evaluationManager->getResourceUserEvaluation($node, $user);

// Mise à jour de la progression de la carte
$this->evaluationManager->updateCardDrawnProgression($card, $user, $request->get('isSuccessful'));

$attempt = $this->resourceEvalRepo->findOneInProgress($node, $user);
Expand Down
1 change: 0 additions & 1 deletion src/plugin/flashcard/Manager/EvaluationManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ public function update(ResourceEvaluation $attempt, $attemptCards): ResourceEval
}
}

// Pas de cartes restantes pour cette session, on passe a la session suivante
if (0 === count($cardsArray)) {
++$session;
}
Expand Down
40 changes: 22 additions & 18 deletions src/plugin/flashcard/Manager/FlashcardManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
$cardsSessionIds = $attempt ? $attempt->getData()['cardsSessionIds'] ?? [] : [];
$cardsAnsweredIds = $attempt ? $attempt->getData()['cardsAnsweredIds'] ?? [] : [];

// Récup des entités cartes de la tentative
$cards = array_map(function ($card) {
return $this->om->getRepository(CardDrawnProgression::class)->findOneBy([
'id' => $card['id'],
Expand All @@ -113,12 +112,12 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
]);
}, $cardsAnsweredIds);

// Création d'une nouvelle tentative si nécessaire
if (!$attempt) {
$attempt = $this->resourceEvalManager->createAttempt($node, $user, [
'status' => AbstractEvaluation::STATUS_OPENED,
'progression' => 0,
'data' => [
// TODO: ajouter la date de la prochaine session en fonction de leitner
'session' => $session,
'cards' => $cards,
'cardsSessionIds' => $cardsSessionIds,
Expand All @@ -127,7 +126,10 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
]);
}

// Récupération des cartes de la tentative
if (0 === count($deck->getCards())) {
return $attempt;
}

$attemptCards = self::shuffleCardByAttempt($deck->getCards(), $attempt, $deck->getDraw());
foreach ($attemptCards as $card) {
$progression = $this->om->getRepository(CardDrawnProgression::class)->findOneBy([
Expand All @@ -149,15 +151,13 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
}
}

// Filtrage des cartes pour la session
$cardsSession = [];
foreach ($cards as $cardProgression) {
if ($this->keepCardInSession($session, $cardProgression)) {
$cardsSession[] = $cardProgression;
}
}

// Ajout des cartes de la session 1
if (0 === count($cardsSession) && 1 === $session) {
$attempt = $this->resourceEvalManager->updateAttempt($attempt, [
'status' => AbstractEvaluation::STATUS_OPENED,
Expand All @@ -177,7 +177,6 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
]);
}

// Suppression des cartes répondues de la liste des cartes de la session
foreach ($cardsAnswered as $cardProgression) {
foreach ($cardsSession as $key => $cardSession) {
if ($cardProgression->getId() === $cardSession->getId()) {
Expand All @@ -187,22 +186,17 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
}
}

// Incrément de la session et réinitialisation des cartes si nécessaire
while (0 === count($cardsSession) && $session < 7) {
++$session;

$cardsSession = [];
$cardsAnswered = [];

// Filtrage des cartes pour la nouvelle session
foreach ($cards as $cardProgression) {
if ($this->keepCardInSession($session, $cardProgression)) {
$cardsSession[] = $cardProgression;
}
}
}

// Calcul de la progression
$successfulCards = 0;
$totalCards = count($cardsSession) + count($cardsAnswered);
foreach ($cardsAnswered as $cardProgression) {
Expand All @@ -211,11 +205,9 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
if (0 === $totalCards) {
$progression = 0;
} else {
// Transformation du résultat en integer car round() retourne un float
$progression = (int) min(round($successfulCards / $totalCards * 100), 100);
}

// Vérification du status
if (7 === $session && 0 === count($cardsSession)) {
if (100 === $progression) {
$status = AbstractEvaluation::STATUS_COMPLETED;
Expand All @@ -226,11 +218,11 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
$status = AbstractEvaluation::STATUS_INCOMPLETE;
}

// Mise à jour de la tentative
$attempt = $this->resourceEvalManager->updateAttempt($attempt, [
'status' => $status,
'progression' => $progression,
'data' => [
'date' => $this->getLeitnerDate($session),
'session' => $session,
'cards' => array_map(function ($card) {
return $this->cardDrawnProgressionSerializer->serialize($card);
Expand All @@ -244,9 +236,7 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
],
]);

// Si on n'a pas de page de début ni de fin
if (!$deck->getShowOverview() && !$deck->getShowEndPage()) {
// On recrée une nouvelle tentative directement une fois la précédente terminée pour enchainer
if (AbstractEvaluation::STATUS_COMPLETED === $status || AbstractEvaluation::STATUS_FAILED === $status) {
$attempt = $this->calculateSession(null, $deck, $user);
}
Expand All @@ -261,7 +251,6 @@ public function answerSessionCard(ResourceEvaluation $attempt, CardDrawnProgress
$cardsSessionIds = $attempt->getData()['cardsSessionIds'] ?? [];
$cardsAnsweredIds = $attempt->getData()['cardsAnsweredIds'] ?? [];

// Deserialization des cartes de la tentative
$cards = array_map(function ($card) {
return $this->om->getRepository(CardDrawnProgression::class)->findOneBy([
'id' => $card['id'],
Expand All @@ -272,7 +261,6 @@ public function answerSessionCard(ResourceEvaluation $attempt, CardDrawnProgress
$cardsAnsweredIds[] = $cardProgression->getId();
}

// Mise à jour de la tentative
return $this->resourceEvalManager->updateAttempt($attempt, [
'status' => $attempt->getStatus(),
'progression' => $attempt->getProgression(),
Expand All @@ -286,4 +274,20 @@ public function answerSessionCard(ResourceEvaluation $attempt, CardDrawnProgress
],
]);
}

private function getLeitnerDate(int $session): \DateTime
{
$interval = match ($session) {
1 => new \DateInterval('P1D'),
2 => new \DateInterval('P2D'),
3 => new \DateInterval('P4D'),
4 => new \DateInterval('P7D'),
5 => new \DateInterval('P10D'),
6 => new \DateInterval('P20D'),
7 => new \DateInterval('P30D'),
default => new \DateInterval('P0D'),
};

return (new \DateTime())->add($interval);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Card.propTypes = {
actions: T.func,
card: T.shape(
CardTypes.propTypes
).isRequired
)
}

export {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const FlashcardMenu = props =>
/>

FlashcardMenu.propTypes = {
// from menu
opened: T.bool.isRequired,
toggle: T.func.isRequired,
autoClose: T.func.isRequired
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ import {PropTypes as T} from 'prop-types'
import get from 'lodash/get'

import {trans} from '#/main/app/intl/translation'
import {ContentHtml} from '#/main/app/content/components/html'
import {LINK_BUTTON} from '#/main/app/buttons'
import {ResourceOverview} from '#/main/core/resource/components/overview'
import {ResourceEvaluation as ResourceEvaluationTypes} from '#/main/evaluation/resource/prop-types'
import {FlashcardInfo} from '#/plugin/flashcard/resources/flashcard/components/info'

import {Timeline} from '#/plugin/flashcard/resources/flashcard/components/timeline'
import {LeitnerRules} from '#/plugin/flashcard/resources/flashcard/components/rules'
import {FlashcardDeck as FlashcardDeckTypes} from '#/plugin/flashcard/resources/flashcard/prop-types'

const Overview = (props) => {
console.log(props)
const attemptData = props.attempt && props.attempt.data
const sessionStarted = attemptData ? attemptData.cardsAnsweredIds.length > 0 : false
const sessionCompleted = attemptData ? attemptData.cardsSessionIds.length === 0 : false
Expand Down Expand Up @@ -57,9 +61,29 @@ const Overview = (props) => {
[trans('session_status', {}, 'flashcard'), statusText]
]}
>
<FlashcardInfo
flashcardProgression={props.attempt.data.cards}

<Timeline
session={session}
started={sessionStarted}
completed={sessionCompleted}
date={attemptData.date ? attemptData.date.date : null}
/>

<section className="resource-info mb-3">
<h3 className="h2">
{trans('leitner_method', {}, 'flashcard')}
</h3>
<div className="card mb-3">
<ContentHtml className="card-body">
{trans('leitner_method_desc', {}, 'flashcard')}
</ContentHtml>
</div>

<LeitnerRules
session={session}
completed={sessionCompleted}
/>
</section>
</ResourceOverview>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React from 'react'
import classes from 'classnames'
import {PropTypes as T} from 'prop-types'

import {trans} from '#/main/app/intl'

const SessionRule= props => {
let icon = <span className={'fa fa-fw fa-map-marker'}/>
if (props.index > 1 && props.index < 7) {
icon = <span className={'fa fa-fw fa-arrow-turn-down icon-mirror'}/>
} else if (props.index === 7) {
icon = <span className={'fa fa-fw fa-flag-checkered'}/>
}

let rule = props.index
if (props.index === 1) {
rule = trans('session_cards_all', {}, 'flashcard')
} else if (props.index === 2 || props.index === 4) {
rule = trans('session_cards_1x', {}, 'flashcard') + ' + ' + trans('session_cards_failed', {}, 'flashcard')
} else if (props.index === 3) {
rule = trans('session_cards_2x', {}, 'flashcard') + ' + ' + trans('session_cards_failed', {}, 'flashcard')
} else if (props.index === 5) {
rule = trans('session_cards_failed', {}, 'flashcard')
} else if (props.index === 6) {
rule = trans('session_cards_1x', {}, 'flashcard') + ' + ' + trans('session_cards_2x', {}, 'flashcard') + ' + ' + trans('session_cards_failed', {}, 'flashcard')
} else if (props.index === 7) {
rule = trans('session_cards_3x', {}, 'flashcard') + ' + ' + trans('session_cards_failed', {}, 'flashcard')
}

let classList = ['icon-with-text-right']
if (props.index < props.session || (props.index === props.session && props.completed)) {
classList.push('session-rule-done')
}

return (
<li className="session-rule">
<div className={classes(classList)}>
{icon}
</div>
<div className="">
Session {props.index} : {trans('session_cards_start', {}, 'flashcard') + ' ' + rule}.
</div>
</li>
)
}

SessionRule.propTypes = {
session: T.number,
rule: T.number,
completed: T.bool,
index: T.number
}

const LeitnerRules = (props) => {
return (
<ul className="sessions-rules">
{Array.from({ length: 7 }, (_, index) => (
<SessionRule
key={index}
session={props.session}
completed={props.completed}
index={index + 1}
/>
))}
</ul>
)
}

LeitnerRules.propTypes = {
session: T.number,
completed: T.bool
}

export {
LeitnerRules
}
Loading

0 comments on commit 7032efc

Please sign in to comment.