Skip to content

Commit

Permalink
[CHAT-4902] feat: add chat room skeleton and default implementations …
Browse files Browse the repository at this point in the history
…for main classes

In this PR most of the methods in the default implementations throws exceptions. We focused on happy path getting client, creating room, attaching to the room (without any corner cases)
  • Loading branch information
ttypic committed Sep 3, 2024
1 parent 1a5dea1 commit f073028
Show file tree
Hide file tree
Showing 10 changed files with 365 additions and 2 deletions.
26 changes: 25 additions & 1 deletion chat-android/src/main/java/com/ably/chat/ChatClient.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
@file:Suppress("StringLiteralDuplication", "NotImplementedDeclaration")

package com.ably.chat

import io.ably.lib.realtime.AblyRealtime
import io.ably.lib.types.ClientOptions

typealias RealtimeClient = AblyRealtime

Expand Down Expand Up @@ -35,3 +36,26 @@ interface ChatClient {
*/
val clientOptions: ClientOptions
}

fun ChatClient(realtimeClient: RealtimeClient, clientOptions: ClientOptions): ChatClient = DefaultChatClient(realtimeClient, clientOptions)

internal class DefaultChatClient(
override val realtime: RealtimeClient,
override val clientOptions: ClientOptions,
) : ChatClient {

private val chatApi = ChatApi(realtime)

override val rooms: Rooms = DefaultRooms(
realtimeClient = realtime,
chatApi = chatApi,
clientOptions = clientOptions,
clientId = clientId,
)

override val connection: Connection
get() = TODO("Not yet implemented")

override val clientId: String
get() = realtime.auth.clientId
}
52 changes: 52 additions & 0 deletions chat-android/src/main/java/com/ably/chat/Messages.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("StringLiteralDuplication", "NotImplementedDeclaration")

package com.ably.chat

import io.ably.lib.realtime.Channel
Expand Down Expand Up @@ -173,3 +175,53 @@ data class SendMessageParams(
*/
val headers: MessageHeaders? = null,
)

class DefaultMessages(
private val roomId: String,
private val clientId: String,
private val realtimeClient: RealtimeClient,
private val chatApi: ChatApi,
) : Messages {

/**
* the channel name for the chat messages channel.
*/
private val messagesChannelName = "$roomId::\$chat::\$chatMessages"

override val channel: Channel
get() = realtimeClient.channels.get(messagesChannelName, ChatChannelOptions())

override fun subscribe(listener: Messages.Listener) {
TODO("Not yet implemented")
}

override fun unsubscribe(listener: Messages.Listener) {
TODO("Not yet implemented")
}

override suspend fun get(options: QueryOptions): PaginatedResult<Message> {
TODO("Not yet implemented")
}

override suspend fun send(params: SendMessageParams): Message {
return chatApi.sendMessage(roomId, params).let {
Message(
timeserial = it.timeserial,
clientId = clientId,
roomId = roomId,
text = params.text,
createdAt = it.createdAt,
metadata = params.metadata ?: mapOf(),
headers = params.headers ?: mapOf(),
)
}
}

override fun onDiscontinuity(listener: EmitsDiscontinuities.Listener) {
TODO("Not yet implemented")
}

override fun offDiscontinuity(listener: EmitsDiscontinuities.Listener) {
TODO("Not yet implemented")
}
}
29 changes: 29 additions & 0 deletions chat-android/src/main/java/com/ably/chat/Occupancy.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("StringLiteralDuplication", "NotImplementedDeclaration")

package com.ably.chat

import io.ably.lib.realtime.Channel
Expand Down Expand Up @@ -63,3 +65,30 @@ data class OccupancyEvent(
*/
val presenceMembers: Int,
)

internal class DefaultOccupancy(
private val messages: Messages,
) : Occupancy {
override val channel: Channel
get() = messages.channel

override fun subscribe(listener: Occupancy.Listener) {
TODO("Not yet implemented")
}

override fun unsubscribe(listener: Occupancy.Listener) {
TODO("Not yet implemented")
}

override suspend fun get(): OccupancyEvent {
TODO("Not yet implemented")
}

override fun onDiscontinuity(listener: EmitsDiscontinuities.Listener) {
TODO("Not yet implemented")
}

override fun offDiscontinuity(listener: EmitsDiscontinuities.Listener) {
TODO("Not yet implemented")
}
}
46 changes: 46 additions & 0 deletions chat-android/src/main/java/com/ably/chat/Presence.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("StringLiteralDuplication", "NotImplementedDeclaration")

package com.ably.chat

import android.text.PrecomputedText.Params
Expand Down Expand Up @@ -132,3 +134,47 @@ data class PresenceEvent(
*/
val data: PresenceData,
)

internal class DefaultPresence(
private val messages: Messages,
) : Presence {

override val channel: Channel
get() = messages.channel

override suspend fun get(params: List<Params>): List<PresenceMember> {
TODO("Not yet implemented")
}

override suspend fun isUserPresent(clientId: String): Boolean {
TODO("Not yet implemented")
}

override suspend fun enter(data: PresenceData?) {
TODO("Not yet implemented")
}

override suspend fun update(data: PresenceData?) {
TODO("Not yet implemented")
}

override suspend fun leave(data: PresenceData?) {
TODO("Not yet implemented")
}

override fun subscribe(listener: Presence.Listener) {
TODO("Not yet implemented")
}

override fun unsubscribe(listener: Presence.Listener) {
TODO("Not yet implemented")
}

override fun onDiscontinuity(listener: EmitsDiscontinuities.Listener) {
TODO("Not yet implemented")
}

override fun offDiscontinuity(listener: EmitsDiscontinuities.Listener) {
TODO("Not yet implemented")
}
}
52 changes: 52 additions & 0 deletions chat-android/src/main/java/com/ably/chat/Room.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("StringLiteralDuplication", "NotImplementedDeclaration")

package com.ably.chat

/**
Expand Down Expand Up @@ -80,3 +82,53 @@ interface Room {
*/
suspend fun detach()
}

internal class DefaultRoom(
override val roomId: String,
override val options: RoomOptions,
realtimeClient: RealtimeClient,
chatApi: ChatApi,
clientId: String,
) : Room {

override val messages: Messages = DefaultMessages(
roomId = roomId,
realtimeClient = realtimeClient,
chatApi = chatApi,
clientId = clientId,
)

override val presence: Presence = DefaultPresence(
messages = messages,
)

override val reactions: RoomReactions = DefaultRoomReactions(
roomId = roomId,
realtimeClient = realtimeClient,
)

override val typing: Typing = DefaultTyping(
roomId = roomId,
realtimeClient = realtimeClient,
)

override val occupancy: Occupancy = DefaultOccupancy(
messages = messages,
)

override val status: RoomStatus get() {
TODO("Not yet implemented")
}

override suspend fun attach() {
messages.channel.attachCoroutine()
typing.channel.attachCoroutine()
reactions.channel.attachCoroutine()
}

override suspend fun detach() {
messages.channel.detachCoroutine()
typing.channel.detachCoroutine()
reactions.channel.detachCoroutine()
}
}
32 changes: 32 additions & 0 deletions chat-android/src/main/java/com/ably/chat/RoomReactions.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("StringLiteralDuplication", "NotImplementedDeclaration")

package com.ably.chat

import io.ably.lib.realtime.Channel
Expand Down Expand Up @@ -100,3 +102,33 @@ data class SendReactionParams(
*/
val headers: ReactionHeaders? = null,
)

internal class DefaultRoomReactions(
roomId: String,
private val realtimeClient: RealtimeClient,
) : RoomReactions {
private val roomReactionsChannelName = "$roomId::\$chat::\$reactions"

override val channel: Channel
get() = realtimeClient.channels.get(roomReactionsChannelName, ChatChannelOptions())

override suspend fun send(params: SendReactionParams) {
TODO("Not yet implemented")
}

override fun subscribe(listener: RoomReactions.Listener) {
TODO("Not yet implemented")
}

override fun unsubscribe(listener: RoomReactions.Listener) {
TODO("Not yet implemented")
}

override fun onDiscontinuity(listener: EmitsDiscontinuities.Listener) {
TODO("Not yet implemented")
}

override fun offDiscontinuity(listener: EmitsDiscontinuities.Listener) {
TODO("Not yet implemented")
}
}
43 changes: 43 additions & 0 deletions chat-android/src/main/java/com/ably/chat/Rooms.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.ably.chat

import io.ably.lib.types.AblyException
import io.ably.lib.types.ErrorInfo

/**
* Manages the lifecycle of chat rooms.
*/
Expand Down Expand Up @@ -35,3 +38,43 @@ interface Rooms {
*/
suspend fun release(roomId: String)
}

/**
* Manages the chat rooms.
*/
internal class DefaultRooms(
private val realtimeClient: RealtimeClient,
private val chatApi: ChatApi,
override val clientOptions: ClientOptions,
private val clientId: String,
) : Rooms {
private val roomIdToRoom: MutableMap<String, Room> = mutableMapOf()

override fun get(roomId: String, options: RoomOptions): Room {
return synchronized(this) {
val room = roomIdToRoom.getOrPut(roomId) {
DefaultRoom(
roomId = roomId,
options = options,
realtimeClient = realtimeClient,
chatApi = chatApi,
clientId = clientId,
)
}

if (room.options != options) {
throw AblyException.fromErrorInfo(
ErrorInfo("Room already exists with different options", HttpStatusCodes.BadRequest, ErrorCodes.BadRequest),
)
}

room
}
}

override suspend fun release(roomId: String) {
synchronized(this) {
roomIdToRoom.remove(roomId)
}
}
}
40 changes: 40 additions & 0 deletions chat-android/src/main/java/com/ably/chat/Typing.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("StringLiteralDuplication", "NotImplementedDeclaration")

package com.ably.chat

import io.ably.lib.realtime.Channel
Expand Down Expand Up @@ -77,3 +79,41 @@ interface Typing : EmitsDiscontinuities {
* Represents a typing event.
*/
data class TypingEvent(val currentlyTyping: Set<String>)

internal class DefaultTyping(
roomId: String,
private val realtimeClient: RealtimeClient,
) : Typing {
private val typingIndicatorsChannelName = "$roomId::\$chat::\$typingIndicators"

override val channel: Channel
get() = realtimeClient.channels.get(typingIndicatorsChannelName, ChatChannelOptions())

override fun subscribe(listener: Typing.Listener) {
TODO("Not yet implemented")
}

override fun unsubscribe(listener: Typing.Listener) {
TODO("Not yet implemented")
}

override suspend fun get(): Set<String> {
TODO("Not yet implemented")
}

override suspend fun start() {
TODO("Not yet implemented")
}

override suspend fun stop() {
TODO("Not yet implemented")
}

override fun onDiscontinuity(listener: EmitsDiscontinuities.Listener) {
TODO("Not yet implemented")
}

override fun offDiscontinuity(listener: EmitsDiscontinuities.Listener) {
TODO("Not yet implemented")
}
}
Loading

0 comments on commit f073028

Please sign in to comment.