瀏覽代碼

Merge branch 'master' into feat/pdf

Tienson Qin 4 年之前
父節點
當前提交
da90255ab8
共有 43 個文件被更改,包括 552 次插入305 次删除
  1. 0 2
      README.md
  2. 3 2
      package.json
  3. 1 1
      shadow-cljs.edn
  4. 7 3
      src/electron/electron/core.cljs
  5. 4 1
      src/main/frontend/commands.cljs
  6. 103 46
      src/main/frontend/components/block.cljs
  7. 6 6
      src/main/frontend/components/content.cljs
  8. 48 20
      src/main/frontend/components/export.cljs
  9. 2 2
      src/main/frontend/components/header.cljs
  10. 1 1
      src/main/frontend/components/page.cljs
  11. 25 13
      src/main/frontend/components/query_table.cljs
  12. 11 5
      src/main/frontend/components/repo.cljs
  13. 4 1
      src/main/frontend/components/right_sidebar.cljs
  14. 16 8
      src/main/frontend/components/search.cljs
  15. 9 9
      src/main/frontend/components/settings.cljs
  16. 3 2
      src/main/frontend/components/widgets.cljs
  17. 14 12
      src/main/frontend/date.cljs
  18. 1 1
      src/main/frontend/db.cljs
  19. 19 0
      src/main/frontend/db/debug.cljs
  20. 22 26
      src/main/frontend/db/model.cljs
  21. 0 1
      src/main/frontend/db/query_react.cljs
  22. 2 3
      src/main/frontend/extensions/code.cljs
  23. 9 10
      src/main/frontend/extensions/zotero/extractor.cljs
  24. 14 2
      src/main/frontend/extensions/zotero/handler.cljs
  25. 2 2
      src/main/frontend/extensions/zotero/setting.cljs
  26. 10 5
      src/main/frontend/format/block.cljs
  27. 15 2
      src/main/frontend/format/mldoc.cljs
  28. 1 1
      src/main/frontend/handler.cljs
  29. 14 3
      src/main/frontend/handler/editor.cljs
  30. 7 0
      src/main/frontend/handler/events.cljs
  31. 2 2
      src/main/frontend/handler/export.cljs
  32. 20 11
      src/main/frontend/handler/extract.cljs
  33. 51 32
      src/main/frontend/handler/page.cljs
  34. 12 26
      src/main/frontend/handler/repo.cljs
  35. 1 1
      src/main/frontend/handler/web/nfs.cljs
  36. 20 18
      src/main/frontend/modules/outliner/core.cljs
  37. 4 1
      src/main/frontend/modules/shortcut/config.cljs
  38. 10 0
      src/main/frontend/state.cljs
  39. 25 9
      src/main/frontend/ui.cljs
  40. 4 0
      src/main/frontend/util.cljc
  41. 7 3
      src/main/frontend/util/property.cljs
  42. 10 2
      src/test/frontend/util/property_test.cljs
  43. 13 10
      yarn.lock

+ 0 - 2
README.md

@@ -22,8 +22,6 @@ Use it to organize your todo list, to write your journals, or to record your uni
 
 
 [Logseq](https://logseq.com) is a platform for knowledge management and collaboration. It focuses on privacy, longevity, and [user control](https://www.gnu.org/philosophy/free-sw.en.html).
 [Logseq](https://logseq.com) is a platform for knowledge management and collaboration. It focuses on privacy, longevity, and [user control](https://www.gnu.org/philosophy/free-sw.en.html).
 
 
-Notice: the backend code will be open-sourced as soon as we’re sure that the backend service meets the security standards.
-
 The server will never store or analyze your private notes. Your data are plain text files and we currently support both Markdown and Emacs Org mode (more to be added soon).
 The server will never store or analyze your private notes. Your data are plain text files and we currently support both Markdown and Emacs Org mode (more to be added soon).
 
 
 In the unlikely event that the website is down or cannot be maintained, your data is, and will always be yours.
 In the unlikely event that the website is down or cannot be maintained, your data is, and will always be yours.

+ 3 - 2
package.json

@@ -82,9 +82,9 @@
         "ignore": "^5.1.8",
         "ignore": "^5.1.8",
         "is-svg": "4.2.2",
         "is-svg": "4.2.2",
         "jszip": "^3.5.0",
         "jszip": "^3.5.0",
-        "mldoc": "0.9.2",
+        "mldoc": "0.9.4",
         "path": "^0.12.7",
         "path": "^0.12.7",
-        "pixi-graph-fork": "^0.1.3",
+        "pixi-graph-fork": "^0.1.4",
         "posthog-js": "^1.10.2",
         "posthog-js": "^1.10.2",
         "react": "^17.0.2",
         "react": "^17.0.2",
         "react-dom": "^17.0.2",
         "react-dom": "^17.0.2",
@@ -94,6 +94,7 @@
         "react-textarea-autosize": "^8.0.1",
         "react-textarea-autosize": "^8.0.1",
         "react-tippy": "^1.4.0",
         "react-tippy": "^1.4.0",
         "react-transition-group": "^4.3.0",
         "react-transition-group": "^4.3.0",
+        "react-tweet-embed": "^1.2.2",
         "reakit": "^0.11.1",
         "reakit": "^0.11.1",
         "yargs-parser": "^20.2.4"
         "yargs-parser": "^20.2.4"
     }
     }

+ 1 - 1
shadow-cljs.edn

@@ -87,7 +87,7 @@
               :depends-on #{:main}}}
               :depends-on #{:main}}}
 
 
    :output-dir "./static/js/publishing"
    :output-dir "./static/js/publishing"
-   :asset-path "/static/js"
+   :asset-path "static/js"
 
 
    :closure-defines {frontend.config/PUBLISHING true
    :closure-defines {frontend.config/PUBLISHING true
                      goog.debug.LOGGING_ENABLED true}
                      goog.debug.LOGGING_ENABLED true}

+ 7 - 3
src/electron/electron/core.cljs

@@ -87,9 +87,13 @@
                             (. fs copy (path/join app-path "404.html") (path/join root-dir "404.html"))]
                             (. fs copy (path/join app-path "404.html") (path/join root-dir "404.html"))]
 
 
                            (map
                            (map
-                            (fn [filename] (. fs copy (path/join assets-from-dir filename) (path/join assets-to-dir filename)))
-
-                            asset-filenames)
+                             (fn [filename]
+                               (-> (. fs copy (path/join assets-from-dir filename) (path/join assets-to-dir filename))
+                                   (p/catch
+                                       (fn [e]
+                                         (println (str "Failed to copy " (path/join assets-from-dir filename) " to " (path/join assets-to-dir filename)))
+                                         (js/console.error e)))))
+                             asset-filenames)
 
 
                            (map
                            (map
                             (fn [part]
                             (fn [part]

+ 4 - 1
src/main/frontend/commands.cljs

@@ -273,7 +273,10 @@
                                                             :backward-pos 2}]]]
                                                             :backward-pos 2}]]]
 
 
      ["Embed Vimeo Video" [[:editor/input "{{vimeo }}" {:last-pattern slash
      ["Embed Vimeo Video" [[:editor/input "{{vimeo }}" {:last-pattern slash
-                                                        :backward-pos 2}]]]]
+                                                        :backward-pos 2}]]]
+
+     ["Embed Twitter" [[:editor/input "{{tweet }}" {:last-pattern slash
+                                                    :backward-pos 2}]]]]
 
 
     @*extend-slash-commands
     @*extend-slash-commands
     ;; Allow user to modify or extend, should specify how to extend.
     ;; Allow user to modify or extend, should specify how to extend.

+ 103 - 46
src/main/frontend/components/block.cljs

@@ -339,28 +339,27 @@
     [:a
     [:a
      {:class (if tag? "tag" "page-ref")
      {:class (if tag? "tag" "page-ref")
       :data-ref page-name
       :data-ref page-name
-      :href href
-      :on-click (fn [e]
-                  (util/stop e)
-                  (let [create-first-block! (fn []
-                                              (when-not (editor-handler/add-default-title-property-if-needed! redirect-page-name)
-                                                (editor-handler/insert-first-page-block-if-not-exists! redirect-page-name)))]
-                    (if (gobj/get e "shiftKey")
-                      (do
-                        (js/setTimeout create-first-block! 310)
-                        (when-let [page-entity (db/entity [:block/name redirect-page-name])]
-                          (state/sidebar-add-block!
-                           (state/get-current-repo)
-                           (:db/id page-entity)
-                           :page
-                           {:page page-entity})))
-                      (do
-                        (create-first-block!)
-                        (route-handler/redirect! {:to :page
-                                                  :path-params {:name redirect-page-name}}))))
-                  (when (and contents-page?
-                             (state/get-left-sidebar-open?))
-                    (ui-handler/close-left-sidebar!)))}
+      :on-mouse-down
+      (fn [e]
+        (util/stop e)
+        (let [create-first-block! (fn []
+                                    (when-not (editor-handler/add-default-title-property-if-needed! redirect-page-name)
+                                      (editor-handler/insert-first-page-block-if-not-exists! redirect-page-name)))]
+          (if (gobj/get e "shiftKey")
+            (do
+              (js/setTimeout create-first-block! 310)
+              (when-let [page-entity (db/entity [:block/name redirect-page-name])]
+                (state/sidebar-add-block!
+                 (state/get-current-repo)
+                 (:db/id page-entity)
+                 :page
+                 {:page page-entity})))
+            (do
+              (create-first-block!)
+              (route-handler/redirect! {:to :page
+                                        :path-params {:name redirect-page-name}}))))
+        (when (and contents-page? (state/get-left-sidebar-open?))
+          (ui-handler/close-left-sidebar!)))}
 
 
      (if (and (coll? children) (seq children))
      (if (and (coll? children) (seq children))
        (for [child children]
        (for [child children]
@@ -1095,6 +1094,16 @@
                     :width width
                     :width width
                     :height (max 500 height)}])))))
                     :height (max 500 height)}])))))
 
 
+
+        (contains? #{"tweet" "twitter"} name)
+        (when-let [url (first arguments)]
+          (let [id-regex #"/status/(\d+)"]
+            (when-let [id (cond
+                            (<= (count url) 15) url
+                            :else
+                            (last (util/safe-re-find id-regex url)))]
+              (ui/tweet-embed id))))
+
         (= name "embed")
         (= name "embed")
         (let [a (first arguments)]
         (let [a (first arguments)]
           (cond
           (cond
@@ -1435,7 +1444,7 @@
 (declare block-content)
 (declare block-content)
 
 
 (defn build-block-title
 (defn build-block-title
-  [{:keys [slide?] :as config} {:block/keys [uuid title tags marker priority anchor meta format content pre-block? block-refs-count page properties unordered level heading-level]
+  [{:keys [slide?] :as config} {:block/keys [uuid title tags marker priority anchor meta format content pre-block? page properties unordered level heading-level]
                                 :as t}]
                                 :as t}]
   (let [config (assoc config :block t)
   (let [config (assoc config :block t)
         slide? (boolean (:slide? config))
         slide? (boolean (:slide? config))
@@ -1722,7 +1731,7 @@
                   (str uuid "-" idx)))))])]]]))
                   (str uuid "-" idx)))))])]]]))
 
 
 (rum/defc block-content-or-editor < rum/reactive
 (rum/defc block-content-or-editor < rum/reactive
-  [config {:block/keys [uuid title body meta content page format repo children marker properties block-refs-count pre-block? idx] :as block} edit-input-id block-id slide? heading-level]
+  [config {:block/keys [uuid title body meta content page format repo children marker properties pre-block? idx] :as block} edit-input-id block-id slide? heading-level]
   (let [editor-box (get config :editor-box)
   (let [editor-box (get config :editor-box)
         edit? (state/sub [:editor/editing? edit-input-id])
         edit? (state/sub [:editor/editing? edit-input-id])
         editor-id (str "editor-" edit-input-id)
         editor-id (str "editor-" edit-input-id)
@@ -1768,18 +1777,19 @@
                [:a.opacity-30.hover:opacity-100
                [:a.opacity-30.hover:opacity-100
                 (utils/timeConversion (- finish-time start-time))]])))
                 (utils/timeConversion (- finish-time start-time))]])))
 
 
-        (when (and block-refs-count (> block-refs-count 0))
-          [:div
-           [:a.open-block-ref-link.bg-base-2.text-sm.ml-2
-            {:title "Open block references"
-             :style {:margin-top -1}
-             :on-click (fn []
-                         (state/sidebar-add-block!
-                          (state/get-current-repo)
-                          (:db/id block)
-                          :block-ref
-                          {:block block}))}
-            block-refs-count]])]])))
+        (let [block-refs-count (count (:block/_refs (db/entity (:db/id block))))]
+          (when (and block-refs-count (> block-refs-count 0))
+           [:div
+            [:a.open-block-ref-link.bg-base-2.text-sm.ml-2
+             {:title "Open block references"
+              :style {:margin-top -1}
+              :on-click (fn []
+                          (state/sidebar-add-block!
+                           (state/get-current-repo)
+                           (:db/id block)
+                           :block-ref
+                           {:block block}))}
+             block-refs-count]]))]])))
 
 
 (defn non-dragging?
 (defn non-dragging?
   [e]
   [e]
@@ -1789,8 +1799,24 @@
        (not @*dragging?)))
        (not @*dragging?)))
 
 
 (rum/defc breadcrumb-fragment
 (rum/defc breadcrumb-fragment
-  [href label]
-  [:a {:href href} label])
+  [config block href label]
+  (if (= block :page)                   ; page
+    (when label
+      (let [page (db/entity [:block/name (string/lower-case label)])]
+       (page-cp config page)))
+    [:a {:on-mouse-down
+         (fn [e]
+           (if (gobj/get e "shiftKey")
+             (do
+               (util/stop e)
+               (state/sidebar-add-block!
+                (state/get-current-repo)
+                (:db/id block)
+                :block-ref
+                {:block block}))
+             (route-handler/redirect! {:to :page
+                                       :path-params {:name (str (:block/uuid block))}})))}
+     label]))
 
 
 (rum/defc breadcrumb-separator [] [:span.mx-2.opacity-50 "➤"])
 (rum/defc breadcrumb-separator [] [:span.mx-2.opacity-50 "➤"])
 
 
@@ -1805,17 +1831,19 @@
          show? (or (seq parents) show-page? page-name)]
          show? (or (seq parents) show-page? page-name)]
      (when show?
      (when show?
        (let [page-name-props (when show-page?
        (let [page-name-props (when show-page?
-                               [(rfe/href :page {:name page-name})
+                               [:page
+                                (rfe/href :page {:name page-name})
                                 (or page-original-name page-name)])
                                 (or page-original-name page-name)])
              parents-props (doall
              parents-props (doall
-                            (for [{:block/keys [uuid title name]} parents]
+                            (for [{:block/keys [uuid title name] :as block} parents]
                               (when-not name ; not page
                               (when-not name ; not page
-                                [(rfe/href :page {:name uuid})
+                                [block
+                                 (rfe/href :page {:name uuid})
                                  (->elem :span (map-inline config title))])))
                                  (->elem :span (map-inline config title))])))
              breadcrumb (->> (into [] parents-props)
              breadcrumb (->> (into [] parents-props)
                              (concat [page-name-props])
                              (concat [page-name-props])
                              (filterv identity)
                              (filterv identity)
-                             (map (fn [[href label]] (breadcrumb-fragment href label)))
+                             (map (fn [[block href label]] (breadcrumb-fragment config block href label)))
                              (interpose (breadcrumb-separator)))]
                              (interpose (breadcrumb-separator)))]
          [:div.block-parents.flex-row.flex-1 breadcrumb])))))
          [:div.block-parents.flex-row.flex-1 breadcrumb])))))
 
 
@@ -1983,7 +2011,7 @@
 
 
      (when (and ref? breadcrumb-show?)
      (when (and ref? breadcrumb-show?)
        (when-let [comp (block-parents config repo uuid format false)]
        (when-let [comp (block-parents config repo uuid format false)]
-         [:div.my-2.opacity-50.ml-4 comp]))
+         [:div.my-2.opacity-70.ml-4.hover:opacity-100 comp]))
 
 
      ;; only render this for the first block in each container
      ;; only render this for the first block in each container
      (when top?
      (when top?
@@ -2180,7 +2208,7 @@
                      (state/remove-custom-query-component! query)
                      (state/remove-custom-query-component! query)
                      (db/remove-custom-query! (state/get-current-repo) query))
                      (db/remove-custom-query! (state/get-current-repo) query))
                    state)}
                    state)}
-  [state config {:keys [title query inputs view collapsed? children?] :as q}]
+  [state config {:keys [title query inputs view collapsed? children? breadcrumb-show?] :as q}]
   (ui/catch-error
   (ui/catch-error
    [:div.warning
    [:div.warning
     [:p "Query failed: "]
     [:p "Query failed: "]
@@ -2264,7 +2292,9 @@
               (and (seq result) (or only-blocks? blocks-grouped-by-page?))
               (and (seq result) (or only-blocks? blocks-grouped-by-page?))
               (->hiccup result (cond-> (assoc config
               (->hiccup result (cond-> (assoc config
                                               :custom-query? true
                                               :custom-query? true
-                                              :breadcrumb-show? true
+                                              :breadcrumb-show? (if (some? breadcrumb-show?)
+                                                                  breadcrumb-show?
+                                                                  true)
                                               :group-by-page? blocks-grouped-by-page?
                                               :group-by-page? blocks-grouped-by-page?
                                               :ref? true)
                                               :ref? true)
                                  children?
                                  children?
@@ -2599,7 +2629,32 @@
   [:div.content
   [:div.content
    (cond-> option
    (cond-> option
      (:document/mode? config) (assoc :class "doc-mode"))
      (:document/mode? config) (assoc :class "doc-mode"))
-   (if (and (:group-by-page? config)
+   (cond
+     (:custom-query? config)
+     [:div.flex.flex-col
+      (let [blocks (sort-by (comp :block/journal-day first) > blocks)]
+        (for [[page blocks] blocks]
+          (let [alias? (:block/alias? page)
+                page (db/entity (:db/id page))
+                parent-blocks (group-by :block/parent blocks)]
+            [:div.my-2 (cond-> {:key (str "page-" (:db/id page))}
+                         (:ref? config)
+                         (assoc :class "color-level px-7 py-2 rounded"))
+             (ui/foldable
+              [:div
+               (page-cp config page)
+               (when alias? [:span.text-sm.font-medium.opacity-50 " Alias"])]
+              (for [[parent blocks] parent-blocks]
+                (let [block (first blocks)]
+                  [:div
+                   (when (:breadcrumb-show? config)
+                     [:div.my-2.opacity-70.ml-4.hover:opacity-100
+                      (block-parents config (state/get-current-repo) (:block/uuid block)
+                                     (:block/format block)
+                                     false)])
+                   (blocks-container blocks (assoc config :breadcrumb-show? false))])))])))]
+
+     (and (:group-by-page? config)
             (vector? (first blocks)))
             (vector? (first blocks)))
      [:div.flex.flex-col
      [:div.flex.flex-col
       (let [blocks (sort-by (comp :block/journal-day first) > blocks)]
       (let [blocks (sort-by (comp :block/journal-day first) > blocks)]
@@ -2614,4 +2669,6 @@
                (page-cp config page)
                (page-cp config page)
                (when alias? [:span.text-sm.font-medium.opacity-50 " Alias"])]
                (when alias? [:span.text-sm.font-medium.opacity-50 " Alias"])]
               (blocks-container blocks config))])))]
               (blocks-container blocks config))])))]
+
+     :else
      (blocks-container blocks config))])
      (blocks-container blocks config))])

+ 6 - 6
src/main/frontend/components/content.cljs

@@ -176,10 +176,10 @@
           (block-template block-id)
           (block-template block-id)
 
 
           (ui/menu-link
           (ui/menu-link
-           {:key "Export"
+           {:key "Copy as"
             :on-click (fn [_]
             :on-click (fn [_]
                         (state/set-modal! #(export/export-blocks block-id)))}
                         (state/set-modal! #(export/export-blocks block-id)))}
-           "Export")
+           "Copy as")
 
 
           (if (srs/card-block? block)
           (if (srs/card-block? block)
             (ui/menu-link
             (ui/menu-link
@@ -246,25 +246,25 @@
                       (let [target (gobj/get e "target")
                       (let [target (gobj/get e "target")
                             block-id (d/attr target "blockid")]
                             block-id (d/attr target "blockid")]
                         (cond
                         (cond
-                          (and block-id (util/uuid-string? block-id))
+                          (state/selection?)
                           (do
                           (do
                             (util/stop e)
                             (util/stop e)
                             (let [client-x (gobj/get e "clientX")
                             (let [client-x (gobj/get e "clientX")
                                   client-y (gobj/get e "clientY")
                                   client-y (gobj/get e "clientY")
                                   scroll-y (util/cur-doc-top)]
                                   scroll-y (util/cur-doc-top)]
-                              (state/show-custom-context-menu! (block-context-menu-content target (cljs.core/uuid block-id)))
+                              (state/show-custom-context-menu! (custom-context-menu-content))
                               (when-let [context-menu (d/by-id "custom-context-menu")]
                               (when-let [context-menu (d/by-id "custom-context-menu")]
                                 (d/set-style! context-menu
                                 (d/set-style! context-menu
                                               :left (str client-x "px")
                                               :left (str client-x "px")
                                               :top (str (+ scroll-y client-y) "px")))))
                                               :top (str (+ scroll-y client-y) "px")))))
 
 
-                          (state/selection?)
+                          (and block-id (util/uuid-string? block-id))
                           (do
                           (do
                             (util/stop e)
                             (util/stop e)
                             (let [client-x (gobj/get e "clientX")
                             (let [client-x (gobj/get e "clientX")
                                   client-y (gobj/get e "clientY")
                                   client-y (gobj/get e "clientY")
                                   scroll-y (util/cur-doc-top)]
                                   scroll-y (util/cur-doc-top)]
-                              (state/show-custom-context-menu! (custom-context-menu-content))
+                              (state/show-custom-context-menu! (block-context-menu-content target (cljs.core/uuid block-id)))
                               (when-let [context-menu (d/by-id "custom-context-menu")]
                               (when-let [context-menu (d/by-id "custom-context-menu")]
                                 (d/set-style! context-menu
                                 (d/set-style! context-menu
                                               :left (str client-x "px")
                                               :left (str client-x "px")

+ 48 - 20
src/main/frontend/components/export.cljs

@@ -70,22 +70,21 @@
                                 {:label "no-indent"
                                 {:label "no-indent"
                                  :selected false}])
                                  :selected false}])
 
 
-(def *export-block-text-indent-style (atom "dashes"))
-
 (rum/defcs export-blocks
 (rum/defcs export-blocks
   < rum/reactive
   < rum/reactive
   (rum/local false ::copied?)
   (rum/local false ::copied?)
   [state root-block-id]
   [state root-block-id]
   (let [current-repo (state/get-current-repo)
   (let [current-repo (state/get-current-repo)
         type (rum/react *export-block-type)
         type (rum/react *export-block-type)
-        text-indent-style (rum/react *export-block-text-indent-style)
+        text-indent-style (rum/react (state/get-export-block-text-indent-style))
+        text-remove-options (rum/react (state/get-export-block-text-remove-options))
         copied? (::copied? state)
         copied? (::copied? state)
         content
         content
         (case type
         (case type
-          :text (export/export-blocks-as-markdown current-repo root-block-id text-indent-style)
+          :text (export/export-blocks-as-markdown current-repo root-block-id text-indent-style (into [] text-remove-options))
           :opml (export/export-blocks-as-opml current-repo root-block-id)
           :opml (export/export-blocks-as-opml current-repo root-block-id)
           :html (export/export-blocks-as-html current-repo root-block-id)
           :html (export/export-blocks-as-html current-repo root-block-id)
-          (export/export-blocks-as-markdown current-repo root-block-id text-indent-style))]
+          (export/export-blocks-as-markdown current-repo root-block-id text-indent-style (into [] text-remove-options)))]
     [:div.export.w-96.resize
     [:div.export.w-96.resize
      [:div
      [:div
       {:class "mb-2"}
       {:class "mb-2"}
@@ -104,21 +103,50 @@
                                 (if (= text-indent-style (:label opt))
                                 (if (= text-indent-style (:label opt))
                                   (assoc opt :selected true)
                                   (assoc opt :selected true)
                                   opt))))]
                                   opt))))]
-       [:div.flex.items-center
-        [:label.mr-8 "Indentation style:"]
-        [:select.block.my-2.text-lg.rounded.border
-         {:style     {:padding "0 0 0 12px"
-                      :visibility (if (= :text type) "visible" "hidden")}
-          :on-change (fn [e]
-                       (let [value (util/evalue e)]
-                         (#(reset! *export-block-text-indent-style %) value)))}
-         (for [{:keys [label value selected]} options]
-           [:option (cond->
-                     {:key   label
-                      :value (or value label)}
-                      selected
-                      (assoc :selected selected))
-            label])]])
+       [:div [:div.flex.items-center
+              [:label.mr-8
+               {:style {:visibility (if (= :text type) "visible" "hidden")}}
+               "Indentation style:"]
+              [:select.block.my-2.text-lg.rounded.border
+               {:style     {:padding "0 0 0 12px"
+                            :visibility (if (= :text type) "visible" "hidden")}
+                :on-change (fn [e]
+                             (let [value (util/evalue e)]
+                               (reset! (state/get-export-block-text-indent-style) value)))}
+               (for [{:keys [label value selected]} options]
+                 [:option (cond->
+                           {:key   label
+                            :value (or value label)}
+                            selected
+                            (assoc :selected selected))
+                  label])]]
+        [:div.flex.items-center
+         (ui/checkbox {:style {:margin-right 6
+                               :visibility (if (= :text type) "visible" "hidden")}
+                       :checked (contains? text-remove-options :page-ref)
+                       :on-change (fn [e] (if (util/echecked? e)
+                                            (swap! (state/get-export-block-text-remove-options)
+                                                   #(conj % :page-ref))
+                                            (swap! (state/get-export-block-text-remove-options)
+                                                   #(disj % :page-ref))))})
+
+         [:div
+          {:style {:visibility (if (= :text type) "visible" "hidden")}}
+          "[[text]] -> text"]
+         (ui/checkbox {:style {:margin-right 6
+                               :margin-left 10
+                               :visibility (if (= :text type) "visible" "hidden")}
+                       :checked (contains? text-remove-options :emphasis)
+                       :on-change (fn [e] (if (util/echecked? e)
+                                            (swap! (state/get-export-block-text-remove-options)
+                                                   #(conj % :emphasis))
+                                            (swap! (state/get-export-block-text-remove-options)
+                                                   #(disj % :emphasis))))})
+
+         [:div
+          {:style {:visibility (if (= :text type) "visible" "hidden")}}
+          "remove emphasis"]]])
+
      (ui/button (if @copied? "Copied to clipboard!" "Copy to clipboard")
      (ui/button (if @copied? "Copied to clipboard!" "Copy to clipboard")
                 :on-click (fn []
                 :on-click (fn []
                             (util/copy-to-clipboard! content)
                             (util/copy-to-clipboard! content)

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

@@ -18,6 +18,7 @@
             [frontend.components.export :as export]
             [frontend.components.export :as export]
             [frontend.components.plugins :as plugins]
             [frontend.components.plugins :as plugins]
             [frontend.components.right-sidebar :as sidebar]
             [frontend.components.right-sidebar :as sidebar]
+            [frontend.modules.shortcut.core :as shortcut]
             [frontend.handler.page :as page-handler]
             [frontend.handler.page :as page-handler]
             [frontend.handler.web.nfs :as nfs]
             [frontend.handler.web.nfs :as nfs]
             [frontend.mixins :as mixins]
             [frontend.mixins :as mixins]
@@ -212,8 +213,7 @@
        (when (and (nfs/supported?) (empty? repos)
        (when (and (nfs/supported?) (empty? repos)
                   (not config/publishing?))
                   (not config/publishing?))
          [:a.text-sm.font-medium.button
          [:a.text-sm.font-medium.button
-          {:on-click (fn []
-                       (page-handler/ls-dir-files!))}
+          {:on-click #(page-handler/ls-dir-files! shortcut/refresh!)}
           [:div.flex.flex-row.text-center.open-button__inner.items-center
           [:div.flex.flex-row.text-center.open-button__inner.items-center
            [:span.inline-block.open-button__icon-wrapper svg/folder-add]
            [:span.inline-block.open-button__icon-wrapper svg/folder-add]
            (when-not config/mobile?
            (when-not config/mobile?

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

@@ -407,7 +407,7 @@
                (let [config {:id "block-parent"
                (let [config {:id "block-parent"
                              :block? true}]
                              :block? true}]
                  [:div.mb-4
                  [:div.mb-4
-                  (block/block-parents config repo block-id format)]))
+                  (block/block-parents config repo block-id format true)]))
 
 
              ;; blocks
              ;; blocks
              (let [page (if block?
              (let [page (if block?

+ 25 - 13
src/main/frontend/components/query_table.cljs

@@ -8,23 +8,25 @@
             [frontend.state :as state]
             [frontend.state :as state]
             [clojure.string :as string]
             [clojure.string :as string]
             [frontend.components.svg :as svg]
             [frontend.components.svg :as svg]
-            [frontend.handler.common :as common-handler]))
+            [frontend.handler.common :as common-handler]
+            [frontend.handler.editor :as editor-handler]))
 
 
 ;; TODO: extract to table utils
 ;; TODO: extract to table utils
 (defn- sort-result-by
 (defn- sort-result-by
   [by-item desc? result]
   [by-item desc? result]
-  (def result result)
-  (def by-item by-item)
-  (def desc? desc?)
   (let [comp (if desc? > <)]
   (let [comp (if desc? > <)]
     (sort-by by-item comp result)))
     (sort-by by-item comp result)))
 
 
 (rum/defc sortable-title
 (rum/defc sortable-title
-  [title key by-item desc?]
+  [title key by-item desc? block-id]
   [:th.whitespace-nowrap
   [:th.whitespace-nowrap
    [:a {:on-click (fn []
    [:a {:on-click (fn []
                     (reset! by-item key)
                     (reset! by-item key)
-                    (swap! desc? not))}
+                    (swap! desc? not)
+                    (when block-id
+                      (when key
+                        (editor-handler/set-block-property! block-id :query-sort-by (name key)))
+                      (editor-handler/set-block-property! block-id :query-sort-desc @desc?)))}
     [:div.flex.items-center
     [:div.flex.items-center
      [:span.mr-1 title]
      [:span.mr-1 title]
      (when (= @by-item key)
      (when (= @by-item key)
@@ -37,18 +39,28 @@
                   (remove (property/built-in-properties))
                   (remove (property/built-in-properties))
                   (remove #{:template}))
                   (remove #{:template}))
         keys (if page? (cons :page keys) (cons :block keys))
         keys (if page? (cons :page keys) (cons :block keys))
-        keys (concat keys [:created-at :updated-at])]
+        keys (if page? (concat keys [:created-at :updated-at]) keys)]
     keys))
     keys))
 
 
 (rum/defcs result-table < rum/reactive
 (rum/defcs result-table < rum/reactive
-  (rum/local :updated-at ::sort-by-item)
-  (rum/local true ::desc?)
+  (rum/local nil ::sort-by-item)
+  (rum/local nil ::desc?)
   (rum/local false ::select?)
   (rum/local false ::select?)
   [state config current-block result {:keys [page?]} map-inline page-cp ->elem inline-text]
   [state config current-block result {:keys [page?]} map-inline page-cp ->elem inline-text]
   (when current-block
   (when current-block
-    (let [select? (get state ::select?)
+    (let [p-sort-by (keyword (get-in current-block [:block/properties :query-sort-by]))
+          p-desc? (get-in current-block [:block/properties :query-sort-desc])
+          select? (get state ::select?)
           *sort-by-item (get state ::sort-by-item)
           *sort-by-item (get state ::sort-by-item)
           *desc? (get state ::desc?)
           *desc? (get state ::desc?)
+          sort-by-item (or @*sort-by-item (some-> p-sort-by keyword) :updated-at)
+          desc? (cond
+                  (some? @*desc?)
+                  @*desc?
+                  (some? p-desc?)
+                  p-desc?
+                  :else
+                  true)
           editor-box (get config :editor-box)
           editor-box (get config :editor-box)
           ;; remove templates
           ;; remove templates
           result (remove (fn [b] (some? (get-in b [:block/properties :template]))) result)
           result (remove (fn [b] (some? (get-in b [:block/properties :template]))) result)
@@ -63,7 +75,7 @@
                   (filter #{:created-at :updated-at} keys))
                   (filter #{:created-at :updated-at} keys))
                  keys)
                  keys)
           sort-by-fn (fn [item]
           sort-by-fn (fn [item]
-                       (let [key @*sort-by-item]
+                       (let [key sort-by-item]
                          (case key
                          (case key
                            :created-at
                            :created-at
                            (:block/created-at item)
                            (:block/created-at item)
@@ -74,12 +86,12 @@
                            :page
                            :page
                            (:block/name item)
                            (:block/name item)
                            (get-in item [:block/properties key]))))
                            (get-in item [:block/properties key]))))
-          result (sort-result-by sort-by-fn @*desc? result)]
+          result (sort-result-by sort-by-fn desc? result)]
       [:div.overflow-x-auto {:on-mouse-down (fn [e] (.stopPropagation e))
       [:div.overflow-x-auto {:on-mouse-down (fn [e] (.stopPropagation e))
                              :style {:width "100%"}}
                              :style {:width "100%"}}
        [:table.table-auto
        [:table.table-auto
         (for [key keys]
         (for [key keys]
-          (sortable-title (name key) key *sort-by-item *desc?))
+          (sortable-title (name key) key *sort-by-item *desc? (:block/uuid current-block)))
         (for [item result]
         (for [item result]
           (let [format (:block/format item)
           (let [format (:block/format item)
                 edit-input-id (str "edit-block-" (:id config) "-" (:block/uuid item))
                 edit-input-id (str "edit-block-" (:id config) "-" (:block/uuid item))

+ 11 - 5
src/main/frontend/components/repo.cljs

@@ -6,6 +6,7 @@
             [frontend.db :as db]
             [frontend.db :as db]
             [frontend.encrypt :as e]
             [frontend.encrypt :as e]
             [frontend.handler.repo :as repo-handler]
             [frontend.handler.repo :as repo-handler]
+            [frontend.handler.page :as page-handler]
             [frontend.handler.common :as common-handler]
             [frontend.handler.common :as common-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.export :as export-handler]
             [frontend.handler.export :as export-handler]
@@ -21,7 +22,8 @@
             [frontend.components.encryption :as encryption]
             [frontend.components.encryption :as encryption]
             [frontend.context.i18n :as i18n]
             [frontend.context.i18n :as i18n]
             [clojure.string :as string]
             [clojure.string :as string]
-            [clojure.string :as str]))
+            [clojure.string :as str]
+            [frontend.modules.shortcut.core :as shortcut]))
 
 
 (rum/defc add-repo
 (rum/defc add-repo
   [args]
   [args]
@@ -52,7 +54,7 @@
              [:div.mr-8
              [:div.mr-8
               (ui/button
               (ui/button
                 (t :open-a-directory)
                 (t :open-a-directory)
-                :on-click page-handler/ls-dir-files!)])
+                :on-click #(page-handler/ls-dir-files! shortcut/refresh!))])
            (when (and (state/logged?) (not (util/electron?)))
            (when (and (state/logged?) (not (util/electron?)))
              (ui/button
              (ui/button
                "Add another git repo"
                "Add another git repo"
@@ -77,7 +79,9 @@
                                            "Sync with the local directory"
                                            "Sync with the local directory"
                                            "Clone again and re-index the db")
                                            "Clone again and re-index the db")
                                   :on-click (fn []
                                   :on-click (fn []
-                                              (repo-handler/re-index! nfs-handler/rebuild-index!))}
+                                              (repo-handler/re-index!
+                                               nfs-handler/rebuild-index!
+                                               page-handler/create-today-journal!))}
                  "Re-index"]
                  "Re-index"]
                 [:a.text-gray-400.ml-4 {:title "No worries, unlink this graph will clear its cache only, it does not remove your files on the disk."
                 [:a.text-gray-400.ml-4 {:title "No worries, unlink this graph will clear its cache only, it does not remove your files on the disk."
                                         :on-click (fn []
                                         :on-click (fn []
@@ -86,7 +90,7 @@
         (widgets/add-graph)))))
         (widgets/add-graph)))))
 
 
 (defn refresh-cb []
 (defn refresh-cb []
-  (repo-handler/create-today-journal!)
+  (page-handler/create-today-journal!)
   (shortcut/refresh!))
   (shortcut/refresh!))
 
 
 (rum/defc sync-status < rum/reactive
 (rum/defc sync-status < rum/reactive
@@ -240,7 +244,9 @@
                               (t :all-graphs)]
                               (t :all-graphs)]
                              [:a {:class "block px-4 py-2 text-sm transition ease-in-out duration-150 cursor menu-link"
                              [:a {:class "block px-4 py-2 text-sm transition ease-in-out duration-150 cursor menu-link"
                                   :on-click (fn []
                                   :on-click (fn []
-                                              (repo-handler/re-index! nfs-handler/rebuild-index!))}
+                                              (repo-handler/re-index!
+                                               nfs-handler/rebuild-index!
+                                               page-handler/create-today-journal!))}
                               (t :re-index)]]}
                               (t :re-index)]]}
              (seq switch-repos)
              (seq switch-repos)
              (assoc :links-header [:div.font-medium.text-sm.opacity-70.px-4.py-2
              (assoc :links-header [:div.font-medium.text-sm.opacity-70.px-4.py-2

+ 4 - 1
src/main/frontend/components/right_sidebar.cljs

@@ -112,7 +112,10 @@
 
 
     :page
     :page
     (let [page-name (or (:block/name block-data)
     (let [page-name (or (:block/name block-data)
-                        db-id)]
+                        db-id)
+          page-name (if (integer? db-id)
+                      (:block/name (db/entity db-id))
+                      page-name)]
       [[:a.page-title {:href     (rfe/href :page {:name page-name})
       [[:a.page-title {:href     (rfe/href :page {:name page-name})
             :on-click (fn [e]
             :on-click (fn [e]
                         (when (gobj/get e "shiftKey")
                         (when (gobj/get e "shiftKey")

+ 16 - 8
src/main/frontend/components/search.cljs

@@ -6,6 +6,7 @@
             [frontend.handler.route :as route]
             [frontend.handler.route :as route]
             [frontend.handler.page :as page-handler]
             [frontend.handler.page :as page-handler]
             [frontend.db :as db]
             [frontend.db :as db]
+            [frontend.db.model :as model]
             [frontend.handler.search :as search-handler]
             [frontend.handler.search :as search-handler]
             [frontend.ui :as ui]
             [frontend.ui :as ui]
             [frontend.state :as state]
             [frontend.state :as state]
@@ -140,7 +141,9 @@
 (rum/defc search-auto-complete
 (rum/defc search-auto-complete
   [{:keys [pages files blocks has-more?] :as result} search-q all?]
   [{:keys [pages files blocks has-more?] :as result} search-q all?]
   (rum/with-context [[t] i18n/*tongue-context*]
   (rum/with-context [[t] i18n/*tongue-context*]
-    (let [pages (when-not all? (map (fn [page] {:type :page :data page}) pages))
+    (let [pages (when-not all? (map (fn [page] {:type :page
+                                               :data page
+                                               :alias (model/get-redirect-page-name page)}) pages))
           files (when-not all? (map (fn [file] {:type :file :data file}) files))
           files (when-not all? (map (fn [file] {:type :file :data file}) files))
           blocks (map (fn [block] {:type :block :data block}) blocks)
           blocks (map (fn [block] {:type :block :data block}) blocks)
           search-mode (state/sub :search/mode)
           search-mode (state/sub :search/mode)
@@ -170,7 +173,7 @@
        (ui/auto-complete
        (ui/auto-complete
         result
         result
         {:class "search-results"
         {:class "search-results"
-         :on-chosen (fn [{:keys [type data]}]
+         :on-chosen (fn [{:keys [type data alias]}]
                       (search-handler/clear-search!)
                       (search-handler/clear-search!)
                       (leave-focus)
                       (leave-focus)
                       (case type
                       (case type
@@ -181,8 +184,9 @@
                         (page-handler/create! search-q)
                         (page-handler/create! search-q)
 
 
                         :page
                         :page
-                        (route/redirect! {:to :page
-                                          :path-params {:name data}})
+                        (let [data (or alias data)]
+                          (route/redirect! {:to :page
+                                            :path-params {:name data}}))
 
 
                         :file
                         :file
                         (route/redirect! {:to :file
                         (route/redirect! {:to :file
@@ -199,10 +203,11 @@
                                                :path-params {:name page}
                                                :path-params {:name page}
                                                :query-params {:anchor (str "ls-block-" (:block/uuid data))}}))))
                                                :query-params {:anchor (str "ls-block-" (:block/uuid data))}}))))
                         nil))
                         nil))
-         :on-shift-chosen (fn [{:keys [type data]}]
+         :on-shift-chosen (fn [{:keys [type data alias]}]
                             (case type
                             (case type
                               :page
                               :page
-                              (let [page (db/entity [:block/name (string/lower-case data)])]
+                              (let [data (or alias data)
+                                    page (db/entity [:block/name (string/lower-case data)])]
                                 (state/sidebar-add-block!
                                 (state/sidebar-add-block!
                                  (state/get-current-repo)
                                  (state/get-current-repo)
                                  (:db/id page)
                                  (:db/id page)
@@ -226,7 +231,7 @@
                                                 :path-params {:path data}})
                                                 :path-params {:path data}})
 
 
                               nil))
                               nil))
-         :item-render (fn [{:keys [type data]}]
+         :item-render (fn [{:keys [type data alias]}]
                         (let [search-mode (state/get-search-mode)]
                         (let [search-mode (state/get-search-mode)]
                           [:div {:class "py-2"} (case type
                           [:div {:class "py-2"} (case type
                                                   :graph-add-filter
                                                   :graph-add-filter
@@ -237,7 +242,10 @@
                                                    [:span.ml-1 (str "\"" search-q "\"")]]
                                                    [:span.ml-1 (str "\"" search-q "\"")]]
 
 
                                                   :page
                                                   :page
-                                                  (search-result-item "Page" (highlight-exact-query data search-q))
+                                                  [:span
+                                                   (when alias
+                                                     [:span.mr-2.text-sm.font-medium.mb-2 (str "Alias -> " alias)])
+                                                   (search-result-item "Page" (highlight-exact-query data search-q))]
 
 
                                                   :file
                                                   :file
                                                   (search-result-item "File" (highlight-exact-query data search-q))
                                                   (search-result-item "File" (highlight-exact-query data search-q))

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

@@ -342,13 +342,13 @@
             (let [value (not enable-all-pages-public?)]
             (let [value (not enable-all-pages-public?)]
               (config-handler/set-config! :publishing/all-pages-public? value)))))
               (config-handler/set-config! :publishing/all-pages-public? value)))))
 
 
-(defn enable-block-timestamps-row [t enable-block-timestamps?]
-  (toggle "block timestamps"
-          (t :settings-page/enable-block-time)
-          enable-block-timestamps?
-          (fn []
-            (let [value (not enable-block-timestamps?)]
-              (config-handler/set-config! :feature/enable-block-timestamps? value)))))
+;; (defn enable-block-timestamps-row [t enable-block-timestamps?]
+;;   (toggle "block timestamps"
+;;           (t :settings-page/enable-block-time)
+;;           enable-block-timestamps?
+;;           (fn []
+;;             (let [value (not enable-block-timestamps?)]
+;;               (config-handler/set-config! :feature/enable-block-timestamps? value)))))
 
 
 (defn encryption-row [t enable-encryption?]
 (defn encryption-row [t enable-encryption?]
   (toggle "enable_encryption"
   (toggle "enable_encryption"
@@ -454,7 +454,7 @@
         logical-outdenting? (state/logical-outdenting?)
         logical-outdenting? (state/logical-outdenting?)
         enable-tooltip? (state/enable-tooltip?)
         enable-tooltip? (state/enable-tooltip?)
         enable-git-auto-push? (state/enable-git-auto-push? current-repo)
         enable-git-auto-push? (state/enable-git-auto-push? current-repo)
-        enable-block-timestamps? (state/enable-block-timestamps?)
+        ;; enable-block-timestamps? (state/enable-block-timestamps?)
         show-brackets? (state/show-brackets?)
         show-brackets? (state/show-brackets?)
         github-token (state/sub [:me :access-token])
         github-token (state/sub [:me :access-token])
         cors-proxy (state/sub [:me :cors_proxy])
         cors-proxy (state/sub [:me :cors_proxy])
@@ -481,7 +481,7 @@
         (file-format-row t preferred-format)
         (file-format-row t preferred-format)
         (date-format-row t preferred-date-format)
         (date-format-row t preferred-date-format)
         (workflow-row t preferred-workflow)
         (workflow-row t preferred-workflow)
-        (enable-block-timestamps-row t enable-block-timestamps?)
+        ;; (enable-block-timestamps-row t enable-block-timestamps?)
         (show-brackets-row t show-brackets?)
         (show-brackets-row t show-brackets?)
         (outdenting-row t logical-outdenting?)
         (outdenting-row t logical-outdenting?)
         (tooltip-row t enable-tooltip?)
         (tooltip-row t enable-tooltip?)

+ 3 - 2
src/main/frontend/components/widgets.cljs

@@ -10,7 +10,8 @@
             [clojure.string :as string]
             [clojure.string :as string]
             [frontend.ui :as ui]
             [frontend.ui :as ui]
             [frontend.context.i18n :as i18n]
             [frontend.context.i18n :as i18n]
-            [frontend.handler.web.nfs :as nfs]))
+            [frontend.handler.web.nfs :as nfs]
+            [frontend.modules.shortcut.core :as shortcut]))
 
 
 (rum/defc choose-preferred-format
 (rum/defc choose-preferred-format
   []
   []
@@ -88,7 +89,7 @@
        [:div.cp__widgets-open-local-directory
        [:div.cp__widgets-open-local-directory
         [:div.select-file-wrap.cursor
         [:div.select-file-wrap.cursor
          (when nfs-supported?
          (when nfs-supported?
-           {:on-click page-handler/ls-dir-files!})
+           {:on-click #(page-handler/ls-dir-files! shortcut/refresh!)})
          [:div
          [:div
           [:h1.title "Open a local directory"]
           [:h1.title "Open a local directory"]
           [:p "Logseq supports both Markdown and Org-mode. You can open an existing directory or create a new one on your device, a directory is also known simply as a folder. Your data will be stored only on this device."]
           [:p "Logseq supports both Markdown and Org-mode. You can open an existing directory or create a new one on your device, a directory is also known simply as a folder. Your data will be stored only on this device."]

+ 14 - 12
src/main/frontend/date.cljs

@@ -190,18 +190,20 @@
        (valid? (util/capitalize-all title))))
        (valid? (util/capitalize-all title))))
 
 
 (defn journal-title->
 (defn journal-title->
-  [journal-title then-fn]
-  (when-not (string/blank? journal-title)
-    (when-let [time (->> (map
-                           (fn [formatter]
-                             (try
-                               (tf/parse (tf/formatter formatter) (util/capitalize-all journal-title))
-                               (catch js/Error _e
-                                 nil)))
-                           safe-journal-title-formatters)
-                         (filter some?)
-                         first)]
-      (then-fn time))))
+  ([journal-title then-fn]
+   (journal-title-> journal-title then-fn (journal-title-formatters)))
+  ([journal-title then-fn formatters]
+   (when-not (string/blank? journal-title)
+     (when-let [time (->> (map
+                            (fn [formatter]
+                              (try
+                                (tf/parse (tf/formatter formatter) (util/capitalize-all journal-title))
+                                (catch js/Error _e
+                                  nil)))
+                            formatters)
+                          (filter some?)
+                          first)]
+       (then-fn time)))))
 
 
 (defn journal-title->int
 (defn journal-title->int
   [journal-title]
   [journal-title]

+ 1 - 1
src/main/frontend/db.cljs

@@ -48,7 +48,7 @@
   get-page-referenced-blocks get-page-referenced-pages get-page-unlinked-references get-page-referenced-blocks-no-cache
   get-page-referenced-blocks get-page-referenced-pages get-page-unlinked-references get-page-referenced-blocks-no-cache
   get-all-pages get-pages get-pages-relation get-pages-that-mentioned-page get-public-pages get-tag-pages
   get-all-pages get-pages get-pages-relation get-pages-that-mentioned-page get-public-pages get-tag-pages
   journal-page? local-native-fs? mark-repo-as-cloned! page-alias-set page-blocks-transform pull-block
   journal-page? local-native-fs? mark-repo-as-cloned! page-alias-set page-blocks-transform pull-block
-  set-file-last-modified-at! transact-files-db! with-block-refs-count get-modified-pages page-empty? page-empty-or-dummy? get-alias-source-page
+  set-file-last-modified-at! transact-files-db! get-modified-pages page-empty? page-empty-or-dummy? get-alias-source-page
   set-file-content! has-children? get-namespace-pages get-all-namespace-relation]
   set-file-content! has-children? get-namespace-pages get-all-namespace-relation]
 
 
  [frontend.db.react
  [frontend.db.react

+ 19 - 0
src/main/frontend/db/debug.cljs

@@ -29,6 +29,25 @@
                                              count-1
                                              count-1
                                              (- count-1 count-2)))))
                                              (- count-1 count-2)))))
 
 
+(defn block-uuid-nil?
+  [block]
+  (->>
+   (concat
+    [(:block/parent block)
+     (:block/left block)
+     (:block/page block)
+     (:block/namespace block)]
+    (:block/tags block)
+    (:block/alias block)
+    (:block/refs block)
+    (:block/path-refs block))
+   (remove nil?)
+   (some (fn [x]
+           (and
+            (vector? x)
+            (= :block/uuid (first x))
+            (nil? (second x)))))))
+
 (comment
 (comment
   (defn debug!
   (defn debug!
     []
     []

+ 22 - 26
src/main/frontend/db/model.cljs

@@ -410,17 +410,9 @@
              (map (fn [m]
              (map (fn [m]
                     (or (:block/original-name m) (:block/name m)))))))))
                     (or (:block/original-name m) (:block/name m)))))))))
 
 
-(defn with-block-refs-count
-  [repo blocks]
-  (map (fn [block]
-         (let [refs-count (count (:block/_refs (db-utils/entity (:db/id block))))]
-           (assoc block :block/block-refs-count refs-count)))
-    blocks))
-
 (defn page-blocks-transform
 (defn page-blocks-transform
   [repo-url result]
   [repo-url result]
-  (->> (db-utils/with-repo repo-url result)
-       (with-block-refs-count repo-url)))
+  (db-utils/with-repo repo-url result))
 
 
 (defn with-pages
 (defn with-pages
   [blocks]
   [blocks]
@@ -556,7 +548,10 @@
 
 
 (defn page-empty?
 (defn page-empty?
   [repo page-id]
   [repo page-id]
-  (empty? (:block/_parent (db-utils/entity repo page-id))))
+  (let [page-id (if (integer? page-id)
+                  page-id
+                  [:block/name page-id])]
+    (empty? (:block/_parent (db-utils/entity repo page-id)))))
 
 
 (defn page-empty-or-dummy?
 (defn page-empty-or-dummy?
   [repo page-id]
   [repo page-id]
@@ -618,8 +613,7 @@
   [result repo-url block-uuid]
   [result repo-url block-uuid]
   (some->> result
   (some->> result
            db-utils/seq-flatten
            db-utils/seq-flatten
-           (db-utils/with-repo repo-url)
-           (with-block-refs-count repo-url)))
+           (db-utils/with-repo repo-url)))
 
 
 (defn get-block-children-ids
 (defn get-block-children-ids
   [repo block-uuid]
   [repo block-uuid]
@@ -757,23 +751,25 @@
 (defn get-redirect-page-name
 (defn get-redirect-page-name
   ([page-name] (get-redirect-page-name page-name false))
   ([page-name] (get-redirect-page-name page-name false))
   ([page-name alias?]
   ([page-name alias?]
-   (let [page-entity (db-utils/entity [:block/name page-name])]
-     (cond
-       alias?
-       page-name
-
-       (page-empty-or-dummy? (state/get-current-repo) (:db/id page-entity))
-       (let [source-page (get-alias-source-page (state/get-current-repo)
-                                                      (string/lower-case page-name))]
-         (or (when source-page (:block/name source-page))
-             page-name))
-
-       :else
-       page-name))))
+   (when page-name
+     (let [page-name (string/lower-case page-name)
+           page-entity (db-utils/entity [:block/name page-name])]
+       (cond
+         alias?
+         page-name
+
+         (page-empty-or-dummy? (state/get-current-repo) (:db/id page-entity))
+         (let [source-page (get-alias-source-page (state/get-current-repo)
+                                                  (string/lower-case page-name))]
+           (or (when source-page (:block/name source-page))
+               page-name))
+
+         :else
+         page-name)))))
 
 
 (defn get-page-original-name
 (defn get-page-original-name
   [page-name]
   [page-name]
-  (when page-name
+  (when (string? page-name)
     (let [page (db-utils/pull [:block/name (string/lower-case page-name)])]
     (let [page (db-utils/pull [:block/name (string/lower-case page-name)])]
       (or (:block/original-name page)
       (or (:block/original-name page)
           (:block/name page)))))
           (:block/name page)))))

+ 0 - 1
src/main/frontend/db/query_react.cljs

@@ -75,7 +75,6 @@
                                 remove-nested-children-blocks
                                 remove-nested-children-blocks
                                 (model/sort-by-left-recursive)
                                 (model/sort-by-left-recursive)
                                 (db-utils/with-repo repo)
                                 (db-utils/with-repo repo)
-                                (model/with-block-refs-count repo)
                                 (model/with-pages)))
                                 (model/with-pages)))
                      result)]
                      result)]
         (if-let [result-transform (:result-transform q)]
         (if-let [result-transform (:result-transform q)]

+ 2 - 3
src/main/frontend/extensions/code.cljs

@@ -12,7 +12,6 @@
             [clojure.string :as string]
             [clojure.string :as string]
             [dommy.core :as dom]
             [dommy.core :as dom]
             [frontend.utf8 :as utf8]
             [frontend.utf8 :as utf8]
-            [frontend.util.property :as property]
             ["codemirror" :as cm]
             ["codemirror" :as cm]
             ["codemirror/addon/edit/matchbrackets"]
             ["codemirror/addon/edit/matchbrackets"]
             ["codemirror/addon/edit/closebrackets"]
             ["codemirror/addon/edit/closebrackets"]
@@ -64,8 +63,8 @@
         (:block/uuid config)
         (:block/uuid config)
         (let [block (db/pull [:block/uuid (:block/uuid config)])
         (let [block (db/pull [:block/uuid (:block/uuid config)])
               format (:block/format block)
               format (:block/format block)
-              content (property/remove-properties format (:block/content block))
-              full-content (property/remove-built-in-properties format (:full_content (last (:rum/args state))))]
+              content (:block/content block)
+              full-content (:full_content (last (:rum/args state)))]
           (when (and full-content (string/includes? content full-content))
           (when (and full-content (string/includes? content full-content))
             (let [lines (string/split-lines full-content)
             (let [lines (string/split-lines full-content)
                   fl (first lines)
                   fl (first lines)

+ 9 - 10
src/main/frontend/extensions/zotero/extractor.cljs

@@ -41,7 +41,7 @@
           (-> item :data :name-of-act)
           (-> item :data :name-of-act)
           ;; default use title
           ;; default use title
           (title item))]
           (title item))]
-    (str (setting/setting :page-insert-prefix) page-title "_" (item-key item))))
+    (str (setting/setting :page-insert-prefix) page-title)))
 
 
 (defn authors [item]
 (defn authors [item]
   (let [creators (-> item :data :creators)
   (let [creators (-> item :data :creators)
@@ -138,16 +138,15 @@
 
 
 (defmethod extract "attachment"
 (defmethod extract "attachment"
   [item]
   [item]
-  (let [{:keys [title url link-mode path]} (-> item :data)]
-    (case link-mode
-      "imported_file"
-      (markdown-link title (local-link item))
-      "imported_url"
-      (markdown-link title url)
-      "linked_file"
-      (markdown-link title (str "file://" path))
-      "linked_url"
+  (let [{:keys [title filename url link-mode path]} (-> item :data)]
+    (cond
+      (contains? #{"imported_file" "imported_url" "linked_file"} link-mode)
+      (markdown-link (or title filename) (local-link item))
+
+      (some? url)
       (markdown-link title url)
       (markdown-link title url)
+
+      :else
       nil)))
       nil)))
 
 
 (defmethod extract :default
 (defmethod extract :default

+ 14 - 2
src/main/frontend/extensions/zotero/handler.cljs

@@ -43,6 +43,15 @@
   (state/set-editor-show-zotero! false)
   (state/set-editor-show-zotero! false)
   (editor-handler/insert-command! id (str "[[" page-name "]]") nil {}))
   (editor-handler/insert-command! id (str "[[" page-name "]]") nil {}))
 
 
+(defn- create-abstract-note!
+  [page-name abstract-note]
+  (when-not (str/blank? abstract-note)
+    (let [block (editor-handler/api-insert-new-block!
+                 "[[Abstract]]" {:page page-name})]
+      (editor-handler/api-insert-new-block!
+       abstract-note {:block-uuid (:block/uuid block)
+                      :sibling? false}))))
+
 (defn create-zotero-page
 (defn create-zotero-page
   ([item]
   ([item]
    (create-zotero-page item {}))
    (create-zotero-page item {}))
@@ -50,8 +59,9 @@
           :or {insert-command? true notification? true}
           :or {insert-command? true notification? true}
           :as opt}]
           :as opt}]
    (go
    (go
-     (let [{:keys [page-name properties]} (extractor/extract item)]
-
+     (let [{:keys [page-name properties]} (extractor/extract item)
+           abstract-note (get properties :abstract-note)
+           properties (dissoc properties :abstract-note)]
        (when insert-command?
        (when insert-command?
          (handle-command-zotero block-dom-id page-name)
          (handle-command-zotero block-dom-id page-name)
          (editor-handler/save-current-block!))
          (editor-handler/save-current-block!))
@@ -68,6 +78,8 @@
            :create-first-block? false
            :create-first-block? false
            :properties properties}))
            :properties properties}))
 
 
+       (create-abstract-note! page-name abstract-note)
+
        (<! (add page-name :attachments item))
        (<! (add page-name :attachments item))
 
 
        (<! (add page-name :notes item))
        (<! (add page-name :notes item))

+ 2 - 2
src/main/frontend/extensions/zotero/setting.cljs

@@ -7,9 +7,9 @@
 (def default-settings
 (def default-settings
   {:type                   :user
   {:type                   :user
    :include-attachments?   true
    :include-attachments?   true
-   :attachments-block-text "[[attachments]]"
+   :attachments-block-text "[[Attachments]]"
    :include-notes?         true
    :include-notes?         true
-   :notes-block-text       "[[notes]]"
+   :notes-block-text       "[[Notes]]"
    :page-insert-prefix     "@"})
    :page-insert-prefix     "@"})
 
 
 (defn api-key []
 (defn api-key []

+ 10 - 5
src/main/frontend/format/block.cljs

@@ -677,11 +677,16 @@
                 (let [[f r] (split-with (fn [p] (<= (:block/level-spaces p) level-spaces)) parents)
                 (let [[f r] (split-with (fn [p] (<= (:block/level-spaces p) level-spaces)) parents)
                       left (first r)
                       left (first r)
                       parents' (->> (concat f [left]) vec)
                       parents' (->> (concat f [left]) vec)
-                      block (assoc block
-                                   :block/parent [:block/uuid (:block/uuid (last f))]
-                                   :block/left [:block/uuid (:block/uuid left)]
-                                   :block/level (:block/level left)
-                                   :block/level-spaces (:block/level-spaces left))
+                      parent-id (if-let [block-id (:block/uuid (last f))]
+                                  [:block/uuid block-id]
+                                  page-id)
+                      block (cond->
+                              (assoc block
+                                     :block/parent parent-id
+                                     :block/left [:block/uuid (:block/uuid left)]
+                                     :block/level (:block/level left)
+                                     :block/level-spaces (:block/level-spaces left)))
+
                       parents' (->> (concat f [block]) vec)
                       parents' (->> (concat f [block]) vec)
                       result' (conj result block)]
                       result' (conj result block)]
                   [others parents' block result'])))]
                   [others parents' block result'])))]

+ 15 - 2
src/main/frontend/format/mldoc.cljs

@@ -21,10 +21,21 @@
 (defonce parseAndExportOPML (gobj/get Mldoc "parseAndExportOPML"))
 (defonce parseAndExportOPML (gobj/get Mldoc "parseAndExportOPML"))
 (defonce astExportMarkdown (gobj/get Mldoc "astExportMarkdown"))
 (defonce astExportMarkdown (gobj/get Mldoc "astExportMarkdown"))
 
 
+(defn convert-export-md-remove-options [opts]
+  (->>
+   (mapv (fn [opt]
+             (case opt
+               :page-ref ["Page_ref"]
+               :emphasis ["Emphasis"]
+               []))
+         opts)
+   (remove empty?)))
+
+
 (defn default-config
 (defn default-config
   ([format]
   ([format]
    (default-config format {:export-heading-to-list? false}))
    (default-config format {:export-heading-to-list? false}))
-  ([format {:keys [export-heading-to-list? export-keep-properties? export-md-indent-style]}]
+  ([format {:keys [export-heading-to-list? export-keep-properties? export-md-indent-style export-md-remove-options]}]
    (let [format (string/capitalize (name (or format :markdown)))]
    (let [format (string/capitalize (name (or format :markdown)))]
      (->> {:toc false
      (->> {:toc false
            :heading_number false
            :heading_number false
@@ -32,7 +43,9 @@
            :format format
            :format format
            :heading_to_list (or export-heading-to-list? false)
            :heading_to_list (or export-heading-to-list? false)
            :exporting_keep_properties export-keep-properties?
            :exporting_keep_properties export-keep-properties?
-           :export_md_indent_style export-md-indent-style}
+           :export_md_indent_style export-md-indent-style
+           :export_md_remove_options
+           (convert-export-md-remove-options export-md-remove-options)}
           (filter #(not(nil? (second %))))
           (filter #(not(nil? (second %))))
           (into {})
           (into {})
           (bean/->js)
           (bean/->js)

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

@@ -47,7 +47,7 @@
   (let [f (fn []
   (let [f (fn []
             (when-not (state/nfs-refreshing?)
             (when-not (state/nfs-refreshing?)
               ;; Don't create the journal file until user writes something
               ;; Don't create the journal file until user writes something
-              (repo-handler/create-today-journal! false))
+              (page-handler/create-today-journal!))
             (when-let [repo (state/get-current-repo)]
             (when-let [repo (state/get-current-repo)]
               (when (and (search-db/empty? repo)
               (when (and (search-db/empty? repo)
                          (state/input-idle? repo))
                          (state/input-idle? repo))

+ 14 - 3
src/main/frontend/handler/editor.cljs

@@ -330,7 +330,7 @@
                         (:block/properties block))]
                         (:block/properties block))]
     (-> block
     (-> block
         (dissoc :block/top?
         (dissoc :block/top?
-                :block/block-refs-count)
+                :block/bottom?)
         (assoc :block/content content
         (assoc :block/content content
                :block/properties new-properties)
                :block/properties new-properties)
         (merge (if level {:block/level level} {})))))
         (merge (if level {:block/level level} {})))))
@@ -348,7 +348,15 @@
        (when refresh?
        (when refresh?
          (let [opts {:key :block/change
          (let [opts {:key :block/change
                      :data [block]}]
                      :data [block]}]
-           (db/refresh! repo opts)))))
+           (db/refresh! repo opts)))
+
+       ;; page title changed
+       (when-let [title (get-in block [:block/properties :title])]
+         (when-let [old-title (:block/name (db/entity (:db/id (:block/page block))))]
+           (when (and (:block/pre-block? block)
+                     (not (string/blank? title))
+                     (not= (string/lower-case title) old-title))
+             (state/pub-event! [:page/title-property-changed old-title title]))))))
 
 
     (repo-handler/push-if-auto-enabled! repo)))
     (repo-handler/push-if-auto-enabled! repo)))
 
 
@@ -1074,7 +1082,10 @@
         level-blocks (mapv (fn [uuid] (get level-blocks-uuid-map uuid)) block-ids*)
         level-blocks (mapv (fn [uuid] (get level-blocks-uuid-map uuid)) block-ids*)
         tree (blocks-vec->tree level-blocks)
         tree (blocks-vec->tree level-blocks)
         top-level-block-uuids (mapv :block/uuid (filterv #(not (vector? %)) tree))
         top-level-block-uuids (mapv :block/uuid (filterv #(not (vector? %)) tree))
-        exported-md-contents (mapv #(export/export-blocks-as-markdown repo % "spaces")
+        exported-md-contents (mapv #(export/export-blocks-as-markdown
+                                     repo %
+                                     @(state/get-export-block-text-indent-style)
+                                     (into [] @(state/get-export-block-text-remove-options)))
                                    top-level-block-uuids)]
                                    top-level-block-uuids)]
     [(string/join "\n" (mapv string/trim-newline exported-md-contents)) tree]))
     [(string/join "\n" (mapv string/trim-newline exported-md-contents)) tree]))
 
 

+ 7 - 0
src/main/frontend/handler/events.cljs

@@ -9,6 +9,7 @@
             [frontend.handler.notification :as notification]
             [frontend.handler.notification :as notification]
             [frontend.handler.common :as common-handler]
             [frontend.handler.common :as common-handler]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.editor :as editor-handler]
+            [frontend.handler.page :as page-handler]
             [frontend.components.encryption :as encryption]
             [frontend.components.encryption :as encryption]
             [frontend.fs.nfs :as nfs]
             [frontend.fs.nfs :as nfs]
             [frontend.db.conn :as conn]
             [frontend.db.conn :as conn]
@@ -133,6 +134,12 @@
 (defmethod handle :modal/show-cards [_]
 (defmethod handle :modal/show-cards [_]
   (state/set-modal! srs/global-cards))
   (state/set-modal! srs/global-cards))
 
 
+(defmethod handle :page/title-property-changed [[_ old-title new-title]]
+  (page-handler/rename! old-title new-title))
+
+(defmethod handle :page/create-today-journal [[_ repo]]
+  (page-handler/create-today-journal!))
+
 (defmethod handle :after-db-restore [[_ repos]]
 (defmethod handle :after-db-restore [[_ repos]]
   (mapv (fn [{url :url} repo]
   (mapv (fn [{url :url} repo]
           ;; compare :ast/version
           ;; compare :ast/version

+ 2 - 2
src/main/frontend/handler/export.cljs

@@ -448,7 +448,7 @@
                    (js/JSON.stringify (clj->js refs)))))
                    (js/JSON.stringify (clj->js refs)))))
 
 
 (defn export-blocks-as-markdown
 (defn export-blocks-as-markdown
-  [repo root-block-uuid indent-style]
+  [repo root-block-uuid indent-style remove-options]
   (let [get-page&block-refs-by-query-aux (get-embed-and-refs-blocks-pages-aux)
   (let [get-page&block-refs-by-query-aux (get-embed-and-refs-blocks-pages-aux)
         f #(get-page&block-refs-by-query repo % get-page&block-refs-by-query-aux {:is-block? true})
         f #(get-page&block-refs-by-query repo % get-page&block-refs-by-query-aux {:is-block? true})
         root-block (db/entity [:block/uuid root-block-uuid])
         root-block (db/entity [:block/uuid root-block-uuid])
@@ -457,7 +457,7 @@
         content (get-blocks-contents repo root-block-uuid)
         content (get-blocks-contents repo root-block-uuid)
         format (or (:block/format root-block) (state/get-preferred-format))]
         format (or (:block/format root-block) (state/get-preferred-format))]
     (fp/exportMarkdown f/mldoc-record content
     (fp/exportMarkdown f/mldoc-record content
-                       (f/get-default-config format {:export-md-indent-style indent-style})
+                       (f/get-default-config format {:export-md-indent-style indent-style :export-md-remove-options remove-options})
                        (js/JSON.stringify (clj->js refs)))))
                        (js/JSON.stringify (clj->js refs)))))
 
 
 (defn export-blocks-as-html
 (defn export-blocks-as-html

+ 20 - 11
src/main/frontend/handler/extract.cljs

@@ -130,9 +130,11 @@
                      ;; remove block references
                      ;; remove block references
                      (remove vector?))
                      (remove vector?))
           pages (util/distinct-by :block/name pages)
           pages (util/distinct-by :block/name pages)
-          block-ids (mapv (fn [block]
-                            {:block/uuid (:block/uuid block)})
-                          (remove nil? blocks))
+          block-ids (->>
+                     (mapv (fn [block]
+                             {:block/uuid (:block/uuid block)})
+                           (remove nil? blocks))
+                     (remove nil?))
           pages (remove nil? pages)
           pages (remove nil? pages)
           pages (map (fn [page] (assoc page :block/uuid (db/new-block-id))) pages)]
           pages (map (fn [page] (assoc page :block/uuid (db/new-block-id))) pages)]
       [pages
       [pages
@@ -189,6 +191,18 @@
          (map (partial apply merge))
          (map (partial apply merge))
          (with-block-uuid))))
          (with-block-uuid))))
 
 
+(defn- remove-illegal-refs
+  [block block-ids-set refresh?]
+  (let [aux-fn (fn [refs]
+                 (let [block-refs (if refresh? (set refs)
+                                      (set/intersection (set refs) block-ids-set))]
+                   (set/union
+                    (filter :block/name refs)
+                    block-refs)))]
+    (-> block
+        (update :block/refs aux-fn)
+        (update :block/path-refs aux-fn))))
+
 (defn extract-all-blocks-pages
 (defn extract-all-blocks-pages
   [repo-url files metadata refresh?]
   [repo-url files metadata refresh?]
   (when (seq files)
   (when (seq files)
@@ -207,6 +221,8 @@
                       (remove empty?))]
                       (remove empty?))]
       (when (seq result)
       (when (seq result)
         (let [[pages block-ids blocks] (apply map concat result)
         (let [[pages block-ids blocks] (apply map concat result)
+              block-ids (remove (fn [b] (or (nil? b)
+                                           (nil? (:block/uuid b)))) block-ids)
               pages (with-ref-pages pages blocks)
               pages (with-ref-pages pages blocks)
               blocks (map (fn [block]
               blocks (map (fn [block]
                             (let [id (:block/uuid block)
                             (let [id (:block/uuid block)
@@ -216,12 +232,5 @@
               ;; To prevent "unique constraint" on datascript
               ;; To prevent "unique constraint" on datascript
               pages-index (map #(select-keys % [:block/name]) pages)
               pages-index (map #(select-keys % [:block/name]) pages)
               block-ids-set (set (map (fn [{:block/keys [uuid]}] [:block/uuid uuid]) block-ids))
               block-ids-set (set (map (fn [{:block/keys [uuid]}] [:block/uuid uuid]) block-ids))
-              blocks (map (fn [b]
-                            (update b :block/refs
-                                    (fn [refs]
-                                      (let [block-refs (if refresh? (set refs)
-                                                           (set/intersection (set refs) block-ids-set))]
-                                        (set/union
-                                         (filter :block/name refs)
-                                         block-refs))))) blocks)]
+              blocks (map #(remove-illegal-refs % block-ids-set refresh?) blocks)]
           (apply concat [pages-index pages block-ids blocks]))))))
           (apply concat [pages-index pages block-ids blocks]))))))

+ 51 - 32
src/main/frontend/handler/page.cljs

@@ -13,7 +13,6 @@
             [frontend.handler.web.nfs :as web-nfs]
             [frontend.handler.web.nfs :as web-nfs]
             [frontend.handler.notification :as notification]
             [frontend.handler.notification :as notification]
             [frontend.handler.config :as config-handler]
             [frontend.handler.config :as config-handler]
-            [frontend.modules.shortcut.core :as shortcut]
             [frontend.handler.ui :as ui-handler]
             [frontend.handler.ui :as ui-handler]
             [frontend.modules.outliner.file :as outliner-file]
             [frontend.modules.outliner.file :as outliner-file]
             [frontend.modules.outliner.core :as outliner-core]
             [frontend.modules.outliner.core :as outliner-core]
@@ -81,35 +80,36 @@
   ([title {:keys [redirect? create-first-block? format properties]
   ([title {:keys [redirect? create-first-block? format properties]
            :or   {redirect?           true
            :or   {redirect?           true
                   create-first-block? true
                   create-first-block? true
-                  format              false
-                  properties          false}}]
-   (let [title    (string/trim title)
-         pages    (util/split-namespace-pages title)
-         page     (string/lower-case title)
-         format   (or format (state/get-preferred-format))
-         pages    (map (fn [page]
-                         (-> (block/page-name->map page true)
-                             (assoc :block/format format)))
-                       pages)
-         txs      (->> pages
-                       ;; for namespace pages, only last page need properties
-                       drop-last
-                       (mapcat #(build-page-tx format false %))
-                       (remove nil?))
-         last-txs (build-page-tx format properties (last pages))
-         txs      (concat txs last-txs)]
-
-     (db/transact! txs)
-
-     (when create-first-block?
-       (editor-handler/insert-first-page-block-if-not-exists! page))
-
-     (when-let [page (db/entity [:block/name page])]
-       (outliner-file/sync-to-file page))
-
-     (when redirect?
-       (route-handler/redirect! {:to          :page
-                                 :path-params {:name page}})))))
+                  format              nil
+                  properties          nil}}]
+   (let [page (string/lower-case title)]
+     (when-not (db/entity [:block/name page])
+       (let [title    (string/trim title)
+             pages    (util/split-namespace-pages title)
+             format   (or format (state/get-preferred-format))
+             pages    (map (fn [page]
+                             (-> (block/page-name->map page true)
+                                 (assoc :block/format format)))
+                        pages)
+             txs      (->> pages
+                           ;; for namespace pages, only last page need properties
+                           drop-last
+                           (mapcat #(build-page-tx format false %))
+                           (remove nil?))
+             last-txs (build-page-tx format properties (last pages))
+             txs      (concat txs last-txs)]
+
+         (db/transact! txs)
+
+         (when create-first-block?
+           (editor-handler/insert-first-page-block-if-not-exists! page))
+
+         (when-let [page (db/entity [:block/name page])]
+           (outliner-file/sync-to-file page))
+
+         (when redirect?
+           (route-handler/redirect! {:to          :page
+                                     :path-params {:name page}})))))))
 
 
 (defn page-add-property!
 (defn page-add-property!
   [page-name key value]
   [page-name key value]
@@ -368,6 +368,9 @@
 
 
                     (d/transact! (db/get-conn repo false) page-txs)
                     (d/transact! (db/get-conn repo false) page-txs)
 
 
+                    (when (not= (util/page-name-sanity new-name) new-name)
+                      (page-add-property! new-name :title new-name))
+
                     (when (and file (not journal?) name-changed?)
                     (when (and file (not journal?) name-changed?)
                       (rename-file! file new-name (fn [] nil)))
                       (rename-file! file new-name (fn [] nil)))
 
 
@@ -481,11 +484,11 @@
           (contains? (set templates) (string/lower-case title)))))))
           (contains? (set templates) (string/lower-case title)))))))
 
 
 (defn ls-dir-files!
 (defn ls-dir-files!
-  []
+  [ok-handler]
   (web-nfs/ls-dir-files-with-handler!
   (web-nfs/ls-dir-files-with-handler!
    (fn []
    (fn []
      (init-commands!)
      (init-commands!)
-     (shortcut/refresh!))))
+     (when ok-handler (ok-handler)))))
 
 
 (defn get-all-pages
 (defn get-all-pages
   [repo]
   [repo]
@@ -570,3 +573,19 @@
                                           format
                                           format
                                           {:last-pattern (str "[[" (if @editor-handler/*selected-text "" q))
                                           {:last-pattern (str "[[" (if @editor-handler/*selected-text "" q))
                                            :postfix-fn   (fn [s] (util/replace-first "]]" s ""))}))))))
                                            :postfix-fn   (fn [s] (util/replace-first "]]" s ""))}))))))
+
+(defn create-today-journal!
+  []
+  (state/set-today! (date/today))
+  (when-let [repo (state/get-current-repo)]
+    (when (or (db/cloned? repo)
+              (and (or (config/local-db? repo)
+                       (= "local" repo))
+                   ;; config file exists
+                   (let [path (config/get-config-path)]
+                     (db/get-file path))))
+      (let [title (date/today)
+            today-page (string/lower-case title)]
+        (when (db/page-empty? repo today-page)
+          (create! title {:redirect? false
+                          :create-first-block? true}))))))

+ 12 - 26
src/main/frontend/handler/repo.cljs

@@ -114,9 +114,8 @@
                      (config/get-file-extension format))
                      (config/get-file-extension format))
            file-path (str "/" path)
            file-path (str "/" path)
            page-exists? (db/entity repo-url [:block/name (string/lower-case title)])
            page-exists? (db/entity repo-url [:block/name (string/lower-case title)])
-           empty-blocks? (empty? (db/get-page-blocks-no-cache repo-url (string/lower-case title)))]
-       (when (or empty-blocks?
-                 (not page-exists?))
+           empty-blocks? (db/page-empty? repo-url (string/lower-case title))]
+       (when (or empty-blocks? (not page-exists?))
          (p/let [_ (nfs/check-directory-permission! repo-url)
          (p/let [_ (nfs/check-directory-permission! repo-url)
                  _ (fs/mkdir-if-not-exists (str repo-dir "/" (config/get-journals-directory)))
                  _ (fs/mkdir-if-not-exists (str repo-dir "/" (config/get-journals-directory)))
                  file-exists? (fs/file-exists? repo-dir file-path)]
                  file-exists? (fs/file-exists? repo-dir file-path)]
@@ -130,22 +129,6 @@
                (when-not (state/editing?)
                (when-not (state/editing?)
                  (ui-handler/re-render-root!))))))))))
                  (ui-handler/re-render-root!))))))))))
 
 
-(defn create-today-journal!
-  ([]
-   (create-today-journal! true))
-  ([write-file?]
-   (state/set-today! (date/today))
-   (when-let [repo (state/get-current-repo)]
-     (when (or (db/cloned? repo)
-               (and (or (config/local-db? repo)
-                        (= "local" repo))
-                    ;; config file exists
-                    (let [path (config/get-config-path)]
-                      (db/get-file path))))
-       (let [today-page (string/lower-case (date/today))]
-         (when (empty? (db/get-page-blocks-no-cache repo today-page))
-           (create-today-journal-if-not-exists repo {:write-file? write-file?})))))))
-
 (defn create-default-files!
 (defn create-default-files!
   ([repo-url]
   ([repo-url]
    (create-default-files! repo-url false))
    (create-default-files! repo-url false))
@@ -153,13 +136,14 @@
    (spec/validate :repos/url repo-url)
    (spec/validate :repos/url repo-url)
    (let [repo-dir (config/get-repo-dir repo-url)]
    (let [repo-dir (config/get-repo-dir repo-url)]
      (p/let [_ (fs/mkdir-if-not-exists (str repo-dir "/" config/app-name))
      (p/let [_ (fs/mkdir-if-not-exists (str repo-dir "/" config/app-name))
-             _ (fs/mkdir-if-not-exists (str repo-dir "/" config/app-name "/" config/recycle-dir))]
+             _ (fs/mkdir-if-not-exists (str repo-dir "/" config/app-name "/" config/recycle-dir))
+             _ (fs/mkdir-if-not-exists (str repo-dir "/" (config/get-journals-directory)))]
        (file-handler/create-metadata-file repo-url encrypted?)
        (file-handler/create-metadata-file repo-url encrypted?)
        ;; TODO: move to frontend.handler.file
        ;; TODO: move to frontend.handler.file
        (create-config-file-if-not-exists repo-url)
        (create-config-file-if-not-exists repo-url)
-       (create-today-journal-if-not-exists repo-url {:write-file? false})
        (create-contents-file repo-url)
        (create-contents-file repo-url)
-       (create-custom-theme repo-url)))))
+       (create-custom-theme repo-url)
+       (state/pub-event! [:page/create-today-journal repo-url])))))
 
 
 (defn- remove-non-exists-refs!
 (defn- remove-non-exists-refs!
   [data]
   [data]
@@ -275,6 +259,8 @@
   [repo-url {:keys [first-clone? diffs nfs-files refresh?]
   [repo-url {:keys [first-clone? diffs nfs-files refresh?]
              :as opts}]
              :as opts}]
   (spec/validate :repos/url repo-url)
   (spec/validate :repos/url repo-url)
+  (when (= :repos (state/get-current-route))
+    (route-handler/redirect-to-home!))
   (let [config (or (state/get-config repo-url)
   (let [config (or (state/get-config repo-url)
                    (some-> (first (filter #(= (config/get-config-path repo-url) (:file/path %)) nfs-files))
                    (some-> (first (filter #(= (config/get-config-path repo-url) (:file/path %)) nfs-files))
                            :file/content
                            :file/content
@@ -329,11 +315,11 @@
               options {:first-clone? first-clone?
               options {:first-clone? first-clone?
                        :delete-files (concat delete-files delete-pages)
                        :delete-files (concat delete-files delete-pages)
                        :delete-blocks delete-blocks
                        :delete-blocks delete-blocks
-                       :re-render? true
-                       :refresh? true}]
+                       :re-render? true}]
           (if (seq nfs-files)
           (if (seq nfs-files)
             (parse-files-and-load-to-db! repo-url nfs-files
             (parse-files-and-load-to-db! repo-url nfs-files
                                          (assoc options
                                          (assoc options
+                                                :refresh? refresh?
                                                 :re-render-opts {:clear-all-query-state? true}))
                                                 :re-render-opts {:clear-all-query-state? true}))
             (load-contents add-or-modify-files options)))))))
             (load-contents add-or-modify-files options)))))))
 
 
@@ -636,11 +622,11 @@
                    (prn "Delete repo failed, error: " error))))))
                    (prn "Delete repo failed, error: " error))))))
 
 
 (defn re-index!
 (defn re-index!
-  [nfs-rebuild-index!]
+  [nfs-rebuild-index! ok-handler]
   (when-let [repo (state/get-current-repo)]
   (when-let [repo (state/get-current-repo)]
     (let [local? (config/local-db? repo)]
     (let [local? (config/local-db? repo)]
       (if local?
       (if local?
-        (nfs-rebuild-index! repo create-today-journal!)
+        (nfs-rebuild-index! repo ok-handler)
         (rebuild-index! repo))
         (rebuild-index! repo))
       (js/setTimeout
       (js/setTimeout
        (fn []
        (fn []

+ 1 - 1
src/main/frontend/handler/web/nfs.cljs

@@ -248,7 +248,7 @@
                       (repo-handler/load-repo-to-db! repo
                       (repo-handler/load-repo-to-db! repo
                                                      {:diffs     diffs
                                                      {:diffs     diffs
                                                       :nfs-files modified-files
                                                       :nfs-files modified-files
-                                                      :refresh? true}))))))))
+                                                      :refresh? (not re-index?)}))))))))
 
 
 (defn- reload-dir!
 (defn- reload-dir!
   ([repo]
   ([repo]

+ 20 - 18
src/main/frontend/modules/outliner/core.cljs

@@ -76,11 +76,12 @@
                 (assoc block :block/updated-at updated-at)
                 (assoc block :block/updated-at updated-at)
                 (nil? (:block/created-at block))
                 (nil? (:block/created-at block))
                 (assoc :block/created-at updated-at))
                 (assoc :block/created-at updated-at))
-        content (property/insert-properties (:block/format block)
-                                            (or (:block/content block) "")
-                                            {:created-at (:block/created-at block)
-                                             :updated-at (:block/updated-at block)})]
-    (assoc block :block/content content)))
+        ;; content (property/insert-properties (:block/format block)
+        ;;                                     (or (:block/content block) "")
+        ;;                                     {:created-at (:block/created-at block)
+        ;;                                      :updated-at (:block/updated-at block)})
+        ]
+    block))
 
 
 ;; -get-id, -get-parent-id, -get-left-id return block-id
 ;; -get-id, -get-parent-id, -get-left-id return block-id
 ;; the :block/parent, :block/left should be datascript lookup ref
 ;; the :block/parent, :block/left should be datascript lookup ref
@@ -96,8 +97,8 @@
          (if uuid
          (if uuid
            uuid
            uuid
            (let [new-id (db/new-block-id)]
            (let [new-id (db/new-block-id)]
-             (db/transact! {:db/id db-id
-                            :block/uuid new-id})
+             (db/transact! [{:db/id db-id
+                             :block/uuid new-id}])
              new-id))))))
              new-id))))))
 
 
   (-get-parent-id [this]
   (-get-parent-id [this]
@@ -243,17 +244,18 @@
   "Insert a node as sibling."
   "Insert a node as sibling."
   [txs-state new-node left-node]
   [txs-state new-node left-node]
   {:pre [(every? tree/satisfied-inode? [new-node left-node])]}
   {:pre [(every? tree/satisfied-inode? [new-node left-node])]}
-  (let [node (-> (tree/-set-left-id new-node (tree/-get-id left-node))
-               (tree/-set-parent-id (tree/-get-parent-id left-node)))
-        right-node (tree/-get-right left-node)]
-    (if (tree/satisfied-inode? right-node)
-      (let [new-right-node (tree/-set-left-id right-node (tree/-get-id new-node))
-            saved-new-node (tree/-save node txs-state)]
-        (tree/-save new-right-node txs-state)
-        [saved-new-node new-right-node])
-      (do
-        (tree/-save node txs-state)
-        [node]))))
+  (when-let [left-id (tree/-get-id left-node)]
+    (let [node (-> (tree/-set-left-id new-node left-id)
+                   (tree/-set-parent-id (tree/-get-parent-id left-node)))
+          right-node (tree/-get-right left-node)]
+      (if (tree/satisfied-inode? right-node)
+        (let [new-right-node (tree/-set-left-id right-node (tree/-get-id new-node))
+              saved-new-node (tree/-save node txs-state)]
+          (tree/-save new-right-node txs-state)
+          [saved-new-node new-right-node])
+        (do
+          (tree/-save node txs-state)
+          [node])))))
 
 
 
 
 (defn- insert-node-aux
 (defn- insert-node-aux

+ 4 - 1
src/main/frontend/modules/shortcut/config.cljs

@@ -4,6 +4,7 @@
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.history :as history]
             [frontend.handler.history :as history]
             [frontend.handler.repo :as repo-handler]
             [frontend.handler.repo :as repo-handler]
+            [frontend.handler.page :as page-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.search :as search-handler]
             [frontend.handler.search :as search-handler]
             [frontend.handler.ui :as ui-handler]
             [frontend.handler.ui :as ui-handler]
@@ -303,7 +304,9 @@
     :graph/re-index
     :graph/re-index
     {:desc    "Re-index the whole graph"
     {:desc    "Re-index the whole graph"
      :binding "mod+c mod+r"
      :binding "mod+c mod+r"
-     :fn      #(repo-handler/re-index! nfs-handler/rebuild-index!)}}
+     :fn      #(repo-handler/re-index!
+                nfs-handler/rebuild-index!
+                page-handler/create-today-journal!)}}
 
 
    :shortcut.handler/misc
    :shortcut.handler/misc
    ;; always overrides the copy due to "mod+c mod+s"
    ;; always overrides the copy due to "mod+c mod+s"

+ 10 - 0
src/main/frontend/state.cljs

@@ -144,6 +144,9 @@
       ;; copied blocks
       ;; copied blocks
       :copy/blocks {:copy/content nil :copy/block-tree nil}
       :copy/blocks {:copy/content nil :copy/block-tree nil}
 
 
+      :copy/export-block-text-indent-style  (atom "dashes")
+      :copy/export-block-text-remove-options (atom #{})
+
       :date-picker/date nil
       :date-picker/date nil
 
 
       :view/components {}})))
       :view/components {}})))
@@ -1350,6 +1353,13 @@
   [content ids]
   [content ids]
   (set-state! :copy/blocks {:copy/content content :copy/block-tree ids}))
   (set-state! :copy/blocks {:copy/content content :copy/block-tree ids}))
 
 
+(defn get-export-block-text-indent-style []
+  (:copy/export-block-text-indent-style @state))
+
+(defn get-export-block-text-remove-options []
+  (:copy/export-block-text-remove-options @state))
+
+
 (defn set-editor-args!
 (defn set-editor-args!
   [args]
   [args]
   (set-state! :editor/args args))
   (set-state! :editor/args args))

+ 25 - 9
src/main/frontend/ui.cljs

@@ -5,6 +5,7 @@
             ["react-textarea-autosize" :as TextareaAutosize]
             ["react-textarea-autosize" :as TextareaAutosize]
             ["react-resize-context" :as Resize]
             ["react-resize-context" :as Resize]
             ["react-tippy" :as react-tippy]
             ["react-tippy" :as react-tippy]
+            ["react-tweet-embed" :as react-tweet-embed]
             [frontend.util :as util]
             [frontend.util :as util]
             [frontend.mixins :as mixins]
             [frontend.mixins :as mixins]
             [frontend.handler.notification :as notification-handler]
             [frontend.handler.notification :as notification-handler]
@@ -27,6 +28,7 @@
 (def resize-provider (r/adapt-class (gobj/get Resize "ResizeProvider")))
 (def resize-provider (r/adapt-class (gobj/get Resize "ResizeProvider")))
 (def resize-consumer (r/adapt-class (gobj/get Resize "ResizeConsumer")))
 (def resize-consumer (r/adapt-class (gobj/get Resize "ResizeConsumer")))
 (def Tippy (r/adapt-class (gobj/get react-tippy "Tooltip")))
 (def Tippy (r/adapt-class (gobj/get react-tippy "Tooltip")))
+(def ReactTweetEmbed (r/adapt-class react-tweet-embed))
 
 
 (rum/defc ls-textarea < rum/reactive
 (rum/defc ls-textarea < rum/reactive
   [{:keys [on-change] :as props}]
   [{:keys [on-change] :as props}]
@@ -652,19 +654,23 @@
                     :trigger (if manual "manual" "mouseenter focus")
                     :trigger (if manual "manual" "mouseenter focus")
                     ;; See https://github.com/tvkhoa/react-tippy/issues/13
                     ;; See https://github.com/tvkhoa/react-tippy/issues/13
                     :popperOptions (if fixed-position?
                     :popperOptions (if fixed-position?
-                                      {:modifiers {:flip {:enabled false}
-                                                   :hide {:enabled false}
-                                                   :preventOverflow {:enabled false}}}
-                                      {})
+                                     {:modifiers {:flip {:enabled false}
+                                                  :hide {:enabled false}
+                                                  :preventOverflow {:enabled false}}}
+                                     {})
                     :onShow #(reset! *mounted? true)
                     :onShow #(reset! *mounted? true)
                     :onHide #(reset! *mounted? false)}
                     :onHide #(reset! *mounted? false)}
                    opts)
                    opts)
             (assoc :html (if (or open? mounted?)
             (assoc :html (if (or open? mounted?)
-                           (when-let [html (:html opts)]
-                             (if (fn? html)
-                               (html)
-                               [:div.pr-3.py-1
-                                html]))
+                           (try
+                             (when-let [html (:html opts)]
+                              (if (fn? html)
+                                (html)
+                                [:div.pr-3.py-1
+                                 html]))
+                             (catch js/Error e
+                               (log/error :exception e)
+                               [:div]))
                            [:div {:key "tippy"} ""])))
                            [:div {:key "tippy"} ""])))
            child)))
            child)))
 
 
@@ -678,3 +684,13 @@
     :style {:width "100%"}
     :style {:width "100%"}
     :on-change #(let [value (util/evalue %)]
     :on-change #(let [value (util/evalue %)]
                   (on-change value))}])
                   (on-change value))}])
+
+(rum/defcs tweet-embed < (rum/local true :loading?)
+  [state id]
+  (let [*loading? (:loading? state)]
+    [:div [(when @*loading? [:span.flex.items-center [svg/loading " ... loading"]])
+           (ReactTweetEmbed
+             {:id                    id
+              :class                 "contents"
+              :options               {:theme (when (= (state/sub :ui/theme) "dark") "dark")}
+              :on-tweet-load-success #(reset! *loading? false)})]]))

+ 4 - 0
src/main/frontend/util.cljc

@@ -90,6 +90,10 @@
    (defn ekey [event]
    (defn ekey [event]
      (gobj/getValueByKeys event "key")))
      (gobj/getValueByKeys event "key")))
 
 
+#?(:cljs
+   (defn echecked? [event]
+     (gobj/getValueByKeys event "target" "checked")))
+
 #?(:cljs
 #?(:cljs
    (defn set-change-value
    (defn set-change-value
      "compatible change event for React"
      "compatible change event for React"

+ 7 - 3
src/main/frontend/util/property.cljs

@@ -20,7 +20,7 @@
 (defn built-in-properties
 (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 :query-sort-by :query-sort-desc}
    (set (map keyword config/markers))
    (set (map keyword config/markers))
    @built-in-extended-properties))
    @built-in-extended-properties))
 
 
@@ -89,8 +89,11 @@
 
 
       (not org?)
       (not org?)
       (let [lines (string/split-lines content)
       (let [lines (string/split-lines content)
-            non-properties (get (group-by simplified-property? lines) false)]
-        (string/join "\n" non-properties))
+            lines (if (simplified-property? (first lines))
+                    (drop-while simplified-property? lines)
+                    (cons (first lines)
+                          (drop-while simplified-property? (rest lines))))]
+        (string/join "\n" lines))
 
 
       :else
       :else
       content)))
       content)))
@@ -271,6 +274,7 @@
   [format content]
   [format content]
   (remove-property format "id" content false))
   (remove-property format "id" content false))
 
 
+;; FIXME: only remove from the properties area
 (defn remove-built-in-properties
 (defn remove-built-in-properties
   [format content]
   [format content]
   (let [built-in-properties* (built-in-properties)
   (let [built-in-properties* (built-in-properties)

+ 10 - 2
src/test/frontend/util/property_test.cljs

@@ -42,10 +42,18 @@
       "** hello"
       "** hello"
 
 
       (property/remove-properties :org "** hello\n:PROPERTIES:\n:x: y\n\na:b\n:END:\n")
       (property/remove-properties :org "** hello\n:PROPERTIES:\n:x: y\n\na:b\n:END:\n")
-      "** hello"
+      "** hello"))
+
+  (testing "invalid-properties"
+    (are [x y] (= x y)
+      (property/remove-properties :markdown "hello\nnice\nfoo:: bar")
+      "hello\nnice\nfoo:: bar"
+
+      (property/remove-properties :markdown "hello\nnice\nfoo:: bar\ntest")
+      "hello\nnice\nfoo:: bar\ntest"
 
 
       (property/remove-properties :markdown "** hello\nx:: y\n\na:: b\n")
       (property/remove-properties :markdown "** hello\nx:: y\n\na:: b\n")
-      "** hello\n")))
+      "** hello\n\na:: b")))
 
 
 (deftest test-insert-property
 (deftest test-insert-property
   (are [x y] (= x y)
   (are [x y] (= x y)

+ 13 - 10
yarn.lock

@@ -6165,10 +6165,10 @@ mkdirp@^0.5.0, mkdirp@^0.5.4, mkdirp@~0.5.1:
   dependencies:
   dependencies:
     minimist "^1.2.5"
     minimist "^1.2.5"
 
 
[email protected].2:
-  version "0.9.2"
-  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-0.9.2.tgz#0d88a049bb9564a1567134178b2dea9196f30148"
-  integrity sha512-e1JFKKkX6IYHFP8XwN0pqcEn2L8biVHWXGUyaUU8RHsCq2poN1fPIAZ5waosS4EffC+CQk68PycEhCobYwbndA==
[email protected].4:
+  version "0.9.4"
+  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-0.9.4.tgz#80dd027e06a297ef4bbbabd28793a40f64bcb451"
+  integrity sha512-Pt994A4XGG1rDdU5tvR8quk1WdlD0eTmo+UWo37qndLaHFxt++lTT7UK8WX3cj0HamJlx8WiYWQO3gOWIzL+dw==
   dependencies:
   dependencies:
     yargs "^12.0.2"
     yargs "^12.0.2"
 
 
@@ -6891,10 +6891,10 @@ pinkie@^2.0.0:
   resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz"
   resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz"
   integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
   integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
 
 
-pixi-graph-fork@^0.1.3:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/pixi-graph-fork/-/pixi-graph-fork-0.1.3.tgz#fc7beee363ba3ec71b35df30fce1d5b2ddf27732"
-  integrity sha512-NHmlG0FI2/xme/p9KXOPLbfrQ0UIcCq4GK36IsSYPGJznhUoJTlNbfT4ML7I3DL84vQx0TliGPAA+EmoVz6CDg==
+pixi-graph-fork@^0.1.4:
+  version "0.1.4"
+  resolved "https://registry.yarnpkg.com/pixi-graph-fork/-/pixi-graph-fork-0.1.4.tgz#9191daa6512e7440c4a767c6d7bcef547a33a5a2"
+  integrity sha512-qR8MJ/q1TL812LuRqaGjHA6xIkZomOINZGH+7tKMA15feow1ud+tzFVb1pKsnvmSy/uWhhOUOVLrqLTf3vYr3Q==
   dependencies:
   dependencies:
     "@pixi-essentials/cull" "^1.1.0"
     "@pixi-essentials/cull" "^1.1.0"
     "@pixi/app" "^6.0.2"
     "@pixi/app" "^6.0.2"
@@ -7607,8 +7607,6 @@ react-icons@^2.2.7:
   version "2.2.7"
   version "2.2.7"
   resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-2.2.7.tgz#d7860826b258557510dac10680abea5ca23cf650"
   resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-2.2.7.tgz#d7860826b258557510dac10680abea5ca23cf650"
   integrity sha512-0n4lcGqzJFcIQLoQytLdJCE0DKSA9dkwEZRYoGrIDJZFvIT6Hbajx5mv9geqhqFiNjUgtxg8kPyDfjlhymbGFg==
   integrity sha512-0n4lcGqzJFcIQLoQytLdJCE0DKSA9dkwEZRYoGrIDJZFvIT6Hbajx5mv9geqhqFiNjUgtxg8kPyDfjlhymbGFg==
-  dependencies:
-    react-icon-base "2.1.0"
 
 
 react-is@^16.3.1, react-is@^16.8.1:
 react-is@^16.3.1, react-is@^16.8.1:
   version "16.13.1"
   version "16.13.1"
@@ -7664,6 +7662,11 @@ react-transition-group@^4.3.0:
     loose-envify "^1.4.0"
     loose-envify "^1.4.0"
     prop-types "^15.6.2"
     prop-types "^15.6.2"
 
 
+react-tweet-embed@^1.2.2:
+  version "1.2.2"
+  resolved "https://registry.yarnpkg.com/react-tweet-embed/-/react-tweet-embed-1.2.2.tgz#b518510a6e6ef17609f9c9b16bc4775624730d8a"
+  integrity sha512-Y932BlSaJsDUsKDucC2opzzd+uhc0YNhrlTa/4Beb2be1od+AjLGo6Fhuo2wPT0D+fF4VTXOyoZyA8Yc88RdYA==
+
 react@^17.0.2:
 react@^17.0.2:
   version "17.0.2"
   version "17.0.2"
   resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
   resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"