Browse Source

feat: add image resize support

Tienson Qin 4 years ago
parent
commit
6c32bbdb27

+ 1 - 0
package.json

@@ -59,6 +59,7 @@
         "mousetrap": "^1.6.5",
         "react": "^17.0.1",
         "react-dom": "^17.0.1",
+        "react-resize-context": "^3.0.0",
         "react-textarea-autosize": "^8.0.1",
         "react-transition-group": "^4.3.0",
         "yargs-parser": "^20.2.4"

+ 5 - 0
resources/css/common.css

@@ -711,3 +711,8 @@ hr {
   margin: 2rem 0;
   border-color: var(--ls-border-color, #ccc);
 }
+
+.resize {
+    resize: both;
+    overflow: hidden;
+}

+ 34 - 18
src/main/frontend/components/block.cljs

@@ -159,43 +159,59 @@
                 parts (remove #(string/blank? %) parts)]
             (string/join "/" (reverse parts))))))))
 
+(rum/defcs resizable-image <
+  (rum/local nil ::size)
+  [state config title src metadata full_text]
+  (let [size (get state ::size)]
+    (ui/resize-provider
+     (ui/resize-consumer
+      (cond->
+       {:className "resize"
+        :onSizeChanged #(reset! size %)
+        :onMouseUp (fn []
+                     (when @size
+                       (when-let [block-id (:block/uuid config)]
+                         (let [size (bean/->clj @size)]
+                           (editor-handler/resize-image! block-id metadata full_text size)))))
+        :onClick (fn [e]
+                   (util/stop e))}
+        (:width metadata)
+        (assoc :style {:width (:width metadata)}))
+      [:img.rounded-sm.shadow-xl
+       (merge
+        {:loading "lazy"
+         :src     src
+         :title   title}
+        metadata)]))))
+
 (rum/defcs asset-link < rum/reactive
   (rum/local nil ::src)
-  [state href label metadata]
-  (let [title (second (first label))
-        src (::src state)
+  [state config title href label metadata full_text]
+  (let [src (::src state)
         granted? (state/sub [:nfs/user-granted? (state/get-current-repo)])]
 
     (when granted?
       (p/then (editor-handler/make-asset-url href) #(reset! src %)))
 
     (when @src
-      [:img
-       (merge
-        {:loading "lazy"
-         :src     @src
-         :title   title}
-        metadata)])))
+      (resizable-image config title @src metadata full_text))))
 
 ;; TODO: safe encoding asciis
 ;; TODO: image link to another link
+
+
 (defn image-link [config url href label metadata full_text]
   (let [metadata (if (string/blank? metadata)
                    nil
-                   (safe-read-string metadata false))]
+                   (safe-read-string metadata false))
+        title (second (first label))]
     (if (or (util/starts-with? href "/assets")
             (util/starts-with? href "../assets"))
-      (asset-link href label metadata)
+      (asset-link config title href label metadata full_text)
       (let [href (if (util/starts-with? href "http")
                    href
                    (get-file-absolute-path config href))]
-        [:img.rounded-sm.shadow-xl
-         (merge
-          {:loading "lazy"
-          ;; :on-error (fn [])
-           :src     href
-           :title   (second (first label))}
-          metadata)]))))
+        (resizable-image config title href metadata full_text)))))
 
 (defn repetition-to-string
   [[[kind] [duration] n]]

+ 10 - 0
src/main/frontend/handler/editor.cljs

@@ -2178,3 +2178,13 @@
     (save-current-block-when-idle! {:check-idle? false})
     (when (string/starts-with? repo "https://") ; git repo
       (repo-handler/auto-push!))))
+
+(defn resize-image!
+  [block-id metadata full_text size]
+  (let [new-meta (merge metadata size)
+        image-part (first (string/split full_text #"\{"))
+        new-full-text (str image-part (pr-str new-meta))
+        block (db/pull [:block/uuid block-id])
+        value (:block/content block)
+        new-value (string/replace value full_text new-full-text)]
+    (save-block-aux! block new-value (:block/format block) {})))

+ 3 - 0
src/main/frontend/ui.cljs

@@ -3,6 +3,7 @@
             [frontend.rum :as r]
             ["react-transition-group" :refer [TransitionGroup CSSTransition]]
             ["react-textarea-autosize" :as TextareaAutosize]
+            ["react-resize-context" :as Resize]
             [frontend.util :as util]
             [frontend.mixins :as mixins]
             [frontend.handler.notification :as notification-handler]
@@ -17,6 +18,8 @@
 (defonce transition-group (r/adapt-class TransitionGroup))
 (defonce css-transition (r/adapt-class CSSTransition))
 (defonce textarea (r/adapt-class (gobj/get TextareaAutosize "default")))
+(def resize-provider (r/adapt-class (gobj/get Resize "ResizeProvider")))
+(def resize-consumer (r/adapt-class (gobj/get Resize "ResizeConsumer")))
 
 (rum/defc ls-textarea < rum/reactive
   [{:keys [on-change] :as props}]

+ 40 - 1
yarn.lock

@@ -710,6 +710,11 @@ base@^0.11.1:
     mixin-deep "^1.2.0"
     pascalcase "^0.1.1"
 
[email protected]:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/batch-processor/-/batch-processor-1.0.0.tgz#75c95c32b748e0850d10c2b168f6bdbe9891ace8"
+  integrity sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg=
+
 binary-extensions@^1.0.0:
   version "1.13.1"
   resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65"
@@ -1746,6 +1751,13 @@ electron-to-chromium@^1.3.621:
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.625.tgz#a7bd18da4dc732c180b2e95e0e296c0bf22f3bd6"
   integrity sha512-CsLk/r0C9dAzVPa9QF74HIXduxaucsaRfqiOYvIv2PRhvyC6EOqc/KbpgToQuDVgPf3sNAFZi3iBu4vpGOwGag==
 
+element-resize-detector@^1.1.14:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/element-resize-detector/-/element-resize-detector-1.2.1.tgz#b0305194447a4863155e58f13323a0aef30851d1"
+  integrity sha512-BdFsPepnQr9fznNPF9nF4vQ457U/ZJXQDSNF1zBe7yaga8v9AdZf3/NElYxFdUh7SitSGt040QygiTo6dtatIw==
+  dependencies:
+    batch-processor "1.0.0"
+
 elliptic@^6.5.3:
   version "6.5.3"
   resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6"
@@ -2021,6 +2033,13 @@ fast-levenshtein@^1.0.0:
   resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz#e6a754cc8f15e58987aa9cbd27af66fd6f4e5af9"
   integrity sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk=
 
+fastdom@^1.0.9:
+  version "1.0.10"
+  resolved "https://registry.yarnpkg.com/fastdom/-/fastdom-1.0.10.tgz#4f2c7c9b24e7e249fc70c63131842b859b92bf09"
+  integrity sha512-sbL4h358IlZn8VsTvA5TYnKVLYif46XhPEll+HTSxVtDSpqZEO/17D/QqlxE9V2K7AQ82GXeYeQLU2HWwKgk1A==
+  dependencies:
+    strictdom "^1.0.1"
+
 fastest-levenshtein@^1.0.12:
   version "1.0.12"
   resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
@@ -3340,7 +3359,7 @@ lodash.uniq@^4.5.0:
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
   integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
 
-lodash@^4.17.11, lodash@^4.17.19, lodash@^4.17.20:
+lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.19, lodash@^4.17.20:
   version "4.17.20"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
   integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
@@ -4795,6 +4814,16 @@ react-is@^16.8.1:
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
   integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
 
+react-resize-context@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/react-resize-context/-/react-resize-context-3.0.0.tgz#fb3c3d24a8c1cbe86d3e1b1da72a9952e462a031"
+  integrity sha512-ocDhYfPgFxaPvKdtouwIxNwGBWbCTTrzjY/wK941ng3XyfWd/wQOh/GnJRTMZpcjrKSnK7OgIVTbJZJRxM/QAA==
+  dependencies:
+    element-resize-detector "^1.1.14"
+    fastdom "^1.0.9"
+    lodash "^4.17.10"
+    shallowequal "^1.1.0"
+
 react-textarea-autosize@^8.0.1:
   version "8.3.0"
   resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.0.tgz#e6e2fd186d9f61bb80ac6e2dcb4c55504f93c2fa"
@@ -5229,6 +5258,11 @@ [email protected]:
     which "^1.3.1"
     ws "^3.0.0"
 
+shallowequal@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
+  integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
+
 shebang-command@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
@@ -5442,6 +5476,11 @@ stream-shift@^1.0.0:
   resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
   integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
 
+strictdom@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/strictdom/-/strictdom-1.0.1.tgz#189de91649f73d44d59b8432efa68ef9d2659460"
+  integrity sha1-GJ3pFkn3PUTVm4Qy76aO+dJllGA=
+
 string-width@^1.0.1, string-width@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"