Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c964432
feat(messages): Store user that created group/chat
SamShanks1 Jun 5, 2022
767d0e6
fix(messages): createdBy errors
SamShanks1 Jun 5, 2022
7096ea5
feat(messages): remove group member
SamShanks1 Jun 6, 2022
dbae408
fix(messages): get createdBy from db
SamShanks1 Jun 6, 2022
c7b02e2
fix(files): delete accidental upload
SamShanks1 Jun 6, 2022
64dd1ce
feat(messages): leave group chats
SamShanks1 Jun 6, 2022
3168c0c
fix(messages): review changes
SamShanks1 Jun 10, 2022
7bed1b7
fix(messages): event typings
SamShanks1 Jun 10, 2022
ccf1274
fix(messages): nested if statement & error logging
SamShanks1 Jun 10, 2022
1cf33e3
fix(messages): created by defined on server
SamShanks1 Jun 10, 2022
a9748cf
fix(messages): removegroupmember endpoint validation
SamShanks1 Jun 10, 2022
692fafa
chore(messages): cleanup
SamShanks1 Jun 10, 2022
abd0155
chore(messages): cleanup
SamShanks1 Jun 10, 2022
876a3dd
feat(messages): system messages
SamShanks1 Jun 11, 2022
6873390
Merge branch 'master' into master
SamShanks1 Jun 11, 2022
ac580da
fix(messages): errors
SamShanks1 Jun 11, 2022
1f6f048
feat(messages): translations
SamShanks1 Jun 11, 2022
de9541e
feat(messages): use name for avatar
SamShanks1 Jun 11, 2022
3083315
refactor(messages): group chat rework
SamShanks1 Jul 2, 2022
e263c4f
refactor(messages): if owner leaves then set new owner
SamShanks1 Jul 2, 2022
f4126dc
feat: add participants
SamShanks1 Aug 14, 2022
831b92c
Merge branch 'master' into master
SamShanks1 Sep 26, 2022
aea51e1
fix(message): merge mistakes
SamShanks1 Sep 26, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions import.sql
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ CREATE TABLE `npwd_messages_conversations`
`createdAt` TIMESTAMP NOT NULL DEFAULT current_timestamp(),
`updatedAt` TIMESTAMP NOT NULL DEFAULT current_timestamp(),
`last_message_id` INT(11) NULL DEFAULT NULL,
`createdBy` varchar(48) NOT NULL DEFAULT ''
Comment thread
SamShanks1 marked this conversation as resolved.
Outdated
`is_group_chat` TINYINT(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const NewMessageGroupForm = ({ phoneNumber }: { phoneNumber?: string }) => {
conversationLabel: isGroupChat ? conversationLabel : '',
participants: [myPhoneNumber, ...selectedParticipants],
isGroupChat,
createdBy: myPhoneNumber,
Comment thread
SamShanks1 marked this conversation as resolved.
Outdated
};

addConversation(dto);
Expand Down
47 changes: 38 additions & 9 deletions phone/src/apps/messages/components/modal/GroupDetailsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Modal from '@ui/components/Modal';
import { Box, Button, Stack, Typography } from '@mui/material';
import PersonIcon from '@mui/icons-material/Person';
import PersonAddIcon from '@mui/icons-material/PersonAdd';
import PersonRemoveIcon from '@mui/icons-material/PersonRemove';
import { findParticipants } from '../../utils/helpers';
import { useMyPhoneNumber } from '@os/simcard/hooks/useMyPhoneNumber';
import { useContactActions } from '../../../contacts/hooks/useContactActions';
Expand All @@ -11,14 +12,20 @@ interface GroupDetailsModalProps {
open: boolean;
onClose: () => void;
conversationList: string;
createdBy: string;
addContact: (number: any) => void;
removeMember: (number: any) => void;
leaveGroup: () => void;
}

const GroupDetailsModal: React.FC<GroupDetailsModalProps> = ({
open,
onClose,
conversationList,
createdBy,
addContact,
removeMember,
leaveGroup,
}) => {
const myPhoneNumber = useMyPhoneNumber();
const { getContactByNumber } = useContactActions();
Expand All @@ -33,13 +40,14 @@ const GroupDetailsModal: React.FC<GroupDetailsModalProps> = ({
addContact(participant);
};

const handleGroupRemove = (participant: string) => {
removeMember(participant);
};

return (
<Modal visible={open} handleClose={onClose}>
<Box>
<Stack direction="row" spacing={4}>
<Typography fontSize={20}>Details</Typography>
{/*<Button size="small">Add participant</Button>*/}
</Stack>
<Typography fontSize={20}>Details</Typography>
</Box>
{participants.map((participant) => {
const contact = findContact(participant);
Expand All @@ -51,15 +59,36 @@ const GroupDetailsModal: React.FC<GroupDetailsModalProps> = ({
<PersonIcon fontSize="medium" />
<Typography fontSize={18}>{contact?.display ?? participant}</Typography>
</Stack>
{!contact && (
<Button onClick={() => handleAddContact(participant)}>
<PersonAddIcon fontSize="medium" />
</Button>
)}
<Box>
{!contact && (
<Button onClick={() => handleAddContact(participant)}>
<PersonAddIcon fontSize="medium" />
</Button>
)}
{myPhoneNumber === createdBy && (
<Button onClick={() => handleGroupRemove(participant)}>
<PersonRemoveIcon fontSize="medium" />
</Button>
)}
</Box>
</Box>
</Box>
);
})}
<Box
sx={{
mt: 2,
display: 'flex',
justifyContent: 'space-evenly',
}}
>
<Button size="medium" onClick={leaveGroup}>
Leave Group
</Button>
{/* {myPhoneNumber === createdBy && (
Comment thread
SamShanks1 marked this conversation as resolved.
Outdated
<Button size="medium">Add participant</Button>
)} */}
</Box>
</Modal>
);
};
Expand Down
20 changes: 20 additions & 0 deletions phone/src/apps/messages/components/modal/MessageModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export const MessageModal = () => {
const { fetchMessages } = useMessageAPI();
const { getLabelOrContact, getConversationParticipant } = useMessageActions();
const { initializeCall } = useCall();
const { removeGroupMember, leaveGroup } = useMessageAPI();

const { getContactByNumber } = useContactActions();
const [messages, setMessages] = useMessagesState();
Expand Down Expand Up @@ -143,6 +144,22 @@ export const MessageModal = () => {
return history.push(`/contacts/-1/?addNumber=${number}&referal=${referal}`);
};

const handleGroupRemove = (number: string) => {
removeGroupMember(
activeMessageConversation.conversationList,
activeMessageConversation.id,
number,
);
};

const handleLeaveGroup = () => {
leaveGroup(
activeMessageConversation.conversationList,
activeMessageConversation.id,
myPhoneNumber,
);
};

// This only gets used for 1 on 1 conversations
let conversationList = activeMessageConversation.conversationList.split('+');
conversationList = conversationList.filter((targetNumber) => targetNumber !== myPhoneNumber);
Expand All @@ -168,7 +185,10 @@ export const MessageModal = () => {
open={isGroupModalOpen}
onClose={closeGroupModal}
conversationList={activeMessageConversation.conversationList}
createdBy={activeMessageConversation.createdBy}
addContact={handleAddContact}
removeMember={handleGroupRemove}
leaveGroup={handleLeaveGroup}
/>
{isGroupModalOpen && <Backdrop />}
<Box
Expand Down
53 changes: 53 additions & 0 deletions phone/src/apps/messages/hooks/useMessageAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { messageState, useSetMessages } from './state';
import { useRecoilValueLoadable } from 'recoil';
import { MockConversationServerResp } from '../utils/constants';
import { useMyPhoneNumber } from '@os/simcard/hooks/useMyPhoneNumber';
import Conversation from '../components/modal/Conversation';

type UseMessageAPIProps = {
sendMessage: ({ conversationId, message, tgtPhoneNumber }: PreDBMessage) => void;
Expand All @@ -25,6 +26,12 @@ type UseMessageAPIProps = {
deleteConversation: (conversationIds: number[]) => void;
fetchMessages: (conversationId: string, page: number) => void;
setMessageRead: (conversationId: number) => void;
removeGroupMember: (
conversationList: string,
conversationId: number,
phoneNumber: string,
) => void;
leaveGroup: (conversationList: string, conversationId: number, phoneNumber: string) => void;
};

export const useMessageAPI = (): UseMessageAPIProps => {
Expand All @@ -35,6 +42,7 @@ export const useMessageAPI = (): UseMessageAPIProps => {
deleteLocalMessage,
updateLocalConversations,
removeLocalConversation,
removeLocalGroupMember,
setMessageReadState,
} = useMessageActions();
const history = useHistory();
Expand Down Expand Up @@ -136,6 +144,7 @@ export const useMessageAPI = (): UseMessageAPIProps => {
conversationLabel: conversation.conversationLabel,
participants: conversation.participants,
isGroupChat: conversation.isGroupChat,
createdBy: conversation.createdBy,
},
).then((resp) => {
if (resp.status !== 'ok') {
Expand Down Expand Up @@ -178,6 +187,7 @@ export const useMessageAPI = (): UseMessageAPIProps => {
isGroupChat: resp.data.isGroupChat,
unread: 0,
unreadCount: 0,
createdBy: resp.data.createdBy,
});

history.push(`/messages`);
Expand Down Expand Up @@ -236,6 +246,47 @@ export const useMessageAPI = (): UseMessageAPIProps => {
[setMessages, addAlert, t, history],
);

const removeGroupMember = useCallback(
(conversationList: string, conversationId: number, phoneNumber: string) => {
fetchNui<ServerPromiseResp<void>>(MessageEvents.REMOVE_GROUP_MEMBER, {
conversationList,
conversationId,
phoneNumber,
leaveGroup: false,
}).then((resp) => {
if (resp.status !== 'ok') {
return addAlert({
message: t('MESSAGES.FEEDBACK.REMOVE_GROUP_MEMBER_FAILED'),
type: 'error',
});
}
removeLocalGroupMember(conversationId, phoneNumber);
});
},
[addAlert, removeLocalGroupMember, t],
);

const leaveGroup = useCallback(
(conversationList: string, conversationId: number, phoneNumber: string) => {
fetchNui<ServerPromiseResp<void>>(MessageEvents.REMOVE_GROUP_MEMBER, {
conversationList,
conversationId,
phoneNumber,
leaveGroup: true,
}).then((resp) => {
if (resp.status !== 'ok') {
return addAlert({
message: t('MESSAGES.FEEDBACK.LEAVE_GROUP_FAILED'),
type: 'error',
});
}
removeLocalConversation([conversationId]);
return history.push('/messages');
});
},
[addAlert, history, removeLocalConversation, t],
);

return {
sendMessage,
deleteMessage,
Expand All @@ -244,5 +295,7 @@ export const useMessageAPI = (): UseMessageAPIProps => {
fetchMessages,
sendEmbedMessage,
setMessageRead,
removeGroupMember,
leaveGroup,
};
};
24 changes: 24 additions & 0 deletions phone/src/apps/messages/hooks/useMessageActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
useConversationId,
useSetMessageConversations,
useSetMessages,
useMessageConversationsValue,
} from './state';
import { useCallback } from 'react';
import { Message, MessageConversation } from '@typings/messages';
Expand All @@ -19,6 +20,7 @@ interface MessageActionProps {
setMessageReadState: (conversationId: number, unreadCount: number) => void;
getLabelOrContact: (messageConversation: MessageConversation) => string;
getConversationParticipant: (conversationList: string) => Contact | null;
removeLocalGroupMember: (conversationId: number, phoneNumber: string) => void;
}

export const useMessageActions = (): MessageActionProps => {
Expand Down Expand Up @@ -91,6 +93,27 @@ export const useMessageActions = (): MessageActionProps => {
[setMessageConversation, conversationLoading, conversations],
);

const removeLocalGroupMember = useCallback(
(conversationsId: number, phoneNumber: string) => {
setMessageConversation((curVal) =>
curVal.map((conversation) => {
if (conversation.id === conversationsId) {
const conversationListRemove = conversation.conversationList
.split('+')
.filter((number) => number !== phoneNumber)
.join('+');
return {
...conversation,
conversationList: conversationListRemove,
};
}
return conversation;
}),
);
},
[setMessageConversation],
);

const updateLocalMessages = useCallback(
(messageDto: Message) => {
if (messageLoading !== 'hasValue') return;
Expand Down Expand Up @@ -136,5 +159,6 @@ export const useMessageActions = (): MessageActionProps => {
setMessageReadState,
getLabelOrContact,
getConversationParticipant,
removeLocalGroupMember,
};
};
33 changes: 30 additions & 3 deletions phone/src/apps/messages/hooks/useMessageService.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import { useNuiEvent } from 'fivem-nui-react-lib';
import { Message, MessageConversation, MessageEvents } from '@typings/messages';
import {
Message,
MessageConversation,
MessageEvents,
RemoveGroupMemberResponse,
} from '@typings/messages';
import { useMessageActions } from './useMessageActions';
import { useCallback } from 'react';
import { useMessageNotifications } from './useMessageNotifications';
import { useLocation } from 'react-router';
import { useActiveMessageConversation } from './state';

export const useMessagesService = () => {
const { updateLocalMessages, updateLocalConversations, setMessageReadState } =
useMessageActions();
const {
updateLocalMessages,
updateLocalConversations,
setMessageReadState,
removeLocalConversation,
removeLocalGroupMember,
} = useMessageActions();
const { setNotification } = useMessageNotifications();
const { pathname } = useLocation();
const activeConversation = useActiveMessageConversation();
Expand Down Expand Up @@ -42,12 +52,29 @@ export const useMessagesService = () => {
conversationList: conversation.conversationList,
label: conversation.label,
unread: 0,
createdBy: conversation.createdBy,
});
},
[updateLocalConversations],
);

const handleDeleteConversation = useCallback(
(conversationId: number[]) => {
removeLocalConversation(conversationId);
},
[removeLocalConversation],
);

const handleRemoveGroupMember = useCallback(
(conversation: RemoveGroupMemberResponse) => {
removeLocalGroupMember(conversation.conversationId, conversation.phoneNumber);
},
[removeLocalGroupMember],
);

useNuiEvent('MESSAGES', MessageEvents.CREATE_MESSAGE_BROADCAST, handleMessageBroadcast);
useNuiEvent('MESSAGES', MessageEvents.SEND_MESSAGE_SUCCESS, handleUpdateMessages);
useNuiEvent('MESSAGES', MessageEvents.CREATE_MESSAGE_CONVERSATION_SUCCESS, handleAddConversation);
useNuiEvent('MESSAGES', MessageEvents.REMOVE_GROUP_MEMBER_CONVERSATION, handleDeleteConversation);
useNuiEvent('MESSAGES', MessageEvents.REMOVE_GROUP_MEMBER_LIST, handleRemoveGroupMember);
};
2 changes: 2 additions & 0 deletions phone/src/apps/messages/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const MockMessageConversations: MessageConversation[] = [
label: '',
updatedAt: 5,
isGroupChat: false,
createdBy: '111-1134',
},
{
id: 2,
Expand All @@ -19,6 +20,7 @@ export const MockMessageConversations: MessageConversation[] = [
label: 'Secret Project Error chat',
updatedAt: 5,
isGroupChat: true,
createdBy: '111-1134',
},
];

Expand Down
4 changes: 3 additions & 1 deletion phone/src/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,9 @@
"FETCHED_MESSAGES_FAILED": "Failed to retrieve messages",
"DELETE_MESSAGE": "Delete message",
"DELETE_MESSAGE_FAILED": "Failed to delete message",
"DELETE_CONVERSATION_FAILED": "Failed to delete conversation"
"DELETE_CONVERSATION_FAILED": "Failed to delete conversation",
"REMOVE_GROUP_MEMBER_FAILED": "Failed to remove member",
"LEAVE_GROUP_FAILED": "Failed to leave group"
},
"SEARCH_PLACEHOLDER": "Search messages...",
"DELETE_CONVERSATION": "Delete conversation",
Expand Down
Loading