浏览代码

fix: cards using async db query

Tienson Qin 1 年之前
父节点
当前提交
db92683d70

+ 53 - 54
src/main/frontend/components/container.cljs

@@ -335,60 +335,59 @@
         (repo/repos-dropdown)
         (repo/repos-dropdown)
 
 
         [:div.nav-header.flex.flex-col.mt-1
         [:div.nav-header.flex.flex-col.mt-1
-           (let [page (:page default-home)]
-             (if (and page (not (state/enable-journals? (state/get-current-repo))))
-               (sidebar-item
-                {:class "home-nav"
-                 :title page
-                 :on-click-handler route-handler/redirect-to-home!
-                 :active (and (not srs-open?)
-                              (= route-name :page)
-                              (= page (get-in route-match [:path-params :name])))
-                 :icon "home"
-                 :shortcut :go/home})
-               (sidebar-item
-                {:class "journals-nav"
-                 :active (and (not srs-open?)
-                              (or (= route-name :all-journals) (= route-name :home)))
-                 :title (t :left-side-bar/journals)
-                 :on-click-handler (fn [e]
-                                     (if (gobj/get e "shiftKey")
-                                       (route-handler/sidebar-journals!)
-                                       (route-handler/go-to-journals!)))
-                 :icon "calendar"
-                 :shortcut :go/journals})))
-
-           (when enable-whiteboards?
-             (when (or config/dev? (not db-based?))
-               (sidebar-item
-                {:class "whiteboard"
-                 :title (t :right-side-bar/whiteboards)
-                 :href (rfe/href :whiteboards)
-                 :on-click-handler (fn [_e] (whiteboard-handler/onboarding-show))
-                 :active (and (not srs-open?) (#{:whiteboard :whiteboards} route-name))
-                 :icon "whiteboard"
-                 :icon-extension? true
-                 :shortcut :go/whiteboards})))
-
-           (when (and (state/enable-flashcards? (state/get-current-repo))
-                      (not db-based?))
-             [:div.flashcards-nav
-              (flashcards srs-open?)])
-
-           (sidebar-item
-            {:class "graph-view-nav"
-             :title (t :right-side-bar/graph-view)
-             :href (rfe/href :graph)
-             :active (and (not srs-open?) (= route-name :graph))
-             :icon "hierarchy"
-             :shortcut :go/graph-view})
-
-           (sidebar-item
-            {:class "all-pages-nav"
-             :title (t :right-side-bar/all-pages)
-             :href (rfe/href :all-pages)
-             :active (and (not srs-open?) (= route-name :all-pages))
-             :icon "files"})]]
+         (let [page (:page default-home)]
+           (if (and page (not (state/enable-journals? (state/get-current-repo))))
+             (sidebar-item
+              {:class "home-nav"
+               :title page
+               :on-click-handler route-handler/redirect-to-home!
+               :active (and (not srs-open?)
+                            (= route-name :page)
+                            (= page (get-in route-match [:path-params :name])))
+               :icon "home"
+               :shortcut :go/home})
+             (sidebar-item
+              {:class "journals-nav"
+               :active (and (not srs-open?)
+                            (or (= route-name :all-journals) (= route-name :home)))
+               :title (t :left-side-bar/journals)
+               :on-click-handler (fn [e]
+                                   (if (gobj/get e "shiftKey")
+                                     (route-handler/sidebar-journals!)
+                                     (route-handler/go-to-journals!)))
+               :icon "calendar"
+               :shortcut :go/journals})))
+
+         (when enable-whiteboards?
+           (when (or config/dev? (not db-based?))
+             (sidebar-item
+              {:class "whiteboard"
+               :title (t :right-side-bar/whiteboards)
+               :href (rfe/href :whiteboards)
+               :on-click-handler (fn [_e] (whiteboard-handler/onboarding-show))
+               :active (and (not srs-open?) (#{:whiteboard :whiteboards} route-name))
+               :icon "whiteboard"
+               :icon-extension? true
+               :shortcut :go/whiteboards})))
+
+         (when (state/enable-flashcards? (state/get-current-repo))
+           [:div.flashcards-nav
+            (flashcards srs-open?)])
+
+         (sidebar-item
+          {:class "graph-view-nav"
+           :title (t :right-side-bar/graph-view)
+           :href (rfe/href :graph)
+           :active (and (not srs-open?) (= route-name :graph))
+           :icon "hierarchy"
+           :shortcut :go/graph-view})
+
+         (sidebar-item
+          {:class "all-pages-nav"
+           :title (t :right-side-bar/all-pages)
+           :href (rfe/href :all-pages)
+           :active (and (not srs-open?) (= route-name :all-pages))
+           :icon "files"})]]
 
 
        [:div.nav-contents-container.flex.flex-col.gap-1.pt-1
        [:div.nav-contents-container.flex.flex-col.gap-1.pt-1
         {:on-scroll on-contents-scroll}
         {:on-scroll on-contents-scroll}

+ 1 - 1
src/main/frontend/components/settings.cljs

@@ -1120,7 +1120,7 @@
        (plugin-system-switcher-row))
        (plugin-system-switcher-row))
      (when (util/electron?)
      (when (util/electron?)
        (http-server-switcher-row))
        (http-server-switcher-row))
-     (when-not db-based? (flashcards-switcher-row enable-flashcards?))
+     (flashcards-switcher-row enable-flashcards?)
      (when-not db-based? (zotero-settings-row))
      (when-not db-based? (zotero-settings-row))
      (when (and config/dev? (config/db-based-graph? current-repo))
      (when (and config/dev? (config/db-based-graph? current-repo))
        ;; FIXME: Wire this up again to RTC init calls
        ;; FIXME: Wire this up again to RTC init calls

+ 77 - 57
src/main/frontend/extensions/fsrs.cljs

@@ -1,11 +1,11 @@
 (ns frontend.extensions.fsrs
 (ns frontend.extensions.fsrs
   "Flashcards functions based on FSRS, only works in db-based graphs"
   "Flashcards functions based on FSRS, only works in db-based graphs"
-  (:require [datascript.core :as d]
-            [frontend.common.missionary-util :as c.m]
+  (:require [frontend.common.missionary-util :as c.m]
             [frontend.components.block :as component-block]
             [frontend.components.block :as component-block]
             [frontend.config :as config]
             [frontend.config :as config]
             [frontend.context.i18n :refer [t]]
             [frontend.context.i18n :refer [t]]
             [frontend.db :as db]
             [frontend.db :as db]
+            [frontend.db.async :as db-async]
             [frontend.extensions.srs :as srs]
             [frontend.extensions.srs :as srs]
             [frontend.handler.db-based.property :as db-property-handler]
             [frontend.handler.db-based.property :as db-property-handler]
             [frontend.state :as state]
             [frontend.state :as state]
@@ -17,7 +17,9 @@
             [clojure.string :as string]
             [clojure.string :as string]
             [logseq.shui.ui :as shui]
             [logseq.shui.ui :as shui]
             [frontend.ui :as ui]
             [frontend.ui :as ui]
-            [frontend.modules.shortcut.core :as shortcut]))
+            [frontend.modules.shortcut.core :as shortcut]
+            [promesa.core :as p]
+            [frontend.db-mixins :as db-mixins]))
 
 
 (def ^:private instant->inst-ms (comp inst-ms tick/inst))
 (def ^:private instant->inst-ms (comp inst-ms tick/inst))
 (defn- inst-ms->instant [ms] (tick/instant (js/Date. ms)))
 (defn- inst-ms->instant [ms] (tick/instant (js/Date. ms)))
@@ -67,22 +69,21 @@
          {:logseq.property.fsrs/state prop-fsrs-state
          {:logseq.property.fsrs/state prop-fsrs-state
           :logseq.property.fsrs/due prop-fsrs-due})))))
           :logseq.property.fsrs/due prop-fsrs-due})))))
 
 
-(defn- get-due-card-block-ids
+(defn- <get-due-card-block-ids
   [repo]
   [repo]
-  (let [db (db/get-db repo)
-        now-inst-ms (inst-ms (js/Date.))]
-    (->> (d/q '[:find ?b
-                :in $ ?now-inst-ms
-                :where
-                [?b :block/tags :logseq.class/Card]
-                (or-join [?b ?now-inst-ms]
-                         (and
-                          [?b :logseq.property.fsrs/due ?due]
-                          [(>= ?now-inst-ms ?due)])
-                         [(missing? $ ?b :logseq.property.fsrs/due)])
-                [?b :block/uuid]]
-              db now-inst-ms)
-         (apply concat))))
+  (let [now-inst-ms (inst-ms (js/Date.))]
+    (db-async/<q repo {:transact-db? false}
+                 '[:find [?b ...]
+                   :in $ ?now-inst-ms
+                   :where
+                   [?b :block/tags :logseq.class/Card]
+                   (or-join [?b ?now-inst-ms]
+                            (and
+                             [?b :logseq.property.fsrs/due ?due]
+                             [(>= ?now-inst-ms ?due)])
+                            [(missing? $ ?b :logseq.property.fsrs/due)])
+                   [?b :block/uuid]]
+                 now-inst-ms)))
 
 
 (defn- btn-with-shortcut [{:keys [shortcut id btn-text background on-click class]}]
 (defn- btn-with-shortcut [{:keys [shortcut id btn-text background on-click class]}]
   (shui/button
   (shui/button
@@ -162,54 +163,72 @@
                                    {:align "start"}))}
                                    {:align "start"}))}
     (ui/icon "info-circle"))])
     (ui/icon "info-circle"))])
 
 
-(rum/defcs ^:private card < rum/reactive
-  [state repo block-entity *card-index *phase]
-  (let [phase (rum/react *phase)
-        next-phase (phase->next-phase block-entity phase)]
-    [:div.ls-card.content
-     [:div (component-block/breadcrumb {} repo (:block/uuid block-entity) {})]
-     (let [option (case phase
-                    :init
-                    {:hide-children? true}
-                    :show-cloze
-                    {:show-cloze? true
-                     :hide-children? true}
-                    {:show-cloze? true})]
-       (component-block/blocks-container option [block-entity]))
-     [:div.mt-8
-      (if (contains? #{:show-cloze :show-answer} next-phase)
-        (btn-with-shortcut {:btn-text (t
-                                       (case next-phase
-                                         :show-answer
-                                         :flashcards/modal-btn-show-answers
-                                         :show-cloze
-                                         :flashcards/modal-btn-show-clozes
-                                         :init
-                                         :flashcards/modal-btn-hide-answers))
-                            :shortcut "s"
-                            :id (str "card-answers")
-                            :on-click #(swap! *phase
-                                              (fn [phase]
-                                                (phase->next-phase block-entity phase)))})
-        (rating-btns repo (:db/id block-entity) *card-index *phase))]]))
+(rum/defcs ^:private card < rum/reactive db-mixins/query
+  {:will-mount (fn [state]
+                 (when-let [[repo block-id _] (:rum/args state)]
+                   (db-async/<get-block repo block-id))
+                 state)}
+  [state repo block-id *card-index *phase]
+  (when-let [block-entity (db/sub-block block-id)]
+    (let [phase (rum/react *phase)
+          next-phase (phase->next-phase block-entity phase)]
+      [:div.ls-card.content
+       [:div (component-block/breadcrumb {} repo (:block/uuid block-entity) {})]
+       (let [option (case phase
+                      :init
+                      {:hide-children? true}
+                      :show-cloze
+                      {:show-cloze? true
+                       :hide-children? true}
+                      {:show-cloze? true})]
+         (component-block/blocks-container option [block-entity]))
+       [:div.mt-8
+        (if (contains? #{:show-cloze :show-answer} next-phase)
+          (btn-with-shortcut {:btn-text (t
+                                         (case next-phase
+                                           :show-answer
+                                           :flashcards/modal-btn-show-answers
+                                           :show-cloze
+                                           :flashcards/modal-btn-show-clozes
+                                           :init
+                                           :flashcards/modal-btn-hide-answers))
+                              :shortcut "s"
+                              :id (str "card-answers")
+                              :on-click #(swap! *phase
+                                                (fn [phase]
+                                                  (phase->next-phase block-entity phase)))})
+          (rating-btns repo (:db/id block-entity) *card-index *phase))]])))
 
 
 (declare update-due-cards-count)
 (declare update-due-cards-count)
-(rum/defcs cards <
+(rum/defcs cards < rum/reactive
   (rum/local 0 ::card-index)
   (rum/local 0 ::card-index)
   (shortcut/mixin :shortcut.handler/cards false)
   (shortcut/mixin :shortcut.handler/cards false)
-  {:will-unmount (fn [state]
+  {:init (fn [state]
+           (let [*block-ids (atom nil)
+                 *loading? (atom nil)]
+             (reset! *loading? true)
+             (p/let [result (<get-due-card-block-ids (state/get-current-repo))]
+               (reset! *block-ids result)
+               (reset! *loading? false))
+             (assoc state
+                    ::block-ids *block-ids
+                    ::loading? *loading?)))
+   :will-unmount (fn [state]
                    (update-due-cards-count)
                    (update-due-cards-count)
                    state)}
                    state)}
   [state]
   [state]
   (let [repo (state/get-current-repo)
   (let [repo (state/get-current-repo)
-        block-ids (get-due-card-block-ids repo)
+        *block-ids (::block-ids state)
+        block-ids (rum/react *block-ids)
+        loading? (rum/react (::loading? state))
         *card-index (::card-index state)
         *card-index (::card-index state)
         *phase (atom :init)]
         *phase (atom :init)]
-    [:div#cards-modal.p-2
-     (if-let [block-entity (some-> (nth block-ids @*card-index nil) db/entity)]
-       [:div.flex.flex-col
-        (card repo block-entity *card-index *phase)]
-       [:p (t :flashcards/modal-finished)])]))
+    (when (false? loading?)
+      [:div#cards-modal.p-2
+      (if-let [block-id (nth block-ids @*card-index nil)]
+        [:div.flex.flex-col
+         (card repo block-id *card-index *phase)]
+        [:p (t :flashcards/modal-finished)])])))
 
 
 (defonce ^:private *last-update-due-cards-count-canceler (atom nil))
 (defonce ^:private *last-update-due-cards-count-canceler (atom nil))
 (def ^:private new-task--update-due-cards-count
 (def ^:private new-task--update-due-cards-count
@@ -220,7 +239,8 @@
         (m/?
         (m/?
          (m/reduce
          (m/reduce
           (fn [_ _]
           (fn [_ _]
-            (state/set-state! :srs/cards-due-count (count (get-due-card-block-ids repo))))
+            (p/let [due-cards (<get-due-card-block-ids repo)]
+              (state/set-state! :srs/cards-due-count (count due-cards))))
           (c.m/clock (* 3600 1000))))
           (c.m/clock (* 3600 1000))))
         (srs/update-cards-due-count!)))))
         (srs/update-cards-due-count!)))))