Skip to content
Client v5: BLE, BLE Hosting, HTTP, Jobs - Linux, MacOS, & Blazor Support! Full AOT, RX on BLE only & MANY other features! Power up!

ChatView | Permissions

ChatView derives every action affordance from Info.Permissions + ownership (CurrentUserId). There is no per-tool wiring anymore — you set permissions on the ChatSessionInfo your session returns, and the control shows or hides the matching UI automatically.

[Flags]
public enum ChatSessionPermissions
{
None = 0,
CanSendMessages = 1,
CanEditMessages = 2, // own messages only
CanDeleteMessages = 4, // own messages only
CanReactToMessages = 8,
CanInviteUsers = 16,
CanLeaveSession = 32,
CanChangeSessionName= 64,
CanSendImages = 128, // gates the gallery/camera attach affordance (independent of text send)
Default = CanSendMessages | CanSendImages | CanReactToMessages | CanInviteUsers | CanLeaveSession,
All = CanSendMessages | CanEditMessages | CanDeleteMessages | CanReactToMessages
| CanInviteUsers | CanLeaveSession | CanChangeSessionName | CanSendImages
}
PermissionSurfaced asCalls
CanSendMessagesinput bar enabledSendMessageAsync
CanEditMessages”Edit” on own bubblesEditMessageAsync
CanDeleteMessages”Delete” on own bubblesDeleteMessageAsync
CanReactToMessagesreaction picker (filtered to PermittedEmojis)ReactToMessageAsync
CanInviteUsersinvite affordanceInviteUserAsync
CanLeaveSessionleave affordanceLeaveAsync
CanChangeSessionNamerename affordanceRenameAsync
CanSendImagesgallery/camera attach affordanceSendMessageAsync with OutgoingAttachment

Set permissions when you build Info:

public ChatSessionInfo BuildInfo() => new(
SessionId: this.SessionId,
SessionName: this.SessionName,
Users: this.Users,
PermittedEmojis: null, // null => control default emoji set
BodyPermissions: MessageBodyPermissions.All,
Permissions: ChatSessionPermissions.Default, // or .All, or a hand-picked set
CreatedAt: this.CreatedAt,
LastReadDate: this.LastReadDate,
UnreadMessageCount: this.Unread
);

Changing permissions at runtime is just a matter of refreshing Info and raising SessionUpdated — the control re-derives the affordances.

GoalPermissions
Read-only feedNone (also set IsInputBarVisible="false")
Text-only, no reactionsCanSendMessages
1:1 chat with edit/deleteCanSendMessages | CanSendImages | CanReactToMessages | CanEditMessages | CanDeleteMessages
Group adminChatSessionPermissions.All
Standard memberChatSessionPermissions.Default

CanSendImages is independent of CanSendMessages, so a session can be image-only, text-only, or both.

This separate flags enum drives the markdown composition toolbar (see Markdown & Input Bar). Only granted formats show a toolbar button; None means a plain-text input with no toolbar.

[Flags]
public enum MessageBodyPermissions
{
None = 0,
Links = 1, Bold = 2, Italics = 4, Underline = 8, Strikethrough = 16, Codeblocks = 32,
All = Links | Bold | Italics | Underline | Strikethrough | Codeblocks
}

MessageBodyPermissions is strictly about text formatting — image sending is the CanSendImages action above, not a body flag.

The control never pre-checks size, counts, or content policy — those depend on your server/business rules. It attempts optimistically and renders the verdict you return. Throw the right exception:

// GetSessionAsync: the session is missing or the current user has no access
public class ChatSessionException : Exception
{
public ChatSessionException(string message) : base(message) { }
}
// SendMessageAsync / ResendMessageAsync / EditMessageAsync: content refused
public class ChatSendRejectedException : Exception
{
public ChatSendRejectedException(string reason, SendRejectionKind kind) : base(reason)
=> this.Kind = kind;
public SendRejectionKind Kind { get; }
}
public enum SendRejectionKind
{
MessageTooLarge, TooManyAttachments, AttachmentTooLarge, UnsupportedContent, NotPermitted, Other
}
ExceptionThrown fromControl reaction
ChatSessionExceptionGetSessionAsync (and the session methods, for not-found)renders an error state instead of the chat
ChatSendRejectedExceptionSendMessageAsync / ResendMessageAsync / EditMessageAsyncflips the optimistic bubble to MessageStatus.Rejected, sets StatusReason, no retry

A transient failure — any other exception — flips the bubble to MessageStatus.Failed with a retry affordance. See Messages & Paging.