|  | @@ -482,124 +482,6 @@
 | 
	
		
			
				|  |  |                 (util/stop e)
 | 
	
		
			
				|  |  |                 (on-submit command @input-value pos)))])))))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -(rum/defc absolute-modal < rum/static
 | 
	
		
			
				|  |  | -  [cp modal-name set-default-width? {:keys [top left rect]}]
 | 
	
		
			
				|  |  | -  (let [MAX-HEIGHT 700
 | 
	
		
			
				|  |  | -        MAX-HEIGHT' 600
 | 
	
		
			
				|  |  | -        MAX-WIDTH 600
 | 
	
		
			
				|  |  | -        SM-MAX-WIDTH 300
 | 
	
		
			
				|  |  | -        Y-BOUNDARY-HEIGHT 150
 | 
	
		
			
				|  |  | -        vw-width js/window.innerWidth
 | 
	
		
			
				|  |  | -        vw-height js/window.innerHeight
 | 
	
		
			
				|  |  | -        vw-max-width (- vw-width (:left rect))
 | 
	
		
			
				|  |  | -        vw-max-height (- vw-height (:top rect))
 | 
	
		
			
				|  |  | -        vw-max-height' (:top rect)
 | 
	
		
			
				|  |  | -        sm? (< vw-width 415)
 | 
	
		
			
				|  |  | -        max-height (min (- vw-max-height 20) MAX-HEIGHT)
 | 
	
		
			
				|  |  | -        max-height' (min (- vw-max-height' 70) MAX-HEIGHT')
 | 
	
		
			
				|  |  | -        max-width (if sm? SM-MAX-WIDTH (min (max 400 (/ vw-max-width 2)) MAX-WIDTH))
 | 
	
		
			
				|  |  | -        offset-top 24
 | 
	
		
			
				|  |  | -        to-max-height (cond-> (if (and (seq rect) (> vw-height max-height))
 | 
	
		
			
				|  |  | -                                (let [delta-height (- vw-height (+ (:top rect) top offset-top))]
 | 
	
		
			
				|  |  | -                                  (if (< delta-height max-height)
 | 
	
		
			
				|  |  | -                                    (- (max (* 2 offset-top) delta-height) 16)
 | 
	
		
			
				|  |  | -                                    max-height))
 | 
	
		
			
				|  |  | -                                max-height)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                        (= modal-name "commands")
 | 
	
		
			
				|  |  | -                        (min 500))
 | 
	
		
			
				|  |  | -        right-sidebar? (:ui/sidebar-open? @state/state)
 | 
	
		
			
				|  |  | -        editing-key    (state/get-edit-input-id)
 | 
	
		
			
				|  |  | -        *el (rum/use-ref nil)
 | 
	
		
			
				|  |  | -        y-overflow-vh? (or (< to-max-height Y-BOUNDARY-HEIGHT)
 | 
	
		
			
				|  |  | -                           (> (- max-height' to-max-height) Y-BOUNDARY-HEIGHT))
 | 
	
		
			
				|  |  | -        to-max-height (if y-overflow-vh? max-height' to-max-height)
 | 
	
		
			
				|  |  | -        pos-rect (when (and (seq rect) editing-key)
 | 
	
		
			
				|  |  | -                   (:rect (cursor/get-caret-pos (state/get-input))))
 | 
	
		
			
				|  |  | -        y-diff (when pos-rect (- (:height pos-rect) (:height rect)))
 | 
	
		
			
				|  |  | -        style (merge
 | 
	
		
			
				|  |  | -               {:top        (+ top offset-top (if (int? y-diff) y-diff 0))
 | 
	
		
			
				|  |  | -                :max-height to-max-height
 | 
	
		
			
				|  |  | -                :max-width  700
 | 
	
		
			
				|  |  | -                ;; TODO: auto responsive fixed size
 | 
	
		
			
				|  |  | -                :width      "fit-content"
 | 
	
		
			
				|  |  | -                :z-index    11}
 | 
	
		
			
				|  |  | -               (when set-default-width?
 | 
	
		
			
				|  |  | -                 {:width max-width})
 | 
	
		
			
				|  |  | -               (if (<= vw-max-width (+ left (if set-default-width? max-width 500)))
 | 
	
		
			
				|  |  | -                 {:right 0}
 | 
	
		
			
				|  |  | -                 {:left 0}))]
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    (rum/use-effect!
 | 
	
		
			
				|  |  | -     (fn []
 | 
	
		
			
				|  |  | -       (when-let [^js/HTMLElement cnt
 | 
	
		
			
				|  |  | -                  (and right-sidebar? editing-key
 | 
	
		
			
				|  |  | -                       (js/document.querySelector "#main-content-container"))]
 | 
	
		
			
				|  |  | -         (when (.contains cnt (js/document.querySelector (str "#" editing-key)))
 | 
	
		
			
				|  |  | -           (let [el  (rum/deref *el)
 | 
	
		
			
				|  |  | -                 ofx (- (.-scrollWidth cnt) (.-clientWidth cnt))]
 | 
	
		
			
				|  |  | -             (when (> ofx 0)
 | 
	
		
			
				|  |  | -               (set! (.-transform (.-style el))
 | 
	
		
			
				|  |  | -                     (util/format "translate(-%spx, %s)" (+ ofx 20) (if y-overflow-vh? "calc(-100% - 2rem)" 0))))))))
 | 
	
		
			
				|  |  | -     [right-sidebar? editing-key y-overflow-vh?])
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    ;; HACK: close when click outside for classic editing models (popup)
 | 
	
		
			
				|  |  | -    (rum/use-effect!
 | 
	
		
			
				|  |  | -      (fn []
 | 
	
		
			
				|  |  | -        (let [^js cnt js/document.body
 | 
	
		
			
				|  |  | -              handle (fn [^js e]
 | 
	
		
			
				|  |  | -                       (when-not (some->> (.-target e) (.contains (rum/deref *el)))
 | 
	
		
			
				|  |  | -                         (state/clear-editor-action!)))]
 | 
	
		
			
				|  |  | -          (.addEventListener cnt "click" handle false)
 | 
	
		
			
				|  |  | -          #(.removeEventListener cnt "click" handle)))
 | 
	
		
			
				|  |  | -      [])
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    [:div.absolute.rounded-md.shadow-lg.absolute-modal
 | 
	
		
			
				|  |  | -     {:ref             *el
 | 
	
		
			
				|  |  | -      :data-modal-name modal-name
 | 
	
		
			
				|  |  | -      :class           (if y-overflow-vh? "is-overflow-vh-y" "")
 | 
	
		
			
				|  |  | -      :on-pointer-down   (fn [e]
 | 
	
		
			
				|  |  | -                         (.stopPropagation e))
 | 
	
		
			
				|  |  | -      :on-key-down     (fn [^js e]
 | 
	
		
			
				|  |  | -                         (case (.-key e)
 | 
	
		
			
				|  |  | -                           "Escape"
 | 
	
		
			
				|  |  | -                           (do (state/clear-editor-action!)
 | 
	
		
			
				|  |  | -                               (some-> (state/get-input)
 | 
	
		
			
				|  |  | -                                 (.focus)))
 | 
	
		
			
				|  |  | -                           :dune)
 | 
	
		
			
				|  |  | -                         (util/stop-propagation e))
 | 
	
		
			
				|  |  | -      :style style}
 | 
	
		
			
				|  |  | -     cp]))
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -(rum/defc transition-cp < rum/reactive
 | 
	
		
			
				|  |  | -  [cp modal-name set-default-width?]
 | 
	
		
			
				|  |  | -  (when-let [pos (:pos (state/sub :editor/action-data))]
 | 
	
		
			
				|  |  | -    (ui/css-transition
 | 
	
		
			
				|  |  | -      {:class-names "fade"
 | 
	
		
			
				|  |  | -       :timeout {:enter 500
 | 
	
		
			
				|  |  | -                 :exit 300}}
 | 
	
		
			
				|  |  | -      (absolute-modal cp modal-name set-default-width? pos))))
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -(rum/defc image-uploader < rum/reactive
 | 
	
		
			
				|  |  | -  [id format]
 | 
	
		
			
				|  |  | -  [:div.image-uploader
 | 
	
		
			
				|  |  | -   [:input
 | 
	
		
			
				|  |  | -    {:id        "upload-file"
 | 
	
		
			
				|  |  | -     :type      "file"
 | 
	
		
			
				|  |  | -     :on-change (fn [e]
 | 
	
		
			
				|  |  | -                  (let [files (.-files (.-target e))]
 | 
	
		
			
				|  |  | -                    (editor-handler/upload-asset id files format editor-handler/*asset-uploading? false)))
 | 
	
		
			
				|  |  | -     :hidden    true}]
 | 
	
		
			
				|  |  | -   #_:clj-kondo/ignore
 | 
	
		
			
				|  |  | -   (when-let [uploading? (util/react editor-handler/*asset-uploading?)]
 | 
	
		
			
				|  |  | -     (let [processing (util/react editor-handler/*asset-uploading-process)]
 | 
	
		
			
				|  |  | -       (transition-cp
 | 
	
		
			
				|  |  | -        [:div.flex.flex-row.align-center.rounded-md.shadow-sm.bg-base-2.px-1.py-1
 | 
	
		
			
				|  |  | -         (ui/loading
 | 
	
		
			
				|  |  | -          (util/format "Uploading %s%" (util/format "%2d" processing)))]
 | 
	
		
			
				|  |  | -        "upload-file"
 | 
	
		
			
				|  |  | -        false)))])
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  (defn- set-up-key-down!
 | 
	
		
			
				|  |  |    [state format]
 | 
	
		
			
				|  |  |    (mixins/on-key-down
 | 
	
	
		
			
				|  | @@ -694,146 +576,98 @@
 | 
	
		
			
				|  |  |           [:span {:id (str "mock-text_" idx)
 | 
	
		
			
				|  |  |                   :key idx} c])))])
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -(rum/defc animated-modal < rum/reactive
 | 
	
		
			
				|  |  | -  [modal-name component set-default-width?]
 | 
	
		
			
				|  |  | -  (when-let [pos (:pos (state/get-editor-action-data))]
 | 
	
		
			
				|  |  | -    (ui/css-transition
 | 
	
		
			
				|  |  | -     {:key modal-name
 | 
	
		
			
				|  |  | -      :class-names {:enter "origin-top-left opacity-0 transform scale-95"
 | 
	
		
			
				|  |  | -                    :enter-done "origin-top-left transition opacity-100 transform scale-100"
 | 
	
		
			
				|  |  | -                    :exit "origin-top-left transition opacity-0 transform scale-95"}
 | 
	
		
			
				|  |  | -      :timeout {:enter 0
 | 
	
		
			
				|  |  | -                :exit 150}}
 | 
	
		
			
				|  |  | -     (fn [_]
 | 
	
		
			
				|  |  | -       (absolute-modal
 | 
	
		
			
				|  |  | -        component
 | 
	
		
			
				|  |  | -        modal-name
 | 
	
		
			
				|  |  | -        set-default-width?
 | 
	
		
			
				|  |  | -        pos)))))
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  (defn- exist-editor-commands-popup?
 | 
	
		
			
				|  |  |    []
 | 
	
		
			
				|  |  |    (some->> (shui-popup/get-popups)
 | 
	
		
			
				|  |  |      (some #(some-> % (:id) (str) (string/starts-with? ":editor.commands")))))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -;; TODO: [WIP]
 | 
	
		
			
				|  |  | -(rum/defc shui-modals
 | 
	
		
			
				|  |  | +(defn- open-editor-popup!
 | 
	
		
			
				|  |  | +  [id content opts]
 | 
	
		
			
				|  |  | +  (let [{:keys [left top rect]} (cursor/get-caret-pos (state/get-input))
 | 
	
		
			
				|  |  | +        pos [(+ left (:left rect) -20) (+ top (:top rect) 20)]
 | 
	
		
			
				|  |  | +        {:keys [root-props content-props]} opts]
 | 
	
		
			
				|  |  | +    (shui/popup-show!
 | 
	
		
			
				|  |  | +      pos content
 | 
	
		
			
				|  |  | +      (merge
 | 
	
		
			
				|  |  | +        {:id (keyword :editor.commands id)
 | 
	
		
			
				|  |  | +         :align :start
 | 
	
		
			
				|  |  | +         :root-props (merge {:onOpenChange #(when-not % (state/clear-editor-action!))} root-props)
 | 
	
		
			
				|  |  | +         :content-props (merge {:onOpenAutoFocus #(.preventDefault %)
 | 
	
		
			
				|  |  | +                                :onCloseAutoFocus #(.preventDefault %)
 | 
	
		
			
				|  |  | +                                :data-editor-popup-ref (name id)} content-props)
 | 
	
		
			
				|  |  | +         :force-popover? true}
 | 
	
		
			
				|  |  | +        (dissoc opts :root-props :content-props)))))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +(rum/defc shui-editor-popups
 | 
	
		
			
				|  |  |    [id format action _data]
 | 
	
		
			
				|  |  |    (rum/use-effect!
 | 
	
		
			
				|  |  |      (fn []
 | 
	
		
			
				|  |  | -      (let [{:keys [left top rect]} (cursor/get-caret-pos (state/get-input))
 | 
	
		
			
				|  |  | -            pos [(+ left (:left rect) -20) (+ top (:top rect) 20)]]
 | 
	
		
			
				|  |  | -        (let [pid (case action
 | 
	
		
			
				|  |  | -                    :commands
 | 
	
		
			
				|  |  | -                    (shui/popup-show! pos
 | 
	
		
			
				|  |  | -                      (commands id format)
 | 
	
		
			
				|  |  | -                      {:id :editor.commands/commands
 | 
	
		
			
				|  |  | -                       :align :start
 | 
	
		
			
				|  |  | -                       :root-props {:onOpenChange
 | 
	
		
			
				|  |  | -                                    #(when-not %
 | 
	
		
			
				|  |  | -                                       (when (= :commands (state/get-editor-action))
 | 
	
		
			
				|  |  | -                                         (state/clear-editor-action!)))}
 | 
	
		
			
				|  |  | -                       :content-props {:onOpenAutoFocus #(.preventDefault %)
 | 
	
		
			
				|  |  | -                                       :onCloseAutoFocus #(.preventDefault %)
 | 
	
		
			
				|  |  | -                                       :withoutAnimation true
 | 
	
		
			
				|  |  | -                                       :data-editor-popup-ref "commands"}
 | 
	
		
			
				|  |  | -                       :force-popover? true})
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    :block-commands
 | 
	
		
			
				|  |  | -                    (shui/popup-show! pos
 | 
	
		
			
				|  |  | -                      (block-commands id format)
 | 
	
		
			
				|  |  | -                      {:id :editor.commands/block-commands
 | 
	
		
			
				|  |  | -                       :align :start
 | 
	
		
			
				|  |  | -                       :root-props {:onOpenChange
 | 
	
		
			
				|  |  | -                                    #(when-not %
 | 
	
		
			
				|  |  | -                                       (when (= :block-commands (state/get-editor-action))
 | 
	
		
			
				|  |  | -                                         (state/clear-editor-action!)))}
 | 
	
		
			
				|  |  | -                       :content-props {:onOpenAutoFocus #(.preventDefault %)
 | 
	
		
			
				|  |  | -                                       :onCloseAutoFocus #(.preventDefault %)
 | 
	
		
			
				|  |  | -                                       :withoutAnimation true
 | 
	
		
			
				|  |  | -                                       :data-editor-popup-ref "commands"}
 | 
	
		
			
				|  |  | -                       :force-popover? true})
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    (:block-search :page-search :page-search-hashtag)
 | 
	
		
			
				|  |  | -                    (shui/popup-show!
 | 
	
		
			
				|  |  | -                      pos (if (= :block-search action)
 | 
	
		
			
				|  |  | -                            (block-search id format)
 | 
	
		
			
				|  |  | -                            (page-search id format))
 | 
	
		
			
				|  |  | -                      {:id :editor.commands/block-search
 | 
	
		
			
				|  |  | -                       :align :start
 | 
	
		
			
				|  |  | -                       :root-props {:onOpenChange
 | 
	
		
			
				|  |  | -                                    #(when-not %
 | 
	
		
			
				|  |  | -                                       (when (contains?
 | 
	
		
			
				|  |  | -                                               #{:block-search :page-search :page-search-hashtag}
 | 
	
		
			
				|  |  | -                                               (state/get-editor-action))
 | 
	
		
			
				|  |  | -                                         (state/clear-editor-action!)))}
 | 
	
		
			
				|  |  | -                       :content-props {:onOpenAutoFocus #(.preventDefault %)
 | 
	
		
			
				|  |  | -                                       :onCloseAutoFocus #(.preventDefault %)
 | 
	
		
			
				|  |  | -                                       :data-editor-popup-ref (name action)}
 | 
	
		
			
				|  |  | -                       :force-popover? true})
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    :datepicker
 | 
	
		
			
				|  |  | -                    (shui/popup-show!
 | 
	
		
			
				|  |  | -                      pos (datetime-comp/date-picker id format nil)
 | 
	
		
			
				|  |  | -                      {:id :editor.commands/datepicker
 | 
	
		
			
				|  |  | -                       :align :start
 | 
	
		
			
				|  |  | -                       :root-props {:onOpenChange #(when-not % (state/clear-editor-action!))}
 | 
	
		
			
				|  |  | -                       :content-props {:onOpenAutoFocus #(.preventDefault %)
 | 
	
		
			
				|  |  | -                                       :data-editor-popup-ref "datepicker"}
 | 
	
		
			
				|  |  | -                       :force-popover? true})
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    :input
 | 
	
		
			
				|  |  | -                    (shui/popup-show!
 | 
	
		
			
				|  |  | -                      pos (input id
 | 
	
		
			
				|  |  | -                            (fn [command m]
 | 
	
		
			
				|  |  | -                              (editor-handler/handle-command-input command id format m))
 | 
	
		
			
				|  |  | -                            (fn []
 | 
	
		
			
				|  |  | -                              (editor-handler/handle-command-input-close id)))
 | 
	
		
			
				|  |  | -                      {:id :editor.commands/input
 | 
	
		
			
				|  |  | -                       :align :start
 | 
	
		
			
				|  |  | -                       :root-props {:onOpenChange #(when-not % (state/clear-editor-action!))}
 | 
	
		
			
				|  |  | -                       :content-props {:onOpenAutoFocus #(.preventDefault %)
 | 
	
		
			
				|  |  | -                                       :onCloseAutoFocus #(.preventDefault %)
 | 
	
		
			
				|  |  | -                                       :data-editor-popup-ref "input"}})
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    :select-code-block-mode
 | 
	
		
			
				|  |  | -                    (shui/popup-show!
 | 
	
		
			
				|  |  | -                      pos (code-block-mode-picker id format)
 | 
	
		
			
				|  |  | -                      {:id :editor.commands/code-block-mode-picker
 | 
	
		
			
				|  |  | -                       :align :start
 | 
	
		
			
				|  |  | -                       :root-props {:onOpenChange #(when-not % (state/clear-editor-action!))}
 | 
	
		
			
				|  |  | -                       :content-props {:onOpenAutoFocus #(.preventDefault %)
 | 
	
		
			
				|  |  | -                                       :data-editor-popup-ref "code-block-mode-picker"}
 | 
	
		
			
				|  |  | -                       :force-popover? true})
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    ;; TODO: try remove local model state
 | 
	
		
			
				|  |  | -                    false)]
 | 
	
		
			
				|  |  | -          #(when pid
 | 
	
		
			
				|  |  | -             (shui/popup-hide! pid)))))
 | 
	
		
			
				|  |  | +      (let [pid (case action
 | 
	
		
			
				|  |  | +                  :commands
 | 
	
		
			
				|  |  | +                  (open-editor-popup! :commands
 | 
	
		
			
				|  |  | +                    (commands id format)
 | 
	
		
			
				|  |  | +                    {:content-props {:withoutAnimation false}})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                  :block-commands
 | 
	
		
			
				|  |  | +                  (open-editor-popup! :block-commands
 | 
	
		
			
				|  |  | +                    (block-commands id format)
 | 
	
		
			
				|  |  | +                    {:content-props {:withoutAnimation true}})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                  (:block-search :page-search :page-search-hashtag)
 | 
	
		
			
				|  |  | +                  (open-editor-popup! action
 | 
	
		
			
				|  |  | +                    (if (= :block-search action)
 | 
	
		
			
				|  |  | +                      (block-search id format)
 | 
	
		
			
				|  |  | +                      (page-search id format))
 | 
	
		
			
				|  |  | +                    {:root-props {:onOpenChange
 | 
	
		
			
				|  |  | +                                  #(when-not %
 | 
	
		
			
				|  |  | +                                     (when (contains?
 | 
	
		
			
				|  |  | +                                             #{:block-search :page-search :page-search-hashtag}
 | 
	
		
			
				|  |  | +                                             (state/get-editor-action))
 | 
	
		
			
				|  |  | +                                       (state/clear-editor-action!)))}})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                  :datepicker
 | 
	
		
			
				|  |  | +                  (open-editor-popup! :datepicker
 | 
	
		
			
				|  |  | +                    (datetime-comp/date-picker id format nil) {})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                  :input
 | 
	
		
			
				|  |  | +                  (open-editor-popup! :input
 | 
	
		
			
				|  |  | +                    (input id
 | 
	
		
			
				|  |  | +                      (fn [command m]
 | 
	
		
			
				|  |  | +                        (editor-handler/handle-command-input command id format m))
 | 
	
		
			
				|  |  | +                      (fn []
 | 
	
		
			
				|  |  | +                        (editor-handler/handle-command-input-close id))) {})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                  :select-code-block-mode
 | 
	
		
			
				|  |  | +                  (open-editor-popup! :code-block-mode-picker
 | 
	
		
			
				|  |  | +                    (code-block-mode-picker id format) {})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                  :template-search
 | 
	
		
			
				|  |  | +                  (open-editor-popup! :template-search
 | 
	
		
			
				|  |  | +                    (template-search id format) {})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                  (:property-search :property-value-search)
 | 
	
		
			
				|  |  | +                  (open-editor-popup! action
 | 
	
		
			
				|  |  | +                    (if (= :property-search action)
 | 
	
		
			
				|  |  | +                      (property-search id) (property-value-search id))
 | 
	
		
			
				|  |  | +                    {})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                  :zotero
 | 
	
		
			
				|  |  | +                  (open-editor-popup! :zotero
 | 
	
		
			
				|  |  | +                    (zotero/zotero-search id) {})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                  ;; TODO: try remove local model state
 | 
	
		
			
				|  |  | +                  false)]
 | 
	
		
			
				|  |  | +        #(when pid
 | 
	
		
			
				|  |  | +           (shui/popup-hide! pid))))
 | 
	
		
			
				|  |  |      [action])
 | 
	
		
			
				|  |  |    [:<>])
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -(rum/defc modals < rum/reactive
 | 
	
		
			
				|  |  | -  "React to atom changes, find and render the correct modal"
 | 
	
		
			
				|  |  | +(rum/defc command-popups <
 | 
	
		
			
				|  |  | +  rum/reactive
 | 
	
		
			
				|  |  | +  "React to atom changes, find and render the correct popup"
 | 
	
		
			
				|  |  |    [id format]
 | 
	
		
			
				|  |  |    (let [action (state/sub :editor/action)]
 | 
	
		
			
				|  |  | -    [:<>
 | 
	
		
			
				|  |  | -     (shui-modals id format action nil)
 | 
	
		
			
				|  |  | -     (cond
 | 
	
		
			
				|  |  | -       (= :template-search action)
 | 
	
		
			
				|  |  | -       (animated-modal "template-search" (template-search id format) true)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -       (= :property-search action)
 | 
	
		
			
				|  |  | -       (animated-modal "property-search" (property-search id) true)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -       (= :property-value-search action)
 | 
	
		
			
				|  |  | -       (animated-modal "property-value-search" (property-value-search id) true)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -       (= :zotero action)
 | 
	
		
			
				|  |  | -       (animated-modal "zotero-search" (zotero/zotero-search id) false)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -       :else
 | 
	
		
			
				|  |  | -       nil)]))
 | 
	
		
			
				|  |  | +    (shui-editor-popups id format action nil)))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  (defn- editor-on-hide
 | 
	
		
			
				|  |  |    [state value* type e]
 | 
	
	
		
			
				|  | @@ -916,9 +750,5 @@
 | 
	
		
			
				|  |  |      [:div.editor-inner.flex.flex-1 {:class (if block "block-editor" "non-block-editor")}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |       (ui/ls-textarea opts)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |       (mock-textarea content)
 | 
	
		
			
				|  |  | -     (modals id format)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -     (when format
 | 
	
		
			
				|  |  | -       (image-uploader id format))]))
 | 
	
		
			
				|  |  | +     (command-popups id format)]))
 |