Added properties panel

This commit is contained in:
Julien Eluard 2019-04-04 08:57:11 +02:00 committed by Julien Eluard
parent 129c3a908e
commit c40f5356c0
10 changed files with 152 additions and 82 deletions

2
.gitignore vendored
View File

@ -17,5 +17,5 @@ pom.xml.asc
resources/public/js/compiled resources/public/js/compiled
figwheel-main.log* figwheel-main.log*
node_modules/ node_modules/
.rebel_readline_history
/.idea/ /.idea/

View File

@ -55,11 +55,12 @@
(defview examples [] (defview examples []
(letsubs [show? [:get :examples]] (letsubs [show? [:get :examples]]
[:> Dialog {:open show? :on-close #(re-frame/dispatch [:set :examples nil])} [:> Dialog {:open (or show? false) :on-close #(re-frame/dispatch [:set :examples nil])}
[:> DialogTitle [:> DialogTitle
"Extensions examples"] "Extensions examples"]
[:div {:style {:padding 20 :overflow :auto}} [:div {:style {:padding 20 :overflow :auto}}
(for [item examples-data] (for [item examples-data]
^ {:key item}
[example-item item])]])) [example-item item])]]))
(defn app-db-browser [] (defn app-db-browser []
@ -70,10 +71,27 @@
"Edit local app-db"] "Edit local app-db"]
[:div {:style {:padding 20 :width "50vw" :height "80vh"}} [:div {:style {:padding 20 :width "50vw" :height "80vh"}}
[source/editor2 {:content (str (or m {})) [source/editor2 {:content (str (or m {}))
:on-change #(re-frame/dispatch [:fiddle/set-app-db nil (edn/read-string %)])}]]])) :on-change #(re-frame/dispatch [:extension/set-app-db nil (edn/read-string %)])}]]]))
(defn dialogs [] (defn- set-properties [id s]
(try
(re-frame/dispatch [:extension/set-properties id (edn/read-string s)])
(catch js/Error _)))
(defn properties-browser [selection]
(let [browse @(re-frame/subscribe [:get :browse-properties])
m @(re-frame/subscribe [:extension/properties selection])]
[:> Dialog {:open browse :on-close #(re-frame/dispatch [:set :browse-properties false])}
[:> DialogTitle
"Edit properties"]
[:div {:style {:padding 20 :width "50vw" :height "80vh"}}
[source/editor2 {:content (str (or m {}))
:on-change #(set-properties selection %)}]]]))
(defn dialogs [selection]
[:div [:div
[publish] [publish]
[examples] [examples]
[app-db-browser]]) [app-db-browser]
[properties-browser selection]])

View File

@ -13,11 +13,10 @@
(.log js/console "trigger" query arguments)) (.log js/console "trigger" query arguments))
(defn tree [ctx m] (defn tree [ctx m]
(println m)
[:div [:div
(for [[k v] (filter primitive? m)] ;; TODO only events and views? (for [[k v] (filter primitive? m)] ;; TODO only events and views?
^{:key k} ^{:key k}
[:div [:div
[:div (str k)] [:div (str k)]
[:button {:on-click #(fire-event ctx m k {})} [:button {:on-click #(fire-event ctx m k {})}
"Fire"]])]) "Fire"]])])

View File

@ -28,6 +28,7 @@
(defmethod pretty-print-data [::log/trace :event/dispatch] [{:keys [data]}] (defmethod pretty-print-data [::log/trace :event/dispatch] [{:keys [data]}]
[:<> [:<>
(for [event data] (for [event data]
^{:key event}
[reference event])]) [reference event])])
;; TODO unify static and runtime (log) errors ;; TODO unify static and runtime (log) errors
@ -42,6 +43,11 @@
[:div {:style {:max-height "100px" :overflow "auto"}} [:div {:style {:max-height "100px" :overflow "auto"}}
child]) child])
(defn- pretty-print-category [category]
(reagent/as-element
[:div {:style {:color (if (= category ::log/error) :red :blue)}}
category]))
(defn table [v] (defn table [v]
[:div [:div
[:> Table [:> Table
@ -53,10 +59,10 @@
[:> TableCell "Data"]]] [:> TableCell "Data"]]]
[:> TableBody [:> TableBody
(for [{:keys [id category type] :as m} v] (for [{:keys [id category type] :as m} v]
^{:key id} ^{:key (or id m)}
[:> TableRow [:> TableRow
[:> TableCell id] [:> TableCell id]
[:> TableCell category] [:> TableCell (pretty-print-category category)]
[:> TableCell type] [:> TableCell type]
[:> TableCell [:> TableCell
[data-wrapper [data-wrapper

View File

@ -1,6 +1,7 @@
(ns pluto.playground.core (ns pluto.playground.core
(:require-macros [react-native-web.views :refer [defview letsubs]]) (:require-macros [react-native-web.views :refer [defview letsubs]])
(:require [pluto.playground.components.source :as source] (:require [clojure.string :as string]
[pluto.playground.components.source :as source]
[pluto.playground.components.logs :as logs] [pluto.playground.components.logs :as logs]
pluto.playground.fx pluto.playground.fx
pluto.playground.subs pluto.playground.subs
@ -8,6 +9,7 @@
pluto.reader.views pluto.reader.views
[pluto.log :as log] [pluto.log :as log]
[react-native-web.extensions :as rnw.extensions] [react-native-web.extensions :as rnw.extensions]
[react-native-web.hooks :as hooks]
[reagent.core :as reagent] [reagent.core :as reagent]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[re-frame.registrar :as registrar] [re-frame.registrar :as registrar]
@ -15,6 +17,30 @@
[react-native-web.react :as react] [react-native-web.react :as react]
[pluto.playground.components.dialogs :as dialogs])) [pluto.playground.components.dialogs :as dialogs]))
;; Components
(def Button (aget js/MaterialUI "Button"))
(defn button [props label]
[:> Button props
label])
(def Switch (aget js/MaterialUI "Switch"))
(defn switch [props]
[:> Switch props])
(def Select (aget js/MaterialUI "Select"))
(def MenuItem (aget js/MaterialUI "MenuItem"))
(defn select [{:keys [on-change selected options]}]
[:> Select {:value (or selected "") :on-change on-change :auto-width true}
(for [{:keys [value label]} options]
^{:key value}
[:> MenuItem {:value value}
label])])
(def warn (js/console.warn.bind js/console)) (def warn (js/console.warn.bind js/console))
(re-frame.loggers/set-loggers! (re-frame.loggers/set-loggers!
{:warn (fn [& args] {:warn (fn [& args]
@ -52,58 +78,75 @@
:event-fn dispatch-events :event-fn dispatch-events
:log-fn #(re-frame/dispatch [:extension/append-log %])}) :log-fn #(re-frame/dispatch [:extension/append-log %])})
(def payload
{:name "Test Extension"
:users [{:nm "Jane"}
{:nm "Sue"}]})
;; TODO list all views/events/queries used (per category)
;; TODO source viewer
(def Button (aget js/MaterialUI "Button"))
(defn button [props label]
[:> Button props
label])
(def Switch (aget js/MaterialUI "Switch"))
(defn switch [props]
[:> Switch props])
(defn flatten-errors [m] (defn flatten-errors [m]
(when (map? m) (when (map? m)
(apply concat (reduce-kv #(concat %1 (vals %3)) [] m)))) (apply concat (reduce-kv #(concat %1 (vals %3)) [] m))))
(defn parse-extension-id [extension-selection]
(map keyword (string/split extension-selection #"/")))
(defn view [props data id]
((get-in data [:views id]) props))
(defn selected-ui [props selection data]
(let [[type id] (parse-extension-id selection)]
(case type
:hooks (hooks/hook-in [id (get-in data [:hooks id])])
:views [:div {:style {:display :flex :width "100%" :height "100%"}}
[:div (:content props)]
[view props data id]]
nil)))
(defview layout [] (defview layout []
(letsubs [logs [:extension/filtered-logs] (letsubs [logs [:extension/filtered-logs]
errors [:extension/errors]] errors [:extension/errors]
[:div {:style {:display :flex :flex 1}} {:keys [views hooks] :as data} [:extension/parsed]
[dialogs/dialogs] extension-selection [:get :extension-selection]]
[:div {:style {:display :inline-block :width "calc(100% - 400px)"}} (let [keys (concat (map #(str "hooks/" (name %)) (keys hooks))
[:div (map #(str "views/" (name %)) (keys views)))
[:div {:style {:display :flex :justify-content :flex-end :align-items :center :margin "10px"}} selection (or extension-selection (first keys))
[button {:color "primary" :variant "contained" :on-click #(re-frame/dispatch [:set :browse-app-db true])} props @(re-frame/subscribe [:extension/properties selection])]
"Local app DB"]] [:div {:style {:display :flex :flex 1}}
[source/editor {:on-change #(re-frame.core/dispatch [:extension/update-source ctx %])}]] [dialogs/dialogs selection]
[:div [:div {:style {:display :inline-block :width "calc(100% - 400px)"}}
[:div {:style {:display :flex :justify-content :flex-end :align-items :center :margin "10px"}} [:div
[switch {:color "primary" :on-change #(re-frame/dispatch [:extension/switch-filter-logs %2])}] [:div {:style {:display :flex :justify-content :flex-end :align-items :center :margin "10px"}}
[:span {:style {:margin "10px"}} "Filter traces"] [button {:color "primary" :variant "contained" :on-click #(re-frame/dispatch [:set :browse-app-db true])}
[button {:color "primary" :variant "contained" :on-click #(re-frame/dispatch [:extension/clear-logs])} "Local app DB"]]
"Clear logs"]]] [source/editor {:on-change #(re-frame.core/dispatch [:extension/update-source ctx %])}]]
[:div {:style {:height "calc(40% - 50px)" :overflow :auto}} [:div
[logs/table (or (flatten-errors errors) logs)]]] [:div {:style {:display :flex :justify-content :flex-end :align-items :center :margin "10px"}}
[:div [switch {:color "primary" :on-change #(re-frame/dispatch [:extension/switch-filter-logs %2])}]
[:div {:style {:display :flex :justify-content :flex-end :padding-right 20 :margin "10px"}} [:span {:style {:margin "10px"}} "Filter traces"]
[button {:color "primary" :variant "contained" :on-click #(re-frame/dispatch [:set :examples true])} [button {:color "primary" :variant "contained" :on-click #(re-frame/dispatch [:extension/clear-logs])}
"Examples"] "Clear logs"]]]
[:div {:style {:width 10}}] [:div {:style {:height "calc(40% - 50px)" :overflow :auto}}
[button {:color "primary" :variant "contained" :on-click #(re-frame/dispatch [:extension/publish])} [logs/table (or (flatten-errors errors) logs)]]]
"Publish"]] [:div
[:div {:style {:border "40px solid #ddd" :border-width "20px 7px" :border-radius "40px" :margin 20}} [:div {:style {:display :flex :justify-content :flex-end :padding-right 20 :margin "10px"}}
[react/view {:style {:width 375 :height 667}} [button {:color "primary" :variant "contained" :on-click #(re-frame/dispatch [:set :examples true])}
[:div {:id "extension" :style {:display :flex :flex 1}}]]]]])) "Examples"]
[:div {:style {:width 10}}]
[button {:color "primary" :variant "contained" :on-click #(re-frame/dispatch [:extension/publish])}
"Publish"]]
[:div {:style {:border "40px solid #ddd" :border-width "20px 7px" :border-radius "40px" :margin 20}}
[react/view {:style {:width 375 :height 667}}
[:div {:id "extension" :style {:display :flex :flex 1}}
[selected-ui props selection data]]]]
[:div {:style {:display :flex :justify-content :center :flex-direction :column :padding 10}}
[:div {:style {:display :flex :justify-content :flex-end}}
[button {:color "primary" :variant "contained" :on-click #(re-frame/dispatch [:set :browse-app-db true])}
"Local app DB"]]
[:div {:style {:display :flex :justify-content :flex-end :align-items :center :margin "10px"}}
[:span {:style {:margin 10}}
"Selection"]
[select
{:on-change #(re-frame/dispatch [:set :extension-selection (.-key %2)])
:selected selection
:options (map #(do {:value % :label %}) keys)}]
[:div {:style {:margin 10}}
[button {:color "primary" :variant "contained" :on-click #(re-frame/dispatch [:set :browse-properties true])}
"Data"]]]]]])))
(defn mount-root [] (defn mount-root []
(reagent/render [layout] (.getElementById js/document "app"))) (reagent/render [layout] (.getElementById js/document "app")))

View File

@ -43,14 +43,10 @@
(re-frame/reg-fx (re-frame/reg-fx
:extension/parse :extension/parse
(fn [[ctx data]] (fn [[ctx data]]
(let [{:keys [data errors] :as m} (pluto/parse ctx data)] (let [{:keys [data errors]} (pluto/parse ctx data)]
(if errors (if errors
(re-frame/dispatch [:extension/update-errors errors]) (re-frame/dispatch [:extension/update-errors errors])
(do (re-frame/dispatch [:extension/update-parsed data])))))
(reagent/render-component
(hooks/hook-in (first (:hooks data)))
(.getElementById js/document "extension"))
(re-frame/dispatch [:extension/update-parsed data]))))))
(defn- update-extension-data (defn- update-extension-data
[{:keys [db]} [_ ctx data]] [{:keys [db]} [_ ctx data]]
@ -151,7 +147,8 @@
(re-frame.core/reg-event-fx (re-frame.core/reg-event-fx
:fetch-extension :fetch-extension
(fn [{:keys [db]} _] (fn [{:keys [db]} _]
{:fetch-extension-fx nil})) {:fetch-extension-fx nil
:dispatch [:store/clear-all]}))
(re-frame.core/reg-fx (re-frame.core/reg-fx
:set-url-fx :set-url-fx
@ -163,4 +160,9 @@
(fn [{db :db} [_ hash]] (fn [{db :db} [_ hash]]
{:db (dissoc db :examples) {:db (dissoc db :examples)
:set-url-fx hash :set-url-fx hash
:dispatch [:fetch-extension]})) :dispatch [:fetch-extension]}))
(re-frame.core/reg-event-fx
:extension/set-properties
(fn [{:keys [db]} [_ id m]]
{:db (assoc-in db [:extensions/properties id] m)}))

View File

@ -69,3 +69,8 @@
(re-frame/reg-sub (re-frame/reg-sub
:extension/preview :extension/preview
preview) preview)
(re-frame/reg-sub
:extension/properties
(fn [db [_ id _]]
(get-in db [:extensions/properties id])))

View File

@ -57,7 +57,7 @@
:else (nil? o))) :else (nil? o)))
(re-frame/reg-event-fx (re-frame/reg-event-fx
:fiddle/set-app-db :extension/set-app-db
(fn [{:keys [db]} [_ {id :hook-id} m]] (fn [{:keys [db]} [_ {id :hook-id} m]]
{:db (assoc-in db [:extensions/store id] m)})) {:db (assoc-in db [:extensions/store id] m)}))

View File

@ -6,9 +6,9 @@
[pluto.core :as pluto] [pluto.core :as pluto]
[clojure.string :as string])) [clojure.string :as string]))
(defn settings-hook [id {:keys [view]}] (defn settings-hook [id {:keys [view]} props]
[react/view {:style {:flex 1}} [react/view {:style {:flex 1}}
[view]]) [view props]])
(defn message-container [preview outgoing] (defn message-container [preview outgoing]
[react/view [react/view
@ -74,7 +74,7 @@
(defn rand-str [len] (defn rand-str [len]
(apply str (take len (repeatedly #(char (+ (rand 26) 65)))))) (apply str (take len (repeatedly #(char (+ (rand 26) 65))))))
(defview chat-view [preview parameters command-id] (defview chat-view [preview parameters command-id props]
(letsubs [{:keys [messages params suggestion-id]} [:get :extension-props]] (letsubs [{:keys [messages params suggestion-id]} [:get :extension-props]]
[react/view {:style {:flex 1}} [react/view {:style {:flex 1}}
[(react/scroll-view) {:style {:flex 1 :background-color :white}} [(react/scroll-view) {:style {:flex 1 :background-color :white}}
@ -82,8 +82,9 @@
(for [message messages] (for [message messages]
^{:key (str message (rand-str 10))} ^{:key (str message (rand-str 10))}
[react/view [react/view
[message-container (when preview (preview (merge {:outgoing false} message))) false] (let [m (merge {:outgoing false} message props)]
[message-container (when preview (preview (merge {:outgoing true} message))) true]])]] [message-container (when preview (preview m)) false]
[message-container (when preview (preview m)) true])])]]
(when-let [suggestion (some #(when (= suggestion-id (:id %)) (:suggestions %)) parameters)] (when-let [suggestion (some #(when (= suggestion-id (:id %)) (:suggestions %)) parameters)]
[react/view {:style {:max-height 300}} [react/view {:style {:max-height 300}}
[suggestion]]) [suggestion]])
@ -105,13 +106,15 @@
#_[icons/icon :main-icons/arrow-up {:container-style send-message-icon #_[icons/icon :main-icons/arrow-up {:container-style send-message-icon
:color :white}]]]]])) :color :white}]]]]]))
(defn command-hook [id {:keys [parameters preview]}] (defn command-hook [id {:keys [parameters preview]} props]
[chat-view preview parameters id]) [chat-view preview parameters id props])
(defn hook-in [[id parsed]] (defn hook-in [[id parsed] props]
(when id (when id
(let [hook-id (last (string/split (name id) #"\.")) (let [hook-id (last (string/split (name id) #"\."))
type (pluto/hook-type id)] type (pluto/hook-type id)]
(case type (case type
"chat.command" (command-hook hook-id parsed) "chat.command" (command-hook hook-id parsed props)
"wallet.settings" (settings-hook hook-id parsed))))) "wallet.settings" (settings-hook hook-id parsed props)
[:div
(str "Unknown hook type " type)]))))

View File

@ -13,12 +13,6 @@
{:photo "?" :name "Test Name 2" :address "0x00testaddress02" :public-key "0x00testpulickey02"} {:photo "?" :name "Test Name 2" :address "0x00testaddress02" :public-key "0x00testpulickey02"}
{:photo "?" :name "Test Name 3" :address "0x00testaddress03" :public-key "0x00testpulickey03"}])) {:photo "?" :name "Test Name 3" :address "0x00testaddress03" :public-key "0x00testpulickey03"}]))
:get-collectible-token
(re-frame/reg-sub
:extensions.wallet/tokens
(fn [_ [_ _ _]]
{:name "Test"}))
(defn get-token-for [network all-tokens token] (defn get-token-for [network all-tokens token]
{:decimals 18 {:decimals 18
:address "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}) :address "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"})