Allow editing existing mailservers
Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
e59ffc905d
commit
1e4311d4cb
|
@ -0,0 +1,22 @@
|
|||
(ns status-im.models.wnode
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[status-im.utils.ethereum.core :as ethereum]))
|
||||
|
||||
(defn- extract-address-components [address]
|
||||
(rest (re-matches #"enode://(.*)@(.*)" address)))
|
||||
|
||||
(defn- get-chain [db]
|
||||
(let [network (get (:networks (:account/account db)) (:network db))]
|
||||
(ethereum/network->chain-keyword network)))
|
||||
|
||||
(defn get-wnode [wnode-id {:keys [db]}]
|
||||
(get-in db [:inbox/wnodes (get-chain db) wnode-id]))
|
||||
|
||||
(defn current-wnode? [wnode-id {:keys [db]}]
|
||||
(let [current-wnode-id (get-in db [:account/account :settings :wnode (get-chain db)])]
|
||||
(= current-wnode-id wnode-id)))
|
||||
|
||||
(defn build-url [address password]
|
||||
(let [[initial host] (extract-address-components address)]
|
||||
(str "enode://" initial ":" password "@" host)))
|
|
@ -1,6 +1,7 @@
|
|||
(ns status-im.ui.screens.offline-messaging-settings.edit-mailserver.events
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.models.wnode :as models.wnode]
|
||||
[status-im.utils.handlers :refer [register-handler] :as handlers]
|
||||
[status-im.utils.handlers-macro :as handlers-macro]
|
||||
[status-im.ui.screens.accounts.utils :as accounts.utils]
|
||||
|
@ -9,38 +10,57 @@
|
|||
[status-im.utils.inbox :as utils.inbox]
|
||||
[status-im.data-store.mailservers :as data-store.mailservers]))
|
||||
|
||||
(defn- new-mailserver [id mailserver-name address]
|
||||
(defn- build-mailserver [id mailserver-name address]
|
||||
(assoc (utils.inbox/address->mailserver address)
|
||||
:id (string/replace id "-" "")
|
||||
:name mailserver-name))
|
||||
|
||||
(defn save-new-mailserver [{{:mailservers/keys [manage] :account/keys [account] :as db} :db :as cofx} _]
|
||||
(let [{:keys [name url]} manage
|
||||
(defn upsert-mailserver [{{:mailservers/keys [manage] :account/keys [account] :as db} :db :as cofx} _]
|
||||
(let [{:keys [name url id]} manage
|
||||
network (get (:networks (:account/account db)) (:network db))
|
||||
chain (ethereum/network->chain-keyword network)
|
||||
mailserver (new-mailserver
|
||||
(string/replace (:random-id cofx) "-" "")
|
||||
mailserver (build-mailserver
|
||||
(or (:value id)
|
||||
(string/replace (:random-id cofx) "-" ""))
|
||||
(:value name)
|
||||
(:value url))]
|
||||
(:value url))
|
||||
connected-to-wnode? (models.wnode/current-wnode? (:id mailserver) cofx)]
|
||||
{:db (-> db
|
||||
(dissoc :mailservers/manage)
|
||||
(assoc-in [:inbox/wnodes chain (:id mailserver)] mailserver))
|
||||
:data-store/tx [(data-store.mailservers/save-mailserver-tx (assoc
|
||||
:data-store/tx [{:transaction
|
||||
(data-store.mailservers/save-mailserver-tx (assoc
|
||||
mailserver
|
||||
:chain
|
||||
chain))]
|
||||
chain))
|
||||
;; we naively logout if the user is connected to the edited mailserver
|
||||
:success-event (when connected-to-wnode? [:logout])}]
|
||||
:dispatch [:navigate-back]}))
|
||||
|
||||
(defn set-input [input-key value {:keys [db]}]
|
||||
{:db (update db :mailservers/manage assoc input-key {:value value
|
||||
:error (if (= input-key :name)
|
||||
(string/blank? value)
|
||||
(not (utils.inbox/valid-enode-address? value)))})})
|
||||
:error (case input-key
|
||||
:id false
|
||||
:name (string/blank? value)
|
||||
:url (not (utils.inbox/valid-enode-address? value)))})})
|
||||
|
||||
(defn edit-mailserver [wnode-id {:keys [db] :as cofx}]
|
||||
(let [{:keys [id
|
||||
address
|
||||
password
|
||||
name]} (models.wnode/get-wnode wnode-id cofx)
|
||||
url (when address (models.wnode/build-url address password))
|
||||
fxs (handlers-macro/merge-fx
|
||||
cofx
|
||||
(set-input :id id)
|
||||
(set-input :url (str url))
|
||||
(set-input :name (str name)))]
|
||||
(assoc fxs :dispatch [:navigate-to :edit-mailserver])))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:save-new-mailserver
|
||||
:upsert-mailserver
|
||||
[(re-frame/inject-cofx :random-id)]
|
||||
save-new-mailserver)
|
||||
upsert-mailserver)
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:mailserver-set-input
|
||||
|
@ -49,11 +69,8 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:edit-mailserver
|
||||
(fn [{db :db} _]
|
||||
{:db (update-in db [:mailservers/manage] assoc
|
||||
:name {:error true}
|
||||
:url {:error true})
|
||||
:dispatch [:navigate-to :edit-mailserver]}))
|
||||
(fn [cofx [_ wnode-id]]
|
||||
(edit-mailserver wnode-id cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:set-mailserver-from-qr
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns status-im.ui.screens.offline-messaging-settings.edit-mailserver.styles
|
||||
(:require-macros [status-im.utils.styles :refer [defstyle]])
|
||||
(:require [status-im.ui.components.styles :as styles]))
|
||||
(:require [status-im.ui.components.styles :as styles]
|
||||
[status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def edit-mailserver-view
|
||||
{:flex 1
|
||||
|
@ -28,3 +29,31 @@
|
|||
{:flex-direction :row
|
||||
:margin-horizontal 12
|
||||
:margin-vertical 15})
|
||||
|
||||
(def connect-button-container
|
||||
{:margin-top 8
|
||||
:margin-bottom 16
|
||||
:margin-horizontal 16})
|
||||
|
||||
(defstyle connect-button
|
||||
{:height 52
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:background-color colors/blue
|
||||
:border-radius 8
|
||||
:ios {:opacity 0.9}})
|
||||
|
||||
(defstyle connect-button-label
|
||||
{:color colors/white
|
||||
:ios {:font-size 17
|
||||
:letter-spacing -0.2}
|
||||
:android {:font-size 14}})
|
||||
|
||||
(defstyle connect-button-description
|
||||
{:color colors/gray
|
||||
:ios {:margin-top 8
|
||||
:height 20
|
||||
:font-size 14
|
||||
:letter-spacing -0.2}
|
||||
:android {:margin-top 12
|
||||
:font-size 12}})
|
||||
|
|
|
@ -14,6 +14,15 @@
|
|||
[status-im.ui.components.text-input.view :as text-input]
|
||||
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.styles :as styles]))
|
||||
|
||||
(defn connect-button [id]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:connect-wnode id])}
|
||||
[react/view styles/connect-button-container
|
||||
[react/view {:style styles/connect-button
|
||||
:accessibility-label :mailserver-connect-button}
|
||||
[react/text {:style styles/connect-button-label
|
||||
:uppercase? true}
|
||||
(i18n/label :t/connect)]]]])
|
||||
|
||||
(def qr-code
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:scan-qr-code
|
||||
{:toolbar-title (i18n/label :t/add-mailserver)}
|
||||
|
@ -25,6 +34,9 @@
|
|||
(views/defview edit-mailserver []
|
||||
(views/letsubs [manage-mailserver [:get-manage-mailserver]
|
||||
is-valid? [:manage-mailserver-valid?]]
|
||||
(let [url (get-in manage-mailserver [:url :value])
|
||||
id (get-in manage-mailserver [:id :value])
|
||||
name (get-in manage-mailserver [:name :value])]
|
||||
[react/view components.styles/flex
|
||||
[status-bar/status-bar]
|
||||
[react/keyboard-avoiding-view components.styles/flex
|
||||
|
@ -36,7 +48,7 @@
|
|||
:placeholder (i18n/label :t/specify-name)
|
||||
:style styles/input
|
||||
:container styles/input-container
|
||||
:default-value (get-in manage-mailserver [:name :value])
|
||||
:default-value name
|
||||
:on-change-text #(re-frame/dispatch [:mailserver-set-input :name %])
|
||||
:auto-focus true}]
|
||||
[text-input/text-input-with-label
|
||||
|
@ -45,12 +57,13 @@
|
|||
:content qr-code
|
||||
:style styles/input
|
||||
:container styles/input-container
|
||||
:default-value (get-in manage-mailserver [:url :value])
|
||||
:on-change-text #(re-frame/dispatch [:mailserver-set-input :url %])}]]]
|
||||
:default-value url
|
||||
:on-change-text #(re-frame/dispatch [:mailserver-set-input :url %])}]
|
||||
(when id [connect-button id])]]
|
||||
[react/view styles/bottom-container
|
||||
[react/view components.styles/flex]
|
||||
[components.common/bottom-button
|
||||
{:forward? true
|
||||
:label (i18n/label :t/save)
|
||||
:disabled? (not is-valid?)
|
||||
:on-press #(re-frame/dispatch [:save-new-mailserver])}]]]]))
|
||||
:on-press #(re-frame/dispatch [:upsert-mailserver])}]]]])))
|
||||
|
|
|
@ -15,14 +15,19 @@
|
|||
[react/view (styles/wnode-icon connected?)
|
||||
[vector-icons/icon :icons/wnode {:color (if connected? :white :gray)}]])
|
||||
|
||||
(defn navigate-to-add-mailserver []
|
||||
(re-frame/dispatch [:edit-mailserver]))
|
||||
(defn connect-to-mailserver [id]
|
||||
(re-frame/dispatch [:connect-wnode id]))
|
||||
|
||||
(defn- render-row [current-wnode]
|
||||
(fn [{:keys [name id]}]
|
||||
(let [connected? (= id current-wnode)]
|
||||
(defn navigate-to-add-mailserver [wnode-id]
|
||||
(re-frame/dispatch [:edit-mailserver wnode-id]))
|
||||
|
||||
(defn- render-row [current-wnode-id]
|
||||
(fn [{:keys [name id user-defined]}]
|
||||
(let [connected? (= id current-wnode-id)]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:connect-wnode id])
|
||||
{:on-press #(if user-defined
|
||||
(navigate-to-add-mailserver id)
|
||||
(connect-to-mailserver id))
|
||||
:accessibility-label :mailserver-item}
|
||||
[react/view styles/wnode-item
|
||||
[wnode-icon connected?]
|
||||
|
@ -31,7 +36,7 @@
|
|||
name]]]])))
|
||||
|
||||
(views/defview offline-messaging-settings []
|
||||
(views/letsubs [current-wnode [:settings/current-wnode]
|
||||
(views/letsubs [current-wnode-id [:settings/current-wnode]
|
||||
wnodes [:settings/network-wnodes]]
|
||||
[react/view {:flex 1}
|
||||
[status-bar/status-bar]
|
||||
|
@ -40,9 +45,9 @@
|
|||
[toolbar/content-title (i18n/label :t/offline-messaging-settings)]
|
||||
(when config/add-custom-mailservers-enabled?
|
||||
[toolbar/actions
|
||||
[(toolbar.actions/add false navigate-to-add-mailserver)]])]
|
||||
[(toolbar.actions/add false (partial navigate-to-add-mailserver nil))]])]
|
||||
[react/view styles/wrapper
|
||||
[list/flat-list {:data (vals wnodes)
|
||||
:default-separator? false
|
||||
:key-fn :id
|
||||
:render-fn (render-row current-wnode)}]]]))
|
||||
:render-fn (render-row current-wnode-id)}]]]))
|
||||
|
|
|
@ -2,7 +2,12 @@
|
|||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.events :as events]))
|
||||
|
||||
(def valid-enode-url "enode://1da276e34126e93babf24ec88aac1a7602b4cbb2e11b0961d0ab5e989ca9c261aa7f7c1c85f15550a5f1e5a5ca2305b53b9280cf5894d5ecf7d257b173136d40:somepassword@167.99.209.61:30504")
|
||||
(def enode-id "1da276e34126e93babf24ec88aac1a7602b4cbb2e11b0961d0ab5e989ca9c261aa7f7c1c85f15550a5f1e5a5ca2305b53b9280cf5894d5ecf7d257b173136d40")
|
||||
(def password "password")
|
||||
(def host "167.99.209.61:30504")
|
||||
|
||||
(def valid-enode-address (str "enode://" enode-id "@" host))
|
||||
(def valid-enode-url (str "enode://" enode-id ":" password "@" host))
|
||||
|
||||
(deftest set-input
|
||||
(testing "it validates names"
|
||||
|
@ -24,8 +29,59 @@
|
|||
:error true}}}}
|
||||
(events/set-input :url "broken" {}))))))
|
||||
|
||||
(deftest save-new-mailserver
|
||||
(testing "save a new mailserver"
|
||||
(deftest edit-mailserver
|
||||
(let [db {:network "mainnet_rpc"
|
||||
:account/account {:networks {"mainnet_rpc"
|
||||
{:config {:NetworkId 1}}}}
|
||||
:inbox/wnodes
|
||||
{:mainnet {"a" {:id "a"
|
||||
:address valid-enode-address
|
||||
:password password
|
||||
:name "name"}}}}
|
||||
cofx {:db db}]
|
||||
(testing "when no id is given"
|
||||
(let [actual (events/edit-mailserver nil cofx)]
|
||||
(testing "it resets :mailserver/manage"
|
||||
(is (= {:id {:value nil
|
||||
:error false}
|
||||
:url {:value ""
|
||||
:error true}
|
||||
:name {:value ""
|
||||
:error true}}
|
||||
(-> actual :db :mailservers/manage))))
|
||||
(testing "it navigates to edit-mailserver view"
|
||||
(is (= [:navigate-to :edit-mailserver]
|
||||
(-> actual :dispatch))))))
|
||||
(testing "when an id is given"
|
||||
(testing "when the wnode is in the list"
|
||||
(let [actual (events/edit-mailserver "a" cofx)]
|
||||
(testing "it populates the fields with the correct values"
|
||||
(is (= {:id {:value "a"
|
||||
:error false}
|
||||
:url {:value valid-enode-url
|
||||
:error false}
|
||||
:name {:value "name"
|
||||
:error false}}
|
||||
(-> actual :db :mailservers/manage))))
|
||||
(testing "it navigates to edit-mailserver view"
|
||||
(is (= [:navigate-to :edit-mailserver]
|
||||
(-> actual :dispatch))))))
|
||||
(testing "when the wnode is not in the list"
|
||||
(let [actual (events/edit-mailserver "not-existing" cofx)]
|
||||
(testing "it populates the fields with the correct values"
|
||||
(is (= {:id {:value nil
|
||||
:error false}
|
||||
:url {:value ""
|
||||
:error true}
|
||||
:name {:value ""
|
||||
:error true}}
|
||||
(-> actual :db :mailservers/manage))))
|
||||
(testing "it navigates to edit-mailserver view"
|
||||
(is (= [:navigate-to :edit-mailserver]
|
||||
(-> actual :dispatch)))))))))
|
||||
|
||||
(deftest upsert-mailserver
|
||||
(testing "new mailserver"
|
||||
(let [cofx {:random-id "random-id"
|
||||
:db {:network "mainnet_rpc"
|
||||
:account/account {:networks {"mainnet_rpc"
|
||||
|
@ -34,7 +90,8 @@
|
|||
:url {:value "enode://test-id:test-password@url:port"}}
|
||||
|
||||
:inbox/wnodes {}}}
|
||||
actual (events/save-new-mailserver cofx nil)]
|
||||
actual (events/upsert-mailserver cofx nil)]
|
||||
|
||||
(testing "it adds the enode to inbox/wnodes"
|
||||
(is (= {:mainnet {"randomid" {:password "test-password"
|
||||
:address "enode://test-id@url:port"
|
||||
|
@ -42,5 +99,40 @@
|
|||
:id "randomid"
|
||||
:user-defined true}}}
|
||||
(get-in actual [:db :inbox/wnodes]))))
|
||||
(testing "it navigates back"
|
||||
(is (= [:navigate-back]
|
||||
(:dispatch actual))))
|
||||
(testing "it stores it in the db"
|
||||
(is (= 1 (count (:data-store/tx actual))))))))
|
||||
(is (= 1 (count (:data-store/tx actual)))))))
|
||||
(testing "existing mailserver"
|
||||
(let [cofx {:random-id "random-id"
|
||||
:db {:network "mainnet_rpc"
|
||||
:account/account {:networks {"mainnet_rpc"
|
||||
{:config {:NetworkId 1}}}}
|
||||
:mailservers/manage {:id {:value "a"}
|
||||
:name {:value "new-name"}
|
||||
:url {:value "enode://new-id:new-password@url:port"}}
|
||||
|
||||
:inbox/wnodes {:mainnet {"a" {:id "a"
|
||||
:name "old-name"
|
||||
:address "enode://old-id:old-password@url:port"}}}}}
|
||||
actual (events/upsert-mailserver cofx nil)]
|
||||
(testing "it navigates back"
|
||||
(is (= [:navigate-back]
|
||||
(:dispatch actual))))
|
||||
(testing "it updates the enode to inbox/wnodes"
|
||||
(is (= {:mainnet {"a" {:password "new-password"
|
||||
:address "enode://new-id@url:port"
|
||||
:name "new-name"
|
||||
:id "a"
|
||||
:user-defined true}}}
|
||||
(get-in actual [:db :inbox/wnodes]))))
|
||||
(testing "it stores it in the db"
|
||||
(is (= 1 (count (:data-store/tx actual)))))
|
||||
(testing "it logs the user out if connected to the current mailserver"
|
||||
(let [actual (events/upsert-mailserver (assoc-in cofx
|
||||
[:db :account/account :settings]
|
||||
{:wnode
|
||||
{:mainnet "a"}}) nil)]
|
||||
(is (= [:logout]
|
||||
(-> actual :data-store/tx first :success-event))))))))
|
||||
|
|
Loading…
Reference in New Issue