Community detail token gating component (#19532)
This commit is contained in:
parent
f3aeddb53a
commit
98762c74f1
|
@ -0,0 +1,71 @@
|
|||
(ns quo.components.community.community-detail-token-gating.component-spec
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Community Detail Token Gating Component"
|
||||
(h/test "render with member permissions"
|
||||
(h/render
|
||||
[quo/community-detail-token-gating
|
||||
{:permissions [{:role 2
|
||||
:role-text "Member"
|
||||
:satisfied? true
|
||||
:tokens [[{:symbol "ETH"
|
||||
:sufficient? true
|
||||
:collectible? false
|
||||
:amount 0.8
|
||||
:img-src nil}]
|
||||
[{:symbol "ETH"
|
||||
:sufficient? false
|
||||
:collectible? false
|
||||
:amount 1
|
||||
:img-src nil}
|
||||
{:symbol "STT"
|
||||
:sufficient? false
|
||||
:collectible? false
|
||||
:amount 10
|
||||
:img-src nil}]]}]}])
|
||||
(h/is-truthy (h/get-by-translation-text :t/you-eligible-to-join-as {:role "Member"}))
|
||||
(h/is-truthy (h/get-by-text "0.8 ETH"))
|
||||
(h/is-truthy (h/get-by-text "1 ETH"))
|
||||
(h/is-truthy (h/get-by-text "10 STT")))
|
||||
|
||||
(h/test "render with admin permissions"
|
||||
(h/render
|
||||
[quo/community-detail-token-gating
|
||||
{:permissions [{:role 1
|
||||
:role-text "Admin"
|
||||
:satisfied? true
|
||||
:tokens [[{:symbol "ETH"
|
||||
:sufficient? true
|
||||
:collectible? false
|
||||
:amount 2
|
||||
:img-src nil}]]}]}])
|
||||
(h/is-truthy (h/get-by-translation-text :t/you-eligible-to-join-as {:role "Admin"}))
|
||||
(h/is-truthy (h/get-by-text "2 ETH")))
|
||||
|
||||
(h/test "render with token master permissions"
|
||||
(h/render-with-theme-provider
|
||||
[quo/community-detail-token-gating
|
||||
{:permissions [{:role 5
|
||||
:role-text "Token Master"
|
||||
:satisfied? true
|
||||
:tokens [[{:symbol "TMANI "
|
||||
:sufficient? true
|
||||
:collectible? true
|
||||
:img-src {:uri "mock-image"}}]]}]}])
|
||||
(h/is-truthy (h/get-by-translation-text :t/you-eligible-to-join-as {:role "Token Master"}))
|
||||
(h/is-truthy (h/get-by-text "TMANI")))
|
||||
|
||||
(h/test "render with token owner permissions"
|
||||
(h/render-with-theme-provider
|
||||
[quo/community-detail-token-gating
|
||||
{:permissions [{:role 6
|
||||
:role-text "Token Owner"
|
||||
:satisfied? true
|
||||
:tokens [[{:symbol "TOANI"
|
||||
:sufficient? true
|
||||
:collectible? true
|
||||
:img-src {:uri "mock-image"}}]]}]}])
|
||||
(h/is-truthy (h/get-by-translation-text :t/you-eligible-to-join-as {:role "Token Owner"}))
|
||||
(h/is-truthy (h/get-by-text "TOANI"))))
|
|
@ -0,0 +1,20 @@
|
|||
(ns quo.components.community.community-detail-token-gating.style)
|
||||
|
||||
(def container
|
||||
{:padding-horizontal 20
|
||||
:margin-vertical -4})
|
||||
|
||||
(defn token-row
|
||||
[first?]
|
||||
{:flex-direction :row
|
||||
:margin-top (if first? 8 4)
|
||||
:row-gap 10
|
||||
:column-gap 8
|
||||
:flex-wrap :wrap
|
||||
:margin-bottom 16})
|
||||
|
||||
(def divider
|
||||
{:padding-left 0
|
||||
:height 28
|
||||
:padding-top 0
|
||||
:align-items :flex-start})
|
|
@ -0,0 +1,74 @@
|
|||
(ns quo.components.community.community-detail-token-gating.view
|
||||
(:require [clojure.string :as string]
|
||||
[quo.components.community.community-detail-token-gating.style :as style]
|
||||
[quo.components.dividers.divider-label.view :as divider-label]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.collectible-tag.view :as collectible-tag]
|
||||
[quo.components.tags.token-tag.view :as token-tag]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn- token-view
|
||||
[{:keys [collectible? img-src amount sufficient?] :as token}]
|
||||
(let [token-symbol (:symbol token)]
|
||||
(if collectible?
|
||||
[collectible-tag/view
|
||||
{:collectible-name token-symbol
|
||||
:size :size-24
|
||||
:collectible-img-src img-src
|
||||
:options (when sufficient?
|
||||
:hold)}]
|
||||
[token-tag/view
|
||||
{:token-symbol token-symbol
|
||||
:size :size-24
|
||||
:token-value amount
|
||||
:token-img-src img-src
|
||||
:options (when sufficient? :hold)}])))
|
||||
|
||||
(defn- tokens-row
|
||||
[{:keys [tokens divider? first?]}]
|
||||
[:<>
|
||||
[rn/view
|
||||
{:style (style/token-row first?)}
|
||||
(map-indexed (fn [token-index token]
|
||||
^{:key (str "token-" token-index)}
|
||||
[token-view token])
|
||||
tokens)]
|
||||
(when-not divider?
|
||||
[divider-label/view
|
||||
{:container-style style/divider}
|
||||
[text/text
|
||||
{:size :label
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}
|
||||
(string/lower-case (i18n/label :t/or))]])])
|
||||
|
||||
(defn- role-view
|
||||
[{:keys [role tokens satisfied? role-text]}]
|
||||
(when (seq tokens)
|
||||
^{:key (str "role-" role)}
|
||||
[:<>
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :medium
|
||||
:style {:margin-top 4}}
|
||||
(if satisfied?
|
||||
(i18n/label :t/you-eligible-to-join-as {:role role-text})
|
||||
(i18n/label :t/you-not-eligible-to-join-as {:role role-text}))]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style {:margin-bottom 8}}
|
||||
(i18n/label (if satisfied? :t/you-hodl :t/you-must-hold))]
|
||||
|
||||
(map-indexed (fn [index tokens-item]
|
||||
^{:key (str role "-tokens-" index)}
|
||||
[tokens-row
|
||||
{:tokens tokens-item
|
||||
:first? (zero? index)
|
||||
:divider? (= index (dec (count tokens)))}])
|
||||
tokens)]))
|
||||
|
||||
(defn view
|
||||
[{:keys [permissions]}]
|
||||
[rn/view {:style style/container}
|
||||
(map role-view permissions)])
|
|
@ -10,5 +10,5 @@
|
|||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:collectible-img-src :schema.common/image-source]
|
||||
[:collectible-name :string]
|
||||
[:collectible-id :string]]]]
|
||||
[:collectible-id {:optional true} [:maybe :string]]]]]
|
||||
:any])
|
||||
|
|
|
@ -41,12 +41,13 @@
|
|||
:weight :medium
|
||||
:style (style/label theme)}
|
||||
collectible-name]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:margin-left 5
|
||||
:style (style/label theme)}
|
||||
collectible-id]]]
|
||||
(when collectible-id
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:margin-left 5
|
||||
:style (style/label theme)}
|
||||
collectible-id])]]
|
||||
(when options
|
||||
[rn/view {:style (style/options-icon size)}
|
||||
[icons/icon (if (= options :hold) :i/hold :i/add-token)
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
quo.components.community.channel-action.view
|
||||
quo.components.community.channel-actions.view
|
||||
quo.components.community.community-card-view
|
||||
quo.components.community.community-detail-token-gating.view
|
||||
quo.components.community.community-list-view
|
||||
quo.components.community.community-stat.view
|
||||
quo.components.community.community-view
|
||||
|
@ -224,6 +225,7 @@
|
|||
|
||||
;;;; Community
|
||||
(def community-card-view-item quo.components.community.community-card-view/view)
|
||||
(def community-detail-token-gating quo.components.community.community-detail-token-gating.view/view)
|
||||
(def communities-membership-list-item
|
||||
quo.components.community.community-list-view/communities-membership-list-item)
|
||||
(def community-stats-column quo.components.community.community-view/community-stats-column)
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
quo.components.calendar.calendar.component-spec
|
||||
quo.components.calendar.calendar.month-picker.component-spec
|
||||
quo.components.colors.color-picker.component-spec
|
||||
quo.components.community.community-detail-token-gating.component-spec
|
||||
quo.components.community.community-stat.component-spec
|
||||
quo.components.counter.collectible-counter.component-spec
|
||||
quo.components.counter.counter.component-spec
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
(ns status-im.contexts.communities.actions.permissions-sheet.style)
|
||||
|
||||
(def container
|
||||
{:flex 1
|
||||
:padding-horizontal 20})
|
|
@ -1,38 +1,12 @@
|
|||
(ns status-im.contexts.communities.actions.permissions-sheet.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im.contexts.communities.actions.permissions-sheet.style :as style]
|
||||
[status-im.contexts.communities.utils :as communities.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- role-text
|
||||
[role]
|
||||
(i18n/label
|
||||
(communities.utils/role->translation-key role
|
||||
:t/token-master)))
|
||||
|
||||
(defn- permission-view
|
||||
[{:keys [tokens role satisfied?]}]
|
||||
(when (seq tokens)
|
||||
^{:key role}
|
||||
[rn/view {:style {:margin-bottom 20}}
|
||||
[quo/text {:weight :medium}
|
||||
(if satisfied?
|
||||
(i18n/label :t/you-eligible-to-join-as {:role (role-text role)})
|
||||
(i18n/label :t/you-not-eligible-to-join-as {:role (role-text role)}))]
|
||||
[quo/text {:size :paragraph-2 :style {:padding-bottom 8}}
|
||||
(if satisfied?
|
||||
(i18n/label :t/you-hodl)
|
||||
(i18n/label :t/you-must-hold))]
|
||||
[quo/token-requirement-list
|
||||
{:tokens tokens
|
||||
:container-style {:padding-horizontal 20}}]]))
|
||||
|
||||
(defn view
|
||||
[id]
|
||||
(let [permissions (rf/sub [:community/token-permissions id])]
|
||||
[gesture/scroll-view {:style style/container}
|
||||
(map permission-view permissions)]))
|
||||
[gesture/scroll-view
|
||||
[quo/community-detail-token-gating {:permissions permissions}]
|
||||
]))
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
(ns status-im.contexts.preview.quo.community.community-detail-token-gating
|
||||
(:require [quo.core :as quo]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.preview.quo.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
[{:key :role
|
||||
:type :select
|
||||
:options [{:key :one-role}
|
||||
{:key :two-roles}
|
||||
{:key :three-roles}
|
||||
{:key :four-roles}]}])
|
||||
|
||||
(def roles
|
||||
{:member
|
||||
{:role 2
|
||||
:role-text "Member"
|
||||
:satisfied? true
|
||||
:tokens
|
||||
[[{:symbol "ETH" :sufficient? true :collectible? false :loading? false :amount 0.8 :img-src nil}]
|
||||
[{:symbol "ETH" :sufficient? false :collectible? false :loading? false :amount 1 :img-src nil}
|
||||
{:symbol "STT" :sufficient? false :collectible? false :loading? false :amount 10 :img-src nil}]]}
|
||||
:admin
|
||||
{:role 1
|
||||
:role-text "Admin"
|
||||
:satisfied? true
|
||||
:tokens
|
||||
[[{:symbol "ETH" :sufficient? true :collectible? false :loading? false :amount 2 :img-src nil}]]}
|
||||
:token-master
|
||||
{:role 5
|
||||
:role-text "Token Master"
|
||||
:satisfied? true
|
||||
:tokens
|
||||
[[{:symbol "TMANI"
|
||||
:sufficient? true
|
||||
:collectible? true
|
||||
:loading? false
|
||||
:amount nil
|
||||
:img-src (resources/mock-images :collectible1)}]]}
|
||||
:token-owner
|
||||
{:role 6
|
||||
:role-text "Token Owner"
|
||||
:satisfied? true
|
||||
:tokens
|
||||
[[{:symbol "TOANI"
|
||||
:sufficient? true
|
||||
:collectible? true
|
||||
:loading? false
|
||||
:amount nil
|
||||
:img-src (resources/mock-images :collectible)}]]}})
|
||||
|
||||
(def permissions
|
||||
{:one-role [(:member roles)]
|
||||
:two-roles [(:admin roles) (:member roles)]
|
||||
:three-roles [(:token-master roles) (:admin roles) (:member roles)]
|
||||
:four-roles [(:token-owner roles) (:token-master roles) (:admin roles) (:member roles)]})
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom {:role :one-role})]
|
||||
(fn []
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:descriptor descriptor
|
||||
:blur? (:blur? @state)
|
||||
:show-blur-background? true}
|
||||
[quo/community-detail-token-gating {:permissions ((:role @state) permissions)}]])))
|
|
@ -39,6 +39,8 @@
|
|||
channel-actions]
|
||||
[status-im.contexts.preview.quo.community.community-card-view :as
|
||||
community-card]
|
||||
[status-im.contexts.preview.quo.community.community-detail-token-gating :as
|
||||
community-detail-token-gating]
|
||||
[status-im.contexts.preview.quo.community.community-membership-list-view
|
||||
:as community-membership-list-view]
|
||||
[status-im.contexts.preview.quo.community.community-stat :as community-stat]
|
||||
|
@ -260,6 +262,8 @@
|
|||
:component color/view}]
|
||||
:community [{:name :community-card-view
|
||||
:component community-card/view}
|
||||
{:name :community-detail-token-gating
|
||||
:component community-detail-token-gating/view}
|
||||
{:name :community-membership-list-view
|
||||
:component community-membership-list-view/view}
|
||||
{:name :community-stat
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
[legacy.status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.communities.utils :as utils]
|
||||
[status-im.subs.chat.utils :as subs.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]))
|
||||
|
@ -325,11 +326,12 @@
|
|||
(let [sym (:symbol criteria)
|
||||
amount-in-wei (:amountInWei criteria)
|
||||
decimals (:decimals criteria)]
|
||||
{:symbol sym
|
||||
:sufficient? satisfied
|
||||
:loading? checking-permissions?
|
||||
:amount (money/to-fixed (money/token->unit amount-in-wei decimals))
|
||||
:img-src (get token-images sym)}))
|
||||
{:symbol sym
|
||||
:sufficient? satisfied
|
||||
:collectible? (= (:type criteria) constants/community-token-type-erc721)
|
||||
:loading? checking-permissions?
|
||||
:amount (money/to-fixed (money/token->unit amount-in-wei decimals))
|
||||
:img-src (get token-images sym)}))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/checking-permissions-by-id
|
||||
|
@ -407,6 +409,7 @@
|
|||
roles)]
|
||||
(mapv (fn [role]
|
||||
{:role (:type role)
|
||||
:role-text (i18n/label (utils/role->translation-key (:type role)))
|
||||
:satisfied? (:satisfied role)
|
||||
:tokens (map (fn [{:keys [tokenRequirement]}]
|
||||
(map
|
||||
|
|
|
@ -321,15 +321,17 @@
|
|||
(swap! rf-db/app-db assoc-in [:communities/permissions-check community-id] checks)
|
||||
(is (match? {:can-request-access? true
|
||||
:networks-not-supported? nil
|
||||
:tokens [[{:symbol "DAI"
|
||||
:amount "5"
|
||||
:sufficient? true
|
||||
:loading? checking-permissions?}]
|
||||
[{:symbol "ETH"
|
||||
:amount "0.002"
|
||||
:sufficient? false
|
||||
:loading? checking-permissions?
|
||||
:img-src token-image-eth}]]}
|
||||
:tokens [[{:symbol "DAI"
|
||||
:amount "5"
|
||||
:collectible? false
|
||||
:sufficient? true
|
||||
:loading? checking-permissions?}]
|
||||
[{:symbol "ETH"
|
||||
:amount "0.002"
|
||||
:collectible? false
|
||||
:sufficient? false
|
||||
:loading? checking-permissions?
|
||||
:img-src token-image-eth}]]}
|
||||
(rf/sub [sub-name community-id])))))
|
||||
|
||||
(h/deftest-sub :communities/community-color
|
||||
|
@ -417,18 +419,20 @@
|
|||
(match? [{:role 1
|
||||
:satisfied? true
|
||||
:tokens
|
||||
[[{:symbol "ETH"
|
||||
:sufficient? true
|
||||
:loading? false
|
||||
:amount "1"
|
||||
:img-src token-image-eth}]]}
|
||||
[[{:symbol "ETH"
|
||||
:sufficient? true
|
||||
:loading? false
|
||||
:collectible? false
|
||||
:amount "1"
|
||||
:img-src token-image-eth}]]}
|
||||
{:role 2
|
||||
:satisfied? false
|
||||
:tokens [[{:symbol "DAI"
|
||||
:sufficient? false
|
||||
:loading? false
|
||||
:amount "10"
|
||||
:img-src nil}]]}]
|
||||
:tokens [[{:symbol "DAI"
|
||||
:sufficient? false
|
||||
:collectible? false
|
||||
:loading? false
|
||||
:amount "10"
|
||||
:img-src nil}]]}]
|
||||
(rf/sub [sub-name community-id])))))
|
||||
(testing
|
||||
"without any visible permissions"
|
||||
|
|
Loading…
Reference in New Issue