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]]
|
[:blur? {:optional true} [:maybe :boolean]]
|
||||||
[:collectible-img-src :schema.common/image-source]
|
[:collectible-img-src :schema.common/image-source]
|
||||||
[:collectible-name :string]
|
[:collectible-name :string]
|
||||||
[:collectible-id :string]]]]
|
[:collectible-id {:optional true} [:maybe :string]]]]]
|
||||||
:any])
|
:any])
|
||||||
|
|
|
@ -41,12 +41,13 @@
|
||||||
:weight :medium
|
:weight :medium
|
||||||
:style (style/label theme)}
|
:style (style/label theme)}
|
||||||
collectible-name]
|
collectible-name]
|
||||||
[text/text
|
(when collectible-id
|
||||||
{:size :paragraph-2
|
[text/text
|
||||||
:weight :medium
|
{:size :paragraph-2
|
||||||
:margin-left 5
|
:weight :medium
|
||||||
:style (style/label theme)}
|
:margin-left 5
|
||||||
collectible-id]]]
|
:style (style/label theme)}
|
||||||
|
collectible-id])]]
|
||||||
(when options
|
(when options
|
||||||
[rn/view {:style (style/options-icon size)}
|
[rn/view {:style (style/options-icon size)}
|
||||||
[icons/icon (if (= options :hold) :i/hold :i/add-token)
|
[icons/icon (if (= options :hold) :i/hold :i/add-token)
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
quo.components.community.channel-action.view
|
quo.components.community.channel-action.view
|
||||||
quo.components.community.channel-actions.view
|
quo.components.community.channel-actions.view
|
||||||
quo.components.community.community-card-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-list-view
|
||||||
quo.components.community.community-stat.view
|
quo.components.community.community-stat.view
|
||||||
quo.components.community.community-view
|
quo.components.community.community-view
|
||||||
|
@ -224,6 +225,7 @@
|
||||||
|
|
||||||
;;;; Community
|
;;;; Community
|
||||||
(def community-card-view-item quo.components.community.community-card-view/view)
|
(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
|
(def communities-membership-list-item
|
||||||
quo.components.community.community-list-view/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)
|
(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.component-spec
|
||||||
quo.components.calendar.calendar.month-picker.component-spec
|
quo.components.calendar.calendar.month-picker.component-spec
|
||||||
quo.components.colors.color-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.community.community-stat.component-spec
|
||||||
quo.components.counter.collectible-counter.component-spec
|
quo.components.counter.collectible-counter.component-spec
|
||||||
quo.components.counter.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
|
(ns status-im.contexts.communities.actions.permissions-sheet.view
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[react-native.core :as rn]
|
|
||||||
[react-native.gesture :as gesture]
|
[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]))
|
[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
|
(defn view
|
||||||
[id]
|
[id]
|
||||||
(let [permissions (rf/sub [:community/token-permissions id])]
|
(let [permissions (rf/sub [:community/token-permissions id])]
|
||||||
[gesture/scroll-view {:style style/container}
|
[gesture/scroll-view
|
||||||
(map permission-view permissions)]))
|
[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]
|
channel-actions]
|
||||||
[status-im.contexts.preview.quo.community.community-card-view :as
|
[status-im.contexts.preview.quo.community.community-card-view :as
|
||||||
community-card]
|
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
|
[status-im.contexts.preview.quo.community.community-membership-list-view
|
||||||
:as community-membership-list-view]
|
:as community-membership-list-view]
|
||||||
[status-im.contexts.preview.quo.community.community-stat :as community-stat]
|
[status-im.contexts.preview.quo.community.community-stat :as community-stat]
|
||||||
|
@ -260,6 +262,8 @@
|
||||||
:component color/view}]
|
:component color/view}]
|
||||||
:community [{:name :community-card-view
|
:community [{:name :community-card-view
|
||||||
:component community-card/view}
|
:component community-card/view}
|
||||||
|
{:name :community-detail-token-gating
|
||||||
|
:component community-detail-token-gating/view}
|
||||||
{:name :community-membership-list-view
|
{:name :community-membership-list-view
|
||||||
:component community-membership-list-view/view}
|
:component community-membership-list-view/view}
|
||||||
{:name :community-stat
|
{:name :community-stat
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
[legacy.status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils]
|
[legacy.status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
|
[status-im.contexts.communities.utils :as utils]
|
||||||
[status-im.subs.chat.utils :as subs.utils]
|
[status-im.subs.chat.utils :as subs.utils]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.money :as money]))
|
[utils.money :as money]))
|
||||||
|
@ -325,11 +326,12 @@
|
||||||
(let [sym (:symbol criteria)
|
(let [sym (:symbol criteria)
|
||||||
amount-in-wei (:amountInWei criteria)
|
amount-in-wei (:amountInWei criteria)
|
||||||
decimals (:decimals criteria)]
|
decimals (:decimals criteria)]
|
||||||
{:symbol sym
|
{:symbol sym
|
||||||
:sufficient? satisfied
|
:sufficient? satisfied
|
||||||
:loading? checking-permissions?
|
:collectible? (= (:type criteria) constants/community-token-type-erc721)
|
||||||
:amount (money/to-fixed (money/token->unit amount-in-wei decimals))
|
:loading? checking-permissions?
|
||||||
:img-src (get token-images sym)}))
|
:amount (money/to-fixed (money/token->unit amount-in-wei decimals))
|
||||||
|
:img-src (get token-images sym)}))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:communities/checking-permissions-by-id
|
:communities/checking-permissions-by-id
|
||||||
|
@ -407,6 +409,7 @@
|
||||||
roles)]
|
roles)]
|
||||||
(mapv (fn [role]
|
(mapv (fn [role]
|
||||||
{:role (:type role)
|
{:role (:type role)
|
||||||
|
:role-text (i18n/label (utils/role->translation-key (:type role)))
|
||||||
:satisfied? (:satisfied role)
|
:satisfied? (:satisfied role)
|
||||||
:tokens (map (fn [{:keys [tokenRequirement]}]
|
:tokens (map (fn [{:keys [tokenRequirement]}]
|
||||||
(map
|
(map
|
||||||
|
|
|
@ -321,15 +321,17 @@
|
||||||
(swap! rf-db/app-db assoc-in [:communities/permissions-check community-id] checks)
|
(swap! rf-db/app-db assoc-in [:communities/permissions-check community-id] checks)
|
||||||
(is (match? {:can-request-access? true
|
(is (match? {:can-request-access? true
|
||||||
:networks-not-supported? nil
|
:networks-not-supported? nil
|
||||||
:tokens [[{:symbol "DAI"
|
:tokens [[{:symbol "DAI"
|
||||||
:amount "5"
|
:amount "5"
|
||||||
:sufficient? true
|
:collectible? false
|
||||||
:loading? checking-permissions?}]
|
:sufficient? true
|
||||||
[{:symbol "ETH"
|
:loading? checking-permissions?}]
|
||||||
:amount "0.002"
|
[{:symbol "ETH"
|
||||||
:sufficient? false
|
:amount "0.002"
|
||||||
:loading? checking-permissions?
|
:collectible? false
|
||||||
:img-src token-image-eth}]]}
|
:sufficient? false
|
||||||
|
:loading? checking-permissions?
|
||||||
|
:img-src token-image-eth}]]}
|
||||||
(rf/sub [sub-name community-id])))))
|
(rf/sub [sub-name community-id])))))
|
||||||
|
|
||||||
(h/deftest-sub :communities/community-color
|
(h/deftest-sub :communities/community-color
|
||||||
|
@ -417,18 +419,20 @@
|
||||||
(match? [{:role 1
|
(match? [{:role 1
|
||||||
:satisfied? true
|
:satisfied? true
|
||||||
:tokens
|
:tokens
|
||||||
[[{:symbol "ETH"
|
[[{:symbol "ETH"
|
||||||
:sufficient? true
|
:sufficient? true
|
||||||
:loading? false
|
:loading? false
|
||||||
:amount "1"
|
:collectible? false
|
||||||
:img-src token-image-eth}]]}
|
:amount "1"
|
||||||
|
:img-src token-image-eth}]]}
|
||||||
{:role 2
|
{:role 2
|
||||||
:satisfied? false
|
:satisfied? false
|
||||||
:tokens [[{:symbol "DAI"
|
:tokens [[{:symbol "DAI"
|
||||||
:sufficient? false
|
:sufficient? false
|
||||||
:loading? false
|
:collectible? false
|
||||||
:amount "10"
|
:loading? false
|
||||||
:img-src nil}]]}]
|
:amount "10"
|
||||||
|
:img-src nil}]]}]
|
||||||
(rf/sub [sub-name community-id])))))
|
(rf/sub [sub-name community-id])))))
|
||||||
(testing
|
(testing
|
||||||
"without any visible permissions"
|
"without any visible permissions"
|
||||||
|
|
Loading…
Reference in New Issue