瀏覽代碼

feat(electron): improve development tools

charlie 4 年之前
父節點
當前提交
22867be6aa

+ 2 - 1
package.json

@@ -31,6 +31,8 @@
         "release-app": "run-s gulp:build cljs:release-app",
         "release-publishing": "run-s gulp:build cljs:release-publishing",
         "dev-release-app": "run-s gulp:build cljs:dev-release-app",
+        "dev-electron-app": "cd static/ && yarn && yarn electron:dev",
+        "debug-electron-app": "cd static/ && yarn electron:debug",
         "clean": "gulp clean",
         "test": "run-s cljs:test cljs:run-test",
         "report": "run-s cljs:report",
@@ -53,7 +55,6 @@
         "codemirror": "^5.58.1",
         "diff": "5.0.0",
         "diff-match-patch": "^1.0.5",
-        "electron": "^11.2.0",
         "fs": "^0.0.1-security",
         "fuzzysort": "^1.1.4",
         "gulp-cached": "^1.1.1",

+ 30 - 0
resources/dev.html

@@ -0,0 +1,30 @@
+<!doctype html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport"
+        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+  <meta http-equiv="X-UA-Compatible" content="ie=edge">
+  <title>Electron Development Entries</title>
+</head>
+<body>
+<div style="padding: 50px; text-align: center;">
+  <h1>
+    Development Mode :)
+  </h1>
+  <h3>
+    <a href="http://localhost:3000">
+      http://localhost:3000
+    </a> <br> <br>
+    <a href="http://localhost:3001">
+      http://localhost:3001
+    </a>
+  </h3>
+</div>
+<script>
+  require('electron').ipcRenderer.on('hello', (e, v) => {
+    console.info('[hello] ', v)
+  })
+</script>
+</body>
+</html>

+ 42 - 0
resources/forge.config.js

@@ -0,0 +1,42 @@
+const path = require('path')
+
+module.exports = {
+  packagerConfig: {
+    icon: './icons/logseq.icns'
+  },
+
+  makers: [
+    {
+      'name': '@electron-forge/maker-squirrel',
+      'config': {
+        'name': 'Logseq'
+      }
+    },
+    {
+      name: '@electron-forge/maker-dmg',
+      config: {
+        background: './img/dmg-bg.png',
+        format: 'ULFO',
+        icon: './icons/logseq.icns',
+        name: 'Logseq'
+      }
+    },
+    {
+      name: '@electron-forge/maker-zip',
+      platforms: ['darwin', 'linux']
+    }
+  ],
+
+  publishers: [
+    {
+      name: '@electron-forge/publisher-github',
+      config: {
+        repository: {
+          owner: 'logseq',
+          name: 'logseq'
+        },
+        prerelease: true
+      }
+    }
+  ]
+}

二進制
resources/icons/logseq.icns


二進制
resources/icons/logseq.ico


二進制
resources/icons/logseq.png


二進制
resources/img/dmg-bg.png


+ 31 - 0
resources/package.json

@@ -0,0 +1,31 @@
+{
+  "name": "logseq",
+  "version": "0.0.1",
+  "main": "electron.js",
+  "author": "logseq",
+  "description": "A privacy-first, open-source platform for knowledge sharing and management.",
+  "scripts": {
+    "electron:dev": "electron-forge start",
+    "electron:debug": "electron-forge start --inspect-electron",
+    "electron:make": "electron-forge make",
+    "electron:publish:github": "electron-forge publish"
+  },
+  "config": {
+    "forge": "./forge.config.js"
+  },
+  "dependencies": {
+    "electron-log": "^4.3.1",
+    "electron-squirrel-startup": "^1.0.0",
+    "electron-updater": "^4.3.5",
+    "update-electron-app": "^2.0.1"
+  },
+  "devDependencies": {
+    "@electron-forge/cli": "^6.0.0-beta.54",
+    "@electron-forge/maker-deb": "^6.0.0-beta.54",
+    "@electron-forge/maker-dmg": "^6.0.0-beta.54",
+    "@electron-forge/maker-rpm": "^6.0.0-beta.54",
+    "@electron-forge/maker-squirrel": "^6.0.0-beta.54",
+    "@electron-forge/maker-zip": "^6.0.0-beta.54",
+    "electron": "11.2.0"
+  }
+}

+ 81 - 45
src/electron/electron/core.cljs

@@ -1,47 +1,83 @@
 (ns electron.core
-  (:require ["electron" :refer [app BrowserWindow crashReporter protocol session]]
+  (:require [electron.init :refer [init-channel]]
             ["fs" :as fs]
-            ["path" :as p]
-            ["url" :as u]))
-
-(def main-window (atom nil))
-
-(defn init-browser []
-
-  (let [options {:width 800
-                 :height 600}]
-    (reset! main-window (BrowserWindow. (clj->js options))))
-
-  (let [f (fn [request callback]
-            (let [url (u/URL. (.-url request))]
-              (if (empty? (.-port url))
-                (let [path (.-pathname url)
-                      path (cond
-                             (= "/" path)
-                             (str path "/static/index.html")
-
-                             (= "/" (last path))
-                             (str path "/index.html")
-
-                             :else path)
-                      path (.normalize p (str js/__dirname "/../" path))
-                      resp (.createReadStream fs path)]
-                  (callback resp))
-                (.uninterceptProtocol protocol "http"))))]
-    (.interceptFileProtocol protocol "http" f))
-
-  ^html (.loadURL @main-window (str "http://localhost/"))
-  ^js (.on @main-window "closed" #(reset! main-window nil)))
-
-(defn main []
-  ; CrashReporter can just be omitted
-  (.start crashReporter
-          (clj->js
-           {:companyName "Logseq"
-            :productName "logseq"
-            :submitURL "https://example.com/submit-url"
-            :autoSubmit false}))
-
-  (.on app "window-all-closed" #(when-not (= js/process.platform "darwin")
-                                  (.quit app)))
-  (.on app "ready" init-browser))
+            ["path" :as path]
+            ["electron" :refer [BrowserWindow app] :as electron]
+            ["electron-updater" :refer [autoUpdater]]))
+
+(defonce mac? (= (.-platform js/process) "darwin"))
+(defonce win32? (= (.-platform js/process) "win32"))
+
+(defonce prod? (= js/process.env.NODE_ENV "production"))
+(defonce dev? (not prod?))
+(defonce log (js/require "electron-log"))
+
+(def ROOT_PATH (path/join js/__dirname ".."))
+(def MAIN_WINDOW_ENTRY (str "file://" (path/join js/__dirname (if dev? "dev.html" "index.html"))))
+
+;; Handle creating/removing shortcuts on Windows when installing/uninstalling.
+(when (js/require "electron-squirrel-startup") (.quit app))
+
+(defn create-main-window
+  "create main app window"
+  []
+  (let [win-opts {:width  980
+                  :height 700
+                  :webPreferences
+                  {:nodeIntegration true            ;; FIXME
+}}
+        url MAIN_WINDOW_ENTRY
+        win (BrowserWindow. (clj->js win-opts))]
+    (.loadURL win url)
+    (when dev? (.. win -webContents (openDevTools)))
+    win))
+
+(defn setup-updater! [notify-update-status]
+  ;; updater logging
+  (set! (.. autoUpdater -logger) log)
+  (set! (.. autoUpdater -logger -transports -file -level) "info")
+
+  (.. log (info (str "Logseq App(" (.getVersion app) ") Starting... ")))
+
+  (let [init-updater (js/require "update-electron-app")]
+    (init-updater #js {:repo           "logseq/logseq"
+                       :updateInterval "1 hour"
+                       :logger         log}))
+  ;;; updater hooks
+  ;(doto autoUpdater
+  ;  (.on "checking-for-update" #(notify-update-status "checking for updating..."))
+  ;  (.on "update-not-available" #(notify-update-status "update not available"))
+  ;  (.on "error" #(notify-update-status %))
+  ;  (.on "download-progress"
+  ;       #(let [progress-clj (js->clj %)
+  ;              {:keys [percent transferred total]} progress-clj
+  ;              msg (str "Progress Downloaded " percent "%"
+  ;                       " (" transferred "/" total ")")]
+  ;          (notify-update-status msg)))
+  ;  (.on "update-downloaded" #(do (notify-update-status "update downloaded")
+  ;                                (.. autoUpdater quitAndInstall)))
+  ;  (.checkForUpdatesAndNotify))
+)
+
+(defn main
+  []
+  (.on app "window-all-closed" #(when-not mac? (.quit app)))
+  (.on app "ready"
+       (fn []
+         (let [^js win (create-main-window)
+               *win (atom win)
+               *quitting? (atom false)]
+
+           ;; auto updater
+           (setup-updater! nil)
+
+           ;; init stuffs
+           (init-channel win)
+
+           ;; main window events
+           (.on win "close" #(if (or @*quitting? win32?)
+                               (reset! *win nil)
+                               (do (.preventDefault ^js/Event %)
+                                   (.hide win))))
+           (.on app "before-quit" #(reset! *quitting? true))
+           (.on app "activate" #(if @*win (.show win)))))))

+ 9 - 0
src/electron/electron/init.cljs

@@ -0,0 +1,9 @@
+(ns electron.init)
+
+;;; FIXME: real world
+(defn init-channel
+  "init main process IPC channel wrapper"
+  [^js win]
+  (js/setInterval
+   #(.. win -webContents (send "hello" "msg from Background :)"))
+   3000))