From bf86a3ab916db132c10cc35189a25d6bff4c8a8f Mon Sep 17 00:00:00 2001
From: "Lucian I. Last"
Date: Mon, 23 Sep 2024 18:00:31 +0200
Subject: [PATCH] Add ban user
---
app/src/components/Chat/ChatPost.tsx | 16 ++---
app/src/components/Chat/ChatPostList.tsx | 82 ++++++++++++++++++------
app/src/pages/Chat.tsx | 10 +++
3 files changed, 79 insertions(+), 29 deletions(-)
diff --git a/app/src/components/Chat/ChatPost.tsx b/app/src/components/Chat/ChatPost.tsx
index 62ddb4afa..061aaf264 100644
--- a/app/src/components/Chat/ChatPost.tsx
+++ b/app/src/components/Chat/ChatPost.tsx
@@ -6,6 +6,7 @@ import { IonButton, IonIcon, IonItem, IonModal, IonText } from "@ionic/react";
import { ellipsisVertical } from "ionicons/icons";
import { useTranslation } from "react-i18next";
import { ChannelMessage, User as UserProfile } from "@heroiclabs/nakama-js";
+import { PostActionSheetOpen } from "./ChatPostList";
export interface ChatPostProps {
post: ChannelMessage;
@@ -14,14 +15,12 @@ export interface ChatPostProps {
getMmUser: (id: string) => Promise;
// getFile: (fileId: string, timestamp: number) => void;
isChainAdmin: boolean;
- onLongPress: (id: string) => void;
+ onLongPress: (o: PostActionSheetOpen) => void;
}
export default function ChatPost(props: ChatPostProps) {
- const { t } = useTranslation();
-
const longPress = useLongPress((e) => {
- props.onLongPress(props.post.message_id!);
+ props.onLongPress({ post: props.post, isMe });
});
const [username, setUsername] = useState("");
const [isMe, setIsMe] = useState(false);
@@ -200,8 +199,8 @@ export default function ChatPost(props: ChatPostProps) {
return (
@@ -219,13 +218,14 @@ export default function ChatPost(props: ChatPostProps) {
{message}
- {props.isChainAdmin ? (
+ {props.isChainAdmin || isMe ? (
props.onLongPress(props.post.message_id!)}
+ onClick={() => props.onLongPress({ post: props.post, isMe })}
color="transparent"
className="tw-sticky tw-top-0 tw-opacity-70"
size="small"
type="button"
+ shape="round"
>
void;
chainUsers: User[];
onDeletePost: (id: string) => void;
+ onBanSender: (id: string) => void;
+}
+
+export interface PostActionSheetOpen {
+ post: ChannelMessage;
+ isMe: boolean;
}
export default function ChatPostList(props: Props) {
const { t } = useTranslation();
- const [isPostActionSheetOpen, setIsPostActionSheetOpen] = useState<
- string | null
- >(null);
+ const [isPostActionSheetOpen, setIsPostActionSheetOpen] =
+ useState(null);
const [presentAlert] = useIonAlert();
+ const { isChainAdmin, authUser } = useContext(StoreContext);
+
+ const postActionButtons = useMemo(() => {
+ const list: ActionSheetButton[] = [
+ {
+ text: t("delete"),
+ role: "destructive",
+ handler: () => handlePostOptionSelect("delete"),
+ },
+ ];
+
+ if (isChainAdmin && isPostActionSheetOpen?.isMe === false) {
+ list.push({
+ text: t("ban"),
+ role: "destructive",
+ handler: () => handlePostOptionSelect("ban"),
+ });
+ }
+ list.push({
+ text: t("cancel"),
+ role: "cancel",
+ });
+ return list;
+ }, [isChainAdmin, isPostActionSheetOpen]);
- function handlePostOptionSelect(value: "delete") {
+ function handlePostOptionSelect(value: "delete" | "ban") {
if (value == "delete") {
- const postID = isPostActionSheetOpen;
- if (!postID) return;
+ if (!isPostActionSheetOpen) return;
+ const postID = isPostActionSheetOpen.post.message_id!;
presentAlert({
header: "Delete post?",
buttons: [
@@ -40,6 +74,22 @@ export default function ChatPostList(props: Props) {
},
],
});
+ } else if (value == "ban") {
+ if (!isPostActionSheetOpen) return;
+ const postUser = isPostActionSheetOpen.post.sender_id!;
+ presentAlert({
+ header: "Ban user?",
+ buttons: [
+ {
+ text: t("cancel"),
+ },
+ {
+ role: "destructive",
+ text: t("ban"),
+ handler: () => props.onBanSender(postUser),
+ },
+ ],
+ });
}
}
@@ -52,7 +102,7 @@ export default function ChatPostList(props: Props) {
setIsPostActionSheetOpen(id)}
+ onLongPress={(o) => setIsPostActionSheetOpen(o)}
post={post}
getMmUser={props.getMmUser}
// getFile={props.getFile}
@@ -65,17 +115,7 @@ export default function ChatPostList(props: Props) {
setIsPostActionSheetOpen(null)}
- buttons={[
- {
- text: t("delete"),
- role: "destructive",
- handler: () => handlePostOptionSelect("delete"),
- },
- {
- text: t("cancel"),
- role: "cancel",
- },
- ]}
+ buttons={postActionButtons}
>
>
);
diff --git a/app/src/pages/Chat.tsx b/app/src/pages/Chat.tsx
index fc9156c16..0313077d3 100644
--- a/app/src/pages/Chat.tsx
+++ b/app/src/pages/Chat.tsx
@@ -280,6 +280,15 @@ export default function Chat() {
});
}
+ function onBanSender(senderID: string) {
+ if (!nakamaClient || !nakama.socket || !nakama.session || !selectedGroup)
+ return;
+ console.info("banning user");
+ nakamaClient.banGroupUsers(nakama.session, selectedGroup.group!.id!, [
+ senderID,
+ ]);
+ }
+
async function onSelectGroup(group: UserGroup) {
if (nakama.socket && selectedGroup)
nakama.socket.leaveChat(selectedGroup.group!.id!);
@@ -448,6 +457,7 @@ export default function Chat() {
// getFile={getFile}
postList={postList}
chainUsers={chainUsers}
+ onBanSender={onBanSender}
onDeletePost={onDeletePost}
/>
) : (