diff --git a/src/electron/electron/core.cljs b/src/electron/electron/core.cljs index a75cdcedf6..26406a7386 100644 --- a/src/electron/electron/core.cljs +++ b/src/electron/electron/core.cljs @@ -11,6 +11,7 @@ [electron.handler :as handler] [electron.i18n :as i18n :refer [t]] [electron.logger :as logger] + [electron.release-warning :as release-warning] [electron.server :as server] [electron.updater :refer [init-updater] :as updater] [electron.url :refer [logseq-url-handler]] @@ -248,6 +249,23 @@ (when-let [url (find-deeplink-url (rest (js->clj (.-argv js/process))))] (open-url-handler win url)))) +(defn- maybe-warn-wrong-release! + [] + (when (release-warning/x64-on-apple-silicon? + {:platform (.-platform js/process) + :arch (.-arch js/process) + :running-under-arm64-translation? (boolean (.-runningUnderARM64Translation app))}) + (-> (.showMessageBox + dialog + (clj->js (assoc (release-warning/warning-dialog-options t) :title "Logseq"))) + (.then + (fn [result] + (when-let [url (release-warning/selected-release-url (.-response result))] + (.openExternal shell url)))) + (.catch + (fn [error] + (logger/warn :electron/wrong-release-warning-failed error)))))) + (defn- on-app-ready! [^js app'] (.on app' "ready" @@ -271,6 +289,7 @@ ;; Windows/Linux: handle deeplink URL passed on first launch via argv (handle-initial-deeplink! win) + (maybe-warn-wrong-release!) (vreset! *setup-fn (fn [] diff --git a/src/electron/electron/release_warning.cljs b/src/electron/electron/release_warning.cljs new file mode 100644 index 0000000000..d25330148e --- /dev/null +++ b/src/electron/electron/release_warning.cljs @@ -0,0 +1,31 @@ +(ns electron.release-warning) + +(def stable-release-url + "https://github.com/logseq/logseq/releases/latest") + +(def nightly-release-url + "https://github.com/logseq/logseq/releases/tag/nightly") + +(defn x64-on-apple-silicon? + [{:keys [platform arch running-under-arm64-translation?]}] + (and (= "darwin" platform) + (= "x64" arch) + (true? running-under-arm64-translation?))) + +(defn selected-release-url + [response] + (case response + 0 stable-release-url + 1 nightly-release-url + nil)) + +(defn warning-dialog-options + [t] + {:type "warning" + :buttons [(t :electron/wrong-release-open-stable) + (t :electron/wrong-release-open-nightly) + (t :electron/cancel)] + :defaultId 0 + :cancelId 2 + :message (t :electron/wrong-release-warning-title) + :detail (t :electron/wrong-release-warning-detail)}) diff --git a/src/resources/dicts/en.edn b/src/resources/dicts/en.edn index 50b57ef5ed..02664c4638 100644 --- a/src/resources/dicts/en.edn +++ b/src/resources/dicts/en.edn @@ -539,6 +539,10 @@ :electron/version "Version {1}" :electron/write-file-error "Write to the file {1} failed, {2}." :electron/write-file-error-with-backup "Write to the file {1} failed, {2}. A backup file was saved to {3}." + :electron/wrong-release-open-nightly "Open nightly release" + :electron/wrong-release-open-stable "Download regular release" + :electron/wrong-release-warning-detail "This release runs through Rosetta and can be very slow. Download the Apple Silicon (arm64) release first. If it is unavailable for your version, use the nightly release." + :electron/wrong-release-warning-title "You are using the Intel (x64) release on Apple Silicon." :encryption/cloud-password-rich (fn [] ["If you lose your password, all of your data in the cloud can't be decrypted. " [:span "You will still be able to access the local version of your graph."]]) :encryption/current-password "Current password" diff --git a/src/test/electron/release_warning_test.cljs b/src/test/electron/release_warning_test.cljs new file mode 100644 index 0000000000..d12a055bc0 --- /dev/null +++ b/src/test/electron/release_warning_test.cljs @@ -0,0 +1,54 @@ +(ns electron.release-warning-test + (:require [cljs.test :refer [deftest is testing]] + [electron.release-warning :as release-warning])) + +(deftest x64-on-apple-silicon?-test + (testing "returns true only when an x64 release runs under Apple Silicon translation" + (is (true? (release-warning/x64-on-apple-silicon? + {:platform "darwin" + :arch "x64" + :running-under-arm64-translation? true}))) + (is (false? (release-warning/x64-on-apple-silicon? + {:platform "darwin" + :arch "arm64" + :running-under-arm64-translation? false}))) + (is (false? (release-warning/x64-on-apple-silicon? + {:platform "darwin" + :arch "x64" + :running-under-arm64-translation? false}))) + (is (false? (release-warning/x64-on-apple-silicon? + {:platform "win32" + :arch "x64" + :running-under-arm64-translation? true}))))) + +(deftest selected-release-url-test + (testing "prefers stable release link and supports nightly fallback" + (is (= release-warning/stable-release-url + (release-warning/selected-release-url 0))) + (is (= release-warning/nightly-release-url + (release-warning/selected-release-url 1))) + (is (nil? (release-warning/selected-release-url 2))) + (is (nil? (release-warning/selected-release-url nil))))) + +(deftest warning-dialog-options-test + (testing "includes warning text and both stable/nightly actions" + (let [calls (atom []) + t (fn [k] + (swap! calls conj k) + (name k)) + options (release-warning/warning-dialog-options t)] + (is (= "warning" (:type options))) + (is (= ["wrong-release-open-stable" + "wrong-release-open-nightly" + "cancel"] + (:buttons options))) + (is (= 0 (:defaultId options))) + (is (= 2 (:cancelId options))) + (is (= "wrong-release-warning-title" (:message options))) + (is (= "wrong-release-warning-detail" (:detail options))) + (is (= [:electron/wrong-release-open-stable + :electron/wrong-release-open-nightly + :electron/cancel + :electron/wrong-release-warning-title + :electron/wrong-release-warning-detail] + @calls)))))