Skip to content

Commit

Permalink
Merge pull request #1 from ably-labs/ECO-4899/chat-public-api
Browse files Browse the repository at this point in the history
[ECO-4899] feat: add public API for Chat SDK
  • Loading branch information
ttypic authored Aug 29, 2024
2 parents 17d0c76 + 344e9f4 commit 623b370
Show file tree
Hide file tree
Showing 21 changed files with 1,362 additions and 2 deletions.
37 changes: 37 additions & 0 deletions chat-android/src/main/java/com/ably/chat/ChatClient.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.ably.chat

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

typealias RealtimeClient = AblyRealtime

/**
* This is the core client for Ably chat. It provides access to chat rooms.
*/
interface ChatClient {
/**
* The rooms object, which provides access to chat rooms.
*/
val room: Room

/**
* The underlying connection to Ably, which can be used to monitor the clients
* connection to Ably servers.
*/
val connection: Connection

/**
* The clientId of the current client.
*/
val clientId: String

/**
* The underlying Ably Realtime client.
*/
val realtime: RealtimeClient

/**
* The resolved client options for the client, including any defaults that have been set.
*/
val clientOptions: ClientOptions
}
20 changes: 20 additions & 0 deletions chat-android/src/main/java/com/ably/chat/ClientOptions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.ably.chat

import io.ably.lib.util.Log.LogHandler

/**
* Configuration options for the chat client.
*/
data class ClientOptions(
/**
* A custom log handler that will be used to log messages from the client.
* @defaultValue The client will log messages to the console.
*/
val logHandler: LogHandler? = null,

/**
* The minimum log level at which messages will be logged.
* @defaultValue LogLevel.Error
*/
val logLevel: LogLevel = LogLevel.Error,
)
11 changes: 11 additions & 0 deletions chat-android/src/main/java/com/ably/chat/Connection.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.ably.chat

/**
* Represents a connection to Ably.
*/
interface Connection {
/**
* The current status of the connection.
*/
val status: ConnectionStatus
}
107 changes: 107 additions & 0 deletions chat-android/src/main/java/com/ably/chat/ConnectionStatus.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.ably.chat

import io.ably.lib.types.ErrorInfo

/**
* Default timeout for transient states before we attempt handle them as a state change.
*/
const val TRANSIENT_TIMEOUT = 5000

/**
* Represents a connection to Ably.
*/
interface ConnectionStatus {
/**
* The current status of the connection.
*/
val current: ConnectionLifecycle

/**
* The current error, if any, that caused the connection to enter the current status.
*/
val error: ErrorInfo?

/**
* Registers a listener that will be called whenever the connection status changes.
* @param listener The function to call when the status changes.
*/
fun on(listener: Listener)

/**
* Unregisters a listener
* @param listener The function to call when the status changes.
*/
fun off(listener: Listener)

/**
* An interface for listening to changes for the connection status
*/
fun interface Listener {
/**
* A function that can be called when the connection status changes.
* @param change The change in status.
*/
fun connectionStatusChanged(change: ConnectionStatusChange)
}
}

/**
* The different states that the connection can be in through its lifecycle.
*/
enum class ConnectionLifecycle(val stateName: String) {
/**
* A temporary state for when the library is first initialized.
*/
Initialized("initialized"),

/**
* The library is currently connecting to Ably.
*/
Connecting("connecting"),

/**
* The library is currently connected to Ably.
*/
Connected("connected"),

/**
* The library is currently disconnected from Ably, but will attempt to reconnect.
*/
Disconnected("disconnected"),

/**
* The library is in an extended state of disconnection, but will attempt to reconnect.
*/
Suspended("suspended"),

/**
* The library is currently disconnected from Ably and will not attempt to reconnect.
*/
Failed("failed"),
}

/**
* Represents a change in the status of the connection.
*/
data class ConnectionStatusChange(
/**
* The new status of the connection.
*/
val current: ConnectionLifecycle,

/**
* The previous status of the connection.
*/
val previous: ConnectionLifecycle,

/**
* An error that provides a reason why the connection has
* entered the new status, if applicable.
*/
val error: ErrorInfo?,

/**
* The time in milliseconds that the client will wait before attempting to reconnect.
*/
val retryIn: Long?,
)
31 changes: 31 additions & 0 deletions chat-android/src/main/java/com/ably/chat/EmitsDiscontinuities.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.ably.chat

import io.ably.lib.types.ErrorInfo

/**
* An interface to be implemented by objects that can emit discontinuities to listeners.
*/
interface EmitsDiscontinuities {
/**
* Register a listener to be called when a discontinuity is detected.
* @param listener The listener to be called when a discontinuity is detected.
*/
fun onDiscontinuity(listener: Listener)

/**
* Unregister a listener to be called when a discontinuity is detected.
* @param listener The listener
*/
fun offDiscontinuity(listener: Listener)

/**
* An interface for listening when discontinuity happens
*/
fun interface Listener {
/**
* A function that can be called when discontinuity happens.
* @param reason reason for discontinuity
*/
fun discontinuityEmitted(reason: ErrorInfo?)
}
}
90 changes: 90 additions & 0 deletions chat-android/src/main/java/com/ably/chat/ErrorCodes.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.ably.chat

/**
* Error codes for the Chat SDK.
*/
object ErrorCodes {
/**
* The messages feature failed to attach.
*/
const val MessagesAttachmentFailed = 102_001

/**
* The presence feature failed to attach.
*/
const val PresenceAttachmentFailed = 102_002

/**
* The reactions feature failed to attach.
*/
const val ReactionsAttachmentFailed = 102_003

/**
* The occupancy feature failed to attach.
*/
const val OccupancyAttachmentFailed = 102_004

/**
* The typing feature failed to attach.
*/
const val TypingAttachmentFailed = 102_005
// 102006 - 102049 reserved for future use for attachment errors

/**
* The messages feature failed to detach.
*/
const val MessagesDetachmentFailed = 102_050

/**
* The presence feature failed to detach.
*/
const val PresenceDetachmentFailed = 102_051

/**
* The reactions feature failed to detach.
*/
const val ReactionsDetachmentFailed = 102_052

/**
* The occupancy feature failed to detach.
*/
const val OccupancyDetachmentFailed = 102_053

/**
* The typing feature failed to detach.
*/
const val TypingDetachmentFailed = 102_054
// 102055 - 102099 reserved for future use for detachment errors

/**
* The room has experienced a discontinuity.
*/
const val RoomDiscontinuity = 102_100

// Unable to perform operation;

/**
* Cannot perform operation because the room is in a failed state.
*/
const val RoomInFailedState = 102_101

/**
* Cannot perform operation because the room is in a releasing state.
*/
const val RoomIsReleasing = 102_102

/**
* Cannot perform operation because the room is in a released state.
*/
const val RoomIsReleased = 102_103

/**
* Cannot perform operation because the previous operation failed.
*/
const val PreviousOperationFailed = 102_104

/**
* An unknown error has happened in the room lifecycle.
*/
const val RoomLifecycleError = 102_105
}
50 changes: 50 additions & 0 deletions chat-android/src/main/java/com/ably/chat/EventTypes.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.ably.chat

/**
* All chat message events.
*/
enum class MessageEventType(val eventName: String) {
/** Fires when a new chat message is received. */
Created("message.created"),
}

/**
* Enum representing presence events.
*/
enum class PresenceEventType(val eventName: String) {
/**
* Event triggered when a user enters.
*/
Enter("enter"),

/**
* Event triggered when a user leaves.
*/
Leave("leave"),

/**
* Event triggered when a user updates their presence data.
*/
Update("update"),

/**
* Event triggered when a user initially subscribes to presence.
*/
Present("present"),
}

enum class TypingEventType(val eventName: String) {
/** The set of currently typing users has changed. */
Changed("typing.changed"),
}

/**
* Room reaction events. This is used for the realtime system since room reactions
* have only one event: "roomReaction".
*/
enum class RoomReactionEventType(val eventName: String) {
/**
* Event triggered when a room reaction was received.
*/
Reaction("roomReaction"),
}
19 changes: 19 additions & 0 deletions chat-android/src/main/java/com/ably/chat/Headers.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.ably.chat

/**
* Headers are a flat key-value map that can be attached to chat messages.
*
* The headers are a flat key-value map and are sent as part of the realtime
* message's extras inside the `headers` property. They can serve similar
* purposes as Metadata but as opposed to Metadata they are read by Ably and
* can be used for features such as
* [subscription filters](https://faqs.ably.com/subscription-filters).
*
* Do not use the headers for authoritative information. There is no
* server-side validation. When reading the headers treat them like user
* input.
*
* The key prefix `ably-chat` is reserved and cannot be used. Ably may add
* headers prefixed with `ably-chat` in the future.
*/
typealias Headers = Map<String, String>
Loading

0 comments on commit 623b370

Please sign in to comment.