From 6c7fc9c64c464748991b33d484d4f056caae9003 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Fri, 3 Apr 2020 23:06:42 +0800 Subject: [PATCH] remove posh --- web/deps.edn | 4 +- web/public/static/js/manifest.edn | 2 +- web/src/frontend/components/agenda.cljs | 116 ++++++------- web/src/frontend/components/file.cljs | 26 +-- web/src/frontend/components/home.cljs | 9 +- web/src/frontend/components/repo.cljs | 17 +- web/src/frontend/components/sidebar.cljs | 29 ++-- web/src/frontend/db.cljs | 201 +++++++++++------------ web/src/frontend/format/org/block.cljs | 12 +- web/src/frontend/git.cljs | 1 + web/src/frontend/handler.cljs | 136 +++++++-------- web/src/frontend/page.cljs | 9 +- web/src/frontend/posh.cljs | 4 - web/src/frontend/state.cljs | 3 +- 14 files changed, 286 insertions(+), 283 deletions(-) delete mode 100644 web/src/frontend/posh.cljs diff --git a/web/deps.edn b/web/deps.edn index 021be07e5..ebeb6a11d 100644 --- a/web/deps.edn +++ b/web/deps.edn @@ -4,9 +4,7 @@ cider/cider-nrepl {:mvn/version "0.23.0-SNAPSHOT"} binaryage/devtools {:mvn/version "0.9.10"} - sablono {:mvn/version "0.8.1"} - rum {:local/root "/home/tienson/codes/source/clj/rum"} - posh {:local/root "/home/tienson/codes/projects/posh"} + rum {:mvn/version "0.11.4"} datascript-transit {:mvn/version "0.3.0"} funcool/promesa {:mvn/version "4.0.2"} medley {:mvn/version "1.2.0"} diff --git a/web/public/static/js/manifest.edn b/web/public/static/js/manifest.edn index ec4301b52..30de245f7 100644 --- a/web/public/static/js/manifest.edn +++ b/web/public/static/js/manifest.edn @@ -1 +1 @@ -[{:module-id :main, :name :main, :output-name "main.js", :entries [devtools.preload shadow.cljs.devtools.client.browser cljs.user shadow.cljs.devtools.client.env frontend.core], :depends-on nil, :sources ["goog/base.js" "goog/debug/error.js" "goog/dom/nodetype.js" "goog/asserts/asserts.js" "goog/reflect/reflect.js" "goog/math/long.js" "goog/math/integer.js" "goog/dom/asserts.js" "goog/functions/functions.js" "goog/array/array.js" "goog/dom/htmlelement.js" "goog/dom/tagname.js" "goog/object/object.js" "goog/dom/tags.js" "goog/html/trustedtypes.js" "goog/string/typedstring.js" "goog/string/const.js" "goog/html/safescript.js" "goog/fs/url.js" "goog/i18n/bidi.js" "goog/html/trustedresourceurl.js" "goog/string/internal.js" "goog/html/safeurl.js" "goog/html/safestyle.js" "goog/html/safestylesheet.js" "goog/labs/useragent/util.js" "goog/labs/useragent/browser.js" "goog/html/safehtml.js" "goog/html/uncheckedconversions.js" "goog/dom/safe.js" "goog/string/string.js" "goog/structs/structs.js" "goog/math/math.js" "goog/iter/iter.js" "goog/structs/map.js" "goog/uri/utils.js" "goog/uri/uri.js" "goog/string/stringbuffer.js" "cljs/core.cljs" "devtools/defaults.cljs" "devtools/prefs.cljs" "devtools/context.cljs" "clojure/string.cljs" "cljs/stacktrace.cljc" "devtools/hints.cljs" "goog/labs/useragent/engine.js" "goog/labs/useragent/platform.js" "goog/useragent/useragent.js" "clojure/set.cljs" "clojure/data.cljs" "devtools/version.cljs" "cljs/pprint.cljs" "devtools/util.cljs" "devtools/format.cljs" "devtools/protocols.cljs" "devtools/reporter.cljs" "clojure/walk.cljs" "devtools/munging.cljs" "devtools/formatters/helpers.cljs" "devtools/formatters/state.cljs" "devtools/formatters/templating.cljs" "devtools/formatters/printing.cljs" "devtools/formatters/markup.cljs" "devtools/formatters/budgeting.cljs" "devtools/formatters/core.cljs" "devtools/formatters.cljs" "goog/debug/entrypointregistry.js" "goog/dom/browserfeature.js" "goog/math/coordinate.js" "goog/math/size.js" "goog/dom/dom.js" "goog/async/nexttick.js" "devtools/async.cljs" "devtools/toolbox.cljs" "devtools/core.cljs" "devtools/preload.cljs" "cljs/tools/reader/impl/utils.cljs" "cljs/tools/reader/reader_types.cljs" "cljs/tools/reader/impl/inspect.cljs" "cljs/tools/reader/impl/errors.cljs" "cljs/tools/reader/impl/commons.cljs" "cljs/tools/reader.cljs" "cljs/tools/reader/edn.cljs" "cljs/reader.cljs" "goog/useragent/product.js" "goog/promise/thenable.js" "goog/async/freelist.js" "goog/async/workqueue.js" "goog/async/run.js" "goog/promise/resolver.js" "goog/promise/promise.js" "goog/disposable/idisposable.js" "goog/disposable/disposable.js" "goog/debug/errorcontext.js" "goog/debug/debug.js" "goog/events/browserfeature.js" "goog/events/eventid.js" "goog/events/event.js" "goog/events/eventtype.js" "goog/events/browserevent.js" "goog/events/listenable.js" "goog/events/listener.js" "goog/events/listenermap.js" "goog/events/events.js" "goog/events/eventtarget.js" "goog/timer/timer.js" "goog/json/json.js" "goog/json/hybrid.js" "goog/debug/logrecord.js" "goog/debug/logbuffer.js" "goog/debug/logger.js" "goog/log/log.js" "goog/net/errorcode.js" "goog/net/eventtype.js" "goog/net/httpstatus.js" "goog/net/xhrlike.js" "goog/net/xmlhttpfactory.js" "goog/net/wrapperxmlhttpfactory.js" "goog/net/xmlhttp.js" "goog/net/xhrio.js" "shadow/cljs/devtools/client/env.cljs" "shadow/cljs/devtools/client/console.cljs" "goog/dom/inputtype.js" "goog/window/window.js" "goog/dom/forms.js" "goog/dom/classlist.js" "goog/dom/vendor.js" "goog/math/box.js" "goog/math/irect.js" "goog/math/rect.js" "goog/style/style.js" "goog/style/transition.js" "cljs/core/async/impl/protocols.cljs" "cljs/core/async/impl/buffers.cljs" "cljs/core/async/impl/dispatch.cljs" "cljs/core/async/impl/channels.cljs" "cljs/core/async/impl/timers.cljs" "cljs/core/async/impl/ioc_helpers.cljs" "cljs/core/async.cljs" "shadow/dom.cljs" "goog/result/result_interface.js" "goog/result/dependentresult.js" "goog/result/simpleresult.js" "goog/result/resultutil.js" "goog/labs/net/xhr.js" "shadow/util.cljs" "shadow/object.cljs" "shadow/xhr.cljs" "shadow/animate.cljs" "goog/string/stringformat.js" "shadow/cljs/devtools/client/hud.cljs" "shadow/cljs/devtools/client/browser.cljs" "cljs/spec/gen/alpha.cljs" "cljs/spec/alpha.cljs" "cljs/repl.cljs" "cljs/user.cljs" "shadow/js.js" "node_modules/object-assign/index.js" "node_modules/prop-types/lib/ReactPropTypesSecret.js" "node_modules/prop-types/checkPropTypes.js" "node_modules/react/cjs/react.development.js" "node_modules/react/index.js" "cljsjs/react.cljs" "node_modules/scheduler/cjs/scheduler.development.js" "node_modules/scheduler/index.js" "node_modules/scheduler/cjs/scheduler-tracing.development.js" "node_modules/scheduler/tracing.js" "node_modules/react-dom/cjs/react-dom.development.js" "node_modules/react-dom/index.js" "cljsjs/react/dom.cljs" "sablono/util.cljc" "sablono/normalize.cljc" "sablono/interpreter.cljc" "sablono/core.cljs" "rum/cursor.cljs" "rum/util.cljc" "rum/derived_atom.cljc" "rum/core.cljs" "promesa/protocols.cljc" "promesa/util.cljc" "promesa/exec.cljc" "promesa/impl.cljc" "promesa/core.cljc" "cljs_bean/from/cljs/core.cljs" "cljs_bean/core.cljs" "frontend/util.cljs" "frontend/git.cljs" "frontend/fs.cljs" "frontend/state.cljs" "me/tonsky/persistent_sorted_set/arrays.cljc" "me/tonsky/persistent_sorted_set.cljs" "datascript/db.cljc" "datascript/pull_parser.cljc" "datascript/pull_api.cljc" "datascript/lru.cljc" "datascript/impl/entity.cljc" "datascript/parser.cljc" "datascript/query.cljc" "datascript/core.cljc" "medley/core.cljc" "posh/lib/util.cljc" "posh/lib/datom_matcher.cljc" "posh/lib/pull_analyze.cljc" "cljs/core/match.cljs" "posh/lib/q_analyze.cljc" "posh/lib/db.cljc" "posh/lib/update.cljc" "posh/lib/graph.cljc" "posh/core.cljc" "posh/stateful.cljc" "posh/plugin_base.cljc" "posh/rum.cljc" "com/cognitect/transit/util.js" "com/cognitect/transit/delimiters.js" "com/cognitect/transit/caching.js" "com/cognitect/transit/eq.js" "com/cognitect/transit/types.js" "com/cognitect/transit/impl/decoder.js" "com/cognitect/transit/impl/reader.js" "com/cognitect/transit/handlers.js" "com/cognitect/transit/impl/writer.js" "com/cognitect/transit.js" "cognitect/transit.cljs" "datascript/transit.cljs" "frontend/db.cljs" "frontend/storage.cljs" "shadow$empty.js" "node_modules/constants-browserify/constants.json" "node_modules/mldoc_org/index.js" "frontend/format/protocol.cljs" "frontend/format/org_mode.cljs" "frontend/format/org/block.cljs" "frontend/config.cljs" "meta_merge/core.cljc" "reitit/exception.cljc" "reitit/trie.cljc" "reitit/impl.cljc" "reitit/core.cljc" "reitit/coercion.cljc" "reitit/frontend.cljs" "reitit/frontend/history.cljs" "reitit/frontend/easy.cljs" "goog/crypt/crypt.js" "goog/crypt/base64.js" "goog/events/eventhandler.js" "frontend/handler.cljs" "frontend/page.cljs" "frontend/rum.cljs" "node_modules/react-is/cjs/react-is.development.js" "node_modules/react-is/index.js" "node_modules/prop-types/factoryWithTypeCheckers.js" "node_modules/prop-types/index.js" "node_modules/@babel/runtime/helpers/interopRequireDefault.js" "node_modules/dom-helpers/cjs/hasClass.js" "node_modules/dom-helpers/cjs/addClass.js" "node_modules/dom-helpers/cjs/removeClass.js" "node_modules/react-transition-group/cjs/config.js" "node_modules/react-transition-group/cjs/utils/PropTypes.js" "node_modules/react-transition-group/cjs/TransitionGroupContext.js" "node_modules/react-transition-group/cjs/Transition.js" "node_modules/react-transition-group/cjs/CSSTransition.js" "node_modules/react-transition-group/cjs/utils/ChildMapping.js" "node_modules/react-transition-group/cjs/TransitionGroup.js" "node_modules/react-transition-group/cjs/ReplaceTransition.js" "node_modules/react-transition-group/cjs/SwitchTransition.js" "node_modules/react-transition-group/cjs/index.js" "frontend/mixins.cljs" "frontend/ui.cljs" "node_modules/showdown/dist/showdown.js" "frontend/format/markdown.cljs" "frontend/format.cljs" "frontend/components/repo.cljs" "frontend/components/sidebar.cljs" "frontend/components/home.cljs" "frontend/components/auth.cljs" "frontend/components/file.cljs" "frontend/components/agenda.cljs" "frontend/routes.cljs" "frontend/core.cljs" "shadow/module/main/append.js"]}] \ No newline at end of file +[{:module-id :main, :name :main, :output-name "main.js", :entries [devtools.preload shadow.cljs.devtools.client.browser cljs.user shadow.cljs.devtools.client.env frontend.core], :depends-on nil, :sources ["goog/base.js" "goog/debug/error.js" "goog/dom/nodetype.js" "goog/asserts/asserts.js" "goog/reflect/reflect.js" "goog/math/long.js" "goog/math/integer.js" "goog/dom/asserts.js" "goog/functions/functions.js" "goog/array/array.js" "goog/dom/htmlelement.js" "goog/dom/tagname.js" "goog/object/object.js" "goog/dom/tags.js" "goog/html/trustedtypes.js" "goog/string/typedstring.js" "goog/string/const.js" "goog/html/safescript.js" "goog/fs/url.js" "goog/i18n/bidi.js" "goog/html/trustedresourceurl.js" "goog/string/internal.js" "goog/html/safeurl.js" "goog/html/safestyle.js" "goog/html/safestylesheet.js" "goog/labs/useragent/util.js" "goog/labs/useragent/browser.js" "goog/html/safehtml.js" "goog/html/uncheckedconversions.js" "goog/dom/safe.js" "goog/string/string.js" "goog/structs/structs.js" "goog/math/math.js" "goog/iter/iter.js" "goog/structs/map.js" "goog/uri/utils.js" "goog/uri/uri.js" "goog/string/stringbuffer.js" "cljs/core.cljs" "devtools/defaults.cljs" "devtools/prefs.cljs" "devtools/context.cljs" "clojure/string.cljs" "cljs/stacktrace.cljc" "devtools/hints.cljs" "goog/labs/useragent/engine.js" "goog/labs/useragent/platform.js" "goog/useragent/useragent.js" "clojure/set.cljs" "clojure/data.cljs" "devtools/version.cljs" "cljs/pprint.cljs" "devtools/util.cljs" "devtools/format.cljs" "devtools/protocols.cljs" "devtools/reporter.cljs" "clojure/walk.cljs" "devtools/munging.cljs" "devtools/formatters/helpers.cljs" "devtools/formatters/state.cljs" "devtools/formatters/templating.cljs" "devtools/formatters/printing.cljs" "devtools/formatters/markup.cljs" "devtools/formatters/budgeting.cljs" "devtools/formatters/core.cljs" "devtools/formatters.cljs" "goog/debug/entrypointregistry.js" "goog/dom/browserfeature.js" "goog/math/coordinate.js" "goog/math/size.js" "goog/dom/dom.js" "goog/async/nexttick.js" "devtools/async.cljs" "devtools/toolbox.cljs" "devtools/core.cljs" "devtools/preload.cljs" "cljs/tools/reader/impl/utils.cljs" "cljs/tools/reader/reader_types.cljs" "cljs/tools/reader/impl/inspect.cljs" "cljs/tools/reader/impl/errors.cljs" "cljs/tools/reader/impl/commons.cljs" "cljs/tools/reader.cljs" "cljs/tools/reader/edn.cljs" "cljs/reader.cljs" "goog/useragent/product.js" "goog/promise/thenable.js" "goog/async/freelist.js" "goog/async/workqueue.js" "goog/async/run.js" "goog/promise/resolver.js" "goog/promise/promise.js" "goog/disposable/idisposable.js" "goog/disposable/disposable.js" "goog/debug/errorcontext.js" "goog/debug/debug.js" "goog/events/browserfeature.js" "goog/events/eventid.js" "goog/events/event.js" "goog/events/eventtype.js" "goog/events/browserevent.js" "goog/events/listenable.js" "goog/events/listener.js" "goog/events/listenermap.js" "goog/events/events.js" "goog/events/eventtarget.js" "goog/timer/timer.js" "goog/json/json.js" "goog/json/hybrid.js" "goog/debug/logrecord.js" "goog/debug/logbuffer.js" "goog/debug/logger.js" "goog/log/log.js" "goog/net/errorcode.js" "goog/net/eventtype.js" "goog/net/httpstatus.js" "goog/net/xhrlike.js" "goog/net/xmlhttpfactory.js" "goog/net/wrapperxmlhttpfactory.js" "goog/net/xmlhttp.js" "goog/net/xhrio.js" "shadow/cljs/devtools/client/env.cljs" "shadow/cljs/devtools/client/console.cljs" "goog/dom/inputtype.js" "goog/window/window.js" "goog/dom/forms.js" "goog/dom/classlist.js" "goog/dom/vendor.js" "goog/math/box.js" "goog/math/irect.js" "goog/math/rect.js" "goog/style/style.js" "goog/style/transition.js" "cljs/core/async/impl/protocols.cljs" "cljs/core/async/impl/buffers.cljs" "cljs/core/async/impl/dispatch.cljs" "cljs/core/async/impl/channels.cljs" "cljs/core/async/impl/timers.cljs" "cljs/core/async/impl/ioc_helpers.cljs" "cljs/core/async.cljs" "shadow/dom.cljs" "goog/result/result_interface.js" "goog/result/dependentresult.js" "goog/result/simpleresult.js" "goog/result/resultutil.js" "goog/labs/net/xhr.js" "shadow/util.cljs" "shadow/object.cljs" "shadow/xhr.cljs" "shadow/animate.cljs" "goog/string/stringformat.js" "shadow/cljs/devtools/client/hud.cljs" "shadow/cljs/devtools/client/browser.cljs" "cljs/spec/gen/alpha.cljs" "cljs/spec/alpha.cljs" "cljs/repl.cljs" "cljs/user.cljs" "shadow/js.js" "node_modules/object-assign/index.js" "node_modules/prop-types/lib/ReactPropTypesSecret.js" "node_modules/prop-types/checkPropTypes.js" "node_modules/react/cjs/react.development.js" "node_modules/react/index.js" "cljsjs/react.cljs" "node_modules/scheduler/cjs/scheduler.development.js" "node_modules/scheduler/index.js" "node_modules/scheduler/cjs/scheduler-tracing.development.js" "node_modules/scheduler/tracing.js" "node_modules/react-dom/cjs/react-dom.development.js" "node_modules/react-dom/index.js" "cljsjs/react/dom.cljs" "sablono/util.cljc" "sablono/normalize.cljc" "sablono/interpreter.cljc" "sablono/core.cljs" "rum/cursor.cljs" "rum/util.cljc" "rum/derived_atom.cljc" "rum/core.cljs" "promesa/protocols.cljc" "promesa/util.cljc" "promesa/exec.cljc" "promesa/impl.cljc" "promesa/core.cljc" "cljs_bean/from/cljs/core.cljs" "cljs_bean/core.cljs" "frontend/util.cljs" "frontend/git.cljs" "frontend/fs.cljs" "frontend/state.cljs" "me/tonsky/persistent_sorted_set/arrays.cljc" "me/tonsky/persistent_sorted_set.cljs" "datascript/db.cljc" "datascript/pull_parser.cljc" "datascript/pull_api.cljc" "datascript/lru.cljc" "datascript/impl/entity.cljc" "datascript/parser.cljc" "datascript/query.cljc" "datascript/core.cljc" "medley/core.cljc" "com/cognitect/transit/util.js" "com/cognitect/transit/delimiters.js" "com/cognitect/transit/caching.js" "com/cognitect/transit/eq.js" "com/cognitect/transit/types.js" "com/cognitect/transit/impl/decoder.js" "com/cognitect/transit/impl/reader.js" "com/cognitect/transit/handlers.js" "com/cognitect/transit/impl/writer.js" "com/cognitect/transit.js" "cognitect/transit.cljs" "datascript/transit.cljs" "shadow$empty.js" "node_modules/constants-browserify/constants.json" "node_modules/mldoc_org/index.js" "frontend/format/protocol.cljs" "frontend/format/org_mode.cljs" "frontend/format/org/block.cljs" "frontend/db.cljs" "frontend/storage.cljs" "frontend/config.cljs" "meta_merge/core.cljc" "reitit/exception.cljc" "reitit/trie.cljc" "reitit/impl.cljc" "reitit/core.cljc" "reitit/coercion.cljc" "reitit/frontend.cljs" "reitit/frontend/history.cljs" "reitit/frontend/easy.cljs" "goog/crypt/crypt.js" "goog/crypt/base64.js" "goog/events/eventhandler.js" "frontend/handler.cljs" "frontend/page.cljs" "frontend/rum.cljs" "node_modules/react-is/cjs/react-is.development.js" "node_modules/react-is/index.js" "node_modules/prop-types/factoryWithTypeCheckers.js" "node_modules/prop-types/index.js" "node_modules/@babel/runtime/helpers/interopRequireDefault.js" "node_modules/dom-helpers/cjs/hasClass.js" "node_modules/dom-helpers/cjs/addClass.js" "node_modules/dom-helpers/cjs/removeClass.js" "node_modules/react-transition-group/cjs/config.js" "node_modules/react-transition-group/cjs/utils/PropTypes.js" "node_modules/react-transition-group/cjs/TransitionGroupContext.js" "node_modules/react-transition-group/cjs/Transition.js" "node_modules/react-transition-group/cjs/CSSTransition.js" "node_modules/react-transition-group/cjs/utils/ChildMapping.js" "node_modules/react-transition-group/cjs/TransitionGroup.js" "node_modules/react-transition-group/cjs/ReplaceTransition.js" "node_modules/react-transition-group/cjs/SwitchTransition.js" "node_modules/react-transition-group/cjs/index.js" "frontend/mixins.cljs" "frontend/ui.cljs" "node_modules/showdown/dist/showdown.js" "frontend/format/markdown.cljs" "frontend/format.cljs" "frontend/components/repo.cljs" "frontend/components/sidebar.cljs" "frontend/components/home.cljs" "frontend/components/auth.cljs" "frontend/components/file.cljs" "frontend/components/agenda.cljs" "frontend/routes.cljs" "frontend/core.cljs" "shadow/module/main/append.js"]}] \ No newline at end of file diff --git a/web/src/frontend/components/agenda.cljs b/web/src/frontend/components/agenda.cljs index 16359612a..a4211522b 100644 --- a/web/src/frontend/components/agenda.cljs +++ b/web/src/frontend/components/agenda.cljs @@ -50,68 +50,68 @@ [:span name]])]) -(rum/defq agenda < - {:q (fn [state] (db/sub-agenda))} - [state tasks] - (sidebar/sidebar - [:div#agenda - [:h2.mb-3 "Agenda"] - (if (seq tasks) - [:div.ml-1 - (let [parent-tasks (block/group-by-parent (block/sort-tasks tasks))] - (for [[parent tasks] parent-tasks] - (let [parent (cond - (string? parent) - parent +(rum/defc agenda + [] + (let [tasks (db/get-agenda)] + (sidebar/sidebar + [:div#agenda + [:h2.mb-3 "Agenda"] + (if (seq tasks) + [:div.ml-1 + (let [parent-tasks (block/group-by-parent (block/sort-tasks tasks))] + (for [[parent tasks] parent-tasks] + (let [parent (cond + (string? parent) + parent - (and (map? parent) - (:label parent)) - (title-cp (:label parent)) + (and (map? parent) + (:label parent)) + (title-cp (:label parent)) - :else - "uncategorized")] - [:div.mt-10 - [:h4.mb-3.text-gray-500 parent] - (for [{:heading/keys [uuid marker title priority level tags children timestamps meta repo file] :as task} tasks] - [:div.mb-2 - {:key (str "task-" uuid) - :style {:padding-left 8 - :padding-right 8}} - [:div.column - [:div.row {:style {:align-items "center"}} - (case marker - (list "DOING" "IN-PROGRESS" "TODO") - (ui/checkbox {:on-change (fn [_] - ;; FIXME: Log timestamp - (handler/check repo file marker (:pos meta)))}) + :else + "uncategorized")] + [:div.mt-10 + [:h4.mb-3.text-gray-500 parent] + (for [{:heading/keys [uuid marker title priority level tags children timestamps meta repo file] :as task} tasks] + [:div.mb-2 + {:key (str "task-" uuid) + :style {:padding-left 8 + :padding-right 8}} + [:div.column + [:div.row {:style {:align-items "center"}} + (case marker + (list "DOING" "IN-PROGRESS" "TODO") + (ui/checkbox {:on-change (fn [_] + ;; FIXME: Log timestamp + (handler/check task))}) - "WAIT" - [:span {:style {:font-weight "bold"}} - "WAIT"] + "WAIT" + [:span {:style {:font-weight "bold"}} + "WAIT"] - "DONE" - (ui/checkbox {:checked true - :on-change (fn [_] - ;; FIXME: Log timestamp - (handler/uncheck repo file (:pos meta)) - )}) + "DONE" + (ui/checkbox {:checked true + :on-change (fn [_] + ;; FIXME: Log timestamp + (handler/uncheck task) + )}) - nil) - [:div.row.ml-2 - (if priority - [:span.priority.mr-1 - (str "#[" priority "]")]) - (title-cp title) - (marker-cp marker) - (when (seq tags) - (tags-cp tags))]] - (when (seq timestamps) - (timestamps-cp timestamps)) + nil) + [:div.row.ml-2 + (if priority + [:span.priority.mr-1 + (str "#[" priority "]")]) + (title-cp title) + (marker-cp marker) + (when (seq tags) + (tags-cp tags))]] + (when (seq timestamps) + (timestamps-cp timestamps)) - ;; FIXME: parse error - ;; (when (seq children) - ;; (children-cp children)) + ;; FIXME: parse error + ;; (when (seq children) + ;; (children-cp children)) - ]] - )])))] - "Empty")])) + ]] + )])))] + "Empty")]))) diff --git a/web/src/frontend/components/file.cljs b/web/src/frontend/components/file.cljs index b4a945051..6d2d5d0dc 100644 --- a/web/src/frontend/components/file.cljs +++ b/web/src/frontend/components/file.cljs @@ -16,17 +16,15 @@ decoded-path (b64/decodeString encoded-path)] [encoded-path decoded-path])) -(rum/defq file < - {:q (fn [state] - (db/sub-file (last (get-path state)))) - :did-mount (fn [state] +(rum/defcs file < + {:did-mount (fn [state] (doseq [block (-> (js/document.querySelectorAll "pre code") (array-seq))] (js/hljs.highlightBlock block)) state)} [state content] - (let [[encoded-path path] (get-path state) - content (ffirst content) + (let [content (db/get-file (last (get-path state))) + [encoded-path path] (get-path state) suffix (last (string/split path #"\."))] (sidebar/sidebar (if (and suffix (contains? #{"md" "markdown" "org"} suffix)) @@ -42,21 +40,23 @@ [s] (count (re-seq #"\n" (or s "")))) -(rum/defq edit < +(rum/defcs edit < (rum/local nil ::content) (rum/local "" ::commit-message) - {:q (fn [state] - (db/sub-file (last (get-path state))))} - [state initial-content] - (let [content (get state ::content) + {:will-mount (fn [state] + (assoc state ::initial-content (db/get-file (last (get-path state)))))} + [state] + (let [initial-content (get state ::initial-content) + initial-rows (+ 3 (count-newlines initial-content)) + content (get state ::content) commit-message (get state ::commit-message) + rows (if (nil? @content) initial-rows (+ 3 (count-newlines @content))) [_encoded-path path] (get-path state)] (sidebar/sidebar [:div#content [:h3.mb-2 (str "Update " path)] [:textarea - {:rows (+ 3 (count-newlines @content)) - :style {:min-height 300} + {:rows rows :default-value initial-content :on-change #(reset! content (.. % -target -value)) :auto-focus true}] diff --git a/web/src/frontend/components/home.cljs b/web/src/frontend/components/home.cljs index c019a776d..8f8b86798 100644 --- a/web/src/frontend/components/home.cljs +++ b/web/src/frontend/components/home.cljs @@ -70,13 +70,12 @@ [:p.text-sm.text-gray-500.leading-tight "Author of Refactoring UI"]]]]]]]) -(rum/defq home < (rum/local false ::loading?) +(rum/defc home < {:will-mount (fn [state] (when-not (db/get-github-token) (handler/get-github-access-token)) - state) - :q (fn [_state] (db/sub-github-token))} - [state {:keys [:github/token]}] - (if token + state)} + [state] + (if (db/get-github-token) (sidebar/sidebar (sidebar/main-content)) (front-page))) diff --git a/web/src/frontend/components/repo.cljs b/web/src/frontend/components/repo.cljs index 35deca8be..38f91d3a4 100644 --- a/web/src/frontend/components/repo.cljs +++ b/web/src/frontend/components/repo.cljs @@ -8,15 +8,14 @@ (defn repos [repos] (when (seq repos) - (let [repos (->> repos (map first) distinct)] - [:div#repos - [:ul - (for [url repos] - [:li {:key url} - [:button {:on-click (fn [] - ;; (handler/set-current-repo url) - )} - (string/replace url "https://github.com/" "")]])]]))) + [:div#repos + [:ul + (for [url repos] + [:li {:key url} + [:button {:on-click (fn [] + ;; (handler/set-current-repo url) + )} + (string/replace url "https://github.com/" "")]])]])) (rum/defcs add-repo < (rum/local "https://github.com/" ::repo-url) [state] diff --git a/web/src/frontend/components/sidebar.cljs b/web/src/frontend/components/sidebar.cljs index 7decc388f..3e81a37d2 100644 --- a/web/src/frontend/components/sidebar.cljs +++ b/web/src/frontend/components/sidebar.cljs @@ -26,19 +26,18 @@ :stroke-linecap "round"}]] title]))) -(rum/defq files-list < - {:q (fn [] (db/sub-files))} - [state files file-active?] - [:div.cursor-pointer.my-1.flex.flex-col.ml-2 - (if (seq files) - (let [files (->> files (map first))] +(rum/defc files-list + [file-active?] + (let [files (db/get-files)] + [:div.cursor-pointer.my-1.flex.flex-col.ml-2 + (if (seq files) (for [file files] (let [encoded-path (b64/encodeString file)] [:a {:key file :class (util/hiccup->class "mt-1.group.flex.items-center.px-2.py-1.text-base.leading-6.font-medium.rounded-md.text-gray-500.hover:text-white.hover:bg-gray-700.focus:outline-none.focus:text-white.focus:bg-gray-700.transition.ease-in-out.duration-150") :style {:color (if (file-active? encoded-path) "#FFF")} :href (str "/file/" encoded-path)} - file]))))]) + file])))])) (rum/defc sidebar-nav < rum/reactive [] @@ -55,14 +54,14 @@ (active? :agenda)) (files-list file-active?)])) -(rum/defq main-content < - {:q (fn [_state] (db/sub-repos))} - [state repos] - [:div.max-w-7xl.mx-auto.px-4.sm:px-6.md:px-8 - (if (seq repos) - [:div - (repo/repos repos)] - (repo/add-repo))]) +(rum/defc main-content + [] + (let [repos (db/get-repos)] + [:div.max-w-7xl.mx-auto.px-4.sm:px-6.md:px-8 + (if (seq repos) + [:div + (repo/repos repos)] + (repo/add-repo))])) (rum/defcs sidebar < (mixins/modal) [state main-content] diff --git a/web/src/frontend/db.cljs b/web/src/frontend/db.cljs index 630240d5b..aad3d1a22 100644 --- a/web/src/frontend/db.cljs +++ b/web/src/frontend/db.cljs @@ -2,8 +2,9 @@ (:require [datascript.core :as d] [frontend.util :as util] [medley.core :as medley] - [posh.rum :as posh] - [datascript.transit :as dt])) + [datascript.transit :as dt] + [frontend.format.org-mode :as org] + [frontend.format.org.block :as block])) ;; TODO: don't persistent :github/token @@ -46,9 +47,7 @@ }) (defonce conn - (let [conn (d/create-conn schema)] - (posh/posh! conn) - conn)) + (d/create-conn schema)) ;; transit serialization @@ -65,15 +64,6 @@ (defn reset-conn! [db] (reset! conn db)) -(d/listen! conn :persistence - (fn [tx-report] ;; FIXME do not notify with nil as db-report - ;; FIXME do not notify if tx-data is empty - (when-let [db (:db-after tx-report)] - (prn "DB changed") - (js/setTimeout (fn [] - (posh/posh! conn) - (persist db)) 0)))) - ;; (new TextEncoder().encode('foo')).length (defn db-size [] @@ -175,6 +165,23 @@ headings (mapv (fn [eid] [:db.fn/retractEntity eid]) headings)] (d/transact! conn headings))) +(defn get-file-headings + [repo-url path] + (-> (d/q '[:find ?heading + :in $ ?repo-url ?path + :where + [?repo :repo/url ?repo-url] + [?file :file/path ?path] + [?heading :heading/file ?file] + [?heading :heading/repo ?repo]] + @conn repo-url path) + seq-flatten)) + +(defn delete-file-headings! + [repo-url path] + (let [headings (get-file-headings repo-url path)] + (mapv (fn [eid] [:db.fn/retractEntity eid]) headings))) + ;; transactions (defn reset-headings! [repo-url headings] @@ -204,27 +211,9 @@ [(?pred $ ?tags)]] @conn pred))) -(comment - (frontend.handler/initial-db!) - ) - -(defn pull - [selector eid] - (posh/pull conn selector eid)) - -(defn pull-many - ([eids] - (pull-many '[*] eids)) - ([selector eids] - (posh/pull-many conn selector eids))) - -(defn q - [query & inputs] - (apply posh/q query inputs)) - (defn transact! [tx-data] - (posh/transact! conn tx-data)) + (d/transact! conn tx-data)) (defn set-key-value [key value] @@ -241,10 +230,6 @@ (some-> (d/entity (d/db conn) key) key)) -(defn sub-github-token - [] - (pull '[*] [:db/ident :github/token])) - (defn get-github-token [] (get-key-value :github/token)) @@ -253,20 +238,10 @@ [repo] (set-key-value :repo/current [:repo/url repo])) -(defn sub-current-repo - [] - (pull '[*] [:db/ident :repo/current])) - (defn get-current-repo [] (:repo/url (get-key-value :repo/current))) -(defn sub-repos - [] - (q '[:find ?url - :where [_ :repo/url ?url]] - conn)) - (defn get-repos [] (->> (d/q '[:find ?url @@ -275,14 +250,16 @@ (map first) distinct)) -(defn sub-files +(defn get-files [] - (q '[:find ?path - :where - [_ :repo/current ?repo] - [?file :file/repo ?repo] - [?file :file/path ?path]] - conn)) + (->> (d/q '[:find ?path + :where + [_ :repo/current ?repo] + [?file :file/repo ?repo] + [?file :file/path ?path]] + @conn) + (map first) + distinct)) (defn set-repo-cloning [repo-url value] @@ -323,31 +300,17 @@ :file/path file :file/content content}])) -(defn get-file-content - [repo-url path] - (->> (d/q '[:find ?content - :in $ ?repo-url ?path - :where - [?repo :repo/url ?repo-url] - [?file :file/repo ?repo] - [?file :file/path ?path] - [?file :file/content ?content] - ] - @conn repo-url path) - (map first) - first)) - -(defn sub-file - [path] - (q '[:find ?content - :in $ ?path - :where - [_ :repo/current ?repo] - [?file :file/repo ?repo] - [?file :file/path ?path] - [?file :file/content ?content]] - conn - path)) +(defn extract-headings + [repo-url file content] + (let [headings (-> content + (org/parse-json) + (util/json->clj)) + headings (block/extract-headings headings)] + (map (fn [heading] + (assoc heading + :heading/repo [:repo/url repo-url] + :heading/file [:file/path file])) + headings))) (defn get-all-files-content [repo-url] @@ -360,26 +323,54 @@ [?file :file/path ?path]] @conn repo-url)) +(defn extract-all-headings + [repo-url] + (let [contents (get-all-files-content repo-url)] + (vec + (mapcat + (fn [[file content] contents] + (extract-headings repo-url file content)) + contents)))) + +(defn reset-file! + [repo-url file content] + (let [file-content [{:file/repo [:repo/url repo-url] + :file/path file + :file/content content}] + delete-headings (delete-file-headings! repo-url file) + headings (extract-headings repo-url file content) + headings (safe-headings headings)] + (d/transact! conn (concat file-content delete-headings headings)))) + +(defn get-file-content + [repo-url path] + (->> (d/q '[:find ?content + :in $ ?repo-url ?path + :where + [?repo :repo/url ?repo-url] + [?file :file/repo ?repo] + [?file :file/path ?path] + [?file :file/content ?content]] + @conn repo-url path) + (map first) + first)) + +(defn get-file + [path] + (-> + (d/q '[:find ?content + :in $ ?path + :where + [_ :repo/current ?repo] + [?file :file/repo ?repo] + [?file :file/path ?path] + [?file :file/content ?content]] + @conn + path) + ffirst)) + ;; marker should be one of: TODO, DOING, IN-PROGRESS ;; time duration -(defn sub-agenda - ([] - (sub-agenda :week)) - ([time] - (let [duration (case time - :today [] - :week [] - :month []) - tasks-ids (-> @(q '[:find ?h - :where - (or [?h :heading/marker "TODO"] - [?h :heading/marker "DOING"] - [?h :heading/marker "IN-PROGRESS"] - [?h :heading/marker "DONE"])] - conn) - seq-flatten)] - (pull-many tasks-ids)))) - (defn get-agenda ([] (get-agenda :week)) @@ -388,13 +379,15 @@ :today [] :week [] :month [])] - (d/q '[:find (pull ?h [*]) - :where - (or [?h :heading/marker "TODO"] - [?h :heading/marker "DOING"] - [?h :heading/marker "IN-PROGRESS"] - [?h :heading/marker "DONE"])] - @conn)))) + (-> + (d/q '[:find (pull ?h [*]) + :where + (or [?h :heading/marker "TODO"] + [?h :heading/marker "DOING"] + [?h :heading/marker "IN-PROGRESS"] + [?h :heading/marker "DONE"])] + @conn) + seq-flatten)))) (defn entity [id-or-lookup-ref] diff --git a/web/src/frontend/format/org/block.cljs b/web/src/frontend/format/org/block.cljs index e4ea08f75..abf550098 100644 --- a/web/src/frontend/format/org/block.cljs +++ b/web/src/frontend/format/org/block.cljs @@ -95,11 +95,19 @@ m2 (get markers (:heading/marker t2) 0) p1 (get priorities (:heading/priority t1) 0) p2 (get priorities (:heading/priority t2) 0)] - (if (= m1 m2) + (cond + (and (= m1 m2) + (= p1 p2)) + (compare (:heading/title t1) (:heading/title t2)) + + (= m1 m2) (> p1 p2) + :else (> m1 m2)))) headings))) (defn group-by-parent [headings] - (group-by :heading/parent-title headings)) + (->> (group-by :heading/parent-title headings) + (into (sorted-map-by (fn [x y] + (compare (str x) (str y))))))) diff --git a/web/src/frontend/git.cljs b/web/src/frontend/git.cljs index 2c68d3144..5f6938f1b 100644 --- a/web/src/frontend/git.cljs +++ b/web/src/frontend/git.cljs @@ -62,6 +62,7 @@ {:dir (get-repo-dir repo-url) :filepath file}))) +;; TODO: cache email and name (defn commit [repo-url message] (js/git.commit (clj->js diff --git a/web/src/frontend/handler.cljs b/web/src/frontend/handler.cljs index fa32fa02f..05e285db3 100644 --- a/web/src/frontend/handler.cljs +++ b/web/src/frontend/handler.cljs @@ -6,8 +6,6 @@ [frontend.db :as db] [frontend.storage :as storage] [frontend.util :as util] - [frontend.format.org-mode :as org] - [frontend.format.org.block :as block] [frontend.config :as config] [clojure.walk :as walk] [clojure.string :as string] @@ -15,7 +13,9 @@ [cljs-bean.core :as bean] [reitit.frontend.easy :as rfe] [goog.crypt.base64 :as b64] - [goog.object :as gobj]) + [goog.object :as gobj] + [rum.core :as rum] + [datascript.core :as d]) (:import [goog.events EventHandler])) ;; We only support Github token now @@ -69,21 +69,24 @@ ;; TODO: callback hell (defn pull [repo-url token] - (util/p-handle (git/pull repo-url token) - (fn [result] - (get-latest-commit - (fn [commit] - (when (or (nil? @latest-commit) - (and @latest-commit - commit - (not= (gobj/get commit "oid") - (gobj/get @latest-commit "oid")))) - (prn "New commit oid: " (gobj/get commit "oid")) - (-> (load-files repo-url) - (p/then - (fn [] - (load-repo-to-db! repo-url))))) - (reset! latest-commit commit)))))) + (prn "pushing? " (:pushing? @state/state)) + (when-not (:pushing? @state/state) + (util/p-handle + (git/pull repo-url token) + (fn [result] + (get-latest-commit + (fn [commit] + (when (or (nil? @latest-commit) + (and @latest-commit + commit + (not= (gobj/get commit "oid") + (gobj/get @latest-commit "oid")))) + (prn "New commit oid: " (gobj/get commit "oid")) + (-> (load-files repo-url) + (p/then + (fn [] + (load-repo-to-db! repo-url))))) + (reset! latest-commit commit))))))) (defn periodically-pull [repo-url] @@ -92,23 +95,10 @@ (js/setInterval #(pull repo-url token) (* 10 1000)))) -(defn add-transaction - [tx] - (swap! state/state update :tasks-transactions conj tx)) - -(defn clear-transactions! - [] - (swap! state/state assoc :tasks-transactions nil)) - -(defn- transactions->commit-msg - [transactions] - (let [transactions (reverse transactions)] - (str - "Gitnotes auto save tasks.\n\n" - (string/join "\n" transactions)))) - +;; TODO: update latest commit (defn push [repo-url file message] + (swap! state/state assoc :pushing? true) (let [token (db/get-github-token)] (git/add-commit-push repo-url @@ -116,9 +106,11 @@ message token (fn [] - (prn "Push successfully!")) + (prn "Push successfully!") + (swap! state/state assoc :pushing? false)) (fn [] - (prn "Failed to push."))))) + (prn "Failed to push.") + (swap! state/state assoc :pushing? false))))) (defn clone [repo] @@ -196,14 +188,16 @@ (util/p-handle (fs/write-file (git/get-repo-dir repo-url) path content) (fn [_] + (rfe/push-state :file {:path (b64/encodeString path)}) + (db/reset-file! repo-url path content) + (git/add-commit-push repo-url path commit-message token (fn [] - (db/set-file-content! repo-url path content) - (rfe/push-state :file {:path (b64/encodeString path)}) - (show-notification! "File updated!")) + ;; (show-notification! "File updated!") + ) (fn [error] (prn "Failed to update file, error: " error))))))) @@ -213,8 +207,10 @@ (clone repo-url)) (defn check - [repo file marker pos] - (let [repo (db/entity (:db/id repo)) + [heading] + (let [{:heading/keys [repo file marker meta uuid]} heading + pos (:pos meta) + repo (db/entity (:db/id repo)) file (db/entity (:db/id file)) repo-url (:repo/url repo) file (:file/path file) @@ -223,15 +219,18 @@ (let [content' (str (subs content 0 pos) (-> (subs content pos) (string/replace-first marker "DONE")))] - (db/set-file-content! repo-url file content') (util/p-handle (fs/write-file (git/get-repo-dir repo-url) file content') (fn [_] + (prn "check successfully, " file) + (db/reset-file! repo-url file content') (push repo-url file (util/format "`%s` marked as DONE." marker)))))))) (defn uncheck - [repo file pos] - (let [repo (db/entity (:db/id repo)) + [heading] + (let [{:heading/keys [repo file marker meta]} heading + pos (:pos meta) + repo (db/entity (:db/id repo)) file (db/entity (:db/id file)) repo-url (:repo/url repo) file (:file/path file) @@ -240,24 +239,13 @@ (let [content' (str (subs content 0 pos) (-> (subs content pos) (string/replace-first "DONE" "TODO")))] - (db/set-file-content! repo-url file content') (util/p-handle (fs/write-file (git/get-repo-dir repo-url) file content') (fn [_] + (prn "uncheck successfully, " file) + (db/reset-file! repo-url file content') (push repo-url file "DONE rollbacks to TODO."))))))) -(defn extract-headings - [repo-url file content] - (let [headings (-> content - (org/parse-json) - (util/json->clj)) - headings (block/extract-headings headings)] - (map (fn [heading] - (assoc heading - :heading/repo [:repo/url repo-url] - :heading/file [:file/path file])) - headings))) - (defn load-all-contents! [repo-url ok-handler] (let [files (db/get-repo-files repo-url)] @@ -269,22 +257,13 @@ (fn [_] (ok-handler)))))) -(defn extract-all-headings - [repo-url] - (let [contents (db/get-all-files-content repo-url)] - (vec - (mapcat - (fn [[file content] contents] - (extract-headings repo-url file content)) - contents)))) - (defonce headings-atom (atom nil)) (defn load-repo-to-db! [repo-url] (load-all-contents! repo-url (fn [] - (let [headings (extract-all-headings repo-url)] + (let [headings (db/extract-all-headings repo-url)] (reset! headings-atom headings) (db/reset-headings! repo-url headings))))) @@ -326,9 +305,34 @@ [route] (swap! state/state assoc :route-match route)) +(defn set-ref-component! + [k ref] + (swap! state/state assoc :ref-components k ref)) + +(defn set-root-component! + [comp] + (swap! state/state assoc :root-component comp)) + +(defn re-render! + [] + (when-let [comp (get @state/state :root-component)] + (rum/request-render comp))) + +(defn db-listen-to-tx! + [] + (d/listen! db/conn :persistence + (fn [tx-report] ;; FIXME do not notify with nil as db-report + ;; FIXME do not notify if tx-data is empty + (when-let [db (:db-after tx-report)] + (prn "DB changed, re-rendered!") + (re-render!) + (js/setTimeout (fn [] + (db/persist db)) 0))))) + (defn start! [] (db/restore!) + (db-listen-to-tx!) (when-let [first-repo (first (db/get-repos))] (db/set-current-repo! first-repo)) (let [repos (db/get-repos)] diff --git a/web/src/frontend/page.cljs b/web/src/frontend/page.cljs index 4248d4da7..fefe57fb1 100644 --- a/web/src/frontend/page.cljs +++ b/web/src/frontend/page.cljs @@ -1,11 +1,16 @@ (ns frontend.page (:require [rum.core :as rum] - [frontend.state :as state])) + [frontend.state :as state] + [frontend.handler :as handler])) (rum/defc current-page < rum/reactive + {:did-mount (fn [state] + (handler/set-root-component! (:rum/react-component state)) + state)} [] (let [state (rum/react state/state) route-match (:route-match state)] (if route-match (when-let [view (:view (:data route-match))] - (view route-match))))) + (view route-match)) + [:div "404 Page"]))) diff --git a/web/src/frontend/posh.cljs b/web/src/frontend/posh.cljs deleted file mode 100644 index b2a2298ce..000000000 --- a/web/src/frontend/posh.cljs +++ /dev/null @@ -1,4 +0,0 @@ -(ns frontend.posh - (:require [posh.core :as posh])) - -;; experiment diff --git a/web/src/frontend/state.cljs b/web/src/frontend/state.cljs index 8f9def58a..a42b27294 100644 --- a/web/src/frontend/state.cljs +++ b/web/src/frontend/state.cljs @@ -5,4 +5,5 @@ {:route-match nil :notification/show? false :notification/text nil - :tasks-transactions nil})) + :root-component nil + :pushing? false}))