[#11797] Communities issues

Signed-off-by: andrey <motor4ik@gmail.com>
This commit is contained in:
andrey 2021-03-09 14:09:28 +01:00
parent 313181ddb3
commit c7cc9e27a9
No known key found for this signature in database
GPG Key ID: 89B67245FD2F0272
21 changed files with 306 additions and 271 deletions

View File

@ -36,15 +36,18 @@
(def one-to-one-chat?
(complement multi-user-chat?))
(defn community-chat? [{:keys [chat-type]}]
(= chat-type constants/community-chat-type))
(defn public-chat?
([chat]
(:public? chat))
([cofx chat-id]
(public-chat? (get-chat cofx chat-id))))
(defn community-chat?
([{:keys [chat-type]}]
(= chat-type constants/community-chat-type))
([cofx chat-id]
(community-chat? (get-chat cofx chat-id))))
(defn active-chat?
([chat]
(:is-active chat))
@ -240,7 +243,7 @@
(fx/merge cofx
{:db (dissoc db :current-chat-id)}
(offload-messages chat-id)
(navigation/navigate-to-cofx :home {})))
(navigation/navigate-back)))
(fx/defn remove-chat
"Removes chat completely from app, producing all necessary effects for that"
@ -296,14 +299,20 @@
(fx/defn start-public-chat
"Starts a new public chat"
{:events [:chat.ui/start-public-chat]}
[cofx topic {:keys [dont-navigate? profile-public-key]}]
[cofx topic {:keys [dont-navigate? profile-public-key navigation-reset?]}]
(if (or (new-public-chat.db/valid-topic? topic) profile-public-key)
(if (active-chat? cofx topic)
(when-not dont-navigate?
(navigate-to-chat cofx topic))
(if navigation-reset?
(fx/merge cofx
{:dispatch [:chat.ui/navigate-to-chat topic]}
(navigation/navigate-to-cofx :home {}))
(navigate-to-chat cofx topic)))
(fx/merge cofx
(add-public-chat topic profile-public-key false)
(transport.filters/load-chat topic)
#(when navigation-reset?
(navigation/navigate-to-cofx % :home {}))
#(when-not dont-navigate?
{:dispatch [:chat.ui/navigate-to-chat topic]})))
{:utils/show-popup {:title (i18n/label :t/cant-open-public-chat)

View File

@ -7,10 +7,7 @@
[taoensso.timbre :as log]
[status-im.utils.fx :as fx]
[status-im.constants :as constants]
[status-im.chat.models :as models.chat]
[status-im.transport.filters.core :as models.filters]
[status-im.bottom-sheet.core :as bottom-sheet]
[status-im.data-store.chats :as data-store.chats]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.ui.components.colors :as colors]
[status-im.navigation :as navigation]))
@ -56,15 +53,6 @@
(defn fetch-community-id-input [{:keys [db]}]
(:communities/community-id-input db))
(fx/defn handle-chats [cofx chats]
(models.chat/ensure-chats cofx chats))
(fx/defn handle-filters [cofx filters]
(models.filters/handle-filters cofx filters))
(fx/defn handle-removed-filters [cofx filters]
(models.filters/handle-filters-removed cofx (map models.filters/responses->filters filters)))
(fx/defn handle-request-to-join [{:keys [db]} r]
(let [{:keys [id community-id] :as request} (<-request-to-join-community-rpc r)]
{:db (assoc-in db [:communities/requests-to-join community-id id] request)}))
@ -75,11 +63,7 @@
db
chat-ids)})
(fx/defn handle-community
[{:keys [db]} {:keys [id] :as community}]
{:db (assoc-in db [:communities id] (<-rpc community))})
(fx/defn handle-fetched
(fx/defn handle-communities
{:events [::fetched]}
[{:keys [db]} communities]
{:db (reduce (fn [db {:keys [id] :as community}]
@ -87,26 +71,20 @@
db
communities)})
(fx/defn handle-response [cofx response]
(fx/merge cofx
(handle-removed-chats (:removedChats response))
(handle-chats (map #(-> %
(data-store.chats/<-rpc)
(dissoc :unviewed-messages-count))
(:chats response)))
(handle-fetched (:communities response))
(handle-removed-filters (:removedFilters response))
(handle-filters (:filters response))))
(fx/defn handle-response [_ response-js]
{:dispatch [:sanitize-messages-and-process-response response-js]})
(fx/defn left
{:events [::left]}
[cofx response]
(handle-response cofx response))
[cofx response-js]
(fx/merge cofx
(handle-response cofx response-js)
(navigation/navigate-to-cofx :home {})))
(fx/defn joined
{:events [::joined ::requested-to-join]}
[cofx response]
(handle-response cofx response))
[cofx response-js]
(handle-response cofx response-js))
(fx/defn export
{:events [::export-pressed]}
@ -124,6 +102,7 @@
[cofx community-key]
{::json-rpc/call [{:method "wakuext_importCommunity"
:params [community-key]
:js-response true
:on-success #(re-frame/dispatch [::community-imported %])
:on-error #(do
(log/error "failed to import community" %)
@ -134,6 +113,7 @@
[cofx 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 %)
@ -144,6 +124,7 @@
[cofx community-id]
{::json-rpc/call [{:method "wakuext_requestToJoinCommunity"
:params [{:communityId community-id}]
:js-response true
:on-success #(re-frame/dispatch [::requested-to-join %])
:on-error #(do
(log/error "failed to request to join community" community-id %)
@ -154,6 +135,7 @@
[cofx community-id]
{::json-rpc/call [{:method "wakuext_leaveCommunity"
:params [community-id]
:js-response true
:on-success #(re-frame/dispatch [::left %])
:on-error #(do
(log/error "failed to leave community" community-id %)
@ -169,7 +151,7 @@
(fx/defn chat-created
{:events [::chat-created]}
[cofx community-id user-pk]
[_ community-id user-pk]
{::json-rpc/call [{:method "wakuext_sendChatMessage"
:params [{:chatId user-pk
:text "Upgrade here to see an invitation to community"
@ -191,6 +173,7 @@
{::json-rpc/call [{:method "wakuext_inviteUsersToCommunity"
:params [{:communityId community-id
:users pks}]
:js-response true
:on-success #(re-frame/dispatch [::people-invited %])
:on-error #(do
(log/error "failed to invite-user community" %)
@ -206,6 +189,7 @@
{::json-rpc/call [{:method "wakuext_shareCommunity"
:params [{:communityId community-id
:users pks}]
:js-response true
:on-success #(re-frame/dispatch [::people-invited %])
:on-error #(do
(log/error "failed to invite-user community" %)
@ -233,6 +217,7 @@
{::json-rpc/call [{:method "wakuext_createCommunity"
:params [params]
:js-response true
:on-success #(re-frame/dispatch [::community-created %])
:on-error #(do
(log/error "failed to create community" %)
@ -264,6 +249,7 @@
:color (rand-nth colors/chat-colors)
:description community-channel-description}
:permissions {:access constants/community-channel-access-no-membership}}]
:js-response true
:on-success #(re-frame/dispatch [::community-channel-created %])
:on-error #(do
(log/error "failed to create community channel" %)
@ -306,23 +292,23 @@
(fx/defn community-created
{:events [::community-created]}
[cofx response]
[cofx response-js]
(fx/merge cofx
(navigation/navigate-back)
(handle-response response)))
(handle-response response-js)))
(fx/defn community-edited
{:events [::community-edited]}
[cofx response]
[cofx response-js]
(fx/merge cofx
(navigation/navigate-back)
(handle-response response)))
(handle-response response-js)))
(fx/defn open-create-community
{:events [::open-create-community]}
[{:keys [db] :as cofx}]
(fx/merge cofx
{:db (assoc db :communities/create {})}
{:db (assoc db :communities/create {:membership constants/community-no-membership-access})}
(navigation/navigate-to :community-create nil)))
(fx/defn open-edit-community
@ -340,24 +326,24 @@
(fx/defn community-imported
{:events [::community-imported]}
[cofx response]
[cofx response-js]
(fx/merge cofx
(navigation/navigate-back)
(handle-response response)))
(handle-response response-js)))
(fx/defn people-invited
{:events [::people-invited]}
[cofx response]
[cofx response-js]
(fx/merge cofx
(navigation/navigate-back)
(handle-response response)))
(handle-response response-js)))
(fx/defn community-channel-created
{:events [::community-channel-created]}
[cofx response]
[cofx response-js]
(fx/merge cofx
(navigation/navigate-back)
(handle-response response)))
(handle-response response-js)))
(fx/defn create-field
{:events [::create-field]}
@ -371,17 +357,17 @@
(fx/defn member-kicked
{:events [::member-kicked]}
[cofx response]
[cofx response-js]
(fx/merge cofx
(bottom-sheet/hide-bottom-sheet)
(handle-response response)))
(handle-response response-js)))
(fx/defn member-kick
{:events [::member-kick]}
[cofx community-id public-key]
{::json-rpc/call [{:method "wakuext_removeUserFromCommunity"
:params [community-id public-key]
:js-response true
:on-success #(re-frame/dispatch [::member-kicked %])
:on-error #(log/error "failed to remove user from community" community-id public-key %)}]})
@ -408,21 +394,24 @@
(fx/defn request-to-join-accepted
{:events [::request-to-join-accepted]}
[{:keys [db] :as cofx} community-id request-id response]
[{:keys [db] :as cofx} community-id request-id response-js]
(fx/merge cofx
{:db (update-in db [:communities/requests-to-join community-id] dissoc request-id)}
(handle-response response)))
(handle-response response-js)))
(fx/defn request-to-join-declined
{:events [::request-to-join-declined]}
[{:keys [db] :as cofx} community-id request-id]
{:db (update-in db [:communities/requests-to-join community-id] dissoc request-id)})
[{:keys [db] :as cofx} community-id request-id response-js]
(fx/merge cofx
{:db (update-in db [:communities/requests-to-join community-id] dissoc request-id)}
(handle-response response-js)))
(fx/defn accept-request-to-join-pressed
{:events [:communities.ui/accept-request-to-join-pressed]}
[cofx community-id request-id]
{::json-rpc/call [{:method "wakuext_acceptRequestToJoinCommunity"
:params [{:id request-id}]
:js-response true
:on-success #(re-frame/dispatch [::request-to-join-accepted community-id request-id %])
:on-error #(log/error "failed to accept requests-to-join" community-id request-id %)}]})
@ -431,5 +420,6 @@
[cofx community-id request-id]
{::json-rpc/call [{:method "wakuext_declineRequestToJoinCommunity"
:params [{:id request-id}]
:js-response true
:on-success #(re-frame/dispatch [::request-to-join-declined community-id request-id %])
:on-error #(log/error "failed to decline requests-to-join" community-id request-id)}]})

View File

@ -983,8 +983,8 @@
:chats/unread-messages-number
:<- [:chats/active-chats]
(fn [chats _]
(reduce-kv (fn [{:keys [public other]} _ {:keys [unviewed-messages-count public?]}]
(if public?
(reduce-kv (fn [{:keys [public other]} _ {:keys [unviewed-messages-count public?] :as chat}]
(if (or public? (chat.models/community-chat? chat))
{:public (+ public unviewed-messages-count)
:other other}
{:other (+ other unviewed-messages-count)

View File

@ -30,7 +30,8 @@
^js emoji-reactions (.-emojiReactions response-js)
^js filters (.-filters response-js)
^js removed-filters (.-removedFilters response-js)
^js invitations (.-invitations response-js)]
^js invitations (.-invitations response-js)
^js removed-chats (.-removedChats response-js)]
(cond
@ -63,10 +64,19 @@
(models.contact/ensure-contacts (map data-store.contacts/<-rpc contacts-clj))))
(seq communities)
(let [community (.pop communities)]
(let [communities-clj (types/js->clj communities)]
(js-delete response-js "communities")
(fx/merge cofx
{:utils/dispatch-later [{:ms 20 :dispatch [:process-response response-js]}]}
(models.communities/handle-community (types/js->clj community))))
(models.communities/handle-communities (types/js->clj communities-clj))))
(seq removed-chats)
(let [removed-chats-clj (types/js->clj removed-chats)]
(js-delete response-js "removedChats")
(fx/merge cofx
{:utils/dispatch-later [{:ms 20 :dispatch [:process-response response-js]}]}
(models.communities/handle-removed-chats (types/js->clj removed-chats-clj))))
(seq requests-to-join-community)
(let [request (.pop requests-to-join-community)]
(fx/merge cofx

View File

@ -76,7 +76,7 @@
:accessibility-label :open-chat
:title (str "#" topic)
:subtitle (i18n/label :t/open-chat)
:on-press #(hide-sheet-and-dispatch [:chat.ui/start-public-chat topic nil])
:on-press #(hide-sheet-and-dispatch [:chat.ui/start-public-chat topic {:navigation-reset? true}])
:chevron true}]
[components/separator]])
(if connected?

View File

@ -12,7 +12,6 @@
[status-im.ui.screens.chat.message.command :as message.command]
[status-im.ui.screens.chat.photos :as photos]
[status-im.ui.screens.chat.sheets :as sheets]
[status-im.ui.components.chat-icon.screen :as chat-icon]
[status-im.ui.screens.chat.styles.message.message :as style]
[status-im.ui.screens.chat.utils :as chat.utils]
[status-im.utils.contenthash :as contenthash]
@ -22,7 +21,8 @@
[quo.core :as quo]
[reagent.core :as reagent]
[status-im.ui.screens.chat.components.reply :as components.reply]
[status-im.ui.screens.chat.message.link-preview :as link-preview])
[status-im.ui.screens.chat.message.link-preview :as link-preview]
[status-im.ui.screens.communities.icon :as communities.icon])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defview mention-element [from]
@ -216,58 +216,31 @@
(defview community-content [{:keys [community-id] :as message}]
(letsubs [{:keys [name description verified] :as community} [:communities/community community-id]]
(when (and
config/communities-enabled?
community)
(when (and config/communities-enabled? community)
[react/view {:style (assoc (style/message-wrapper message)
:margin-vertical 10
:margin-left 8
:width 271)}
(when verified
[react/view {:border-right-width 1
:border-left-width 1
:border-top-width 1
:border-left-color colors/gray-lighter
:border-right-color colors/gray-lighter
:border-top-left-radius 10
:border-top-right-radius 10
:padding-vertical 8
:padding-horizontal 15
:border-top-color colors/gray-lighter}
[react/view (style/community-verified)
[react/text {:style {:font-size 13
:color colors/blue}} (i18n/label :t/communities-verified)]])
[react/view {:flex-direction :row
:padding-vertical 12
:border-top-left-radius (when-not verified 10)
:border-top-right-radius (when-not verified 10)
:border-right-width 1
:border-left-width 1
:border-top-width 1
:border-color colors/gray-lighter}
[react/view (style/community-message verified)
[react/view {:width 62
:padding-left 14}
(if (= community-id constants/status-community-id)
[react/image {:source (resources/get-image :status-logo)
:style {:width 40
:height 40}}]
[chat-icon/chat-icon-view-chat-list
name
true
name
colors/default-community-color])]
[react/view {:padding-right 14}
[react/text {:style {:font-weight "700"
:font-size 17}}
[communities.icon/community-icon community])]
[react/view {:padding-right 14 :flex 1}
[react/text {:style {:font-weight "700" :font-size 17}}
name]
[react/text description]]]
[react/view {:border-width 1
:padding-vertical 8
:border-bottom-left-radius 10
:border-bottom-right-radius 10
:border-color colors/gray-lighter}
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :community {:community-id (:id community)}])}
[react/view (style/community-view-button)
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to
:community
{:community-id (:id community)}])}
[react/text {:style {:text-align :center
:color colors/blue}} (i18n/label :t/view)]]]])))
@ -355,12 +328,14 @@
(defn on-long-press-fn [on-long-press message content]
(on-long-press
[{:on-press #(re-frame/dispatch [:chat.ui/reply-to-message message])
:label (i18n/label :t/message-reply)}
{:on-press #(react/copy-to-clipboard
(components.reply/get-quoted-text-with-mentions
(get content :parsed-text)))
:label (i18n/label :t/sharing-copy-to-clipboard)}]))
(concat
(when (:show-input? message)
[{:on-press #(re-frame/dispatch [:chat.ui/reply-to-message message])
:label (i18n/label :t/message-reply)}])
[{:on-press #(react/copy-to-clipboard
(components.reply/get-quoted-text-with-mentions
(get content :parsed-text)))
:label (i18n/label :t/sharing-copy-to-clipboard)}])))
(defn collapsible-text-message [_ _]
(let [collapsed? (reagent/atom false)

View File

@ -43,10 +43,9 @@
colors/gray)}))
(defn message-wrapper [{:keys [outgoing]}]
(merge {:flex-direction :column}
(if outgoing
{:margin-left 96}
{:margin-right 52})))
(if outgoing
{:margin-left 96}
{:margin-right 52}))
(defn message-author-wrapper
[outgoing display-photo?]
@ -318,3 +317,32 @@
:position :absolute
:background-color :transparent
:border-color colors/black-transparent}))
(defn community-verified []
{:border-right-width 1
:border-left-width 1
:border-top-width 1
:border-left-color colors/gray-lighter
:border-right-color colors/gray-lighter
:border-top-left-radius 10
:border-top-right-radius 10
:padding-vertical 8
:padding-horizontal 15
:border-top-color colors/gray-lighter})
(defn community-message [verified]
{:flex-direction :row
:padding-vertical 12
:border-top-left-radius (when-not verified 10)
:border-top-right-radius (when-not verified 10)
:border-right-width 1
:border-left-width 1
:border-top-width 1
:border-color colors/gray-lighter})
(defn community-view-button []
{:border-width 1
:padding-vertical 8
:border-bottom-left-radius 10
:border-bottom-right-radius 10
:border-color colors/gray-lighter})

View File

@ -249,7 +249,7 @@
(defn render-fn [{:keys [outgoing type] :as message}
idx
_
{:keys [group-chat public? current-public-key space-keeper chat-id]}]
{:keys [group-chat public? current-public-key space-keeper chat-id show-input?]}]
[react/view {:style (when platform/android? {:scaleY -1})}
(if (= type :datemark)
[message-datemark/chat-datemark (:value message)]
@ -261,11 +261,12 @@
:incoming-group (and group-chat (not outgoing))
:group-chat group-chat
:public? public?
:current-public-key current-public-key)
:current-public-key current-public-key
:show-input? show-input?)
space-keeper]))])
(defn messages-view
[{:keys [chat bottom-space pan-responder space-keeper]}]
[{:keys [chat bottom-space pan-responder space-keeper show-input?]}]
(let [{:keys [group-chat chat-id public?]} chat
messages @(re-frame/subscribe [:chats/chat-messages-stream chat-id])
current-public-key @(re-frame/subscribe [:multiaccount/public-key])]
@ -281,7 +282,8 @@
:public? public?
:current-public-key current-public-key
:space-keeper space-keeper
:chat-id chat-id}
:chat-id chat-id
:show-input? show-input?}
:render-fn render-fn
:on-viewable-items-changed on-viewable-items-changed
;;TODO this is not really working in pair with inserting new messages because we stop inserting new messages
@ -332,7 +334,8 @@
[messages-view {:chat current-chat
:bottom-space (max @bottom-space @panel-space)
:pan-responder pan-responder
:space-keeper space-keeper}]]
:space-keeper space-keeper
:show-input? show-input?}]]
(when (and group-chat invitation-admin)
[accessory/view {:y position-y
:on-update-inset on-update}

View File

@ -7,7 +7,6 @@
[status-im.utils.handlers :refer [>evt <sub]]
[status-im.i18n.i18n :as i18n]
[status-im.utils.datetime :as datetime]
[status-im.utils.config :as config]
[status-im.communities.core :as communities]
[status-im.ui.components.list.views :as list]
[status-im.ui.screens.home.views.inner-item :as inner-item]
@ -16,7 +15,9 @@
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.icons.icons :as icons]
[status-im.utils.core :as utils]))
[status-im.utils.core :as utils]
[status-im.ui.components.plus-button :as components.plus-button]
[status-im.utils.config :as config]))
(def request-cooldown-ms (* 60 1000))
@ -47,25 +48,49 @@
[quo/text {:number-of-lines 1
:accessibility-label :community-name-text}
display-name]
(when show-members-count?
[quo/text {:number-of-lines 1
:size :small
:color :secondary}
(i18n/label-pluralize members :t/community-members {:count members})])]]))
[quo/text {:number-of-lines 1
:size :small
:color :secondary}
(if show-members-count?
(i18n/label-pluralize members :t/community-members {:count members})
(i18n/label :t/open-membership))]]]))
(defn hide-sheet-and-dispatch [event]
(>evt [:bottom-sheet/hide])
(>evt event))
(defn community-actions [{:keys [id
permissions
can-manage-users? name images color]}]
(defn community-plus-actions [{:keys [id permissions can-manage-users?]}]
(let [can-invite? (and can-manage-users? (not= (:access permissions) constants/community-no-membership-access))
can-share? (not= (:access permissions) constants/community-invitation-only-access)
thumbnail-image (get-in images [:thumbnail :uri])]
can-share? (not= (:access permissions) constants/community-invitation-only-access)]
[:<>
[quo/list-item
{:theme :accent
:title (i18n/label :t/create-channel)
:accessibility-label :community-create-channel
:icon :main-icons/channel
:on-press #(hide-sheet-and-dispatch [::communities/create-channel-pressed id])}]
[quo/separator]
(when can-invite?
[quo/list-item
{:theme :accent
:title (i18n/label :t/invite-people)
:icon :main-icons/share
:accessibility-label :community-invite-people
:on-press #(>evt [::communities/invite-people-pressed id])}])
(when (and can-share? (not can-invite?))
[quo/list-item
{:theme :accent
:title (i18n/label :t/invite-people)
:icon :main-icons/share
:accessibility-label :community-share
:on-press #(>evt [::communities/share-community-pressed id])}])]))
(defn community-actions [{:keys [id name images color can-manage-users?]}]
(let [thumbnail-image (get-in images [:thumbnail :uri])]
[:<>
[quo/list-item
{:title name
:subtitle (i18n/label :t/view-profile)
:on-press #(hide-sheet-and-dispatch [:navigate-to :community-management {:community-id id}])
:chevron true
:icon (cond
@ -83,42 +108,12 @@
name
(or color (rand-nth colors/chat-colors))])}]
(when (and config/communities-management-enabled? can-manage-users?)
[:<>
[quo/list-item
{:theme :accent
:title (i18n/label :t/export-key)
:accessibility-label :community-export-key
:icon :main-icons/objects
:on-press #(hide-sheet-and-dispatch [::communities/export-pressed id])}]
[quo/list-item
{:theme :accent
:title (i18n/label :t/create-channel)
:accessibility-label :community-create-channel
:icon :main-icons/channel
:on-press #(hide-sheet-and-dispatch [::communities/create-channel-pressed id])}]])
(when can-invite?
[quo/list-item
{:theme :accent
:title (i18n/label :t/invite-people)
:icon :main-icons/share
:accessibility-label :community-invite-people
:on-press #(>evt [::communities/invite-people-pressed id])}])
(when can-share?
[quo/list-item
{:theme :accent
:title (i18n/label :t/share)
:icon :main-icons/share
:accessibility-label :community-share
:on-press #(>evt [::communities/share-community-pressed id])}])
[quo/list-item
{:theme :accent
:title (i18n/label :t/leave-community)
:accessibility-label :leave
:icon :main-icons/arrow-left
:on-press #(do
(>evt [:bottom-sheet/hide])
(>evt [:navigate-to :home])
(>evt [::communities/leave id]))}]]))
:title (i18n/label :t/export-key)
:accessibility-label :community-export-key
:icon :main-icons/objects
:on-press #(hide-sheet-and-dispatch [::communities/export-pressed id])}])]))
(defn welcome-blank-page []
[rn/view {:style {:padding 16 :flex 1 :flex-direction :row :align-items :center :justify-content :center}}
@ -148,7 +143,7 @@
[community-chat-list chats]))
(defn channel-preview-item [{:keys [id color name]}]
(let [color (or color (rand-nth colors/chat-colors))]
(let [color (or color colors/default-community-color)]
[quo/list-item
{:icon [chat-icon.screen/chat-icon-view-chat-list
id true name color false false]
@ -185,39 +180,35 @@
(defn community [route]
(let [{:keys [community-id]} (get-in route [:route :params])
{:keys [id
chats
name
images
members
permissions
color
joined
can-request-access?
can-join?
requested-to-join-at
admin]
{:keys [id chats name images members permissions color joined can-request-access?
can-join? requested-to-join-at admin]
:as community} (<sub [:communities/community community-id])]
[rn/view {:style {:flex 1}}
[topbar/topbar
{:content [toolbar-content id
name
color
images
(not= (:access permissions) constants/community-no-membership-access)
(count members)]
:right-accessories (when (or admin joined)
[{:icon :main-icons/more
:accessibility-label :community-menu-button
:on-press
#(>evt [:bottom-sheet/show-sheet
{:content (fn []
[community-actions community])
:height 256}])}])}]
{:content
[toolbar-content
id
name
color
images
(not= (:access permissions) constants/community-no-membership-access)
(count members)]
:right-accessories
(when (or admin joined)
[{:icon :main-icons/more
:accessibility-label :community-menu-button
:on-press #(>evt [:bottom-sheet/show-sheet
{:content (fn []
[community-actions community])}])}])}]
(if joined
[community-channel-list id]
[community-channel-preview-list id chats])
(when admin
[components.plus-button/plus-button
{:on-press #(>evt [:bottom-sheet/show-sheet
{:content (fn []
[community-plus-actions community])}])
:accessibility-label :new-chat-button}])
(when-not joined
(cond
can-join?

View File

@ -11,7 +11,8 @@
[quo.design-system.colors :as colors]
[status-im.ui.components.react :as react]
[status-im.ui.screens.communities.membership :as memberships]
[status-im.ui.components.icons.icons :as icons]))
[status-im.ui.components.icons.icons :as icons]
[status-im.utils.debounce :as debounce]))
(def max-name-length 30)
(def max-description-length 140)
@ -29,14 +30,22 @@
:height crop-size})
(defn pick-pic []
(react/show-image-picker
#(>evt [::communities/create-field :image (.-path ^js %)])
crop-opts))
;;we need timeout because first we need to close bottom sheet and then open picker
(js/setTimeout
(fn []
(react/show-image-picker
#(>evt [::communities/create-field :image (.-path ^js %)])
crop-opts))
300))
(defn take-pic []
(react/show-image-picker-camera
#(>evt [::communities/create-field :image (.-path ^js %)])
crop-opts))
;;we need timeout because first we need to close bottom sheet and then open picker
(js/setTimeout
(fn []
(react/show-image-picker-camera
#(>evt [::communities/create-field :image (.-path ^js %)])
crop-opts))
300))
(defn bottom-sheet [has-picture]
(fn []
@ -118,7 +127,8 @@
(defn form []
(let [{:keys [name description membership]} (<sub [:communities/create])]
[rn/scroll-view {:style {:flex 1}
[rn/scroll-view {:keyboard-should-persist-taps :handled
:style {:flex 1}
:content-container-style {:padding-vertical 16}}
[rn/view {:style {:padding-bottom 16
:padding-top 10
@ -166,5 +176,5 @@
:center
[quo/button {:disabled (not (valid? name description))
:type :secondary
:on-press #(>evt [::communities/create-confirmation-pressed])}
:on-press #(debounce/dispatch-and-chill [::communities/create-confirmation-pressed] 3000)}
(i18n/label :t/create)]}]]))

View File

@ -5,9 +5,9 @@
[quo.core :as quo]
[status-im.i18n.i18n :as i18n]
[status-im.ui.components.toolbar :as toolbar]
[status-im.utils.handlers :refer [>evt]]
[status-im.communities.core :as communities]
[status-im.ui.components.topbar :as topbar]))
[status-im.ui.components.topbar :as topbar]
[status-im.utils.debounce :as debounce]))
(defn valid? [community-name]
(not (str/blank? community-name)))
@ -32,5 +32,7 @@
:center
[quo/button {:disabled (not (valid? @channel-name))
:type :secondary
:on-press #(>evt [::communities/create-channel-confirmation-pressed @channel-name])}
:on-press #(debounce/dispatch-and-chill
[::communities/create-channel-confirmation-pressed @channel-name]
3000)}
(i18n/label :t/create)]}]])))

View File

@ -0,0 +1,22 @@
(ns status-im.ui.screens.communities.icon
(:require [status-im.ui.components.colors :as colors]
[status-im.constants :as constants]
[status-im.react-native.resources :as resources]
[status-im.ui.components.react :as react]
[status-im.ui.screens.chat.photos :as photos]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]))
(defn community-icon [{:keys [id name images color]}]
(let [color (or color (rand-nth colors/chat-colors))
thumbnail-image (get-in images [:thumbnail :uri])]
(cond
(= id constants/status-community-id)
[react/image {:source (resources/get-image :status-logo)
:style {:width 40
:height 40}}]
(seq thumbnail-image)
[photos/photo thumbnail-image {:size 40}]
:else
[chat-icon.screen/chat-icon-view-chat-list
id true name color false false])))

View File

@ -5,7 +5,7 @@
[status-im.i18n.i18n :as i18n]
[status-im.constants :as constants]
[status-im.ui.components.toolbar :as toolbar]
[status-im.utils.handlers :refer [>evt <sub]]
[status-im.utils.handlers :refer [<sub >evt-once]]
[status-im.communities.core :as communities]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
@ -57,11 +57,12 @@
(not= (:access permissions) constants/community-no-membership-access))]
[:<>
[topbar/topbar {:title (i18n/label (if can-invite?
:t/community-invite-title
:t/community-share-title))}]
:t/invite-people
:t/community-share-title))
:modal? true}]
[rn/flat-list {:style {:flex 1}
:content-container-style {:padding-vertical 16}
:header [header user-pk]
;:header [header user-pk]
:render-data {:selected contacts-selected}
:render-fn contacts-list-item
:key-fn (fn [{:keys [active public-key]}]
@ -73,7 +74,8 @@
[quo/button {:disabled (and (str/blank? @user-pk)
(zero? (count selected)))
:type :secondary
:on-press #(>evt [(if can-invite?
::communities/invite-people-confirmation-pressed
::communities/share-community-confirmation-pressed) @user-pk selected])}
:on-press #(>evt-once
[(if can-invite?
::communities/invite-people-confirmation-pressed
::communities/share-community-confirmation-pressed) @user-pk selected])}
(i18n/label (if can-invite? :t/invite :t/share))]}]]))))

View File

@ -16,13 +16,13 @@
(>evt [:bottom-sheet/hide])
(>evt event))
(defn member-sheet [{:keys [public-key] :as member} community-id can-kick-users?]
(defn member-sheet [first-name {:keys [public-key] :as member} community-id can-kick-users?]
[:<>
[quo/list-item
{:theme :accent
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo member)]
:title (multiaccounts/displayed-name member)
:title first-name
:subtitle (i18n/label :t/view-profile)
:accessibility-label :view-chat-details-button
:chevron true
@ -43,18 +43,19 @@
(defn render-member [public-key _ _ {:keys [community-id
my-public-key
can-kick-users?]}]
(let [{:keys [nickname] :as member} (or (<sub [:contacts/contact-by-identity public-key])
{:public-key public-key})]
(let [member (<sub [:contacts/contact-by-identity public-key])
[first-name second-name] (<sub [:contacts/contact-two-names-by-identity public-key])]
[quo/list-item
{:title (if (seq nickname)
nickname
(multiaccounts/displayed-name member))
{:title first-name
:subtitle second-name
:accessibility-label :member-item
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo member)]
:accessory (when (not= public-key my-public-key)
[quo/button {:on-press #(>evt [:bottom-sheet/show-sheet
{:content (fn [] [member-sheet member community-id can-kick-users?])}])
[quo/button {:on-press
#(>evt [:bottom-sheet/show-sheet
{:content (fn []
[member-sheet first-name member community-id can-kick-users?])}])
:type :icon
:theme :icon
:accessibility-label :menu-option}

View File

@ -10,23 +10,18 @@
[status-im.constants :as constants]
[status-im.react-native.resources :as resources]
[status-im.ui.components.unviewed-indicator :as unviewed-indicator]
[quo.react-native :as rn]))
[quo.react-native :as rn]
[clojure.string :as string]))
(defn management [route]
(let [{:keys [community-id]} (get-in route [:route :params])
requests-to-join (<sub [:communities/requests-to-join-for-community community-id])
community (<sub [:communities/community community-id])
{:keys [color
members
permissions
description
name admin]} community
{:keys [color members permissions description name admin]} community
roles false
notifications false
show-members-count? (not= (:access permissions) constants/community-no-membership-access)
members-count (count members)]
[:<>
[quo/animated-header {:left-accessories [{:icon :main-icons/arrow-left
:accessibility-label :back-button
@ -42,12 +37,16 @@
(rn/resolve-asset-source
(resources/get-image :status-logo)))
(get-in community [:images :large :uri]))
:subtitle (when show-members-count? (i18n/label-pluralize members-count :t/community-members {:count members-count}))})
:subtitle (if show-members-count?
(i18n/label-pluralize members-count :t/community-members {:count members-count})
(i18n/label :t/open-membership))})
:use-insets true}
[:<>
[quo/list-footer {:color :main}
(get-in description [:identity :description])]
[quo/separator {:style {:margin-vertical 8}}]
(when-not (string/blank? description)
[:<>
[quo/list-footer {:color :main}
description]
[quo/separator {:style {:margin-vertical 8}}]])
(when show-members-count?
[quo/list-item {:chevron true
:accessory

View File

@ -7,15 +7,13 @@
[status-im.constants :as constants]
[status-im.communities.core :as communities]
[status-im.utils.handlers :refer [>evt <sub]]
[status-im.ui.screens.chat.photos :as photos]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.copyable-text :as copyable-text]
[status-im.react-native.resources :as resources]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.components.toolbar :as toolbar]
[status-im.ui.components.react :as react]))
[status-im.ui.components.react :as react]
[status-im.ui.screens.communities.icon :as communities.icon]))
(defn hide-sheet-and-dispatch [event]
(>evt [:bottom-sheet/hide])
@ -31,25 +29,10 @@
:height 12}
:accessibility-label :unviewed-messages-public}]))
(defn community-icon [{:keys [id name images color]}]
(let [color (or color (rand-nth colors/chat-colors))
thumbnail-image (get-in images [:thumbnail :uri])]
(cond
(= id constants/status-community-id)
[react/image {:source (resources/get-image :status-logo)
:style {:width 40
:height 40}}]
(seq thumbnail-image)
[photos/photo thumbnail-image {:size 40}]
:else
[chat-icon.screen/chat-icon-view-chat-list
id true name color false false])))
(defn community-home-list-item [{:keys [id name last?] :as community}]
[react/view
[quo/list-item
{:icon [community-icon community]
{:icon [communities.icon/community-icon community]
:title [react/view {:flex-direction :row
:flex 1}
[react/view {:flex-direction :row
@ -70,11 +53,11 @@
:title-accessibility-label :chat-name-text
:on-press #(do
(>evt [:dismiss-keyboard])
(>evt [:navigate-to :community {:community-id id}]))
(>evt [:navigate-to :community {:community-id id}]))}]
;; TODO: actions
;; :on-long-press #(>evt [:bottom-sheet/show-sheet
;; nil])
}]
(when last?
[quo/separator])])
@ -82,7 +65,7 @@
(let [members-count (count members)
show-members-count? (not= (:access permissions) constants/community-no-membership-access)]
[quo/list-item
{:icon [community-icon community]
{:icon [communities.icon/community-icon community]
:title [react/view {:flex-direction :row
:flex 1
:padding-right 16
@ -156,7 +139,7 @@
{:show-border? true
:center [quo/button {:on-press #(>evt [::communities/open-create-community])
:type :secondary}
(i18n/label :t/create)]}])]))
(i18n/label :t/create-community)]}])]))
(defn export-community []
(let [{:keys [community-key]} (<sub [:popover/popover])]

View File

@ -72,7 +72,7 @@
parsed-text)]
(:components result)))
(defn message-content-text [{:keys [content content-type]}]
(defn message-content-text [{:keys [content content-type community-id]}]
[:<>
(cond
@ -96,6 +96,13 @@
:accessibility-label :no-messages-text}
(i18n/label :t/audio)]
(= constants/content-type-community content-type)
(let [{:keys [name]}
@(re-frame/subscribe [:communities/community community-id])]
[react/text {:style styles/last-message-text
:accessibility-label :no-messages-text}
(i18n/label :t/community-message-preview {:community-name name})])
(string/blank? (:text content))
[react/text {:style styles/last-message-text}
""]
@ -171,8 +178,9 @@
:title-accessibility-label :chat-name-text
:subtitle [react/view {:flex-direction :row}
[react/view {:flex 1}
[message-content-text {:content (:content last-message)
:content-type (:content-type last-message)}]]
[message-content-text (select-keys last-message [:content
:content-type
:community-id])]]
[unviewed-indicator home-item]]
:on-press (fn []
(re-frame/dispatch [:dismiss-keyboard])

View File

@ -14,7 +14,6 @@
[status-im.ui.screens.communities.membership :as membership]
[status-im.ui.screens.communities.members :as members]
[status-im.ui.screens.communities.requests-to-join :as requests-to-join]
[status-im.ui.screens.communities.invite :as invite]
[status-im.ui.screens.profile.group-chat.views :as profile.group-chat]
[status-im.ui.components.tabbar.styles :as tabbar.styles]
[status-im.ui.screens.stickers.views :as stickers]
@ -54,9 +53,7 @@
{:name :community-requests-to-join
:component requests-to-join/requests-to-join-container}
{:name :create-community-channel
:component create-channel/create-channel}
{:name :invite-people-community
:component invite/invite}]])
:component create-channel/create-channel}]])
(defn communities []
[communities-stack {:header-mode :none}
@ -68,11 +65,7 @@
{:name :community-import
:insets {:bottom true
:top false}
:component communities.import/view}
{:name :invite-people-community
:insets {:bottom true
:top false}
:component invite/invite}]
:component communities.import/view}]
(when config/communities-management-enabled?
[{:name :community-edit
:insets {:bottom true

View File

@ -26,7 +26,8 @@
[status-im.ui.screens.link-previews-settings.views :as link-previews]
[status-im.ui.screens.status.new.views :as status.new]
[status-im.ui.screens.browser.bookmarks.views :as bookmarks]
[status-im.ui.screens.routing.status-stack :as status-stack]))
[status-im.ui.screens.routing.status-stack :as status-stack]
[status-im.ui.screens.communities.invite :as communities.invite]))
(defonce main-stack (navigation/create-stack))
(defonce bottom-tabs (navigation/create-bottom-tabs))
@ -161,7 +162,10 @@
{:name :buy-crypto-website
:transition :presentation-ios
:insets {:bottom true}
:component wallet.buy-crypto/website}]
:component wallet.buy-crypto/website}
{:name :invite-people-community
:component communities.invite/invite
:insets {:bottom true}}]
(when config/quo-preview-enabled?
[{:name :quo-preview

View File

@ -1,7 +1,8 @@
(ns status-im.utils.handlers
(:require [re-frame.core :as re-frame]
[re-frame.interceptor :refer [->interceptor get-coeffect]]
[taoensso.timbre :as log]))
[taoensso.timbre :as log]
[status-im.utils.debounce :as debounce]))
(defn- parse-json
;; NOTE(dmitryn) Expects JSON response like:
@ -56,3 +57,6 @@
(def <sub (comp deref re-frame/subscribe))
(def >evt re-frame/dispatch)
(defn >evt-once [event]
(debounce/dispatch-and-chill event 3000))

View File

@ -1486,5 +1486,6 @@
"rpc-usage-get-stats": "Refresh",
"rpc-usage-reset": "Reset",
"rpc-usage-filter": "Filter methods",
"rpc-usage-copy": "Copy"
"rpc-usage-copy": "Copy",
"community-message-preview": "Invitation to join {{community-name}}"
}