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 | API Reference

Namespaces are mirrored: Shiny.Maui.Controls.Chat and Shiny.Blazor.Controls.Chat. Models are identical across platforms except ChatSessionUserInfo (MAUI uses ImageSource/Color; Blazor uses string URL / CSS color).

MemberReturnsDescription
CreateSessionAsync(string[] userIds, CancellationToken)Task<IChatSession>Create a new session for the given users
GetSessionAsync(string sessionId, CancellationToken)Task<IChatSession>Resolve an existing session; throws ChatSessionException if missing/forbidden
MemberTypeDescription
InfoChatSessionInfoAlways current; refreshed before SessionUpdated fires
CurrentUserIdstringWho “me” is — drives bubble alignment + ownership
MemberReturnsDescription
GetMessagesAsync(string? cursorMessageId, MessagePageDirection direction, int count, CancellationToken)Task<MessagePage>Cursor paging; null + Older = newest page
SendMessageAsync(OutgoingMessage, CancellationToken)Task<ChatMessage>Send; echo carries the same ClientMessageId
ResendMessageAsync(string clientMessageId, CancellationToken)Task<ChatMessage>Retry a Failed message
EditMessageAsync(string messageId, string body, CancellationToken)TaskEdit own message
DeleteMessageAsync(string messageId, CancellationToken)TaskDelete own message
ReactToMessageAsync(string messageId, string emoji, bool add, CancellationToken)TaskToggle a reaction on/off
MarkReadAsync(string[] messageIds, CancellationToken)TaskMark messages read (control passes only visible, not-mine, unread ids)
ToggleTypingAsync(bool isTyping, CancellationToken)TaskReport the current user’s typing state
InviteUserAsync(string userId, CancellationToken)TaskInvite a user
LeaveAsync(CancellationToken)TaskLeave the session
RenameAsync(string sessionName, CancellationToken)TaskRename the session
EventArgsDescription
MessageReceivedChatMessageNew inbound message or own-send echo (multi-device)
MessageUpdatedMessageChangedEdit / reaction / receipt / status change
MessageDeletedstringDeleted message id
UserTypingUserTypingEventRemote user typing state
UserJoinedChatSessionUserInfoA user joined
UserLeftChatSessionUserInfoA user left
SessionUpdatedChatSessionInfoName / users / permitted emojis / permissions changed
ConnectionStateChangedChatConnectionStateConnectivity changed

Events may fire off the UI thread — the control marshals them.

public record ChatMessage(
string MessageId,
string? ClientMessageId,
string SenderId,
string? Body,
string? ImageUrl,
MessageStatus Status,
string? StatusReason,
DateTimeOffset Timestamp,
DateTimeOffset? EditedTimestamp,
IReadOnlyList<Reaction> Reactions,
IReadOnlyList<ReadReceipt> ReadReceipts,
string? Identifier = null,
IReadOnlyDictionary<string, string>? Metadata = null
);
public record Reaction(string UserId, string Emoji, DateTimeOffset Timestamp);
public record ReadReceipt(string UserId, DateTimeOffset Timestamp);
public record MessageChanged(ChatMessage Message, MessageChangeKind Change);
public record MessagePage(IReadOnlyList<ChatMessage> Messages, bool HasMore); // Messages always chronological asc
public record OutgoingMessage(string? Body, OutgoingAttachment? Attachment = null, string ClientMessageId = "");
public record OutgoingAttachment(ChatAttachmentKind Kind, Stream Content, string FileName, string ContentType);
public record ChatSessionInfo(
string SessionId,
string SessionName,
ChatSessionUserInfo[] Users,
string[]? PermittedEmojis,
MessageBodyPermissions BodyPermissions,
ChatSessionPermissions Permissions,
DateTimeOffset CreatedAt,
DateTimeOffset? LastReadDate,
int UnreadMessageCount
);
// MAUI
public record ChatSessionUserInfo(string UserId, string DisplayName, ImageSource? Avatar, Color? BubbleColor, DateTimeOffset JoinedDate);
// Blazor
public record ChatSessionUserInfo(string UserId, string DisplayName, string? AvatarUrl, string? BubbleColor, DateTimeOffset JoinedDate);
public record UserTypingEvent(string UserId, bool IsTyping, DateTimeOffset Timestamp);
public enum MessageStatus { Sending, Sent, Delivered, Read, Failed, Rejected }
public enum MessageChangeKind { Edited, ReactionChanged, ReadReceiptChanged, StatusChanged }
public enum MessagePageDirection { Older, Newer }
public enum ChatAttachmentKind { Image } // Video/Audio/File reserved
public enum ChatConnectionState { Connected, Reconnecting, Offline }
public enum SendRejectionKind { MessageTooLarge, TooManyAttachments, AttachmentTooLarge, UnsupportedContent, NotPermitted, Other }
[Flags]
public enum ChatSessionPermissions
{
None = 0,
CanSendMessages = 1,
CanEditMessages = 2,
CanDeleteMessages = 4,
CanReactToMessages = 8,
CanInviteUsers = 16,
CanLeaveSession = 32,
CanChangeSessionName = 64,
CanSendImages = 128,
Default = CanSendMessages | CanSendImages | CanReactToMessages | CanInviteUsers | CanLeaveSession,
All = CanSendMessages | CanEditMessages | CanDeleteMessages | CanReactToMessages
| CanInviteUsers | CanLeaveSession | CanChangeSessionName | CanSendImages
}
[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
}
public class ChatSessionException : Exception { } // GetSessionAsync: missing/forbidden session
public class ChatSendRejectedException : Exception // send refused — bubble => Rejected, no retry
{
public SendRejectionKind Kind { get; }
}
PropertyTypeDefaultNotes
ProviderIChatSessionProvider?nullThe integration provider
SessionIdstring?nullSession resolved via GetSessionAsync
PageSizeint30Messages fetched per page
OpenImagesInViewerbooltrueTap an image bubble → built-in ImageViewer
MyBubbleColorColor/string#DCF8C6Local user bubble color
MyTextColorColor/stringBlackLocal user text color
OtherBubbleColorColor/stringWhiteDefault other-user bubble (overridden by ChatSessionUserInfo.BubbleColor)
OtherTextColorColor/stringBlackOther-user text color
ChatBackgroundColorColor?/string?nullMessages area background
BubbleFontSizedouble15MAUI
BubbleFontFamilystring?nullMAUI
TimestampFontSizedouble11MAUI
BubbleCornerRadiusdouble18Tail corner stays 4 (MAUI)
PlaceholderTextstring"Type a message..."Input placeholder
SendButtonTextstring"Send"Send button label
SendButtonBackgroundColorColor/string#007AFFMAUI
SendButtonTextColorColor/stringWhiteMAUI
InputBarBackgroundColorColor/string#F5F5F5MAUI
InputBarBorderColorColor/string#E0E0E0MAUI
IsInputBarVisiblebooltruefalse for read-only chats
ShowTypingIndicatorbooltrueEnable typing indicators
ScrollToFirstUnreadboolfalseAnchor initial scroll at first unread (via Info.LastReadDate)
InputActionsIList<ChatInputAction>[]Custom input-bar actions (MAUI)
CustomBubbleActionsIList<ChatBubbleAction>[]Custom bubble actions appended to built-ins (MAUI)
MessageTemplateDataTemplate?nullSingle content template (MAUI)
MessageTemplateSelectorDataTemplateSelector?nullPer-message template (MAUI)
UseFeedbackbooltrueHaptic feedback (MAUI)
AdjustForKeyboardbooltrueiOS keyboard padding; set false inside a FloatingPanel (MAUI)
MemberDescription
ScrollToEnd(bool animate)Scroll to the latest message
ScrollToMessage(string messageId, bool animate)Scroll to a message by id
SubmitEntry()Programmatically submit the input text
EntryText (property)Get/set the input field text
MessageTapped (event)Fires for non-image bubble taps
public class ChatInputAction : BindableObject
{
public string? Text { get; set; }
public ImageSource? Icon { get; set; }
public Func<ChatView, Task>? Handler { get; set; }
public event EventHandler<ChatView>? Clicked;
public virtual Task InvokeAsync(ChatView chatView);
}
public class ChatBubbleAction : BindableObject
{
public string? Text { get; set; }
public ImageSource? Icon { get; set; }
public Func<ChatMessage, Task>? Handler { get; set; }
public event EventHandler<ChatMessage>? Clicked;
public virtual Task InvokeAsync(ChatMessage message);
}

Shiny.Maui.Controls.SpeechAddins ships SpeechToTextTool : ChatInputAction and TextToSpeechBubbleTool : ChatBubbleAction — see Custom Actions.