using Newtonsoft.Json.Linq; using PolyChat.Models; using PolyChat.Util; using PolyChat.Views; using System; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Text.Json; using Windows.Foundation; using Windows.UI.Core; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace PolyChat { /// /// An empty page that can be used on its own or navigated to within a Frame. /// public sealed partial class MainPage : Page { private Controller Controller; private ObservableCollection Partners; private ChatPartner selectedPartner = null; private string username; public MainPage() { this.InitializeComponent(); // init controller Controller = new Controller(this); // ui variables ipAddress.Text = IP.GetCodeFromIP(Controller.getIP()); Partners = new ObservableCollection(); updateNoChatsPlaceholder(); updateNoUsernamePlaceholder(); updateNoChatSelected(); updateSendButtonEnabled(); } public async void ShowConnectionError(string param, string heading, string message) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { Dialog dialog = new Dialog( Dialog.TYPE_ERROR, heading, message, new DialogButton( "Retry", () => { Controller.Connect(param); Partners.Add(new ChatPartner( "Connecting...", param )); updateNoChatsPlaceholder(); } ), new DialogButton( "Ignore", () => { /* do nothing */ } ) ); }); } // EVENTS public void OnSendMessage(object sender = null, RoutedEventArgs e = null) { selectedPartner.AddMessage(new ChatMessage(username, "message", inputSend.Text)); Controller.SendMessage(selectedPartner.Code, "message", inputSend.Text); // clear input inputSend.Text = ""; } public async void OnOpenNewChatDialog(object sender = null, RoutedEventArgs e = null) { NewChatDialog dialog = new NewChatDialog(); var result = await SafelyOpenDialog(dialog); if (result == ContentDialogResult.Primary) { string ip = IP.GetIPFromCode(dialog.getValue()); Controller.Connect(ip); Partners.Add(new ChatPartner( "Connecting...", ip )); updateNoChatsPlaceholder(); } } public async void OnOpenEditUsernameDialog(object sender = null, RoutedEventArgs e = null) { EditUsernameDialog dialog = new EditUsernameDialog(username); var result = await SafelyOpenDialog(dialog); if (result == ContentDialogResult.Primary) { username = dialog.getValue(); textUsername.Text = username; Controller.SendBroadcastMessage("username", username); } updateNoUsernamePlaceholder(); } /// /// Adds a new ChatPartner to the UI with default Name. /// /// IP Adress, gets shown as Util.IP > Code public async void OnIncomingConnection(string ip) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { Partners.Add(new ChatPartner( "Connecting...", ip )); updateNoChatsPlaceholder(); }); } /// /// Adds an message to the UI, based on .sender if known /// /// ChatMessage public async void OnIncomingMessage(string origin, string json, DateTime timeStamp) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { var doc = JsonDocument.Parse(json).RootElement; string type = doc.GetProperty("type").GetString(); string content = doc.GetProperty("content").GetString(); ChatPartner sendingPartner = Partners.FirstOrDefault(p => p.Code == origin); switch (type) { case "username": Debug.WriteLine($"! username change for {sendingPartner.Code} -> {content}"); sendingPartner.SetName(Name); break; default: sendingPartner.AddMessage(new ChatMessage(origin, type, content, timeStamp)); break; } }); } public async void OnIncomingMessages(string origin, string json) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { ChatPartner sendingPartner = Partners.FirstOrDefault(p => p.Code == origin); JArray arr = JArray.Parse(json); foreach (JObject item in arr) { sendingPartner.AddMessage( new ChatMessage( origin, item["type"].ToString(), item["content"].ToString()//, //DateTime.Parse(item["timestamp"].ToString()) ) ); } }); } private void OnDeleteChat(object sender = null, RoutedEventArgs e = null) { Controller.CloseChat(selectedPartner.Code); Partners.Remove(selectedPartner); updateNoChatsPlaceholder(); updateNoChatSelected(); } public async void OnChatPartnerDeleted(string code) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { Partners.Remove(Partners.FirstOrDefault(p => p.Code.Equals(code))); selectedPartner = null; updateNoChatsPlaceholder(); updateNoChatSelected(); }); } public void OnChatPartnerSelected(object sender, RoutedEventArgs e) { string code = ((RadioButton)sender).Tag.ToString(); selectedPartner = Partners.FirstOrDefault(p => p.Code == code); listViewMessages.ItemsSource = selectedPartner.Messages; selectedPartnerName.Text = selectedPartner.Name; updateNoChatSelected(); if (!Controller.IsConnected(code)) Controller.Connect(code); } private void OnKeyUp(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e) { updateSendButtonEnabled(); if (e.Key == Windows.System.VirtualKey.Enter) { OnSendMessage(); } } public static IAsyncOperation SafelyOpenDialog(Dialog d) { if(VisualTreeHelper.GetOpenPopups(Window.Current).Count == 0) return d.ShowAsync(); return null; } public static IAsyncOperation SafelyOpenDialog(NewChatDialog d) { if (VisualTreeHelper.GetOpenPopups(Window.Current).Count == 0) return d.ShowAsync(); return null; } public static IAsyncOperation SafelyOpenDialog(EditUsernameDialog d) { if (VisualTreeHelper.GetOpenPopups(Window.Current).Count == 0) return d.ShowAsync(); return null; } // UPDATE FUNCTIONS FOR UI PLACEHOLDERS private void updateNoChatsPlaceholder() { textNoChats.Visibility = Partners.Count() == 0 ? Visibility.Visible : Visibility.Collapsed; } private void updateNoUsernamePlaceholder() { if (username == null) { textNoUsername.Visibility = Visibility.Visible; textUsername.Visibility = Visibility.Collapsed; } else { textNoUsername.Visibility = Visibility.Collapsed; textUsername.Visibility = Visibility.Visible; } } private void updateNoChatSelected() { if (selectedPartner != null) { gridRight.Visibility = Visibility.Visible; textNoChatSelected.Visibility = Visibility.Collapsed; } else { gridRight.Visibility = Visibility.Collapsed; textNoChatSelected.Visibility = Visibility.Visible; } } private void updateSendButtonEnabled() { buttonSend.IsEnabled = inputSend.Text.Length != 0; } } }