diff --git a/ios/EphemeraMobileChat.xcodeproj/project.pbxproj b/ios/EphemeraMobileChat.xcodeproj/project.pbxproj index 8f1cc98..f240d5a 100644 --- a/ios/EphemeraMobileChat.xcodeproj/project.pbxproj +++ b/ios/EphemeraMobileChat.xcodeproj/project.pbxproj @@ -672,7 +672,11 @@ "-DFOLLY_USE_LIBCPP=1", "-DFOLLY_CFG_NO_COROUTINES=1", ); - OTHER_LDFLAGS = "$(inherited)"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-Wl", + "-ld_classic", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; SWIFT_VERSION = 5.0; @@ -741,7 +745,11 @@ "-DFOLLY_USE_LIBCPP=1", "-DFOLLY_CFG_NO_COROUTINES=1", ); - OTHER_LDFLAGS = "$(inherited)"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-Wl", + "-ld_classic", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; SWIFT_VERSION = 5.0; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index b3bb776..7f8d9a5 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -114,7 +114,7 @@ PODS: - libwebp/sharpyuv (1.3.2) - libwebp/webp (1.3.2): - libwebp/sharpyuv - - LibXMTP (0.4.4-beta5) + - LibXMTP (0.5.0-beta2) - Logging (1.0.0) - MessagePacker (0.4.7) - MMKV (1.3.5): @@ -1240,16 +1240,16 @@ PODS: - GenericJSON (~> 2.0) - Logging (~> 1.0.0) - secp256k1.swift (~> 0.1) - - XMTP (0.10.11): + - XMTP (0.11.1): - Connect-Swift (= 0.12.0) - GzipSwift - - LibXMTP (= 0.4.4-beta5) + - LibXMTP (= 0.5.0-beta2) - web3.swift - - XMTPReactNative (1.33.1-beta.2): + - XMTPReactNative (1.34.0-beta.2): - ExpoModulesCore - MessagePacker - secp256k1.swift - - XMTP (= 0.10.11) + - XMTP (= 0.11.1) - Yoga (1.14.0) DEPENDENCIES: @@ -1588,7 +1588,7 @@ SPEC CHECKSUMS: hermes-engine: b12d9bb1b7cee546f5e48212e7ea7e3c1665a367 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009 - LibXMTP: e2fb601691981900099551ff3e05621bd73dccf1 + LibXMTP: 0a2e98cc3b101e53538c54061633e6587dc861bf Logging: 9ef4ecb546ad3169398d5a723bc9bea1c46bef26 MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02 MMKV: 506311d0494023c2f7e0b62cc1f31b7370fa3cfb @@ -1664,10 +1664,10 @@ SPEC CHECKSUMS: SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1 WatermelonDB: 842d22ba555425aa9f3ce551239a001200c539bc web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959 - XMTP: 1deb40ac712ba315dcfdecd590a9b924d8c2241a - XMTPReactNative: ffc7fb00c38f3d3f8af038ae5d1f9712cac0bb5f - Yoga: e5b887426cee15d2a326bdd34afc0282fc0486ad + XMTP: b2145642aae614c82b8115d479442f58513139b6 + XMTPReactNative: cb23f376c29cd889a4c360eb2d4bb4417bc37690 + Yoga: 2a16e58450c48e110211dae1159fb114bbcdcfc0 PODFILE CHECKSUM: 47641fd2f7a6fc6169785131e7615d136e56edd8 -COCOAPODS: 1.14.3 +COCOAPODS: 1.15.2 diff --git a/package.json b/package.json index cd40931..b5cccc2 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@tanstack/react-query": "^5.36.2", "@tanstack/react-query-persist-client": "^5.36.2", "@xmtp/frames-client": "^0.5.1", - "@xmtp/react-native-sdk": "1.33.1-beta.2", + "@xmtp/react-native-sdk": "1.34.0-beta.2", "aws-sdk": "^2.1540.0", "expo": ">=50.0.0-0 <51.0.0", "fastestsmallesttextencoderdecoder": "1.0.22", diff --git a/src/__mocks__/@xmtp/react-native-sdk.ts b/src/__mocks__/@xmtp/react-native-sdk.ts index ed19fe3..6c30869 100644 --- a/src/__mocks__/@xmtp/react-native-sdk.ts +++ b/src/__mocks__/@xmtp/react-native-sdk.ts @@ -24,7 +24,7 @@ module.exports = { JSContentCodec: jest.fn().mockImplementation(() => { return {}; }), - GroupChangeCodec: jest.fn().mockImplementation(() => { + GroupUpdatedCodec: jest.fn().mockImplementation(() => { return {}; }), ReplyCodec: jest.fn().mockImplementation(() => ({})), diff --git a/src/components/Message.tsx b/src/components/Message.tsx index 9d2c9dc..9f6b0f3 100644 --- a/src/components/Message.tsx +++ b/src/components/Message.tsx @@ -13,11 +13,11 @@ import {ConversationMessageContent} from './messageContent/ConversationMessageCo export interface MessageProps { message: DecodedMessage; - isMe: boolean; + isFromUser: boolean; reactions: MessageIdReactionsMapping[string]; } -export const Message: FC = ({message, isMe, reactions}) => { +export const Message: FC = ({message, isFromUser, reactions}) => { if (message.contentTypeId === ContentTypes.Reaction) { return null; } @@ -25,7 +25,7 @@ export const Message: FC = ({message, isMe, reactions}) => { - {!isMe && ( + {!isFromUser && ( = ({message, isMe, reactions}) => { )} = ({message, isMe, reactions}) => { color={colors.primaryN200} typography="text-xs/semi-bold" alignSelf={ - message.contentTypeId === ContentTypes.GroupMembershipChange + message.contentTypeId === ContentTypes.GroupUpdated ? 'center' - : isMe + : isFromUser ? 'flex-end' : 'flex-start' }> diff --git a/src/components/messageContent/ConversationMessageContent.tsx b/src/components/messageContent/ConversationMessageContent.tsx index 2b96e51..c6c916f 100644 --- a/src/components/messageContent/ConversationMessageContent.tsx +++ b/src/components/messageContent/ConversationMessageContent.tsx @@ -1,6 +1,6 @@ import { DecodedMessage, - GroupChangeContent, + GroupUpdatedContent, RemoteAttachmentContent, } from '@xmtp/react-native-sdk'; import {Container} from 'native-base'; @@ -18,7 +18,7 @@ import {TextMessageContent} from './TextMessageContent'; interface ConversationMessageContentProps { message: DecodedMessage; - isMe: boolean; + isFromUser: boolean; reactions: MessageIdReactionsMapping[string]; } @@ -32,7 +32,7 @@ export type ReactionItems = ReactionItem[]; export const ConversationMessageContent: FC< ConversationMessageContentProps -> = ({message, isMe, reactions}) => { +> = ({message, isFromUser, reactions}) => { const reacts = useMemo(() => { const arr: ReactionItems = []; for (const content of reactions.keys()) { @@ -51,9 +51,9 @@ export const ConversationMessageContent: FC< return ( - + ); } @@ -62,12 +62,12 @@ export const ConversationMessageContent: FC< return ( 0) { if (content?.membersAdded.length > 1) { text = translate('group_add_plural', { - initiatedByAddress: formatAddress( - content?.membersAdded[0].initiatedByAddress ?? '', + initiatedByInboxId: formatAddress( + content?.membersAdded[0].initiatedByInboxId ?? '', ), - addressCount: String(content?.membersAdded.length), + count: String(content?.membersAdded.length), }); } else { text = translate('group_add_single', { - initiatedByAddress: formatAddress( - content?.membersAdded[0].initiatedByAddress, + initiatedByInboxId: formatAddress( + content?.membersAdded[0].initiatedByInboxId, ), - address: formatAddress(content?.membersAdded[0].address), + inboxId: formatAddress(content?.membersAdded[0].inboxId), }); } } else if (content?.membersRemoved.length > 0) { if (content?.membersRemoved.length > 1) { text = translate('group_remove_plural', { - initiatedByAddress: formatAddress( - content?.membersRemoved[0].initiatedByAddress, + initiatedByInboxId: formatAddress( + content?.membersRemoved[0].initiatedByInboxId, ), addressCount: String(content?.membersRemoved.length), }); } else { text = translate('group_remove_single', { - initiatedByAddress: formatAddress( - content?.membersRemoved[0].initiatedByAddress, + initiatedByInboxId: formatAddress( + content?.membersRemoved[0].initiatedByInboxId, ), - address: formatAddress(content?.membersRemoved[0].address), + inboxId: formatAddress(content?.membersRemoved[0].inboxId), }); } } @@ -133,9 +133,9 @@ export const ConversationMessageContent: FC< return ( - + ); } diff --git a/src/components/messageContent/MessageOptionsContainer.tsx b/src/components/messageContent/MessageOptionsContainer.tsx index e865930..3f8fc05 100644 --- a/src/components/messageContent/MessageOptionsContainer.tsx +++ b/src/components/messageContent/MessageOptionsContainer.tsx @@ -17,11 +17,11 @@ import {ReactionItems} from './ConversationMessageContent'; export const MessageOptionsContainer: FC< PropsWithChildren<{ - isMe: boolean; + isFromUser: boolean; messageId: string; reactions: ReactionItems; }> -> = ({children, isMe, messageId, reactions}) => { +> = ({children, isFromUser, messageId, reactions}) => { const [shown, setShown] = useState(false); const {group, setReplyId} = useContext(GroupContext); @@ -75,8 +75,8 @@ export const MessageOptionsContainer: FC< {children} {reactions.length > 0 && ( diff --git a/src/components/messageContent/ReplyMessageContent.tsx b/src/components/messageContent/ReplyMessageContent.tsx index 013bb6a..5076503 100644 --- a/src/components/messageContent/ReplyMessageContent.tsx +++ b/src/components/messageContent/ReplyMessageContent.tsx @@ -16,12 +16,12 @@ import {ImageMessage} from '../ImageMessage'; interface ReplyMessageContentProps { message: DecodedMessage; - isMe: boolean; + isFromUser: boolean; } export const ReplyMessageContent = ({ message, - isMe, + isFromUser, }: ReplyMessageContentProps) => { const {scrollToMessage} = useContext(GroupContext); @@ -39,17 +39,19 @@ export const ReplyMessageContent = ({ return ( + color={ + isFromUser ? colors.actionPrimaryText : colors.textPrimary + }> {textContent.text} @@ -61,7 +63,7 @@ export const ReplyMessageContent = ({ default: return null; } - }, [isMe, reply]); + }, [isFromUser, reply]); const handlePress = useCallback(() => { if (reply.reference) { @@ -75,8 +77,8 @@ export const ReplyMessageContent = ({ return ( + borderBottomRightRadius={isFromUser ? 0 : '16px'} + borderTopLeftRadius={isFromUser ? '16px' : 0}> {translate('replied_to')} diff --git a/src/components/messageContent/TextMessageContent.tsx b/src/components/messageContent/TextMessageContent.tsx index 1e30a1e..38167e9 100644 --- a/src/components/messageContent/TextMessageContent.tsx +++ b/src/components/messageContent/TextMessageContent.tsx @@ -10,10 +10,10 @@ import {Button as AppButton} from '../common/Button'; import {Text} from '../common/Text'; export const TextMessageContent = ({ - isMe, + isFromUser, message, }: { - isMe: boolean; + isFromUser: boolean; message: DecodedMessage; }) => { const {width} = useWindowDimensions(); @@ -22,16 +22,16 @@ export const TextMessageContent = ({ return ( + color={isFromUser ? colors.actionPrimaryText : colors.textPrimary}> {message.content() as string} @@ -43,10 +43,10 @@ export const TextMessageContent = ({ return ( { const newMessages = updateFn(prevMessages); expect(newMessages).toEqual([mockMessage, ...prevMessages]); - if (mockMessage.contentTypeId === ContentTypes.GroupMembershipChange) { + if (mockMessage.contentTypeId === ContentTypes.GroupUpdated) { await act(async () => { await mockGroup.sync(); const addresses = await mockGroup.memberAddresses(); diff --git a/src/hooks/useGroupMessages.ts b/src/hooks/useGroupMessages.ts index 4e80102..ee75444 100644 --- a/src/hooks/useGroupMessages.ts +++ b/src/hooks/useGroupMessages.ts @@ -19,9 +19,9 @@ export const useGroupMessages = (topic: string) => { [QueryKeys.GroupMessages, topic], prevMessages => [message, ...(prevMessages ?? [])], ); - if (message.contentTypeId === ContentTypes.GroupMembershipChange) { + if (message.contentTypeId === ContentTypes.GroupUpdated) { await group.sync(); - const addresses = await group.memberAddresses(); + const addresses = await group.memberInboxIds(); queryClient.setQueryData( [QueryKeys.GroupParticipants, topic], addresses, diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index f55a45b..7809161 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -61,10 +61,10 @@ "message_requests_from_new_addresses": "Message requests from addresses you’ve never interacted with show up here", "not_on_xmtp_group": "User can't be added to group because they are not on XMTP Group network", "wallet_error": "Wallet Error", - "group_add_single": "%{initiatedByAddress} added %{address}", - "group_add_plural": "%{initiatedByAddress} added %{addressCount} members", - "group_remove_single": "%{initiatedByAddress} removed %{address}", - "group_remove_plural": "%{initiatedByAddress} removed %{addressCount} members", + "group_add_single": "%{initiatedByInboxId} added %{inboxId}", + "group_add_plural": "%{initiatedByInboxId} added %{count} members", + "group_remove_single": "%{initiatedByInboxId} removed %{inboxId}", + "group_remove_plural": "%{initiatedByInboxId} removed %{count} members", "error_group_remove": "An error occurred removing from group", "error_group_adding": "An error occurred adding to group", "reply": "Reply", diff --git a/src/queries/useFirstGroupMessageQuery.ts b/src/queries/useFirstGroupMessageQuery.ts index f9bfc67..43094a4 100644 --- a/src/queries/useFirstGroupMessageQuery.ts +++ b/src/queries/useFirstGroupMessageQuery.ts @@ -19,7 +19,7 @@ export const useFirstGroupMessageQuery = (topic: string) => { return undefined; } const messages: DecodedMessage[] = - await group.messages(false, { + await group.messages({ // limit: 1, // direction: 'SORT_DIRECTION_ASCENDING', }); diff --git a/src/queries/useGroupParticipantsQuery.ts b/src/queries/useGroupParticipantsQuery.ts index 86b5199..42f28cc 100644 --- a/src/queries/useGroupParticipantsQuery.ts +++ b/src/queries/useGroupParticipantsQuery.ts @@ -32,7 +32,7 @@ export const useGroupParticipantsQuery = (topic: string) => { return []; } await withRequestLogger(group.sync(), {name: 'group_sync'}); - return withRequestLogger(group.memberAddresses(), { + return withRequestLogger(group.memberInboxIds(), { name: 'group_members', }); }, diff --git a/src/screens/CreateGroupScreen.tsx b/src/screens/CreateGroupScreen.tsx index ff7998f..24a5f96 100644 --- a/src/screens/CreateGroupScreen.tsx +++ b/src/screens/CreateGroupScreen.tsx @@ -192,9 +192,17 @@ export const CreateGroupScreen = () => { const {recents, contacts} = useData(); const onItemPress = useCallback( (item: Contact) => { + if ( + participants.some(participant => participant.address === item.address) + ) { + setParticipants(prev => + prev.filter(participant => participant.address !== item.address), + ); + return; + } setParticipants(prev => [...prev, item]); }, - [setParticipants], + [participants], ); const onGroupStart = useCallback(async () => { diff --git a/src/screens/GroupScreen.tsx b/src/screens/GroupScreen.tsx index 8f39724..4e51dd7 100644 --- a/src/screens/GroupScreen.tsx +++ b/src/screens/GroupScreen.tsx @@ -149,11 +149,17 @@ export const GroupScreen = () => { return null; } const reactions = reactionsEntities?.[item] ?? new Map(); - const isMe = + const isFromUser = message.senderAddress?.toLocaleLowerCase() === - myAddress?.toLocaleLowerCase(); + client?.inboxId?.toLocaleLowerCase(); - return ; + return ( + + ); }; const setReply = useCallback( diff --git a/src/screens/NewConversationScreen.tsx b/src/screens/NewConversationScreen.tsx index 1cd8ef9..9c9408e 100644 --- a/src/screens/NewConversationScreen.tsx +++ b/src/screens/NewConversationScreen.tsx @@ -35,7 +35,7 @@ export const NewConversationScreen = () => { try { const group = await client?.conversations.newGroup( addresses, - 'creator_admin', + 'all_members', ); if (!group) { Alert.alert('Error creating group'); diff --git a/yarn.lock b/yarn.lock index b1b0277..7144a98 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4892,10 +4892,10 @@ rxjs "^7.8.0" undici "^5.8.1" -"@xmtp/react-native-sdk@1.33.1-beta.2": - version "1.33.1-beta.2" - resolved "https://registry.yarnpkg.com/@xmtp/react-native-sdk/-/react-native-sdk-1.33.1-beta.2.tgz#876b2ea00be1aa5fc37260f8f810a3150512b97c" - integrity sha512-4lHWFk/A/vaJP/YTDuTkugD8+bue1Gq4wFIsny+t0CMuhGQf06VGPIZ5l/i3NtzDkPV1U48trzuA8Uk5Hcn4xA== +"@xmtp/react-native-sdk@1.34.0-beta.2": + version "1.34.0-beta.2" + resolved "https://registry.yarnpkg.com/@xmtp/react-native-sdk/-/react-native-sdk-1.34.0-beta.2.tgz#d1972a40867698f97bc7e301409c1b2d8d7716cc" + integrity sha512-JhfQKM+WXUSc6VfwE66yGrhYLtuXWWgYdaE7B1IMGmulaXZZ1MqcDw67F0RX5Ls2GZTk7KlVo69bxHX+V4t6LQ== dependencies: "@ethersproject/bytes" "^5.7.0" "@msgpack/msgpack" "^3.0.0-beta2"