Skip to content

Commit

Permalink
feat: Groups iOS
Browse files Browse the repository at this point in the history
Also native codec for group change
  • Loading branch information
Alex Risch authored and Alex Risch committed Feb 15, 2024
1 parent 86a9720 commit 7514590
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ import org.xmtp.android.library.codecs.description
import org.xmtp.android.library.codecs.getReactionAction
import org.xmtp.android.library.codecs.getReactionSchema
import org.xmtp.android.library.codecs.id
import uniffi.xmtpv3.org.xmtp.android.library.codecs.ContentTypeGroupMembershipChange
import uniffi.xmtpv3.org.xmtp.android.library.codecs.GroupMembershipChangeCodec
import uniffi.xmtpv3.org.xmtp.android.library.codecs.GroupMembershipChanges
import java.net.URL

class ContentJson(
Expand All @@ -51,6 +54,7 @@ class ContentJson(
Client.register(RemoteAttachmentCodec())
Client.register(ReplyCodec())
Client.register(ReadReceiptCodec())
Client.register(GroupMembershipChangeCodec())
}

fun fromJsonObject(obj: JsonObject): ContentJson {
Expand Down Expand Up @@ -171,6 +175,21 @@ class ContentJson(
"readReceipt" to ""
)

ContentTypeGroupMembershipChange.id -> mapOf(
"groupChange" to mapOf(
"membersAdded" to (content as GroupMembershipChanges).membersAddedList.map {
mapOf(
"address" to it.accountAddress,
"initiatedByAddress" to it.initiatedByAccountAddress
)},
"membersRemoved" to content.membersRemovedList.map {
mapOf(
"address" to it.accountAddress,
"initiatedByAddress" to it.initiatedByAccountAddress
)},
)
)

else -> {
val json = JsonObject()
encodedContent?.let {
Expand Down
56 changes: 50 additions & 6 deletions example/src/GroupScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as ImagePicker from 'expo-image-picker'
import type { ImagePickerAsset } from 'expo-image-picker'
import { PermissionStatus } from 'expo-modules-core'
import moment from 'moment'
import React, { useCallback, useMemo, useRef, useState } from 'react'
import React, { FC, useCallback, useMemo, useRef, useState } from 'react'

Check warning on line 11 in example/src/GroupScreen.tsx

View workflow job for this annotation

GitHub Actions / lint

'FC' is defined but never used
import {
Button,
FlatList,
Expand All @@ -31,6 +31,7 @@ import {
StaticAttachmentContent,
ReplyContent,
useClient,
GroupChangeContent,
} from 'xmtp-react-native-sdk'
import { ConversationSendPayload } from 'xmtp-react-native-sdk/lib/types'

Expand Down Expand Up @@ -1058,6 +1059,53 @@ function RemoteAttachmentMessageContents({
)
}

function formatAddress(address: string) {
return `${address.slice(0, 6)}${address.slice(-4)}`
}

function GroupChangeContents({ content }: { content: GroupChangeContent }) {
return (
<>
{content.membersAdded.length > 0 &&
(content.membersAdded.length === 1 ? (
<Text style={{ opacity: 0.5, fontStyle: 'italic' }}>
{`${formatAddress(
content.membersAdded[0].address
)} has been added by ${formatAddress(
content.membersAdded[0].initiatedByAddress
)}`}
</Text>
) : (
<Text style={{ opacity: 0.5, fontStyle: 'italic' }}>
{`${
content.membersAdded.length
} members have been added by ${formatAddress(
content.membersAdded[0].initiatedByAddress
)}`}
</Text>
))}
{content.membersRemoved.length > 0 &&
(content.membersRemoved.length === 1 ? (
<Text style={{ opacity: 0.5, fontStyle: 'italic' }}>
{`${formatAddress(
content.membersRemoved[0].address
)} has been removed by ${formatAddress(
content.membersRemoved[0].initiatedByAddress
)}`}
</Text>
) : (
<Text style={{ opacity: 0.5, fontStyle: 'italic', flexWrap: 'wrap' }}>
{`${
content.membersRemoved.length
} members have been removed by ${formatAddress(
content.membersRemoved[0].initiatedByAddress
)}`}
</Text>
))}
</>
)
}

function MessageContents({
contentTypeId,
content,
Expand Down Expand Up @@ -1113,11 +1161,7 @@ function MessageContents({
)
}
if (contentTypeId === 'xmtp.org/group_membership_change:1.0') {
return (
<Text style={{ opacity: 0.5, fontStyle: 'italic' }}>
Group members have changed
</Text>
)
return <GroupChangeContents content={content} />
}

return (
Expand Down
9 changes: 6 additions & 3 deletions src/lib/NativeCodecs/GroupChangeCodec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import {
ContentTypeId,
GroupChangeContent,
NativeContentCodec,
NativeMessageContent,
} from '../ContentCodec'

export class GroupChangeCodec implements NativeContentCodec<string> {
export class GroupChangeCodec
implements NativeContentCodec<GroupChangeContent>
{
contentKey: 'groupChange' = 'groupChange'
contentType: ContentTypeId = {
authorityId: 'xmtp.org',
Expand All @@ -17,8 +20,8 @@ export class GroupChangeCodec implements NativeContentCodec<string> {
return {}
}

decode(nativeContent: NativeMessageContent): string {
return nativeContent.text!
decode(nativeContent: NativeMessageContent): GroupChangeContent {
return nativeContent.groupChange!
}

fallback(): string | undefined {
Expand Down
11 changes: 11 additions & 0 deletions src/lib/types/ContentCodec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ export type RemoteAttachmentContent = RemoteAttachmentMetadata & {
url: string
}

export type GroupChangeEntry = {
address: string
initiatedByAddress: string
}

export type GroupChangeContent = {
membersAdded: GroupChangeEntry[]
membersRemoved: GroupChangeEntry[]
}

// This contains a message that has been prepared for sending.
// It contains the message ID and the URI of a local file
// containing the payload that needs to be published.
Expand Down Expand Up @@ -91,6 +101,7 @@ export type NativeMessageContent = {
remoteAttachment?: RemoteAttachmentContent
readReceipt?: ReadReceiptContent
encoded?: string
groupChange?: GroupChangeContent
}

export interface JSContentCodec<T> {
Expand Down

0 comments on commit 7514590

Please sign in to comment.