Implementing Own Capabilities

Each Channel has a list of capabilities that can be performed in it, such as muting a user, deleting messages and many others. Not all channels should have the same capabilities neither should all users, which is where own capabilities come into play.

Inside of Channel you will find a property with a signature ownCapabilities: Set<String>. Which channel capabilities this set contains depends on the current user’s role (for example admin, guest, etc.), the channel type (for example messaging, livestream, etc.) and channel level settings. You can read more about channel capabilities here and more about channel level settings here.

Integrating channel capabilities into the UI

If you are using our UI components bound to our ViewModels, then own capabilities work out of the box without any additional effort from your side, otherwise you will have to pass the correct set of capabilities to individual components.

Different components have different ways of passing own capabilities to them, so we’ll go through them individually. Capabilities that were a part of the minimal chat experience before the introduction of own capabilities will be highlighted in bold with an asterisk next to them.

As a safety precaution, by default own capabilities are initially set to an empty set, this means that a user has no capabilities. Setting it to a set containing all capabilities will give the user potentially dangerous capabilities such as the ability to delete any message.

MessageListView

Inside MessageListView you will find the following function:

public fun setOwnCapabilities(ownCapabilities: Set<String>)

After setting own capabilities, the following capabilities will be regulated:

  • send-reaction *
  • send-reply *
  • pin-message
  • delete-any-message
  • delete-own-message *
  • update-any-message
  • update-own-message *
  • ban-channel-members

For this component, as well as all the other examples, the capabilities in bold are a part of the “default” behavior that is set up for most users in the dashboard.

MessageComposerView

Inside MessageComposerView you will find the following function:

public fun renderState(state: MessageComposerState)

The file containing MessageComposerView can be found here.

Let’s take a look at MessageComposerState:

public data class MessageComposerState(
    ..., // State
    val ownCapabilities: Set<String> = setOf()
)

The file containing MessageComposerState can be found here.

MessageComposerView regulates the following capabilities:

  • send-message *
  • send-links *
  • upload-file *
  • send-typing-events *

Own capabilities are publicly exposed inside MessageComposerController and MessageComposerViewModel as ownCapabilities: StateFlow<Set<String>>.

For this component, as well as all the other examples, the capabilities in bold are a part of the “default” behavior that is set up for most users in the dashboard.

ChannelListView

If you use our ChannelListView as is, no further action is needed as it is set up to use own capabilities.

It regulates the following capabilities.

  • leave-channel *
  • delete-channel

ChannelListView contains the following function:

public fun setMoreOptionsClickListener(listener: ChannelClickListener?)

Should you wish to use it in order to override the default behavior, you will have to implement a UI capable of correctly using own capabilities.

Other capabilities

There are channel capabilities that are not implemented in the SDK because we do not offer the corresponding components or the functionality. You can implement these yourself after creating the correct components.

These are as follows:

  • freeze-channel
  • set-channel-cooldown
  • update-channel
  • update-channel-members
  • search-messages

Please note that while we do offer a search component, its functionality is not simple enough to be regulated by the ‘search-messages’ capability.

How capabilities affect the UI

Let’s take MessageComposerView into consideration. If we left it with the default, empty set of own capabilities we would get the following result:

MessageComposerView with empty capabilities

This leaves the user unable to perform any action provided by MessageComposerView. Ideally, you should let your Dashboard App settings regulate capabilities, but if you wish to control them manually, you can do so.

Take a look at the object called ChannelCapabilities:

public object ChannelCapabilities {
    /** Ability to ban channel members. */
    public const val BAN_CHANNEL_MEMBERS: String = "ban-channel-members"
    ... // Other capabilities
}

The file containing ChannelCapabilities can be found here.

This object contains all relevant channel capabilities as type safe properties. You can use the properties to build a set containing only the capabilities you want enabled for the user.

If you were to enable the user to send messages, links, attachments and typing events, you would build a set as follows:

val customOwnCapabilities = setOf(
    ChannelCapabilities.SEND_MESSAGE,
    ChannelCapabilities.SEND_LINKS,
    ChannelCapabilities.UPLOAD_FILE,
    ChannelCapabilities.SEND_TYPING_EVENTS
)

Then use it to create MessageComposerState:

val messageComposerState = MessageComposerState(
    ownCapabilities = customOwnCapabilities
)

And finally call the MessageComposerView::renderState method with messageComposerState parameter:

messageComposerView.renderState(messageComposerState)

This enables the following capabilities:

  • send-message *
  • send-links *
  • upload-file *
  • send-typing-events *

And results in MessageComposerView having the following appearance:

MessageComposerView with custom capabilities

Please note that providing custom client side capabilities leaves you in charge of making sure that users are not awarded with dangerous capabilities and that different clients are in sync. This is why it is recommended to fetch own capabilities that are provided to you by the server.

© Getstream.io, Inc. All Rights Reserved.