add Non Token Gated - Manual Approval Required flow (#14513)

chore: add flow for closed community overview page
This commit is contained in:
Jamie Caprani 2022-12-27 00:05:03 +00:00 committed by GitHub
parent 99f7788c22
commit aca8c9250f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 220 additions and 137 deletions

View File

@ -1,12 +1,15 @@
(ns quo2.components.community.community-card-view
(:require [quo2.components.community.community-view :as community-view]
[quo2.components.community.icon :as icon]
[quo2.components.community.style :as style]
[react-native.core :as rn]))
(defn community-card-view-item
[{:keys [name description locked
[{:keys [name description locked images
status tokens cover tags width]} on-press]
[rn/touchable-opacity {:on-press on-press}
[rn/touchable-opacity
{:accessibility-label :community-card-item
:on-press on-press}
[rn/view {:style (style/community-card 20)}
[rn/view
{:style {:width width
@ -22,9 +25,9 @@
{:flex 1
:border-radius 20}}]]
[rn/view (style/card-view-content-container 12)
[rn/view (style/card-view-chat-icon 48)]
;;TODO new pure component based on quo2 should be implemented without status-im usage
;[communities.icon/community-icon-redesign community 48]]
[rn/view (style/card-view-chat-icon 48)
[icon/community-icon {:images images} 48]]
(when (= status :gated)
[rn/view (style/permission-tag-styles)
[community-view/permission-tag-container

View File

@ -0,0 +1,11 @@
(ns quo2.components.community.icon
(:require [react-native.core :as rn]))
(defn community-icon [{:keys [images]} size]
(let [thumbnail-image (get-in images [:thumbnail :uri])]
[rn/image {:source {:uri thumbnail-image}
:style {:border-radius 50
:border-width 0
:border-color :transparent
:width size
:height size}}]))

View File

@ -23,10 +23,10 @@
colors/neutral-20
colors/neutral-70)})}
[selectors/checkbox
{:on-change on-change}]
[text/text
{:accessibility-label accessibility-label
:size :paragraph-2
:style {:margin-left 8}}
:on-change on-change}]
[text/text
{:size :paragraph-2
:style {:margin-left 8}}
label]])

View File

@ -69,9 +69,10 @@
(defn checkbox
[{:keys [default-checked?]}]
(let [checked? (reagent/atom (or default-checked? false))]
(fn [{:keys [on-change disabled? blurred-background? container-style]}]
(fn [{:keys [on-change disabled? blurred-background? container-style accessibility-label]}]
[rn/touchable-without-feedback
{:on-press (handle-press disabled? on-change checked?)}
{:accessibility-label accessibility-label
:on-press (handle-press disabled? on-change checked?)}
[rn/view
{:style (merge
container-style

View File

@ -13,6 +13,7 @@
quo2.components.community.community-list-view
quo2.components.community.community-view
quo2.components.community.discover-card
quo2.components.community.icon
quo2.components.community.token-gating
quo2.components.counter.counter
quo2.components.dividers.date
@ -104,6 +105,7 @@
(def permission-tag-container quo2.components.community.community-view/permission-tag-container)
(def discover-card quo2.components.community.discover-card/discover-card)
(def token-gating quo2.components.community.token-gating/token-gating)
(def community-icon quo2.components.community.icon/community-icon)
;;;; DIVIDERS
(def divider-label quo2.components.dividers.divider-label/divider-label)

View File

@ -34,13 +34,12 @@
(get mock-community-item-data :data)
{:featured featured?})]
(if (= view-type :card-view)
[quo/community-card-view-item (assoc item :width width)
#(rf/dispatch [:navigate-to :community-overview item])]
[quo/community-card-view-item (assoc item :width width) #(rf/dispatch [:navigate-to :community-overview (:id item)])]
[quo/communities-list-view-item
{:on-press (fn []
(rf/dispatch [:communities/load-category-states (:id item)])
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:navigate-to :community {:community-id (:id item)}]))
(rf/dispatch [:navigate-to :community (:id item)]))
:on-long-press #(rf/dispatch [:bottom-sheet/show-sheet
{:content (fn []
;; TODO implement with quo2
@ -94,8 +93,8 @@
:width "100%"
:margin-bottom 24}
:on-layout #(swap! view-size
(fn []
(oops/oget % "nativeEvent.layout.width")))}
(fn []
(oops/oget % "nativeEvent.layout.width")))}
(when-not (= @view-size 0)
[rn/flat-list
{:key-fn :id
@ -111,7 +110,6 @@
(defn other-communities-list
[communities view-type]
(println view-type)
[rn/flat-list
{:key-fn :id
:keyboard-should-persist-taps :always
@ -127,10 +125,9 @@
[]
(let [view-type (reagent/atom :card-view)]
(fn []
(let [communities (rf/sub [:communities/communities])
communities-count (count communities)
; TODO move sorting to subscription
sorted-communities (sort-by :name communities)]
(let [communities (rf/sub [:communities/sorted-communities])
featured-communities (rf/sub [:communities/featured-communities])
featured-communities-count (count featured-communities)]
[safe-area/consumer
(fn []
[rn/view
@ -148,6 +145,6 @@
:on-press #(rf/dispatch [:navigate-back])}
:i/close]
[screen-title]
[featured-communities-header communities-count]
[featured-list communities @view-type]
[other-communities-list sorted-communities @view-type]])]))))
[featured-communities-header featured-communities-count]
[featured-list featured-communities @view-type]
[other-communities-list communities @view-type]])]))))

View File

@ -1,5 +1,6 @@
(ns status-im2.contexts.communities.overview.style
(:require [react-native.platform :as platform]))
(:require [react-native.platform :as platform]
[quo2.foundations.colors :as colors]))
(def preview-user
{:flex-direction :row
@ -18,3 +19,16 @@
:margin-top 20
:margin-left :auto
:margin-right :auto})
(defn scroll-view-container [border-radius]
{:position :absolute
:top -48
:overflow :scroll
:border-radius border-radius
:height "100%"})
(def review-notice
{:color colors/neutral-50
:margin-top 12
:margin-left :auto
:margin-right :auto})

View File

@ -6,14 +6,10 @@
[react-native.core :as rn]
[react-native.platform :as platform]
[reagent.core :as reagent]
[status-im.react-native.resources :as resources]
[status-im.ui.screens.communities.icon :as communities.icon]
[status-im.utils.utils :as utils]
[status-im2.common.constants :as constants]
[status-im2.common.scroll-page.view :as scroll-page]
[status-im2.contexts.communities.home.actions.view :as home.actions]
[status-im2.contexts.communities.overview.style :as style] ;; TODO move to status-im2 when
;; reimplemented
[status-im2.contexts.communities.overview.style :as style]
[status-im2.contexts.communities.requests.actions.view :as requests.actions]
[utils.re-frame :as rf]))
@ -56,7 +52,7 @@
:emoji emoji
:emoji-background-color channel-color
:on-enter-channel (fn []
(utils/show-popup
(js/alert
"Entered channel"
"Wuhuu!! You successfully entered the channel :)"))
:gates {:read [{:token "KNC"
@ -174,21 +170,39 @@
(def channel-list-component (memoize channel-list-component-fn))
(defn request-to-join-text
[is-open?]
(if is-open?
(i18n/label :t/join-open-community)
(i18n/label :t/request-to-join-community)))
(defn join-community
[{:keys [joined can-join? requested-to-join-at community-color] :as community}]
(let [node-offline? (and can-join? (not joined) (pos? requested-to-join-at))]
[{:keys [joined can-join? requested-to-join-at
community-color permissions]
:as community}]
(let [pending? (pos? requested-to-join-at)
is-open? (not= constants/community-channel-access-on-request (:access permissions))
node-offline? (and can-join? (not joined) (pos? requested-to-join-at))]
[:<>
(when-not joined
(when-not (or joined pending?)
[quo/button
{:on-press #(rf/dispatch
[:bottom-sheet/show-sheet
{:content (fn [] [requests.actions/request-to-join
community])
:content-height 300}])
:accessibility-label :show-request-to-join-screen-button
:override-background-color community-color
:style style/join-button
:before :i/communities}
(i18n/label :t/join-open-community)])
(request-to-join-text is-open?)])
(when (and (not (or joined pending?)) (not (or is-open? node-offline?)))
[quo/text
{:size :paragraph-2
:style style/review-notice}
(i18n/label :t/community-admins-will-review-your-request)])
(when node-offline?
[quo/information-box
{:type :informative
@ -196,12 +210,21 @@
: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 render-page-content
[{:keys [name description locked joined id images
status tokens tags]
[{:keys [name description locked joined images
status tokens tags requested-to-join-at]
:as community}
channel-heights first-channel-height]
(let [thumbnail-image (get-in images [:thumbnail])]
(let [pending? (pos? requested-to-join-at)
thumbnail-image (get-in images [:thumbnail])]
(fn [scroll-height icon-top icon-size]
[rn/view
[rn/view {:padding-horizontal 20}
@ -216,9 +239,10 @@
:background-color (colors/theme-colors
colors/white
colors/neutral-90)}
[communities.icon/community-icon-redesign community
[quo/community-icon community
(icon-size scroll-height)]]
(when (and (not joined)
(not pending?)
(= status :gated))
[rn/view
{:position :absolute
@ -236,11 +260,7 @@
[quo/token-gating
{:community {:name name
:community-color colors/primary-50
:community-avatar (cond
(= id constants/status-community-id)
(resources/get-image :status-logo)
(seq thumbnail-image)
thumbnail-image)
:community-avatar thumbnail-image
:gates {:join [{:token "KNC"
:token-img-src knc-token-img
:amount 200
@ -255,12 +275,12 @@
:amount 10
:is-sufficient?
false}]}}}])}])}]])
(when joined
(when (or pending? joined)
[rn/view
{:position :absolute
:top 12
:right 12}
[quo/status-tag {:status {:type :positive} :label (i18n/label :t/joined)}]])
[get-tag joined]])
[rn/view {:margin-top 56}
[quo/text
{:accessibility-label :chat-name-text
@ -268,7 +288,6 @@
:ellipsize-mode :tail
:weight :semi-bold
:size :heading-1} name]]
[quo/text
{:accessibility-label :community-description-text
:number-of-lines 2
@ -300,12 +319,12 @@
:chevron-position :left}]])))
(defn community-card-page-view
[{:keys [name cover] :as community}]
[{:keys [name images] :as community}]
(let [channel-heights (reagent/atom [])
first-channel-height (reagent/atom 0)
scroll-component (scroll-page/scroll-page
(fn [] [communities.icon/community-icon-redesign community 24])
cover
(fn [] [quo/community-icon community 24])
{:uri (get-in images [:large :uri])}
{:right-section-buttons [{:icon :i/search
:background-color (scroll-page/icon-color)}
{:icon :i/options
@ -328,15 +347,13 @@
(defn overview
[]
(let [community-mock (rf/sub [:get-screen-params :community-overview]) ;TODO stop using mock data and
;only pass community id
community (rf/sub [:communities/community (:id community-mock)])]
(let [id (rf/sub [:get-screen-params :community-overview])
community (rf/sub [:communities/community id])]
[rn/view
{:style
{:position :absolute
:top (if platform/ios? 0 44)
:width "100%"
:height "110%"}}
[community-card-page-view
(merge community-mock {:joined (:joined community)})]]))
[community-card-page-view community]]))

View File

@ -11,22 +11,33 @@
:border-width 1
:border-radius 6})
(def community-rule-container
{:flex 1
:margin-top 16})
(def inner-community-rule-container
{:flex 1
:flex-direction :row
:align-items :center})
(def community-rule-text
{:margin-left :auto
:margin-right :auto
:margin-top :auto
:margin-bottom :auto})
(def request-container1
{:flex 1
:margin-left 20
(def community-rule-sub-text
{:margin-left 28
:margin-top 1})
(def page-container
{:margin-left 20
:margin-right 20
:margin-bottom 20})
(def request-container2
(def title-container
{:flex 1
:flex-direction
:row
:flex-direction :row
:align-items :center
:justify-content :space-between})
@ -41,6 +52,10 @@
:display :flex
:justify-content :center})
(def cancel-button
{:flex 1
:margin-right 12})
(def request-button
{:margin-top 32
:margin-bottom 16

View File

@ -1,17 +1,13 @@
(ns status-im2.contexts.communities.requests.actions.view
(:require [quo.react-native :as rn]
[quo2.components.buttons.button :as button]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.components.selectors.disclaimer :as disclaimer]
[quo2.components.tags.context-tags :as context-tags]
[quo2.foundations.colors :as colors]
[quo2.core :as quo]
[reagent.core :as reagent]
[status-im.communities.core :as communities]
[status-im.i18n.i18n :as i18n]
[status-im.react-native.resources :as resources]
[status-im.ui.components.list.views :as list]
[utils.re-frame :as rf]))
[status-im2.contexts.communities.requests.actions.style :as style]
[utils.re-frame :as rf]
[utils.requests :as requests]))
;; TODO: update with real data
(def community-rules
@ -38,86 +34,72 @@
:title "No offensive names and profile pictures"
:content "You will be asked to change your name or picture if the staff deems them inappropriate."}])
(defn request-to-join-text
[is-open?]
(if is-open?
(i18n/label :t/join-open-community)
(i18n/label :t/request-to-join)))
(defn community-rule-item
[{:keys [title content index]}]
[rn/view
{:style {:flex 1 :margin-top 16}}
{:style style/community-rule-container}
[rn/view
{:style
{:flex 1
:flex-direction :row
:align-items :center}}
{:style style/inner-community-rule-container}
[rn/view
{:style
{:height 18
:width 18
:margin-left 1
:margin-right 9
:background-color colors/white
:border-color colors/neutral-20
:border-width 1
:border-radius 6}}
[text/text
{:style
{:margin-left :auto
:margin-right :auto
:margin-top :auto
:margin-bottom :auto}
{:style style/community-rule}
[quo/text
{:style style/community-rule-text
:accessibility-label :communities-rule-index
:weight :medium
:size :label}
(str index)]]
[text/text
[quo/text
{:accessibility-label :communities-rule-title
:weight :semi-bold
:size :paragraph-2}
title]]
[text/text
{:style {:margin-left 28 :margin-top 1}
[quo/text
{:style style/community-rule-sub-text
:accessibility-label :communities-rule-content
:size :paragraph-2}
content]])
(defn community-rules-list
[rules]
[list/flat-list
[rn/flat-list
{:shows-horizontal-scroll-indicator false
:data rules
:separator [rn/view {:margin-top 1}]
:render-fn community-rule-item}])
(defn request-to-join
[community]
(let [agreed-to-rules? (reagent/atom false)]
[{:keys [permissions name id joined
can-join? can-request-access?
requested-to-join-at]}]
(let [agreed-to-rules? (reagent/atom false)
is-open? (not= 3 (:access permissions))]
(fn []
[rn/scroll-view {:style {:margin-left 20 :margin-right 20 :margin-bottom 20}}
[rn/scroll-view {:style style/page-container}
[rn/view
{:style {:flex 1 :flex-direction :row :align-items :center :justify-content :space-between}}
{:style style/title-container}
[text/text
[quo/text
{:accessibility-label :communities-join-community
:weight :semi-bold
:size :heading-1}
(i18n/label :t/join-open-community)]
(request-to-join-text is-open?)]
[rn/view
{:style {:height 32
:width 32
:align-items :center
:background-color colors/white
:border-color colors/neutral-20
:border-width 1
:border-radius 8
:display :flex
:justify-content :center}}
[icon/icon :i/info]]]
{:style style/request-icon}
[quo/icon :i/info]]]
;; TODO get tag image from community data
[context-tags/context-tag
[quo/context-tag
{:style
{:margin-right :auto
:margin-top 8}}
(resources/get-image :status-logo) (:name community)]
[text/text
(resources/get-image :status-logo) name]
[quo/text
{:style {:margin-top 24}
:accessibility-label :communities-rules-title
:weight :semi-bold
@ -125,26 +107,30 @@
(i18n/label :t/community-rules)]
[community-rules-list community-rules]
[disclaimer/disclaimer
{:container-style {:margin-top 20}
:on-change #(swap! agreed-to-rules? not)}
[quo/disclaimer
{:accessibility-label :rules-disclaimer-checkbox
:container-style {:margin-top 20}
:on-change #(swap! agreed-to-rules? not)}
(i18n/label :t/accept-community-rules)]
[rn/view
{:style {:width "100%"
:margin-top 32
:margin-bottom 16
:flex 1
:flex-direction :row
:align-items :center
:justify-content :space-evenly}}
[button/button
{:on-press #(rf/dispatch [:bottom-sheet/hide])
:type :grey
:style {:flex 1 :margin-right 12}} (i18n/label :t/cancel)]
[button/button
{:on-press (fn []
(rf/dispatch [::communities/join (:id community)])
(rf/dispatch [:bottom-sheet/hide]))
:disabled (not @agreed-to-rules?)
:style {:flex 1}} (i18n/label :t/join-open-community)]]])))
{:style style/request-button}
[quo/button
{:accessibility-label :cancel
:on-press #(rf/dispatch [:bottom-sheet/hide])
:type :grey
:style style/cancel-button} (i18n/label :t/cancel)]
[quo/button
{:accessibility-label :join-community-button
:on-press (fn []
(when-not joined
(when can-join?
(rf/dispatch [::communities/join id]))
(rf/dispatch [:bottom-sheet/hide])
(when
(and can-request-access?
(not (pos? requested-to-join-at))
(requests/can-request-access-again? requested-to-join-at))
(rf/dispatch [::communities/request-to-join id])
(rf/dispatch [:bottom-sheet/hide]))))
:disabled (not @agreed-to-rules?)
:style {:flex 1}} (request-to-join-text is-open?)]]])))

View File

@ -78,15 +78,19 @@
:<- [:communities]
(fn [[communities-enabled? search-filter communities]]
(filterv
(fn [{:keys [name featured id]}]
(and (or featured (= name "Status")) ;; TO DO: remove once featured communities
;; exist
(or communities-enabled?
(fn [{:keys [name id]}]
(and (or communities-enabled?
(= id constants/status-community-id))
(or (empty? search-filter)
(string/includes? (string/lower-case (str name)) search-filter))))
(vals communities))))
(re-frame/reg-sub
:communities/sorted-communities
:<- [:communities]
(fn [communities]
(sort-by :name (vals communities))))
(re-frame/reg-sub
:communities/communities
:<- [:communities/enabled?]

View File

@ -115,3 +115,24 @@
"0x3" {:id "0x3" :name "Civilized dolphins"}})
(is (= {:joined ["0x1"] :pending ["0x2"] :opened ["0x3"]}
(rf/sub [sub-name])))))
(h/deftest-sub :communities/sorted-communities
[sub-name]
(testing "Empty communities list"
(swap! rf-db/app-db assoc
:communities/enabled? true
:communities {})
(is (= []
(rf/sub [sub-name]))))
(testing "communities sorted by name"
(swap! rf-db/app-db assoc
:communities/enabled? true
:communities
{"0x1" {:id "0x1" :name "Civilized monkeys"}
"0x2" {:id "0x2" :name "Civilized rats"}
"0x3" {:id "0x3" :name "Civilized dolphins"}})
(is (= [{:id "0x3" :name "Civilized dolphins"}
{:id "0x1" :name "Civilized monkeys"}
{:id "0x2" :name "Civilized rats"}]
(rf/sub [sub-name])))))

9
src/utils/requests.cljs Normal file
View File

@ -0,0 +1,9 @@
(ns utils.requests
(:require [status-im.utils.datetime :as datetime]))
(def request-cooldown-ms (* 24 60 60 1000))
(defn can-request-access-again?
[requested-at]
(> (datetime/timestamp) (+ (* requested-at 1000) request-cooldown-ms)))

View File

@ -210,6 +210,7 @@
"membership-title": "Membership requirement",
"create-channel-title": "New channel",
"edit-channel-title": "Edit channel",
"community-admins-will-review-your-request":"Community admins will review your request",
"community-thumbnail-image": "Thumbnail image",
"community-emoji-thumbnail-title": "Thumbnail",
"community-thumbnail-upload": "Upload",
@ -1124,6 +1125,8 @@
"repeat-puk": "Repeat new 12-digit PUK",
"report-bug-email-template": "1. Issue Description\n{{description}}\n\n\n2. Steps to reproduce\n{{steps}}\n\n\n3. Attach screenshots that can demo the problem, please\n",
"request-processed-after-node-online": "Your request will be processed once the community owner node is back online.",
"request-to-join": "Request to join",
"request-to-join-community": "Request to join Community",
"request-transaction": "Request transaction",
"required-field": "Required field",
"resend-message": "Resend",