refactor(srs): update due-cards count

This commit is contained in:
rcmerci
2024-09-21 20:51:22 +08:00
parent ef2f79e2a1
commit 8d0d4b5063
4 changed files with 59 additions and 28 deletions

View File

@@ -1,13 +1,17 @@
(ns frontend.extensions.fsrs
"Flashcards functions based on FSRS, only works in db-based graphs"
(:require [datascript.core :as d]
[frontend.common.missionary-util :as c.m]
[frontend.components.block :as component-block]
[frontend.config :as config]
[frontend.context.i18n :refer [t]]
[frontend.db :as db]
[frontend.extensions.srs :as srs]
[frontend.handler.db-based.property :as db-property-handler]
[frontend.state :as state]
[frontend.ui :as ui]
[frontend.util :as util]
[missionary.core :as m]
[open-spaced-repetition.cljc-fsrs.core :as fsrs.core]
[rum.core :as rum]
[tick.core :as tick]))
@@ -39,10 +43,14 @@
fsrs-due (:property.value/content (:logseq.property.fsrs/due block-entity))
return-default-card-map? (not (and fsrs-state fsrs-due))]
(if return-default-card-map?
(fsrs.core/new-card!)
(if-let [block-created-at (some-> (:block/created-at block-entity) (js/Date.) tick/instant)]
(assoc (fsrs.core/new-card!)
:last-repeat block-created-at
:due block-created-at)
(fsrs.core/new-card!))
(property-fsrs-state->fsrs-card-map (assoc fsrs-state :due fsrs-due))))))
(defn repeat-card!
(defn- repeat-card!
[repo block-id rating]
(let [eid (if (uuid? block-id) [:block/uuid block-id] block-id)
block-entity (db/entity repo eid)]
@@ -57,18 +65,7 @@
block-id :logseq.property.fsrs/due (str prop-fsrs-due)
{:new-block-id (db/new-block-id)})))))
(defn get-card-block-ids
[repo]
(let [db (db/get-db repo)]
(->>
(d/q '[:find ?b
:where
[?b :block/tags :logseq.class/Card]
[?b :block/uuid]]
db)
(apply concat))))
(defn get-due-card-block-ids
(defn- get-due-card-block-ids
[repo]
(let [db (db/get-db repo)
now-inst-ms (inst-ms (js/Date.))]
@@ -76,9 +73,12 @@
:in $ ?now-inst-ms
:where
[?b :block/tags :logseq.class/Card]
[?b :logseq.property.fsrs/due ?due-b]
[?due-b :property.value/content ?due]
[(>= ?now-inst-ms ?due)]
(or-join [?b ?now-inst-ms]
(and
[?b :logseq.property.fsrs/due ?due-b]
[?due-b :property.value/content ?due]
[(>= ?now-inst-ms ?due)])
[(missing? $ ?b :logseq.property.fsrs/due)])
[?b :block/uuid]]
db now-inst-ms)
(apply concat))))
@@ -96,20 +96,22 @@
(def ^:private phase->next-phase
{:init :show-answer
:show-answer :end
:end :end})
:show-answer :init})
(rum/defcs card <
(rum/defcs ^:private card <
(rum/local :init ::phase)
[state repo block-entity]
(let [*phase (::phase state)]
(let [*phase (::phase state)
show-btn? (contains? #{:show-answer} @*phase)]
[:div.ls-card.content
[:div (component-block/breadcrumb {} repo (:block/uuid block-entity) {})]
(component-block/blocks-container
(cond-> {}
(contains? #{:init} @*phase) (assoc :hide-children? true))
[block-entity])
(btn-with-shortcut {:btn-text (t :flashcards/modal-btn-show-answers)
(btn-with-shortcut {:btn-text (t (if show-btn?
:flashcards/modal-btn-show-answers
:flashcards/modal-btn-hide-answers))
:shortcut "s"
:id (str "card-answers")
:on-click #(swap! *phase phase->next-phase)})]))
@@ -140,13 +142,39 @@
(swap! *card-index inc))}))
(keys rating->shortcut)))
(declare update-due-cards-count)
(rum/defcs cards <
(rum/local 0 ::card-index)
{:will-unmount (fn [state]
(update-due-cards-count)
state)}
[state]
(let [repo (state/get-current-repo)
block-ids (get-card-block-ids repo)
block-ids (get-due-card-block-ids repo)
*card-index (::card-index state)]
(if-let [block-entity (some-> (nth block-ids @*card-index nil) db/entity)]
(vec (concat [:div (card repo block-entity)]
(rating-btns repo (:db/id block-entity) *card-index)))
[:p.p-2 (t :flashcards/modal-finished)])))
(defonce ^:private *last-update-due-cards-count-canceler (atom nil))
(def ^:private new-task--update-due-cards-count
"Return a task that update `:srs/cards-due-count` periodically."
(m/sp
(let [repo (state/get-current-repo)]
(if (config/db-based-graph? repo)
(m/?
(m/reduce
(fn [_ _]
(state/set-state! :srs/cards-due-count (count (get-due-card-block-ids repo))))
(c.m/clock (* 3600 1000))))
(srs/update-cards-due-count!)))))
(defn update-due-cards-count
[]
(when-let [canceler @*last-update-due-cards-count-canceler]
(canceler)
(reset! *last-update-due-cards-count-canceler nil))
(let [canceler (c.m/run-task new-task--update-due-cards-count :update-due-cards-count)]
(reset! *last-update-due-cards-count-canceler canceler)
nil))