mirror of https://github.com/logseq/logseq
Fix clone
parent
9265ba957d
commit
fee8e9d407
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -8,11 +8,11 @@
|
|||
[clojure.string :as string]))
|
||||
|
||||
(rum/defc files-list
|
||||
[files]
|
||||
[current-repo files]
|
||||
[:div
|
||||
(if (seq files)
|
||||
(let [files-set (set files)
|
||||
prefix [(files-set "tasks.org") (files-set "links.org")]
|
||||
prefix [(files-set "tasks.org")]
|
||||
files (->> (remove (set prefix) files)
|
||||
(concat prefix)
|
||||
(remove nil?))]
|
||||
|
@ -23,7 +23,7 @@
|
|||
:key file
|
||||
:style {:overflow "hidden"}
|
||||
:on-click (fn []
|
||||
(handler/load-file file)
|
||||
(handler/load-file current-repo file)
|
||||
(handler/toggle-drawer? false))}
|
||||
(mui/list-item-text file)))))
|
||||
"Loading...")])
|
||||
|
@ -31,7 +31,7 @@
|
|||
(rum/defc edit < rum/reactive
|
||||
[]
|
||||
(let [state (rum/react state/state)
|
||||
{:keys [current-file contents]} state]
|
||||
{:keys [current-repo current-file contents]} state]
|
||||
(mui/container
|
||||
{:id "root-container"
|
||||
:style {:display "flex"
|
||||
|
@ -62,5 +62,5 @@
|
|||
(mui/button {:variant "contained"
|
||||
:color "primary"
|
||||
:on-click (fn []
|
||||
(handler/alter-file current-file))}
|
||||
(handler/alter-file current-repo current-file))}
|
||||
"Submit")])))
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
(rum/defc home < rum/reactive
|
||||
[]
|
||||
(let [state (rum/react state/state)
|
||||
{:keys [user tokens repos repo-url cloned? github-username github-token github-repo contents loadings current-file files width drawer? tasks links cloning?]} state
|
||||
{:keys [user tokens repos repo-url cloned? github-token github-repo contents loadings current-repo current-file files width drawer? tasks cloning?]} state
|
||||
loading? (get loadings current-file)
|
||||
width (or width (util/get-width))
|
||||
mobile? (and width (<= width 600))]
|
||||
|
@ -56,7 +56,7 @@
|
|||
:spacing 3}
|
||||
(when-not mobile?
|
||||
(mui/grid {:xs 2}
|
||||
(file/files-list files)))
|
||||
(file/files-list current-repo files)))
|
||||
|
||||
(if (and (not mobile?)
|
||||
(not drawer?))
|
||||
|
@ -82,5 +82,5 @@
|
|||
|
||||
:else
|
||||
[:div "TBC"]
|
||||
;; (settings/settings-form github-username github-token github-repo)
|
||||
;; (settings/settings-form github-token github-repo)
|
||||
))))
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
(ns frontend.components.link
|
||||
(:require [rum.core :as rum]
|
||||
[frontend.mui :as mui]
|
||||
[frontend.util :as util]
|
||||
[frontend.state :as state]
|
||||
[frontend.handler :as handler]
|
||||
[clojure.string :as string]))
|
||||
|
||||
(rum/defc links < rum/reactive
|
||||
[]
|
||||
(let [state (rum/react state/state)
|
||||
links (reverse (get state :links))]
|
||||
(mui/container
|
||||
{:id "root-container"
|
||||
:style {:display "flex"
|
||||
:justify-content "center"
|
||||
;; TODO: fewer spacing for mobile, 24px
|
||||
:margin-top 64}}
|
||||
(if (seq links)
|
||||
(mui/list
|
||||
(for [[idx link] (util/indexed links)]
|
||||
(mui/list-item
|
||||
{:key (str "link-" idx)}
|
||||
(mui/list-item-text
|
||||
[:a {:href link
|
||||
:target "_blank"}
|
||||
link]))))
|
||||
[:div "Loading..."]))))
|
||||
|
||||
(rum/defcs dialog < (rum/local "" :link)
|
||||
[state open?]
|
||||
(let [link (get state :link)]
|
||||
(mui/dialog
|
||||
{:open open?
|
||||
:on-close (fn []
|
||||
(handler/toggle-link-dialog? false))}
|
||||
(mui/dialog-title "Add new link")
|
||||
(mui/dialog-content
|
||||
(mui/text-field
|
||||
{:auto-focus true
|
||||
:auto-complete "off"
|
||||
:margin "dense"
|
||||
:id "link"
|
||||
:label "Link"
|
||||
:full-width true
|
||||
:value @link
|
||||
:on-change (fn [e] (reset! link (util/evalue e)))}))
|
||||
(mui/dialog-actions
|
||||
(mui/button {:on-click (fn []
|
||||
(handler/toggle-link-dialog? false))
|
||||
:color "primary"}
|
||||
"Cancel")
|
||||
(mui/button {:on-click (fn []
|
||||
(when-not (string/blank? @link)
|
||||
(handler/add-new-link @link
|
||||
"New link")))
|
||||
:color "primary"}
|
||||
"Submit")))))
|
|
@ -8,12 +8,13 @@
|
|||
|
||||
(defn repos
|
||||
[repos]
|
||||
[:div#repos
|
||||
[:ul
|
||||
(for [{:keys [url id]} repos]
|
||||
[:li {:key id}
|
||||
[:a {:href url}
|
||||
(string/replace url "https://github.com/" "")]])]])
|
||||
(when (seq repos)
|
||||
[:div#repos
|
||||
[:ul
|
||||
(for [{:keys [url id]} (vals repos)]
|
||||
[:li {:key id}
|
||||
[:a {:href url}
|
||||
(string/replace url "https://github.com/" "")]])]]))
|
||||
|
||||
(defn add-repo
|
||||
[repo-url]
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
[clojure.string :as string]))
|
||||
|
||||
(defn settings-form
|
||||
[github-username github-token github-repo]
|
||||
[github-token github-repo]
|
||||
[:form {:style {:min-width 300}}
|
||||
(mui/grid
|
||||
{:container true
|
||||
|
@ -24,14 +24,14 @@
|
|||
:color "primary"
|
||||
:on-click (fn []
|
||||
(when (and github-token github-repo)
|
||||
(handler/clone github-username github-token github-repo)))}
|
||||
(handler/clone github-token github-repo)))}
|
||||
"Sync"))])
|
||||
|
||||
(rum/defc settings < rum/reactive
|
||||
[]
|
||||
;; Change username, repo and basic token
|
||||
;; Change repo and basic token
|
||||
(let [state (rum/react state/state)
|
||||
{:keys [github-username github-token github-repo]} state]
|
||||
{:keys [github-token github-repo]} state]
|
||||
(mui/container
|
||||
{:id "root-container"
|
||||
:style {:display "flex"
|
||||
|
@ -40,7 +40,7 @@
|
|||
|
||||
[:div
|
||||
|
||||
(settings-form github-username github-token github-repo)
|
||||
(settings-form github-token github-repo)
|
||||
|
||||
(mui/divider {:style {:margin "24px 0"}})
|
||||
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
(ns frontend.config)
|
||||
|
||||
(defonce dir "/gitnotes")
|
||||
|
||||
(defonce tasks-org "tasks.org")
|
||||
(defonce links-org "links.org")
|
||||
(defonce hidden-file ".hidden")
|
||||
(defonce dev? ^boolean goog.DEBUG)
|
||||
(def website
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
(ns frontend.core
|
||||
(:require [rum.core :as rum]
|
||||
[frontend.git :as git]
|
||||
[frontend.fs :as fs]
|
||||
[frontend.util :as util]
|
||||
[frontend.state :as state]
|
||||
[frontend.handler :as handler]
|
||||
|
@ -19,13 +18,6 @@
|
|||
;; so it is available even in :advanced release builds
|
||||
(handler/get-me)
|
||||
|
||||
(handler/load-from-disk)
|
||||
|
||||
(when (:cloned? @state/state)
|
||||
(handler/initial-db!)
|
||||
(handler/periodically-pull)
|
||||
(handler/periodically-push-tasks))
|
||||
|
||||
(handler/listen-to-resize)
|
||||
|
||||
;; (handler/request-notifications-if-not-asked)
|
||||
|
|
|
@ -5,11 +5,6 @@
|
|||
|
||||
(def conn (d/create-conn))
|
||||
|
||||
;; links
|
||||
[:link/id
|
||||
:link/label
|
||||
:link/link]
|
||||
|
||||
;; TODO: added_at, started_at, schedule, deadline
|
||||
(def qualified-map
|
||||
{:file :heading/file
|
||||
|
@ -111,7 +106,6 @@
|
|||
;; transactions
|
||||
(defn transact-headings!
|
||||
[headings]
|
||||
(prn "headings: " headings)
|
||||
(let [headings (safe-headings headings)]
|
||||
(d/transact! conn headings)))
|
||||
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
(ns frontend.fs
|
||||
(:require [frontend.config :refer [dir]]))
|
||||
(ns frontend.fs)
|
||||
|
||||
(defn mkdir
|
||||
[]
|
||||
[dir]
|
||||
(js/pfs.mkdir dir))
|
||||
|
||||
(defn readdir
|
||||
[]
|
||||
[dir]
|
||||
(js/pfs.readdir dir))
|
||||
|
||||
(defn read-file
|
||||
[path]
|
||||
[dir path]
|
||||
(js/pfs.readFile (str dir "/" path)
|
||||
(clj->js {:encoding "utf8"})))
|
||||
|
||||
(defn write-file
|
||||
[path content]
|
||||
[dir path content]
|
||||
(js/pfs.writeFile (str dir "/" path) content))
|
||||
|
|
|
@ -2,78 +2,77 @@
|
|||
(:refer-clojure :exclude [clone])
|
||||
(:require [promesa.core :as p]
|
||||
[frontend.util :as util]
|
||||
[frontend.config :refer [dir]]))
|
||||
[clojure.string :as string]))
|
||||
|
||||
;; only support Github now
|
||||
(defn auth
|
||||
[token]
|
||||
(prn {:token token})
|
||||
{:onAuth (fn []
|
||||
(clj->js
|
||||
{:username token
|
||||
:password "x-oauth-basic"}))})
|
||||
{:username token
|
||||
:password "x-oauth-basic"})
|
||||
|
||||
(defn with-auth
|
||||
[token m]
|
||||
(prn {:arguments (merge (auth token)
|
||||
m)})
|
||||
(clj->js
|
||||
(merge (auth token)
|
||||
m)))
|
||||
|
||||
(defn get-repo-dir
|
||||
[repo-url]
|
||||
(str "/" (last (string/split repo-url #"/"))))
|
||||
|
||||
(defn clone
|
||||
[username token repo]
|
||||
[repo-url token]
|
||||
(js/git.clone (with-auth token
|
||||
{:dir dir
|
||||
:url repo
|
||||
{:dir (get-repo-dir repo-url)
|
||||
:url repo-url
|
||||
:corsProxy "https://cors.isomorphic-git.org"
|
||||
:singleBranch true
|
||||
:depth 1})))
|
||||
|
||||
(defn list-files
|
||||
[]
|
||||
[repo-url]
|
||||
(js/git.listFiles (clj->js
|
||||
{:dir dir
|
||||
{:dir (get-repo-dir repo-url)
|
||||
:ref "HEAD"})))
|
||||
|
||||
(defn pull
|
||||
[username token]
|
||||
[repo-url token]
|
||||
(js/git.pull (with-auth token
|
||||
{:dir dir
|
||||
{:dir (get-repo-dir repo-url)
|
||||
:ref "master"
|
||||
:singleBranch true})))
|
||||
(defn add
|
||||
[file]
|
||||
[repo-url file]
|
||||
(js/git.add (clj->js
|
||||
{:dir dir
|
||||
{:dir (get-repo-dir repo-url)
|
||||
:filepath file})))
|
||||
|
||||
(defn commit
|
||||
[message]
|
||||
[repo-url message]
|
||||
(js/git.commit (clj->js
|
||||
{:dir dir
|
||||
{:dir (get-repo-dir repo-url)
|
||||
:author {:name "Orgnote"
|
||||
:email "orgnote@hello.world"}
|
||||
:message message})))
|
||||
|
||||
(defn push
|
||||
[token]
|
||||
[repo-url token]
|
||||
(js/git.push (with-auth token
|
||||
{:dir dir
|
||||
{:dir (get-repo-dir repo-url)
|
||||
:remote "origin"
|
||||
:ref "master"
|
||||
})))
|
||||
|
||||
(defn add-commit-push
|
||||
[file message token push-ok-handler push-error-handler]
|
||||
[repo-url file message token push-ok-handler push-error-handler]
|
||||
(util/p-handle
|
||||
(let [files (if (coll? file) file [file])]
|
||||
(doseq [file files]
|
||||
(add file)))
|
||||
(add repo-url file)))
|
||||
(fn [_]
|
||||
(util/p-handle
|
||||
(commit message)
|
||||
(commit repo-url message)
|
||||
(fn [_]
|
||||
(push token)
|
||||
(push repo-url token)
|
||||
(push-ok-handler))
|
||||
push-error-handler))))
|
||||
|
|
|
@ -15,9 +15,14 @@
|
|||
[frontend.api :as api])
|
||||
(:import [goog.events EventHandler]))
|
||||
|
||||
;; We only support Github token now
|
||||
(defn get-token
|
||||
[]
|
||||
(:oauth_token (first (:tokens @state/state))))
|
||||
|
||||
(defn load-file
|
||||
([path]
|
||||
(util/p-handle (fs/read-file path)
|
||||
([repo-url path]
|
||||
(util/p-handle (fs/read-file (git/get-repo-dir repo-url) path)
|
||||
(fn [content]
|
||||
(let [state @state/state
|
||||
state' (-> state
|
||||
|
@ -25,8 +30,8 @@
|
|||
(assoc-in [:loadings path] false)
|
||||
(assoc :current-file path))]
|
||||
(reset! state/state state')))))
|
||||
([path state-handler]
|
||||
(util/p-handle (fs/read-file path)
|
||||
([repo-url path state-handler]
|
||||
(util/p-handle (fs/read-file (git/get-repo-dir repo-url) path)
|
||||
(fn [content]
|
||||
(state-handler content)))))
|
||||
|
||||
|
@ -40,73 +45,66 @@
|
|||
pattern)))) patterns))
|
||||
|
||||
(defn load-files
|
||||
[]
|
||||
(util/p-handle (git/list-files)
|
||||
[repo-url]
|
||||
(util/p-handle (git/list-files repo-url)
|
||||
(fn [files]
|
||||
(when (> (count files) 0)
|
||||
(let [files (js->clj files)]
|
||||
(if (contains? (set files) config/hidden-file)
|
||||
(load-file config/hidden-file
|
||||
(load-file repo-url config/hidden-file
|
||||
(fn [patterns-content]
|
||||
(let [patterns (string/split patterns-content #"\n")
|
||||
files (remove (fn [path] (hidden? path patterns)) files)]
|
||||
(swap! state/state
|
||||
assoc :files files))))
|
||||
(when patterns-content
|
||||
(let [patterns (string/split patterns-content #"\n")
|
||||
files (remove (fn [path] (hidden? path patterns)) files)]
|
||||
(swap! state/state
|
||||
assoc-in [:repos repo-url :files] files)))))
|
||||
(swap! state/state
|
||||
assoc :files files)))))))
|
||||
assoc-in [:repos repo-url :files] files)))))))
|
||||
|
||||
(defn extract-links
|
||||
[form]
|
||||
(let [links (atom [])]
|
||||
(clojure.walk/postwalk
|
||||
(fn [x]
|
||||
(when (and (vector? x)
|
||||
(= "Link" (first x)))
|
||||
(let [[_ {:keys [url label]}] x
|
||||
[_ {:keys [protocol link]}] url
|
||||
link (str protocol ":" link)]
|
||||
(swap! links conj link)))
|
||||
x)
|
||||
form)
|
||||
@links))
|
||||
;; (defn extract-links
|
||||
;; [form]
|
||||
;; (let [links (atom [])]
|
||||
;; (clojure.walk/postwalk
|
||||
;; (fn [x]
|
||||
;; (when (and (vector? x)
|
||||
;; (= "Link" (first x)))
|
||||
;; (let [[_ {:keys [url label]}] x
|
||||
;; [_ {:keys [protocol link]}] url
|
||||
;; link (str protocol ":" link)]
|
||||
;; (swap! links conj link)))
|
||||
;; x)
|
||||
;; form)
|
||||
;; @links))
|
||||
|
||||
(defn load-links
|
||||
([]
|
||||
(load-links config/links-org))
|
||||
([path]
|
||||
(util/p-handle (fs/read-file path)
|
||||
(fn [content]
|
||||
(when content
|
||||
(let [blocks (org/parse-json content)
|
||||
blocks (-> (.parse js/JSON blocks)
|
||||
(js->clj :keywordize-keys true))]
|
||||
(when (seq blocks)
|
||||
(swap! state/state assoc :links (extract-links blocks)))))))))
|
||||
|
||||
(defn load-from-disk
|
||||
(defn load-cloned?
|
||||
[]
|
||||
(let [cloned? (storage/get :cloned?)]
|
||||
(swap! state/state assoc
|
||||
:cloned? cloned?
|
||||
:github-username (storage/get :github-username)
|
||||
:github-token (storage/get :github-token)
|
||||
:github-repo (storage/get :github-repo))
|
||||
(when cloned?
|
||||
(load-files)
|
||||
(load-links))))
|
||||
(storage/get :cloned?))
|
||||
|
||||
(defn set-cloned?
|
||||
[repo-url value]
|
||||
(let [cloned (or (load-cloned?) {})
|
||||
new-cloned (assoc cloned repo-url value)]
|
||||
(storage/set :cloned? new-cloned)
|
||||
new-cloned))
|
||||
|
||||
;; TODO: remove this
|
||||
(declare load-repo-to-db!)
|
||||
|
||||
(defn pull
|
||||
[repo-url token]
|
||||
(util/p-handle (git/pull repo-url token)
|
||||
(fn [result]
|
||||
;; TODO: diff
|
||||
(-> (load-files repo-url)
|
||||
(p/then
|
||||
(fn []
|
||||
(load-repo-to-db! repo-url)))))))
|
||||
|
||||
(defn periodically-pull
|
||||
[]
|
||||
(let [username (storage/get :github-username)
|
||||
token (storage/get :github-token)
|
||||
pull (fn []
|
||||
(util/p-handle (git/pull username token)
|
||||
(fn [_result]
|
||||
;; TODO: diff
|
||||
(load-files)))
|
||||
(load-links))]
|
||||
(pull)
|
||||
(js/setInterval pull
|
||||
[repo-url]
|
||||
(when-let [token (get-token)]
|
||||
(pull repo-url token)
|
||||
(js/setInterval #(pull repo-url token)
|
||||
(* 60 1000))))
|
||||
|
||||
(defn add-transaction
|
||||
|
@ -121,19 +119,20 @@
|
|||
[transactions]
|
||||
(let [transactions (reverse transactions)]
|
||||
(str
|
||||
"Orgnote auto save tasks.\n\n"
|
||||
"Gitnotes auto save tasks.\n\n"
|
||||
(string/join "\n" transactions))))
|
||||
|
||||
(defn periodically-push-tasks
|
||||
[]
|
||||
(let [github-token (storage/get :github-token)
|
||||
[repo-url]
|
||||
(let [token (get-token)
|
||||
push (fn []
|
||||
(let [transactions (:tasks-transactions @state/state)]
|
||||
(when (seq transactions)
|
||||
(git/add-commit-push
|
||||
repo-url
|
||||
config/tasks-org
|
||||
(transactions->commit-msg transactions)
|
||||
github-token
|
||||
token
|
||||
(fn []
|
||||
(prn "Commit tasks to Github.")
|
||||
(clear-transactions!))
|
||||
|
@ -143,19 +142,20 @@
|
|||
(* 5 1000))))
|
||||
|
||||
(defn clone
|
||||
[github-username github-token github-repo]
|
||||
[token repo]
|
||||
(util/p-handle
|
||||
(do
|
||||
(swap! state/state assoc
|
||||
:cloning? true)
|
||||
(git/clone github-username github-token github-repo))
|
||||
(prn "Debug: cloning")
|
||||
(swap! state/state assoc-in
|
||||
[:repos repo :cloning?] true)
|
||||
(git/clone repo token))
|
||||
(fn []
|
||||
(swap! state/state assoc
|
||||
:cloned? true)
|
||||
(storage/set :cloned? true)
|
||||
(swap! state/state assoc
|
||||
:cloning? false)
|
||||
(periodically-pull))
|
||||
(prn "Debug: cloned")
|
||||
(swap! state/state assoc-in
|
||||
[:repos repo :cloned?] true)
|
||||
(set-cloned? repo true)
|
||||
(swap! state/state assoc-in
|
||||
[:repos repo :cloning?] false))
|
||||
(fn [e]
|
||||
(prn "Clone failed, reason: " e))))
|
||||
|
||||
|
@ -179,28 +179,6 @@
|
|||
[]
|
||||
(swap! state/state assoc :current-file nil))
|
||||
|
||||
(defn toggle-link-dialog?
|
||||
[switch]
|
||||
(swap! state/state assoc :add-link-dialog? switch))
|
||||
|
||||
(defn add-new-link
|
||||
[link message]
|
||||
(if-let [github-token (storage/get :github-token)]
|
||||
(util/p-handle (fs/read-file config/links-org)
|
||||
(fn [content]
|
||||
(let [content' (str content "\n** " link)]
|
||||
(util/p-handle
|
||||
(fs/write-file config/links-org content')
|
||||
(fn [_]
|
||||
(git/add-commit-push config/links-org
|
||||
message
|
||||
github-token
|
||||
(fn []
|
||||
(toggle-link-dialog? false))
|
||||
(fn []
|
||||
(.log js/console "Failed to push the new link."))))))))
|
||||
(.log js/console "Github token does not exists!")))
|
||||
|
||||
(defn new-notification
|
||||
[text]
|
||||
(js/Notification. "Gitnotes" #js {:body text
|
||||
|
@ -257,70 +235,68 @@
|
|||
(js/setTimeout hide-snackbar 3000))
|
||||
|
||||
(defn alter-file
|
||||
[file]
|
||||
(when-let [content (get-in @state/state [:contents file])]
|
||||
(let [content' (get-in @state/state [:editing-files file])]
|
||||
[repo-url file]
|
||||
(when-let [content (get-in @state/state [:repos repo-url :contents file])]
|
||||
(let [content' (get-in @state/state [:repos repo-url :editing-files file])]
|
||||
(when-not (= (string/trim content)
|
||||
(string/trim content'))
|
||||
(let [github-token (:github-token @state/state)
|
||||
path [:commit-message file]
|
||||
(let [token (get-token)
|
||||
path [:repos repo-url :commit-message file]
|
||||
message (get-in @state/state path (str "Update " file))]
|
||||
(util/p-handle
|
||||
(fs/write-file file content')
|
||||
(fs/write-file (git/get-repo-dir repo-url) file content')
|
||||
(fn [_]
|
||||
(git/add-commit-push file
|
||||
(git/add-commit-push repo-url
|
||||
file
|
||||
message
|
||||
github-token
|
||||
token
|
||||
(fn []
|
||||
(swap! state/state util/dissoc-in path)
|
||||
(swap! state/state assoc-in [:contents file] content')
|
||||
(swap! state/state assoc-in [:repos repo-url :contents file] content')
|
||||
(show-snackbar "File updated!")
|
||||
(change-page :home))
|
||||
(fn []
|
||||
(prn "Failed to update file."))))))))))
|
||||
|
||||
(defn clear-storage
|
||||
[]
|
||||
(js/window.pfs._idb.wipe)
|
||||
(storage/set :cloned? false)
|
||||
(swap! state/state assoc
|
||||
:cloned? false
|
||||
:contents nil
|
||||
:files nil)
|
||||
(clone (:github-username @state/state)
|
||||
(:github-token @state/state)
|
||||
(:github-repo @state/state)))
|
||||
[repo-url]
|
||||
(let [token (get-token)]
|
||||
(js/window.pfs._idb.wipe)
|
||||
(storage/set :cloned? false)
|
||||
(swap! state/state assoc
|
||||
:cloned? false
|
||||
:contents nil
|
||||
:files nil)
|
||||
(clone token repo-url)))
|
||||
|
||||
(defn check
|
||||
[marker pos]
|
||||
(let [file config/tasks-org
|
||||
github-token (storage/get :github-token)]
|
||||
(when-let [content (get-in @state/state [:contents file])]
|
||||
[repo-url file marker pos]
|
||||
(let [token (get-token)]
|
||||
(when-let [content (get-in @state/state [:repos repo-url :contents file])]
|
||||
(let [content' (str (subs content 0 pos)
|
||||
(-> (subs content pos)
|
||||
(string/replace-first marker "DONE")))]
|
||||
;; TODO: optimize, only update the specific block
|
||||
;; (build-tasks content' file)
|
||||
(util/p-handle
|
||||
(fs/write-file file content')
|
||||
(fs/write-file (git/get-repo-dir repo-url) file content')
|
||||
(fn [_]
|
||||
(swap! state/state assoc-in [:contents file] content')
|
||||
(swap! state/state assoc-in [:repos repo-url :contents file] content')
|
||||
(add-transaction (util/format "`%s` marked as DONE." marker))))))))
|
||||
|
||||
(defn uncheck
|
||||
[pos]
|
||||
(let [file config/tasks-org
|
||||
github-token (storage/get :github-token)]
|
||||
(when-let [content (get-in @state/state [:contents file])]
|
||||
[repo-url file pos]
|
||||
(let [token (get-token)]
|
||||
(when-let [content (get-in @state/state [:repos repo-url :contents file])]
|
||||
(let [content' (str (subs content 0 pos)
|
||||
(-> (subs content pos)
|
||||
(string/replace-first "DONE" "TODO")))]
|
||||
;; TODO: optimize, only update the specific block
|
||||
;; (build-tasks content' file)
|
||||
(util/p-handle
|
||||
(fs/write-file file content')
|
||||
(fs/write-file (git/get-repo-dir repo-url) file content')
|
||||
(fn [_]
|
||||
(swap! state/state assoc-in [:contents file] content')
|
||||
(swap! state/state assoc-in [:repos repo-url :contents file] content')
|
||||
(add-transaction "DONE rollbacks to TODO.")))))))
|
||||
|
||||
(defn extract-headings
|
||||
|
@ -334,21 +310,21 @@
|
|||
headings)))
|
||||
|
||||
(defn load-all-contents!
|
||||
[ok-handler]
|
||||
(let [files (:files @state/state)]
|
||||
[repo-url ok-handler]
|
||||
(let [files (get-in @state/state [:repos repo-url :files])]
|
||||
(-> (p/all (for [file files]
|
||||
(load-file file
|
||||
(load-file repo-url file
|
||||
(fn [content]
|
||||
(swap! state/state
|
||||
assoc-in [:contents file] content) ))))
|
||||
assoc-in [:repos repo-url :contents file] content) ))))
|
||||
(p/then
|
||||
(fn [_]
|
||||
(prn "Files are loaded!")
|
||||
(ok-handler))))))
|
||||
|
||||
(defn extract-all-headings
|
||||
[]
|
||||
(let [contents (:contents @state/state)]
|
||||
[repo-url]
|
||||
(let [contents (get-in @state/state [:repos repo-url :contents])]
|
||||
(vec
|
||||
(mapcat
|
||||
(fn [[file content] contents]
|
||||
|
@ -357,31 +333,19 @@
|
|||
|
||||
(defonce headings-atom (atom nil))
|
||||
|
||||
(defn initial-db!
|
||||
[]
|
||||
(db/init)
|
||||
(load-all-contents!
|
||||
(fn []
|
||||
(let [headings (extract-all-headings)]
|
||||
(reset! headings-atom headings)
|
||||
(db/transact-headings! headings)))))
|
||||
|
||||
(defn get-me
|
||||
[]
|
||||
(api/get-me (fn [body]
|
||||
(let [{:keys [user tokens repos]} body]
|
||||
(swap! state/state assoc
|
||||
:user user
|
||||
:tokens tokens
|
||||
:repos repos)))
|
||||
(fn [response]
|
||||
(prn "Can't get user's information, error response: " response))))
|
||||
(defn load-repo-to-db!
|
||||
[repo-url]
|
||||
(load-all-contents! repo-url
|
||||
(fn []
|
||||
(let [headings (extract-all-headings repo-url)]
|
||||
(reset! headings-atom headings)
|
||||
(db/transact-headings! headings)))))
|
||||
|
||||
(defn get-user-token-repos
|
||||
[]
|
||||
(let [user (:user @state/state)
|
||||
token (:oauth_token (first (:tokens @state/state)))
|
||||
repos (map :url (:repos @state/state))]
|
||||
repos (map :url (vals (:repos @state/state)))]
|
||||
[user token repos]))
|
||||
|
||||
(defn add-repo-and-clone
|
||||
|
@ -392,15 +356,44 @@
|
|||
(swap! state/state
|
||||
update :repos conj repo)
|
||||
;; clone
|
||||
(clone (:name user) token url)))
|
||||
(clone token url)))
|
||||
(fn [response]
|
||||
(prn "Can't add repo: " url))))
|
||||
|
||||
(defn sync
|
||||
[]
|
||||
(let [[user token repos] (get-user-token-repos)]
|
||||
(let [[_user token repos] (get-user-token-repos)]
|
||||
(doseq [repo repos]
|
||||
(prn {:name (:name user)
|
||||
:token token
|
||||
:repo repo})
|
||||
(clone (:name user) token repo))))
|
||||
(pull token repo))))
|
||||
|
||||
(defn periodically-pull-and-push
|
||||
[repo-url]
|
||||
;; automatically pull
|
||||
(periodically-pull repo-url)
|
||||
|
||||
;; automatically push
|
||||
(periodically-push-tasks repo-url))
|
||||
|
||||
(defn get-me
|
||||
[]
|
||||
(api/get-me
|
||||
(fn [body]
|
||||
(let [{:keys [user tokens repos]} body]
|
||||
(swap! state/state assoc
|
||||
:user user
|
||||
:tokens tokens
|
||||
:repos (util/index-by repos :url))
|
||||
(db/init)
|
||||
(let [repos (map :url repos)
|
||||
cloned (load-cloned?)
|
||||
token (get-token)]
|
||||
(when (seq repos)
|
||||
(doseq [repo-url repos]
|
||||
(if (get cloned repo-url)
|
||||
(periodically-pull-and-push repo-url)
|
||||
(-> (clone token repo-url)
|
||||
(p/then
|
||||
(fn []
|
||||
(periodically-pull-and-push repo-url))))))))))
|
||||
(fn [response]
|
||||
(prn "Can't get user's information, error response: " response))))
|
||||
|
|
|
@ -2,16 +2,15 @@
|
|||
(:require [frontend.mui :as mui]
|
||||
[frontend.handler :as handler]
|
||||
[frontend.state :as state]
|
||||
[frontend.components.link :as link]
|
||||
[frontend.components.file :as file]
|
||||
[frontend.components.repo :as repo]
|
||||
[rum.core :as rum]
|
||||
[clojure.string :as string]))
|
||||
|
||||
(rum/defc frame < rum/reactive
|
||||
[content width link-dialog?]
|
||||
[content width]
|
||||
(let [state (rum/react state/state)
|
||||
{:keys [files drawer? snackbar? snackbar-message]} state
|
||||
{:keys [files drawer? snackbar? snackbar-message current-repo]} state
|
||||
mobile? (and width (<= width 600))]
|
||||
(mui/theme-provider
|
||||
{:theme (mui/custom-theme)}
|
||||
|
@ -46,13 +45,7 @@
|
|||
(mui/button {:color "inherit"
|
||||
:on-click (fn []
|
||||
(handler/change-page :settings))}
|
||||
"Settings")
|
||||
|
||||
(mui/icon-button {:color "inherit"
|
||||
:class "addButton"
|
||||
:on-click (fn []
|
||||
(handler/toggle-link-dialog? true))}
|
||||
(mui/add-icon))))
|
||||
"Settings")))
|
||||
|
||||
(repo/repos (:repos state))
|
||||
|
||||
|
@ -66,9 +59,7 @@
|
|||
:on-close (fn []
|
||||
(handler/toggle-drawer? false))}
|
||||
[:div {:style {:width 240}}
|
||||
(file/files-list files)]))
|
||||
|
||||
(link/dialog link-dialog?)
|
||||
(file/files-list current-repo files)]))
|
||||
|
||||
(mui/snackbar {:open snackbar?
|
||||
:auto-hide-duration 3000
|
||||
|
|
|
@ -9,4 +9,4 @@
|
|||
(let [state (rum/react state/state)
|
||||
current-page (get state :current-page :home)]
|
||||
(when-let [view (get routes/routes current-page)]
|
||||
(layout/frame (view) (:width state) (:add-link-dialog? state)))))
|
||||
(layout/frame (view) (:width state)))))
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
(ns frontend.routes
|
||||
(:require [frontend.components.home :as home]
|
||||
[frontend.components.link :as link]
|
||||
[frontend.components.settings :as settings]
|
||||
[frontend.components.file :as file]
|
||||
))
|
||||
|
||||
(def routes
|
||||
{:home home/home
|
||||
:links link/links
|
||||
:settings settings/settings
|
||||
:edit-file file/edit})
|
||||
|
|
|
@ -3,18 +3,23 @@
|
|||
|
||||
(def state (atom {:user nil
|
||||
:tokens []
|
||||
:repos []
|
||||
:repos {}
|
||||
;; nested in repos -> repo->url -> map
|
||||
;; {
|
||||
;; :cloning? false
|
||||
;; :cloned? (storage/get :cloned?)
|
||||
;; :files []
|
||||
;; :contents {} ; file name -> string
|
||||
|
||||
;; :loadings {} ; file name -> bool
|
||||
;; }
|
||||
|
||||
:repo-url ""
|
||||
:current-page :home
|
||||
:cloning? false
|
||||
:cloned? (storage/get :cloned?)
|
||||
:files []
|
||||
:contents {} ; file name -> string
|
||||
:current-repo nil
|
||||
:current-file nil
|
||||
:loadings {} ; file name -> bool
|
||||
|
||||
:width nil
|
||||
:drawer? false
|
||||
:tasks {}
|
||||
:links []
|
||||
:add-link-dialog? false
|
||||
}))
|
||||
|
|
|
@ -86,3 +86,9 @@
|
|||
(not-empty (into {} (remove (comp nil? second)) el))
|
||||
el))
|
||||
nm))
|
||||
|
||||
(defn index-by
|
||||
[col k]
|
||||
(->> (map (fn [entry] [(get entry k) entry])
|
||||
col)
|
||||
(into {})))
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
** File directory example
|
||||
#+BEGIN_SRC shell
|
||||
links.org # the app will extract links from this file
|
||||
tasks.org # the app will extract todos from this file
|
||||
other_notes.org
|
||||
other_notes.markdown
|
||||
|
|
Loading…
Reference in New Issue