[#15756] Token gated communities
This commit is contained in:
parent
78621207e1
commit
6858884c83
|
@ -1,4 +1,4 @@
|
|||
library 'status-jenkins-lib@v1.7.5'
|
||||
library 'status-jenkins-lib@v1.7.6'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
library 'status-jenkins-lib@v1.7.5'
|
||||
library 'status-jenkins-lib@v1.7.6'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
library 'status-jenkins-lib@v1.7.5'
|
||||
library 'status-jenkins-lib@v1.7.6'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
library 'status-jenkins-lib@v1.7.5'
|
||||
library 'status-jenkins-lib@v1.7.6'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
library 'status-jenkins-lib@v1.7.5'
|
||||
library 'status-jenkins-lib@v1.7.6'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
library 'status-jenkins-lib@v1.7.5'
|
||||
library 'status-jenkins-lib@v1.7.6'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
library 'status-jenkins-lib@v1.7.5'
|
||||
library 'status-jenkins-lib@v1.7.6'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
library 'status-jenkins-lib@v1.7.5'
|
||||
library 'status-jenkins-lib@v1.7.6'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
library 'status-jenkins-lib@v1.7.5'
|
||||
library 'status-jenkins-lib@v1.7.6'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
library 'status-jenkins-lib@v1.7.5'
|
||||
library 'status-jenkins-lib@v1.7.6'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
library 'status-jenkins-lib@v1.7.5'
|
||||
library 'status-jenkins-lib@v1.7.6'
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
|
@ -53,8 +53,13 @@
|
|||
;; @testing-library/react-native.
|
||||
test-helpers.component]}
|
||||
:closure-defines
|
||||
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
|
||||
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im2.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
|
||||
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
|
||||
status-im2.config/ALCHEMY_ARBITRUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ARBITRUM_GOERLI_TOKEN"
|
||||
status-im2.config/ALCHEMY_OPTIMISM_GOERLI_TOKEN #shadow/env "ALCHEMY_OPTIMISM_GOERLI_TOKEN"
|
||||
status-im2.config/ALCHEMY_OPTIMISM_MAINNET_TOKEN #shadow/env "ALCHEMY_OPTIMISM_MAINNET_TOKEN"
|
||||
status-im2.config/ALCHEMY_ARBITRUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ARBITRUM_MAINNET_TOKEN"}
|
||||
:compiler-options {:output-feature-set :es5
|
||||
:closure-defines
|
||||
{re-frame.trace/trace-enabled? true}
|
||||
|
@ -67,8 +72,13 @@
|
|||
:chunks {:fleets status-im.fleet.default-fleet/default-fleets}
|
||||
:release
|
||||
{:closure-defines
|
||||
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
|
||||
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im2.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
|
||||
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
|
||||
status-im2.config/ALCHEMY_ARBITRUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ARBITRUM_GOERLI_TOKEN"
|
||||
status-im2.config/ALCHEMY_OPTIMISM_GOERLI_TOKEN #shadow/env "ALCHEMY_OPTIMISM_GOERLI_TOKEN"
|
||||
status-im2.config/ALCHEMY_OPTIMISM_MAINNET_TOKEN #shadow/env "ALCHEMY_OPTIMISM_MAINNET_TOKEN"
|
||||
status-im2.config/ALCHEMY_ARBITRUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ARBITRUM_MAINNET_TOKEN"}
|
||||
:compiler-options {:output-feature-set :es6
|
||||
;;disable for android build as there
|
||||
;;is an intermittent warning with deftype
|
||||
|
@ -95,8 +105,13 @@
|
|||
:ui-driven
|
||||
true
|
||||
:closure-defines
|
||||
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
|
||||
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im2.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
|
||||
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
|
||||
status-im2.config/ALCHEMY_ARBITRUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ARBITRUM_GOERLI_TOKEN"
|
||||
status-im2.config/ALCHEMY_OPTIMISM_GOERLI_TOKEN #shadow/env "ALCHEMY_OPTIMISM_GOERLI_TOKEN"
|
||||
status-im2.config/ALCHEMY_OPTIMISM_MAINNET_TOKEN #shadow/env "ALCHEMY_OPTIMISM_MAINNET_TOKEN"
|
||||
status-im2.config/ALCHEMY_ARBITRUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ARBITRUM_MAINNET_TOKEN"}
|
||||
:compiler-options
|
||||
{;; needed because we override require and it
|
||||
;; messes with source-map which reports callstack
|
||||
|
|
|
@ -226,9 +226,8 @@
|
|||
[_ _]
|
||||
(let [pressed (reagent/atom false)]
|
||||
(fn
|
||||
[{:keys [on-press disabled type size community-color community-text-color before after above
|
||||
width customization-color
|
||||
override-theme override-background-color
|
||||
[{:keys [on-press disabled type size before after above
|
||||
width customization-color override-theme override-background-color
|
||||
on-long-press accessibility-label icon icon-no-color style inner-style test-ID]
|
||||
:or {type :primary
|
||||
size 40
|
||||
|
@ -247,18 +246,13 @@
|
|||
[rn/touchable-without-feedback
|
||||
(merge {:test-ID test-ID
|
||||
:disabled disabled
|
||||
:accessibility-label accessibility-label}
|
||||
:accessibility-label accessibility-label
|
||||
:on-press-in #(reset! pressed true)
|
||||
:on-press-out #(reset! pressed nil)}
|
||||
(when on-press
|
||||
{:on-press (fn []
|
||||
(on-press))})
|
||||
{:on-press on-press})
|
||||
(when on-long-press
|
||||
{:on-long-press (fn []
|
||||
(on-long-press))})
|
||||
{:on-press-in (fn []
|
||||
(reset! pressed true))}
|
||||
{:on-press-out (fn []
|
||||
(reset! pressed nil))})
|
||||
|
||||
{:on-long-press on-long-press}))
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(shape-style-container type icon size)
|
||||
|
@ -277,11 +271,7 @@
|
|||
width
|
||||
before
|
||||
after)
|
||||
(when
|
||||
(community-themed? type community-color)
|
||||
(merge
|
||||
{:background-color community-color}
|
||||
(when (= state :pressed) {:opacity 0.9})))
|
||||
(when (= state :pressed) {:opacity 0.9})
|
||||
inner-style)}
|
||||
(when above
|
||||
[rn/view
|
||||
|
@ -309,12 +299,7 @@
|
|||
{:size (when (#{56 24} size) :paragraph-2)
|
||||
:weight :medium
|
||||
:number-of-lines 1
|
||||
:style {:color (if
|
||||
(and
|
||||
(community-themed? type community-color)
|
||||
(string? community-text-color))
|
||||
community-text-color
|
||||
label-color)}}
|
||||
:style {:color label-color}}
|
||||
|
||||
children]
|
||||
|
||||
|
|
|
@ -112,3 +112,39 @@
|
|||
{:position :absolute
|
||||
:top 8
|
||||
:right 8})
|
||||
|
||||
(def token-tag-spacing
|
||||
{:margin-top 10
|
||||
:margin-right 8})
|
||||
|
||||
(defn token-row
|
||||
[padding?]
|
||||
(merge
|
||||
{:flex-direction :row
|
||||
:flex-wrap :wrap
|
||||
:align-items :center}
|
||||
(when padding?
|
||||
{:padding-horizontal 12})))
|
||||
|
||||
(def token-row-container
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:margin-bottom 12})
|
||||
|
||||
(defn token-row-or-text
|
||||
[padding?]
|
||||
(merge
|
||||
{:margin-top 4
|
||||
:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40)}
|
||||
(when padding?
|
||||
{:padding-left 12})))
|
||||
|
||||
(defn token-row-or-border
|
||||
[]
|
||||
{:height 1
|
||||
:background-color (colors/theme-colors
|
||||
colors/neutral-20
|
||||
colors/neutral-80)})
|
||||
|
||||
|
|
|
@ -1,295 +1,45 @@
|
|||
(ns quo2.components.community.token-gating
|
||||
(:require [quo2.components.avatars.channel-avatar :as channel-avatar]
|
||||
[quo2.components.buttons.button :as button]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.components.info.information-box :as information-box]
|
||||
[quo2.components.markdown.text :as text]
|
||||
(:require [quo2.components.markdown.text :as text]
|
||||
[quo2.components.tags.token-tag :as token-tag]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[utils.i18n :as i18n]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def ^:private token-tag-horizontal-spacing 7)
|
||||
(def token-tag-vertical-spacing 5)
|
||||
|
||||
(def styles
|
||||
{:container {:flex 1
|
||||
:padding-horizontal 20}
|
||||
:header-container {:flex-direction :row
|
||||
:align-items :center}
|
||||
:header-spacing-community {:margin-bottom 16}
|
||||
:header-spacing-channel {:margin-bottom 24}
|
||||
:header-avatar {:margin-right 8}
|
||||
:header-community-avatar-image {:width 32 :height 32}
|
||||
:header-title-container {:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center}
|
||||
:header-title-lock {:margin-left 6}
|
||||
:header-info-button {:margin-left 8}
|
||||
:token-requirement-text-spacing {:margin-vertical 8}
|
||||
:token-requirement-list-spacing {:padding-vertical (- 8 token-tag-vertical-spacing)}
|
||||
:token-row {:flex-direction :row
|
||||
:flex-wrap :wrap
|
||||
:align-items :center}
|
||||
:token-row-container {:flex-direction :row
|
||||
:align-items :center
|
||||
:margin-horizontal (- token-tag-horizontal-spacing)}
|
||||
:token-row-container-no-shift {:margin-left 0}
|
||||
:token-row-or-text {:margin-right 3}
|
||||
:token-tag-spacing {:margin-horizontal token-tag-horizontal-spacing
|
||||
:margin-vertical token-tag-vertical-spacing}
|
||||
:divider {:height 1
|
||||
:margin-horizontal -20
|
||||
:margin-top (- 12 token-tag-vertical-spacing)
|
||||
:margin-bottom 8}
|
||||
:membership-request-denied {:margin-top 13}
|
||||
:enter-button {:margin-top 16}
|
||||
:info-text {:margin-top 12
|
||||
:text-align :center
|
||||
:padding-horizontal 20}})
|
||||
|
||||
(defn multiple-token-requirements?
|
||||
[token-requirement-lists]
|
||||
(when (vector? (first token-requirement-lists))
|
||||
(> (count token-requirement-lists) 1)))
|
||||
|
||||
(defn is-token-requirement-met?
|
||||
[token-requirement-list]
|
||||
(and (seq token-requirement-list)
|
||||
(every?
|
||||
(fn [token]
|
||||
(get token :is-sufficient?))
|
||||
token-requirement-list)))
|
||||
|
||||
(defn are-multiple-token-requirements-met?
|
||||
[token-requirement-lists]
|
||||
(if (multiple-token-requirements? token-requirement-lists)
|
||||
(some is-token-requirement-met? token-requirement-lists)
|
||||
(is-token-requirement-met? token-requirement-lists)))
|
||||
[clojure.string :as string]
|
||||
[quo2.components.community.style :as style]))
|
||||
|
||||
(defn token-requirement-list-row
|
||||
[tokens community-color]
|
||||
[tokens padding?]
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(get styles :token-row)
|
||||
(get styles :token-requirement-list-spacing))}
|
||||
(map-indexed (fn [token-index token]
|
||||
(let [{:keys [token-img-src token amount is-sufficient? is-purchasable?]} token]
|
||||
^{:key token-index}
|
||||
[rn/view {:style (get styles :token-tag-spacing)}
|
||||
[token-tag/token-tag
|
||||
{:token token
|
||||
:value amount
|
||||
:size 24
|
||||
:border-color community-color
|
||||
:is-required is-sufficient?
|
||||
:is-purchasable is-purchasable?
|
||||
:token-img-src token-img-src}]]))
|
||||
tokens)])
|
||||
{:style (style/token-row padding?)}
|
||||
(doall
|
||||
(map-indexed (fn [token-index token]
|
||||
(let [{:keys [img-src symbol amount sufficient? purchasable? loading?]} token]
|
||||
^{:key token-index}
|
||||
[rn/view {:style style/token-tag-spacing}
|
||||
[token-tag/token-tag
|
||||
{:symbol symbol
|
||||
:value amount
|
||||
:size 24
|
||||
:sufficient? sufficient?
|
||||
:purchasable purchasable?
|
||||
:loading? loading?
|
||||
:img-src img-src}]]))
|
||||
tokens))])
|
||||
|
||||
(defn token-requirement-list
|
||||
[props community-color]
|
||||
(let [{:keys [gate token-requirements-changed?
|
||||
required-tokens-lost?]} props
|
||||
[gate-type token-requirement-lists] gate
|
||||
multiple-token-requirements? (multiple-token-requirements? token-requirement-lists)
|
||||
is-sufficient? (are-multiple-token-requirements-met?
|
||||
token-requirement-lists)
|
||||
you-must-hold-label (if (= gate-type :join)
|
||||
(cond
|
||||
token-requirements-changed? :t/you-must-now-hold
|
||||
required-tokens-lost? :t/you-must-always-hold
|
||||
:else :t/you-must-hold)
|
||||
:t/you-must-hold)
|
||||
message-label (cond
|
||||
(= gate-type :join)
|
||||
(cond
|
||||
token-requirements-changed?
|
||||
:t/community-join-requirements-changed
|
||||
required-tokens-lost?
|
||||
:t/community-join-requirements-tokens-lost
|
||||
:else (if is-sufficient?
|
||||
:t/community-join-requirements-met
|
||||
:t/community-join-requirements-not-met))
|
||||
(= gate-type :read)
|
||||
(if is-sufficient?
|
||||
:t/community-channel-read-requirements-met
|
||||
:t/community-channel-read-requirements-not-met)
|
||||
(= gate-type :write)
|
||||
(if is-sufficient?
|
||||
:t/community-channel-write-requirements-met
|
||||
:t/community-channel-write-requirements-not-met))]
|
||||
[rn/view
|
||||
[rn/view {:style (get styles :token-requirement-text-spacing)}
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:number-of-lines 1}
|
||||
(i18n/label
|
||||
message-label)]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:number-of-lines 1}
|
||||
(i18n/label
|
||||
you-must-hold-label)]]
|
||||
|
||||
(if multiple-token-requirements?
|
||||
(map-indexed
|
||||
(fn [token-requirement-index tokens]
|
||||
^{:key token-requirement-index}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(get styles :token-row-container)
|
||||
(when-not (= token-requirement-index 0)
|
||||
(get styles :token-row-container-no-shift)))}
|
||||
(when-not (= token-requirement-index 0)
|
||||
[text/text
|
||||
{:style (get styles :token-row-or-text)
|
||||
:size :paragraph-2} "or"])
|
||||
[token-requirement-list-row tokens community-color]])
|
||||
token-requirement-lists)
|
||||
[rn/view {:style (get styles :token-row-container)}
|
||||
[token-requirement-list-row token-requirement-lists community-color]])]))
|
||||
|
||||
(defn is-community-locked?
|
||||
[community]
|
||||
(not (are-multiple-token-requirements-met? (get-in community [:gates :join]))))
|
||||
|
||||
(defn is-channel-locked?
|
||||
[channel]
|
||||
(not (are-multiple-token-requirements-met?
|
||||
(or (get-in channel [:gates :read])
|
||||
(get-in channel [:gates :write])))))
|
||||
|
||||
(defn token-gating
|
||||
"[token-gating opts]
|
||||
opts
|
||||
{
|
||||
:community {
|
||||
:name string
|
||||
:community-avatar-img-src string
|
||||
:community-color string
|
||||
:community-text-color string
|
||||
:token-requirements-changed? boolean
|
||||
:required-tokens-lost? boolean
|
||||
}
|
||||
:channel {
|
||||
:name string
|
||||
:emoji string
|
||||
:emoji-background-color :string
|
||||
:on-enter-channel callback
|
||||
:membership-request-denied? boolean
|
||||
}
|
||||
}"
|
||||
[_ _]
|
||||
(fn [{:keys [community channel]}]
|
||||
(let [type (if (some? community) :community :channel)
|
||||
{:keys [name
|
||||
emoji
|
||||
emoji-background-color
|
||||
on-enter-channel
|
||||
community-avatar-img-src
|
||||
community-color
|
||||
community-text-color
|
||||
membership-request-denied?
|
||||
token-requirements-changed?
|
||||
required-tokens-lost?
|
||||
gates]}
|
||||
(if (= type :community) community channel)
|
||||
locked? (if
|
||||
(= type :community)
|
||||
(is-community-locked? community)
|
||||
(is-channel-locked? channel))]
|
||||
|
||||
[rn/view
|
||||
{:style (merge (get styles :container)
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-90)})}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(get styles :header-container)
|
||||
(if
|
||||
(= type :community)
|
||||
(get styles :header-spacing-community)
|
||||
(get styles :header-spacing-channel)))}
|
||||
|
||||
[rn/view {:style (get styles :header-avatar)}
|
||||
(if (= type :community)
|
||||
[fast-image/fast-image
|
||||
{:source community-avatar-img-src
|
||||
:style (get styles :header-community-avatar-image)}]
|
||||
|
||||
[channel-avatar/channel-avatar
|
||||
{:big? true
|
||||
:locked? locked?
|
||||
:emoji emoji
|
||||
:emoji-background-color emoji-background-color}])]
|
||||
|
||||
[rn/view {:style (get styles :header-title-container)}
|
||||
[text/text
|
||||
{:weight :semi-bold
|
||||
:number-of-lines 1
|
||||
:size :heading-1
|
||||
:style (get styles :header-text)} (if (= type :community) name (str "# " name))]
|
||||
|
||||
(when (= type :community)
|
||||
[icon/icon
|
||||
(if locked?
|
||||
:main-icons2/locked
|
||||
:main-icons2/unlocked)
|
||||
{:container-style (get styles :header-title-lock)
|
||||
:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40)}])]
|
||||
|
||||
[button/button
|
||||
{:type :outline
|
||||
:size 32
|
||||
:icon true
|
||||
:style (get styles :header-info-button)} :main-icons2/info]]
|
||||
|
||||
(map-indexed (fn [gate-index gate]
|
||||
^{:key gate-index}
|
||||
[:<>
|
||||
(when-not (= gate-index 0)
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(get styles :divider)
|
||||
{:background-color (colors/theme-colors
|
||||
colors/neutral-10
|
||||
colors/neutral-80)})}])
|
||||
[token-requirement-list
|
||||
{:gate gate
|
||||
:token-requirements-changed? token-requirements-changed?
|
||||
:required-tokens-lost? required-tokens-lost?} community-color]])
|
||||
gates)
|
||||
|
||||
(when (= type :channel)
|
||||
(if membership-request-denied?
|
||||
[information-box/information-box
|
||||
{:type :error
|
||||
:icon :main-icons2/untrustworthy
|
||||
:no-icon-color? true
|
||||
:style (get styles :membership-request-denied)}
|
||||
(i18n/label
|
||||
:t/membership-request-denied)]
|
||||
|
||||
[:<>
|
||||
[button/button
|
||||
{:type :community
|
||||
:community-color community-color
|
||||
:community-text-color community-text-color
|
||||
:style (get styles :enter-button)
|
||||
:disabled locked?
|
||||
:on-press on-enter-channel}
|
||||
(str "# "
|
||||
(i18n/label
|
||||
:t/enter-channel))]
|
||||
[{:keys [tokens padding?]}]
|
||||
[:<>
|
||||
(if (> (count tokens) 1)
|
||||
(doall
|
||||
(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)}])
|
||||
(when-not (= token-requirement-index 0)
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style (merge
|
||||
(get styles :info-text)
|
||||
{:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40)})}
|
||||
(i18n/label
|
||||
:t/community-enter-channel-info)]]))])))
|
||||
{:style (style/token-row-or-text padding?)
|
||||
:size :label} (string/lower-case (i18n/label :t/or))])
|
||||
[token-requirement-list-row tokens padding?]])
|
||||
tokens))
|
||||
[token-requirement-list-row (first tokens) padding?])])
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
(def context-tag-text-container
|
||||
{:align-items :center
|
||||
:margin-left 4
|
||||
:flex-direction :row})
|
||||
|
||||
(def audio-tag-container
|
||||
|
|
|
@ -47,23 +47,24 @@
|
|||
empty-photo? (empty? photo)
|
||||
avatar-size :xxs
|
||||
avatar-outer-size (get-in user-avatar-style/sizes [avatar-size :outer])]
|
||||
[base-tag (assoc-in params [:style :padding-left] 3)
|
||||
(if (and empty-photo? no-avatar-placeholder?)
|
||||
[rn/view {:style {:width avatar-outer-size}}]
|
||||
[user-avatar/user-avatar
|
||||
{:full-name name
|
||||
:profile-picture photo
|
||||
:size avatar-size
|
||||
:status-indicator? false}])
|
||||
[rn/view {:style style/context-tag-text-container}
|
||||
[text/text text-params (str " " name)]
|
||||
(when channel-name
|
||||
[:<>
|
||||
[icons/icon
|
||||
:i/chevron-right
|
||||
{:color (style/context-tag-icon-color blur?)
|
||||
:size 16}]
|
||||
[text/text text-params (str "# " channel-name)]])]]))
|
||||
[rn/view {:flex-direction :row}
|
||||
[base-tag (assoc-in params [:style :padding-left] 3)
|
||||
(if (and empty-photo? no-avatar-placeholder?)
|
||||
[rn/view {:style {:width avatar-outer-size}}]
|
||||
[user-avatar/user-avatar
|
||||
{:full-name name
|
||||
:profile-picture photo
|
||||
:size avatar-size
|
||||
:status-indicator? false}])
|
||||
[rn/view {:style style/context-tag-text-container}
|
||||
[text/text text-params (str " " name)]
|
||||
(when channel-name
|
||||
[:<>
|
||||
[icons/icon
|
||||
:i/chevron-right
|
||||
{:color (style/context-tag-icon-color blur?)
|
||||
:size 16}]
|
||||
[text/text text-params (str "# " channel-name)]])]]]))
|
||||
|
||||
(defn user-avatar-tag
|
||||
[params username photo]
|
||||
|
|
|
@ -39,8 +39,9 @@
|
|||
:overlay child-elements
|
||||
}"
|
||||
[_ _]
|
||||
(fn [{:keys [size token-img-src token-img-style border-color overlay]
|
||||
:or {size :small}} label]
|
||||
(fn [{:keys [size img-src img-style border-color overlay]
|
||||
:or {size :small}}
|
||||
label]
|
||||
[rn/view
|
||||
{:style (when border-color
|
||||
{:border-color border-color
|
||||
|
@ -49,13 +50,13 @@
|
|||
[rn/view
|
||||
{:style (merge (tag-container size) (get themes (theme/get-theme)))}
|
||||
[rn/image
|
||||
{:source token-img-src
|
||||
:style (merge
|
||||
{:height (get-value-from-size size 28 20)
|
||||
:width (get-value-from-size size 28 20)
|
||||
:margin-left 2
|
||||
:margin-right (get-value-from-size size 8 6)}
|
||||
token-img-style)}]
|
||||
{:src img-src
|
||||
:style (merge
|
||||
{:height (get-value-from-size size 28 20)
|
||||
:width (get-value-from-size size 28 20)
|
||||
:margin-left 2
|
||||
:margin-right (get-value-from-size size 8 6)}
|
||||
img-style)}]
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:number-of-lines 1
|
||||
|
@ -64,38 +65,58 @@
|
|||
:size (get-value-from-size size :paragraph-2 :label)} label]
|
||||
overlay]]))
|
||||
|
||||
(defn loading-icon
|
||||
[]
|
||||
[rn/view
|
||||
{:style {:align-items :center
|
||||
:justify-content :center
|
||||
:position :absolute
|
||||
:right -8
|
||||
:top -8}}
|
||||
[icons/icon :t/checktoken
|
||||
{:no-color true
|
||||
:size 20}]])
|
||||
|
||||
(defn icon
|
||||
[size border-color sufficient?]
|
||||
[rn/view
|
||||
{:style (merge
|
||||
icon-container-styles
|
||||
{:background-color border-color
|
||||
:border-color (if (= (theme/get-theme) :dark) colors/neutral-100 colors/white)
|
||||
:border-width 1
|
||||
:right (get-value-from-size size -3.75 -5.75)
|
||||
:bottom (get-value-from-size size (- 32 7.75 4) (- 24 7.75 2))})}
|
||||
[icons/icon (if sufficient? :i/hold :i/add)
|
||||
{:no-color true
|
||||
:size 12}]])
|
||||
|
||||
(defn token-tag
|
||||
"[token-tag opts]
|
||||
opts
|
||||
{
|
||||
:token string
|
||||
:symbol string
|
||||
:value string
|
||||
:size :small/:big
|
||||
:token-img-src :token-img-src
|
||||
:border-color :color
|
||||
:is-required true/false
|
||||
:is-purchasable true/false
|
||||
:sufficient? true/false
|
||||
:purchasable? true/false
|
||||
:loading? true/false
|
||||
}"
|
||||
[_ _]
|
||||
(fn [{:keys [token value size token-img-src border-color is-required is-purchasable]
|
||||
(fn [{:keys [symbol value size img-src border-color purchasable? sufficient? loading?]
|
||||
:or
|
||||
{size :small border-color (colors/custom-color-by-theme :purple 50 60)}}]
|
||||
|
||||
[tag
|
||||
{:size size
|
||||
:token-img-src token-img-src
|
||||
:border-color (when is-required border-color)
|
||||
:overlay
|
||||
(when (or is-required is-purchasable)
|
||||
[rn/view
|
||||
{:style (merge
|
||||
icon-container-styles
|
||||
{:background-color border-color
|
||||
:border-color (if (= (theme/get-theme) :dark) colors/neutral-100 colors/white)
|
||||
:border-width 1
|
||||
:right (get-value-from-size size -3.75 -5.75)
|
||||
:bottom (get-value-from-size size (- 32 7.75 4) (- 24 7.75 2))})}
|
||||
[icons/icon (if is-required :i/hold :i/add)
|
||||
{:no-color true
|
||||
:size 12}]])}
|
||||
(str value " " token)]))
|
||||
{size :small}}]
|
||||
(let [sufficient? (when-not loading? sufficient?)
|
||||
border-color (if sufficient? colors/success-50 border-color)]
|
||||
[tag
|
||||
{:size size
|
||||
:img-src img-src
|
||||
:border-color (if sufficient? colors/success-50 border-color)
|
||||
:overlay
|
||||
(if loading?
|
||||
[loading-icon]
|
||||
(when (or purchasable? sufficient?)
|
||||
[icon size border-color sufficient?]))}
|
||||
(str value " " symbol)])))
|
||||
|
|
|
@ -145,8 +145,8 @@
|
|||
(def community-title quo2.components.community.community-view/community-title)
|
||||
(def permission-tag-container quo2.components.community.community-view/permission-tag-container)
|
||||
(def discover-card quo2.components.community.banner.view/view)
|
||||
(def token-gating quo2.components.community.token-gating/token-gating)
|
||||
(def community-icon quo2.components.community.icon/community-icon)
|
||||
(def token-requirement-list quo2.components.community.token-gating/token-requirement-list)
|
||||
|
||||
;;;; COUNTER
|
||||
(def counter quo2.components.counter.counter/counter)
|
||||
|
|
|
@ -74,13 +74,19 @@
|
|||
:canJoin :can-join?
|
||||
:requestedToJoinAt :requested-to-join-at
|
||||
:isMember :is-member?
|
||||
:adminSettings :admin-settings})
|
||||
:adminSettings :admin-settings
|
||||
:tokenPermissions :token-permissions
|
||||
:communityTokensMetadata :tokens-metadata})
|
||||
(update :admin-settings
|
||||
set/rename-keys
|
||||
{:pinMessageAllMembersEnabled :pin-message-all-members-enabled?})
|
||||
(update :members walk/stringify-keys)
|
||||
(update :chats <-chats-rpc)
|
||||
(update :categories <-categories-rpc)))
|
||||
(update :categories <-categories-rpc)
|
||||
(assoc :token-images
|
||||
(reduce (fn [acc {:keys [symbol image]}] (assoc acc symbol image))
|
||||
{}
|
||||
(:communityTokensMetadata c)))))
|
||||
|
||||
(defn- fetch-community-id-input
|
||||
[{:keys [db]}]
|
||||
|
@ -174,6 +180,7 @@
|
|||
(let [community-name (aget response-js "communities" 0 "name")]
|
||||
(rf/merge cofx
|
||||
(handle-response cofx response-js)
|
||||
(navigation/hide-bottom-sheet)
|
||||
(toasts/upsert {:icon :correct
|
||||
:icon-color (:positive-01 @colors/theme)
|
||||
:text (i18n/label
|
||||
|
@ -215,14 +222,12 @@
|
|||
|
||||
(rf/defn join
|
||||
{:events [:communities/join]}
|
||||
[cofx community-id]
|
||||
[_ community-id]
|
||||
{:json-rpc/call [{:method "wakuext_joinCommunity"
|
||||
:params [community-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::joined %])
|
||||
:on-error #(do
|
||||
(log/error "failed to join community" community-id %)
|
||||
(re-frame/dispatch [::failed-to-join %]))}]})
|
||||
:on-error #(log/error "failed to join community" community-id %)}]})
|
||||
|
||||
(rf/defn request-to-join
|
||||
{:events [:communities/request-to-join]}
|
||||
|
@ -231,9 +236,24 @@
|
|||
:params [{:communityId community-id}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:communities/requested-to-join %])
|
||||
:on-error (fn []
|
||||
(log/error "failed to request to join community" community-id)
|
||||
(re-frame/dispatch [::failed-to-request-to-join]))}]})
|
||||
:on-error #(log/error "failed to request to join community" community-id)}]})
|
||||
|
||||
(rf/defn requested-to-join-with-password-error
|
||||
{:events [:communities/requested-to-join-with-password-error]}
|
||||
[{:keys [db]} error]
|
||||
{:db (assoc-in db [:password-authentication :error] error)})
|
||||
|
||||
(rf/defn request-to-join-with-password
|
||||
{:events [:communities/request-to-join-with-password]}
|
||||
[_ community-id password]
|
||||
{:json-rpc/call [{:method "wakuext_requestToJoinCommunity"
|
||||
:params [{:communityId community-id :password password}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:communities/requested-to-join %])
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to request to join community" community-id error)
|
||||
(re-frame/dispatch [:communities/requested-to-join-with-password-error
|
||||
error]))}]})
|
||||
|
||||
(rf/defn get-user-requests-to-join
|
||||
{:events [:communities/get-user-requests-to-join]}
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
(ns status-im.ui.screens.communities.requests-to-join
|
||||
(:require [quo.components.animated.pressable :as animation]
|
||||
[quo.core :as quo]
|
||||
[quo.design-system.colors :as colors]
|
||||
[quo.react-native :as rn]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.communities.core :as communities]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn request-actions
|
||||
[community-id request-id]
|
||||
[react/view {:flex-direction :row}
|
||||
[animation/pressable
|
||||
{:on-press #(re-frame/dispatch [:communities.ui/accept-request-to-join-pressed community-id
|
||||
request-id])}
|
||||
[icons/icon :main-icons/checkmark-circle
|
||||
{:width 35
|
||||
:height 35
|
||||
:color colors/green}]]
|
||||
[animation/pressable
|
||||
{:on-press #(re-frame/dispatch [:communities.ui/decline-request-to-join-pressed community-id
|
||||
request-id])}
|
||||
[icons/icon :main-icons/cancel
|
||||
{:width 35
|
||||
:height 35
|
||||
:container-style {:margin-left 16}
|
||||
:color colors/red}]]])
|
||||
|
||||
(defn render-request
|
||||
[{:keys [id public-key]} _ _
|
||||
{:keys [community-id
|
||||
can-manage-users?]}]
|
||||
(let [member (or (rf/sub [:contacts/contact-by-identity public-key])
|
||||
{:public-key public-key})]
|
||||
[quo/list-item
|
||||
{:title (multiaccounts/displayed-name member)
|
||||
:accessibility-label :member-item
|
||||
:accessory-style (when can-manage-users?
|
||||
{:flex-basis 120})
|
||||
:accessory (when can-manage-users?
|
||||
[request-actions community-id id])
|
||||
:icon [chat-icon/contact-icon-contacts-tab member]
|
||||
:on-press #(re-frame/dispatch [:chat.ui/show-profile public-key])}]))
|
||||
|
||||
(defn requests-to-join
|
||||
[]
|
||||
(let [{:keys [community-id]} (rf/sub [:get-screen-params])]
|
||||
(fn []
|
||||
(let [requests (rf/sub [:communities/requests-to-join-for-community
|
||||
community-id])
|
||||
{:keys [can-manage-users?]} (rf/sub [:communities/community community-id])]
|
||||
[:<>
|
||||
[topbar/topbar
|
||||
{:title (i18n/label :t/community-requests-to-join-title)
|
||||
:subtitle (str (count requests))}]
|
||||
[rn/flat-list
|
||||
{:data requests
|
||||
:render-data {:community-id community-id
|
||||
:can-manage-users? can-manage-users?}
|
||||
:key-fn :id
|
||||
:render-fn render-request}]]))))
|
||||
|
||||
(defn requests-to-join-container
|
||||
[]
|
||||
(reagent/create-class
|
||||
{:display-name "community-requests-to-join-view"
|
||||
:component-did-mount (fn []
|
||||
(communities/fetch-requests-to-join! (get (rf/sub [:get-screen-params])
|
||||
:community-id)))
|
||||
:reagent-render requests-to-join}))
|
|
@ -26,7 +26,6 @@
|
|||
[status-im.ui.screens.communities.membership :as membership]
|
||||
[status-im.ui.screens.communities.profile :as community.profile]
|
||||
[status-im.ui.screens.communities.reorder-categories :as reorder-categories]
|
||||
[status-im.ui.screens.communities.requests-to-join :as requests-to-join]
|
||||
[status-im.ui.screens.communities.select-category :as select-category]
|
||||
[status-im.ui.screens.contacts-list.views :as contacts-list]
|
||||
[status-im.ui.screens.currency-settings.views :as currency-settings]
|
||||
|
@ -229,10 +228,6 @@
|
|||
;;TODO custom subtitle
|
||||
:options {:insets {:top? true}}
|
||||
:component members/members-container}
|
||||
{:name :community-requests-to-join
|
||||
;;TODO custom subtitle
|
||||
:options {:insets {:top? true}}
|
||||
:component requests-to-join/requests-to-join-container}
|
||||
{:name :create-community-channel
|
||||
:options {:topBar {:title {:text (i18n/label :t/create-channel-title)}}
|
||||
:insets {:bottom? true
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
(ns status-im2.common.password-authentication.events
|
||||
(:require [utils.re-frame :as rf]
|
||||
[status-im2.navigation.events :as navigation]))
|
||||
|
||||
(rf/defn close
|
||||
{:events [:password-authentication/show]}
|
||||
[{:keys [db]} content button]
|
||||
(rf/merge {:db (assoc db
|
||||
:password-authentication
|
||||
{:error nil
|
||||
:button button})}
|
||||
(navigation/show-bottom-sheet content)))
|
|
@ -0,0 +1,41 @@
|
|||
(ns status-im2.common.password-authentication.view
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.core :as quo]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [entered-password (reagent/atom "")]
|
||||
(fn []
|
||||
(let [account (rf/sub [:profile/multiaccount])
|
||||
{:keys [error button]} (rf/sub [:password-authentication])]
|
||||
[rn/view {:padding-horizontal 20}
|
||||
[quo/text {:size :heading-1 :weight :semi-bold}
|
||||
(i18n/label :t/enter-password)]
|
||||
[quo/user-avatar-tag
|
||||
{:size :small
|
||||
:style {:margin-top 8 :margin-bottom 20}}
|
||||
(multiaccounts/displayed-name account)
|
||||
(multiaccounts/displayed-photo account)]
|
||||
[quo/input
|
||||
{:type :password
|
||||
:label (i18n/label :t/profile-password)
|
||||
:placeholder (i18n/label :t/type-your-password)
|
||||
:error? (when (not-empty error) error)
|
||||
:auto-focus true
|
||||
:on-change-text #(reset! entered-password %)}]
|
||||
(when (not-empty error)
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:style {:margin-top 8}}
|
||||
(i18n/label :t/oops-wrong-password)])
|
||||
[quo/button
|
||||
{:style {:margin-bottom 12 :margin-top 40}
|
||||
:on-press #((:on-press button) (ethereum/sha3 @entered-password))}
|
||||
(:label button)]]))))
|
|
@ -8,7 +8,12 @@
|
|||
|
||||
(defn enabled? [v] (= "1" v))
|
||||
|
||||
(goog-define INFURA_TOKEN "")
|
||||
(goog-define POKT_TOKEN "3ef2018191814b7e1009b8d9")
|
||||
(goog-define ALCHEMY_ARBITRUM_GOERLI_TOKEN "")
|
||||
(goog-define ALCHEMY_OPTIMISM_GOERLI_TOKEN "")
|
||||
(goog-define ALCHEMY_OPTIMISM_MAINNET_TOKEN "")
|
||||
(goog-define ALCHEMY_ARBITRUM_MAINNET_TOKEN "")
|
||||
(goog-define OPENSEA_API_KEY "")
|
||||
|
||||
(def mainnet-rpc-url (str "https://eth-archival.gateway.pokt.network/v1/lb/" POKT_TOKEN))
|
||||
|
|
|
@ -37,8 +37,8 @@
|
|||
|
||||
(h/test "joined options - Token Gated"
|
||||
(setup-subs {:communities/my-pending-request-to-join nil
|
||||
:communities/community {:joined true
|
||||
:token-gated? true}})
|
||||
:communities/community {:joined true
|
||||
:token-permissions []}})
|
||||
(h/render [options/community-options-bottom-sheet {:id "test"}])
|
||||
(-> (h/expect (h/get-by-translation-text :view-members))
|
||||
(.toBeTruthy))
|
||||
|
@ -86,8 +86,8 @@
|
|||
|
||||
(h/test "admin options - Token Gated"
|
||||
(setup-subs {:communities/my-pending-request-to-join nil
|
||||
:communities/community {:admin true
|
||||
:token-gated? true}})
|
||||
:communities/community {:admin true
|
||||
:token-permissions []}})
|
||||
(h/render [options/community-options-bottom-sheet {:id "test"}])
|
||||
(-> (h/expect (h/get-by-translation-text :view-members))
|
||||
(.toBeTruthy))
|
||||
|
@ -127,7 +127,7 @@
|
|||
|
||||
(h/test "request sent options - Token Gated"
|
||||
(setup-subs {:communities/my-pending-request-to-join "mock-id"
|
||||
:communities/community {:token-gated? true}})
|
||||
:communities/community {:token-permissions []}})
|
||||
(h/render [options/community-options-bottom-sheet {:id "test"}])
|
||||
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
|
||||
(.toBeTruthy))
|
||||
|
@ -157,8 +157,8 @@
|
|||
|
||||
(h/test "banned options - Token Gated"
|
||||
(setup-subs {:communities/my-pending-request-to-join nil
|
||||
:communities/community {:banList 100
|
||||
:token-gated? true}})
|
||||
:communities/community {:banList 100
|
||||
:token-permissions []}})
|
||||
(h/render [options/community-options-bottom-sheet {:id "test"}])
|
||||
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
|
||||
(.toBeTruthy))
|
||||
|
@ -171,8 +171,8 @@
|
|||
|
||||
(h/test "banned options - Token Gated"
|
||||
(setup-subs {:communities/my-pending-request-to-join nil
|
||||
:communities/community {:banList 100
|
||||
:token-gated? true}})
|
||||
:communities/community {:banList 100
|
||||
:token-permissions []}})
|
||||
(h/render [options/community-options-bottom-sheet {:id "test"}])
|
||||
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
|
||||
(.toBeTruthy))
|
||||
|
@ -185,11 +185,9 @@
|
|||
|
||||
(h/test "joined and muted community"
|
||||
(setup-subs {:communities/my-pending-request-to-join nil
|
||||
:communities/community {:joined true
|
||||
:muted true
|
||||
:token-gated? true}})
|
||||
:communities/community {:joined true
|
||||
:muted true
|
||||
:token-permissions []}})
|
||||
(h/render [options/community-options-bottom-sheet {:id "test"}])
|
||||
(-> (h/expect (h/get-by-translation-text :unmute-community))
|
||||
(.toBeTruthy))))
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
[utils.re-frame :as rf]
|
||||
[quo2.core :as quo]
|
||||
[status-im2.contexts.communities.actions.see-rules.view :as see-rules]
|
||||
[status-im2.contexts.communities.actions.leave.view :as leave-menu]))
|
||||
[status-im2.contexts.communities.actions.leave.view :as leave-menu]
|
||||
[status-im2.contexts.communities.actions.token-gating.view :as token-gating]))
|
||||
|
||||
(defn hide-sheet-and-dispatch
|
||||
[event]
|
||||
|
@ -29,10 +30,11 @@
|
|||
|
||||
(defn view-token-gating
|
||||
[id]
|
||||
{:icon :i/bullet-list
|
||||
:right-icon :i/token
|
||||
{:icon :i/token
|
||||
:right-icon :i/chevron-right
|
||||
:accessibility-label :view-token-gating
|
||||
:on-press #(js/alert (str "implement action" id))
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [token-gating/token-requirements id])}])
|
||||
:label (i18n/label :t/view-token-gating)})
|
||||
|
||||
(defn mark-as-read
|
||||
|
@ -152,15 +154,15 @@
|
|||
|
||||
(defn get-context-drawers
|
||||
[{:keys [id]}]
|
||||
(let [{:keys [token-gated? admin joined
|
||||
(let [{:keys [token-permissions admin joined
|
||||
muted banList]} (rf/sub [:communities/community id])
|
||||
request-id (rf/sub [:communities/my-pending-request-to-join id])]
|
||||
(cond
|
||||
admin (owner-options id token-gated? muted)
|
||||
joined (joined-options id token-gated? muted)
|
||||
request-id (join-request-sent-options id token-gated? request-id)
|
||||
banList (banned-options id token-gated?)
|
||||
:else (not-joined-options id token-gated?))))
|
||||
admin (owner-options id token-permissions muted)
|
||||
joined (joined-options id token-permissions muted)
|
||||
request-id (join-request-sent-options id token-permissions request-id)
|
||||
banList (banned-options id token-permissions)
|
||||
:else (not-joined-options id token-permissions))))
|
||||
|
||||
(defn community-options-bottom-sheet
|
||||
[id]
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
(ns status-im2.contexts.communities.actions.token-gating.view
|
||||
(:require [quo2.core :as quo]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn token-requirements
|
||||
[id]
|
||||
(rf/dispatch [:communities/check-permissions-to-join-community id])
|
||||
(fn []
|
||||
(let [{:keys [can-request-access?
|
||||
number-of-hold-tokens tokens]} (rf/sub [:community/token-gated-overview id])]
|
||||
[rn/view {:style {:padding-horizontal 12}}
|
||||
[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 18} :size :paragraph-2}
|
||||
(if can-request-access?
|
||||
(i18n/label :t/you-hold-number-of-hold-tokens-of-these
|
||||
{:number-of-hold-tokens number-of-hold-tokens})
|
||||
(i18n/label :t/you-must-hold))]
|
||||
[quo/token-requirement-list {:tokens tokens}]])))
|
|
@ -0,0 +1,22 @@
|
|||
(ns status-im2.contexts.communities.overview.events
|
||||
(:require [utils.re-frame :as rf]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(rf/defn check-permissions-to-join-community-success
|
||||
{:events [:communities/check-permissions-to-join-community-success]}
|
||||
[{:keys [db]} community-id result]
|
||||
{:db (-> db
|
||||
(assoc-in [:communities community-id :checking-permissions?] false)
|
||||
(assoc-in [:communities community-id :token-permissions-check] result))})
|
||||
|
||||
(rf/defn check-permissions-to-join-community
|
||||
{:events [:communities/check-permissions-to-join-community]}
|
||||
[{:keys [db]} community-id]
|
||||
{:db (-> db
|
||||
(assoc-in [:communities community-id :checking-permissions?] true)
|
||||
(assoc-in [:communities community-id :can-request-access?] false))
|
||||
:json-rpc/call [{:method "wakuext_checkPermissionsToJoinCommunity"
|
||||
:params [{:communityId community-id}]
|
||||
:on-success #(rf/dispatch [:communities/check-permissions-to-join-community-success
|
||||
community-id %])
|
||||
:on-error #(log/error "failed to request to join community" community-id %)}]})
|
|
@ -32,3 +32,10 @@
|
|||
:left 0
|
||||
:right 0
|
||||
:bottom 0})
|
||||
|
||||
(defn token-gated-container
|
||||
[]
|
||||
{:border-radius 16
|
||||
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80)
|
||||
:border-width 1
|
||||
:padding-top 10})
|
||||
|
|
|
@ -13,47 +13,23 @@
|
|||
[status-im2.contexts.communities.actions.community-options.view :as options]
|
||||
[quo2.components.navigation.floating-shell-button :as floating-shell-button]
|
||||
[status-im2.contexts.communities.overview.utils :as utils]
|
||||
[status-im2.common.password-authentication.view :as password-authentication]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn preview-user-list
|
||||
[user-list]
|
||||
[rn/view style/preview-user
|
||||
[quo/preview-list
|
||||
{:type :user
|
||||
:list-size (count user-list)
|
||||
:size 24}
|
||||
user-list]
|
||||
[quo/text
|
||||
{:accessibility-label :communities-screen-title
|
||||
:style {:margin-left 8}
|
||||
:size :label}
|
||||
(utils/join-existing-users-string user-list)]])
|
||||
|
||||
(defn channel-token-gating-details
|
||||
[name token-gating emoji channel-color]
|
||||
[rn/view {:height 350 :margin-top 20}
|
||||
[quo/token-gating
|
||||
{:channel {:name name
|
||||
:community-color channel-color
|
||||
:emoji emoji
|
||||
:emoji-background-color channel-color
|
||||
:on-enter-channel (fn []
|
||||
(js/alert
|
||||
"Entered channel"
|
||||
"Wuhuu!! You successfully entered the channel :)"))
|
||||
:gates token-gating}}]])
|
||||
|
||||
(defn open-channel-token-gating-details
|
||||
[name token-gating emoji channel-color]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[channel-token-gating-details name token-gating emoji channel-color])}]))
|
||||
|
||||
(defn layout-y
|
||||
[event]
|
||||
(oops/oget event "nativeEvent.layout.y"))
|
||||
(when (seq user-list)
|
||||
[rn/view style/preview-user
|
||||
[quo/preview-list
|
||||
{:type :user
|
||||
:list-size (count user-list)
|
||||
:size 24}
|
||||
user-list]
|
||||
[quo/text
|
||||
{:accessibility-label :communities-screen-title
|
||||
:style {:margin-left 8}
|
||||
:size :label}
|
||||
(utils/join-existing-users-string user-list)]]))
|
||||
|
||||
(defn add-category-height
|
||||
[categories-heights category height]
|
||||
|
@ -65,17 +41,18 @@
|
|||
[community-id category-id collapsed?]
|
||||
(rf/dispatch [:communities/toggle-collapsed-category community-id category-id (not collapsed?)]))
|
||||
|
||||
(defn layout-y
|
||||
[event]
|
||||
(oops/oget event "nativeEvent.layout.y"))
|
||||
|
||||
(defn channel-list-component
|
||||
[{:keys [on-category-layout
|
||||
community-id
|
||||
on-first-channel-height-changed]}
|
||||
[{:keys [on-category-layout community-id on-first-channel-height-changed]}
|
||||
channels-list]
|
||||
[rn/view
|
||||
{:on-layout #(on-first-channel-height-changed (+ (if platform/ios?
|
||||
0
|
||||
38)
|
||||
(int (Math/ceil (layout-y %))))
|
||||
(into #{} (map (comp :name second) channels-list)))
|
||||
{:on-layout #(on-first-channel-height-changed
|
||||
(+ (if platform/ios? 0 38)
|
||||
(int (Math/ceil (layout-y %))))
|
||||
(into #{} (map (comp :name second) channels-list)))
|
||||
:style {:margin-top 20 :flex 1}}
|
||||
(map
|
||||
(fn [[category-id {:keys [chats name collapsed?]}]]
|
||||
|
@ -123,10 +100,68 @@
|
|||
constants/community-on-request-access :request-access
|
||||
:unknown-access))
|
||||
|
||||
(defn join-gated-community
|
||||
[id]
|
||||
(rf/dispatch [:password-authentication/show
|
||||
{:content (fn [] [password-authentication/view])}
|
||||
{:label (i18n/label :t/join-open-community)
|
||||
:on-press #(rf/dispatch [:communities/request-to-join-with-password id %])}]))
|
||||
|
||||
(defn info-button
|
||||
[]
|
||||
[rn/touchable-without-feedback
|
||||
{: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 (i18n/label :t/token-gated-communities-info)]])}])}
|
||||
[rn/view
|
||||
[quo/icon :i/info {:no-color true}]]])
|
||||
|
||||
(defn token-gates
|
||||
[{:keys [id]}]
|
||||
(rf/dispatch [:communities/check-permissions-to-join-community id])
|
||||
(fn [{:keys [id community-color]}]
|
||||
(let [{:keys [can-request-access?
|
||||
number-of-hold-tokens tokens]} (rf/sub [:community/token-gated-overview id])]
|
||||
[rn/view {:style (style/token-gated-container)}
|
||||
[rn/view
|
||||
{:style {:padding-horizontal 12
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :space-between
|
||||
:flex 1}}
|
||||
[quo/text {:weight :medium}
|
||||
(if can-request-access?
|
||||
(i18n/label :t/you-eligible-to-join)
|
||||
(i18n/label :t/you-not-eligible-to-join))]
|
||||
[info-button]]
|
||||
[quo/text {:style {:padding-horizontal 12 :padding-bottom 18} :size :paragraph-2}
|
||||
(if can-request-access?
|
||||
(i18n/label :t/you-hold-number-of-hold-tokens-of-these
|
||||
{:number-of-hold-tokens number-of-hold-tokens})
|
||||
(i18n/label :t/you-must-hold))]
|
||||
[quo/token-requirement-list
|
||||
{:tokens tokens
|
||||
:padding? true}]
|
||||
[quo/button
|
||||
{:on-press #(join-gated-community id)
|
||||
:accessibility-label :join-community-button
|
||||
:override-background-color community-color
|
||||
:style {:margin-horizontal 12 :margin-top 12 :margin-bottom 12}
|
||||
:disabled (not can-request-access?)
|
||||
:before (if can-request-access? :i/unlocked :i/locked)}
|
||||
(i18n/label :t/join-open-community)]])))
|
||||
|
||||
(defn join-community
|
||||
[{:keys [joined can-join?
|
||||
community-color permissions]
|
||||
:as community} pending?]
|
||||
[{:keys [joined can-join? community-color permissions token-permissions] :as community}
|
||||
pending?]
|
||||
(let [access-type (get-access-type (:access permissions))
|
||||
unknown-access? (= access-type :unknown-access)
|
||||
invite-only? (= access-type :invite-only)
|
||||
|
@ -134,15 +169,16 @@
|
|||
node-offline? (and can-join? (not joined) pending?)]
|
||||
[:<>
|
||||
(when-not (or joined pending? invite-only? unknown-access?)
|
||||
[quo/button
|
||||
{:on-press #(rf/dispatch [:open-modal :community-requests-to-join community])
|
||||
:accessibility-label :show-request-to-join-screen-button
|
||||
:override-background-color community-color
|
||||
:style style/join-button
|
||||
:before :i/communities}
|
||||
(request-to-join-text is-open?)])
|
||||
(if token-permissions
|
||||
[token-gates community]
|
||||
[quo/button
|
||||
{:on-press #(rf/dispatch [:open-modal :community-requests-to-join community])
|
||||
:accessibility-label :show-request-to-join-screen-button
|
||||
:override-background-color community-color
|
||||
:before :i/communities}
|
||||
(request-to-join-text is-open?)]))
|
||||
|
||||
(when (and (not (or joined pending?)) (not (or is-open? node-offline?)))
|
||||
(when (and (not (or joined pending? token-permissions)) (not (or is-open? node-offline?)))
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/review-notice}
|
||||
|
@ -155,38 +191,24 @@
|
|||
:style {:margin-top 12}}
|
||||
(i18n/label :t/request-processed-after-node-online)])]))
|
||||
|
||||
(defn get-tag
|
||||
[joined]
|
||||
[quo/status-tag
|
||||
{:status {:type (if joined :positive :pending)}
|
||||
:label (if joined
|
||||
(i18n/label :t/joined)
|
||||
(i18n/label :t/pending))}])
|
||||
|
||||
(defn community-token-gating-details
|
||||
[name thumbnail-image tokens]
|
||||
[rn/view {:height 200 :margin-top 20}
|
||||
[quo/token-gating
|
||||
{:community {:name name
|
||||
:community-color colors/primary-50
|
||||
:community-avatar-img-src thumbnail-image
|
||||
:gates tokens}}]])
|
||||
(defn status-tag
|
||||
[pending? joined]
|
||||
(when (or pending? joined)
|
||||
[rn/view {:position :absolute :top 12 :right 12}
|
||||
[quo/status-tag
|
||||
{:status {:type (if joined :positive :pending)}
|
||||
:label (if joined
|
||||
(i18n/label :t/joined)
|
||||
(i18n/label :t/pending))}]]))
|
||||
|
||||
(defn add-on-press-handler
|
||||
[community-id {:keys [name emoji id locked? token-gating] :or {locked? false} :as chat}]
|
||||
[community-id {:keys [id locked?] :or {locked? false} :as chat}]
|
||||
(merge
|
||||
chat
|
||||
(if (and locked? token-gating)
|
||||
{:on-press #(open-channel-token-gating-details
|
||||
name
|
||||
token-gating
|
||||
emoji
|
||||
(colors/custom-color :pink 50))}
|
||||
|
||||
(when (and (not locked?) id)
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:chat/navigate-to-chat (str community-id id)]))}))))
|
||||
(when (and (not locked?) id)
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:chat/navigate-to-chat (str community-id id)]))})))
|
||||
|
||||
(defn add-on-press-handler-to-chats
|
||||
[community-id chats]
|
||||
|
@ -206,7 +228,8 @@
|
|||
:number-of-lines 1
|
||||
:ellipsize-mode :tail
|
||||
:weight :semi-bold
|
||||
:size :heading-1}
|
||||
:size :heading-1
|
||||
:style {:margin-top 56}}
|
||||
name])
|
||||
|
||||
(defn community-description
|
||||
|
@ -221,49 +244,20 @@
|
|||
description])
|
||||
|
||||
(defn community-content
|
||||
[{:keys [name description locked joined images
|
||||
status tokens tags id]
|
||||
[{:keys [name description joined tags id]
|
||||
:as community}
|
||||
pending?
|
||||
{:keys [on-category-layout
|
||||
on-first-channel-height-changed]}]
|
||||
(let [thumbnail-image (:thumbnail images)
|
||||
chats-by-category (rf/sub [:communities/categorized-channels id])
|
||||
users (rf/sub [:communities/users id])]
|
||||
[rn/view
|
||||
{:keys [on-category-layout on-first-channel-height-changed]}]
|
||||
(let [chats-by-category (rf/sub [:communities/categorized-channels id])]
|
||||
[:<>
|
||||
[rn/view {:padding-horizontal 20}
|
||||
(when (and (not joined)
|
||||
(not pending?)
|
||||
(= status :gated))
|
||||
[rn/view
|
||||
{:position :absolute
|
||||
:top 8
|
||||
:right 8}
|
||||
[quo/permission-tag-container
|
||||
{:locked locked
|
||||
:status status
|
||||
:tokens tokens
|
||||
:on-press #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[community-token-gating-details
|
||||
name
|
||||
thumbnail-image
|
||||
tokens])}])}]])
|
||||
(when (or pending? joined)
|
||||
[rn/view
|
||||
{:position :absolute
|
||||
:top 12
|
||||
:right 12}
|
||||
[get-tag joined]])
|
||||
[rn/view {:margin-top 56}
|
||||
[community-header name]]
|
||||
[status-tag pending? joined]
|
||||
[community-header name]
|
||||
[community-description description]
|
||||
[quo/community-stats-column :card-view]
|
||||
;; [quo/community-stats-column :card-view] not implemented
|
||||
[rn/view {:margin-top 12}]
|
||||
[quo/community-tags tags]
|
||||
[preview-user-list users]
|
||||
;;[preview-user-list users] not implemented
|
||||
[join-community community pending?]]
|
||||
[channel-list-component
|
||||
{:on-category-layout on-category-layout
|
||||
|
|
|
@ -79,29 +79,38 @@
|
|||
effect (if seed-phrase
|
||||
:multiaccount/restore-account-and-login
|
||||
:multiaccount/create-account-and-login)
|
||||
request {:displayName display-name
|
||||
:password (ethereum/sha3 (security/safe-unmask-data password))
|
||||
:mnemonic (when seed-phrase
|
||||
(security/safe-unmask-data seed-phrase))
|
||||
:imagePath (strip-file-prefix image-path)
|
||||
:customizationColor color
|
||||
:backupDisabledDataDir (native-module/backup-disabled-data-dir)
|
||||
:rootKeystoreDir (native-module/keystore-dir)
|
||||
request {:displayName display-name
|
||||
:password (ethereum/sha3 (security/safe-unmask-data
|
||||
password))
|
||||
:mnemonic (when seed-phrase
|
||||
(security/safe-unmask-data seed-phrase))
|
||||
:imagePath (strip-file-prefix image-path)
|
||||
:customizationColor color
|
||||
:backupDisabledDataDir (native-module/backup-disabled-data-dir)
|
||||
:rootKeystoreDir (native-module/keystore-dir)
|
||||
;; Temporary fix until https://github.com/status-im/status-go/issues/3024 is
|
||||
;; resolved
|
||||
:wakuV2Nameserver "1.1.1.1"
|
||||
:logLevel (when log-enabled? config/log-level)
|
||||
:logEnabled log-enabled?
|
||||
:logFilePath (native-module/log-file-directory)
|
||||
:openseaAPIKey config/opensea-api-key
|
||||
:verifyTransactionURL config/verify-transaction-url
|
||||
:verifyENSURL config/verify-ens-url
|
||||
:verifyENSContractAddress config/verify-ens-contract-address
|
||||
:verifyTransactionChainID config/verify-transaction-chain-id
|
||||
:upstreamConfig config/default-network-rpc-url
|
||||
:networkId config/default-network-id
|
||||
:currentNetwork config/default-network
|
||||
:previewPrivacy config/blank-preview?}]
|
||||
:wakuV2Nameserver "1.1.1.1"
|
||||
:logLevel (when log-enabled? config/log-level)
|
||||
:logEnabled log-enabled?
|
||||
:logFilePath (native-module/log-file-directory)
|
||||
:openseaAPIKey config/opensea-api-key
|
||||
:verifyTransactionURL config/verify-transaction-url
|
||||
:verifyENSURL config/verify-ens-url
|
||||
:verifyENSContractAddress config/verify-ens-contract-address
|
||||
:verifyTransactionChainID config/verify-transaction-chain-id
|
||||
:upstreamConfig config/default-network-rpc-url
|
||||
:networkId config/default-network-id
|
||||
:poktToken config/POKT_TOKEN
|
||||
:infuraToken config/INFURA_TOKEN
|
||||
|
||||
:alchemyOptimismMainnetToken config/ALCHEMY_OPTIMISM_MAINNET_TOKEN
|
||||
:alchemyOptimismGoerliToken config/ALCHEMY_OPTIMISM_GOERLI_TOKEN
|
||||
:alchemyArbitrumMainnetToken config/ALCHEMY_ARBITRUM_MAINNET_TOKEN
|
||||
:alchemyArbitrumGoerliToken config/ALCHEMY_ARBITRUM_GOERLI_TOKEN
|
||||
|
||||
:currentNetwork config/default-network
|
||||
:previewPrivacy config/blank-preview?}]
|
||||
{effect request
|
||||
:dispatch [:navigate-to :generating-keys]
|
||||
:db (-> db
|
||||
|
|
|
@ -1,171 +1,90 @@
|
|||
(ns status-im2.contexts.quo-preview.community.token-gating
|
||||
(:require [quo.previews.preview :as preview]
|
||||
[quo.react-native :as rn]
|
||||
[quo2.components.community.token-gating :as quo2]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.resources :as resources]))
|
||||
|
||||
(def styles
|
||||
{:container-sandbox {:flex 1
|
||||
:padding-vertical 20
|
||||
:border-top-left-radius 20
|
||||
:border-top-right-radius 20}})
|
||||
(:require [reagent.core :as reagent]
|
||||
[status-im2.common.resources :as resources]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]
|
||||
[quo2.core :as quo]))
|
||||
|
||||
(def descriptor
|
||||
[{:label "Type:"
|
||||
:key :type
|
||||
:type :select
|
||||
:options [{:key :community
|
||||
:value "Community"}
|
||||
{:key :channel
|
||||
:value "Channel"}]}
|
||||
{:label "Tokens sufficient:"
|
||||
:key :is-sufficient?
|
||||
[{:label "Tokens sufficient"
|
||||
:key :sufficient?
|
||||
:type :boolean}
|
||||
{:label "Many tokens:"
|
||||
{:label "Many tokens ?"
|
||||
:key :many-tokens?
|
||||
:type :boolean}
|
||||
{:label "Membership request denied:"
|
||||
:key :membership-request-denied?
|
||||
{:label "Loading ?"
|
||||
:key :loading?
|
||||
:type :boolean}
|
||||
{:label "Сondition ?"
|
||||
:key :condition?
|
||||
:type :boolean}
|
||||
{:label "Padding ?"
|
||||
:key :padding?
|
||||
:type :boolean}])
|
||||
|
||||
(defn join-gate-options-base
|
||||
[is-sufficient? many-tokens?]
|
||||
[sufficient? many-tokens? loading?]
|
||||
(into
|
||||
[{:token "KNC"
|
||||
:token-img-src (resources/get-token :knc)
|
||||
:amount 200
|
||||
:is-sufficient? true}
|
||||
{:token "MANA"
|
||||
:token-img-src (resources/get-token :mana)
|
||||
:amount 10
|
||||
:is-sufficient? is-sufficient?
|
||||
:is-purchasable? true}
|
||||
{:token "RARE"
|
||||
:token-img-src (resources/get-token :rare)
|
||||
:amount 10
|
||||
:is-sufficient? is-sufficient?}]
|
||||
[{:symbol "KNC"
|
||||
:img-src (resources/get-token :knc)
|
||||
:amount 200
|
||||
:sufficient? true
|
||||
:loading? loading?}
|
||||
{:symbol "MANA"
|
||||
:img-src (resources/get-token :mana)
|
||||
:amount 10
|
||||
:sufficient? sufficient?
|
||||
:purchasable? true
|
||||
:loading? loading?}
|
||||
{:symbol "RARE"
|
||||
:img-src (resources/get-token :rare)
|
||||
:amount 10
|
||||
:sufficient? sufficient?
|
||||
:loading? loading?}]
|
||||
(when many-tokens?
|
||||
[{:token "FXC"
|
||||
:token-img-src (resources/get-token :fxc)
|
||||
:amount 20
|
||||
:is-sufficient? true}
|
||||
{:token "SNT"
|
||||
:token-img-src (resources/get-token :snt)
|
||||
:amount 10000
|
||||
:is-sufficient? is-sufficient?}])))
|
||||
|
||||
(defn write-gate-options-base
|
||||
[is-sufficient?]
|
||||
[{:token "KNC"
|
||||
:token-img-src (resources/get-token :knc)
|
||||
:amount 200
|
||||
:is-sufficient? true}
|
||||
{:token "DAI"
|
||||
:token-img-src (resources/get-token :dai)
|
||||
:amount 20
|
||||
:is-purchasable? true
|
||||
:is-sufficient? is-sufficient?}
|
||||
{:token "ETH"
|
||||
:token-img-src (resources/get-token :eth)
|
||||
:amount 0.5
|
||||
:is-sufficient? is-sufficient?}])
|
||||
[{:symbol "FXC"
|
||||
:img-src (resources/get-token :fxc)
|
||||
:amount 20
|
||||
:sufficient? true
|
||||
:loading? loading?}
|
||||
{:symbol "SNT"
|
||||
:img-src (resources/get-token :snt)
|
||||
:amount 10000
|
||||
:sufficient? sufficient?
|
||||
:loading? loading?}])))
|
||||
|
||||
(defn get-mocked-props
|
||||
[props]
|
||||
(let [{:keys [type is-sufficient? many-tokens? membership-request-denied?]} props]
|
||||
(if (= type :community)
|
||||
{:community {:name "Ethereum"
|
||||
:community-color "#14044d"
|
||||
:community-avatar-img-src (resources/get-token :eth)
|
||||
:gates {:join (if
|
||||
many-tokens?
|
||||
[(join-gate-options-base is-sufficient?
|
||||
many-tokens?)
|
||||
[{:token "FXC"
|
||||
:token-img-src (resources/get-token :fxc)
|
||||
:amount 20
|
||||
:is-sufficient? true}
|
||||
{:token "USDT"
|
||||
:token-img-src (resources/get-token :usdt)
|
||||
:amount 20
|
||||
:is-sufficient? false}]]
|
||||
(join-gate-options-base is-sufficient?
|
||||
many-tokens?))}}}
|
||||
{:channel {:name "onboarding"
|
||||
:community-color (colors/custom-color :pink 50)
|
||||
:community-text-color colors/white
|
||||
:emoji "🍑"
|
||||
:emoji-background-color "#F38888"
|
||||
:on-enter-channel #(js/alert
|
||||
"Entered channel - Wuhuu!! You successfully entered the channel :)")
|
||||
:membership-request-denied? membership-request-denied?
|
||||
:gates {:read (into [{:token "KNC"
|
||||
:token-img-src (resources/get-token :knc)
|
||||
:amount 200
|
||||
:is-sufficient? true}
|
||||
{:token "MANA"
|
||||
:token-img-src (resources/get-token :mana)
|
||||
:amount 10
|
||||
:is-sufficient? is-sufficient?
|
||||
:is-purchasable? true}
|
||||
{:token "RARE"
|
||||
:token-img-src (resources/get-token :rare)
|
||||
:amount 10
|
||||
:is-sufficient? is-sufficient?}]
|
||||
(when many-tokens?
|
||||
[{:token "FXC"
|
||||
:token-img-src (resources/get-token :fxc)
|
||||
:amount 20
|
||||
:is-sufficient? true}
|
||||
{:token "SNT"
|
||||
:token-img-src (resources/get-token :snt)
|
||||
:amount 10000
|
||||
:is-sufficient? is-sufficient?}]))
|
||||
:write (if
|
||||
many-tokens?
|
||||
[(write-gate-options-base is-sufficient?)
|
||||
[{:token "FXC"
|
||||
:token-img-src (resources/get-token :fxc)
|
||||
:amount 20
|
||||
:is-sufficient? true}
|
||||
{:token "MANA"
|
||||
:token-img-src (resources/get-token :mana)
|
||||
:amount 10
|
||||
:is-sufficient? is-sufficient?}
|
||||
{:token "USDT"
|
||||
:token-img-src (resources/get-token :usdt)
|
||||
:amount 20
|
||||
:is-sufficient? false}]]
|
||||
(write-gate-options-base is-sufficient?))}}})))
|
||||
(let [{:keys [sufficient? condition? many-tokens? padding? loading?]} props]
|
||||
{:tokens
|
||||
(if condition?
|
||||
[(join-gate-options-base sufficient?
|
||||
many-tokens?
|
||||
loading?)
|
||||
[{:symbol "FXC"
|
||||
:img-src (resources/get-token :fxc)
|
||||
:amount 20
|
||||
:sufficient? true}
|
||||
{:symbol "USDT"
|
||||
:img-src (resources/get-token :usdt)
|
||||
:amount 20
|
||||
:sufficient? false}]]
|
||||
[(join-gate-options-base sufficient?
|
||||
many-tokens?
|
||||
loading?)])
|
||||
:padding? padding?}))
|
||||
|
||||
(def state
|
||||
(reagent/atom {:type :channel
|
||||
:is-sufficient? false
|
||||
:many-tokens? false
|
||||
:membership-request-denied? false}))
|
||||
(reagent/atom {:sufficient? false
|
||||
:many-tokens? false
|
||||
:condition? false
|
||||
:padding? false}))
|
||||
|
||||
(defn preview-token-gating
|
||||
[]
|
||||
(let [preview-props (get-mocked-props @state)]
|
||||
[rn/view
|
||||
{:style {:background-color (colors/theme-colors
|
||||
colors/neutral-10
|
||||
colors/neutral-80)
|
||||
:flex 1}}
|
||||
[rn/view {:style {:flex 1}}
|
||||
[rn/view
|
||||
{:style {:position :absolute
|
||||
:left 0
|
||||
:right 0
|
||||
:top 0}}
|
||||
[preview/customizer state descriptor]]]
|
||||
[rn/view {:height (if (= (:type @state) :community) 280 495) :margin-top 20}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(get styles :container-sandbox)
|
||||
{:background-color (colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-90)})}
|
||||
[quo2/token-gating preview-props]]]]))
|
||||
[rn/view {:flex 1}
|
||||
[rn/scroll-view {:style {:flex 1}}
|
||||
[preview/customizer state descriptor]]
|
||||
[rn/view {:padding-horizontal 20 :padding-vertical 20}
|
||||
[quo/token-requirement-list preview-props]]]))
|
||||
|
|
|
@ -150,7 +150,8 @@
|
|||
:options {:topBar {:visible true}}
|
||||
:component discover-card/preview-discoverd-card}
|
||||
{:name :token-gating
|
||||
:options {:topBar {:visible true}}
|
||||
:options {:insets {:bottom? true}
|
||||
:topBar {:visible true}}
|
||||
:component token-gating/preview-token-gating}]
|
||||
:counter [{:name :counter
|
||||
:options {:topBar {:visible true}}
|
||||
|
|
|
@ -27,19 +27,11 @@
|
|||
:value "1000"}
|
||||
{:key 10000
|
||||
:value "10000"}]}
|
||||
|
||||
{:label "Community Color:"
|
||||
:key :border-color
|
||||
:type :select
|
||||
:options [{:key "#00a191"
|
||||
:value "green"}
|
||||
{:key "red"
|
||||
:value "red"}]}
|
||||
{:label "Is Required:"
|
||||
:key :is-required
|
||||
{:label "Is Sufficient:"
|
||||
:key :sufficient?
|
||||
:type :boolean}
|
||||
{:label "Is Purchasable:"
|
||||
:key :is-purchasable
|
||||
:key :purchasable?
|
||||
:type :boolean}
|
||||
{:label "Token:"
|
||||
:key :token
|
||||
|
@ -54,7 +46,7 @@
|
|||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom {:size :big :value 10 :token "ETH" :is-required true :is-purchasable false})]
|
||||
(let [state (reagent/atom {:size :big :value 10 :token "ETH" :sufficient? false :purchasable? false})]
|
||||
(fn []
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view {:padding-bottom 150}
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
[utils.datetime :as datetime]
|
||||
status-im2.contexts.share.events
|
||||
status-im2.contexts.syncing.events
|
||||
status-im2.contexts.chat.events))
|
||||
status-im2.contexts.chat.events
|
||||
status-im2.common.password-authentication.events
|
||||
status-im2.contexts.communities.overview.events))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:now
|
||||
|
|
|
@ -262,17 +262,33 @@
|
|||
|
||||
categories-and-chats)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/users
|
||||
:<- [:communities]
|
||||
(fn [_ [_ _]]
|
||||
[{:full-name "Alicia K"}
|
||||
{:full-name "Marcus C"}
|
||||
{:full-name "MNO PQR"}
|
||||
{:full-name "STU VWX"}]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/collapsed-categories-for-community
|
||||
:<- [:communities/collapsed-categories]
|
||||
(fn [collapsed-categories [_ community-id]]
|
||||
(get collapsed-categories community-id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:community/token-gated-overview
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:communities/community community-id])])
|
||||
(fn [[{:keys [token-permissions-check token-permissions checking-permissions? token-images]}] _]
|
||||
{:can-request-access? (:satisfied token-permissions-check)
|
||||
:number-of-hold-tokens (reduce
|
||||
(fn [acc [_ {:keys [criteria]}]]
|
||||
(reduce #(+ %1 (if %2 1 0)) acc criteria))
|
||||
0
|
||||
(:permissions token-permissions-check))
|
||||
:tokens (map (fn [[perm-key {:keys [token_criteria]}]]
|
||||
(let [check-criteria (get-in token-permissions-check
|
||||
[:permissions perm-key :criteria])]
|
||||
(map
|
||||
(fn [{:keys [symbol amount]} sufficient?]
|
||||
{:symbol symbol
|
||||
:sufficient? (when (seq check-criteria) sufficient?)
|
||||
:loading? checking-permissions?
|
||||
:amount amount
|
||||
:img-src (get token-images symbol)})
|
||||
token_criteria
|
||||
(or check-criteria token_criteria))))
|
||||
token-permissions)}))
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
(reg-root-key-sub :waku/v2-peer-stats :peer-stats)
|
||||
(reg-root-key-sub :visibility-status-updates :visibility-status-updates)
|
||||
(reg-root-key-sub :shell/switcher-cards :shell/switcher-cards)
|
||||
(reg-root-key-sub :password-authentication :password-authentication)
|
||||
|
||||
;;NOTE this one is not related to ethereum network
|
||||
;; it is about cellular network/ wifi network
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.151.12",
|
||||
"commit-sha1": "6fa8c113821509d744b81d90dc21c1e79c575577",
|
||||
"src-sha256": "02mmhy4z6gd9xlqjhw4i4j48gd85pijyyga48if9dd3zasqkp3y1"
|
||||
"version": "v0.151.14",
|
||||
"commit-sha1": "959e3703891286853574f4974e87bd53e079e72d",
|
||||
"src-sha256": "11l9p1psl331b4vaw1694z09z9rlaps5w1cildmdgnx2pnkgcr7q"
|
||||
}
|
||||
|
|
|
@ -1447,7 +1447,7 @@
|
|||
"view-details": "View Details",
|
||||
"view-signing": "View signing phrase",
|
||||
"view-superrare": "View in SuperRare",
|
||||
"view-token-gating": "View token gating",
|
||||
"view-token-gating": "View token requirements",
|
||||
"vote-to-feature": "Vote to feature this community",
|
||||
"waiting-for-wifi": "No Wi-fi, message syncing disabled.",
|
||||
"waiting-for-wifi-change": "Settings",
|
||||
|
@ -2168,5 +2168,11 @@
|
|||
"sync-devices-error-sub-title":"Make sure both devices are powered on and connected to the internet.",
|
||||
"sync-devices-complete-title": "Device sync complete!",
|
||||
"sync-devices-complete-sub-title": "Your devices are now in sync",
|
||||
"sync-with": "Synced with"
|
||||
}
|
||||
"sync-with": "Synced with",
|
||||
"you-eligible-to-join": "You’re eligible to join",
|
||||
"you-not-eligible-to-join": "You’re not eligible to join",
|
||||
"you-hold-number-of-hold-tokens-of-these": "You hold {{number-of-hold-tokens}} of these:",
|
||||
"token-gated-communities": "Token gated communities",
|
||||
"read-more": "Read more",
|
||||
"token-gated-communities-info": "Here will be something relevant about this topic. This will help the user get more context and therefore have a better understanding of it."
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue