Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"validate-llms-txt": "node bin/validate-llms.txt.ts"
},
"dependencies": {
"@ably/ui": "17.9.16",
"@ably/ui": "17.11.4",
"@codesandbox/sandpack-react": "^2.20.0",
"@codesandbox/sandpack-themes": "^2.0.21",
"@gfx/zopfli": "^1.0.15",
Expand Down
3 changes: 2 additions & 1 deletion src/data/languages/languageData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ export default {
javascript: '1.1',
react: '1.1',
swift: '1.0',
kotlin: '1.0',
kotlin: '1.1',
jetpack: '1.1',
},
spaces: {
javascript: '0.4',
Expand Down
4 changes: 4 additions & 0 deletions src/data/languages/languageInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ export default {
label: 'Kotlin',
syntaxHighlighterKey: 'kotlin',
},
jetpack: {
label: 'Jetpack Compose',
syntaxHighlighterKey: 'kotlin',
},
realtime: {
label: 'Realtime',
syntaxHighlighterKey: 'javascript',
Expand Down
1 change: 1 addition & 0 deletions src/data/languages/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const languageKeys = [
'css',
'laravel',
'typescript',
'jetpack',
] as const;

export type LanguageKey = (typeof languageKeys)[number];
Expand Down
52 changes: 49 additions & 3 deletions src/pages/docs/chat/connect.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ A connection can have any of the following statuses:
| closed | The connection has been explicitly closed by the client. In the closed state, no reconnection attempts are made automatically. No connection state is preserved by the service or the library. |
| failed | This status is entered if the SDK encounters a failure condition that it cannot recover from. This may be a fatal connection error received from the Ably service, such as an attempt to connect with an incorrect API key, or some local terminal error, such as that the token in use has expired and the SDK does not have any way to renew it. |

<If lang="javascript,swift,kotlin">
Use the <If lang="javascript">[`status`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Connection.html#status)</If><If lang="swift">[`status`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/connectionstatus)</If><If lang="kotlin">[`status`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-connection/status.html)</If> property to check which status a connection is currently in:
<If lang="javascript,swift,kotlin,jetpack">
Use the <If lang="javascript">[`status`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Connection.html#status)</If><If lang="swift">[`status`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/connectionstatus)</If><If lang="kotlin,jetpack">[`status`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-connection/status.html)</If> property to check which status a connection is currently in:
</If>

<If lang="react">
Expand Down Expand Up @@ -56,6 +56,10 @@ let status = chatClient.connection.status
```kotlin
val connectionStatus = chatClient.connection.status
```

```jetpack
val connectionStatus = chatClient.connection.status
```
</Code>

<If lang="react">
Expand All @@ -81,7 +85,11 @@ Listeners can also be registered to monitor the changes in connection status. An
</If>

<If lang="javascript,swift,kotlin">
Use the <If lang="javascript">[`connection.onStatusChange()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Connection.html#onStatusChange)</If><If lang="swift">[`connection.onStatusChange()`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/connection/onstatuschange%28%29-76t7)</If><If lang="kotlin">[`connection.status.onStatusChange()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-connection/on-status-change.html)</If> method to register a listener for status change updates:
Use the <If lang="javascript">[`connection.onStatusChange()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Connection.html#onStatusChange)</If><If lang="swift">[`connection.onStatusChange()`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/connection/onstatuschange%28%29-76t7)</If><If lang="kotlin">[`connection.onStatusChange()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-connection/on-status-change.html)</If> method to register a listener for status change updates:
</If>

<If lang="jetpack">
Use the [`collectAsStatus()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/jetpack/chat-extensions-compose/com.ably.chat.extensions.compose/collect-as-status.html) composable function to observe the connection status:
</If>

<Code>
Expand Down Expand Up @@ -114,6 +122,24 @@ val (off) = chatClient.connection.onStatusChange { statusChange: ConnectionStatu
println(statusChange.toString())
}
```

```jetpack
import androidx.compose.material.*
import androidx.compose.runtime.*
import com.ably.chat.ChatClient
import com.ably.chat.extensions.compose.collectAsStatus

@Composable
fun MyComponent(chatClient: ChatClient) {
val connectionStatus by chatClient.connection.collectAsStatus()

LaunchedEffect(connectionStatus) {
println("Connection status changed to: $connectionStatus")
}

Text("Connection status: $connectionStatus")
}
```
</Code>

<If lang="javascript,kotlin">
Expand Down Expand Up @@ -148,6 +174,10 @@ The Chat SDK provides an `onDiscontinuity()` handler exposed via the Room object
Any hooks that take an optional listener to monitor their events, such as typing indicator events in the `useTyping` hook, can also register a listener to be notified of, and handle, periods of discontinuity.
</If>

<If lang="jetpack">
Use the [`discontinuityAsFlow()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/discontinuity-as-flow.html) extension function to observe discontinuity events as a Flow in Jetpack Compose:
</If>

For example, for messages:

<Code>
Expand Down Expand Up @@ -184,6 +214,22 @@ val (off) = room.onDiscontinuity { reason: ErrorInfo ->
// Recover from the discontinuity
}
```

```jetpack
import androidx.compose.runtime.*
import com.ably.chat.Room
import com.ably.chat.discontinuityAsFlow

@Composable
fun MyComponent(room: Room) {
LaunchedEffect(room) {
room.discontinuityAsFlow().collect { error ->
// Recover from the discontinuity
println("Discontinuity detected: $error")
}
}
}
```
</Code>

<If lang="javascript,kotlin">
Expand Down
45 changes: 21 additions & 24 deletions src/pages/docs/chat/getting-started/android.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ fun ChatBox(room: Room?) {
var sending by remember { mutableStateOf(false) }
val messages = remember { mutableStateListOf<Message>() }

DisposableEffect(room) {
val subscription = room?.messages?.subscribe { event ->
LaunchedEffect(room) {
room?.messages?.asFlow()?.collect { event ->
when (event.type) {
MessageEventType.Created -> {
// Check if the incoming message is correctly ordered
Expand All @@ -266,10 +266,6 @@ fun ChatBox(room: Room?) {
else -> Unit
}
}

onDispose {
subscription?.unsubscribe()
}
}

Column(
Expand Down Expand Up @@ -445,8 +441,8 @@ var edited: Message? by remember { mutableStateOf(null) }

<Code>
```kotlin
DisposableEffect(room) {
val subscription = room?.messages?.subscribe { event ->
LaunchedEffect(room) {
room?.messages?.asFlow()?.collect { event ->
when (event.type) {
MessageEventType.Created -> messages.add(0, event.message)
MessageEventType.Updated -> messages.replaceFirstWith(event.message) {
Expand All @@ -455,10 +451,6 @@ DisposableEffect(room) {
else -> Unit
}
}

onDispose {
subscription?.unsubscribe()
}
}
```
</Code>
Expand Down Expand Up @@ -543,17 +535,18 @@ When you click on the edit button in the UI, you can modify the text and it will

## Step 6: Message history and continuity <a id="step-6"/>

Ably Chat enables you to retrieve previously sent messages in a room. This is useful for providing conversational context when a user first joins a room, or when they subsequently rejoin it later on. The message subscription object exposes the [`getPreviousMessages()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-messages-subscription/get-previous-messages.html) method to enable this functionality. This method returns a paginated response, which can be queried further to retrieve the next set of messages.
Ably Chat enables you to retrieve previously sent messages in a room. This is useful for providing conversational context when a user first joins a room, or when they subsequently rejoin it later on. The message subscription object exposes the [`historyBeforeSubscribe()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-messages-subscription/history-before-subscribe.html) method to enable this functionality. This method returns a paginated response, which can be queried further to retrieve the next set of messages.

Extend the `ChatBox` component to include a method to retrieve the last 10 messages when the component mounts. In your `MainActivity.kt` file, add the `DisposableEffect` in your `ChatBox` component:

<Code>
```kotlin
fun ChatBox(room: Room?) {
/* variables declaration */
var subscription by remember { mutableStateOf<MessagesSubscription?>(null) }

DisposableEffect(room) {
val subscription = room?.messages?.subscribe { event ->
subscription = room?.messages?.subscribe { event ->
when (event.type) {
MessageEventType.Created -> messages.add(0, event.message)
MessageEventType.Updated -> messages.replaceFirstWith(event.message) {
Expand All @@ -563,16 +556,19 @@ fun ChatBox(room: Room?) {
}
}

scope.launch {
val previousMessages = subscription?.historyBeforeSubscribe(10)?.items ?: emptyList()
messages.addAll(previousMessages)
}

onDispose {
subscription?.unsubscribe()
}
}
/* rest of your code */
}

LaunchedEffect(subscription) {
subscription?.let { sub ->
val previousMessages = sub.historyBeforeSubscribe(10)?.items ?: emptyList()
messages.addAll(previousMessages)
}
}

/* rest of your code */
}
```
</Code>
Expand Down Expand Up @@ -709,7 +705,7 @@ fun ChatBox(room: Room?) {
Do the following to test this out:

1. Use the ably CLI to simulate sending some messages to the room from another client.
2. Refresh the page, this will cause the `ChatBox` component to mount again and call the `getPreviousMessages()` method.
2. Refresh the page, this will cause the `ChatBox` component to mount again and call the `historyBeforeSubscribe()` method.
3. You'll see the last 10 messages appear in the chat box.

## Step 7: Display who is present in the room <a id="step-7"/>
Expand All @@ -722,14 +718,15 @@ In your `MainActivity.kt` file, create a new component called `PresenceStatusUi`
```kotlin
@Composable
fun PresenceStatusUi(room: Room?) {
val members = room?.collectAsPresenceMembers()
val membersState = room?.collectAsPresenceMembers()
val members = membersState?.value ?: emptyList()

LaunchedEffect(room) {
room?.presence?.enter()
}

Text(
text = "Online: ${members?.size ?: 0}",
text = "Online: ${members.size}",
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.padding(start = 8.dp)
)
Expand Down
Loading