[#8977] [Multi-account] Allow user to choose wallet for DApp transactions

Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
Andrey Shovkoplyas 2019-10-04 13:52:33 +02:00
parent 5fd269fde8
commit df098f82f6
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
28 changed files with 360 additions and 153 deletions

View File

@ -1,5 +1,9 @@
# new icons
## Export icons
![](./export-icons.gif)
## android
1. copy files to corresponding directories at `/Users/romanvolosovskyi/clj/status-react/android/app/src/main/res` (one of `drawable-hdpi`, `drawable-mdpi`, `drawable-xhdpi`, `drawable-xxhdpi`, `drawable-xxxhdpi` for corresponding resolution)
If you only have 3 pngs 1x, 2x and 3x put them in mdpi, xhdpi and xxhdpi

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

BIN
export-icons.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "account.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "account@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "account@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

View File

@ -21,7 +21,9 @@
[status-im.utils.types :as types]
[status-im.utils.universal-links.core :as universal-links]
[taoensso.timbre :as log]
[status-im.signing.core :as signing]))
[status-im.signing.core :as signing]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]))
(fx/defn update-browser-option
[{:keys [db]} option-key option-value]
@ -311,29 +313,37 @@
(ethereum/address? second-param)
[second-param first-param]))))
(fx/defn send-to-bridge
[cofx message]
{:browser/send-to-bridge {:message message
:webview (get-in cofx [:db :webview-bridge])}})
(fx/defn web3-send-async
[cofx {:keys [method params id] :as payload} message-id]
(let [message? (constants/web3-sign-message? method)]
(let [message? (constants/web3-sign-message? method)
dapps-address (get-in cofx [:db :multiaccount :dapps-address])]
(if (or message? (= constants/web3-send-transaction method))
(let [[address data] (when message? (normalize-sign-message-params params))]
(when (or (not message?) (and address data))
(signing/sign cofx (merge
(if message?
{:message {:address address :data data :typed? (not= constants/web3-personal-sign method)}}
{:tx-obj (first params)})
{:message {:address address :data data :typed? (not= constants/web3-personal-sign method)
:from dapps-address}}
{:tx-obj (update (first params) :from #(or % dapps-address))})
{:on-result [:browser.dapp/transaction-on-result message-id id]
:on-error [:browser.dapp/transaction-on-error message-id]}))))
{:browser/call-rpc [payload
#(re-frame/dispatch [:browser.callback/call-rpc
{:type constants/web3-send-async-callback
:messageId message-id
:error %1
:result %2}])]})))
(fx/defn send-to-bridge
[cofx message]
{:browser/send-to-bridge {:message message
:webview (get-in cofx [:db :webview-bridge])}})
(if (#{"eth_accounts" "eth_coinbase"} method)
(send-to-bridge cofx {:type constants/web3-send-async-callback
:messageId message-id
:result {:jsonrpc "2.0"
:id (int id)
:result (if (= method "eth_coinbase") dapps-address [dapps-address])}})
{:browser/call-rpc [payload
#(re-frame/dispatch [:browser.callback/call-rpc
{:type constants/web3-send-async-callback
:messageId message-id
:error %1
:result %2}])]}))))
(fx/defn web3-send-async-read-only
[{:keys [db] :as cofx} dapp-name {:keys [method] :as payload} message-id]
@ -437,7 +447,24 @@
(fn [link]
(list-selection/browse-in-web-browser link)))
(re-frame/reg-fx
:browser/clear-web-data
(fn []
(status/clear-web-data)))
(defn share-link [url]
(let [link (universal-links/generate-link :browse :external url)
message (i18n/label :t/share-dapp-text {:link link})]
(list-selection/open-share {:message message})))
(fx/defn dapps-account-selected
{:events [:dapps-account-selected]}
[{:keys [db] :as cofx} address]
(fx/merge cofx
{:browser/clear-web-data nil}
(bottom-sheet/hide-bottom-sheet)
(browser.permissions/clear-dapps-permissions)
(multiaccounts.update/multiaccount-update {:dapps-address address} {})
#(when (= (:view-id db) :browser)
(merge (navigation/navigate-back %)
{:dispatch [:browser.ui/browser-item-selected (get-in db [:browser/options :browser-id])]}))))

View File

@ -1,12 +1,10 @@
(ns status-im.browser.permissions
(:require [status-im.constants :as constants]
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.i18n :as i18n]
[status-im.qr-scanner.core :as qr-scanner]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.fx :as fx]
[status-im.ethereum.core :as ethereum]))
[status-im.utils.fx :as fx]))
(declare process-next-permission)
(declare send-response-to-bridge)
@ -14,10 +12,12 @@
(def supported-permissions
{constants/dapp-permission-qr-code {:yield-control? true
:allowed? true}
constants/dapp-permission-contact-code {:title (i18n/label :t/wants-to-access-profile)
constants/dapp-permission-contact-code {:type :profile
:title (i18n/label :t/wants-to-access-profile)
:description (i18n/label :t/your-contact-code)
:icon :main-icons/profile}
constants/dapp-permission-web3 {:title (i18n/label :t/dapp-would-like-to-connect-wallet)
constants/dapp-permission-web3 {:type :wallet
:title (i18n/label :t/dapp-would-like-to-connect-wallet)
:description (i18n/label :t/allowing-authorizes-this-dapp)
:icon :main-icons/wallet}})
@ -44,7 +44,7 @@
(defn get-permission-data [cofx allowed-permission]
(let [multiaccount (get-in cofx [:db :multiaccount])]
(get {constants/dapp-permission-contact-code (:public-key multiaccount)
constants/dapp-permission-web3 [(:address (ethereum/get-default-account (:accounts multiaccount)))]}
constants/dapp-permission-web3 [(:dapps-address multiaccount)]}
allowed-permission)))
(fx/defn send-response-to-bridge
@ -81,6 +81,15 @@
:on-success #()}]}
(navigation/navigate-back)))
(fx/defn clear-dapps-permissions
[{:keys [db]}]
(let [dapp-permissions (keys (:dapps/permissions db))]
{:db (dissoc db :dapps/permissions)
::json-rpc/call (for [dapp dapp-permissions]
{:method "permissions_deleteDappPermissions"
:params [dapp]
:on-success #()})}))
(fx/defn process-next-permission
"Process next permission by removing it from pending permissions and prompting user
if there is no pending permissions left, save all granted permissions

View File

@ -228,6 +228,8 @@
:photo-path photo-path
; public key of the chat account
:public-key publicKey
; default address for Dapps
:dapps-address (:address wallet-account)
:latest-derived-path 0
:accounts [wallet-account]
:signing-phrase signing-phrase

View File

@ -60,9 +60,9 @@
(fx/defn sign-message
[{{:signing/keys [sign tx] :as db} :db}]
(let [{{:keys [data typed?]} :message} tx
(let [{{:keys [data typed? from]} :message} tx
{:keys [in-progress? password]} sign
from (ethereum/default-address db)
from (or from (ethereum/default-address db))
hashed-password (ethereum/sha3 (security/safe-unmask-data password))]
(when-not in-progress?
(merge

View File

@ -457,6 +457,19 @@
(or (get sett :log-level)
config/log-level-status-go)))
(re-frame/reg-sub
:dapps-address
:<- [:multiaccount]
(fn [acc]
(get acc :dapps-address)))
(re-frame/reg-sub
:dapps-account
:<- [:multiaccount]
:<- [:dapps-address]
(fn [[acc address]]
(some #(when (= (:address %) address) %) (:accounts acc))))
;;CHAT ==============================================================================================================
(re-frame/reg-sub

View File

@ -102,10 +102,7 @@
height content on-cancel]
:or {on-cancel #(re-frame/dispatch [:bottom-sheet/hide])}
:as opts}]
[react/keyboard-avoiding-view
(merge
(pan-handlers (swipe-pan-responder opts))
{:style styles/container})
[react/keyboard-avoiding-view {:style styles/container}
[react/touchable-highlight
{:on-press #(cancel opts on-cancel)
:style styles/container}
@ -113,7 +110,10 @@
[react/animated-view (styles/shadow opacity-value)]]
[react/animated-view
{:style (styles/content-container height bottom-value)}
[react/view styles/content-header
[react/view
(merge
(pan-handlers (swipe-pan-responder opts))
{:style styles/content-header})
[react/view styles/handle]]
[react/view {:style {:flex 1
:height height}}

View File

@ -4,7 +4,7 @@
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.utils.label :as utils.label]))
(defn style-container [type disabled?]
(defn style-container [type disabled? theme]
(merge
(when (= type :main)
{:margin-vertical 8 :margin-horizontal 16})
@ -24,7 +24,10 @@
disabled?
colors/gray-transparent-10
(= type :main)
colors/blue-transparent-10
(case theme
:red colors/red-transparent-10
:green colors/green-transparent-10
colors/blue-transparent-10)
:else
"")}))
@ -34,6 +37,9 @@
'type'
:main (default), :secondary, :next, :previous
`theme`
:blue (default), :green, :red
`label`
Any one of string, keyword representing translated string in the form of :t/{translation-key-in-translation-files}
@ -45,12 +51,12 @@
Spec: https://www.figma.com/file/cb4p8AxLtTF3q1L6JYDnKN15/Index?node-id=858%3A0"
[{:keys [label type disabled? on-press accessibility-label style] :or {type :main}}]
[{:keys [label type theme disabled? on-press accessibility-label style] :or {type :main theme :blue}}]
(let [label (utils.label/stringify label)]
[react/touchable-opacity (merge {:on-press on-press :disabled disabled? :active-pacity 0.5 :style style}
(when accessibility-label
{:accessibility-label accessibility-label}))
[react/view {:style (style-container type disabled?)}
[react/view {:style (style-container type disabled? theme)}
[react/view {:flex-direction :row :align-items :center}
(when (= type :previous)
[vector-icons/icon :main-icons/back {:container-style {:width 24 :height 24 :margin-right 4}
@ -59,7 +65,10 @@
disabled?
colors/gray
(#{:main :secondary :next :previous} type)
colors/blue
(case theme
:green colors/green
:red colors/red
colors/blue)
:else
"")}}
label]

View File

@ -47,7 +47,7 @@
:padding-bottom (if (= type :section-header) 4 10)
:align-items :center}
(when selected?
{:background-color colors/gray-transparent-40})))
{:background-color colors/blue-light})))
(def icon-column-container
{:margin-right 14

View File

@ -7,7 +7,8 @@
[status-im.ui.components.tooltip.views :as tooltip]
[status-im.ui.screens.chat.photos :as photos]
[status-im.ui.screens.profile.db :as profile.db]
[status-im.utils.label :as utils.label]))
[status-im.utils.label :as utils.label]
[status-im.ui.components.radio :as radio]))
(def divider
[react/view {:height 1 :background-color colors/gray-lighter}])
@ -350,13 +351,12 @@
(reagent/create-class
{:reagent-render
(fn
[{:keys
[react-key type theme container-margin-top container-margin-bottom
icon title-prefix title-prefix-width title-prefix-height
title title-color-override title-row-accessory
title-accessibility-label subtitle subtitle-max-lines
subtitle-row-accessory content accessories on-press
on-long-press error accessibility-label disabled? selected?]
[{:keys [react-key type theme container-margin-top container-margin-bottom
icon title-prefix title-prefix-width title-prefix-height
title title-color-override title-row-accessory
title-accessibility-label subtitle subtitle-max-lines
subtitle-row-accessory content accessories on-press
on-long-press error accessibility-label disabled? selected?]
:or {react-key r-key
type :default
theme :default
@ -364,19 +364,18 @@
container-margin-top 0
container-margin-bottom 0
subtitle-max-lines 1}}]
(let [title-row-elements
{:title title
:title-color-override title-color-override
:title-accessibility-label title-accessibility-label
:title-prefix title-prefix
:title-prefix-width title-prefix-width
:title-prefix-height title-prefix-height
:title-row-accessory title-row-accessory}
subtitle-row-elements
{:subtitle subtitle
:subtitle-max-lines subtitle-max-lines
:subtitle-row-accessory subtitle-row-accessory}
radio-selected? (and (= theme :selectable) selected?)]
(let [title-row-elements {:title title
:title-color-override title-color-override
:title-accessibility-label title-accessibility-label
:title-prefix title-prefix
:title-prefix-width title-prefix-width
:title-prefix-height title-prefix-height
:title-row-accessory title-row-accessory}
subtitle-row-elements {:subtitle subtitle
:subtitle-max-lines subtitle-max-lines
:subtitle-row-accessory subtitle-row-accessory}
theme-select? (= theme :selectable)
radio-selected? (and theme-select? selected?)]
^{:key react-key}
(if (= type :divider)
divider
@ -384,12 +383,12 @@
:margin-bottom container-margin-bottom}
:on-layout #(reset! width (-> % .-nativeEvent .-layout .-width))}
[react/touchable-highlight
(cond-> {:on-press (when (not= theme :selectable) on-press)
:on-press-in (when (= theme :selectable) on-press)
(cond-> {:on-press (when (not theme-select?) on-press)
:on-press-in (when theme-select? on-press)
:on-long-press on-long-press
:underlay-color colors/gray-transparent-40
:active-opacity (if (= theme :selectable) 1 0.85)
:disabled (or (not on-press) selected? disabled?)}
:active-opacity (if theme-select? 1 0.85)
:disabled (or (not on-press) selected? disabled?)}
accessibility-label
(assoc :accessibility-label accessibility-label))
[react/view {:style (styles/container type radio-selected?)}
@ -401,7 +400,10 @@
title-row-elements subtitle-row-elements
type icon disabled? theme content accessories])
(when accessories
[accessories-column accessories width])]]
(if theme-select?
[react/view styles/accessories-container
[radio/radio radio-selected?]]
(when accessories
[accessories-column accessories width]))]]
(when error
[tooltip/tooltip error styles/error])])))})))

View File

@ -0,0 +1,27 @@
(ns status-im.ui.screens.browser.accounts
(:require [status-im.ui.components.list.views :as list]
[status-im.i18n :as i18n]
[status-im.ui.components.react :as react]
[status-im.ui.components.list-item.views :as list-item]
[status-im.ui.components.chat-icon.screen :as chat-icon]
[status-im.utils.utils :as utils]
[re-frame.core :as re-frame]))
(defn render-account [dapps-account]
(fn [account]
[list-item/list-item
{:theme :selectable
:selected? (= (:address dapps-account) (:address account))
:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]
:title (:name account)
:subtitle (utils/get-shortened-checksum-address (:address account))
:on-press #(re-frame/dispatch [:dapps-account-selected (:address account)])}]))
(defn accounts-list [accounts dapps-account]
(fn []
[react/view {:flex 1}
[react/text {:style {:margin 16 :text-align :center}}
(i18n/label :t/select-account-dapp)]
[list/flat-list {:data accounts
:key-fn :address
:render-fn (render-account dapps-account)}]]))

View File

@ -63,3 +63,18 @@
:color colors/gray
:line-height 18
:margin-top 2})
(defn dapps-account [color]
{:flex-direction :row
:background-color color
:border-radius 36
:padding-horizontal 8
:padding-vertical 6
:flex 1
:align-items :center
:justify-content :center
:shadow-offset {:width 0 :height 1}
:shadow-radius 6
:shadow-opacity 1
:shadow-color "rgba(0, 12, 63, 0.2)"
:elevation 2})

View File

@ -15,7 +15,8 @@
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.radio :as radio]
[status-im.ui.components.icons.vector-icons :as icons]
[reagent.core :as reagent])
[reagent.core :as reagent]
[status-im.ui.screens.browser.accounts :as accounts])
(:require-macros [status-im.utils.views :as views]))
(defn hide-sheet-and-dispatch [event]
@ -96,6 +97,30 @@
[react/text {:style {:line-height 22 :font-size 15 :color colors/gray}}
(i18n/label :t/recent)]])])
(views/defview select-account []
(views/letsubs [height [:dimensions/window-height]
{:keys [accounts]} [:multiaccount]
{:keys [name color] :as dapps-account} [:dapps-account]]
[react/view {:position :absolute
:z-index 2
:align-items :center
:bottom (+ 16 tabs.styles/tabs-diff)
:left 0
:right 0
:padding-horizontal 32}
[react/touchable-highlight
{:accessibility-label :select-account
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet
{:content (accounts/accounts-list accounts dapps-account)
:content-height (/ height 2)}])}
[react/view (styles/dapps-account color)
[icons/icon :main-icons/account {:color colors/white}]
[react/view {:flex-shrink 1}
[react/text {:numberOfLines 1
:style {:margin-horizontal 6 :color :white :typography :main-medium}}
name]]
[icons/icon :main-icons/dropdown {:color colors/white-transparent}]]]]))
(views/defview open-dapp []
(views/letsubs [browsers [:browser/browsers-vals]
url-text (atom nil)]
@ -116,8 +141,9 @@
[list-header false]
[list/flat-list {:data browsers
:footer [react/view
{:style {:height tabs.styles/tabs-diff
{:style {:height (+ tabs.styles/tabs-diff 64)
:align-self :stretch}}]
:key-fn :browser-id
:end-fill-color colors/white
:render-fn list-item}]])]))
:render-fn list-item}]])
[select-account]]))

View File

@ -5,11 +5,11 @@
[status-im.i18n :as i18n]
[status-im.ui.components.animation :as anim]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.components.react :as react]
[status-im.ui.screens.browser.styles :as styles]
[status-im.ui.components.colors :as colors])
[status-im.ui.components.colors :as colors]
[status-im.ui.components.button :as button])
(:require-macros [status-im.utils.views :as views]))
(defn hide-panel-anim
@ -26,7 +26,7 @@
[bottom-anim-value alpha-value]
(anim/start
(anim/parallel
[(anim/spring bottom-anim-value {:toValue 20
[(anim/spring bottom-anim-value {:toValue 20
:useNativeDriver true})
(anim/timing alpha-value {:toValue 0.6
:duration 500
@ -35,7 +35,7 @@
(defn permission-details [requested-permission]
(get browser.permissions/supported-permissions requested-permission))
(views/defview permissions-panel [[dapp? dapp] {:keys [dapp-name]}]
(views/defview permissions-panel [[dapp? dapp dapps-account] {:keys [dapp-name]}]
(views/letsubs [bottom-anim-value (anim/create-value styles/panel-height)
alpha-value (anim/create-value 0)
current-permission (reagent/atom nil)
@ -76,37 +76,54 @@
(do (js/setTimeout #(reset! current-permission nil) 500)
(hide-panel-anim bottom-anim-value alpha-value))))}
(when @current-permission
(let [{:keys [title description icon]} @current-permission]
(let [{:keys [title description type icon]} @current-permission]
[react/view styles/permissions-panel-container
[react/animated-view {:style (styles/permissions-panel-background alpha-value)}]
[react/animated-view {:style (styles/permissions-panel bottom-anim-value)}
[react/view styles/permissions-panel-icons-container
(if dapp?
[chat-icon.screen/dapp-icon-permission dapp 48]
[chat-icon.screen/dapp-icon-permission dapp 40]
[react/view styles/permissions-panel-dapp-icon-container
[icons/icon :main-icons/dapp {:color colors/gray}]])
[react/view {:margin-left 3 :margin-right 3}
[react/view {:margin-left 8 :margin-right 4}
[react/view styles/dot]]
[react/view {:margin-right 3}
[react/view {:margin-right 4}
[react/view styles/dot]]
[react/view {:margin-right 8}
[react/view styles/dot]]
[react/view styles/permissions-panel-ok-icon-container
[icons/icon :main-icons/check styles/permissions-panel-ok-ico]]
[react/view {:margin-left 3 :margin-right 3}
[icons/icon :tiny-icons/tiny-check styles/permissions-panel-ok-ico]]
[react/view {:margin-left 8 :margin-right 4}
[react/view styles/dot]]
[react/view {:margin-right 3}
[react/view {:margin-right 4}
[react/view styles/dot]]
[react/view styles/permissions-panel-wallet-icon-container
(when icon
[icons/icon icon {:color :white}])]]
[react/view {:margin-right 8}
[react/view styles/dot]]
(if (= :wallet type)
[chat-icon.screen/custom-icon-view-list (:name dapps-account) (:color dapps-account)]
[react/view styles/permissions-panel-wallet-icon-container
(when icon
[icons/icon icon {:color :white}])])]
[react/text {:style styles/permissions-panel-title-label}
(str "\"" dapp-name "\" " title)]
(when (= :wallet type)
[react/view styles/permissions-account
[icons/icon :main-icons/account {:color (:color dapps-account)}]
[react/view {:flex-shrink 1}
[react/text {:numberOfLines 1
:style {:margin-horizontal 6 :color (:color dapps-account) :typography :main-medium
:font-size 13}}
(:name dapps-account)]]])
[react/text {:style styles/permissions-panel-description-label}
description]
[react/view {:flex-direction :row :margin-top 14}
[components.common/button
{:on-press #(re-frame/dispatch [:browser.permissions.ui/dapp-permission-denied])
[react/view {:flex-direction :row :margin-top 24}
[button/button
{:theme :red
:style {:flex 1}
:on-press #(re-frame/dispatch [:browser.permissions.ui/dapp-permission-denied])
:label (i18n/label :t/deny)}]
[react/view {:width 16}]
[components.common/button
{:on-press #(re-frame/dispatch [:browser.permissions.ui/dapp-permission-allowed])
[button/button
{:theme :green
:style {:flex 1}
:on-press #(re-frame/dispatch [:browser.permissions.ui/dapp-permission-allowed])
:label (i18n/label :t/allow)}]]]]))))

View File

@ -20,10 +20,12 @@
(def navbar
{:background-color :white
:height 48
:height 51
:flex-direction :row
:align-items :center
:justify-content :space-between
:border-top-color colors/gray-lighter
:border-top-width 1
:padding-horizontal 32})
(def disabled-button
@ -56,8 +58,8 @@
:border-radius 8
:max-height 36
:background-color colors/gray-lighter
:padding-horizontal 12
:margin-right 8
:padding-horizontal 10
:margin-right 16
:align-items :center
:align-self :center
:margin-top 10
@ -78,7 +80,7 @@
(def dot
{:height 4
:width 4
:background-color "#E4E6EB"
:background-color colors/blue
:border-radius 2})
(def permissions-panel-container
@ -114,42 +116,53 @@
:flex-direction :row})
(def permissions-panel-dapp-icon-container
{:height 48
:width 48
:background-color "#E4E6EB"
:border-radius 24
{:height 40
:width 40
:background-color colors/gray-lighter
:border-radius 20
:align-items :center
:justify-content :center})
(def permissions-panel-ok-icon-container
{:height 24
:width 24
:background-color "#48EA77"
:background-color colors/blue-light
:border-radius 12
:align-items :center
:justify-content :center})
(def permissions-panel-ok-ico
{:color :white
:width 12
:height 12})
{:color colors/blue
:width 16
:height 16})
(def permissions-panel-wallet-icon-container
{:height 48
:width 48
{:height 40
:width 40
:background-color colors/blue
:border-radius 24
:border-radius 20
:align-items :center
:justify-content :center})
(def permissions-panel-title-label
{:typography :header
{:typography :title-bold
:margin-horizontal 20
:text-align :center
:margin-top 19})
:margin-top 16})
(def permissions-panel-description-label
{:margin-horizontal 20
:color colors/gray
:text-align :center
:margin-top 9})
:margin-top 16})
(def permissions-account
{:flex-direction :row
:border-radius 36
:border-width 1
:border-color colors/gray-lighter
:padding-horizontal 8
:padding-vertical 6
:margin-top 16
:align-items :center
:justify-content :center})

View File

@ -19,7 +19,9 @@
[status-im.ui.screens.browser.site-blocked.views :as site-blocked.views]
[status-im.ui.screens.browser.styles :as styles]
[status-im.utils.http :as http]
[status-im.utils.js-resources :as js-res])
[status-im.utils.js-resources :as js-res]
[status-im.ui.components.chat-icon.screen :as chat-icon]
[status-im.ui.screens.browser.accounts :as accounts])
(:require-macros
[status-im.utils.slurp :refer [slurp]]
[status-im.utils.views :as views]))
@ -38,7 +40,7 @@
(fn []
(edn/read-string (browser-config-edn)))))
(defn toolbar-content [url url-original {:keys [secure?]} url-editing?]
(defn toolbar-content [url url-original {:keys [secure?]} url-editing? webview]
(let [url-text (atom url)]
[react/view styles/toolbar-content
[react/touchable-highlight {:on-press #(re-frame/dispatch [:browser.ui/lock-pressed secure?])}
@ -58,9 +60,12 @@
:style styles/url-input}]
[react/touchable-highlight {:style styles/url-text-container
:on-press #(re-frame/dispatch [:browser.ui/url-input-pressed])}
[react/text (http/url-host url-original)]])]))
[react/text (http/url-host url-original)]])
[react/touchable-highlight {:on-press #(.reload @webview)
:accessibility-label :refresh-page-button}
[icons/icon :main-icons/refresh]]]))
(defn toolbar [error? url url-original browser browser-id url-editing?]
(defn toolbar [error? url url-original browser browser-id url-editing? webview]
[toolbar.view/toolbar
{:browser? true}
[toolbar.view/nav-button
@ -69,7 +74,7 @@
(re-frame/dispatch [:navigate-back])
(when error?
(re-frame/dispatch [:browser.ui/remove-browser-pressed browser-id]))))]
[toolbar-content url url-original browser url-editing?]])
[toolbar-content url url-original browser url-editing? webview]])
(defn- web-view-error [_ code desc]
(reagent/as-element
@ -85,38 +90,43 @@
(let [domain-name (nth (re-find #"^\w+://(www\.)?([^/:]+)" url) 2)]
(get (:inject-js (browser-config)) domain-name))))
(defn navigation [browser-id url webview can-go-back? can-go-forward?]
[react/view styles/navbar
[react/touchable-highlight {:on-press #(re-frame/dispatch [:browser.ui/previous-page-button-pressed])
:disabled (not can-go-back?)
:style (when-not can-go-back? styles/disabled-button)
:accessibility-label :previous-page-button}
[react/view
[icons/icon :main-icons/arrow-left]]]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:browser.ui/next-page-button-pressed])
:disabled (not can-go-forward?)
:style (when-not can-go-forward? styles/disabled-button)
:accessibility-label :next-page-button}
[react/view
[icons/icon :main-icons/arrow-right]]]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:browser.ui/open-modal-chat-button-pressed (http/url-host url)])
:accessibility-label :modal-chat-button}
[icons/icon :main-icons/message]]
[react/touchable-highlight
{:on-press #(browser/share-link url)
:accessibility-label :modal-share-link-button}
[icons/icon :main-icons/share]]
[react/touchable-highlight {:on-press #(.reload @webview)
:accessibility-label :refresh-page-button}
[icons/icon :main-icons/refresh]]])
(views/defview navigation [url can-go-back? can-go-forward? dapps-account]
(views/letsubs [height [:dimensions/window-height]
{:keys [accounts]} [:multiaccount]]
[react/view styles/navbar
[react/touchable-highlight {:on-press #(re-frame/dispatch [:browser.ui/previous-page-button-pressed])
:disabled (not can-go-back?)
:style (when-not can-go-back? styles/disabled-button)
:accessibility-label :previous-page-button}
[react/view
[icons/icon :main-icons/arrow-left]]]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:browser.ui/next-page-button-pressed])
:disabled (not can-go-forward?)
:style (when-not can-go-forward? styles/disabled-button)
:accessibility-label :next-page-button}
[react/view
[icons/icon :main-icons/arrow-right]]]
[react/touchable-highlight
{:on-press #(browser/share-link url)
:accessibility-label :modal-share-link-button}
[icons/icon :main-icons/share]]
[react/touchable-highlight
{:accessibility-label :select-account
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet
{:content (accounts/accounts-list accounts dapps-account)
:content-height (/ height 2)}])}
[chat-icon/custom-icon-view-list (:name dapps-account) (:color dapps-account) 32]]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:browser.ui/open-modal-chat-button-pressed (http/url-host url)])
:accessibility-label :modal-chat-button}
[icons/icon :main-icons/message]]]))
;; should-component-update is called only when component's props are changed,
;; that's why it can't be used in `browser`, because `url` comes from subs
(views/defview browser-component
[{:keys [webview error? url browser browser-id unsafe? can-go-back?
can-go-forward? resolving? network-id address url-original
show-permission show-tooltip opt-in? dapp? name]}]
can-go-forward? resolving? network-id url-original
show-permission show-tooltip opt-in? dapp? name dapps-account]}]
{:should-component-update (fn [_ _ args]
(let [[_ props] args]
(not (nil? (:url props)))))}
@ -144,11 +154,11 @@
:injected-on-start-loading-java-script (str (when-not opt-in? (js-res/web3))
(if opt-in?
(js-res/web3-opt-in-init (str network-id))
(js-res/web3-init address (str network-id)))
(js-res/web3-init (:address dapps-account) (str network-id)))
(get-inject-js url))
:injected-java-script (js-res/webview-js)}])]
[navigation browser-id url-original webview can-go-back? can-go-forward?]
[permissions.views/permissions-panel [(:dapp? browser) (:dapp browser)] show-permission]
[navigation url-original can-go-back? can-go-forward? dapps-account]
[permissions.views/permissions-panel [(:dapp? browser) (:dapp browser) dapps-account] show-permission]
(when show-tooltip
[tooltip/bottom-tooltip-info
(if (= show-tooltip :secure)
@ -159,9 +169,10 @@
(views/defview browser []
(views/letsubs [webview (atom nil)
window-width [:dimensions/window-width]
{:keys [accounts settings]} [:multiaccount]
{:keys [settings]} [:multiaccount]
{:keys [browser-id dapp? name unsafe?] :as browser} [:get-current-browser]
{:keys [url error? loading? url-editing? show-tooltip show-permission resolving?]} [:browser/options]
dapps-account [:dapps-account]
network-id [:chain-id]]
(let [can-go-back? (browser/can-go-back? browser)
can-go-forward? (browser/can-go-forward? browser)
@ -169,7 +180,7 @@
opt-in? (or (nil? (:web3-opt-in? settings)) (:web3-opt-in? settings))]
[react/view {:style styles/browser}
[status-bar/status-bar]
[toolbar error? url url-original browser browser-id url-editing?]
[toolbar error? url url-original browser browser-id url-editing? webview]
[react/view
(when loading?
[connectivity/loading-indicator window-width])]
@ -185,8 +196,8 @@
:can-go-forward? can-go-forward?
:resolving? resolving?
:network-id network-id
:address (:address (ethereum/get-default-account accounts))
:show-permission show-permission
:show-tooltip show-tooltip
:opt-in? opt-in?
:name name}]])))
:name name
:dapps-account dapps-account}]])))

View File

@ -22,12 +22,13 @@
:on-press #(re-frame/dispatch [:navigate-to :manage-dapps-permissions {:dapp dapp :permissions permissions}])
:icon d-icon})
(defn prepare-items-manage [permission]
{:title (case permission
constants/dapp-permission-web3 :t/wallet
constants/dapp-permission-contact-code :t/contact-code)
:type :small
:accessories [:main-icons/check]})
(defn prepare-items-manage [name]
(fn [permission]
{:title (case permission
constants/dapp-permission-web3 name
constants/dapp-permission-contact-code :t/contact-code)
:type :small
:accessories [:main-icons/check]}))
(views/defview dapps-permissions []
(views/letsubs [permissions [:dapps/permissions]]
@ -41,12 +42,13 @@
:render-fn list/flat-list-generic-render-fn}]]))
(views/defview manage []
(views/letsubs [{:keys [dapp permissions]} [:get-screen-params]]
(views/letsubs [{:keys [dapp permissions]} [:get-screen-params]
{:keys [name]} [:dapps-account]]
[react/view {:flex 1 :background-color colors/white}
[status-bar/status-bar]
[toolbar/simple-toolbar dapp]
[list/flat-list
{:data (vec (map prepare-items-manage permissions))
{:data (vec (map (prepare-items-manage name) permissions))
:key-fn (fn [_ i] (str i))
:render-fn list/flat-list-generic-render-fn}]
[react/view {:padding-vertical 16}

View File

@ -95,7 +95,7 @@
[list/flat-list {:data all-home-items
:key-fn first
:header [react/view {:height 4 :flex 1}]
:footer [react/view {:height 4 :flex 1}]
:footer [react/view {:height 68 :flex 1}]
:on-scroll-begin-drag
(fn [e]
(reset! scrolling-from-top?

View File

@ -2,7 +2,9 @@
(:require [status-im.i18n :as i18n]
[status-im.react-native.js-dependencies :as rn-dependencies]
[re-frame.core :as re-frame]
[status-im.utils.platform :as platform]))
[status-im.utils.platform :as platform]
[status-im.ethereum.eip55 :as eip55]
[status-im.ethereum.core :as ethereum]))
(defn show-popup
([title content]
@ -79,6 +81,10 @@
(when address
(str (subs address 0 6) "\u2026" (subs address (- (count address) 4) (count address)))))
(defn get-shortened-checksum-address [address]
(when address
(get-shortened-address (eip55/address->checksum (ethereum/normalized-address address)))))
;; background-timer
(defn set-timeout [cb ms]

View File

@ -268,7 +268,7 @@
"custom": "Custom",
"custom-networks": "Custom networks",
"dapp": "ÐApp",
"dapp-would-like-to-connect-wallet": "would like\n to connect to your wallet",
"dapp-would-like-to-connect-wallet": "would like to connect to",
"dapps": "ÐApps",
"dapps-can-access": "ÐApps can access my wallet and chat key",
"dapps-permissions": "DApp permissions",
@ -1107,5 +1107,6 @@
"ok-save-pass": "OK, save password",
"lock-app-with": "Lock app with",
"grant-face-id-permissions": "To grant the required Face ID permission, please go to your system settings and make sure that Status > Face ID is selected",
"request-feature": "Request a feature"
"request-feature": "Request a feature",
"select-account-dapp": "Select the account you wish to use with Dapps"
}