|  | @@ -469,7 +469,9 @@
 | 
	
		
			
				|  |  |                                       (> (count blocks) 1)
 | 
	
		
			
				|  |  |                                       (not move?)))
 | 
	
		
			
				|  |  |          blocks' (blocks-with-level blocks)
 | 
	
		
			
				|  |  | -        blocks' (fix-top-level-blocks blocks')
 | 
	
		
			
				|  |  | +        blocks' (if (= outliner-op ::paste)
 | 
	
		
			
				|  |  | +                  (fix-top-level-blocks blocks')
 | 
	
		
			
				|  |  | +                  blocks')
 | 
	
		
			
				|  |  |          insert-opts {:sibling? sibling?
 | 
	
		
			
				|  |  |                       :replace-empty-target? replace-empty-target?
 | 
	
		
			
				|  |  |                       :keep-uuid? keep-uuid?
 | 
	
	
		
			
				|  | @@ -709,51 +711,53 @@
 | 
	
		
			
				|  |  |    "Indent or outdent `blocks`."
 | 
	
		
			
				|  |  |    [blocks indent?]
 | 
	
		
			
				|  |  |    {:pre [(seq blocks) (boolean? indent?)]}
 | 
	
		
			
				|  |  | -  (let [first-block (db/entity (:db/id (first blocks)))
 | 
	
		
			
				|  |  | -        left (db/entity (:db/id (:block/left first-block)))
 | 
	
		
			
				|  |  | -        parent (:block/parent first-block)
 | 
	
		
			
				|  |  | -        db (db/get-db)
 | 
	
		
			
				|  |  | -        top-level-blocks (get-top-level-blocks blocks)
 | 
	
		
			
				|  |  | -        concat-tx-fn (fn [& results]
 | 
	
		
			
				|  |  | -                       {:tx-data (->> (map :tx-data results)
 | 
	
		
			
				|  |  | -                                      (apply util/concat-without-nil))
 | 
	
		
			
				|  |  | -                        :tx-meta (:tx-meta (first results))})
 | 
	
		
			
				|  |  | -        opts {:outliner-op :indent-outdent-blocks}]
 | 
	
		
			
				|  |  | -    (if indent?
 | 
	
		
			
				|  |  | -      (when (and left (not (page-first-child? first-block)))
 | 
	
		
			
				|  |  | -        (let [last-direct-child-id (db-model/get-block-last-direct-child db (:db/id left) false)
 | 
	
		
			
				|  |  | -              blocks' (drop-while (fn [b]
 | 
	
		
			
				|  |  | -                                    (= (:db/id (:block/parent b))
 | 
	
		
			
				|  |  | -                                       (:db/id left)))
 | 
	
		
			
				|  |  | -                                  top-level-blocks)]
 | 
	
		
			
				|  |  | -          (when (seq blocks')
 | 
	
		
			
				|  |  | -            (if last-direct-child-id
 | 
	
		
			
				|  |  | -              (let [last-direct-child (db/entity last-direct-child-id)
 | 
	
		
			
				|  |  | -                    result (move-blocks blocks' last-direct-child (merge opts {:sibling? true}))
 | 
	
		
			
				|  |  | -                    ;; expand `left` if it's collapsed
 | 
	
		
			
				|  |  | -                    collapsed-tx (when (:block/collapsed? left)
 | 
	
		
			
				|  |  | -                                   {:tx-data [{:db/id (:db/id left)
 | 
	
		
			
				|  |  | -                                               :block/collapsed? false}]})]
 | 
	
		
			
				|  |  | -                (concat-tx-fn result collapsed-tx))
 | 
	
		
			
				|  |  | -              (move-blocks blocks' left (merge opts {:sibling? false}))))))
 | 
	
		
			
				|  |  | -      (when (and parent (not (page-block? (db/entity (:db/id parent)))))
 | 
	
		
			
				|  |  | -        (let [blocks' (take-while (fn [b]
 | 
	
		
			
				|  |  | -                                    (not= (:db/id (:block/parent b))
 | 
	
		
			
				|  |  | -                                          (:db/id (:block/parent parent))))
 | 
	
		
			
				|  |  | -                                  top-level-blocks)
 | 
	
		
			
				|  |  | -              result (move-blocks blocks' parent (merge opts {:sibling? true}))]
 | 
	
		
			
				|  |  | -          (if (state/logical-outdenting?)
 | 
	
		
			
				|  |  | -            result
 | 
	
		
			
				|  |  | -            ;; direct outdenting (default behavior)
 | 
	
		
			
				|  |  | -            (let [last-top-block (db/pull (:db/id (last blocks')))
 | 
	
		
			
				|  |  | -                  right-siblings (->> (get-right-siblings (block last-top-block))
 | 
	
		
			
				|  |  | -                                      (map :data))]
 | 
	
		
			
				|  |  | -              (if (seq right-siblings)
 | 
	
		
			
				|  |  | -                (let [result2 (if-let [last-direct-child-id (db-model/get-block-last-direct-child db (:db/id last-top-block) false)]
 | 
	
		
			
				|  |  | -                                (move-blocks right-siblings (db/entity last-direct-child-id) (merge opts {:sibling? true}))
 | 
	
		
			
				|  |  | -                                (move-blocks right-siblings last-top-block (merge opts {:sibling? false})))]
 | 
	
		
			
				|  |  | -                  (concat-tx-fn result result2))
 | 
	
		
			
				|  |  | -                result))))))))
 | 
	
		
			
				|  |  | +  (let [non-consecutive-blocks (db-model/get-non-consecutive-blocks blocks)]
 | 
	
		
			
				|  |  | +    (when (empty? non-consecutive-blocks)
 | 
	
		
			
				|  |  | +      (let [first-block (db/entity (:db/id (first blocks)))
 | 
	
		
			
				|  |  | +            left (db/entity (:db/id (:block/left first-block)))
 | 
	
		
			
				|  |  | +            parent (:block/parent first-block)
 | 
	
		
			
				|  |  | +            db (db/get-db)
 | 
	
		
			
				|  |  | +            top-level-blocks (get-top-level-blocks blocks)
 | 
	
		
			
				|  |  | +            concat-tx-fn (fn [& results]
 | 
	
		
			
				|  |  | +                           {:tx-data (->> (map :tx-data results)
 | 
	
		
			
				|  |  | +                                          (apply util/concat-without-nil))
 | 
	
		
			
				|  |  | +                            :tx-meta (:tx-meta (first results))})
 | 
	
		
			
				|  |  | +            opts {:outliner-op :indent-outdent-blocks}]
 | 
	
		
			
				|  |  | +        (if indent?
 | 
	
		
			
				|  |  | +          (when (and left (not (page-first-child? first-block)))
 | 
	
		
			
				|  |  | +            (let [last-direct-child-id (db-model/get-block-last-direct-child db (:db/id left) false)
 | 
	
		
			
				|  |  | +                  blocks' (drop-while (fn [b]
 | 
	
		
			
				|  |  | +                                        (= (:db/id (:block/parent b))
 | 
	
		
			
				|  |  | +                                           (:db/id left)))
 | 
	
		
			
				|  |  | +                                      top-level-blocks)]
 | 
	
		
			
				|  |  | +              (when (seq blocks')
 | 
	
		
			
				|  |  | +                (if last-direct-child-id
 | 
	
		
			
				|  |  | +                  (let [last-direct-child (db/entity last-direct-child-id)
 | 
	
		
			
				|  |  | +                        result (move-blocks blocks' last-direct-child (merge opts {:sibling? true}))
 | 
	
		
			
				|  |  | +                        ;; expand `left` if it's collapsed
 | 
	
		
			
				|  |  | +                        collapsed-tx (when (:block/collapsed? left)
 | 
	
		
			
				|  |  | +                                       {:tx-data [{:db/id (:db/id left)
 | 
	
		
			
				|  |  | +                                                   :block/collapsed? false}]})]
 | 
	
		
			
				|  |  | +                    (concat-tx-fn result collapsed-tx))
 | 
	
		
			
				|  |  | +                  (move-blocks blocks' left (merge opts {:sibling? false}))))))
 | 
	
		
			
				|  |  | +          (when (and parent (not (page-block? (db/entity (:db/id parent)))))
 | 
	
		
			
				|  |  | +            (let [blocks' (take-while (fn [b]
 | 
	
		
			
				|  |  | +                                        (not= (:db/id (:block/parent b))
 | 
	
		
			
				|  |  | +                                              (:db/id (:block/parent parent))))
 | 
	
		
			
				|  |  | +                                      top-level-blocks)
 | 
	
		
			
				|  |  | +                  result (move-blocks blocks' parent (merge opts {:sibling? true}))]
 | 
	
		
			
				|  |  | +              (if (state/logical-outdenting?)
 | 
	
		
			
				|  |  | +                result
 | 
	
		
			
				|  |  | +                ;; direct outdenting (default behavior)
 | 
	
		
			
				|  |  | +                (let [last-top-block (db/pull (:db/id (last blocks')))
 | 
	
		
			
				|  |  | +                      right-siblings (->> (get-right-siblings (block last-top-block))
 | 
	
		
			
				|  |  | +                                          (map :data))]
 | 
	
		
			
				|  |  | +                  (if (seq right-siblings)
 | 
	
		
			
				|  |  | +                    (let [result2 (if-let [last-direct-child-id (db-model/get-block-last-direct-child db (:db/id last-top-block) false)]
 | 
	
		
			
				|  |  | +                                    (move-blocks right-siblings (db/entity last-direct-child-id) (merge opts {:sibling? true}))
 | 
	
		
			
				|  |  | +                                    (move-blocks right-siblings last-top-block (merge opts {:sibling? false})))]
 | 
	
		
			
				|  |  | +                      (concat-tx-fn result result2))
 | 
	
		
			
				|  |  | +                    result))))))))))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ;;; ### write-operations have side-effects (do transactions) ;;;;;;;;;;;;;;;;
 | 
	
		
			
				|  |  |  
 |