Sfoglia il codice sorgente

Merge remote-tracking branch 'upstream/master' into whiteboards

Peng Xiao 3 anni fa
parent
commit
050cea4b35

+ 106 - 65
src/main/frontend/components/block.cljs

@@ -246,6 +246,34 @@
           [:p.text-red-500.text-xs [:small.opacity-80
           [:p.text-red-500.text-xs [:small.opacity-80
                                     (util/format "%s not found!" (string/capitalize type))]])))))
                                     (util/format "%s not found!" (string/capitalize type))]])))))
 
 
+(defn open-lightbox
+  [e]
+  (let [images (js/document.querySelectorAll ".asset-container img")
+        images (to-array images)
+        images (if-not (= (count images) 1)
+                 (let [^js _image (.closest (.-target e) ".asset-container")
+                       image (. _image querySelector "img")]
+                   (->> images
+                        (sort-by (juxt #(.-y %) #(.-x %)))
+                        (split-with (complement #{image}))
+                        reverse
+                        (apply concat)))
+                 images)
+        images (for [^js it images] {:src (.-src it)
+                                     :w (.-naturalWidth it)
+                                     :h (.-naturalHeight it)})]
+
+    (when (seq images)
+      (lightbox/preview-images! images))))
+
+(defn copy-image-to-clipboard
+  [src]
+  (-> (js/fetch src)
+      (.then (fn [data]
+               (-> (.blob data)
+                   (.then (fn [blob]
+                            (js/navigator.clipboard.write (clj->js [(js/ClipboardItem. (clj->js {(.-type blob) blob}))])))))))))
+
 (defonce *resizing-image? (atom false))
 (defonce *resizing-image? (atom false))
 (rum/defcs resizable-image <
 (rum/defcs resizable-image <
   (rum/local nil ::size)
   (rum/local nil ::size)
@@ -258,25 +286,25 @@
      (ui/resize-consumer
      (ui/resize-consumer
       (if-not (mobile-util/native-ios?)
       (if-not (mobile-util/native-ios?)
         (cond->
         (cond->
-            {:className "resize image-resize"
-             :onSizeChanged (fn [value]
-                              (when (and (not @*resizing-image?)
-                                         (some? @size)
-                                         (not= value @size))
-                                (reset! *resizing-image? true))
-                              (reset! size value))
-             :onMouseUp (fn []
-                          (when (and @size @*resizing-image?)
-                            (when-let [block-id (:block/uuid config)]
-                              (let [size (bean/->clj @size)]
-                                (editor-handler/resize-image! block-id metadata full_text size))))
-                          (when @*resizing-image?
+         {:className "resize image-resize"
+          :onSizeChanged (fn [value]
+                           (when (and (not @*resizing-image?)
+                                      (some? @size)
+                                      (not= value @size))
+                             (reset! *resizing-image? true))
+                           (reset! size value))
+          :onMouseUp (fn []
+                       (when (and @size @*resizing-image?)
+                         (when-let [block-id (:block/uuid config)]
+                           (let [size (bean/->clj @size)]
+                             (editor-handler/resize-image! block-id metadata full_text size))))
+                       (when @*resizing-image?
                             ;; TODO: need a better way to prevent the clicking to edit current block
                             ;; TODO: need a better way to prevent the clicking to edit current block
-                            (js/setTimeout #(reset! *resizing-image? false) 200)))
-             :onClick (fn [e]
-                        (when @*resizing-image? (util/stop e)))}
-            (and (:width metadata) (not (util/mobile?)))
-            (assoc :style {:width (:width metadata)}))
+                         (js/setTimeout #(reset! *resizing-image? false) 200)))
+          :onClick (fn [e]
+                     (when @*resizing-image? (util/stop e)))}
+          (and (:width metadata) (not (util/mobile?)))
+          (assoc :style {:width (:width metadata)}))
         {})
         {})
       [:div.asset-container {:key "resize-asset-container"}
       [:div.asset-container {:key "resize-asset-container"}
        [:img.rounded-sm.shadow-xl.relative
        [:img.rounded-sm.shadow-xl.relative
@@ -285,51 +313,62 @@
           :src     src
           :src     src
           :title   title}
           :title   title}
          metadata)]
          metadata)]
-       [:span.ctl
-        [:a.delete
-         {:title "Delete this image"
-          :on-click
-          (fn [e]
-            (when-let [block-id (:block/uuid config)]
-              (let [confirm-fn (ui/make-confirm-modal
-                                {:title         (t :asset/confirm-delete (.toLocaleLowerCase (t :text/image)))
-                                 :sub-title     (if local? :asset/physical-delete "")
-                                 :sub-checkbox? local?
-                                 :on-confirm    (fn [_e {:keys [close-fn sub-selected]}]
-                                                  (close-fn)
-                                                  (editor-handler/delete-asset-of-block!
-                                                   {:block-id    block-id
-                                                    :local?      local?
-                                                    :delete-local? (and sub-selected (first sub-selected))
-                                                    :repo        (state/get-current-repo)
-                                                    :href        src
-                                                    :title       title
-                                                    :full-text   full_text}))})]
-                (state/set-modal! confirm-fn)
-                (util/stop e))))}
-         svg/trash-sm]
-
-        [:a.delete.ml-1
-         {:title    "maximize image"
-          :on-click (fn [^js e] (let [images (js/document.querySelectorAll ".asset-container img")
-                                      images (to-array images)
-                                      images (if-not (= (count images) 1)
-                                               (let [^js _image (.closest (.-target e) ".asset-container")
-                                                     image (. _image querySelector "img")]
-                                                 (->> images
-                                                      (sort-by (juxt #(.-y %) #(.-x %)))
-                                                      (split-with (complement #{image}))
-                                                      reverse
-                                                      (apply concat)))
-                                               images)
-                                      images (for [^js it images] {:src (.-src it)
-                                                                   :w (.-naturalWidth it)
-                                                                   :h (.-naturalHeight it)})]
-
-                                  (when (seq images)
-                                    (lightbox/preview-images! images))))}
-
-         (svg/maximize)]]]))))
+       [:.asset-overlay]
+       (let [image-src (string/replace src #"^assets://" "")]
+         [:.asset-action-bar {:aria-hidden "true"}
+          (when (util/electron?)
+            [:button.asset-action-btn.text-left
+             {:title (t (if local? :asset/show-in-folder :asset/open-in-browser))
+              :tabIndex "-1"
+              :on-mouse-down util/stop
+              :on-click (fn [e]
+                          (util/stop e)
+                          (if local?
+                            (js/window.apis.showItemInFolder image-src)
+                            (js/window.apis.openExternal image-src)))}
+             image-src])
+          [:.flex
+           [:button.asset-action-btn
+            {:title (t :asset/delete)
+             :tabIndex "-1"
+             :on-mouse-down util/stop
+             :on-click
+             (fn [e]
+               (when-let [block-id (:block/uuid config)]
+                 (let [confirm-fn (ui/make-confirm-modal
+                                   {:title         (t :asset/confirm-delete (.toLocaleLowerCase (t :text/image)))
+                                    :sub-title     (if local? :asset/physical-delete "")
+                                    :sub-checkbox? local?
+                                    :on-confirm    (fn [_e {:keys [close-fn sub-selected]}]
+                                                     (close-fn)
+                                                     (editor-handler/delete-asset-of-block!
+                                                      {:block-id    block-id
+                                                       :local?      local?
+                                                       :delete-local? (and sub-selected (first sub-selected))
+                                                       :repo        (state/get-current-repo)
+                                                       :href        src
+                                                       :title       title
+                                                       :full-text   full_text}))})]
+                   (util/stop e)
+                   (state/set-modal! confirm-fn))))}
+            (ui/icon "trash")]
+
+           [:button.asset-action-btn
+            {:title (t :asset/copy)
+             :tabIndex "-1"
+             :on-mouse-down util/stop
+             :on-click (fn [e]
+                         (util/stop e)
+                         (copy-image-to-clipboard image-src))}
+            (ui/icon "copy")]
+
+           [:button.asset-action-btn
+            {:title (t :asset/maximize)
+             :tabIndex "-1"
+             :on-mouse-down util/stop
+             :on-click open-lightbox}
+
+            (ui/icon "maximize")]]])]))))
 
 
 (rum/defc audio-cp [src]
 (rum/defc audio-cp [src]
   [:audio {:src src
   [:audio {:src src
@@ -1167,7 +1206,7 @@
 ;;;; Macro component render functions
 ;;;; Macro component render functions
 (defn- macro-query-cp
 (defn- macro-query-cp
   [config arguments]
   [config arguments]
-  [:div.dsl-query.overflow-x-hidden.pr-3.sm:pr-0
+  [:div.dsl-query.pr-3.sm:pr-0
    (let [query (->> (string/join ", " arguments)
    (let [query (->> (string/join ", " arguments)
                     (string/trim))]
                     (string/trim))]
      (when-not (string/blank? query)
      (when-not (string/blank? query)
@@ -1900,7 +1939,9 @@
         user-config (state/get-config)
         user-config (state/get-config)
         ;; In this mode and when value is a set of refs, display full property text
         ;; In this mode and when value is a set of refs, display full property text
         ;; because :block/properties value only contains refs but user wants to see text
         ;; because :block/properties value only contains refs but user wants to see text
-        v (if (and (:rich-property-values? user-config) (coll? value))
+        v (if (and (:rich-property-values? user-config)
+                   (coll? value)
+                   (not (contains? gp-property/editable-linkable-built-in-properties k)))
             (gp-property/property-value-from-content (name k) (:block/content block))
             (gp-property/property-value-from-content (name k) (:block/content block))
             value)
             value)
         property-pages-enabled? (contains? #{true nil} (:property-pages/enabled? user-config))]
         property-pages-enabled? (contains? #{true nil} (:property-pages/enabled? user-config))]

+ 34 - 34
src/main/frontend/components/block.css

@@ -36,47 +36,47 @@
   }
   }
 
 
   .asset-container {
   .asset-container {
-    display: inline-block;
-    position: relative;
+    @apply relative inline-block;
+
     margin-top: 0.5rem;
     margin-top: 0.5rem;
 
 
-    .ctl {
-      position: absolute;
-      top: 0;
-      right: 0;
-      padding: 5px;
-      z-index: 1;
-      display: none;
-
-      > a {
-        padding: 3px;
-        border-radius: 4px;
-        opacity: 0.4;
-        user-select: none;
-        background: var(--ls-primary-background-color);
-
-        &.delete {
-          svg {
-            color: var(--ls-primary-text-color);
-
-            opacity: 0.5;
-            font-weight: normal;
-          }
-        }
+    .asset-overlay {
+      @apply inset-0 absolute p-2;
 
 
-        &:hover {
-          opacity: 1;
-        }
+      opacity: 0;
+      transition: opacity 300ms;
+      background-image: linear-gradient(var(--ls-primary-background-color), transparent);
+      pointer-events: none;
+    }
 
 
-        &:active {
-          opacity: 1;
-        }
+    .asset-action-bar {
+      @apply top-0 left-0 w-full flex absolute items-start justify-between px-1;
+
+      transition: opacity 300ms;
+      opacity: 0;
+      color: var(--ls-primary-text-color);
+    }
+
+    .asset-action-btn {
+      @apply m-1 p-1 rounded truncate;
+
+      opacity: 0.8;
+      user-select: none;
+
+      &:hover,
+      &:active {
+        opacity: 1;
       }
       }
     }
     }
 
 
-    &:hover {
-      .ctl {
-        display: flex;
+    &:hover,
+    &:focus {
+      .asset-overlay {
+        opacity: 0.9;
+      }
+
+      .asset-action-bar {
+        opacity: 1;
       }
       }
     }
     }
   }
   }

+ 3 - 4
src/main/frontend/components/sidebar.css

@@ -85,7 +85,7 @@
   overflow-x: hidden;
   overflow-x: hidden;
   background-color: var(--ls-primary-background-color);
   background-color: var(--ls-primary-background-color);
   transition: transform .3s;
   transition: transform .3s;
-  transform: translateX(-100%);
+  transform: translate3d(-100%, 0, 0);
   z-index: 3;
   z-index: 3;
 
 
   -webkit-font-smoothing: antialiased;
   -webkit-font-smoothing: antialiased;
@@ -128,7 +128,7 @@
 
 
   a.item {
   a.item {
     @apply px-2 py-2 sm:py-1.5;
     @apply px-2 py-2 sm:py-1.5;
-    
+
     user-select: none;
     user-select: none;
     transition: background-color .3s;
     transition: background-color .3s;
 
 
@@ -328,7 +328,7 @@
     width: 100%;
     width: 100%;
 
 
     .left-sidebar-inner {
     .left-sidebar-inner {
-      transform: translateX(0);
+      transform: translate3d(0, 0, 0);
       overflow: visible;
       overflow: visible;
     }
     }
 
 
@@ -559,4 +559,3 @@ html[data-theme='dark'] {
 .full-height-without-header {
 .full-height-without-header {
   height: calc(100vh - var(--ls-headbar-height) - 4rem);
   height: calc(100vh - var(--ls-headbar-height) - 4rem);
 }
 }
-

+ 1 - 12
src/main/frontend/components/svg.cljs

@@ -59,8 +59,7 @@
 (def folder (hero-icon "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"))
 (def folder (hero-icon "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"))
 (def settings-sm [:svg {:viewBox "0 0 20 20", :fill "currentColor", :height "20", :width "20"}
 (def settings-sm [:svg {:viewBox "0 0 20 20", :fill "currentColor", :height "20", :width "20"}
                   [:path {:fill-rule "evenodd", :d "M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z", :clip-rule "evenodd"}]])
                   [:path {:fill-rule "evenodd", :d "M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z", :clip-rule "evenodd"}]])
-(def trash-sm [:svg {:viewBox "0 0 20 20", :fill "currentColor", :height "16", :width "16"}
-               [:path {:fill-rule "evenodd", :d "M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z", :clip-rule "evenodd"}]])
+
 (def external-link
 (def external-link
   [:svg {:fill   "none", :view-box "0 0 24 24", :height "21", :width "21"
   [:svg {:fill   "none", :view-box "0 0 24 24", :height "21", :width "21"
          :stroke "currentColor"}
          :stroke "currentColor"}
@@ -358,16 +357,6 @@
     [:line {:x1 "16" :y1 "15" :x2 "12" :y2 "19"}]
     [:line {:x1 "16" :y1 "15" :x2 "12" :y2 "19"}]
     [:line {:x1 "8" :y1 "15" :x2 "12" :y2 "19"}]]))
     [:line {:x1 "8" :y1 "15" :x2 "12" :y2 "19"}]]))
 
 
-(defn maximize
-  ([] (maximize 16))
-  ([size]
-   [:svg.icon {:width size :height size :viewBox "0 0 24 24" :stroke-width "2" :stroke "currentColor" :fill "none" :stroke-linecap "round" :stroke-linejoin "round"}
-    [:path {:stroke "none" :d "M0 0h24v24H0z" :fill "none"}]
-    [:path {:d "M4 8v-2a2 2 0 0 1 2 -2h2"}]
-    [:path {:d "M4 16v2a2 2 0 0 0 2 2h2"}]
-    [:path {:d "M16 4h2a2 2 0 0 1 2 2v2"}]
-    [:path {:d "M16 20h2a2 2 0 0 0 2 -2v-2"}]]))
-
 (defn help-circle
 (defn help-circle
   ([] (help-circle 16))
   ([] (help-circle 16))
   ([size]
   ([size]

+ 2 - 1
src/main/frontend/core.cljs

@@ -45,7 +45,8 @@
     (set-router!)
     (set-router!)
     (rum/mount (page/current-page) node)
     (rum/mount (page/current-page) node)
     (display-welcome-message)
     (display-welcome-message)
-    (persist-var/load-vars)))
+    (persist-var/load-vars)
+    (js/setTimeout #(sync/sync-start) 1000)))
 
 
 (defn ^:export init []
 (defn ^:export init []
   ;; init is called ONCE when the page loads
   ;; init is called ONCE when the page loads

+ 5 - 0
src/main/frontend/dicts.cljc

@@ -134,6 +134,11 @@
         :draw/more-options "More options"
         :draw/more-options "More options"
         :draw/back-to-logseq "Back to logseq"
         :draw/back-to-logseq "Back to logseq"
         :text/image "Image"
         :text/image "Image"
+        :asset/show-in-folder "Show image in folder"
+        :asset/open-in-browser "Open image in browser"
+        :asset/delete "Delete image"
+        :asset/copy "Copy image"
+        :asset/maximize "Maximize image"
         :asset/confirm-delete "Are you sure you want to delete this {1}?"
         :asset/confirm-delete "Are you sure you want to delete this {1}?"
         :asset/physical-delete "Remove the file too (notice it can't be restored)"
         :asset/physical-delete "Remove the file too (notice it can't be restored)"
         :content/copy "Copy"
         :content/copy "Copy"

+ 43 - 24
src/main/frontend/fs/sync.cljs

@@ -26,7 +26,8 @@
             [frontend.fs :as fs]
             [frontend.fs :as fs]
             [frontend.encrypt :as encrypt]
             [frontend.encrypt :as encrypt]
             [medley.core :refer [dedupe-by]]
             [medley.core :refer [dedupe-by]]
-            [rum.core :as rum]))
+            [rum.core :as rum]
+            [goog.object :as gobj]))
 
 
 ;;; ### Commentary
 ;;; ### Commentary
 ;; file-sync related local files/dirs:
 ;; file-sync related local files/dirs:
@@ -485,7 +486,7 @@
    (diffs->partitioned-filetxns n)))
    (diffs->partitioned-filetxns n)))
 
 
 
 
-(defrecord FileMetadata [size etag path encrypted-path last-modified remote? ^:mutable normalized-path]
+(deftype FileMetadata [size etag path encrypted-path last-modified remote? ^:mutable normalized-path]
   Object
   Object
   (get-normalized-path [_]
   (get-normalized-path [_]
     (when-not normalized-path
     (when-not normalized-path
@@ -496,7 +497,27 @@
     normalized-path)
     normalized-path)
 
 
   IRelativePath
   IRelativePath
-  (-relative-path [_] path))
+  (-relative-path [_] path)
+
+  IEquiv
+  (-equiv [o ^FileMetadata other]
+    (and (= (.get-normalized-path o) (.get-normalized-path other))
+         (= etag (.-etag other))))
+
+  IHash
+  (-hash [_] (hash {:etag etag :path path}))
+
+  ILookup
+  (-lookup [this k]
+    (gobj/get this (name k)))
+  (-lookup [this k not-found]
+    (or (gobj/get this (name k)) not-found))
+
+  IPrintWithWriter
+  (-pr-writer [_ w _opts]
+    (write-all w (str {:size size :etag etag :path path :remote? remote?}))))
+
+
 
 
 (def ^:private higher-priority-remote-files
 (def ^:private higher-priority-remote-files
   "when diff all remote files and local files, following remote files always need to download(when checksum not matched),
   "when diff all remote files and local files, following remote files always need to download(when checksum not matched),
@@ -539,6 +560,9 @@
    #{} s1))
    #{} s1))
 
 
 (comment
 (comment
+  (defn map->FileMetadata [m]
+    (apply ->FileMetadata ((juxt :size :etag :path :encrypted-path :last-modified :remote? (constantly nil)) m)))
+
   (assert
   (assert
    (=
    (=
     #{(map->FileMetadata {:size 1 :etag 2 :path 2 :encrypted-path 2 :last-modified 2})}
     #{(map->FileMetadata {:size 1 :etag 2 :path 2 :encrypted-path 2 :last-modified 2})}
@@ -2721,27 +2745,22 @@
         (when-some [sm (sync-manager-singleton current-user-uuid graph-uuid
         (when-some [sm (sync-manager-singleton current-user-uuid graph-uuid
                                                (config/get-repo-dir repo) repo
                                                (config/get-repo-dir repo) repo
                                                txid *sync-state)]
                                                txid *sync-state)]
-          ;; 1. if remote graph has been deleted, clear graphs-txid.edn
-          ;; 2. if graphs-txid.edn's content isn't [user-uuid graph-uuid txid], clear it
-          (if (not= 3 (count @graphs-txid))
-            (do (clear-graphs-txid! repo)
-                (state/set-file-sync-state repo nil))
-            (when (check-graph-belong-to-current-user current-user-uuid user-uuid)
-              (if-not (<! (<check-remote-graph-exists graph-uuid))
-                (clear-graphs-txid! repo)
-                (do
-                  (state/set-file-sync-state repo @*sync-state)
-                  (state/set-file-sync-manager sm)
-
-                  ;; update global state when *sync-state changes
-                  (add-watch *sync-state ::update-global-state
-                             (fn [_ _ _ n]
-                               (state/set-file-sync-state repo n)))
-
-                  (.start sm)
-
-                  (offer! remote->local-full-sync-chan true)
-                  (offer! full-sync-chan true))))))))))
+          (when (check-graph-belong-to-current-user current-user-uuid user-uuid)
+            (if-not (<! (<check-remote-graph-exists graph-uuid)) ; remote graph has been deleted
+              (clear-graphs-txid! repo)
+              (do
+                (state/set-file-sync-state repo @*sync-state)
+                (state/set-file-sync-manager sm)
+
+                ;; update global state when *sync-state changes
+                (add-watch *sync-state ::update-global-state
+                           (fn [_ _ _ n]
+                             (state/set-file-sync-state repo n)))
+
+                (.start sm)
+
+                (offer! remote->local-full-sync-chan true)
+                (offer! full-sync-chan true)))))))))
 
 
 ;;; ### some add-watches
 ;;; ### some add-watches
 
 

+ 4 - 4
src/main/frontend/handler/page.cljs

@@ -65,10 +65,10 @@
          (:file/path (:block/file page)))))))
          (:file/path (:block/file page)))))))
 
 
 (defn- build-title [page]
 (defn- build-title [page]
-  (let [original-name (:block/original-name page)]
-    (if (string/includes? original-name ",")
-      (util/format "\"%s\"" original-name)
-      original-name)))
+  ;; Don't wrap `\"` anymore, as tiitle property is not effected by `,` now
+  ;; The previous extract behavior isn't unwrapping the `'"` either. So no need
+  ;; to maintain the compatibility.
+  (:block/original-name page))
 
 
 (defn default-properties-block
 (defn default-properties-block
   ([title format page]
   ([title format page]

+ 5 - 4
src/main/frontend/modules/file/core.cljs

@@ -16,19 +16,20 @@
 
 
 (defn- content-with-collapsed-state
 (defn- content-with-collapsed-state
   "Only accept nake content (without any indentation)"
   "Only accept nake content (without any indentation)"
-  [format content collapsed? properties]
+  [format content collapsed?]
   (cond
   (cond
     collapsed?
     collapsed?
     (property/insert-property format content :collapsed true)
     (property/insert-property format content :collapsed true)
 
 
-    (and (:collapsed properties) (false? collapsed?))
+    ;; Don't check properties. Collapsed is an internal state log as property in file, but not counted into properties
+    (false? collapsed?)
     (property/remove-property format :collapsed content)
     (property/remove-property format :collapsed content)
 
 
     :else
     :else
     content))
     content))
 
 
 (defn transform-content
 (defn transform-content
-  [{:block/keys [collapsed? format pre-block? unordered content heading-level left page parent properties]} level {:keys [heading-to-list?]}]
+  [{:block/keys [collapsed? format pre-block? unordered content heading-level left page parent]} level {:keys [heading-to-list?]}]
   (let [content (or content "")
   (let [content (or content "")
         pre-block? (or pre-block?
         pre-block? (or pre-block?
                        (and (= page parent left) ; first block
                        (and (= page parent left) ; first block
@@ -69,7 +70,7 @@
                                   (-> (string/replace content #"^\s?#+\s+" "")
                                   (-> (string/replace content #"^\s?#+\s+" "")
                                       (string/replace #"^\s?#+\s?$" ""))
                                       (string/replace #"^\s?#+\s?$" ""))
                                   content)
                                   content)
-                        content (content-with-collapsed-state format content collapsed? properties)
+                        content (content-with-collapsed-state format content collapsed?)
                         new-content (indented-block-content (string/trim content) spaces-tabs)
                         new-content (indented-block-content (string/trim content) spaces-tabs)
                         sep (if (or markdown-top-heading?
                         sep (if (or markdown-top-heading?
                                     (string/blank? new-content))
                                     (string/blank? new-content))