Browse Source

enhance(capacitor): WIP blocks content and editor

charlie 5 months ago
parent
commit
0f5dc8613c

+ 1 - 0
android/app/src/main/java/com/logseq/app/UILocal.kt

@@ -55,6 +55,7 @@ class UILocal : Plugin() {
       val selectedDate = Calendar.getInstance().apply {
         set(selectedYear, selectedMonth, selectedDay)
       }
+
       val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
       val formattedDate = sdf.format(selectedDate.time)
 

+ 9 - 8
src/main/capacitor/app.cljs

@@ -11,8 +11,8 @@
             [capacitor.ionic :as ionic]
             [capacitor.state :as state]
             [capacitor.handler :as handler]
-            [capacitor.pages.utils :as pages-util]
-            [capacitor.pages.blocks :as blocks]
+            [capacitor.components.utils :as cc-utils]
+            [capacitor.components.blocks :as cc-blocks]
             [capacitor.components.ui :as ui]
             [frontend.db.conn :as db-conn]
             [frontend.db-mixins :as db-mixins]
@@ -23,7 +23,7 @@
             [frontend.mobile.util :as mobile-util]
             [goog.date :as gdate]
             [logseq.db :as ldb]
-            [capacitor.pages.settings :as settings]))
+            [capacitor.components.settings :as settings]))
 
 (rum/defc app-graphs-select
   []
@@ -87,11 +87,12 @@
     [:ul.app-journals-list
      (for [journal-id journals]
        (let [journal (db-util/entity journal-id)]
-         [:li.flex.py-1.active:opacity-50.flex-col.w-full
-          {:on-click #(pages-util/nav-to-block! journal {:reload-pages! (fn [] ())})}
-          [:h1.font-semibold.opacity-90 (:block/title journal)]
+         [:li.flex.py-1.flex-col.w-full
+          [:h1.font-semibold.opacity-90.active:opacity-50
+           {:on-click #(cc-utils/nav-to-block! journal {:reload-pages! (fn [] ())})}
+           (:block/title journal)]
           ;; blocks editor
-          (blocks/page-blocks journal)
+          (cc-blocks/page-blocks journal)
           ]))]))
 
 (rum/defc home []
@@ -136,7 +137,7 @@
                 :on-click (fn []
                             (let [apply-date! (fn [date]
                                                 (let [page-name (frontend-date/journal-name (gdate/Date. (js/Date. date)))
-                                                      nav-to-journal! #(pages-util/nav-to-block! % {:reload-pages! (fn [] ())})]
+                                                      nav-to-journal! #(cc-utils/nav-to-block! % {:reload-pages! (fn [] ())})]
                                                   (if-let [journal (handler/local-page page-name)]
                                                     (nav-to-journal! journal)
                                                     (-> (handler/<create-page! page-name)

+ 33 - 6
src/main/capacitor/pages/blocks.cljs → src/main/capacitor/components/blocks.cljs

@@ -1,4 +1,4 @@
-(ns capacitor.pages.blocks
+(ns capacitor.components.blocks
   (:require [capacitor.state :as state]
             [frontend.db.model :as db-model]
             [promesa.core :as p]
@@ -8,6 +8,7 @@
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.page :as page-handler]
             [frontend.state :as fstate]
+            [capacitor.components.editor :as cc-editor]
             [capacitor.ionic :as ionic]))
 
 (rum/defc edit-block-modal
@@ -80,17 +81,43 @@
   (some-> @state/*nav-root
     (.push #(edit-block-modal block opts))))
 
+(defn get-dom-block-uuid
+  [^js el]
+  (some-> el
+    (.closest "[data-blockid]")
+    (.-dataset) (.-blockid)
+    (uuid)))
+
 (rum/defc block-editor
-  [])
+  [block]
+  (let [content (:block/title block)]
+    (cc-editor/editor-aux content
+      {:on-outside! (fn []
+                      (when (= block (:editing-block @state/*state))
+                        (state/set-state! :editing-block nil)))})))
 
 (rum/defc block-content
-  [])
+  [block]
+  (let [content (:block/title block)]
+    (cc-editor/content-aux content {})))
 
 (rum/defc block-item
   [block]
-  (when block
-    [:li.text-xl.pr-1 {:on-click #()}
-     [:span (:block/title block)]]))
+  (let [[editing-block set-editing-block!] (state/use-app-state :editing-block)]
+    (when block
+      (let [editing? (and editing-block
+                       (= (:block/uuid block) (:block/uuid editing-block)))]
+
+        [:li.text-xl.pr-1.active:opacity-50.block-item
+         {:on-click (fn []
+                      (when-not editing?
+                        (set-editing-block! block)))
+          :data-blockid (:block/uuid block)}
+         [:div.block-content-or-editor
+          {:class (if editing? "block" "inline")}
+          (if editing?
+            (block-editor block)
+            (block-content block))]]))))
 
 (rum/defc blocks-list
   [blocks]

+ 44 - 0
src/main/capacitor/components/editor.cljs

@@ -0,0 +1,44 @@
+(ns capacitor.components.editor
+  (:require [rum.core :as rum]
+            [capacitor.ionic :as ionic]
+            [frontend.handler.notification :as notification]))
+
+(rum/defc editor-aux
+  [content {:keys [on-outside!]}]
+
+  (let [*input (rum/use-ref nil)]
+
+    (rum/use-effect!
+      (fn []
+        (let [timer (js/requestAnimationFrame
+                      (fn []
+                        (when-let [^js input (some-> (rum/deref *input)
+                                               (.querySelector "textarea"))]
+                          (.focus input)
+                          (let [len (.-length (.-value input))]
+                            (.setSelectionRange input len len))
+                          ;(.scrollIntoView input #js {:behavior "smooth", :block "start"})
+                          )))]
+          #(js/clearTimeout timer)))
+      [])
+
+    (rum/use-effect!
+      (fn []
+        (let [handle-outside! (fn [^js e]
+                                (when-not (some-> e (.-target) (.closest ".editor-aux-input"))
+                                  (on-outside! e)))]
+          (js/window.addEventListener "mousedown" handle-outside!)
+          #(js/window.removeEventListener "mousedown" handle-outside!)))
+      [])
+
+    (ionic/ion-textarea
+      {:class "editor-aux-input bg-gray-100 border"
+       :ref *input
+       :auto-grow true
+       :autofocus true
+       :value content})))
+
+(rum/defc content-aux
+  [content & opts]
+
+  [:p content])

+ 3 - 3
src/main/capacitor/pages/settings.cljs → src/main/capacitor/components/settings.cljs

@@ -1,6 +1,6 @@
-(ns capacitor.pages.settings
+(ns capacitor.components.settings
   (:require [capacitor.handler :as handler]
-            [capacitor.pages.utils :as pages-util]
+            [capacitor.components.utils :as cc-util]
             [promesa.core :as p]
             [rum.core :as rum]
             [capacitor.state :as state]
@@ -74,7 +74,7 @@
        (for [page filtered-pages]
          (let [ident (some-> (:block/tags page) first :db/ident)]
            [:li.font-mono.flex.items-center.py-1.active:opacity-50.active:underline.whitespace-nowrap
-            {:on-click #(pages-util/nav-to-block! page {:reload-pages! (fn [] (set-reload! (inc reload)))})}
+            {:on-click #(cc-util/nav-to-block! page {:reload-pages! (fn [] (set-reload! (inc reload)))})}
             (case ident
               :logseq.class/Property (ionic/tabler-icon "letter-t")
               :logseq.class/Page (ionic/tabler-icon "file")

+ 4 - 5
src/main/capacitor/pages/utils.cljs → src/main/capacitor/components/utils.cljs

@@ -1,7 +1,6 @@
-(ns capacitor.pages.utils
+(ns capacitor.components.utils
   (:require [capacitor.state :as state]
-            [capacitor.pages.blocks :as page-blocks]
-            [capacitor.components.ui :as ui]
+            [capacitor.components.blocks :as cc-blocks]
             [cljs-bean.core :as bean]))
 
 ;; https://ionicframework.com/docs/api/nav#push
@@ -16,9 +15,9 @@
 (defn nav-to-block!
   [page-or-block opts]
   (some-> @state/*nav-root
-    (.push #(page-blocks/page page-or-block opts))))
+    (.push #(cc-blocks/page page-or-block opts))))
 
 (defn nav-to-edit-block!
   [block opts]
   (some-> @state/*nav-root
-    (.push #(page-blocks/edit-block-modal block opts))))
+    (.push #(cc-blocks/edit-block-modal block opts))))

+ 2 - 1
src/main/capacitor/hooks.cljs

@@ -1 +1,2 @@
-(ns capacitor.hooks)
+(ns capacitor.hooks
+  (:require [rum.core :as rum]))

+ 35 - 2
src/main/capacitor/state.cljs

@@ -1,14 +1,47 @@
 (ns capacitor.state
-  (:require [frontend.rum :as r]))
+  (:require [frontend.rum :as r]
+            [frontend.util :as util]))
 
 (defonce *nav-root (atom nil))
 (defonce *state
   (atom {:version 0
-         :last-modified-page-uuid nil}))
+         :last-modified-page-uuid nil
+         :editing-block nil
+         }))
 
 (defn use-nav-root [] (r/use-atom *nav-root))
 (defn use-app-state
   ([] (r/use-atom *state))
   ([ks] (r/use-atom-in *state ks)))
 
+(defn set-state!
+  [path value & {:keys [path-in-sub-atom]}]
+  (let [path-coll? (coll? path)
+        get-fn (if path-coll? get-in get)
+        s (get-fn @*state path)
+        s-atom? (util/atom? s)
+        path-coll?-in-sub-atom (coll? path-in-sub-atom)]
+    (cond
+      (and s-atom? path-in-sub-atom path-coll?-in-sub-atom)
+      (let [old-v (get-in @s path-in-sub-atom)]
+        (when (not= old-v value)
+          (swap! s assoc-in path-in-sub-atom value)))
+
+      (and s-atom? path-in-sub-atom)
+      (let [old-v (get @s path-in-sub-atom)]
+        (when (not= old-v value)
+          (swap! s assoc path-in-sub-atom value)))
+
+      s-atom?
+      (when (not= @s value)
+        (reset! s value))
+
+      path-coll?
+      (when (not= s value)
+        (swap! *state assoc-in path value))
+
+      :else
+      (when (not= s value)
+        (swap! *state assoc path value))))
+  nil)