Răsfoiți Sursa

Merge branch 'master' into ci/init

Tienson Qin 5 ani în urmă
părinte
comite
bfc1d2af01

+ 2 - 1
deps.edn

@@ -25,7 +25,8 @@
   tongue                      {:mvn/version "0.2.9"}
   tongue                      {:mvn/version "0.2.9"}
   org.clojure/core.async      {:mvn/version "1.3.610"}
   org.clojure/core.async      {:mvn/version "1.3.610"}
   thheller/shadow-cljs        {:mvn/version "2.8.81"}
   thheller/shadow-cljs        {:mvn/version "2.8.81"}
-  expound                     {:mvn/version "0.8.6"}}
+  expound                     {:mvn/version "0.8.6"}
+  lambdaisland/glogi          {:mvn/version "1.0.74"}}
 
 
  :aliases {:cljs {:extra-paths ["src/dev-cljs/"]
  :aliases {:cljs {:extra-paths ["src/dev-cljs/"]
                   :extra-deps  {org.clojure/clojurescript   {:mvn/version "1.10.520"}
                   :extra-deps  {org.clojure/clojurescript   {:mvn/version "1.10.520"}

+ 6 - 0
resources/css/common.css

@@ -148,6 +148,8 @@ textarea {
     width: 100%;
     width: 100%;
     resize: none;
     resize: none;
     outline: none;
     outline: none;
+    font-weight: inherit;
+    letter-spacing: inherit;
 }
 }
 
 
 ul {
 ul {
@@ -203,6 +205,7 @@ ol {
 p {
 p {
   line-height: 1.5;
   line-height: 1.5;
   margin: 0.5rem 0;
   margin: 0.5rem 0;
+  color: var(--ls-primary-text-color)
 }
 }
 
 
 li p:first-child, .block-body p:first-child {
 li p:first-child, .block-body p:first-child {
@@ -1048,6 +1051,8 @@ button.context-menu-option {
 
 
 .notification-area {
 .notification-area {
   background-color: #FFF;
   background-color: #FFF;
+  background-color: var(--ls-tertiary-background-color);
+  color: var(--ls-primary-text-color);
 }
 }
 
 
 .content img {
 .content img {
@@ -1078,6 +1083,7 @@ a.login:hover {
   opacity: 0.5;
   opacity: 0.5;
   padding: 0 2px 0 2px;
   padding: 0 2px 0 2px;
   border: 1px solid;
   border: 1px solid;
+  line-height: 1.3;
 }
 }
 
 
 a.marker-switch:hover {
 a.marker-switch:hover {

+ 7 - 7
resources/css/datepicker.css

@@ -168,7 +168,7 @@
 .datepicker th.month {
 .datepicker th.month {
     width: auto;
     width: auto;
     font-size: 14px;
     font-size: 14px;
-    color: #777;
+    color: var(--ls-title-text-color);
 }
 }
 
 
 .dropdown-button {
 .dropdown-button {
@@ -194,7 +194,7 @@
 }
 }
 
 
 .dark-theme .datepicker {
 .dark-theme .datepicker {
-    background: #073642;
+    background: var(--ls-secondary-background-color);
 }
 }
 
 
 .dark-theme .datepicker th.day-disabled, .dark-theme .datepicker th.disabled, .dark-theme .datepicker td.disabled, .dark-theme .datepicker td.off {
 .dark-theme .datepicker th.day-disabled, .dark-theme .datepicker th.disabled, .dark-theme .datepicker td.disabled, .dark-theme .datepicker td.off {
@@ -206,16 +206,16 @@
 }
 }
 
 
 .dark-theme .datepicker td.active, .dark-theme .datepicker td.active:hover {
 .dark-theme .datepicker td.active, .dark-theme .datepicker td.active:hover {
-    background-color: #011b22;
-    border-color: #011b22;
+    background-color: var(--ls-block-properties-background-color);
+    border-color: var(--ls-block-properties-background-color);
 }
 }
 
 
 .dark-theme .datepicker th.selectable {
 .dark-theme .datepicker th.selectable {
-     color: #fff;
+     color: var(--ls-primary-text-color);
 }
 }
 
 
 .dark-theme .datepicker td.available:hover, .dark-theme .datepicker th.available:hover {
 .dark-theme .datepicker td.available:hover, .dark-theme .datepicker th.available:hover {
-    background: #011b22;
+    background: var(--ls-block-properties-background-color);
 }
 }
 
 
 .datepicker tr:nth-child(odd), .datepicker tr:nth-child(even), .dark-theme .datepicker tr:nth-child(odd), .dark-theme .datepicker tr:nth-child(even) {
 .datepicker tr:nth-child(odd), .datepicker tr:nth-child(even), .dark-theme .datepicker tr:nth-child(odd), .dark-theme .datepicker tr:nth-child(even) {
@@ -227,4 +227,4 @@
 }
 }
 /*----------------------------------------------------------------------------------------
 /*----------------------------------------------------------------------------------------
   END OF DATE PICKER SECTION...
   END OF DATE PICKER SECTION...
-----------------------------------------------------------------------------------------*/
+----------------------------------------------------------------------------------------*/

+ 4 - 1
shadow-cljs.edn

@@ -18,6 +18,8 @@
                       :output-feature-set :es6
                       :output-feature-set :es6
                       :externs ["datascript/externs.js"
                       :externs ["datascript/externs.js"
                                 "externs.js"]}
                                 "externs.js"]}
+   :closure-defines {goog.debug.LOGGING_ENABLED true}
+
    :devtools
    :devtools
    ;; before live-reloading any code call this function
    ;; before live-reloading any code call this function
    {:before-load frontend.core/stop
    {:before-load frontend.core/stop
@@ -42,7 +44,8 @@
    :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}
 
 
    :compiler-options {:infer-externs :auto
    :compiler-options {:infer-externs :auto
                       :output-feature-set :es6
                       :output-feature-set :es6

+ 9 - 2
src/main/frontend/components/block.cljs

@@ -321,12 +321,19 @@
   [config page-name]
   [config page-name]
   (let [page-name (string/lower-case page-name)
   (let [page-name (string/lower-case page-name)
         page-original-name (:page/original-name (db/entity [:page/name page-name]))
         page-original-name (:page/original-name (db/entity [:page/name page-name]))
-        blocks (db/get-page-blocks (state/get-current-repo) page-name)]
+        blocks (db/get-page-blocks (state/get-current-repo) page-name)
+        current-page (state/get-current-page)]
     [:div.embed-page.py-2.my-2.px-3.bg-base-2
     [:div.embed-page.py-2.my-2.px-3.bg-base-2
      [:p
      [:p
       [:code.mr-2 "Embed page:"]
       [:code.mr-2 "Embed page:"]
       (page-cp config {:page/name page-name})]
       (page-cp config {:page/name page-name})]
-     (blocks-container blocks (assoc config :embed? true))]))
+     (when (or
+            (not current-page)
+            (and current-page
+                 (not= (string/lower-case current-page) page-name)))
+       (blocks-container blocks (assoc config
+                                       :embed? true
+                                       :ref? false)))]))
 
 
 (defn- get-label-text
 (defn- get-label-text
   [label]
   [label]

+ 1 - 0
src/main/frontend/components/datetime.cljs

@@ -26,6 +26,7 @@
         {:style {:width 240}
         {:style {:width 240}
          :default-value default-value
          :default-value default-value
          :on-change (fn [event]
          :on-change (fn [event]
+                      (util/stop event)
                       (let [value (util/evalue event)]
                       (let [value (util/evalue event)]
                         (swap! *timestamp assoc :time value)))}]
                         (swap! *timestamp assoc :time value)))}]
        [:a.ml-2.self-center {:on-click (fn []
        [:a.ml-2.self-center {:on-click (fn []

+ 76 - 76
src/main/frontend/components/diff.cljs

@@ -20,7 +20,6 @@
             [frontend.diff :as diff]
             [frontend.diff :as diff]
             [medley.core :as medley]))
             [medley.core :as medley]))
 
 
-(defonce diffs (atom nil))
 (defonce remote-hash-id (atom nil))
 (defonce remote-hash-id (atom nil))
 (defonce diff-state (atom {}))
 (defonce diff-state (atom {}))
 (defonce commit-message (atom ""))
 (defonce commit-message (atom ""))
@@ -62,78 +61,78 @@
          (svg/arrow-right)
          (svg/arrow-right)
          (svg/arrow-down))]
          (svg/arrow-down))]
       [:span.cp__diff-file-header-content path]
       [:span.cp__diff-file-header-content path]
-      [:span.cp__diff-file-header-type type]
       (when resolved?
       (when resolved?
         [:span.text-green-600
         [:span.text-green-600
          {:dangerouslySetInnerHTML
          {:dangerouslySetInnerHTML
           {:__html "✓"}}])]
           {:__html "✓"}}])]
 
 
-     (if-let [content (get contents path)]
-       (let [local-content (db/get-file path)
-             local-content (or local-content "")
-             diff (medley/indexed (diff/diff local-content content))
-             diff? (some (fn [[_idx {:keys [added removed]}]]
-                           (or added removed))
-                         diff)]
-         [:div.pre-line-white-space.p-2 {:class (if collapse? "hidden")
-                                         :style {:overflow "auto"}}
-          (if edit?
-            [:div.grid.grid-cols-2.gap-1
-             (diff-cp diff)
-             (ui/textarea
-              {:default-value local-content
-               :on-change (fn [e]
-                            (reset! *edit-content (util/evalue e)))})]
-            (diff-cp diff))
-
-          (cond
-            edit?
-            [:div.mt-2
-             (ui/button "Save"
-                        :on-click
-                        (fn []
-                          (reset! *edit? false)
-                          (let [new-content @*edit-content]
-                            (file/alter-file repo path new-content
-                                             {:commit? false
-                                              :re-render-root? true})
-                            (swap! state/state
-                                   assoc-in [:github/contents repo remote-oid path] new-content)
-                            (mark-as-resolved path))))]
-
-            diff?
-            [:div.mt-2
-             (ui/button "Use remote"
-                        :on-click
-                        (fn []
-                 ;; overwrite the file
-                          (file/alter-file repo path content
-                                           {:commit? false
-                                            :re-render-root? true})
-                          (mark-as-resolved path))
-                        :background "green")
-
-             [:span.pl-2.pr-2 "or"]
-
-             (ui/button "Keep local"
-                        :on-click
-                        (fn []
-                 ;; overwrite the file
-                          (swap! state/state
-                                 assoc-in [:github/contents repo remote-oid path] local-content)
-                          (mark-as-resolved path))
-                        :background "pink")
-
-             [:span.pl-2.pr-2 "or"]
-
-             (ui/button "Edit"
-                        :on-click
-                        (fn []
-                          (reset! *edit? true)))]
-
-            :else
-            nil)])
-       [:div "loading..."])]))
+     (let [content (get contents path)
+           local-content (db/get-file path)]
+       (if (not= content local-content)
+         (let [local-content (or local-content "")
+               content (or content "")
+               diff (medley/indexed (diff/diff local-content content))
+               diff? (some (fn [[_idx {:keys [added removed]}]]
+                             (or added removed))
+                           diff)]
+           [:div.pre-line-white-space.p-2 {:class (if collapse? "hidden")
+                                           :style {:overflow "auto"}}
+            (if edit?
+              [:div.grid.grid-cols-2.gap-1
+               (diff-cp diff)
+               (ui/textarea
+                {:default-value local-content
+                 :on-change (fn [e]
+                              (reset! *edit-content (util/evalue e)))})]
+              (diff-cp diff))
+
+            (cond
+              edit?
+              [:div.mt-2
+               (ui/button "Save"
+                 :on-click
+                 (fn []
+                   (reset! *edit? false)
+                   (let [new-content @*edit-content]
+                     (file/alter-file repo path new-content
+                                      {:commit? false
+                                       :re-render-root? true})
+                     (swap! state/state
+                            assoc-in [:github/contents repo remote-oid path] new-content)
+                     (mark-as-resolved path))))]
+
+              diff?
+              [:div.mt-2
+               (ui/button "Use remote"
+                 :on-click
+                 (fn []
+                   ;; overwrite the file
+                   (file/alter-file repo path content
+                                    {:commit? false
+                                     :re-render-root? true})
+                   (mark-as-resolved path))
+                 :background "green")
+
+               [:span.pl-2.pr-2 "or"]
+
+               (ui/button "Keep local"
+                 :on-click
+                 (fn []
+                   ;; overwrite the file
+                   (swap! state/state
+                          assoc-in [:github/contents repo remote-oid path] local-content)
+                   (mark-as-resolved path))
+                 :background "pink")
+
+               [:span.pl-2.pr-2 "or"]
+
+               (ui/button "Edit"
+                 :on-click
+                 (fn []
+                   (reset! *edit? true)))]
+
+              :else
+              nil)])))]))
 
 
 ;; TODO: `n` shortcut for next diff, `p` for previous diff
 ;; TODO: `n` shortcut for next diff, `p` for previous diff
 (rum/defcc diff <
 (rum/defcc diff <
@@ -145,10 +144,10 @@
                local-latest-commit (common-handler/get-ref repo)
                local-latest-commit (common-handler/get-ref repo)
                result (git/get-local-diffs repo local-latest-commit remote-latest-commit)
                result (git/get-local-diffs repo local-latest-commit remote-latest-commit)
                token (helper/get-github-token repo)]
                token (helper/get-github-token repo)]
-         (reset! diffs result)
+         (reset! state/diffs result)
          (reset! remote-hash-id remote-latest-commit)
          (reset! remote-hash-id remote-latest-commit)
          (doseq [{:keys [type path]} result]
          (doseq [{:keys [type path]} result]
-           (when (contains? #{"added" "modify"}
+           (when (contains? #{"add" "modify"}
                             type)
                             type)
              (github/get-content
              (github/get-content
               token
               token
@@ -157,11 +156,11 @@
               remote-latest-commit
               remote-latest-commit
               (fn [{:keys [repo-url path ref content]}]
               (fn [{:keys [repo-url path ref content]}]
                 (swap! state/state
                 (swap! state/state
-                       assoc-in [:github/contents repo-url remote-latest-commit path] content))
+                       assoc-in [:github/contents repo-url remote-latest-commit path] (or content "")))
               (fn [response]
               (fn [response]
                 (when (= (gobj/get response "status") 401)
                 (when (= (gobj/get response "status") 401)
                   (notification/show!
                   (notification/show!
-                   [:span.text-gray-700.mr-2
+                   [:span.mr-2
                     (util/format
                     (util/format
                      "Please make sure that you've installed the logseq app for the repo %s on GitHub. "
                      "Please make sure that you've installed the logseq app for the repo %s on GitHub. "
                      repo)
                      repo)
@@ -169,10 +168,11 @@
                       "Install Logseq on GitHub"
                       "Install Logseq on GitHub"
                       :href (str "https://github.com/apps/" config/github-app-name "/installations/new"))]
                       :href (str "https://github.com/apps/" config/github-app-name "/installations/new"))]
                    :error
                    :error
-                   false)))))))))
+                   false))))))))
+     state)
    :will-unmount
    :will-unmount
    (fn [state]
    (fn [state]
-     (reset! diffs nil)
+     (reset! state/diffs nil)
      (reset! remote-hash-id nil)
      (reset! remote-hash-id nil)
      (reset! diff-state {})
      (reset! diff-state {})
      (reset! commit-message "")
      (reset! commit-message "")
@@ -181,7 +181,7 @@
      (reset! *edit-content "")
      (reset! *edit-content "")
      state)}
      state)}
   [component]
   [component]
-  (let [diffs (util/react diffs)
+  (let [diffs (util/react state/diffs)
         remote-oid (util/react remote-hash-id)
         remote-oid (util/react remote-hash-id)
         repo (state/get-current-repo)
         repo (state/get-current-repo)
         contents (if remote-oid (state/sub [:github/contents repo remote-oid]))
         contents (if remote-oid (state/sub [:github/contents repo remote-oid]))
@@ -201,7 +201,7 @@
          (ui/textarea
          (ui/textarea
           {:placeholder "Commit message (optional)"
           {:placeholder "Commit message (optional)"
            :on-change (fn [e]
            :on-change (fn [e]
-                       (reset! commit-message (util/evalue e)))})
+                        (reset! commit-message (util/evalue e)))})
          (if pushing?
          (if pushing?
            [:span (ui/loading "Pushing")]
            [:span (ui/loading "Pushing")]
            (ui/button "Commit and push"
            (ui/button "Commit and push"

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

@@ -557,6 +557,16 @@
                        true)))
                        true)))
               (commands/simple-insert! input-id "$$" {:backward-pos 2})
               (commands/simple-insert! input-id "$$" {:backward-pos 2})
 
 
+              (let [sym "^"]
+                (and (= key sym)
+                     (>= (count value) 1)
+                     (> pos 0)
+                     (= (nth value (dec pos)) sym)
+                     (if (> (count value) pos)
+                       (not= (nth value pos) sym)
+                       true)))
+              (commands/simple-insert! input-id "^^" {:backward-pos 2})
+
               :else
               :else
               nil))))
               nil))))
        (mixins/on-key-up
        (mixins/on-key-up

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

@@ -73,7 +73,7 @@
            (let [branch (string/trim @branch)]
            (let [branch (string/trim @branch)]
              (if (string/blank? branch)
              (if (string/blank? branch)
                (notification/show!
                (notification/show!
-                [:p.text-gray-700 "Please input a branch, make sure it's matched with your setting on Github."]
+                [:p "Please input a branch, make sure it's matched with your setting on Github."]
                 :error
                 :error
                 false)
                 false)
                (let [repo (util/lowercase-first @repo)]
                (let [repo (util/lowercase-first @repo)]
@@ -82,6 +82,6 @@
                      (repo-handler/create-repo! repo branch))
                      (repo-handler/create-repo! repo branch))
 
 
                    (notification/show!
                    (notification/show!
-                    [:p.text-gray-700 "Please input a valid repo url, e.g. https://github.com/username/repo"]
+                    [:p "Please input a valid repo url, e.g. https://github.com/username/repo"]
                     :error
                     :error
                     false)))))))]])))
                     false)))))))]])))

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

@@ -5,9 +5,9 @@
             [frontend.page :as page]
             [frontend.page :as page]
             [frontend.routes :as routes]
             [frontend.routes :as routes]
             [frontend.spec]
             [frontend.spec]
+            [frontend.log]
             [reitit.frontend :as rf]
             [reitit.frontend :as rf]
-            [reitit.frontend.easy :as rfe]
-            ))
+            [reitit.frontend.easy :as rfe]))
 
 
 (defn set-router!
 (defn set-router!
   []
   []

+ 2 - 1
src/main/frontend/format/block.cljs

@@ -31,7 +31,8 @@
                  (or
                  (or
                   (and
                   (and
                    (= typ "Search")
                    (= typ "Search")
-                   (not (contains? #{\# \* \/ \( \[} (first (second (:url (second block))))))
+                   ;; FIXME: alert error
+                   (not (contains? #{\# \* \/ \[} (first (second (:url (second block))))))
                    (let [page (second (:url (second block)))]
                    (let [page (second (:url (second block)))]
                      (when (and (not (util/starts-with? page "http"))
                      (when (and (not (util/starts-with? page "http"))
                                 (not (util/starts-with? page "file"))
                                 (not (util/starts-with? page "file"))

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

@@ -1422,7 +1422,8 @@
    "*" "*"
    "*" "*"
    ;; "_" "_"
    ;; "_" "_"
    ;; ":" ":"                              ; TODO: only properties editing and org mode tag
    ;; ":" ":"                              ; TODO: only properties editing and org mode tag
-   "^" "^"})
+   ;; "^" "^"
+   })
 
 
 (def reversed-autopair-map
 (def reversed-autopair-map
   (zipmap (vals autopair-map)
   (zipmap (vals autopair-map)

+ 58 - 40
src/main/frontend/handler/repo.cljs

@@ -32,7 +32,7 @@
   (notification/show!
   (notification/show!
    [:p.content
    [:p.content
     title
     title
-    [:span.text-gray-700.mr-2
+    [:span.mr-2
      (util/format
      (util/format
       "Please make sure that you've installed the logseq app for the repo %s on GitHub. "
       "Please make sure that you've installed the logseq app for the repo %s on GitHub. "
       repo-url)
       repo-url)
@@ -256,7 +256,9 @@
 (declare push)
 (declare push)
 
 
 (defn pull
 (defn pull
-  [repo-url {:keys [force-pull?] :or {force-pull? false}}]
+  [repo-url {:keys [force-pull? show-diff?]
+             :or {force-pull? false
+                  show-diff? false}}]
   (when (and
   (when (and
          (db/get-conn repo-url true)
          (db/get-conn repo-url true)
          (db/cloned? repo-url))
          (db/cloned? repo-url))
@@ -275,47 +277,61 @@
                      (and
                      (and
                       (not= status :pushing)
                       (not= status :pushing)
                       (not (state/get-edit-input-id))
                       (not (state/get-edit-input-id))
-                      (not (state/in-draw-mode?))))
+                      (not (state/in-draw-mode?))
+                      (or
+                       show-diff?
+                       (and (not show-diff?)
+                            (empty? @state/diffs)))))
                 (git-handler/set-git-status! repo-url :pulling)
                 (git-handler/set-git-status! repo-url :pulling)
                 (->
                 (->
                  (p/let [token (helper/get-github-token repo-url)
                  (p/let [token (helper/get-github-token repo-url)
                          result (git/fetch repo-url token)]
                          result (git/fetch repo-url token)]
                    (let [{:keys [fetchHead]} (bean/->clj result)]
                    (let [{:keys [fetchHead]} (bean/->clj result)]
-                     (-> (git/merge repo-url)
-                         (p/then (fn [result]
-                                   (-> (git/checkout repo-url)
-                                       (p/then (fn [result]
-                                                 (git-handler/set-git-status! repo-url nil)
-                                                 (git-handler/set-git-last-pulled-at! repo-url)
-                                                 (when (and local-latest-commit fetchHead
-                                                            (not= local-latest-commit fetchHead))
-                                                   (p/let [diffs (git/get-diffs repo-url local-latest-commit fetchHead)]
-                                                     (when (seq diffs)
-                                                       (load-db-and-journals! repo-url diffs false))))
-                                                 (common-handler/check-changed-files-status repo-url)))
-                                       (p/catch (fn [error]
-                                                  (git-handler/set-git-status! repo-url :checkout-failed)
-                                                  (git-handler/set-git-error! repo-url error))))))
-                         (p/catch (fn [error]
-                                    (println "Git pull error:")
-                                    (js/console.error error)
-                                    (git-handler/set-git-status! repo-url :merge-failed)
-                                    (git-handler/set-git-error! repo-url error)
-                                    (p/let [remote-latest-commit (common-handler/get-remote-ref repo-url)
-                                            local-latest-commit (common-handler/get-ref repo-url)
-                                            result (git/get-local-diffs repo-url local-latest-commit remote-latest-commit)]
-                                      (if (seq result)
-                                        (do
-                                          (notification/show!
-                                           [:p.content
-                                            "Failed to merge, please "
-                                            [:span.text-gray-700.font-bold
-                                             "resolve any diffs first."]]
-                                           :error)
-                                          (route-handler/redirect! {:to :diff}))
-                                        (push repo-url {:commit-push? true
-                                                        :force? true
-                                                        :commit-message "Merge push without diffed files"}))))))))
+                     (if show-diff?
+                       (do
+                         (notification/show!
+                          [:p.content
+                           "Failed to push, please "
+                           [:span.font-bold
+                            "resolve any diffs first."]]
+                          :error)
+                         (route-handler/redirect! {:to :diff}))
+
+                       (-> (git/merge repo-url)
+                          (p/then (fn [result]
+                                    (-> (git/checkout repo-url)
+                                        (p/then (fn [result]
+                                                  (git-handler/set-git-status! repo-url nil)
+                                                  (git-handler/set-git-last-pulled-at! repo-url)
+                                                  (when (and local-latest-commit fetchHead
+                                                             (not= local-latest-commit fetchHead))
+                                                    (p/let [diffs (git/get-diffs repo-url local-latest-commit fetchHead)]
+                                                      (when (seq diffs)
+                                                        (load-db-and-journals! repo-url diffs false))))
+                                                  (common-handler/check-changed-files-status repo-url)))
+                                        (p/catch (fn [error]
+                                                   (git-handler/set-git-status! repo-url :checkout-failed)
+                                                   (git-handler/set-git-error! repo-url error))))))
+                          (p/catch (fn [error]
+                                     (println "Git pull error:")
+                                     (js/console.error error)
+                                     (git-handler/set-git-status! repo-url :merge-failed)
+                                     (git-handler/set-git-error! repo-url error)
+                                     (p/let [remote-latest-commit (common-handler/get-remote-ref repo-url)
+                                             local-latest-commit (common-handler/get-ref repo-url)
+                                             result (git/get-local-diffs repo-url local-latest-commit remote-latest-commit)]
+                                       (if (seq result)
+                                         (do
+                                           (notification/show!
+                                            [:p.content
+                                             "Failed to merge, please "
+                                             [:span.font-bold
+                                              "resolve any diffs first."]]
+                                            :error)
+                                           (route-handler/redirect! {:to :diff}))
+                                         (push repo-url {:commit-push? true
+                                                         :force? true
+                                                         :commit-message "Merge push without diffed files"})))))))))
                  (p/catch (fn [error]
                  (p/catch (fn [error]
                             (println "Pull error:" (str error))
                             (println "Pull error:" (str error))
                             (js/console.error error)
                             (js/console.error error)
@@ -335,7 +351,8 @@
            (and
            (and
             (db/cloned? repo-url)
             (db/cloned? repo-url)
             (not (state/get-edit-input-id))
             (not (state/get-edit-input-id))
-            (not= status :pushing)))
+            (not= status :pushing)
+            (empty? @state/diffs)))
       (-> (p/let [files (js/window.workerThread.getChangedFiles (util/get-repo-dir (state/get-current-repo)))]
       (-> (p/let [files (js/window.workerThread.getChangedFiles (util/get-repo-dir (state/get-current-repo)))]
             (when (or
             (when (or
                    commit-push?
                    commit-push?
@@ -363,7 +380,8 @@
                          (git-handler/set-git-status! repo-url :push-failed)
                          (git-handler/set-git-status! repo-url :push-failed)
                          (git-handler/set-git-error! repo-url error)
                          (git-handler/set-git-error! repo-url error)
                          (when (state/online?)
                          (when (state/online?)
-                           (pull repo-url {:force-pull? true}))))))))))
+                           (pull repo-url {:force-pull? true
+                                           :show-diff? true}))))))))))
           (p/catch (fn [error]
           (p/catch (fn [error]
                      (println "Git push error: ")
                      (println "Git push error: ")
                      (git-handler/set-git-status! repo-url :push-failed)
                      (git-handler/set-git-status! repo-url :push-failed)

+ 3 - 2
src/main/frontend/handler/ui.cljs

@@ -81,8 +81,9 @@
 
 
 (defn scroll-and-highlight!
 (defn scroll-and-highlight!
   [state]
   [state]
-  (when-let [fragment (util/get-fragment)]
-    (highlight-element! fragment))
+  (if-let [fragment (util/get-fragment)]
+    (highlight-element! fragment)
+    (util/scroll-to-top))
   state)
   state)
 
 
 (defn add-style-if-exists!
 (defn add-style-if-exists!

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

@@ -0,0 +1,10 @@
+(ns frontend.log
+  (:require [lambdaisland.glogi :as log]
+            [lambdaisland.glogi.console :as glogi-console]
+            [frontend.config :as config]))
+
+(glogi-console/install!)
+
+(if config/dev?
+  (log/set-levels {:glogi/root :info})
+  (log/set-levels {:glogi/root :warn}))

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

@@ -867,6 +867,7 @@
   []
   []
   (:commands (get-config)))
   (:commands (get-config)))
 
 
+;; TODO: Move those to the uni `state`
 (defonce editor-op (atom nil))
 (defonce editor-op (atom nil))
 (defn set-editor-op!
 (defn set-editor-op!
   [value]
   [value]
@@ -874,3 +875,5 @@
 (defn get-editor-op
 (defn get-editor-op
   []
   []
   @editor-op)
   @editor-op)
+
+(defonce diffs (atom nil))

+ 4 - 3
src/main/frontend/util.cljs

@@ -322,9 +322,10 @@
 
 
 (defn scroll-to
 (defn scroll-to
   [pos]
   [pos]
-  (.scroll (gdom/getElement "main-content")
-           #js {:top pos
-                :behavior "smooth"}))
+  (when-let [main-content (gdom/getElement "main-content")]
+    (.scroll main-content
+            #js {:top pos
+                 :behavior "smooth"})))
 
 
 (defn scroll-to-top
 (defn scroll-to-top
   []
   []