Tienson Qin %!s(int64=5) %!d(string=hai) anos
pai
achega
fee8e9d407

BIN=BIN
frontend/public/favicon.ico


+ 5 - 5
frontend/src/frontend/components/file.cljs

@@ -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")])))

+ 3 - 3
frontend/src/frontend/components/home.cljs

@@ -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)
        ))))

+ 0 - 58
frontend/src/frontend/components/link.cljs

@@ -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")))))

+ 7 - 6
frontend/src/frontend/components/repo.cljs

@@ -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]

+ 5 - 5
frontend/src/frontend/components/settings.cljs

@@ -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"}})
 

+ 0 - 3
frontend/src/frontend/config.cljs

@@ -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

+ 0 - 8
frontend/src/frontend/core.cljs

@@ -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)

+ 0 - 6
frontend/src/frontend/db.cljs

@@ -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)))
 

+ 5 - 6
frontend/src/frontend/fs.cljs

@@ -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))

+ 24 - 25
frontend/src/frontend/git.cljs

@@ -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 "[email protected]"}
                    :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))))

+ 154 - 161
frontend/src/frontend/handler.cljs

@@ -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)))))))
-
-(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
+                                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 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))))

+ 4 - 13
frontend/src/frontend/layout.cljs

@@ -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

+ 1 - 1
frontend/src/frontend/page.cljs

@@ -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)))))

+ 0 - 2
frontend/src/frontend/routes.cljs

@@ -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})

+ 13 - 8
frontend/src/frontend/state.cljs

@@ -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
                   }))

+ 6 - 0
frontend/src/frontend/util.cljs

@@ -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 {})))

+ 0 - 1
readme.org

@@ -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