[#5584] Implement Manage permissions screen and option for web3 provider Opt-in access

Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
Andrey Shovkoplyas 2019-02-04 10:07:41 +01:00
parent 0ec88fdba8
commit 4c4fb6bbe9
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
19 changed files with 221 additions and 21 deletions

4
resources/icons/dapp.svg Executable file
View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M12.184 6H9.84583C9.23067 6 8.91984 6.03348 8.75135 6.06602C8.63018 6.08942 8.57605 6.11185 8.47793 6.16433C8.33758 6.23939 8.23939 6.33758 8.16433 6.47793C8.11185 6.57605 8.08942 6.63018 8.06602 6.75135C8.03348 6.91984 8 7.23067 8 7.84583V9H6V7.84583C6 6.50855 6.13924 6.02362 6.4007 5.53473C6.66216 5.04584 7.04584 4.66216 7.53473 4.4007C8.02362 4.13924 8.50855 4 9.84583 4H12.184C13.9152 4 15.2782 4.32489 16.419 4.93496C17.5597 5.54504 18.455 6.4403 19.065 7.58104C19.6751 8.72178 20 10.0848 20 11.816V12.184C20 13.9152 19.6751 15.2782 19.065 16.419C18.455 17.5597 17.5597 18.455 16.419 19.065C15.2782 19.6751 13.9152 20 12.184 20H9.84583C8.50855 20 8.02362 19.8608 7.53473 19.5993C7.04584 19.3378 6.66216 18.9542 6.4007 18.4653C6.13924 17.9764 6 17.4915 6 16.1542V15H8V16.1542C8 16.7693 8.03348 17.0802 8.06602 17.2487C8.08942 17.3698 8.11185 17.4239 8.16433 17.5221C8.23939 17.6624 8.33758 17.7606 8.47793 17.8357C8.57605 17.8882 8.63018 17.9106 8.75134 17.934C8.91984 17.9665 9.23067 18 9.84583 18H12.184C13.6558 18 14.681 17.7265 15.4758 17.3014C16.268 16.8777 16.8777 16.268 17.3014 15.4758C17.7265 14.681 18 13.6558 18 12.184V11.816C18 10.3442 17.7265 9.31902 17.3014 8.52424C16.8777 7.73203 16.268 7.12227 15.4758 6.69859C14.681 6.27354 13.6558 6 12.184 6Z" fill=""/>
<path d="M5 11C4.44772 11 4 11.4477 4 12C4 12.5523 4.44772 13 5 13H11C11.5523 13 12 12.5523 12 12C12 11.4477 11.5523 11 11 11H5Z" fill=""/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -5,7 +5,8 @@
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.fx :as fx]
[status-im.qr-scanner.core :as qr-scanner]
[status-im.extensions.registry :as extensions.registry]))
[status-im.extensions.registry :as extensions.registry]
[status-im.ui.screens.navigation :as navigation]))
(declare process-next-permission)
(declare send-response-to-bridge)
@ -77,6 +78,13 @@
{:db (assoc-in db [:dapps/permissions dapp-name] allowed-permissions)
:data-store/tx [(dapp-permissions/save-dapp-permissions allowed-permissions)]}))
(fx/defn revoke-dapp-permissions
[{:keys [db] :as cofx} dapp]
(fx/merge cofx
{:db (update-in db [:dapps/permissions] dissoc dapp)
:data-store/tx [(dapp-permissions/remove-dapp-permissions dapp)]}
(navigation/navigate-back)))
(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

@ -13,4 +13,10 @@
"Returns tx function for saving dapp permissions"
[permissions]
(fn [realm]
(core/create realm :dapp-permissions permissions true)))
(core/create realm :dapp-permissions permissions true)))
(defn remove-dapp-permissions
"Returns tx function for removing dapp permissions"
[dapp]
(fn [realm]
(core/delete realm (core/single (core/get-by-field realm :dapp-permissions :dapp dapp)))))

View File

@ -1382,6 +1382,11 @@
(fn [cofx [_ host]]
(browser/open-chat-from-browser cofx host)))
(handlers/register-handler-fx
:dapps/revoke-access
(fn [cofx [_ dapp]]
(browser.permissions/revoke-dapp-permissions cofx dapp)))
;; group-chats module
(handlers/register-handler-fx

View File

@ -95,6 +95,12 @@
:style (merge styles/button-label label-style)}
label]]])
(defn red-button [props]
[react/view {:align-items :center}
[button (merge props
{:label-style {:color colors/red :font-size 15}
:button-style {:padding-horizontal 32 :background-color colors/red-light}})]])
(defn counter
([value] (counter nil value))
([{:keys [size accessibility-label] :or {size 18}} value]

View File

@ -108,7 +108,8 @@
:icons/indicator-big (js/require "./resources/icons/indicator-big.svg")
:icons/indicator-middle (js/require "./resources/icons/indicator-middle.svg")
:icons/indicator-small (js/require "./resources/icons/indicator-small.svg")
:icons/stickers (js/require "./resources/icons/stickers.svg")}
:icons/stickers (js/require "./resources/icons/stickers.svg")
:icons/dapp (js/require "./resources/icons/dapp.svg")}
{:main-icons/add (components.svg/slurp-svg "./resources/icons/main/add.svg")
:main-icons/cancel (components.svg/slurp-svg "./resources/icons/main/cancel.svg")
:main-icons/group-chat (components.svg/slurp-svg "./resources/icons/main/group_chat.svg")
@ -195,7 +196,8 @@
:icons/indicator-small (components.svg/slurp-svg "./resources/icons/indicator-small.svg")
:icons/stickers (components.svg/slurp-svg "./resources/icons/stickers.svg")
:icons/stickers-big (components.svg/slurp-svg "./resources/icons/stickers_big.svg")
:icons/clock (components.svg/slurp-svg "./resources/icons/clock.svg")}))
:icons/clock (components.svg/slurp-svg "./resources/icons/clock.svg")
:icons/dapp (components.svg/slurp-svg "./resources/icons/dapp.svg")}))
(defn normalize-property-name [n]
(if (= n :icons/options)

View File

@ -0,0 +1,35 @@
(ns status-im.ui.components.list-item.styles
(:require [status-im.ui.components.colors :as colors]))
(defn container [small?]
{:height (if small? 52 64)
:align-items :center
:flex-direction :row
:padding-right 8
:background-color :white})
(defn title [small? subtitle]
(cond-> (if small?
{:line-height 22 :font-size 15}
{:line-height 20 :font-size 17})
subtitle
(assoc :font-weight 500 :font-size 15)))
(def subtitle
{:margin-top 4
:line-height 22
:font-size 15
:color colors/gray})
(def accessory-text
{:line-height 22
:font-size 15
:color colors/gray
:margin-right 8})
(defn radius [size] (/ size 2))
(defn photo [size]
{:border-radius (radius size)
:width size
:height size})

View File

@ -0,0 +1,46 @@
(ns status-im.ui.components.list-item.views
(:require [status-im.ui.components.colors :as colors]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.components.react :as react]
[status-im.ui.components.list-item.styles :as styles]
[status-im.utils.image :as utils.image]))
; type - optional :default , :small
; accessories - optional vector of :chevron, :check or component or string
; theme - optional :default, :wallet
(defn list-item [{:keys [title subtitle accessories image image-path type theme on-press] :or {type :default theme :default}}]
(let [small? (= :small type)]
[react/touchable-highlight {:on-press on-press :disabled (not on-press)}
[react/view {:style (styles/container small?)}
;;Image
(when image
[react/view {:margin-left 16}
[image]])
(when image-path
[react/view {:margin-left 16}
[react/image {:source (utils.image/source image-path)
:style (styles/photo 40)}]])
;;Title
[react/view {:style {:margin-left 16 :flex 1}}
[react/text {:style (styles/title small? subtitle)}
title]
;;Subtitle
(when subtitle
[react/text {:style styles/subtitle}
subtitle])]
;;Accessories
(for [accessory accessories]
(with-meta
(cond
(string? accessory)
[react/text {:style styles/accessory-text}
accessory]
(= :chevron accessory)
[icons/icon :icons/forward {:color colors/gray-transparent-40}]
(= :check accessory)
[icons/icon :icons/ok {:color colors/gray}]
:else accessory)
{:key accessory}))]]))

View File

@ -36,6 +36,7 @@
{:color colors/black
:letter-spacing -0.2
:font-size 17
:font-weight :bold
:ios {:text-align :center
:margin-left 15
:margin-right 15}

View File

@ -8,7 +8,8 @@
[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.screens.browser.styles :as styles]
[status-im.ui.components.colors :as colors])
(:require-macros [status-im.utils.views :as views]))
(defn hide-panel-anim
@ -79,7 +80,7 @@
(if dapp?
[chat-icon.screen/dapp-icon-permission dapp 48]
[react/view styles/permissions-panel-dapp-icon-container
[react/text {:style styles/permissions-panel-d-label} "Ð"]])
[icons/icon :icons/dapp {:color colors/gray}]])
[react/view {:margin-left 3 :margin-right 3}
[react/view styles/dot]]
[react/view {:margin-right 3}

View File

@ -4,20 +4,12 @@
[status-im.ui.screens.chat.styles.photos :as style]
[status-im.utils.identicon :as identicon]
[clojure.string :as string]
[status-im.react-native.resources :as resources]))
(defn- source [photo-path]
(if (and (not (string/blank? photo-path))
(string/starts-with? photo-path "contacts://"))
(->> (string/replace photo-path #"contacts://" "")
(keyword)
(get resources/contacts))
{:uri photo-path}))
[status-im.utils.image :as utils.image]))
(defn photo [photo-path {:keys [size
accessibility-label]}]
[react/view {:style (style/photo-container size)}
[react/image {:source (source photo-path)
[react/image {:source (utils.image/source photo-path)
:style (style/photo size)
:accessibility-label (or accessibility-label :chat-icon)}]
[react/view {:style (style/photo-border size)}]])

View File

@ -0,0 +1,10 @@
(ns status-im.ui.screens.dapps-permissions.styles
(:require [status-im.ui.components.colors :as colors]))
(def icon-container
{:width 40
:height 40
:border-radius 20
:background-color colors/gray-lighter
:align-items :center
:justify-content :center})

View File

@ -0,0 +1,61 @@
(ns status-im.ui.screens.dapps-permissions.views
(:require-macros [status-im.utils.views :as views])
(:require [re-frame.core :as re-frame]
[status-im.i18n :as i18n]
[status-im.ui.components.react :as react]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.list-item.views :as list-item]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.colors :as colors]
[status-im.ui.screens.dapps-permissions.styles :as styles]
[status-im.constants :as constants]
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.icons.vector-icons :as icons]))
(defn d-icon []
[react/view styles/icon-container
[icons/icon :icons/dapp {:color colors/gray}]])
(defn prepare-items [dapps]
(fn [{:keys [dapp permissions]}]
(merge
{:title dapp
:accessories [:chevron]
:on-press #(re-frame/dispatch [:navigate-to :manage-dapps-permissions {:dapp dapp :permissions permissions}])}
(let [path (get-in dapps [dapp :photo-path])]
(if path
{:image-path path}
{:image d-icon})))))
(defn prepare-items-manage [permission]
{:title (case permission
constants/dapp-permission-web3 (i18n/label :t/wallet)
constants/dapp-permission-contact-code (i18n/label :t/contact-code))
:type :small
:accessories [:check]})
(views/defview dapps-permissions []
(views/letsubs [permissions [:get :dapps/permissions]
dapps [:contacts/dapps-by-name]]
[react/view {:flex 1 :background-color colors/white}
[status-bar/status-bar]
[toolbar/simple-toolbar
(i18n/label :t/dapps-permissions)]
[list/flat-list
{:data (map (prepare-items dapps) (vals permissions))
:key-fn (fn [_ i] (str i))
:render-fn list-item/list-item}]]))
(views/defview manage []
(views/letsubs [{:keys [dapp permissions]} [:get-screen-params]]
[react/view {:flex 1 :background-color colors/white}
[status-bar/status-bar]
[toolbar/simple-toolbar dapp]
[list/flat-list
{:data (map prepare-items-manage permissions)
:key-fn (fn [_ i] (str i))
:render-fn list-item/list-item}]
[react/view {:padding-vertical 16}
[components.common/red-button {:label (i18n/label :t/revoke-access)
:on-press #(re-frame/dispatch [:dapps/revoke-access dapp])}]]]))

View File

@ -138,6 +138,7 @@
(spec/def :navigation.screen-params/show-extension map?)
(spec/def :navigation.screen-params/selection-modal-screen map?)
(spec/def :navigation.screen-params/manage-dapps-permissions map?)
(spec/def :navigation/screen-params (spec/nilable (spec/keys :opt-un [:navigation.screen-params/network-details
:navigation.screen-params/browser
@ -148,7 +149,8 @@
:navigation.screen-params/dapp-description
:navigation.screen-params/collectibles-list
:navigation.screen-params/show-extension
:navigation.screen-params/selection-modal-screen])))
:navigation.screen-params/selection-modal-screen
:navigation.screen-params/manage-dapps-permissions])))
(spec/def :desktop/desktop (spec/nilable any?))
(spec/def ::tooltips (spec/nilable any?))

View File

@ -140,6 +140,11 @@
:value (or (nil? (:web3-opt-in? settings)) (:web3-opt-in? settings))
:action-fn #(re-frame/dispatch [:accounts.ui/web3-opt-in-mode-switched %])}]
[profile.components/settings-item-separator]
[profile.components/settings-item
{:label-kw :t/dapps-permissions
:accessibility-label :dapps-permissions-button
:action-fn #(re-frame/dispatch [:navigate-to :dapps-permissions])}]
[profile.components/settings-item-separator]
[profile.components/settings-item
{:label-kw :t/need-help
:accessibility-label :help-button

View File

@ -67,6 +67,7 @@
[status-im.ui.screens.profile.seed.views :refer [backup-seed]]
[status-im.ui.screens.about-app.views :as about-app]
[status-im.ui.screens.stickers.views :as stickers]
[status-im.ui.screens.dapps-permissions.views :as dapps-permissions]
[status-im.utils.navigation :as navigation]
[reagent.core :as reagent]
[cljs-react-navigation.reagent :as nav-reagent]
@ -329,6 +330,8 @@
:offline-messaging-settings offline-messaging-settings
:edit-mailserver edit-mailserver
:help-center help-center
:dapps-permissions dapps-permissions/dapps-permissions
:manage-dapps-permissions dapps-permissions/manage
:extensions-settings extensions-settings
:edit-extension edit-extension
:show-extension show-extension

View File

@ -0,0 +1,11 @@
(ns status-im.utils.image
(:require [clojure.string :as string]
[status-im.react-native.resources :as resources]))
(defn source [photo-path]
(if (and (not (string/blank? photo-path))
(string/starts-with? photo-path "contacts://"))
(->> (string/replace photo-path #"contacts://" "")
(keyword)
(get resources/contacts))
{:uri photo-path}))

View File

@ -1,13 +1,13 @@
(ns status-im.test.chat.views.photos
(:require [cljs.test :refer [deftest testing is]]
[status-im.react-native.resources :as resources]
[status-im.ui.screens.chat.photos :as photos]))
[status-im.utils.image :as utils.image]))
(deftest photos-test
(testing "a normal string"
(let [actual (photos/source "some-string")]
(let [actual (utils.image/source "some-string")]
(is (= {:uri "some-string"} actual))))
(testing "a contact string"
(with-redefs [resources/contacts {:test "something"}]
(let [actual (photos/source "contacts://test")]
(let [actual (utils.image/source "contacts://test")]
(is (= "something" actual))))))

View File

@ -917,5 +917,7 @@
"mailserver-retry": "Retry",
"mailserver-pick-another": "Pick another mailserver",
"mailserver-error-title": "Error connecting to mailserver",
"mailserver-error-content": "The mailserver you selected couldn't be reached."
"mailserver-error-content": "The mailserver you selected couldn't be reached.",
"dapps-permissions": "Dapps permissions",
"revoke-access": "Revoke access"
}