pull/645/head
Tienson Qin 2020-07-07 22:12:58 +08:00
parent 028a173547
commit 21373e355c
18 changed files with 230 additions and 133 deletions

View File

@ -7,4 +7,4 @@ aws s3 sync ./resources/static/ s3://logseq-site/static/
aws cloudfront create-invalidation \
--distribution-id $AWS_LOGSEQ_CLOUDFRONT_ID \
--paths "/static/js/main.js" "/static/js/sci.js" "/static/js/mldoc.min.js" "/static/style.css" "/static/index.html" "/static/img/logo.png"
--paths "/static/js/main.js" "/static/js/sci.js" "/static/js/mldoc.min.js" "/static/style.css" "/static/img/logo.png"

View File

@ -39,3 +39,6 @@
*** Or if you are using Emacs
1. M-x cider-jack-in
2. type ~(cljs-repl)~ in the repl
*** Notes
1. deps should be synced between the two files: ~project.clj~ and ~deps.edn~.
~project.clj~ is for dokku deployment.

View File

@ -2,7 +2,7 @@ const purgecss = require('@fullhuman/postcss-purgecss')({
// Specify the paths to all of the template files in your project
content: [
'../resources/static/index.html',
// '../resources/static/index.html',
// '../resources/static/js/main.js',
// etc.
],

View File

@ -51,12 +51,12 @@
[["NOW" (->marker "NOW")]
["LATER" (->marker "LATER")]
["DONE" (->marker "DONE")]
["TODO" (->marker "TODO")]
["DOING" (->marker "DOING")]
["WAIT" (->marker "WAIT")]
["WAITING" (->marker "WAITING")]
["IN-PROGRESS" (->marker "IN-PROGRESS")]
["CANCELED" (->marker "CANCELED")]
;; ["TODO" (->marker "TODO")]
;; ["DOING" (->marker "DOING")]
;; ["WAIT" (->marker "WAIT")]
;; ["WAITING" (->marker "WAITING")]
;; ["IN-PROGRESS" (->marker "IN-PROGRESS")]
;; ["CANCELED" (->marker "CANCELED")]
["Tomorrow" (->page-reference (date/tomorrow))]
["Yesterday" (->page-reference (date/yesterday))]
["Today" (->page-reference (date/today))]

View File

@ -14,8 +14,6 @@
[:div#docs
[:h1.title {:style {:margin-bottom "0.25rem"}}
"What's your preferred mode?"]
[:span.text-gray-500.text-sm.ml-1
"It'll be used for new pages."]
[:div.mt-4.ml-1
(ui/button

View File

@ -409,27 +409,25 @@
(when (or (and file elements)
(nil? file))
(excalidraw-component
(cond->
{:width (get option :width width)
:height (get option :height height)
:on-resize (fn []
(reset! layout [js/window.innerWidth js/window.innerHeight]))
{:width (get option :width width)
:height (get option :height height)
:on-resize (fn []
(reset! layout [js/window.innerWidth js/window.innerHeight]))
:on-change (or (:on-change option)
(fn [elements state]
(when (not= (bean/->clj elements)
(bean/->clj @*elements))
(reset! *unsaved? true))
(set-last-elements! elements)
(set-last-app-state! state)
(reset! *elements elements)))
:options options
:user (bean/->js {:name (or (:user-name option)
(:name (state/get-me))
(util/unique-id))})
:on-username-change (fn [])}
(seq elements)
(assoc :initial-data elements))))
:on-change (or (:on-change option)
(fn [elements state]
(when (not= (bean/->clj elements)
(bean/->clj @*elements))
(reset! *unsaved? true))
(set-last-elements! elements)
(set-last-app-state! state)
(reset! *elements elements)))
:options options
:user (bean/->js {:name (or (:user-name option)
(:name (state/get-me))
(util/unique-id))})
:on-username-change (fn [])
:initial-data (or elements #js [])}))
[:div.absolute.top-4.left-4.hidden.md:block
[:div.flex.flex-row.items-center
[:a.mr-3 {:href "/"
@ -482,13 +480,16 @@
(let [loaded? (or (loaded?)
(rum/react *loaded?))
current-repo (state/sub :git/current-repo)]
(if (and loaded? current-repo)
(if loaded?
(let [current-file (rum/react *current-file)
current-file (or current-file
(get-last-file current-repo))]
(let [key (str current-repo "-"
(or (and current-file (str "draw-" current-file))
"draw-with-no-file"))]
(and current-repo
(get-last-file current-repo)))]
(let [key (if current-repo
(str current-repo "-"
(or (and current-file (str "draw-" current-file))
"draw-with-no-file"))
"draw-with-no-file")]
(rum/with-key (draw-inner option) key)))
[:div.center
[:span.lds-dual-ring.ml-3]])))

View File

@ -193,11 +193,11 @@
[:div {:key "page-references"}
(reference/references page-name false)])]))))
(defonce layout (atom [js/window.innerWidth js/window.innerHeight]))
(defonce layout (atom [js/window.outerWidth js/window.outerHeight]))
(defonce graph-ref (atom nil))
(rum/defcs global-graph < rum/reactive
(rum/local false ::show-journal?)
(rum/local true ::show-journal?)
[state]
(let [show-journal? (get state ::show-journal?)
theme (state/sub :ui/theme)

View File

@ -108,10 +108,11 @@
theme (:ui/theme @state/state)
page (get-page match)
graph (db/build-page-graph page theme)]
[:div.sidebar-item.flex-col.flex-1
(ui/force-graph-2d (graph/build-graph-opts graph dark?
{:width 600
:height 600}))]))
(when (seq (:nodes graph))
[:div.sidebar-item.flex-col.flex-1
(ui/force-graph-2d (graph/build-graph-opts graph dark?
{:width 600
:height 600}))])))
(rum/defcs starred-cp <
(rum/local true ::show?)

View File

@ -104,32 +104,32 @@
show-result? (boolean (seq search-result))]
[:div#search.flex-1.flex.ml-0.md:ml-12
[:div.w-full.flex.md:ml-0
[:label.sr-only {:for "search_field"} "Search"]
[:div#search-wrapper.relative.w-full.text-gray-400.focus-within:text-gray-600
[:div.absolute.inset-y-0.flex.items-center.pointer-events-none.left-0
[:svg.h-5.w-5
{:view-box "0 0 20 20", :fill "currentColor"}
[:path
{:d
"M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z",
:clip-rule "evenodd",
:fill-rule "evenodd"}]]]
[:input#search_field.block.w-full.h-full.pr-3.py-2.rounded-md.focus:outline-none.placeholder-gray-500.focus:placeholder-gray-400.sm:text-sm.bg-base-3.sm:bg-transparent
[:label.sr-only {:for "search_field"} "Search"]
[:div#search-wrapper.relative.w-full.text-gray-400.focus-within:text-gray-600
[:div.absolute.inset-y-0.flex.items-center.pointer-events-none.left-0
[:svg.h-5.w-5
{:view-box "0 0 20 20", :fill "currentColor"}
[:path
{:d
"M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z",
:clip-rule "evenodd",
:fill-rule "evenodd"}]]]
[:input#search_field.block.w-full.h-full.pr-3.py-2.rounded-md.focus:outline-none.placeholder-gray-500.focus:placeholder-gray-400.sm:text-sm.bg-base-3.sm:bg-transparent
{:style {:padding-left "2rem"}
:placeholder "Search"
:auto-complete "off"
:value search-q
:on-change (fn [e]
(let [value (util/evalue e)]
(if (string/blank? value)
(handler/clear-search!)
(do
(state/set-q! value)
(handler/search value)))))}]
(when-not (string/blank? search-q)
(ui/css-transition
{:class-names "fade"
:timeout {:enter 500
:exit 300}}
(search-auto-complete search-result search-q)))]]]))
{:style {:padding-left "2rem"}
:placeholder "Search"
:auto-complete "off"
:value search-q
:on-change (fn [e]
(let [value (util/evalue e)]
(if (string/blank? value)
(handler/clear-search!)
(do
(state/set-q! value)
(handler/search value)))))}]
(when-not (string/blank? search-q)
(ui/css-transition
{:class-names "fade"
:timeout {:enter 500
:exit 300}}
(search-auto-complete search-result search-q)))]]]))

View File

@ -20,7 +20,7 @@
(rum/defc logo
[]
[:div#logo.p-4
[:a.opacity-50.hover:opacity-100 {:href "/docs"}
[:a.opacity-50.hover:opacity-100 {:href "/"}
[:img.h-6.w-auto
{:alt "Logseq",
:src "/static/img/white_logo.png"}]]])
@ -99,7 +99,10 @@
token (state/sub :encrypt/token)]
[:div.max-w-7xl.mx-auto
(cond
(not preferred-format)
(and (not logged?) (seq latest-journals))
(journal/journals latest-journals)
(and logged? (not preferred-format))
(widgets/choose-preferred-format)
;; TODO: delay this
@ -112,7 +115,7 @@
(widgets/set-personal-access-token)
cloning?
(widgets/loading "Cloning ")
(widgets/loading "Cloning")
(seq latest-journals)
(journal/journals latest-journals)
@ -159,7 +162,8 @@
current-repo (state/sub :git/current-repo)
theme (state/sub :ui/theme)
white? (= "white" (state/sub :ui/theme))
global-graph-pages? (= :graph (get-in route-match [:data :name]))]
global-graph-pages? (= :graph (get-in route-match [:data :name]))
logged? (:name me)]
[:div {:class (if white? "white-theme" "dark-theme")
:on-click (fn []
(handler/unhighlight-heading!))}
@ -202,7 +206,9 @@
:stroke-linejoin "round",
:stroke-linecap "round"}]]]
[:div.flex-1.px-4.flex.justify-between
(search/search)
(if current-repo
(search/search)
[:div.w-full.flex.md:ml-0])
[:div.ml-4.flex.items-center.md:ml-6
(when current-repo (widgets/sync-status))
[:div.repos.hidden.md:block
@ -220,7 +226,7 @@
(if-let [avatar (:avatar me)]
[:img.h-7.w-7.rounded-full
{:src avatar}]
[:div.h-7.w-7.rounded-full.bg-base-3])])
[:div.h-7.w-7.rounded-full.bg-base-2])])
(let [logged? (:name me)]
(->>
[(when current-repo
@ -232,10 +238,10 @@
(when logged?
{:title "All repos"
:options {:href "/repos"}})
(when logged?
(when current-repo
{:title "All pages"
:options {:href "/all-pages"}})
(when logged?
(when current-repo
{:title "All files"
:options {:href "/all-files"}})
(when current-repo
@ -247,8 +253,6 @@
{:title "Feature request"
:options {:href "https://github.com/logseq/logseq/issues/new"
:target "_blank"}}
{:title "Logseq documentation"
:options {:href "/docs"}}
{:title [:div.flex-row.flex.justify-between.items-center
[:span "Join the community"]
svg/discord]

View File

@ -12,8 +12,6 @@
[:div
[:h1.title {:style {:margin-bottom "0.25rem"}}
"What's your preferred mode?"]
[:span.text-gray-500.text-sm.ml-1
"It'll be used for new pages."]
[:div.mt-4.ml-1
(ui/button

View File

@ -162,3 +162,5 @@
(apply str (repeat n heading-pattern)))))
(defonce default-draw-directory "draws")
(defonce local-repo "local")

View File

@ -35,8 +35,10 @@
(defn get-repo-path
[url]
(->> (take-last 2 (string/split url #"/"))
(string/join "/")))
(if (string/starts-with? url "http")
(->> (take-last 2 (string/split url #"/"))
(string/join "/"))
url))
(defn datascript-db
[repo]
@ -112,7 +114,11 @@
:me/email {}
:me/avatar {}
;; repo
;; local, github, dropbox, etc.
:db/type {}
:encrypted-token {}
;; Git
:repo/url {:db/unique :db.unique/identity}
:repo/cloned? {}
:git/latest-commit {}
@ -1305,39 +1311,42 @@
(swap! conns assoc files-db-name files-db-conn)
(swap! conns assoc db-name db-conn)
(listen-handler repo db-conn)
(d/transact! db-conn [(me-tx (d/db db-conn) me)])))
(when me
(d/transact! db-conn [(me-tx (d/db db-conn) me)]))))
(defn restore!
[{:keys [repos] :as me} listen-handler restore-config-handler]
(doall
(for [{:keys [id url]} repos]
(let [repo url
db-name (datascript-files-db repo)
db-conn (d/create-conn files-db-schema)]
(swap! conns assoc db-name db-conn)
(->
(p/let [stored (-> (.getItem localforage-instance db-name)
(p/then (fn [result]
result))
(p/catch (fn [error]
nil)))
_ (when stored
(let [stored-db (string->db stored)
attached-db (d/db-with stored-db [(me-tx stored-db me)])]
(when (= (:schema stored-db) files-db-schema) ;; check for code update
(reset-conn! db-conn attached-db))))
db-name (datascript-db repo)
db-conn (d/create-conn schema)
_ (swap! conns assoc db-name db-conn)
stored (.getItem localforage-instance db-name)
_ (if stored
(let [stored-db (string->db stored)
attached-db (d/db-with stored-db [(me-tx stored-db me)])]
(when (= (:schema stored-db) schema) ;; check for code update
(reset-conn! db-conn attached-db)))
(d/transact! db-conn [(me-tx (d/db db-conn) me)]))
_ (restore-config-handler repo)]
(listen-handler repo db-conn)))))))
(let [logged? (:name me)]
(doall
(for [{:keys [url]} repos]
(let [repo url
db-name (datascript-files-db repo)
db-conn (d/create-conn files-db-schema)]
(swap! conns assoc db-name db-conn)
(->
(p/let [stored (-> (.getItem localforage-instance db-name)
(p/then (fn [result]
result))
(p/catch (fn [error]
nil)))
_ (when stored
(let [stored-db (string->db stored)
attached-db (d/db-with stored-db [(me-tx stored-db me)])]
(when (= (:schema stored-db) files-db-schema) ;; check for code update
(reset-conn! db-conn attached-db))))
db-name (datascript-db repo)
db-conn (d/create-conn schema)
_ (swap! conns assoc db-name db-conn)
stored (.getItem localforage-instance db-name)
_ (if stored
(let [stored-db (string->db stored)
attached-db (d/db-with stored-db [(me-tx stored-db me)])]
(when (= (:schema stored-db) schema) ;; check for code update
(reset-conn! db-conn attached-db)))
(when logged?
(d/transact! db-conn [(me-tx (d/db db-conn) me)])))
_ (restore-config-handler repo)]
(listen-handler repo db-conn))))))))
(defn- build-edges
[edges]

View File

@ -184,6 +184,8 @@
path (date/current-journal-path format)
file-path (str "/" path)
default-content (default-month-journal-content format)]
(prn {:repo-dir repo-dir
:dir (str repo-dir "/journals")})
(p/let [_ (-> (fs/mkdir (str repo-dir "/journals"))
(p/catch (fn [_e])))
file-exists? (fs/create-if-not-exists repo-dir file-path default-content)]
@ -594,8 +596,6 @@
"Git diff"
:draw
"Draw"
:docs
"Logseq documents"
:else
"Logseq"))
@ -1302,17 +1302,37 @@
(defn watch-for-date!
[]
(js/setInterval #(state/set-today! (date/today))
1000))
10000))
(defn setup-local-repo-if-not-exists!
[]
(if js/window.pfs
(let [repo config/local-repo]
(p/let [result (-> (fs/mkdir (str "/" repo))
(p/catch (fn [_e] nil)))]
(state/set-current-repo! repo)
(db/start-db-conn! nil
repo
db-listen-to-tx!)
(create-month-journal-if-not-exists repo)
(create-config-file-if-not-exists repo)))
(js/setTimeout setup-local-repo-if-not-exists! 100)))
(defn start!
[render]
(let [me (and js/window.user (bean/->clj js/window.user))]
;; async
(-> (p/all (db/restore! me db-listen-to-tx! restore-config!))
(let [me (and js/window.user (bean/->clj js/window.user))
logged? (:name me)
repos (if logged?
(:repos me)
[{:url config/local-repo}])]
(-> (p/all (db/restore! (assoc me :repos repos) db-listen-to-tx! restore-config!))
(p/then
(fn []
(when me (set-state-kv! :me me))
(render)
(when (and (not logged?)
(not (db/get-conn config/local-repo)))
(setup-local-repo-if-not-exists!))
(watch-for-date!)
(when me
(when-let [object-key (:encrypt_object_key me)]
@ -1326,8 +1346,7 @@
(p/catch
(fn [error]
(println "Token decrypted failed")
(state/clear-encrypt-token!)))))))
)))))
(state/clear-encrypt-token!))))))))))))
(defn load-docs!
[]

View File

@ -5,8 +5,7 @@
[frontend.components.file :as file]
[frontend.components.page :as page]
[frontend.components.diff :as diff]
[frontend.components.draw :as draw]
[frontend.components.docs :as docs]))
[frontend.components.draw :as draw]))
(def routes
[["/"
@ -51,8 +50,4 @@
["/draw"
{:name :draw
:view draw/draw}]
["/docs"
{:name :doc
:view docs/docs}]])
:view draw/draw}]])

View File

@ -293,10 +293,6 @@
(set-state! :git/clone-repo repo)
(storage/set :git/clone-repo repo))
(defn logged?
[]
(get-in @state [:me :name]))
(defn set-github-token!
[token]
(swap! state assoc-in [:me :access-token] token))
@ -433,6 +429,10 @@
[]
(:me @state))
(defn logged?
[]
(some? (:name (get-me))))
(defn set-draw!
[value]
(set-state! :draw? value))

View File

@ -0,0 +1,56 @@
(ns frontend.sync.dropbox
(:require ["dropbox" :as dropbox]
[goog.object :as gobj]
[frontend.sync.protocol :refer [Sync] :as sync]
[promesa.core :as p]
[cljs-bean.core :as bean]))
;; Note: there's also a `DropboxTeam`
(defonce DropboxModule (gobj/get dropbox "Dropbox"))
(defonce *dropbox-client (atom nil))
(defn upload-file
[client path contents]
(.filesUpload ^Object client
(bean/->js {:path path
:contents contents
:mode {".tag" "overwrite"}
:autorename true})))
(defrecord Dropbox [token]
Sync
(get-client [this]
(if-let [client @*dropbox-client]
client
(let [client (DropboxModule. #js {:accessToken token})]
(reset! *dropbox-client client)
client)))
(signed? [this]
true)
(get-dir [this path]
(p/let [resp (.filesListFolder ^Object (sync/get-client this) (bean/->js {:path path}))]
(bean/->clj resp)))
(get-more-dir [this cursor]
(p/let [resp (.filesListFolderContinue ^Object (sync/get-client this) (bean/->js {:cursor cursor}))]
(bean/->clj resp)))
(create-file [this path contents]
(upload-file ^Object (sync/get-client this) path contents))
(update-file [this path contents]
(upload-file ^Object (sync/get-client this) path contents))
(get-file-contents-and-metadata [this path]
(->
(p/let [resp (.filesDownload ^Object (sync/get-client this) (bean/->js {:path path}))
file-binary (gobj/get resp "fileBinary")
contents (.toString file-binary)
last-modified-at (gobj/get resp "server_modified")]
{:contents contents
:last-modified-at last-modified-at})
(p/catch
(fn [error]
;; TODO:
(println "Dropbox get file " path " failed:")
(js/console.dir error))
)))
(delete-file [this path]
(.filesDelete ^Object (sync/get-client this) (bean/->js {:path path}))))

View File

@ -0,0 +1,11 @@
(ns frontend.sync.protocol)
(defprotocol Sync
(get-client [this])
(signed? [this])
(get-dir [this path])
(get-more-dir [this more-state])
(create-file [this path contents])
(update-file [this path contents])
(get-file-contents-and-metadata [this path])
(delete-file [this path]))