Allow owner/admin to delete messages of a community (#14366)

This commit is contained in:
frank 2022-12-02 20:13:02 +08:00 committed by GitHub
parent f3ad8beb6d
commit f7af7ca25d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 278 additions and 226 deletions

View File

@ -26,12 +26,12 @@
(def featured (def featured
[{:name "Status" [{:name "Status"
:id constants/status-community-id}]) :id constants/status-community-id}])
(defn <-request-to-join-community-rpc [r] (defn <-request-to-join-community-rpc [r]
(clojure.set/rename-keys r {:communityId :community-id (clojure.set/rename-keys r {:communityId :community-id
:publicKey :public-key :publicKey :public-key
:chatId :chat-id})) :chatId :chat-id}))
(defn <-requests-to-join-community-rpc [requests] (defn <-requests-to-join-community-rpc [requests]
(reduce (fn [acc r] (reduce (fn [acc r]
@ -60,11 +60,12 @@
(defn <-rpc [c] (defn <-rpc [c]
(-> c (-> c
(clojure.set/rename-keys {:canRequestAccess :can-request-access? (clojure.set/rename-keys {:canRequestAccess :can-request-access?
:canManageUsers :can-manage-users? :canManageUsers :can-manage-users?
:canJoin :can-join? :canDeleteMessageForEveryone :can-delete-message-for-everyone?
:requestedToJoinAt :requested-to-join-at :canJoin :can-join?
:isMember :is-member?}) :requestedToJoinAt :requested-to-join-at
:isMember :is-member?})
(update :members walk/stringify-keys) (update :members walk/stringify-keys)
(update :chats <-chats-rpc) (update :chats <-chats-rpc)
(update :categories <-categories-rpc))) (update :categories <-categories-rpc)))
@ -125,67 +126,67 @@
(fx/defn import-community (fx/defn import-community
{:events [::import]} {:events [::import]}
[cofx community-key] [cofx community-key]
{::json-rpc/call [{:method "wakuext_importCommunity" {::json-rpc/call [{:method "wakuext_importCommunity"
:params [community-key] :params [community-key]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::community-imported %]) :on-success #(re-frame/dispatch [::community-imported %])
:on-error #(do :on-error #(do
(log/error "failed to import community" %) (log/error "failed to import community" %)
(re-frame/dispatch [::failed-to-import %]))}]}) (re-frame/dispatch [::failed-to-import %]))}]})
(fx/defn join (fx/defn join
{:events [:communities/join]} {:events [:communities/join]}
[cofx community-id] [cofx community-id]
{::json-rpc/call [{:method "wakuext_joinCommunity" {::json-rpc/call [{:method "wakuext_joinCommunity"
:params [community-id] :params [community-id]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::joined %]) :on-success #(re-frame/dispatch [::joined %])
:on-error #(do :on-error #(do
(log/error "failed to join community" community-id %) (log/error "failed to join community" community-id %)
(re-frame/dispatch [::failed-to-join %]))}]}) (re-frame/dispatch [::failed-to-join %]))}]})
(fx/defn request-to-join (fx/defn request-to-join
{:events [::request-to-join]} {:events [::request-to-join]}
[cofx community-id] [cofx community-id]
{::json-rpc/call [{:method "wakuext_requestToJoinCommunity" {::json-rpc/call [{:method "wakuext_requestToJoinCommunity"
:params [{:communityId community-id}] :params [{:communityId community-id}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::requested-to-join %]) :on-success #(re-frame/dispatch [::requested-to-join %])
:on-error #(do :on-error #(do
(log/error "failed to request to join community" community-id %) (log/error "failed to request to join community" community-id %)
(re-frame/dispatch [::failed-to-request-to-join %]))}]}) (re-frame/dispatch [::failed-to-request-to-join %]))}]})
(fx/defn leave (fx/defn leave
{:events [:communities/leave]} {:events [:communities/leave]}
[{:keys [db]} community-id] [{:keys [db]} community-id]
(let [community-chat-ids (map #(str community-id %) (let [community-chat-ids (map #(str community-id %)
(keys (get-in db [:communities community-id :chats])))] (keys (get-in db [:communities community-id :chats])))]
{:clear-message-notifications [community-chat-ids {:clear-message-notifications [community-chat-ids
(get-in db [:multiaccount :remote-push-notifications-enabled?])] (get-in db [:multiaccount :remote-push-notifications-enabled?])]
::json-rpc/call [{:method "wakuext_leaveCommunity" ::json-rpc/call [{:method "wakuext_leaveCommunity"
:params [community-id] :params [community-id]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::left %]) :on-success #(re-frame/dispatch [::left %])
:on-error #(do :on-error #(do
(log/error "failed to leave community" community-id %) (log/error "failed to leave community" community-id %)
(re-frame/dispatch [::failed-to-leave %]))}]})) (re-frame/dispatch [::failed-to-leave %]))}]}))
(fx/defn fetch [_] (fx/defn fetch [_]
{::json-rpc/call [{:method "wakuext_communities" {::json-rpc/call [{:method "wakuext_communities"
:params [] :params []
:on-success #(re-frame/dispatch [::fetched %]) :on-success #(re-frame/dispatch [::fetched %])
:on-error #(do :on-error #(do
(log/error "failed to fetch communities" %) (log/error "failed to fetch communities" %)
(re-frame/dispatch [::failed-to-fetch %]))}]}) (re-frame/dispatch [::failed-to-fetch %]))}]})
(fx/defn chat-created (fx/defn chat-created
{:events [::chat-created]} {:events [::chat-created]}
[_ community-id user-pk] [_ community-id user-pk]
{::json-rpc/call [{:method "wakuext_sendChatMessage" {::json-rpc/call [{:method "wakuext_sendChatMessage"
:params [{:chatId user-pk :params [{:chatId user-pk
:text "Upgrade here to see an invitation to community" :text "Upgrade here to see an invitation to community"
:communityId community-id :communityId community-id
:contentType constants/content-type-community}] :contentType constants/content-type-community}]
:js-response true :js-response true
:on-success :on-success
#(re-frame/dispatch [:transport/message-sent %]) #(re-frame/dispatch [:transport/message-sent %])
@ -196,56 +197,56 @@
{:events [::invite-people-confirmation-pressed]} {:events [::invite-people-confirmation-pressed]}
[cofx user-pk contacts] [cofx user-pk contacts]
(let [community-id (fetch-community-id-input cofx) (let [community-id (fetch-community-id-input cofx)
pks (if (seq user-pk) pks (if (seq user-pk)
(conj contacts user-pk) (conj contacts user-pk)
contacts)] contacts)]
(when (seq pks) (when (seq pks)
{::json-rpc/call [{:method "wakuext_inviteUsersToCommunity" {::json-rpc/call [{:method "wakuext_inviteUsersToCommunity"
:params [{:communityId community-id :params [{:communityId community-id
:users pks}] :users pks}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::people-invited %]) :on-success #(re-frame/dispatch [::people-invited %])
:on-error #(do :on-error #(do
(log/error "failed to invite-user community" %) (log/error "failed to invite-user community" %)
(re-frame/dispatch [::failed-to-invite-people %]))}]}))) (re-frame/dispatch [::failed-to-invite-people %]))}]})))
(fx/defn share-community (fx/defn share-community
{:events [::share-community-confirmation-pressed]} {:events [::share-community-confirmation-pressed]}
[cofx user-pk contacts] [cofx user-pk contacts]
(let [community-id (fetch-community-id-input cofx) (let [community-id (fetch-community-id-input cofx)
pks (if (seq user-pk) pks (if (seq user-pk)
(conj contacts user-pk) (conj contacts user-pk)
contacts)] contacts)]
(when (seq pks) (when (seq pks)
{::json-rpc/call [{:method "wakuext_shareCommunity" {::json-rpc/call [{:method "wakuext_shareCommunity"
:params [{:communityId community-id :params [{:communityId community-id
:users pks}] :users pks}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::people-invited %]) :on-success #(re-frame/dispatch [::people-invited %])
:on-error #(do :on-error #(do
(log/error "failed to invite-user community" %) (log/error "failed to invite-user community" %)
(re-frame/dispatch [::failed-to-share-community %]))}]}))) (re-frame/dispatch [::failed-to-share-community %]))}]})))
(fx/defn create (fx/defn create
{:events [::create-confirmation-pressed]} {:events [::create-confirmation-pressed]}
[{:keys [db]}] [{:keys [db]}]
(let [{:keys [name description membership image]} (get db :communities/create)] (let [{:keys [name description membership image]} (get db :communities/create)]
(let [params {:name name (let [params {:name name
:description description :description description
:membership membership :membership membership
:color (rand-nth colors/chat-colors) :color (rand-nth colors/chat-colors)
:image (string/replace-first (str image) #"file://" "") :image (string/replace-first (str image) #"file://" "")
:imageAx 0 :imageAx 0
:imageAy 0 :imageAy 0
:imageBx crop-size :imageBx crop-size
:imageBy crop-size}] :imageBy crop-size}]
{::json-rpc/call [{:method "wakuext_createCommunity" {::json-rpc/call [{:method "wakuext_createCommunity"
:params [params] :params [params]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::community-created %]) :on-success #(re-frame/dispatch [::community-created %])
:on-error #(do :on-error #(do
(log/error "failed to create community" %) (log/error "failed to create community" %)
(re-frame/dispatch [::failed-to-create-community %]))}]}))) (re-frame/dispatch [::failed-to-create-community %]))}]})))
(fx/defn edit (fx/defn edit
{:events [::edit-confirmation-pressed]} {:events [::edit-confirmation-pressed]}
@ -253,15 +254,15 @@
(let [{:keys [id name description membership new-image color]} (get db :communities/create)] (let [{:keys [id name description membership new-image color]} (get db :communities/create)]
{::json-rpc/call [{:method "wakuext_editCommunity" {::json-rpc/call [{:method "wakuext_editCommunity"
:params [{:communityID id :params [{:communityID id
:name name :name name
:description description :description description
:color color :color color
:image (string/replace-first (str new-image) #"file://" "") :image (string/replace-first (str new-image) #"file://" "")
:imageAx 0 :imageAx 0
:imageAy 0 :imageAy 0
:imageBx crop-size :imageBx crop-size
:imageBy crop-size :imageBy crop-size
:membership membership}] :membership membership}]
:on-success #(re-frame/dispatch [::community-edited %]) :on-success #(re-frame/dispatch [::community-edited %])
:on-error #(do :on-error #(do
(log/error "failed to edit community" %) (log/error "failed to edit community" %)
@ -272,18 +273,18 @@
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [community-id (fetch-community-id-input cofx) (let [community-id (fetch-community-id-input cofx)
{:keys [name description color emoji]} (get db :communities/create-channel)] {:keys [name description color emoji]} (get db :communities/create-channel)]
{::json-rpc/call [{:method "wakuext_createCommunityChat" {::json-rpc/call [{:method "wakuext_createCommunityChat"
:params [community-id :params [community-id
{:identity {:display_name name {:identity {:display_name name
:description description :description description
:color color :color color
:emoji emoji} :emoji emoji}
:permissions {:access constants/community-channel-access-no-membership}}] :permissions {:access constants/community-channel-access-no-membership}}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::community-channel-created %]) :on-success #(re-frame/dispatch [::community-channel-created %])
:on-error #(do :on-error #(do
(log/error "failed to create community channel" %) (log/error "failed to create community channel" %)
(re-frame/dispatch [::failed-to-create-community-channel %]))}]})) (re-frame/dispatch [::failed-to-create-community-channel %]))}]}))
(def community-chat-id-length 68) (def community-chat-id-length 68)
@ -295,21 +296,21 @@
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [{:keys [name description color community-id emoji edit-channel-id category-id position]} (let [{:keys [name description color community-id emoji edit-channel-id category-id position]}
(get db :communities/create-channel)] (get db :communities/create-channel)]
{::json-rpc/call [{:method "wakuext_editCommunityChat" {::json-rpc/call [{:method "wakuext_editCommunityChat"
:params [community-id :params [community-id
edit-channel-id edit-channel-id
{:identity {:display_name name {:identity {:display_name name
:description description :description description
:color color :color color
:emoji emoji} :emoji emoji}
:category_id category-id :category_id category-id
:position position :position position
:permissions {:access constants/community-channel-access-no-membership}}] :permissions {:access constants/community-channel-access-no-membership}}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::community-channel-edited %]) :on-success #(re-frame/dispatch [::community-channel-edited %])
:on-error #(do :on-error #(do
(log/error "failed to edit community channel" %) (log/error "failed to edit community channel" %)
(re-frame/dispatch [::failed-to-edit-community-channel %]))}]})) (re-frame/dispatch [::failed-to-edit-community-channel %]))}]}))
(defn require-membership? [permissions] (defn require-membership? [permissions]
(not= constants/community-no-membership-access (:access permissions))) (not= constants/community-no-membership-access (:access permissions)))
@ -461,12 +462,12 @@
(fx/defn member-ban (fx/defn member-ban
{:events [::member-ban]} {:events [::member-ban]}
[cofx community-id public-key] [cofx community-id public-key]
{::json-rpc/call [{:method "wakuext_banUserFromCommunity" {::json-rpc/call [{:method "wakuext_banUserFromCommunity"
:params [{:communityId community-id :params [{:communityId community-id
:user public-key}] :user public-key}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::member-banned %]) :on-success #(re-frame/dispatch [::member-banned %])
:on-error #(log/error "failed to ban user from community" community-id public-key %)}]}) :on-error #(log/error "failed to ban user from community" community-id public-key %)}]})
(fx/defn member-kicked (fx/defn member-kicked
{:events [::member-kicked]} {:events [::member-kicked]}
@ -478,11 +479,11 @@
(fx/defn member-kick (fx/defn member-kick
{:events [::member-kick]} {:events [::member-kick]}
[cofx community-id public-key] [cofx community-id public-key]
{::json-rpc/call [{:method "wakuext_removeUserFromCommunity" {::json-rpc/call [{:method "wakuext_removeUserFromCommunity"
:params [community-id public-key] :params [community-id public-key]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::member-kicked %]) :on-success #(re-frame/dispatch [::member-kicked %])
:on-error #(log/error "failed to remove user from community" community-id public-key %)}]}) :on-error #(log/error "failed to remove user from community" community-id public-key %)}]})
(fx/defn delete-community (fx/defn delete-community
{:events [::delete-community]} {:events [::delete-community]}
@ -522,88 +523,88 @@
(fx/defn accept-request-to-join-pressed (fx/defn accept-request-to-join-pressed
{:events [:communities.ui/accept-request-to-join-pressed]} {:events [:communities.ui/accept-request-to-join-pressed]}
[cofx community-id request-id] [cofx community-id request-id]
{::json-rpc/call [{:method "wakuext_acceptRequestToJoinCommunity" {::json-rpc/call [{:method "wakuext_acceptRequestToJoinCommunity"
:params [{:id request-id}] :params [{:id request-id}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::request-to-join-accepted community-id request-id %]) :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 %)}]}) :on-error #(log/error "failed to accept requests-to-join" community-id request-id %)}]})
(fx/defn decline-request-to-join-pressed (fx/defn decline-request-to-join-pressed
{:events [:communities.ui/decline-request-to-join-pressed]} {:events [:communities.ui/decline-request-to-join-pressed]}
[cofx community-id request-id] [cofx community-id request-id]
{::json-rpc/call [{:method "wakuext_declineRequestToJoinCommunity" {::json-rpc/call [{:method "wakuext_declineRequestToJoinCommunity"
:params [{:id request-id}] :params [{:id request-id}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [::request-to-join-declined community-id request-id %]) :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)}]}) :on-error #(log/error "failed to decline requests-to-join" community-id request-id)}]})
(fx/defn switch-communities-enabled (fx/defn switch-communities-enabled
{:events [:multiaccounts.ui/switch-communities-enabled]} {:events [:multiaccounts.ui/switch-communities-enabled]}
[{:keys [db]} enabled?] [{:keys [db]} enabled?]
{::async-storage/set! {:communities-enabled? enabled?} {::async-storage/set! {:communities-enabled? enabled?}
:db (assoc db :communities/enabled? enabled?)}) :db (assoc db :communities/enabled? enabled?)})
(fx/defn create-category (fx/defn create-category
{:events [::create-category-confirmation-pressed]} {:events [::create-category-confirmation-pressed]}
[_ community-id category-title chat-ids] [_ community-id category-title chat-ids]
{::json-rpc/call [{:method "wakuext_createCommunityCategory" {::json-rpc/call [{:method "wakuext_createCommunityCategory"
:params [{:communityId community-id :params [{:communityId community-id
:categoryName category-title :categoryName category-title
:chatIds (map #(string/replace % community-id "") chat-ids)}] :chatIds (map #(string/replace % community-id "") chat-ids)}]
:js-response true :js-response true
:on-success #(do :on-success #(do
(re-frame/dispatch [:navigate-back]) (re-frame/dispatch [:navigate-back])
(re-frame/dispatch [:sanitize-messages-and-process-response %])) (re-frame/dispatch [:sanitize-messages-and-process-response %]))
:on-error #(log/error "failed to create community category" %)}]}) :on-error #(log/error "failed to create community category" %)}]})
(fx/defn remove-chat-from-category (fx/defn remove-chat-from-category
{:events [:remove-chat-from-community-category]} {:events [:remove-chat-from-community-category]}
[{:keys [db]} community-id id categoryID] [{:keys [db]} community-id id categoryID]
(let [category (get-in db [:communities community-id :categories categoryID]) (let [category (get-in db [:communities community-id :categories categoryID])
category-chats (map :id (filter #(and (= (:categoryID %) categoryID) (not= id (:id %))) category-chats (map :id (filter #(and (= (:categoryID %) categoryID) (not= id (:id %)))
(vals (get-in db [:communities community-id :chats]))))] (vals (get-in db [:communities community-id :chats]))))]
{::json-rpc/call [{:method "wakuext_editCommunityCategory" {::json-rpc/call [{:method "wakuext_editCommunityCategory"
:params [{:communityId community-id :params [{:communityId community-id
:categoryId categoryID :categoryId categoryID
:categoryName (:name category) :categoryName (:name category)
:chatIds category-chats}] :chatIds category-chats}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %]) :on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to remove chat from community" %)}]})) :on-error #(log/error "failed to remove chat from community" %)}]}))
(fx/defn delete-community-chat (fx/defn delete-community-chat
{:events [:delete-community-chat]} {:events [:delete-community-chat]}
[_ community-id chat-id] [_ community-id chat-id]
{::json-rpc/call [{:method "wakuext_deleteCommunityChat" {::json-rpc/call [{:method "wakuext_deleteCommunityChat"
:params [community-id chat-id] :params [community-id chat-id]
:js-response true :js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %]) :on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to delete community chat" %)}]}) :on-error #(log/error "failed to delete community chat" %)}]})
(fx/defn delete-category (fx/defn delete-category
{:events [:delete-community-category]} {:events [:delete-community-category]}
[_ community-id category-id] [_ community-id category-id]
{::json-rpc/call [{:method "wakuext_deleteCommunityCategory" {::json-rpc/call [{:method "wakuext_deleteCommunityCategory"
:params [{:communityId community-id :params [{:communityId community-id
:categoryId category-id}] :categoryId category-id}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %]) :on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to delete community category" %)}]}) :on-error #(log/error "failed to delete community category" %)}]})
(fx/defn change-category (fx/defn change-category
{:events [::change-category-confirmation-pressed]} {:events [::change-category-confirmation-pressed]}
[cofx community-id category-id {:keys [id position categoryID]}] [cofx community-id category-id {:keys [id position categoryID]}]
(if (not (string/blank? category-id)) (if (not (string/blank? category-id))
{::json-rpc/call [{:method "wakuext_reorderCommunityChat" {::json-rpc/call [{:method "wakuext_reorderCommunityChat"
:params [{:communityId community-id :params [{:communityId community-id
:categoryId category-id :categoryId category-id
:chatId id :chatId id
:position position}] :position position}]
:js-response true :js-response true
:on-success #(do :on-success #(do
(re-frame/dispatch [:navigate-back]) (re-frame/dispatch [:navigate-back])
(re-frame/dispatch [:sanitize-messages-and-process-response %])) (re-frame/dispatch [:sanitize-messages-and-process-response %]))
:on-error #(log/error "failed to change community category" %)}]} :on-error #(log/error "failed to change community category" %)}]}
(fx/merge cofx (fx/merge cofx
(navigation/navigate-back) (navigation/navigate-back)
(remove-chat-from-category community-id id categoryID)))) (remove-chat-from-category community-id id categoryID))))
@ -611,22 +612,22 @@
(fx/defn reorder-category-chat (fx/defn reorder-category-chat
{:events [::reorder-community-category-chat]} {:events [::reorder-community-category-chat]}
[_ community-id category-id chat-id new-position] [_ community-id category-id chat-id new-position]
{::json-rpc/call [{:method "wakuext_reorderCommunityChat" {::json-rpc/call [{:method "wakuext_reorderCommunityChat"
:params [{:communityId community-id :params [{:communityId community-id
:categoryId category-id :categoryId category-id
:chatId chat-id :chatId chat-id
:position new-position}] :position new-position}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %]) :on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to reorder community category chat" %)}]}) :on-error #(log/error "failed to reorder community category chat" %)}]})
(fx/defn reorder-category (fx/defn reorder-category
{:events [::reorder-community-category]} {:events [::reorder-community-category]}
[_ community-id category-id new-position] [_ community-id category-id new-position]
{::json-rpc/call [{:method "wakuext_reorderCommunityCategories" {::json-rpc/call [{:method "wakuext_reorderCommunityCategories"
:params [{:communityId community-id :params [{:communityId community-id
:categoryId category-id :categoryId category-id
:position new-position}] :position new-position}]
:js-response true :js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %]) :on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to reorder community category" %)}]}) :on-error #(log/error "failed to reorder community category" %)}]})
@ -679,3 +680,38 @@
(fx/merge cofx (fx/merge cofx
(navigation/pop-to-root-tab :shell-stack) (navigation/pop-to-root-tab :shell-stack)
(navigation/navigate-to-nav2 :community community-id true))) (navigation/navigate-to-nav2 :community community-id true)))
(fx/defn member-role-updated
{:events [:community.member/role-updated]}
[cofx response-js]
(fx/merge cofx
(bottom-sheet/hide-bottom-sheet)
(handle-response response-js)))
(fx/defn add-role-to-member
{:events [:community.member/add-role]}
[cofx community-id public-key role-id]
{::json-rpc/call [{:method "wakuext_addRoleToMember"
:params [{:communityId community-id
:user public-key
:role role-id}]
:on-success #(re-frame/dispatch [:community.member/role-updated %])
:on-error #(log/error "failed to add role to member"
{:error %
:community-id community-id
:public-key public-key
:role-id role-id})}]})
(fx/defn remove-role-from-member
{:events [:community.member/remove-role]}
[_ community-id public-key role-id]
{::json-rpc/call [{:method "wakuext_removeRoleFromMember"
:params [{:communityId community-id
:user public-key
:role role-id}]}
:on-success #(re-frame/dispatch [:community.member/role-updated %])
:on-error #(log/error "failed to remove role from member"
{:error %
:community-id community-id
:public-key public-key
:role-id role-id})]})

View File

@ -198,3 +198,7 @@
(def ^:const sticker-pack-status-owned 3) (def ^:const sticker-pack-status-owned 3)
(def ^:const delete-message-for-me-undo-time-limit-ms 4000) (def ^:const delete-message-for-me-undo-time-limit-ms 4000)
(def ^:const community-member-role-all 1)
(def ^:const community-member-role-manage-users 2)
(def ^:const community-member-role-moderator 3)

View File

@ -16,7 +16,7 @@
(>evt [:bottom-sheet/hide]) (>evt [:bottom-sheet/hide])
(>evt event)) (>evt event))
(defn member-sheet [first-name {:keys [public-key] :as member} community-id can-kick-users? can-manage-users?] (defn member-sheet [first-name {:keys [public-key] :as member} community-id can-kick-users? can-manage-users? admin?]
[:<> [:<>
[quo/list-item [quo/list-item
{:theme :accent {:theme :accent
@ -26,7 +26,7 @@
:subtitle (i18n/label :t/view-profile) :subtitle (i18n/label :t/view-profile)
:accessibility-label :view-chat-details-button :accessibility-label :view-chat-details-button
:chevron true :chevron true
:on-press #(hide-sheet-and-dispatch [:chat.ui/show-profile public-key])}] :on-press #(hide-sheet-and-dispatch [:chat.ui/show-profile public-key])}]
(when can-kick-users? (when can-kick-users?
[:<> [:<>
[quo/separator {:style {:margin-vertical 8}}] [quo/separator {:style {:margin-vertical 8}}]
@ -39,13 +39,20 @@
[quo/list-item {:theme :negative [quo/list-item {:theme :negative
:icon :main-icons/cancel :icon :main-icons/cancel
:title (i18n/label :t/member-ban) :title (i18n/label :t/member-ban)
:on-press #(>evt [::communities/member-ban community-id public-key])}]])]) :on-press #(>evt [::communities/member-ban community-id public-key])}]])
(when admin?
[:<>
[quo/list-item {:theme :accent
:icon :main-icons/make-admin
:title (i18n/label :t/make-moderator)
:on-press #(>evt [:community.member/add-role community-id public-key constants/community-member-role-moderator])}]])])
(defn render-member [public-key _ _ {:keys [community-id (defn render-member [public-key _ _ {:keys [community-id
my-public-key my-public-key
can-manage-users? can-manage-users?
can-kick-users?]}] can-kick-users?
(let [member (<sub [:contacts/contact-by-identity public-key]) admin?]}]
(let [member (<sub [:contacts/contact-by-identity public-key])
[first-name second-name] (<sub [:contacts/contact-two-names-by-identity public-key])] [first-name second-name] (<sub [:contacts/contact-two-names-by-identity public-key])]
[quo/list-item [quo/list-item
{:title first-name {:title first-name
@ -58,7 +65,7 @@
[quo/button {:on-press [quo/button {:on-press
#(>evt [:bottom-sheet/show-sheet #(>evt [:bottom-sheet/show-sheet
{:content (fn [] {:content (fn []
[member-sheet first-name member community-id can-kick-users? can-manage-users?])}]) [member-sheet first-name member community-id can-kick-users? can-manage-users? admin?])}])
:type :icon :type :icon
:theme :icon :theme :icon
:accessibility-label :menu-option} :accessibility-label :menu-option}
@ -74,16 +81,16 @@
[quo/separator {:style {:margin-vertical 8}}]]) [quo/separator {:style {:margin-vertical 8}}]])
(defn requests-to-join [community-id] (defn requests-to-join [community-id]
(let [requests (<sub [:communities/requests-to-join-for-community community-id]) (let [requests (<sub [:communities/requests-to-join-for-community community-id])
requests-count (count requests)] requests-count (count requests)]
[:<> [:<>
[quo/list-item {:chevron true [quo/list-item {:chevron true
:accessory :accessory
[react/view {:flex-direction :row} [react/view {:flex-direction :row}
(when (pos? requests-count) (when (pos? requests-count)
[unviewed-indicator/unviewed-indicator requests-count])] [unviewed-indicator/unviewed-indicator requests-count])]
:on-press #(>evt [:navigate-to :community-requests-to-join {:community-id community-id}]) :on-press #(>evt [:navigate-to :community-requests-to-join {:community-id community-id}])
:title (i18n/label :t/membership-requests)}] :title (i18n/label :t/membership-requests)}]
[quo/separator {:style {:margin-vertical 8}}]])) [quo/separator {:style {:margin-vertical 8}}]]))
(defn members [] (defn members []
@ -91,7 +98,8 @@
(fn [] (fn []
(let [my-public-key (<sub [:multiaccount/public-key]) (let [my-public-key (<sub [:multiaccount/public-key])
{:keys [permissions {:keys [permissions
can-manage-users?]} (<sub [:communities/community community-id]) can-manage-users?
admin]} (<sub [:communities/community community-id])
sorted-members (<sub [:communities/sorted-community-members sorted-members (<sub [:communities/sorted-community-members
community-id])] community-id])]
[:<> [:<>
@ -101,18 +109,19 @@
(when (and can-manage-users? (= constants/community-on-request-access (:access permissions))) (when (and can-manage-users? (= constants/community-on-request-access (:access permissions)))
[requests-to-join community-id]) [requests-to-join community-id])
[rn/flat-list {:data (keys sorted-members) [rn/flat-list {:data (keys sorted-members)
:render-data {:community-id community-id :render-data {:community-id community-id
:my-public-key my-public-key :my-public-key my-public-key
:can-kick-users? (and can-manage-users? :can-kick-users? (and can-manage-users?
(not= (:access permissions) (not= (:access permissions)
constants/community-no-membership-access)) constants/community-no-membership-access))
:can-manage-users? can-manage-users?} :can-manage-users? can-manage-users?
:admin? admin}
:key-fn identity :key-fn identity
:render-fn render-member}]])))) :render-fn render-member}]]))))
(defn members-container [] (defn members-container []
(reagent/create-class (reagent/create-class
{:display-name "community-members-view" {:display-name "community-members-view"
:component-did-mount (fn [] :component-did-mount (fn []
(communities/fetch-requests-to-join! (get (<sub [:get-screen-params]) :community-id))) (communities/fetch-requests-to-join! (get (<sub [:get-screen-params]) :community-id)))
:reagent-render members})) :reagent-render members}))

View File

@ -416,7 +416,7 @@
(re-frame/dispatch [::models.pin-message/show-pin-limit-modal chat-id])) (re-frame/dispatch [::models.pin-message/show-pin-limit-modal chat-id]))
(re-frame/dispatch [::models.pin-message/send-pin-message (assoc message :pinned (not pinned))])))) (re-frame/dispatch [::models.pin-message/send-pin-message (assoc message :pinned (not pinned))]))))
(defn on-long-press-fn [on-long-press {:keys [pinned message-pin-enabled outgoing edit-enabled show-input? community?] :as message} content] (defn on-long-press-fn [on-long-press {:keys [pinned message-pin-enabled outgoing edit-enabled show-input? community? can-delete-message-for-everyone?] :as message} content]
(on-long-press (on-long-press
(concat (concat
(when (and outgoing edit-enabled) (when (and outgoing edit-enabled)
@ -453,7 +453,7 @@
:label (i18n/label :t/delete-for-me) :label (i18n/label :t/delete-for-me)
:icon :i/delete :icon :i/delete
:id :delete-for-me}] :id :delete-for-me}]
(when (and outgoing config/delete-message-enabled?) (when (and (or outgoing can-delete-message-for-everyone?) config/delete-message-enabled?)
[{:type :danger [{:type :danger
:on-press (fn [] :on-press (fn []
(when pinned (pin-message message)) (when pinned (pin-message message))

View File

@ -50,9 +50,9 @@
:height 12}]]]) :height 12}]]])
(defn on-scroll [^js ev] (defn on-scroll [^js ev]
(let [y (-> ev .-nativeEvent .-contentOffset .-y) (let [y (-> ev .-nativeEvent .-contentOffset .-y)
layout-height (-> ev .-nativeEvent .-layoutMeasurement .-height) layout-height (-> ev .-nativeEvent .-layoutMeasurement .-height)
threshold-height (* (/ layout-height 100) threshold-percentage-to-show-floating-scroll-down-button) threshold-height (* (/ layout-height 100) threshold-percentage-to-show-floating-scroll-down-button)
reached-threshold? (> y threshold-height)] reached-threshold? (> y threshold-height)]
(when (not= reached-threshold? @show-floating-scroll-down-button) (when (not= reached-threshold? @show-floating-scroll-down-button)
(rn/configure-next (:ease-in-ease-out rn/layout-animation-presets)) (rn/configure-next (:ease-in-ease-out rn/layout-animation-presets))
@ -65,8 +65,8 @@
(defn list-footer [{:keys [chat-id] :as chat}] (defn list-footer [{:keys [chat-id] :as chat}]
(let [loading-messages? (<sub [:chats/loading-messages? chat-id]) (let [loading-messages? (<sub [:chats/loading-messages? chat-id])
no-messages? (<sub [:chats/chat-no-messages? chat-id]) no-messages? (<sub [:chats/chat-no-messages? chat-id])
all-loaded? (<sub [:chats/all-loaded? chat-id])] all-loaded? (<sub [:chats/all-loaded? chat-id])]
[rn/view {:style (when platform/android? {:scaleY -1})} [rn/view {:style (when platform/android? {:scaleY -1})}
(if (or loading-messages? (not chat-id) (not all-loaded?)) (if (or loading-messages? (not chat-id) (not all-loaded?))
[messages-skeleton/messages-skeleton @messages-view-height] [messages-skeleton/messages-skeleton @messages-view-height]
@ -81,7 +81,7 @@
idx idx
_ _
{:keys [group-chat public? community? current-public-key {:keys [group-chat public? community? current-public-key
chat-id show-input? message-pin-enabled edit-enabled in-pinned-view?]}] chat-id show-input? message-pin-enabled edit-enabled in-pinned-view? can-delete-message-for-everyone?]}]
[rn/view {:style (when (and platform/android? (not in-pinned-view?)) {:scaleY -1})} [rn/view {:style (when (and platform/android? (not in-pinned-view?)) {:scaleY -1})}
(if (= type :datemark) (if (= type :datemark)
[message-datemark/chat-datemark (:value message)] [message-datemark/chat-datemark (:value message)]
@ -97,13 +97,14 @@
:current-public-key current-public-key :current-public-key current-public-key
:show-input? show-input? :show-input? show-input?
:message-pin-enabled message-pin-enabled :message-pin-enabled message-pin-enabled
:edit-enabled edit-enabled)]))]) :edit-enabled edit-enabled
:can-delete-message-for-everyone? can-delete-message-for-everyone?)]))])
(defn on-viewable-items-changed [^js e] (defn on-viewable-items-changed [^js e]
(when @messages-list-ref (when @messages-list-ref
(reset! state/first-not-visible-item (reset! state/first-not-visible-item
(when-let [^js last-visible-element (aget (.-viewableItems e) (dec (.-length ^js (.-viewableItems e))))] (when-let [^js last-visible-element (aget (.-viewableItems e) (dec (.-length ^js (.-viewableItems e))))]
(let [index (.-index last-visible-element) (let [index (.-index last-visible-element)
;; Get first not visible element, if it's a datemark/gap ;; Get first not visible element, if it's a datemark/gap
;; we might unnecessarely add messages on receiving as ;; we might unnecessarely add messages on receiving as
;; they do not have a clock value, but most of the times ;; they do not have a clock value, but most of the times
@ -123,25 +124,26 @@
(if platform/low-device? 700 200)))) (if platform/low-device? 700 200))))
(defn get-render-data [{:keys [group-chat chat-id public? community-id admins space-keeper show-input? edit-enabled in-pinned-view?]}] (defn get-render-data [{:keys [group-chat chat-id public? community-id admins space-keeper show-input? edit-enabled in-pinned-view?]}]
(let [current-public-key (<sub [:multiaccount/public-key]) (let [current-public-key (<sub [:multiaccount/public-key])
community (<sub [:communities/community community-id]) {:keys [can-delete-message-for-everyone?] :as community} (<sub [:communities/community community-id])
group-admin? (get admins current-public-key) group-admin? (get admins current-public-key)
community-admin? (when community (community :admin)) community-admin? (when community (community :admin))
message-pin-enabled (and (not public?) message-pin-enabled (and (not public?)
(or (not group-chat) (or (not group-chat)
(and group-chat (and group-chat
(or group-admin? (or group-admin?
community-admin?))))] community-admin?))))]
{:group-chat group-chat {:group-chat group-chat
:public? public? :public? public?
:community? (not (nil? community-id)) :community? (not (nil? community-id))
:current-public-key current-public-key :current-public-key current-public-key
:space-keeper space-keeper :space-keeper space-keeper
:chat-id chat-id :chat-id chat-id
:show-input? show-input? :show-input? show-input?
:message-pin-enabled message-pin-enabled :message-pin-enabled message-pin-enabled
:edit-enabled edit-enabled :edit-enabled edit-enabled
:in-pinned-view? in-pinned-view?})) :in-pinned-view? in-pinned-view?
:can-delete-message-for-everyone? can-delete-message-for-everyone?}))
(defn messages-view [{:keys [chat (defn messages-view [{:keys [chat
bottom-space bottom-space
@ -149,8 +151,8 @@
mutual-contact-requests-enabled? mutual-contact-requests-enabled?
show-input?]}] show-input?]}]
(let [{:keys [group-chat chat-type chat-id public? community-id admins]} chat (let [{:keys [group-chat chat-type chat-id public? community-id admins]} chat
messages (<sub [:chats/raw-chat-messages-stream chat-id]) messages (<sub [:chats/raw-chat-messages-stream chat-id])
one-to-one? (= chat-type constants/one-to-one-chat-type) one-to-one? (= chat-type constants/one-to-one-chat-type)
contact-added? (when one-to-one? (<sub [:contacts/contact-added? chat-id])) contact-added? (when one-to-one? (<sub [:contacts/contact-added? chat-id]))
should-send-contact-request? should-send-contact-request?
(and (and
@ -179,17 +181,17 @@
:render-fn render-fn :render-fn render-fn
:on-viewable-items-changed on-viewable-items-changed :on-viewable-items-changed on-viewable-items-changed
:on-end-reached list-on-end-reached :on-end-reached list-on-end-reached
:on-scroll-to-index-failed identity ;;don't remove this :on-scroll-to-index-failed identity ;;don't remove this
:content-container-style {:padding-top (+ bottom-space 16) :content-container-style {:padding-top (+ bottom-space 16)
:padding-bottom 16} :padding-bottom 16}
:scroll-indicator-insets {:top bottom-space} ;;ios only :scroll-indicator-insets {:top bottom-space} ;;ios only
:keyboard-dismiss-mode :interactive :keyboard-dismiss-mode :interactive
:keyboard-should-persist-taps :handled :keyboard-should-persist-taps :handled
:onMomentumScrollBegin state/start-scrolling :onMomentumScrollBegin state/start-scrolling
:onMomentumScrollEnd state/stop-scrolling :onMomentumScrollEnd state/stop-scrolling
:scrollEventThrottle 16 :scrollEventThrottle 16
:on-scroll on-scroll :on-scroll on-scroll
;;TODO https://github.com/facebook/react-native/issues/30034 ;;TODO https://github.com/facebook/react-native/issues/30034
:inverted (when platform/ios? true) :inverted (when platform/ios? true)
:style (when platform/android? {:scaleY -1}) :style (when platform/android? {:scaleY -1})
:on-layout on-messages-view-layout})] :on-layout on-messages-view-layout})]

View File

@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>", "_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im", "owner": "status-im",
"repo": "status-go", "repo": "status-go",
"version": "v0.115.2", "version": "v0.115.5",
"commit-sha1": "9227c631c30a88548cf04bed3b32938ef56f71aa", "commit-sha1": "684e9654de4800df619ce593b5d331ebea9ed1a8",
"src-sha256": "1rkfiy9ka7qkka1a08mzs27f358dfvwgjjkcjd68207snis536iz" "src-sha256": "0ci1s3w5jnf6sz2b6hn30gy14hp142gic006r6c3g5ln8y19wdbi"
} }

View File

@ -860,6 +860,7 @@
"main-wallet": "Main Wallet", "main-wallet": "Main Wallet",
"mainnet-network": "Main network", "mainnet-network": "Main network",
"make-admin": "Make admin", "make-admin": "Make admin",
"make-moderator": "Make moderator",
"manage-keys-and-storage": "Manage keys and storage", "manage-keys-and-storage": "Manage keys and storage",
"mark-as-read": "Mark as read", "mark-as-read": "Mark as read",
"mark-all-read": "Mark all read", "mark-all-read": "Mark all read",