namespace RelayClient; public partial class MainPage : ContentPage { private readonly string _username; public MainPage(string username) { InitializeComponent(); _username = username; UserLabel.Text = $"Logged in as: {_username}"; ChatSimulator.MessageSent += OnMessageSent; } private void SendButton_OnClicked(object? sender, EventArgs e) { SendMessage(); } private void MessageEntry_OnCompleted(object? sender, EventArgs e) { SendMessage(); } private void SendMessage() { var text = MessageEntry.Text?.Trim(); if (string.IsNullOrWhiteSpace(text)) return; ChatSimulator.Send(_username, text); Console.WriteLine($"[{_username}] sent message: {text}"); MessageEntry.Text = string.Empty; MessageEntry.Focus(); } private void OnMessageSent(ChatMessage message) { MainThread.BeginInvokeOnMainThread(async () => { bool isOwnMessage = message.SenderUsername == _username; var bubble = new Border { StrokeThickness = 1, Padding = 10, Margin = isOwnMessage ? new Thickness(40, 0, 0, 0) : new Thickness(0, 0, 40, 0), HorizontalOptions = isOwnMessage ? LayoutOptions.End : LayoutOptions.Start, Content = new VerticalStackLayout { Spacing = 2, Children = { new Label { Text = message.SenderUsername, FontAttributes = FontAttributes.Bold, FontSize = 12 }, new Label { Text = message.Text, FontSize = 14 }, new Label { Text = message.Timestamp.ToString("h:mm tt"), FontSize = 10 } } } }; MessagesLayout.Children.Add(bubble); await MessagesScrollView.ScrollToAsync(MessagesLayout, ScrollToPosition.End, true); }); } protected override void OnDisappearing() { ChatSimulator.MessageSent -= OnMessageSent; base.OnDisappearing(); } }