Community Token Gating Component (#19642)
This commit is contained in:
parent
deb7bfe23c
commit
d73c38a00c
|
@ -0,0 +1,61 @@
|
||||||
|
(ns quo.components.community.community-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 satisfied permissions"
|
||||||
|
(let [mock-on-press-fn (h/mock-fn)
|
||||||
|
mock-on-press-info-fn (h/mock-fn)]
|
||||||
|
(h/render
|
||||||
|
[quo/community-token-gating
|
||||||
|
{: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}]]
|
||||||
|
:community-color "#FF0000"
|
||||||
|
:role "Member"
|
||||||
|
:satisfied? true
|
||||||
|
:on-press mock-on-press-fn
|
||||||
|
:on-press-info mock-on-press-info-fn}])
|
||||||
|
(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/fire-event :press (h/get-by-translation-text :t/request-to-join))
|
||||||
|
(h/was-called mock-on-press-fn)
|
||||||
|
(h/fire-event :press (h/get-by-label-text :community-token-gating-info))
|
||||||
|
(h/was-called mock-on-press-info-fn)))
|
||||||
|
|
||||||
|
(h/test "render with unsatisfied permissions"
|
||||||
|
(let [mock-on-press-fn (h/mock-fn)
|
||||||
|
mock-on-press-info-fn (h/mock-fn)]
|
||||||
|
(h/render
|
||||||
|
[quo/community-token-gating
|
||||||
|
{:tokens [[{:symbol "ETH"
|
||||||
|
:sufficient? false
|
||||||
|
:collectible? false
|
||||||
|
:amount "0.8"
|
||||||
|
:img-src nil}]]
|
||||||
|
:community-color "#FF0000"
|
||||||
|
:role "Member"
|
||||||
|
:satisfied? false
|
||||||
|
:on-press mock-on-press-fn
|
||||||
|
:on-press-info mock-on-press-info-fn}])
|
||||||
|
(h/is-truthy (h/get-by-translation-text :t/you-not-eligible-to-join))
|
||||||
|
(h/is-truthy (h/get-by-text "0.8 ETH"))
|
||||||
|
(h/fire-event :press (h/get-by-translation-text :t/request-to-join))
|
||||||
|
(h/was-not-called mock-on-press-fn)
|
||||||
|
(h/fire-event :press (h/get-by-label-text :community-token-gating-info))
|
||||||
|
(h/was-called mock-on-press-info-fn))))
|
|
@ -0,0 +1,22 @@
|
||||||
|
(ns quo.components.community.community-token-gating.schema)
|
||||||
|
|
||||||
|
(def ^:private ?token-schema
|
||||||
|
[:map
|
||||||
|
[:symbol :string]
|
||||||
|
[:sufficient? :boolean]
|
||||||
|
[:collectible? :boolean]
|
||||||
|
[:amount {:optional true} [:maybe :string]]
|
||||||
|
[:img-src {:optional true} [:maybe :schema.common/image-source]]])
|
||||||
|
|
||||||
|
(def ?schema
|
||||||
|
[:=>
|
||||||
|
[:catn
|
||||||
|
[:props
|
||||||
|
[:map
|
||||||
|
[:tokens [:sequential [:sequential ?token-schema]]]
|
||||||
|
[:community-color [:or :string :schema.common/customization-color]]
|
||||||
|
[:role {:optional true} [:maybe :string]]
|
||||||
|
[:satisfied? :boolean]
|
||||||
|
[:on-press fn?]
|
||||||
|
[:on-press-info fn?]]]]
|
||||||
|
:any])
|
|
@ -0,0 +1,47 @@
|
||||||
|
(ns quo.components.community.community-token-gating.style
|
||||||
|
(:require [quo.foundations.colors :as colors]))
|
||||||
|
|
||||||
|
(defn container
|
||||||
|
[theme]
|
||||||
|
{:padding-bottom 12
|
||||||
|
:padding-top 10
|
||||||
|
:border-width 1
|
||||||
|
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
||||||
|
:border-radius 16
|
||||||
|
:margin-vertical -4})
|
||||||
|
|
||||||
|
(def eligibility-row
|
||||||
|
{:flex-direction :row
|
||||||
|
:padding-horizontal 12
|
||||||
|
:align-items :center})
|
||||||
|
|
||||||
|
(def divider
|
||||||
|
{:height 27
|
||||||
|
:padding-left 12
|
||||||
|
:padding-top 0
|
||||||
|
:align-items :flex-start})
|
||||||
|
|
||||||
|
(def eligibility-label
|
||||||
|
{:flex 1})
|
||||||
|
|
||||||
|
(def you-hodl
|
||||||
|
{:padding-horizontal 12
|
||||||
|
:margin-bottom 15})
|
||||||
|
|
||||||
|
(def join-button
|
||||||
|
{:padding-horizontal 12
|
||||||
|
:margin-top 8})
|
||||||
|
|
||||||
|
(def token-row
|
||||||
|
{:flex-direction :row
|
||||||
|
:padding-horizontal 12
|
||||||
|
:row-gap 10
|
||||||
|
:column-gap 8
|
||||||
|
:flex-wrap :wrap
|
||||||
|
:margin-bottom 11})
|
||||||
|
|
||||||
|
;; This wrapper prevents layout shifts caused by border effects on
|
||||||
|
;; the view's height when the token has a border.
|
||||||
|
(def token-wrapper
|
||||||
|
{:height 26
|
||||||
|
:justify-content :center})
|
|
@ -0,0 +1,89 @@
|
||||||
|
(ns quo.components.community.community-token-gating.view
|
||||||
|
(:require [clojure.string :as string]
|
||||||
|
[quo.components.buttons.button.view :as button]
|
||||||
|
[quo.components.community.community-token-gating.schema :as component-schema]
|
||||||
|
[quo.components.community.community-token-gating.style :as style]
|
||||||
|
[quo.components.dividers.divider-label.view :as divider-label]
|
||||||
|
[quo.components.icon :as icon]
|
||||||
|
[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]
|
||||||
|
[quo.theme :as theme]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[schema.core :as schema]
|
||||||
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
|
(defn- token-view
|
||||||
|
[{:keys [collectible? img-src amount sufficient?] :as token}]
|
||||||
|
(let [token-symbol (:symbol token)]
|
||||||
|
[rn/view {:style style/token-wrapper}
|
||||||
|
(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 [theme tokens divider?]}]
|
||||||
|
[:<>
|
||||||
|
[rn/view
|
||||||
|
{:style style/token-row}
|
||||||
|
(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 theme)}}
|
||||||
|
(string/lower-case (i18n/label :t/or))]])])
|
||||||
|
|
||||||
|
(defn- view-internal
|
||||||
|
[{:keys [tokens community-color role satisfied? on-press on-press-info]}]
|
||||||
|
(let [theme (theme/use-theme)
|
||||||
|
last-token-index (dec (count tokens))]
|
||||||
|
[rn/view {:style (style/container theme)}
|
||||||
|
[rn/view {:style style/eligibility-row}
|
||||||
|
[text/text
|
||||||
|
{:size :paragraph-1
|
||||||
|
:weight :medium
|
||||||
|
:style style/eligibility-label}
|
||||||
|
(if satisfied?
|
||||||
|
(i18n/label :t/you-eligible-to-join-as {:role role})
|
||||||
|
(i18n/label :t/you-not-eligible-to-join))]
|
||||||
|
[rn/pressable {:on-press on-press-info}
|
||||||
|
[icon/icon :i/info
|
||||||
|
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||||
|
:accessibility-label :community-token-gating-info}]]]
|
||||||
|
[text/text
|
||||||
|
{:size :paragraph-2
|
||||||
|
:style style/you-hodl}
|
||||||
|
(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
|
||||||
|
:theme theme
|
||||||
|
:divider? (= index last-token-index)}])
|
||||||
|
tokens)
|
||||||
|
[button/button
|
||||||
|
{:on-press on-press
|
||||||
|
:container-style style/join-button
|
||||||
|
:accessibility-label :join-community-button
|
||||||
|
:customization-color community-color
|
||||||
|
:disabled? (not satisfied?)
|
||||||
|
:icon-left (if satisfied? :i/unlocked :i/locked)}
|
||||||
|
(i18n/label :t/request-to-join)]]))
|
||||||
|
|
||||||
|
(def view (schema/instrument #'view-internal component-schema/?schema))
|
|
@ -101,39 +101,6 @@
|
||||||
:top 8
|
:top 8
|
||||||
:right 8})
|
:right 8})
|
||||||
|
|
||||||
(def token-tag-spacing
|
|
||||||
{:padding-top 10
|
|
||||||
:margin-right 8})
|
|
||||||
|
|
||||||
(defn token-row
|
|
||||||
[padding?]
|
|
||||||
(merge
|
|
||||||
{:flex-direction :row
|
|
||||||
:flex-wrap :wrap
|
|
||||||
:align-items :center}
|
|
||||||
(when padding?
|
|
||||||
{:padding-horizontal 12})))
|
|
||||||
|
|
||||||
(defn token-row-or-text
|
|
||||||
[padding? theme]
|
|
||||||
(merge
|
|
||||||
{:padding-top 4
|
|
||||||
:margin-bottom -2
|
|
||||||
:color (colors/theme-colors
|
|
||||||
colors/neutral-50
|
|
||||||
colors/neutral-40
|
|
||||||
theme)}
|
|
||||||
(when padding?
|
|
||||||
{:padding-left 12})))
|
|
||||||
|
|
||||||
(defn token-row-or-border
|
|
||||||
[theme]
|
|
||||||
{:height 1
|
|
||||||
:background-color (colors/theme-colors
|
|
||||||
colors/neutral-20
|
|
||||||
colors/neutral-80
|
|
||||||
theme)})
|
|
||||||
|
|
||||||
(defn loading-card
|
(defn loading-card
|
||||||
[width theme]
|
[width theme]
|
||||||
(merge
|
(merge
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
(ns quo.components.community.token-gating
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[quo.components.community.style :as style]
|
|
||||||
[quo.components.markdown.text :as text]
|
|
||||||
[quo.components.tags.token-tag.view :as token-tag]
|
|
||||||
[quo.theme :as quo.theme]
|
|
||||||
[react-native.core :as rn]
|
|
||||||
[utils.i18n :as i18n]))
|
|
||||||
|
|
||||||
(defn token-requirement-list-row
|
|
||||||
[tokens padding?]
|
|
||||||
[rn/view {:style (style/token-row padding?)}
|
|
||||||
(map-indexed (fn [token-index {:keys [img-src amount sufficient? purchasable?] :as token}]
|
|
||||||
^{:key token-index}
|
|
||||||
[rn/view {:style style/token-tag-spacing}
|
|
||||||
[token-tag/view
|
|
||||||
{:token-symbol (:symbol token)
|
|
||||||
:token-img-src img-src
|
|
||||||
:token-value amount
|
|
||||||
:size :size-24
|
|
||||||
:options (cond
|
|
||||||
sufficient? :hold
|
|
||||||
purchasable? :add)}]])
|
|
||||||
tokens)])
|
|
||||||
|
|
||||||
(defn token-requirement-list
|
|
||||||
[{:keys [tokens padding?]}]
|
|
||||||
(let [theme (quo.theme/use-theme)]
|
|
||||||
[:<>
|
|
||||||
(if (> (count tokens) 1)
|
|
||||||
(map-indexed
|
|
||||||
(fn [token-requirement-index tokens]
|
|
||||||
^{:key token-requirement-index}
|
|
||||||
[rn/view {:margin-bottom 12}
|
|
||||||
(when-not (= token-requirement-index 0)
|
|
||||||
[rn/view {:style (style/token-row-or-border theme)}])
|
|
||||||
(when-not (= token-requirement-index 0)
|
|
||||||
[text/text
|
|
||||||
{:style (style/token-row-or-text padding? theme)
|
|
||||||
:size :label} (string/lower-case (i18n/label :t/or))])
|
|
||||||
[token-requirement-list-row tokens padding?]])
|
|
||||||
tokens)
|
|
||||||
[token-requirement-list-row (first tokens) padding?])]))
|
|
|
@ -35,9 +35,9 @@
|
||||||
quo.components.community.community-detail-token-gating.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-token-gating.view
|
||||||
quo.components.community.community-view
|
quo.components.community.community-view
|
||||||
quo.components.community.icon
|
quo.components.community.icon
|
||||||
quo.components.community.token-gating
|
|
||||||
quo.components.counter.collectible-counter.view
|
quo.components.counter.collectible-counter.view
|
||||||
quo.components.counter.counter.view
|
quo.components.counter.counter.view
|
||||||
quo.components.counter.step.view
|
quo.components.counter.step.view
|
||||||
|
@ -227,6 +227,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 community-detail-token-gating quo.components.community.community-detail-token-gating.view/view)
|
||||||
|
(def community-token-gating quo.components.community.community-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)
|
||||||
|
@ -236,7 +237,6 @@
|
||||||
(def permission-tag-container quo.components.community.community-view/permission-tag-container)
|
(def permission-tag-container quo.components.community.community-view/permission-tag-container)
|
||||||
(def discover-card quo.components.community.banner.view/view)
|
(def discover-card quo.components.community.banner.view/view)
|
||||||
(def community-icon quo.components.community.icon/community-icon)
|
(def community-icon quo.components.community.icon/community-icon)
|
||||||
(def token-requirement-list quo.components.community.token-gating/token-requirement-list)
|
|
||||||
(def channel-action quo.components.community.channel-action.view/view)
|
(def channel-action quo.components.community.channel-action.view/view)
|
||||||
(def channel-actions quo.components.community.channel-actions.view/view)
|
(def channel-actions quo.components.community.channel-actions.view/view)
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
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-detail-token-gating.component-spec
|
||||||
quo.components.community.community-stat.component-spec
|
quo.components.community.community-stat.component-spec
|
||||||
|
quo.components.community.community-token-gating.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
|
||||||
quo.components.counter.step.component-spec
|
quo.components.counter.step.component-spec
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
[status-im.common.muting.helpers :refer [format-mute-till]]
|
[status-im.common.muting.helpers :refer [format-mute-till]]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.communities.actions.leave.view :as leave-menu]
|
[status-im.contexts.communities.actions.leave.view :as leave-menu]
|
||||||
|
[status-im.contexts.communities.actions.permissions-sheet.view :as permissions-sheet]
|
||||||
[status-im.contexts.communities.actions.see-rules.view :as see-rules]
|
[status-im.contexts.communities.actions.see-rules.view :as see-rules]
|
||||||
[status-im.contexts.communities.actions.token-gating.view :as token-gating]
|
|
||||||
[status-im.feature-flags :as ff]
|
[status-im.feature-flags :as ff]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
@ -39,8 +39,7 @@
|
||||||
:right-icon :i/chevron-right
|
:right-icon :i/chevron-right
|
||||||
:accessibility-label :view-token-gating
|
:accessibility-label :view-token-gating
|
||||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||||
{:content (fn [] [token-gating/token-requirements
|
{:content (fn [] [permissions-sheet/view id])
|
||||||
id])
|
|
||||||
:padding-bottom-override 16}])
|
:padding-bottom-override 16}])
|
||||||
:label (i18n/label :t/view-token-gating)})
|
:label (i18n/label :t/view-token-gating)})
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,4 @@
|
||||||
[id]
|
[id]
|
||||||
(let [permissions (rf/sub [:community/token-permissions id])]
|
(let [permissions (rf/sub [:community/token-permissions id])]
|
||||||
[gesture/scroll-view
|
[gesture/scroll-view
|
||||||
[quo/community-detail-token-gating {:permissions permissions}]
|
[quo/community-detail-token-gating {:permissions permissions}]]))
|
||||||
]))
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
(ns status-im.contexts.communities.actions.token-gating.view
|
|
||||||
(:require
|
|
||||||
[quo.core :as quo]
|
|
||||||
[react-native.core :as rn]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.re-frame :as rf]))
|
|
||||||
|
|
||||||
(defn token-requirements
|
|
||||||
[]
|
|
||||||
(fn [id]
|
|
||||||
(let [{:keys [can-request-access? tokens]} (rf/sub [:community/token-gated-overview id])]
|
|
||||||
[rn/view {:style {:padding-horizontal 20}}
|
|
||||||
[quo/text {:weight :medium}
|
|
||||||
(if can-request-access?
|
|
||||||
(i18n/label :t/you-eligible-to-join)
|
|
||||||
(i18n/label :t/you-not-eligible-to-join))]
|
|
||||||
[quo/text {:style {:padding-bottom 8} :size :paragraph-2}
|
|
||||||
(if can-request-access?
|
|
||||||
(i18n/label :t/you-hodl)
|
|
||||||
(i18n/label :t/you-must-hold))]
|
|
||||||
[quo/token-requirement-list {:tokens tokens}]])))
|
|
|
@ -1,6 +1,5 @@
|
||||||
(ns status-im.contexts.communities.overview.style
|
(ns status-im.contexts.communities.overview.style
|
||||||
(:require
|
(:require
|
||||||
[quo.foundations.colors :as colors]
|
|
||||||
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]))
|
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]))
|
||||||
|
|
||||||
(def screen-horizontal-padding 20)
|
(def screen-horizontal-padding 20)
|
||||||
|
@ -16,11 +15,6 @@
|
||||||
(def community-content-container
|
(def community-content-container
|
||||||
{:padding-horizontal screen-horizontal-padding})
|
{:padding-horizontal screen-horizontal-padding})
|
||||||
|
|
||||||
(def preview-user
|
|
||||||
{:flex-direction :row
|
|
||||||
:align-items :center
|
|
||||||
:margin-top 20})
|
|
||||||
|
|
||||||
(defn fetching-placeholder
|
(defn fetching-placeholder
|
||||||
[top-inset]
|
[top-inset]
|
||||||
{:flex 1
|
{:flex 1
|
||||||
|
@ -34,12 +28,6 @@
|
||||||
:left 0
|
:left 0
|
||||||
:flex 1})
|
:flex 1})
|
||||||
|
|
||||||
(def review-notice
|
|
||||||
{:color colors/neutral-50
|
|
||||||
:margin-top 12
|
|
||||||
:margin-left :auto
|
|
||||||
:margin-right :auto})
|
|
||||||
|
|
||||||
(def community-overview-container
|
(def community-overview-container
|
||||||
{:position :absolute
|
{:position :absolute
|
||||||
:top 0
|
:top 0
|
||||||
|
@ -56,11 +44,3 @@
|
||||||
{:margin-top 8
|
{:margin-top 8
|
||||||
:margin-bottom (+ 21 jump-to.constants/floating-shell-button-height)
|
:margin-bottom (+ 21 jump-to.constants/floating-shell-button-height)
|
||||||
:flex 1})
|
:flex 1})
|
||||||
|
|
||||||
(defn token-gated-container
|
|
||||||
[theme]
|
|
||||||
{:border-radius 16
|
|
||||||
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
|
||||||
:border-width 1
|
|
||||||
:padding-top 10
|
|
||||||
:margin-bottom 106})
|
|
||||||
|
|
|
@ -102,24 +102,6 @@
|
||||||
constants/community-on-request-access :request-access
|
constants/community-on-request-access :request-access
|
||||||
:unknown-access))
|
:unknown-access))
|
||||||
|
|
||||||
(defn- info-button
|
|
||||||
[]
|
|
||||||
(let [theme (quo.theme/use-theme)]
|
|
||||||
[rn/pressable
|
|
||||||
{:on-press
|
|
||||||
#(rf/dispatch
|
|
||||||
[:show-bottom-sheet
|
|
||||||
{:content
|
|
||||||
(fn []
|
|
||||||
[quo/documentation-drawers
|
|
||||||
{:title (i18n/label :t/token-gated-communities)
|
|
||||||
:show-button? true
|
|
||||||
:button-label (i18n/label :t/read-more)
|
|
||||||
:button-icon :info}
|
|
||||||
[quo/text {:size :paragraph-2} (i18n/label :t/token-gated-communities-info)]])}])}
|
|
||||||
[rn/view
|
|
||||||
[quo/icon :i/info {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}]]]))
|
|
||||||
|
|
||||||
(defn- network-not-supported
|
(defn- network-not-supported
|
||||||
[]
|
[]
|
||||||
[quo/text (i18n/label :t/network-not-supported)])
|
[quo/text (i18n/label :t/network-not-supported)])
|
||||||
|
@ -137,19 +119,39 @@
|
||||||
:icon-left :i/communities}
|
:icon-left :i/communities}
|
||||||
(i18n/label :t/request-to-join)])
|
(i18n/label :t/request-to-join)])
|
||||||
|
|
||||||
|
(defn- info-button-handler
|
||||||
|
[]
|
||||||
|
(rf/dispatch
|
||||||
|
[:show-bottom-sheet
|
||||||
|
{:content
|
||||||
|
(fn []
|
||||||
|
[quo/documentation-drawers
|
||||||
|
{:title (i18n/label :t/token-gated-communities)
|
||||||
|
:show-button? true
|
||||||
|
:button-label (i18n/label :t/read-more)
|
||||||
|
:button-icon :info}
|
||||||
|
[quo/text {:size :paragraph-2}
|
||||||
|
(i18n/label :t/token-gated-communities-info)]])}]))
|
||||||
|
|
||||||
(defn- token-requirements
|
(defn- token-requirements
|
||||||
[{:keys [id color role-permissions?]}]
|
[{:keys [id color role-permissions?]}]
|
||||||
(let [theme (quo.theme/use-theme)
|
(let [{:keys [can-request-access?
|
||||||
{:keys [can-request-access?
|
|
||||||
no-member-permission?
|
no-member-permission?
|
||||||
tokens
|
tokens
|
||||||
networks-not-supported?
|
networks-not-supported?
|
||||||
highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
||||||
highest-role-text
|
highest-role-text
|
||||||
(i18n/label
|
(i18n/label
|
||||||
(communities.utils/role->translation-key highest-permission-role :t/member))]
|
(communities.utils/role->translation-key highest-permission-role :t/member))
|
||||||
|
on-press (rn/use-callback (fn []
|
||||||
|
(if config/community-accounts-selection-enabled?
|
||||||
|
(rf/dispatch [:open-modal :community-account-selection-sheet
|
||||||
|
{:community-id id}])
|
||||||
|
(rf/dispatch [:open-modal :community-requests-to-join
|
||||||
|
{:id
|
||||||
|
id}])))
|
||||||
|
[id])]
|
||||||
(cond
|
(cond
|
||||||
|
|
||||||
networks-not-supported?
|
networks-not-supported?
|
||||||
[network-not-supported]
|
[network-not-supported]
|
||||||
|
|
||||||
|
@ -157,36 +159,14 @@
|
||||||
[request-access-button id color]
|
[request-access-button id color]
|
||||||
|
|
||||||
:else
|
:else
|
||||||
[rn/view {:style (style/token-gated-container theme)}
|
[quo/community-token-gating
|
||||||
[rn/view
|
{:role highest-role-text
|
||||||
{:style {:padding-horizontal 12
|
:tokens tokens
|
||||||
:flex-direction :row
|
:community-color color
|
||||||
:align-items :center
|
:satisfied? can-request-access?
|
||||||
:justify-content :space-between
|
:on-press on-press
|
||||||
:flex 1}}
|
:on-press-info
|
||||||
[quo/text {:weight :medium}
|
info-button-handler}])))
|
||||||
(if (and can-request-access? highest-permission-role)
|
|
||||||
(i18n/label :t/you-eligible-to-join-as {:role highest-role-text})
|
|
||||||
(i18n/label :t/you-not-eligible-to-join))]
|
|
||||||
[info-button]]
|
|
||||||
[quo/text {:style {:padding-horizontal 12 :padding-bottom 6} :size :paragraph-2}
|
|
||||||
(if can-request-access?
|
|
||||||
(i18n/label :t/you-hodl)
|
|
||||||
(i18n/label :t/you-must-hold))]
|
|
||||||
[quo/token-requirement-list
|
|
||||||
{:tokens tokens
|
|
||||||
:padding? true}]
|
|
||||||
[quo/button
|
|
||||||
{:on-press (if config/community-accounts-selection-enabled?
|
|
||||||
#(rf/dispatch [:open-modal :community-account-selection-sheet
|
|
||||||
{:community-id id}])
|
|
||||||
#(rf/dispatch [:open-modal :community-requests-to-join {:id id}]))
|
|
||||||
:accessibility-label :join-community-button
|
|
||||||
:customization-color color
|
|
||||||
:container-style {:margin-horizontal 12 :margin-top 8 :margin-bottom 12}
|
|
||||||
:disabled? (not can-request-access?)
|
|
||||||
:icon-left (if can-request-access? :i/unlocked :i/locked)}
|
|
||||||
(i18n/label :t/request-to-join)]])))
|
|
||||||
|
|
||||||
(defn- join-community
|
(defn- join-community
|
||||||
[{:keys [id joined permissions] :as community}]
|
[{:keys [id joined permissions] :as community}]
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
(ns status-im.contexts.preview.quo.community.community-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]
|
||||||
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
|
(def descriptor
|
||||||
|
[{:key :role
|
||||||
|
:type :select
|
||||||
|
:options [{:key :member}
|
||||||
|
{:key :admin}
|
||||||
|
{:key :token-master}
|
||||||
|
{:key :token-owner}]}
|
||||||
|
{:key :satisfied?
|
||||||
|
:type :boolean}
|
||||||
|
(preview/customization-color-option {:key :community-color})])
|
||||||
|
|
||||||
|
(def tokens
|
||||||
|
{:member
|
||||||
|
[[{: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}]]
|
||||||
|
:admin
|
||||||
|
[[{:symbol "ETH" :sufficient? true :collectible? false :amount "2" :img-src nil}]]
|
||||||
|
:token-master
|
||||||
|
[[{:symbol "TMANI"
|
||||||
|
:sufficient? true
|
||||||
|
:collectible? true
|
||||||
|
:amount nil
|
||||||
|
:img-src (resources/mock-images :collectible1)}]]
|
||||||
|
:token-owner
|
||||||
|
[[{:symbol "TOANI"
|
||||||
|
:sufficient? true
|
||||||
|
:collectible? true
|
||||||
|
:amount nil
|
||||||
|
:img-src (resources/mock-images :collectible)}]]})
|
||||||
|
|
||||||
|
(def role
|
||||||
|
{:member (i18n/label :t/member)
|
||||||
|
:admin (i18n/label :t/admin)
|
||||||
|
:token-master (i18n/label :t/token-master)
|
||||||
|
:token-owner (i18n/label :t/token-owner)})
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
(let [state (reagent/atom {:role :member
|
||||||
|
:satisfied? true
|
||||||
|
:community-color :blue})]
|
||||||
|
(fn []
|
||||||
|
[preview/preview-container
|
||||||
|
{:state state
|
||||||
|
:descriptor descriptor
|
||||||
|
:show-blur-background? false}
|
||||||
|
[quo/community-token-gating
|
||||||
|
{:community-color (:community-color @state)
|
||||||
|
:role ((:role @state) role)
|
||||||
|
:satisfied? (:satisfied? @state)
|
||||||
|
:on-press #(js/alert "On press 'Request to join'")
|
||||||
|
:on-press-info #(js/alert "On press info")
|
||||||
|
:tokens ((:role @state) tokens)}]])))
|
|
@ -1,73 +0,0 @@
|
||||||
(ns status-im.contexts.preview.quo.community.token-gating
|
|
||||||
(:require
|
|
||||||
[quo.core :as quo]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[status-im.contexts.preview.quo.preview :as preview]))
|
|
||||||
|
|
||||||
(def descriptor
|
|
||||||
[{:label "Tokens sufficient?"
|
|
||||||
:key :sufficient?
|
|
||||||
:type :boolean}
|
|
||||||
{:key :many-tokens?
|
|
||||||
:type :boolean}
|
|
||||||
{:key :loading?
|
|
||||||
:type :boolean}
|
|
||||||
{:key :condition?
|
|
||||||
:type :boolean}
|
|
||||||
{:key :padding?
|
|
||||||
:type :boolean}])
|
|
||||||
|
|
||||||
(defn join-gate-options-base
|
|
||||||
[sufficient? many-tokens? loading?]
|
|
||||||
(into
|
|
||||||
[{:symbol "KNC"
|
|
||||||
:amount 200
|
|
||||||
:sufficient? true
|
|
||||||
:loading? loading?}
|
|
||||||
{:symbol "MANA"
|
|
||||||
:amount 10
|
|
||||||
:sufficient? sufficient?
|
|
||||||
:purchasable? true
|
|
||||||
:loading? loading?}
|
|
||||||
{:symbol "RARE"
|
|
||||||
:amount 10
|
|
||||||
:sufficient? sufficient?
|
|
||||||
:loading? loading?}]
|
|
||||||
(when many-tokens?
|
|
||||||
[{:symbol "FXC"
|
|
||||||
:amount 20
|
|
||||||
:sufficient? true
|
|
||||||
:loading? loading?}
|
|
||||||
{:symbol "SNT"
|
|
||||||
:amount 10000
|
|
||||||
:sufficient? sufficient?
|
|
||||||
:loading? loading?}])))
|
|
||||||
|
|
||||||
(defn get-mocked-props
|
|
||||||
[props]
|
|
||||||
(let [{:keys [sufficient? condition? many-tokens? padding? loading?]} props]
|
|
||||||
{:tokens
|
|
||||||
(if condition?
|
|
||||||
[(join-gate-options-base sufficient?
|
|
||||||
many-tokens?
|
|
||||||
loading?)
|
|
||||||
[{:symbol "FXC"
|
|
||||||
:amount 20
|
|
||||||
:sufficient? true}
|
|
||||||
{:symbol "USDT"
|
|
||||||
:amount 20
|
|
||||||
:sufficient? false}]]
|
|
||||||
[(join-gate-options-base sufficient?
|
|
||||||
many-tokens?
|
|
||||||
loading?)])
|
|
||||||
:padding? padding?}))
|
|
||||||
|
|
||||||
(defn view
|
|
||||||
[]
|
|
||||||
(let [state (reagent/atom {:sufficient? false
|
|
||||||
:many-tokens? false
|
|
||||||
:condition? false
|
|
||||||
:padding? false})]
|
|
||||||
(fn []
|
|
||||||
[preview/preview-container {:state state :descriptor descriptor}
|
|
||||||
[quo/token-requirement-list (get-mocked-props @state)]])))
|
|
|
@ -45,9 +45,9 @@
|
||||||
[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]
|
||||||
|
[status-im.contexts.preview.quo.community.community-token-gating :as community-token-gating]
|
||||||
[status-im.contexts.preview.quo.community.discover-card :as discover-card]
|
[status-im.contexts.preview.quo.community.discover-card :as discover-card]
|
||||||
[status-im.contexts.preview.quo.community.list-item :as community-list-item]
|
[status-im.contexts.preview.quo.community.list-item :as community-list-item]
|
||||||
[status-im.contexts.preview.quo.community.token-gating :as token-gating]
|
|
||||||
[status-im.contexts.preview.quo.counter.collectible-counter :as collectible-counter]
|
[status-im.contexts.preview.quo.counter.collectible-counter :as collectible-counter]
|
||||||
[status-im.contexts.preview.quo.counter.counter :as counter]
|
[status-im.contexts.preview.quo.counter.counter :as counter]
|
||||||
[status-im.contexts.preview.quo.counter.step :as step]
|
[status-im.contexts.preview.quo.counter.step :as step]
|
||||||
|
@ -266,15 +266,14 @@
|
||||||
:component community-card/view}
|
:component community-card/view}
|
||||||
{:name :community-detail-token-gating
|
{:name :community-detail-token-gating
|
||||||
:component community-detail-token-gating/view}
|
:component community-detail-token-gating/view}
|
||||||
|
{:name :community-token-gating
|
||||||
|
:component community-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
|
||||||
:component community-stat/view}
|
:component community-stat/view}
|
||||||
{:name :discover-card
|
{:name :discover-card
|
||||||
:component discover-card/view}
|
:component discover-card/view}
|
||||||
{:name :token-gating
|
|
||||||
:options {:insets {:bottom? true}}
|
|
||||||
:component token-gating/view}
|
|
||||||
{:name :channel-action
|
{:name :channel-action
|
||||||
:options {:insets {:bottom? true}}
|
:options {:insets {:bottom? true}}
|
||||||
:component channel-action/view}
|
:component channel-action/view}
|
||||||
|
|
Loading…
Reference in New Issue