Browse Source

add card preview & score help info

rcmerci 4 years ago
parent
commit
57af1823a7

+ 0 - 3
shadow-cljs.edn

@@ -20,9 +20,6 @@
               :depends-on #{:main}}
               :depends-on #{:main}}
              :excalidraw
              :excalidraw
              {:entries [frontend.extensions.excalidraw]
              {:entries [frontend.extensions.excalidraw]
-              :depends-on #{:main}}
-             :srs
-             {:entries [frontend.extensions.srs]
               :depends-on #{:main}}}
               :depends-on #{:main}}}
 
 
    :output-dir "./static/js"
    :output-dir "./static/js"

+ 2 - 2
src/main/frontend/components/block.cljs

@@ -1490,8 +1490,8 @@
   [config block]
   [config block]
   (let [properties (walk/keywordize-keys (:block/properties block))
   (let [properties (walk/keywordize-keys (:block/properties block))
         properties-order (:block/properties-order block)
         properties-order (:block/properties-order block)
-        properties (apply dissoc properties property/built-in-properties)
-        properties-order (remove property/built-in-properties properties-order)
+        properties (apply dissoc properties (property/built-in-properties))
+        properties-order (remove (property/built-in-properties) properties-order)
         pre-block? (:block/pre-block? block)
         pre-block? (:block/pre-block? block)
         properties (if pre-block?
         properties (if pre-block?
                      (let [repo (state/get-current-repo)
                      (let [repo (state/get-current-repo)

+ 12 - 5
src/main/frontend/components/content.cljs

@@ -22,7 +22,8 @@
             [frontend.components.export :as export]
             [frontend.components.export :as export]
             [frontend.context.i18n :as i18n]
             [frontend.context.i18n :as i18n]
             [frontend.text :as text]
             [frontend.text :as text]
-            [frontend.handler.page :as page-handler]))
+            [frontend.handler.page :as page-handler]
+            [frontend.extensions.srs :as srs]))
 
 
 (defn- set-format-js-loading!
 (defn- set-format-js-loading!
   [format value]
   [format value]
@@ -179,6 +180,12 @@
                         (state/set-modal! #(export/export-blocks block-id)))}
                         (state/set-modal! #(export/export-blocks block-id)))}
            "Export")
            "Export")
 
 
+          (when (srs/card-block? block)
+            (ui/menu-link
+             {:key "Preview Card"
+              :on-click #(srs/preview [(db/pull [:block/uuid block-id])])}
+             "Preview"))
+
           (ui/menu-link
           (ui/menu-link
            {:key "Copy as JSON"
            {:key "Copy as JSON"
             :on-click (fn [_e]
             :on-click (fn [_e]
@@ -195,10 +202,10 @@
             (when-let [cmds (state/get-plugins-commands-with-type :block-context-menu-item)]
             (when-let [cmds (state/get-plugins-commands-with-type :block-context-menu-item)]
               (for [[_ {:keys [key label] :as cmd} action pid] cmds]
               (for [[_ {:keys [key label] :as cmd} action pid] cmds]
                 (ui/menu-link
                 (ui/menu-link
-                  {:key      key
-                   :on-click #(commands/exec-plugin-simple-command!
-                                pid (assoc cmd :uuid block-id) action)}
-                  label))))
+                 {:key      key
+                  :on-click #(commands/exec-plugin-simple-command!
+                              pid (assoc cmd :uuid block-id) action)}
+                 label))))
 
 
           (when (state/sub [:ui/developer-mode?])
           (when (state/sub [:ui/developer-mode?])
             (ui/menu-link
             (ui/menu-link

+ 74 - 18
src/main/frontend/extensions/srs.cljs

@@ -9,6 +9,7 @@
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.editor :as editor-handler]
             [frontend.components.block :as component-block]
             [frontend.components.block :as component-block]
             [frontend.components.macro :as component-macro]
             [frontend.components.macro :as component-macro]
+            [frontend.components.svg :as svg]
             [frontend.ui :as ui]
             [frontend.ui :as ui]
             [cljs-time.core :as t]
             [cljs-time.core :as t]
             [cljs-time.coerce :as tc]
             [cljs-time.coerce :as tc]
@@ -23,11 +24,10 @@
 ;;;   and its children are the back side
 ;;;   and its children are the back side
 ;;; - When the card's type is ':cloze', '{{cloze: <content>}}' shows as '[...]'
 ;;; - When the card's type is ':cloze', '{{cloze: <content>}}' shows as '[...]'
 
 
-
 ;;; ================================================================
 ;;; ================================================================
 ;;; const & vars
 ;;; const & vars
 
 
-(def card-type [:cloze :sided])
+(def card-type-set #{:cloze :sided})
 
 
 (def card-type-property          :card-type)
 (def card-type-property          :card-type)
 (def card-last-interval-property :card-last-interval)
 (def card-last-interval-property :card-last-interval)
@@ -58,6 +58,10 @@
 ;;; ================================================================
 ;;; ================================================================
 ;;; utils
 ;;; utils
 
 
+(defn- get-block-card-type
+  [block]
+  (keyword (get (:block/properties block) card-type-property)))
+
 (defn- get-block-card-properties
 (defn- get-block-card-properties
   [block]
   [block]
   (when-let [properties (:block/properties block)]
   (when-let [properties (:block/properties block)]
@@ -88,6 +92,13 @@
      (#(do (println %) (identity %)))
      (#(do (println %) (identity %)))
      (editor-handler/save-block! repo (:block/uuid block)))))
      (editor-handler/save-block! repo (:block/uuid block)))))
 
 
+
+;;; used by other ns
+(defn card-block?
+  [block]
+  (let [type (keyword (get (:block/properties block) card-type-property))]
+    (and type (contains? card-type-set type))))
+
 ;;; ================================================================
 ;;; ================================================================
 ;;; sr algorithm (sm-5)
 ;;; sr algorithm (sm-5)
 ;;; https://www.supermemo.com/zh/archives1990-2015/english/ol/sm5
 ;;; https://www.supermemo.com/zh/archives1990-2015/english/ol/sm5
@@ -184,6 +195,12 @@
   (show-phase-2-config [this] {}))
   (show-phase-2-config [this] {}))
 
 
 
 
+(defn- ->card [block]
+  (case (get-block-card-type block)
+    :cloze (->ClozeCard block)
+    :sided (->SidedCard block)
+    :else (->SidedCard block)))
+
 ;;; ================================================================
 ;;; ================================================================
 ;;;
 ;;;
 
 
@@ -276,6 +293,25 @@
 ;;; ================================================================
 ;;; ================================================================
 ;;; UI
 ;;; UI
 
 
+(defn- score-help-info [days-3 days-4 days-5]
+  (ui/tippy {:html [:div
+                    [:p.text-sm "0-2: you have forgotten this card."]
+                    [:p.text-sm "3-5: you remember this card."]
+                    [:p.text-sm "0: completely forgot."]
+                    [:p.text-sm "1: it still takes a while to recall even after seeing the answer."]
+                    [:p.text-sm "2: immediately recall after seeing the answer."]
+                    [:p.text-sm
+                     (util/format "3: it takes a while to recall. (will reappear after %d days)" days-3)]
+                    [:p.text-sm
+                     (util/format "4: you recall this after a little thought. (will reappear after %d days)"
+                                  days-4)]
+                    [:p.text-sm
+                     (util/format "5: you remember it easily. (will reappear after %d days)" days-5)]]
+             :class "tippy-hover mr-2"
+             :interactive true
+             :disabled false}
+            (svg/info)))
+
 (rum/defcs view
 (rum/defcs view
   < rum/reactive
   < rum/reactive
   (rum/local 1 ::phase)
   (rum/local 1 ::phase)
@@ -292,9 +328,11 @@
                                  (operation-score! card score)
                                  (operation-score! card score)
                                  (if (>= (inc @card-index) (count cards))
                                  (if (>= (inc @card-index) (count cards))
                                    (state/close-modal!)
                                    (state/close-modal!)
-                                   (swap! card-index inc)))]
+                                   (do
+                                     (swap! card-index inc)
+                                     (reset! phase 1))))]
     [:div
     [:div
-     [:div.w-144.h-96.resize
+     [:div.w-144.h-96.resize.overflow-y-auto
       (component-block/blocks-container
       (component-block/blocks-container
        blocks
        blocks
        (merge
        (merge
@@ -306,32 +344,50 @@
            (concat
            (concat
             [:div.flex.items-start
             [:div.flex.items-start
              (ui/button (if (= 1 @phase) "Show Answers" "Hide Answers")
              (ui/button (if (= 1 @phase) "Show Answers" "Hide Answers")
-                        :class "w-32"
+                        :class "w-32 mr-8"
                         :on-click #(swap! phase (fn [o] (if (= 1 o) 2 1))))]
                         :on-click #(swap! phase (fn [o] (if (= 1 o) 2 1))))]
             (when (and (not read-only) (= 2 @phase))
             (when (and (not read-only) (= 2 @phase))
               (let [interval-days-score-3 (get (get-next-interval card 3) card-last-interval-property)
               (let [interval-days-score-3 (get (get-next-interval card 3) card-last-interval-property)
                     interval-days-score-4 (get (get-next-interval card 4) card-last-interval-property)
                     interval-days-score-4 (get (get-next-interval card 4) card-last-interval-property)
                     interval-days-score-5 (get (get-next-interval card 5) card-last-interval-property)]
                     interval-days-score-5 (get (get-next-interval card 5) card-last-interval-property)]
-                [(ui/button "0" :on-click #(score-and-next-card-fn 0))
-                 (ui/button "1" :on-click #(score-and-next-card-fn 1))
-                 (ui/button "2" :on-click #(score-and-next-card-fn 2))
-                 (ui/button (util/format "3 (+%ddays)" (Math/round interval-days-score-3))
-                            :on-click #(score-and-next-card-fn 3))
-                 (ui/button (util/format "4 (+%ddays)" (Math/round interval-days-score-4))
-                            :on-click #(score-and-next-card-fn 4))
-                 (ui/button (util/format "5 (+%ddays)" (Math/round interval-days-score-5))
-                            :on-click #(score-and-next-card-fn 5))]))))]))
+                [(ui/button "0" :on-click #(score-and-next-card-fn 0) :class "mr-2")
+                 (ui/button "1" :on-click #(score-and-next-card-fn 1) :class "mr-2")
+                 (ui/button "2" :on-click #(score-and-next-card-fn 2) :class "mr-2")
+                 (ui/button "3" :on-click #(score-and-next-card-fn 3) :class "mr-2")
+                 (ui/button "4" :on-click #(score-and-next-card-fn 4) :class "mr-2")
+                 (ui/button "5" :on-click #(score-and-next-card-fn 5) :class "mr-2")
+                 (score-help-info
+                  (Math/round interval-days-score-3)
+                  (Math/round interval-days-score-4)
+                  (Math/round interval-days-score-5))
+                 (ui/button "skip" :on-click #(if (>= (inc @card-index) (count cards))
+                                                (state/close-modal!)
+                                                (do
+                                                  (swap! card-index inc)
+                                                  (reset! phase 1))))]))))]))
 
 
 (defn preview
 (defn preview
-  [card]
-  (state/set-modal! #(view [card] {}))
-  '())
+  [blocks]
+  (def aaa blocks)
+  (state/set-modal! #(view (mapv ->card blocks) {:read-only true})))
+
 
 
 ;;; register cloze macro
 ;;; register cloze macro
 (defn cloze-macro-show
 (defn cloze-macro-show
   [config options]
   [config options]
   (if (:cloze config)
   (if (:cloze config)
     [:span.text-blue-600 "[...]"]
     [:span.text-blue-600 "[...]"]
-    (string/join ", " (:arguments options))))
+    [:span
+     [:span.text-blue-600 "["]
+     (string/join ", " (:arguments options))
+     [:span.text-blue-600 "]"]]))
 
 
 (component-macro/register cloze-macro-name cloze-macro-show)
 (component-macro/register cloze-macro-name cloze-macro-show)
+
+;;; register builtin properties
+
+(property/register-built-in-properties #{card-last-interval-property
+                                         card-repeats-property
+                                         card-last-reviewed-property
+                                         card-next-schedule-property
+                                         card-last-easiness-factor})

+ 1 - 1
src/main/frontend/handler/editor.cljs

@@ -324,7 +324,7 @@
         block (update block :block/refs remove-non-existed-refs!)
         block (update block :block/refs remove-non-existed-refs!)
         block (attach-page-properties-if-exists! block)
         block (attach-page-properties-if-exists! block)
         new-properties (merge
         new-properties (merge
-                        (select-keys properties property/built-in-properties)
+                        (select-keys properties (property/built-in-properties))
                         (:block/properties block))]
                         (:block/properties block))]
     (-> block
     (-> block
         (dissoc :block/top?
         (dissoc :block/top?

+ 14 - 6
src/main/frontend/util/property.cljs

@@ -12,16 +12,23 @@
 (defonce properties-end-pattern
 (defonce properties-end-pattern
   (re-pattern (util/format "%s[\t\r ]*\n|(%s\\s*$)" properties-end properties-end)))
   (re-pattern (util/format "%s[\t\r ]*\n|(%s\\s*$)" properties-end properties-end)))
 
 
-(def built-in-properties
+(def built-in-extended-properties (atom #{}))
+(defn register-built-in-properties
+  [props]
+  (reset! built-in-extended-properties (set/union @built-in-extended-properties props)))
+
+(defn built-in-properties
+  []
   (set/union
   (set/union
    #{:id :custom-id :background-color :heading :collapsed :created-at :updated-at :last-modified-at :created_at :last_modified_at :query-table :query-properties}
    #{:id :custom-id :background-color :heading :collapsed :created-at :updated-at :last-modified-at :created_at :last_modified_at :query-table :query-properties}
-   (set (map keyword config/markers))))
+   (set (map keyword config/markers))
+   @built-in-extended-properties))
 
 
 (defn properties-built-in?
 (defn properties-built-in?
   [properties]
   [properties]
   (and (seq properties)
   (and (seq properties)
        (let [ks (map (comp keyword string/lower-case name) (keys properties))]
        (let [ks (map (comp keyword string/lower-case name) (keys properties))]
-         (every? built-in-properties ks))))
+         (every? (built-in-properties) ks))))
 
 
 (defn contains-properties?
 (defn contains-properties?
   [content]
   [content]
@@ -102,7 +109,7 @@
 (defn with-built-in-properties
 (defn with-built-in-properties
   [properties content format]
   [properties content format]
   (let [org? (= format :org)
   (let [org? (= format :org)
-        properties (filter (fn [[k v]] (built-in-properties k)) properties)]
+        properties (filter (fn [[k v]] ((built-in-properties) k)) properties)]
     (if (seq properties)
     (if (seq properties)
       (let [[title & body] (string/split-lines content)
       (let [[title & body] (string/split-lines content)
             properties-in-content? (and title (= (string/upper-case title) properties-start))
             properties-in-content? (and title (= (string/upper-case title) properties-start))
@@ -265,8 +272,9 @@
 
 
 (defn remove-built-in-properties
 (defn remove-built-in-properties
   [format content]
   [format content]
-  (let [content (reduce (fn [content key]
-                          (remove-property format key content)) content built-in-properties)]
+  (let [built-in-properties* (built-in-properties)
+        content (reduce (fn [content key]
+                          (remove-property format key content)) content built-in-properties*)]
     (if (= format :org)
     (if (= format :org)
       (string/replace-first content ":PROPERTIES:\n:END:" "")
       (string/replace-first content ":PROPERTIES:\n:END:" "")
       content)))
       content)))