Communities - Token gated community fixes (#17799)
- Fix: when there are only channel token permissions, don't show the text "You hold 0 of these:" because there are no requirements to show. - Fix: do not show channel token permissions when the user wants to join a community. In other words: only "become admin", "become member", "become token master", and "become token owner" are taken in consideration. - Fix: render correct channel lock icon in 3 states (no permission, with permissions and locked and with permissions and unlocked). - Fix: Previously, before having joined a community, all channels had a lock icon closed, now the lock icon is only closed when there's a permission set, otherwise no icon is shown (the lock is never open before the user joins the community). - Fix: small UI spacing fix, only display community tags component when there's at least one tag. - Bonus fix: community Overview and Discover screens top bar had a regression, see the screenshots. Fixes https://github.com/status-im/status-mobile/issues/17267 ### Areas that may be impacted - Community overview, before and after joining a community. ### Steps to test Code tested using the Goerli network and with the testnet flag enabled in the Desktop client. Out of scope: minted tokens.
This commit is contained in:
parent
69f87ce8b0
commit
ffeb06f36c
|
@ -0,0 +1,9 @@
|
||||||
|
(ns status-im.data-store.communities
|
||||||
|
(:require [clojure.set :as set]))
|
||||||
|
|
||||||
|
(defn rpc->channel-permissions
|
||||||
|
[rpc-channels-permissions]
|
||||||
|
(update-vals rpc-channels-permissions
|
||||||
|
(fn [{:keys [viewAndPostPermissions viewOnlyPermissions]}]
|
||||||
|
{:view-only (set/rename-keys viewOnlyPermissions {:satisfied :satisfied?})
|
||||||
|
:view-and-post (set/rename-keys viewAndPostPermissions {:satisfied :satisfied?})})))
|
|
@ -0,0 +1,23 @@
|
||||||
|
(ns status-im.data-store.communities-test
|
||||||
|
(:require
|
||||||
|
[cljs.test :refer [deftest is]]
|
||||||
|
[status-im.data-store.communities :as sut]))
|
||||||
|
|
||||||
|
(def permissions
|
||||||
|
{"community-id-chat-1"
|
||||||
|
{:viewOnlyPermissions {:satisfied false
|
||||||
|
:permissions {:token-permission-id-01 {:criteria [false]}}}
|
||||||
|
:viewAndPostPermissions {:satisfied true :permissions {}}}
|
||||||
|
"community-id-chat-2"
|
||||||
|
{:viewOnlyPermissions {:satisfied true :permissions {}}
|
||||||
|
:viewAndPostPermissions {:satisfied true :permissions {}}}})
|
||||||
|
|
||||||
|
(deftest rpc->channel-permissions-test
|
||||||
|
(is (= {"community-id-chat-1"
|
||||||
|
{:view-only {:satisfied? false
|
||||||
|
:permissions {:token-permission-id-01 {:criteria [false]}}}
|
||||||
|
:view-and-post {:satisfied? true :permissions {}}}
|
||||||
|
"community-id-chat-2"
|
||||||
|
{:view-only {:satisfied? true :permissions {}}
|
||||||
|
:view-and-post {:satisfied? true :permissions {}}}}
|
||||||
|
(sut/rpc->channel-permissions permissions))))
|
|
@ -143,6 +143,14 @@
|
||||||
(def ^:const community-invitation-only-access 2)
|
(def ^:const community-invitation-only-access 2)
|
||||||
(def ^:const community-on-request-access 3)
|
(def ^:const community-on-request-access 3)
|
||||||
|
|
||||||
|
(def ^:const community-token-permission-unknown 0)
|
||||||
|
(def ^:const community-token-permission-become-admin 1)
|
||||||
|
(def ^:const community-token-permission-become-member 2)
|
||||||
|
(def ^:const community-token-permission-can-view-channel 3)
|
||||||
|
(def ^:const community-token-permission-can-view-and-post-channel 4)
|
||||||
|
(def ^:const community-token-permission-become-token-master 5)
|
||||||
|
(def ^:const community-token-permission-become-token-owner 6)
|
||||||
|
|
||||||
;; Community rules for joining
|
;; Community rules for joining
|
||||||
(def ^:const community-rule-ens-only "ens-only")
|
(def ^:const community-rule-ens-only "ens-only")
|
||||||
|
|
||||||
|
|
|
@ -206,15 +206,16 @@
|
||||||
featured-communities-count (count featured-communities)]
|
featured-communities-count (count featured-communities)]
|
||||||
(fn []
|
(fn []
|
||||||
[scroll-page/scroll-page
|
[scroll-page/scroll-page
|
||||||
{:theme theme
|
{:theme theme
|
||||||
:on-scroll #(reset! scroll-height %)
|
:on-scroll #(reset! scroll-height %)
|
||||||
:navigate-back? :true
|
:navigate-back? :true
|
||||||
:height (if (> @scroll-height 360)
|
:height (if (> @scroll-height 360)
|
||||||
208
|
208
|
||||||
148)
|
148)
|
||||||
:sticky-header [render-sticky-header
|
:background-color (colors/theme-colors colors/white colors/neutral-95)
|
||||||
{:selected-tab selected-tab
|
:sticky-header [render-sticky-header
|
||||||
:scroll-height scroll-height}]}
|
{:selected-tab selected-tab
|
||||||
|
:scroll-height scroll-height}]}
|
||||||
|
|
||||||
[render-communities
|
[render-communities
|
||||||
selected-tab
|
selected-tab
|
||||||
|
|
|
@ -1,8 +1,28 @@
|
||||||
(ns status-im2.contexts.communities.overview.events
|
(ns status-im2.contexts.communities.overview.events
|
||||||
(:require
|
(:require
|
||||||
|
[status-im.data-store.communities :as data-store]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/check-all-community-channels-permissions-success
|
||||||
|
(fn [{:keys [db]} [community-id response]]
|
||||||
|
{:db (assoc-in db
|
||||||
|
[:community-channels-permissions community-id]
|
||||||
|
(data-store/rpc->channel-permissions (:channels response)))}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/check-all-community-channels-permissions
|
||||||
|
(fn [_ [community-id]]
|
||||||
|
{:fx [[:json-rpc/call
|
||||||
|
[{:method "wakuext_checkAllCommunityChannelsPermissions"
|
||||||
|
:params [{:CommunityID community-id}]
|
||||||
|
:on-success [:communities/check-all-community-channels-permissions-success community-id]
|
||||||
|
:on-error (fn [error]
|
||||||
|
(log/error "failed to check channels permissions"
|
||||||
|
{:error error
|
||||||
|
:community-id community-id
|
||||||
|
:event
|
||||||
|
:communities/check-all-community-channels-permissions}))}]]]}))
|
||||||
|
|
||||||
(rf/defn check-permissions-to-join-community-success
|
(rf/defn check-permissions-to-join-community-success
|
||||||
{:events [:communities/check-permissions-to-join-community-success]}
|
{:events [:communities/check-permissions-to-join-community-success]}
|
||||||
[{:keys [db]} community-id result]
|
[{:keys [db]} community-id result]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(:require
|
(:require
|
||||||
[oops.core :as oops]
|
[oops.core :as oops]
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
|
[quo.foundations.colors :as colors]
|
||||||
[react-native.blur :as blur]
|
[react-native.blur :as blur]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
|
@ -82,23 +83,23 @@
|
||||||
(+ 38 (int (Math/ceil (layout-y %))))
|
(+ 38 (int (Math/ceil (layout-y %))))
|
||||||
(into #{} (map (comp :name second) channels-list)))
|
(into #{} (map (comp :name second) channels-list)))
|
||||||
:style {:margin-top 8 :flex 1}}
|
:style {:margin-top 8 :flex 1}}
|
||||||
(doall
|
(for [[category-id {:keys [chats name collapsed?]}] channels-list]
|
||||||
(for [[category-id {:keys [chats name collapsed?]}] channels-list]
|
[rn/view
|
||||||
[rn/view
|
{:key category-id
|
||||||
{:key category-id
|
;; on-layout fires only when the component re-renders, so
|
||||||
;; on-layout fires only when the component re-renders, so
|
;; in case the category hasn't changed, it will not be fired
|
||||||
;; in case the category hasn't changed, it will not be fired
|
:on-layout #(on-category-layout name (int (layout-y %)))}
|
||||||
:on-layout #(on-category-layout name (int (layout-y %)))}
|
(when-not (= constants/empty-category-id category-id)
|
||||||
(when-not (= constants/empty-category-id category-id)
|
[quo/divider-label
|
||||||
[quo/divider-label
|
{:on-press #(collapse-category community-id category-id collapsed?)
|
||||||
{:on-press #(collapse-category community-id category-id collapsed?)
|
:chevron-icon (if collapsed? :i/chevron-right :i/chevron-down)
|
||||||
:chevron-icon (if collapsed? :i/chevron-right :i/chevron-down)
|
:chevron :left}
|
||||||
:chevron :left}
|
name])
|
||||||
name])
|
(when-not collapsed?
|
||||||
(when-not collapsed?
|
[rn/view {:style {:padding-horizontal 8 :padding-bottom 8}}
|
||||||
(into [rn/view {:style {:padding-horizontal 8 :padding-bottom 8}}]
|
(for [chat chats]
|
||||||
(map #(channel-chat-item community-id community-color %))
|
^{:key (:id chat)}
|
||||||
chats))]))])
|
[channel-chat-item community-id community-color chat])])])])
|
||||||
|
|
||||||
(defn get-access-type
|
(defn get-access-type
|
||||||
[access]
|
[access]
|
||||||
|
@ -151,11 +152,12 @@
|
||||||
(i18n/label :t/you-eligible-to-join)
|
(i18n/label :t/you-eligible-to-join)
|
||||||
(i18n/label :t/you-not-eligible-to-join))]
|
(i18n/label :t/you-not-eligible-to-join))]
|
||||||
[info-button]]
|
[info-button]]
|
||||||
[quo/text {:style {:padding-horizontal 12 :padding-bottom 18} :size :paragraph-2}
|
(when (pos? number-of-hold-tokens)
|
||||||
(if can-request-access?
|
[quo/text {:style {:padding-horizontal 12 :padding-bottom 18} :size :paragraph-2}
|
||||||
(i18n/label :t/you-hold-number-of-hold-tokens-of-these
|
(if can-request-access?
|
||||||
{:number-of-hold-tokens number-of-hold-tokens})
|
(i18n/label :t/you-hold-number-of-hold-tokens-of-these
|
||||||
(i18n/label :t/you-must-hold))]
|
{:number-of-hold-tokens number-of-hold-tokens})
|
||||||
|
(i18n/label :t/you-must-hold))])
|
||||||
[quo/token-requirement-list
|
[quo/token-requirement-list
|
||||||
{:tokens tokens
|
{:tokens tokens
|
||||||
:padding? true}]
|
:padding? true}]
|
||||||
|
@ -204,15 +206,18 @@
|
||||||
|
|
||||||
(defn add-handlers
|
(defn add-handlers
|
||||||
[community-id
|
[community-id
|
||||||
|
joined
|
||||||
{:keys [id locked?]
|
{:keys [id locked?]
|
||||||
:or {locked? false}
|
:or {locked? false}
|
||||||
:as chat}]
|
:as chat}]
|
||||||
(merge
|
(merge
|
||||||
chat
|
chat
|
||||||
(when (and (not locked?) id)
|
(when (and (not locked?) id)
|
||||||
{:on-press (fn []
|
{:on-press (when joined
|
||||||
(rf/dispatch [:dismiss-keyboard])
|
(fn []
|
||||||
(debounce/dispatch-and-chill [:chat/navigate-to-chat (str community-id id)] 1000))
|
(rf/dispatch [:dismiss-keyboard])
|
||||||
|
(debounce/dispatch-and-chill [:chat/navigate-to-chat (str community-id id)]
|
||||||
|
1000)))
|
||||||
:on-long-press #(rf/dispatch
|
:on-long-press #(rf/dispatch
|
||||||
[:show-bottom-sheet
|
[:show-bottom-sheet
|
||||||
{:content (fn []
|
{:content (fn []
|
||||||
|
@ -220,12 +225,12 @@
|
||||||
:community-id community-id})))
|
:community-id community-id})))
|
||||||
|
|
||||||
(defn add-handlers-to-chats
|
(defn add-handlers-to-chats
|
||||||
[community-id chats]
|
[community-id joined chats]
|
||||||
(mapv (partial add-handlers community-id) chats))
|
(mapv (partial add-handlers community-id joined) chats))
|
||||||
|
|
||||||
(defn add-handlers-to-categorized-chats
|
(defn add-handlers-to-categorized-chats
|
||||||
[community-id categorized-chats]
|
[community-id categorized-chats joined]
|
||||||
(let [add-on-press (partial add-handlers-to-chats community-id)]
|
(let [add-on-press (partial add-handlers-to-chats community-id joined)]
|
||||||
(map (fn [[category v]]
|
(map (fn [[category v]]
|
||||||
[category (update v :chats add-on-press)])
|
[category (update v :chats add-on-press)])
|
||||||
categorized-chats)))
|
categorized-chats)))
|
||||||
|
@ -248,31 +253,32 @@
|
||||||
:description-accessibility-label :community-description}])
|
:description-accessibility-label :community-description}])
|
||||||
|
|
||||||
(defn community-content
|
(defn community-content
|
||||||
[{:keys [name description joined images tags color id]
|
[community]
|
||||||
:as community}
|
(rf/dispatch [:communities/check-all-community-channels-permissions (:id community)])
|
||||||
pending?
|
(fn [{:keys [name description joined images tags color id] :as community}
|
||||||
{:keys [on-category-layout
|
pending?
|
||||||
collapsed?
|
{:keys [on-category-layout
|
||||||
on-first-channel-height-changed]}]
|
collapsed?
|
||||||
(let [chats-by-category (rf/sub [:communities/categorized-channels id])]
|
on-first-channel-height-changed]}]
|
||||||
[:<>
|
(let [chats-by-category (rf/sub [:communities/categorized-channels id])]
|
||||||
[rn/view {:style style/community-content-container}
|
[:<>
|
||||||
(when-not collapsed?
|
[rn/view {:style style/community-content-container}
|
||||||
[status-tag pending? joined])
|
(when-not collapsed?
|
||||||
[community-header name (when collapsed? (get-in images [:thumbnail :uri]))
|
[status-tag pending? joined])
|
||||||
(when-not collapsed? description)]
|
[community-header name (when collapsed? (get-in images [:thumbnail :uri]))
|
||||||
(when-not collapsed?
|
(when-not collapsed? description)]
|
||||||
[quo/community-tags
|
(when (and (seq tags) (not collapsed?))
|
||||||
{:tags tags
|
[quo/community-tags
|
||||||
:last-item-style style/last-community-tag
|
{:tags tags
|
||||||
:container-style style/community-tag-container}])
|
:last-item-style style/last-community-tag
|
||||||
[join-community community pending?]]
|
:container-style style/community-tag-container}])
|
||||||
[channel-list-component
|
[join-community community pending?]]
|
||||||
{:on-category-layout on-category-layout
|
[channel-list-component
|
||||||
:community-id id
|
{:on-category-layout on-category-layout
|
||||||
:community-color color
|
:community-id id
|
||||||
:on-first-channel-height-changed on-first-channel-height-changed}
|
:community-color color
|
||||||
(add-handlers-to-categorized-chats id chats-by-category)]]))
|
:on-first-channel-height-changed on-first-channel-height-changed}
|
||||||
|
(add-handlers-to-categorized-chats id chats-by-category joined)]])))
|
||||||
|
|
||||||
(defn sticky-category-header
|
(defn sticky-category-header
|
||||||
[_]
|
[_]
|
||||||
|
@ -319,24 +325,25 @@
|
||||||
collapsed? (and initial-joined? (:joined community))
|
collapsed? (and initial-joined? (:joined community))
|
||||||
overlay-shown? (boolean (:sheets (rf/sub [:bottom-sheet])))]
|
overlay-shown? (boolean (:sheets (rf/sub [:bottom-sheet])))]
|
||||||
[scroll-page/scroll-page
|
[scroll-page/scroll-page
|
||||||
{:cover-image cover
|
{:cover-image cover
|
||||||
:collapsed? collapsed?
|
:collapsed? collapsed?
|
||||||
:logo logo
|
:logo logo
|
||||||
:name name
|
:name name
|
||||||
:on-scroll #(reset! scroll-height %)
|
:on-scroll #(reset! scroll-height %)
|
||||||
:navigate-back? true
|
:navigate-back? true
|
||||||
:height 148
|
:height 148
|
||||||
:overlay-shown? overlay-shown?
|
:overlay-shown? overlay-shown?
|
||||||
:page-nav-props {:type :community
|
:background-color (colors/theme-colors colors/white colors/neutral-95)
|
||||||
:right-side (page-nav-right-section-buttons id)
|
:page-nav-props {:type :community
|
||||||
:community-name name
|
:right-side (page-nav-right-section-buttons id)
|
||||||
:community-logo logo}
|
:community-name name
|
||||||
:sticky-header [sticky-category-header
|
:community-logo logo}
|
||||||
{:enabled (> @scroll-height @first-channel-height)
|
:sticky-header [sticky-category-header
|
||||||
:label (pick-first-category-by-height
|
{:enabled (> @scroll-height @first-channel-height)
|
||||||
@scroll-height
|
:label (pick-first-category-by-height
|
||||||
@first-channel-height
|
@scroll-height
|
||||||
@categories-heights)}]}
|
@first-channel-height
|
||||||
|
@categories-heights)}]}
|
||||||
[community-content
|
[community-content
|
||||||
community
|
community
|
||||||
pending?
|
pending?
|
||||||
|
|
|
@ -204,14 +204,42 @@
|
||||||
(sort-by :position)
|
(sort-by :position)
|
||||||
(into []))))
|
(into []))))
|
||||||
|
|
||||||
(defn reduce-over-categories
|
(defn- get-chat-lock-state
|
||||||
|
"Returns the chat lock state.
|
||||||
|
|
||||||
|
- Nil: no lock (there are no permissions for the chat)
|
||||||
|
- True: locked (there are permissions and can-post? is false)
|
||||||
|
- False: unlocked (there are permissions and can-post? is true)"
|
||||||
|
[community-id channels-permissions {chat-id :id}]
|
||||||
|
(let [composite-key (keyword (str community-id chat-id))
|
||||||
|
permissions (get channels-permissions composite-key)
|
||||||
|
{view-only-satisfied? :satisfied?
|
||||||
|
view-only-permissions :permissions} (:view-only permissions)
|
||||||
|
{view-and-post-satisfied? :satisfied?
|
||||||
|
view-and-post-permissions :permissions} (:view-and-post permissions)
|
||||||
|
can-access? (or (and (seq view-only-permissions)
|
||||||
|
view-only-satisfied?)
|
||||||
|
(and (seq view-and-post-permissions)
|
||||||
|
view-and-post-satisfied?))]
|
||||||
|
(if (and (empty? view-only-permissions)
|
||||||
|
(empty? view-and-post-permissions))
|
||||||
|
nil
|
||||||
|
(not can-access?))))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:communities/community-channels-permissions
|
||||||
|
:<- [:communities/channels-permissions]
|
||||||
|
(fn [channel-permissions [_ community-id]]
|
||||||
|
(get channel-permissions community-id)))
|
||||||
|
|
||||||
|
(defn- reduce-over-categories
|
||||||
[community-id
|
[community-id
|
||||||
joined
|
|
||||||
categories
|
categories
|
||||||
collapsed-categories
|
collapsed-categories
|
||||||
full-chats-data]
|
full-chats-data
|
||||||
|
channels-permissions]
|
||||||
(fn [acc
|
(fn [acc
|
||||||
[_ {:keys [name categoryID position id emoji can-post?]}]]
|
[_ {:keys [name categoryID position id emoji] :as chat}]]
|
||||||
(let [category-id (if (seq categoryID) categoryID constants/empty-category-id)
|
(let [category-id (if (seq categoryID) categoryID constants/empty-category-id)
|
||||||
{:keys [unviewed-messages-count
|
{:keys [unviewed-messages-count
|
||||||
unviewed-mentions-count
|
unviewed-mentions-count
|
||||||
|
@ -227,40 +255,40 @@
|
||||||
:collapsed? (get collapsed-categories
|
:collapsed? (get collapsed-categories
|
||||||
category-id)
|
category-id)
|
||||||
:chats [])))
|
:chats [])))
|
||||||
chat {:name name
|
categorized-chat {:name name
|
||||||
:emoji emoji
|
:emoji emoji
|
||||||
:muted? muted
|
:muted? muted
|
||||||
:unread-messages? (pos? unviewed-messages-count)
|
:unread-messages? (pos? unviewed-messages-count)
|
||||||
:position position
|
:position position
|
||||||
:mentions-count (or unviewed-mentions-count 0)
|
:mentions-count (or unviewed-mentions-count 0)
|
||||||
:locked? (or (not joined)
|
:locked? (get-chat-lock-state community-id
|
||||||
(not can-post?))
|
channels-permissions
|
||||||
|
chat)
|
||||||
:id id}]
|
:id id}]
|
||||||
(update-in acc-with-category [category-id :chats] conj chat))))
|
(update-in acc-with-category [category-id :chats] conj categorized-chat))))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:communities/categorized-channels
|
:communities/categorized-channels
|
||||||
(fn [[_ community-id]]
|
(fn [[_ community-id]]
|
||||||
[(re-frame/subscribe [:communities/community community-id])
|
[(re-frame/subscribe [:communities/community community-id])
|
||||||
(re-frame/subscribe [:chats/chats])
|
(re-frame/subscribe [:chats/chats])
|
||||||
(re-frame/subscribe [:communities/collapsed-categories-for-community community-id])])
|
(re-frame/subscribe [:communities/collapsed-categories-for-community community-id])
|
||||||
(fn [[{:keys [joined categories chats]} full-chats-data collapsed-categories] [_ community-id]]
|
(re-frame/subscribe [:communities/community-channels-permissions community-id])])
|
||||||
|
(fn [[{:keys [categories chats]} full-chats-data collapsed-categories
|
||||||
|
channels-permissions]
|
||||||
|
[_ community-id]]
|
||||||
(let [reduce-fn (reduce-over-categories
|
(let [reduce-fn (reduce-over-categories
|
||||||
community-id
|
community-id
|
||||||
joined
|
|
||||||
categories
|
categories
|
||||||
collapsed-categories
|
collapsed-categories
|
||||||
full-chats-data)
|
full-chats-data
|
||||||
|
channels-permissions)
|
||||||
categories-and-chats
|
categories-and-chats
|
||||||
(->>
|
(->> chats
|
||||||
chats
|
(reduce reduce-fn {})
|
||||||
(reduce
|
(sort-by (comp :position second))
|
||||||
reduce-fn
|
(map (fn [[k v]]
|
||||||
{})
|
[k (update v :chats #(sort-by :position %))])))]
|
||||||
(sort-by (comp :position second))
|
|
||||||
(map (fn [[k v]]
|
|
||||||
[k (update v :chats #(sort-by :position %))])))]
|
|
||||||
|
|
||||||
categories-and-chats)))
|
categories-and-chats)))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
|
@ -280,19 +308,21 @@
|
||||||
(reduce #(+ %1 (if %2 1 0)) acc criteria))
|
(reduce #(+ %1 (if %2 1 0)) acc criteria))
|
||||||
0
|
0
|
||||||
(:permissions token-permissions-check))
|
(:permissions token-permissions-check))
|
||||||
:tokens (map (fn [[perm-key {:keys [token_criteria]}]]
|
:tokens (->> token-permissions
|
||||||
(let [check-criteria (get-in token-permissions-check
|
(filter (fn [[_ {:keys [type]}]]
|
||||||
[:permissions perm-key :criteria])]
|
(= type constants/community-token-permission-become-member)))
|
||||||
(map
|
(map (fn [[perm-key {:keys [token_criteria]}]]
|
||||||
(fn [{sym :symbol amount :amount} sufficient?]
|
(let [check-criteria (get-in token-permissions-check
|
||||||
{:symbol sym
|
[:permissions perm-key :criteria])]
|
||||||
:sufficient? (when (seq check-criteria) sufficient?)
|
(map
|
||||||
:loading? checking-permissions?
|
(fn [{sym :symbol amount :amount} sufficient?]
|
||||||
:amount amount
|
{:symbol sym
|
||||||
:img-src (get token-images sym)})
|
:sufficient? (when (seq check-criteria) sufficient?)
|
||||||
token_criteria
|
:loading? checking-permissions?
|
||||||
(or check-criteria token_criteria))))
|
:amount amount
|
||||||
token-permissions)}))
|
:img-src (get token-images sym)})
|
||||||
|
token_criteria
|
||||||
|
(or check-criteria token_criteria))))))}))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:community/images
|
:community/images
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
(ns status-im2.subs.communities-test
|
(ns status-im2.subs.communities-test
|
||||||
(:require
|
(:require
|
||||||
[cljs.test :refer [is testing use-fixtures]]
|
[cljs.test :refer [is testing]]
|
||||||
[re-frame.db :as rf-db]
|
[re-frame.db :as rf-db]
|
||||||
[status-im2.constants :as constants]
|
[status-im2.constants :as constants]
|
||||||
status-im2.subs.communities
|
status-im2.subs.communities
|
||||||
|
@ -8,9 +8,6 @@
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(use-fixtures :each
|
|
||||||
{:before #(reset! rf-db/app-db {})})
|
|
||||||
|
|
||||||
(def community-id "0x1")
|
(def community-id "0x1")
|
||||||
|
|
||||||
(h/deftest-sub :communities
|
(h/deftest-sub :communities
|
||||||
|
@ -123,7 +120,7 @@
|
||||||
:position 3
|
:position 3
|
||||||
:emoji nil
|
:emoji nil
|
||||||
:muted? nil
|
:muted? nil
|
||||||
:locked? false
|
:locked? nil
|
||||||
:id "0x3"
|
:id "0x3"
|
||||||
:unread-messages? false
|
:unread-messages? false
|
||||||
:mentions-count 0}]}]
|
:mentions-count 0}]}]
|
||||||
|
@ -136,7 +133,7 @@
|
||||||
:emoji nil
|
:emoji nil
|
||||||
:position 1
|
:position 1
|
||||||
:muted? nil
|
:muted? nil
|
||||||
:locked? false
|
:locked? nil
|
||||||
:id "0x1"
|
:id "0x1"
|
||||||
:unread-messages? false
|
:unread-messages? false
|
||||||
:mentions-count 0}
|
:mentions-count 0}
|
||||||
|
@ -144,11 +141,111 @@
|
||||||
:emoji nil
|
:emoji nil
|
||||||
:position 2
|
:position 2
|
||||||
:muted? nil
|
:muted? nil
|
||||||
:locked? true
|
:locked? nil
|
||||||
:id "0x2"
|
:id "0x2"
|
||||||
:unread-messages? false
|
:unread-messages? false
|
||||||
:mentions-count 0}]}]]
|
:mentions-count 0}]}]]
|
||||||
(rf/sub [sub-name "0x1"]))))
|
(rf/sub [sub-name "0x1"]))))
|
||||||
|
|
||||||
|
(testing "Channels with categories and token permissions"
|
||||||
|
(swap! rf-db/app-db assoc
|
||||||
|
:community-channels-permissions
|
||||||
|
{community-id
|
||||||
|
{(keyword (str community-id "0x100"))
|
||||||
|
{:view-only {:satisfied? false
|
||||||
|
:permissions {:token-permission-id-01 {:criteria [false]}}}
|
||||||
|
:view-and-post {:satisfied? true :permissions {}}}
|
||||||
|
(keyword (str community-id "0x200"))
|
||||||
|
{:view-only {:satisfied? true :permissions {}}
|
||||||
|
:view-and-post {:satisfied? true :permissions {}}}
|
||||||
|
(keyword (str community-id "0x300"))
|
||||||
|
{:view-only {:satisfied? false :permissions {}}
|
||||||
|
:view-and-post {:satisfied? true
|
||||||
|
:permissions {:token-permission-id-03 {:criteria [true]}}}}
|
||||||
|
(keyword (str community-id "0x400"))
|
||||||
|
{:view-only {:satisfied? true
|
||||||
|
:permissions {}}
|
||||||
|
:view-and-post {:satisfied? false
|
||||||
|
:permissions {:token-permission-id-04 {:criteria [false]}}}}}}
|
||||||
|
|
||||||
|
:communities
|
||||||
|
{community-id {:id community-id
|
||||||
|
:chats {"0x100" {:id "0x100"
|
||||||
|
:position 1
|
||||||
|
:name "chat1"
|
||||||
|
:muted? nil
|
||||||
|
:categoryID "1"
|
||||||
|
:can-post? false}
|
||||||
|
"0x200" {:id "0x200"
|
||||||
|
:position 2
|
||||||
|
:name "chat2"
|
||||||
|
:muted? nil
|
||||||
|
:categoryID "1"
|
||||||
|
:can-post? false}
|
||||||
|
"0x300" {:id "0x300"
|
||||||
|
:position 3
|
||||||
|
:name "chat3"
|
||||||
|
:muted? nil
|
||||||
|
:categoryID "2"
|
||||||
|
:can-post? true}
|
||||||
|
"0x400" {:id "0x400"
|
||||||
|
:position 4
|
||||||
|
:name "chat4"
|
||||||
|
:muted? nil
|
||||||
|
:categoryID "2"
|
||||||
|
:can-post? true}}
|
||||||
|
:categories {"1" {:id "1"
|
||||||
|
:position 2
|
||||||
|
:name "category1"}
|
||||||
|
"2" {:id "2"
|
||||||
|
:position 1
|
||||||
|
:name "category2"}}
|
||||||
|
:joined true}})
|
||||||
|
(is
|
||||||
|
(= [["2"
|
||||||
|
{:id "2"
|
||||||
|
:name "category2"
|
||||||
|
:collapsed? nil
|
||||||
|
:position 1
|
||||||
|
:chats [{:name "chat3"
|
||||||
|
:position 3
|
||||||
|
:emoji nil
|
||||||
|
:muted? nil
|
||||||
|
:locked? false
|
||||||
|
:id "0x300"
|
||||||
|
:unread-messages? false
|
||||||
|
:mentions-count 0}
|
||||||
|
{:name "chat4"
|
||||||
|
:position 4
|
||||||
|
:emoji nil
|
||||||
|
:muted? nil
|
||||||
|
:locked? true
|
||||||
|
:id "0x400"
|
||||||
|
:unread-messages? false
|
||||||
|
:mentions-count 0}]}]
|
||||||
|
["1"
|
||||||
|
{:id "1"
|
||||||
|
:name "category1"
|
||||||
|
:collapsed? nil
|
||||||
|
:position 2
|
||||||
|
:chats [{:name "chat1"
|
||||||
|
:emoji nil
|
||||||
|
:position 1
|
||||||
|
:muted? nil
|
||||||
|
:locked? true
|
||||||
|
:id "0x100"
|
||||||
|
:unread-messages? false
|
||||||
|
:mentions-count 0}
|
||||||
|
{:name "chat2"
|
||||||
|
:emoji nil
|
||||||
|
:position 2
|
||||||
|
:muted? nil
|
||||||
|
:locked? nil
|
||||||
|
:id "0x200"
|
||||||
|
:unread-messages? false
|
||||||
|
:mentions-count 0}]}]]
|
||||||
|
(rf/sub [sub-name "0x1"]))))
|
||||||
|
|
||||||
(testing "Channels without categories"
|
(testing "Channels without categories"
|
||||||
(swap! rf-db/app-db assoc
|
(swap! rf-db/app-db assoc
|
||||||
:communities
|
:communities
|
||||||
|
@ -183,7 +280,7 @@
|
||||||
:chats [{:name "chat3"
|
:chats [{:name "chat3"
|
||||||
:emoji nil
|
:emoji nil
|
||||||
:position 3
|
:position 3
|
||||||
:locked? false
|
:locked? nil
|
||||||
:muted? nil
|
:muted? nil
|
||||||
:id "0x3"
|
:id "0x3"
|
||||||
:unread-messages? false
|
:unread-messages? false
|
||||||
|
@ -196,7 +293,7 @@
|
||||||
:chats [{:name "chat1"
|
:chats [{:name "chat1"
|
||||||
:emoji nil
|
:emoji nil
|
||||||
:position 1
|
:position 1
|
||||||
:locked? false
|
:locked? nil
|
||||||
:muted? nil
|
:muted? nil
|
||||||
:id "0x1"
|
:id "0x1"
|
||||||
:unread-messages? false
|
:unread-messages? false
|
||||||
|
@ -204,18 +301,21 @@
|
||||||
{:name "chat2"
|
{:name "chat2"
|
||||||
:emoji nil
|
:emoji nil
|
||||||
:position 2
|
:position 2
|
||||||
:locked? true
|
:locked? nil
|
||||||
:id "0x2"
|
:id "0x2"
|
||||||
:muted? nil
|
:muted? nil
|
||||||
:unread-messages? false
|
:unread-messages? false
|
||||||
:mentions-count 0}]}]]
|
:mentions-count 0}]}]]
|
||||||
(rf/sub [sub-name "0x1"]))))
|
(rf/sub [sub-name "0x1"]))))
|
||||||
|
|
||||||
(testing "Unread messages"
|
(testing "Unread messages"
|
||||||
(swap! rf-db/app-db assoc
|
(swap! rf-db/app-db assoc
|
||||||
:communities
|
:communities
|
||||||
{"0x1" {:id "0x1"
|
{"0x1" {:id "0x1"
|
||||||
:chats {"0x1" {:id "0x1" :position 1 :name "chat1" :categoryID "1" :can-post? true}
|
:chats {"0x1"
|
||||||
"0x2" {:id "0x2" :position 2 :name "chat2" :categoryID "1" :can-post? false}}
|
{:id "0x1" :position 1 :name "chat1" :categoryID "1" :can-post? true}
|
||||||
|
"0x2"
|
||||||
|
{:id "0x2" :position 2 :name "chat2" :categoryID "1" :can-post? false}}
|
||||||
:categories {"1" {:id "1" :name "category1"}}
|
:categories {"1" {:id "1" :name "category1"}}
|
||||||
:joined true}}
|
:joined true}}
|
||||||
:chats
|
:chats
|
||||||
|
@ -229,7 +329,7 @@
|
||||||
:chats [{:name "chat1"
|
:chats [{:name "chat1"
|
||||||
:emoji nil
|
:emoji nil
|
||||||
:position 1
|
:position 1
|
||||||
:locked? false
|
:locked? nil
|
||||||
:id "0x1"
|
:id "0x1"
|
||||||
:muted? nil
|
:muted? nil
|
||||||
:unread-messages? true
|
:unread-messages? true
|
||||||
|
@ -237,7 +337,7 @@
|
||||||
{:name "chat2"
|
{:name "chat2"
|
||||||
:emoji nil
|
:emoji nil
|
||||||
:position 2
|
:position 2
|
||||||
:locked? true
|
:locked? nil
|
||||||
:muted? nil
|
:muted? nil
|
||||||
:id "0x2"
|
:id "0x2"
|
||||||
:unread-messages? false
|
:unread-messages? false
|
||||||
|
@ -276,3 +376,86 @@
|
||||||
:community-id-2 {:id :request-id-2}})
|
:community-id-2 {:id :request-id-2}})
|
||||||
(is (= :request-id-1
|
(is (= :request-id-1
|
||||||
(rf/sub [sub-name :community-id-1])))))
|
(rf/sub [sub-name :community-id-1])))))
|
||||||
|
|
||||||
|
(h/deftest-sub :community/token-gated-overview
|
||||||
|
[sub-name]
|
||||||
|
(let
|
||||||
|
[checking-permissions? true
|
||||||
|
token-image-eth "data:image/jpeg;base64,/9j/2w"
|
||||||
|
community {:id community-id
|
||||||
|
:checking-permissions? checking-permissions?
|
||||||
|
:permissions {:access 3}
|
||||||
|
:token-images {"ETH" token-image-eth}
|
||||||
|
:token-permissions [[:permission-id-01
|
||||||
|
{:id "permission-id-01"
|
||||||
|
:type constants/community-token-permission-can-view-channel
|
||||||
|
:token_criteria [{:contract_addresses {:5 "0x0"}
|
||||||
|
:type 1
|
||||||
|
:symbol "SNT"
|
||||||
|
:amount "0.002"
|
||||||
|
:decimals 18}]
|
||||||
|
:chat_ids [(str community-id
|
||||||
|
"89f98a1e-6776-4e5f-8626-8ab9f855253f")]}]
|
||||||
|
[:permission-id-02
|
||||||
|
{:id "permission-id-02"
|
||||||
|
:type constants/community-token-permission-become-admin
|
||||||
|
:token_criteria [{:contract_addresses {:5 "0x0"}
|
||||||
|
:type 1
|
||||||
|
:symbol "DAI"
|
||||||
|
:amount "5.0"
|
||||||
|
:decimals 18}]
|
||||||
|
:chat_ids [(str community-id
|
||||||
|
"89f98a1e-6776-4e5f-8626-8ab9f855253f")]}]
|
||||||
|
[:permission-id-03
|
||||||
|
{:id "permission-id-03"
|
||||||
|
:type constants/community-token-permission-become-member
|
||||||
|
:token_criteria [{:contract_addresses {:5 "0x0"}
|
||||||
|
:type 1
|
||||||
|
:symbol "ETH"
|
||||||
|
:amount "0.001"
|
||||||
|
:decimals 18}]}]]
|
||||||
|
:name "Community super name"
|
||||||
|
:chats {"89f98a1e-6776-4e5f-8626-8ab9f855253f"
|
||||||
|
{:description "x"
|
||||||
|
:emoji "🎲"
|
||||||
|
:permissions {:access 1}
|
||||||
|
:color "#88B0FF"
|
||||||
|
:name "random"
|
||||||
|
:categoryID "0c3c64e7-d56e-439b-a3fb-a946d83cb056"
|
||||||
|
:id "89f98a1e-6776-4e5f-8626-8ab9f855253f"
|
||||||
|
:position 4
|
||||||
|
:can-post? false
|
||||||
|
:members {"0x04" {"roles" [1]}}}
|
||||||
|
"a076358e-4638-470e-a3fb-584d0a542ce6"
|
||||||
|
{:description "General channel for the community"
|
||||||
|
:emoji "🐷 "
|
||||||
|
:permissions {:access 1}
|
||||||
|
:color "#4360DF"
|
||||||
|
:name "general"
|
||||||
|
:categoryID "0c3c64e7-d56e-439b-a3fb-a946d83cb056"
|
||||||
|
:id "a076358e-4638-470e-a3fb-584d0a542ce6"
|
||||||
|
:position 0
|
||||||
|
:can-post? false
|
||||||
|
:members {"0x04" {"roles" [1]}}}}
|
||||||
|
:token-permissions-check {:satisfied true
|
||||||
|
:permissions
|
||||||
|
{:a3dd5b6b-d93b-452c-b22a-09a8f42ec566 {:criteria [true false
|
||||||
|
true]}}
|
||||||
|
:validCombinations
|
||||||
|
[{:address "0xd722eaa60dc73e334b588d34ba66a3b27e537783"
|
||||||
|
:chainIds nil}
|
||||||
|
{:address "0x738d3146831c5871fa15872b409e8f360e341784"
|
||||||
|
:chainIds [5 420]}]}
|
||||||
|
:members {"0x04" {"roles" [1]}}
|
||||||
|
:can-request-access? false
|
||||||
|
:outroMessage "bla"
|
||||||
|
:verified false}]
|
||||||
|
(swap! rf-db/app-db assoc-in [:communities community-id] community)
|
||||||
|
(is (= {:can-request-access? true
|
||||||
|
:number-of-hold-tokens 2
|
||||||
|
:tokens [[{:symbol "ETH"
|
||||||
|
:amount "0.001"
|
||||||
|
:sufficient? nil
|
||||||
|
:loading? checking-permissions?
|
||||||
|
:img-src token-image-eth}]]}
|
||||||
|
(rf/sub [sub-name community-id])))))
|
||||||
|
|
|
@ -136,6 +136,7 @@
|
||||||
(reg-root-key-sub :communities :communities)
|
(reg-root-key-sub :communities :communities)
|
||||||
(reg-root-key-sub :communities/create :communities/create)
|
(reg-root-key-sub :communities/create :communities/create)
|
||||||
(reg-root-key-sub :communities/create-channel :communities/create-channel)
|
(reg-root-key-sub :communities/create-channel :communities/create-channel)
|
||||||
|
(reg-root-key-sub :communities/channels-permissions :community-channels-permissions)
|
||||||
(reg-root-key-sub :communities/requests-to-join :communities/requests-to-join)
|
(reg-root-key-sub :communities/requests-to-join :communities/requests-to-join)
|
||||||
(reg-root-key-sub :communities/community-id-input :communities/community-id-input)
|
(reg-root-key-sub :communities/community-id-input :communities/community-id-input)
|
||||||
(reg-root-key-sub :communities/resolve-community-info :communities/resolve-community-info)
|
(reg-root-key-sub :communities/resolve-community-info :communities/resolve-community-info)
|
||||||
|
|
Loading…
Reference in New Issue