Merge branch 'ConnectionController'

This commit is contained in:
Felix Hartmann (PEA3-Fe-FI)
2021-09-24 09:15:02 +02:00
21 changed files with 991 additions and 152 deletions

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

211
PolyChat/Controller.cs Normal file
View File

@@ -0,0 +1,211 @@
using System.Collections.Generic;
using System.Diagnostics;
using Newtonsoft.Json.Linq;
using System.Net;
using SocketIOSharp.Server;
using SocketIOSharp.Server.Client;
using PolyChat.Models;
using System;
namespace PolyChat
{
// 10.1.211.26 Marc
// 10.1.218.90 Felix
// 10.4.141.77 Pat
class Controller
{
// Constants
private const ushort PORT = 8050;
// Controller
private readonly MainPage UIController;
private readonly FileManager fileManager;
// Props
private Dictionary<string, Connection> Connections = new Dictionary<string, Connection>();
/// <summary>
/// Initializes Controller with UI access
/// </summary>
/// <param name="uiController">UWP UI Controller</param>
public Controller(MainPage uiController)
{
UIController = uiController;
fileManager = new FileManager(this);
fileManager.loadChats();
Serve();
// test
/*
UIController.OnIncomingConnection("localhost");
UIController.OnIncomingConnection("1.2.3.4");
UIController.OnIncomingConnection("1.2.4.8");
*/
}
public void Connect(string ip)
{
Debug.WriteLine("--- Controller.Connect ---");
if (isInConnections(ip))
{
Debug.WriteLine("---- We have an active connection to this client. ABORT! ----");
CloseChatUI(ip);
//Todo show error!
}
else
{
Connections.Add(ip, new Connection(ip, PORT, Data => OnMessage(ip, Data), CloseChat));
}
}
/// <summary>
/// starts server for clients to connect to
/// </summary>
private void Serve()
{
Debug.WriteLine("--- Controller.Serve ---");
SocketIOServer server = new SocketIOServer(new SocketIOServerOption(PORT));
server.Start();
Debug.WriteLine("Port " + server.Option.Port);
Debug.WriteLine("Path " + server.Option.Path);
// listen for connection
server.OnConnection((SocketIOSocket socket) =>
{
Debug.WriteLine("--- Client connected! ---");
// setup event listeners
socket.On("initial", (JToken[] data) =>
{
Debug.WriteLine("--- initial packet received ---");
string ForeignIp = data[0].ToString();
Debug.WriteLine($"--- this ip was in the inital packet: {ForeignIp} ---");
if (isInConnections(ForeignIp))
{
Debug.WriteLine("---- We have an active connection to this client. ABORT! ----");//Todo show error!
CloseChatUI(ForeignIp);
}
else
{
Debug.WriteLine("---- Added new Connection ----");
Connections.Add(ForeignIp, new Connection(socket, Data => OnMessage(ForeignIp, Data), CloseChat));
UIController.OnIncomingConnection(ForeignIp);
}
});
});
}
public void SendBroadcastMessage(string type, string content)
{
Debug.WriteLine("--- Controller.Broadcast ---");
foreach (KeyValuePair<string, Connection> entry in Connections)
{
SendMessage(entry.Key, type, content);
}
}
/// <summary>
/// Sends message to given ip
/// </summary>
/// <param name="ip"></param>
/// <param name="type"></param>
/// <param name="content"></param>
public void SendMessage(string ip, string type, string content)
{
Debug.WriteLine("--- Controller.SendMessage ---");
Debug.WriteLine($"{type} -> {ip} content: {content}");
JObject json = new JObject(
new JProperty("type", type),
new JProperty("content", content)
);
Debug.WriteLine($"json: {json.ToString()}");
// send as json
Connections[ip].SendMessage(json.ToString());
// save to logs
fileManager.saveChats(ip, json.ToString(), DateTime.Now);
}
/// <summary>
/// if We recieve a message this method gets triggert
/// </summary>
/// <param name="ip">ip from sender</param>
/// <param name="data">String that is send</param>
private void OnMessage(string ip, JToken[] data)
{
Debug.WriteLine("--- Controller.OnMessage ---");
if (data != null && data.Length > 0 && data[0] != null)
{
DateTime now = DateTime.Now;
Debug.WriteLine("RAW: " + data[0]);
UIController.OnIncomingMessage(ip, data[0].ToString(), now);
fileManager.saveChats(ip, data[0].ToString(), now);
}
else Debug.WriteLine("Undefined: " + data);
}
/// <summary>
/// Closes chat connection
/// </summary>
/// <param name="IP">ip of user to be closed</param>
/// <param name="wasConnected"></param>
/// <param name="delete"></param>
public void CloseChat(string IP, bool wasConnected = true, bool delete = false)
{
Debug.WriteLine($"Deleting connection with IP:{IP}");
if (IP != null && Connections.ContainsKey(IP))
{
Connections[IP].Close();
Connections.Remove(IP);
}
if (delete || !wasConnected)
CloseChatUI(IP, wasConnected, delete);
if (delete)
fileManager.deleteChat(IP);
}
/// <summary>
/// sends incoming message to ui
/// </summary>
/// <param name="ip">ip of client that send the message</param>
/// <param name="jsonArr">the json array that is ti be displayed in th gui</param>
public void SendIncomingMessageUI(String ip, String jsonArr)
{
UIController.OnIncomingConnection(ip);
UIController.OnIncomingMessages(ip, jsonArr);
}
private void CloseChatUI(string IP, bool wasConnected = true, bool delete = false)
{
UIController.OnChatPartnerDeleted(IP);
string heading = wasConnected ? "Connection Closed" : "Connection Failed";
if(!delete)
UIController.ShowConnectionError(IP, heading, $"Connecting to {IP} failed...");
}
private bool isInConnections(string IP)
{
return Connections.ContainsKey(IP);
}
public bool IsConnected(string ip)
{
return Connections.ContainsKey(ip) && Connections[ip].IsConnected();
}
/// <summary>
/// returns your own ip that starts with 10. becuase that is our subnet
/// </summary>
/// <returns></returns>
public static string getIP()
{
IPHostEntry ipEntry = Dns.GetHostEntry(Dns.GetHostName());
IPAddress[] addrList = ipEntry.AddressList;
for (short i = 0; i < addrList.Length; i++)
{
if (addrList[i].ToString().Substring(0, 3).Equals("10."))
{
return addrList[i].ToString();
}
}
return null;
}
}
}

View File

@@ -13,10 +13,11 @@
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!-- LEFT SIDE --> <!-- LEFT SIDE -->
<Grid Grid.Column="0" Margin="16"> <Grid Grid.Column="0" Padding="16" Background="{ThemeResource SystemChromeMediumColor}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- CONNECTION HEADER --> <!-- CONNECTION HEADER -->
<StackPanel HorizontalAlignment="Stretch" Spacing="8" Margin="0 0 0 8"> <StackPanel HorizontalAlignment="Stretch" Spacing="8" Margin="0 0 0 8">
@@ -37,7 +38,7 @@
<TextBlock Text="Connect to" Foreground="{ThemeResource SystemColorDisabledTextColor}"/> <TextBlock Text="Connect to" Foreground="{ThemeResource SystemColorDisabledTextColor}"/>
<TextBlock x:Name="ipAddress" Grid.Column="1"/> <TextBlock x:Name="ipAddress" Grid.Column="1"/>
</Grid> </Grid>
<Border BorderThickness="1" BorderBrush="{ThemeResource AppBarBorderThemeBrush}"/> <Border BorderThickness="1" BorderBrush="{ThemeResource SystemControlBackgroundListLowBrush}"/>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center"> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
@@ -53,14 +54,10 @@
<ListView x:Name="listViewPartners" ItemsSource="{x:Bind Partners}" HorizontalAlignment="Stretch" Margin="0 8 0 0"> <ListView x:Name="listViewPartners" ItemsSource="{x:Bind Partners}" HorizontalAlignment="Stretch" Margin="0 8 0 0">
<ListView.ItemTemplate> <ListView.ItemTemplate>
<DataTemplate x:DataType="models:ChatPartner"> <DataTemplate x:DataType="models:ChatPartner">
<RadioButton GroupName="chatSelect" Tag="{x:Bind Code}" HorizontalAlignment="Stretch" Height="64" Checked="OnChatPartnerSelected"> <RadioButton GroupName="chatSelect" Tag="{x:Bind Code}" HorizontalAlignment="Stretch" Height="64" Click="OnChatPartnerSelected">
<StackPanel x:Name="ChatPartner" VerticalAlignment="Center" HorizontalAlignment="Stretch"> <StackPanel x:Name="ChatPartner" VerticalAlignment="Center" HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch"> <TextBlock HorizontalAlignment="Stretch" Text="{x:Bind Name}"/>
<TextBlock HorizontalAlignment="Stretch" Text="{x:Bind Name}"/> <TextBlock Foreground="{ThemeResource SystemColorDisabledTextColor}" Text="{x:Bind Code}"/>
<TextBlock Foreground="{ThemeResource SystemColorDisabledTextColor}" Text=" ("/>
<TextBlock Foreground="{ThemeResource SystemColorDisabledTextColor}" Text="{x:Bind Code}"/>
<TextBlock Foreground="{ThemeResource SystemColorDisabledTextColor}" Text=")"/>
</StackPanel>
<!-- <!--
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<TextBlock HorizontalAlignment="Stretch" Text="{x:Bind Messages.Last().toString()}"/> <TextBlock HorizontalAlignment="Stretch" Text="{x:Bind Messages.Last().toString()}"/>
@@ -73,6 +70,7 @@
</ListView.ItemTemplate> </ListView.ItemTemplate>
</ListView> </ListView>
</ScrollViewer> </ScrollViewer>
<Button Grid.Row="2" Click="OnToggleTheme" Content="Toggle Theme"/>
</Grid> </Grid>
<TextBlock x:Name="textNoChatSelected" Grid.Column="1" Text="No Chat Selected" Foreground="{ThemeResource SystemColorDisabledTextColor}" FontSize="24" VerticalAlignment="Center" HorizontalAlignment="Center"/> <TextBlock x:Name="textNoChatSelected" Grid.Column="1" Text="No Chat Selected" Foreground="{ThemeResource SystemColorDisabledTextColor}" FontSize="24" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<!-- RIGHT SIDE --> <!-- RIGHT SIDE -->
@@ -97,13 +95,17 @@
</Grid> </Grid>
<!-- CHAT --> <!-- CHAT -->
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden"> <ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden">
<ListView x:Name="listViewMessages" VerticalAlignment="Bottom" Margin="4 16"> <ListView x:Name="listViewMessages" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="4 16">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate> <ListView.ItemTemplate>
<DataTemplate x:DataType="models:Message"> <DataTemplate x:DataType="models:ChatMessage">
<StackPanel x:Name="Message" Margin="0 4" Padding="16 8" CornerRadius="4" Background="{ThemeResource SystemAccentColor}"> <StackPanel HorizontalAlignment="{x:Bind Align}" x:Name="Message" MaxWidth="320" Margin="0 4" Padding="16 8" CornerRadius="4" Background="{ThemeResource SystemAccentColor}">
<TextBlock Text="{x:Bind Msg}"/> <TextBlock Text="{x:Bind Content}" Foreground="{ThemeResource SystemAltHighColor}" TextWrapping="WrapWholeWords" FontSize="14"/>
<TextBlock Text="{x:Bind Timestamp.ToShortDateString()}"/> <TextBlock Text="{x:Bind TimeStamp.ToString()}" Foreground="{ThemeResource SystemAltMediumColor}"/>
<TextBlock Text="{x:Bind Foreign}"/>
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
</ListView.ItemTemplate> </ListView.ItemTemplate>

View File

@@ -1,12 +1,17 @@
using PolyChat.Models; using Newtonsoft.Json.Linq;
using PolyChat.Models;
using PolyChat.Util; using PolyChat.Util;
using PolyChat.Views; using PolyChat.Views;
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Text.Json;
using Windows.Foundation;
using Windows.UI.Core;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; 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 // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
@@ -17,63 +22,90 @@ namespace PolyChat
/// </summary> /// </summary>
public sealed partial class MainPage : Page public sealed partial class MainPage : Page
{ {
private NetworkingController networkingController; private Controller Controller;
private ObservableCollection<ChatPartner> Partners; private ObservableCollection<ChatPartner> Partners;
private ChatPartner selectedPartner = null; private ChatPartner selectedPartner = null;
private string username; private string username;
private static ElementTheme Theme = ElementTheme.Light;
public MainPage() public MainPage()
{ {
this.InitializeComponent(); this.InitializeComponent();
// init controller // init controller
networkingController = new NetworkingController(this); Controller = new Controller(this);
// ui variables // ui variables
ipAddress.Text = IP.GetCodeFromIP(networkingController.getIP().ToString()); ipAddress.Text = IP.GetCodeFromIP(Controller.getIP());
Partners = new ObservableCollection<ChatPartner>(); Partners = new ObservableCollection<ChatPartner>();
// theming
RequestedTheme = Theme;
// updated placeholder
updateNoChatsPlaceholder(); updateNoChatsPlaceholder();
updateNoUsernamePlaceholder(); updateNoUsernamePlaceholder();
updateNoChatSelected(); updateNoChatSelected();
updateSendButtonEnabled(); updateSendButtonEnabled();
} }
public async void ShowConnectionError(string message) public async void ShowConnectionError(string param, string heading, string message)
{ {
ConnectionFailedDialog dialog = new ConnectionFailedDialog(message); await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
var result = await dialog.ShowAsync();
if (result == ContentDialogResult.Primary)
{ {
//retry Dialog dialog = new Dialog(
} Dialog.TYPE_ERROR,
// else abort -> del chat heading,
message,
new DialogButton(
"Retry",
() =>
{
Controller.Connect(param);
Partners.Add(new ChatPartner(
"Connecting...",
param
));
updateNoChatsPlaceholder();
}
),
new DialogButton(
"Ignore",
() => { /* do nothing */ }
)
);
SafelyOpenDialog(dialog);
});
} }
// EVENTS // EVENTS
public void OnChatPartnerSelected(object sender, RoutedEventArgs e)
{
string code = ((RadioButton)sender).Tag.ToString();
selectedPartner = Partners.First(p => p.Code == code);
listViewMessages.ItemsSource = selectedPartner.Messages;
selectedPartnerName.Text = selectedPartner.Name;
updateNoChatSelected();
}
public void OnSendMessage(object sender = null, RoutedEventArgs e = null) public void OnSendMessage(object sender = null, RoutedEventArgs e = null)
{ {
selectedPartner.AddMessage(new Message(inputSend.Text,false)); selectedPartner.AddMessage(new ChatMessage(username, "message", inputSend.Text, DateTime.Now, false));
networkingController.sendMessage(selectedPartner.Code, inputSend.Text); Controller.SendMessage(selectedPartner.Code, "message", inputSend.Text);
// clear input // clear input
inputSend.Text = ""; inputSend.Text = "";
} }
public async void OnOpenNewChatDialog(object sender = null, RoutedEventArgs e = null) public async void OnOpenNewChatDialog(object sender = null, RoutedEventArgs e = null)
{ {
// test
/*
OnIncomingMessage(
"localhost",
new JObject(
new JProperty("type", "message"),
new JProperty("content", "Test")
).ToString(),
DateTime.Now
);
*/
NewChatDialog dialog = new NewChatDialog(); NewChatDialog dialog = new NewChatDialog();
var result = await dialog.ShowAsync(); var result = await SafelyOpenDialog(dialog);
if (result == ContentDialogResult.Primary) if (result == ContentDialogResult.Primary)
{ {
string ip = IP.GetIPfromCode(dialog.getValue()); string ip = IP.GetIPFromCode(dialog.getValue());
networkingController.connectNewClient(ip); Controller.Connect(ip);
Partners.Add(new ChatPartner( ChatPartner pa = Partners.FirstOrDefault(p => p.Code == ip);
if (pa == null)
Partners.Add(new ChatPartner(
"Connecting...", "Connecting...",
ip ip
)); ));
@@ -84,41 +116,133 @@ namespace PolyChat
public async void OnOpenEditUsernameDialog(object sender = null, RoutedEventArgs e = null) public async void OnOpenEditUsernameDialog(object sender = null, RoutedEventArgs e = null)
{ {
EditUsernameDialog dialog = new EditUsernameDialog(username); EditUsernameDialog dialog = new EditUsernameDialog(username);
var result = await dialog.ShowAsync(); var result = await SafelyOpenDialog(dialog);
if (result == ContentDialogResult.Primary) if (result == ContentDialogResult.Primary)
{ {
username = dialog.getValue(); username = dialog.getValue();
if (username.Length == 0) textUsername.Text = "Unknown"; textUsername.Text = username;
else textUsername.Text = username; Controller.SendBroadcastMessage("username", username);
} }
updateNoUsernamePlaceholder(); updateNoUsernamePlaceholder();
} }
public void OnIncomingMessage(Message message) /// <summary>
/// Adds a new ChatPartner to the UI with default Name.
/// </summary>
/// <param name="ip">IP Adress, gets shown as Util.IP > Code</param>
public async void OnIncomingConnection(string ip)
{ {
ChatPartner sendingPartner = Partners.First(p => p.Code == message.Ip); await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
sendingPartner.AddMessage(new Message( {
message.Msg, Partners.Add(new ChatPartner(
true, "Connecting...",
message.Sender ip
)); ));
updateNoChatsPlaceholder();
});
}
/// <summary>
/// Adds an message to the UI, based on .sender if known
/// </summary>
/// <param name="message">ChatMessage</param>
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.Name = content;
int index = Partners.IndexOf(sendingPartner);
Partners.Remove(sendingPartner);
Partners.Insert(index, sendingPartner);
break;
default:
sendingPartner.AddMessage(new ChatMessage(origin, type, content, timeStamp, true));
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()),
false // TODO: FIX !!!!
)
);
}
});
} }
private void OnDeleteChat(object sender = null, RoutedEventArgs e = null) private void OnDeleteChat(object sender = null, RoutedEventArgs e = null)
{ {
Controller.CloseChat(selectedPartner.Code,delete: true);
Partners.Remove(selectedPartner); Partners.Remove(selectedPartner);
updateNoChatsPlaceholder(); 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);
}
public void OnToggleTheme(object sender, RoutedEventArgs e)
{
Theme = Theme == ElementTheme.Light ? ElementTheme.Dark : ElementTheme.Light;
RequestedTheme = Theme;
} }
private void OnKeyUp(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e) private void OnKeyUp(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{ {
updateSendButtonEnabled(); updateSendButtonEnabled();
if (e.Key == Windows.System.VirtualKey.Enter) if (buttonSend.IsEnabled && e.Key == Windows.System.VirtualKey.Enter)
{ {
OnSendMessage(); OnSendMessage();
} }
} }
public static IAsyncOperation<ContentDialogResult> SafelyOpenDialog(ContentDialog d)
{
if(VisualTreeHelper.GetOpenPopups(Window.Current).Count == 0)
return d.ShowAsync();
return null;
}
// GETTERS
public static ElementTheme GetTheme() => Theme;
// UPDATE FUNCTIONS FOR UI PLACEHOLDERS // UPDATE FUNCTIONS FOR UI PLACEHOLDERS
private void updateNoChatsPlaceholder() private void updateNoChatsPlaceholder()

View File

@@ -1,29 +1,42 @@
using System; using System;
using System.Diagnostics;
using System.Text.Json;
using Windows.UI.Xaml;
namespace PolyChat.Models namespace PolyChat.Models
{ {
public class ChatMessage public class ChatMessage
{ {
public readonly string Sender; public string Origin;
public readonly DateTime Timestamp = new DateTime(1970, 01, 01); public string Type;
public readonly string Content; public string Content;
public readonly string Ip; public DateTime TimeStamp;
public readonly bool Foreign; public HorizontalAlignment Align;
private bool Foreign;
public ChatMessage(string Content = "", bool Foreign = true, string Sender= "Unknown", string Ip = "127.0.0.1") /// <summary>
/// Create Message
/// </summary>
/// <param name="origin">Origin IP</param>
/// <param name="type">Message Type, usually "message"</param>
/// <param name="content">Message Content, usually plain text</param>
/// <param name="timeStamp">Parsed DateTime</param>
public ChatMessage(string origin, string type, string content, DateTime timeStamp, bool foreign)
{ {
this.Sender = Sender; Origin = origin;
this.Timestamp = DateTime.Now; TimeStamp = timeStamp;
this.Content = Content; Type = type;
this.Foreign = Foreign; Content = content;
this.Ip = Ip; Align = foreign ? HorizontalAlignment.Right : HorizontalAlignment.Left;
Foreign = foreign;
Debug.WriteLine("Created Loaded Message: " + ToString());
} }
override override
public string ToString() public string ToString()
{ {
string prefix = Foreign ? "Other" : "Me"; string prefix = Foreign ? "Other" : "Me";
return $"{prefix}: {Content}({Sender})"; return $"{Type} from {prefix}: {Content}({Origin})";
} }
} }
} }

View File

@@ -1,5 +1,8 @@
using SocketIOSharp.Server.Client; using SocketIOSharp.Server.Client;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace PolyChat.Models namespace PolyChat.Models
{ {
@@ -7,20 +10,20 @@ namespace PolyChat.Models
{ {
public string Name; public string Name;
public string Code; public string Code;
public ObservableCollection<Message> Messages; public ObservableCollection<ChatMessage> Messages;
private SocketIOSocket socketIOSocket; private SocketIOSocket socketIOSocket;
public ChatPartner(string name, string code, ObservableCollection<Message> messages = null) public ChatPartner(string name, string code, ObservableCollection<ChatMessage> messages = null)
{ {
Name = name; Name = name;
Code = code; Code = code;
if (messages == null) Messages = new ObservableCollection<Message>(); if (messages == null) Messages = new ObservableCollection<ChatMessage>();
else Messages = messages; else Messages = messages;
} }
public SocketIOSocket SocketIOSocket { get => socketIOSocket; set => socketIOSocket = value; } public SocketIOSocket SocketIOSocket { get => socketIOSocket; set => socketIOSocket = value; }
public void AddMessage(Message message) public void AddMessage(ChatMessage message)
{ {
Messages.Add(message); Messages.Add(message);
} }

View File

@@ -0,0 +1,101 @@
using System;
using System.Diagnostics;
using EngineIOSharp.Common.Enum;
using Newtonsoft.Json.Linq;
using SocketIOSharp.Client;
using SocketIOSharp.Common;
using SocketIOSharp.Server.Client;
using PolyChat.Models;
namespace PolyChat.Models
{
public class Connection
{
private SocketIOClient Client;
private SocketIOSocket Socket;
private bool Connected = false;
private readonly string IP;
private Action<string, bool, bool> DeleteConnection;
public Connection(string ip, ushort port, Action<JToken[]> onMessage, Action<string, bool, bool> onClose)
{
Debug.WriteLine("! CONNECTING TO SERVER !");
IP = ip;
DeleteConnection = onClose;
// establish connection
Client = new SocketIOClient(new SocketIOClientOption(EngineIOScheme.http, ip, port));
Client.Connect();
// setup event listeners
Client.On(SocketIOEvent.CONNECTION, OnConnect);
Client.On(SocketIOEvent.DISCONNECT, OnDisconnect);
Client.On(SocketIOEvent.ERROR, (JToken[] Data) => OnError(Data));
Client.On("message", (Action<JToken[]>) onMessage);
}
public Connection(SocketIOSocket socket, Action<JToken[]> onMessage, Action<string, bool, bool> onClose)
{
Socket = socket;
DeleteConnection = onClose;
Socket.On(SocketIOEvent.DISCONNECT, OnDisconnect);
Socket.On(SocketIOEvent.ERROR, (JToken[] Data) => OnError(Data));
Socket.On("message", (Action<JToken[]>) onMessage);
//we are connected if we got here, inital packet was already received
Connected = true;
}
public void SendMessage(string message)
{
Debug.WriteLine("--- Sending message ---");
Debug.WriteLine($"Connected {Connected}");
Debug.WriteLine($"Client {Client}");
Debug.WriteLine($"Socket {Socket}");
if (Socket != null) Socket.Emit("message", message);
else if (Client != null) Client.Emit("message", message);
}
// Event Methods
private void OnConnect()
{
Debug.WriteLine("--- Sending initial packet to server ---");
Client.Emit("initial", Controller.getIP());
Debug.WriteLine("--- Connection successfull ---");
Connected = true;
}
private void OnDisconnect()
{
Debug.WriteLine("--- Disconnected! ---");
Debug.WriteLine($"--- Deleting Connection with IP: {IP}---");
DeleteConnection(IP, IsConnected(),false);
Connected = false;
}
private void OnError(JToken[] data)
{
Debug.WriteLine("--- Error: ---");
if (data != null && data.Length > 0 && data[0] != null)
Debug.WriteLine(data[0]);
else
Debug.WriteLine("Unkown Error");
Debug.WriteLine("---");
Close();
}
// Getters
public void Close()
{
if (Client != null) Client.Close();
if (Socket != null) Socket.Close();
}
public bool IsConnected()
{
return Connected;
}
public string getIP()
{
return IP;
}
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PolyChat.Models
{
public class DialogButton
{
public string Text;
public Action Action;
public DialogButton(string text, Action action)
{
Text = text;
Action = action;
}
}
}

View File

@@ -0,0 +1,258 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Cryptography;
using System.Diagnostics;
using System.Threading;
using Newtonsoft.Json.Linq;
namespace PolyChat.Models
{
class FileManager
{
// Controller
private readonly Controller controller;
//===============================================================================================================================================
//Constructor
//===============================================================================================================================================
public FileManager(Controller controller)
{
this.controller = controller;
}
//===============================================================================================================================================
// editing save files
//===============================================================================================================================================
/// <summary>
/// deletes chatlog of one speciffic user
/// </summary>
/// <param name="ip"></param>
public void deleteChat(String ip)
{
if (Directory.Exists("U:\\PolyChat\\Saves"))
{
Debug.WriteLine("--Path exists.--");
//go through all files and send ip and json array to ui
String[] filepaths = Directory.GetFiles("U:\\PolyChat\\Saves");
if (filepaths.Length > 0)
{
foreach (String path in filepaths)
{
if (Path.GetFileName(path).Equals(ip+".txt"))
{
File.Delete(path);
return;
}
}
}
}
}
/// <summary>
/// loads one chatlog probably when someone tries to connect
/// </summary>
/// <param name="ip"></param>
public void loadChat(String ip)
{
//load dir and create if non existant
if (Directory.Exists("U:\\PolyChat\\Saves"))
{
Debug.WriteLine("--Path exists.--");
if (File.Exists($"U:\\PolyChat\\Saves\\{ip}.txt"))
{
String jsonArr = decrypt(File.ReadAllText($"U:\\PolyChat\\Saves\\{ip}.txt"));
controller.SendIncomingMessageUI(ip, jsonArr);
}
}
}
/// <summary>
/// sends chatlogs as json array to uiController with corrosponding ip
///
/// in ui when chat is clicked connection gets established
/// </summary>
/// <param name="ip"></param>
public void loadChats()
{
//load dir and create if non existant
if (Directory.Exists("U:\\PolyChat\\Saves"))
{
Debug.WriteLine("--Path exists.--");
}
else
{
Directory.CreateDirectory("U:\\PolyChat\\Saves");
Debug.WriteLine("--Path Created--.");
}
//go through all files and send ip and json array to ui
String[] filepaths = Directory.GetFiles("U:\\PolyChat\\Saves");
if (filepaths.Length > 0)
{
Debug.WriteLine("---Loading Saves");
foreach (String path in filepaths)
{
Debug.WriteLine($"--{path}");
String jsonArr = decrypt(File.ReadAllText(path));
String ip = Path.GetFileName(path);
ip = ip.Substring(0, ip.Length - 4);
Debug.WriteLine($"-{ip}");
Debug.WriteLine(jsonArr);
controller.SendIncomingMessageUI(ip, jsonArr);
}
}
}
/// <summary>
/// Saves incoming chat message to U:\PolyChat\Saves\ip.txt
/// </summary>
/// <param name="ip"></param>
/// <param name="json"></param>
public void saveChats(string ip, string json, DateTime timeStamp)
{
new Thread(() =>
{
//breaking if namechange
JObject obj = JObject.Parse(json);
if (!obj["type"].ToString().Equals("username"))
{
//adding timestamp
obj.Add(new JProperty("timestamp", timeStamp));
json = obj.ToString();
if (File.Exists($"U:\\PolyChat\\Saves\\{ip}.txt"))
{
Debug.WriteLine("--File allready exists--");
//check for integraty of file
string output = decrypt(File.ReadAllText($"U:\\PolyChat\\Saves\\{ip}.txt"));
Debug.WriteLine($"---{output}---");
if (output.Substring(0, 1).Equals("[") && output.Substring(output.Length - 1, 1).Equals("]"))
{
//structure intact
//save new chat
Debug.WriteLine("--adding new chatmessage--");
output = output.Substring(0, output.Length - 1) + ", " + json + " ]"; //rip appart and put file back together
File.Delete($"U:\\PolyChat\\Saves\\{ip}.txt");
File.WriteAllText($"U:\\PolyChat\\Saves\\{ip}.txt", encrypt(output)); //encrypt and save to textfile
}
else
{
//structure not intact
//redo file
Debug.WriteLine("--Structure not intact--");
Debug.WriteLine("--redoing file--");
File.Delete($"U:\\PolyChat\\Saves\\{ip}.txt");
File.WriteAllText($"U:\\PolyChat\\Saves\\{ip}.txt", encrypt($"[ {json} ]")); //encrypt and write to file
}
}
else
{
//setup file
Debug.WriteLine("--Creating new File--");
File.WriteAllText($"U:\\PolyChat\\Saves\\{ip}.txt", encrypt($"[ {json} ]"));
}
}
}).Start();
}
//===============================================================================================================================================
// Encryption
//===============================================================================================================================================
/// <summary>
/// generates keypair [public, privte] (100% secure, trust me)
/// </summary>
/// <returns></returns>
private String[] genKeys()
{
return new String[] {"12345678", "12345678" };
}
/// <summary>
/// does exactly what it says. XD
///
/// encrypts given string and returns unreadable string
/// </summary>
/// <param name="toEncrypt"></param>
/// <returns></returns>
private String encrypt(String toEncrypt)
{
try
{
string textToEncrypt = toEncrypt;
string ToReturn = "";
string publickey = genKeys()[0];
string secretkey = genKeys()[1];
byte[] secretkeyByte = { };
secretkeyByte = System.Text.Encoding.UTF8.GetBytes(secretkey);
byte[] publickeybyte = { };
publickeybyte = System.Text.Encoding.UTF8.GetBytes(publickey);
MemoryStream ms = null;
CryptoStream cs = null;
byte[] inputbyteArray = System.Text.Encoding.UTF8.GetBytes(textToEncrypt);
using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
{
ms = new MemoryStream();
cs = new CryptoStream(ms, des.CreateEncryptor(publickeybyte, secretkeyByte), CryptoStreamMode.Write);
cs.Write(inputbyteArray, 0, inputbyteArray.Length);
cs.FlushFinalBlock();
ToReturn = Convert.ToBase64String(ms.ToArray());
}
return ToReturn;
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex.InnerException);
}
}
/// <summary>
/// does exactly what it says. XD
///
/// takes in unreadable string and returns infirmation
/// </summary>
/// <param name="toEncrypt"></param>
/// <returns></returns>
private String decrypt(String toDecrypt)
{
try
{
string textToDecrypt = toDecrypt;
string ToReturn = "";
string publickey = genKeys()[0];
string privatekey = genKeys()[1];
byte[] privatekeyByte = { };
privatekeyByte = System.Text.Encoding.UTF8.GetBytes(privatekey);
byte[] publickeybyte = { };
publickeybyte = System.Text.Encoding.UTF8.GetBytes(publickey);
MemoryStream ms = null;
CryptoStream cs = null;
byte[] inputbyteArray = new byte[textToDecrypt.Replace(" ", "+").Length];
inputbyteArray = Convert.FromBase64String(textToDecrypt.Replace(" ", "+"));
using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
{
ms = new MemoryStream();
cs = new CryptoStream(ms, des.CreateDecryptor(publickeybyte, privatekeyByte), CryptoStreamMode.Write);
cs.Write(inputbyteArray, 0, inputbyteArray.Length);
cs.FlushFinalBlock();
Encoding encoding = Encoding.UTF8;
ToReturn = encoding.GetString(ms.ToArray());
}
return ToReturn;
}
catch (Exception ae)
{
throw new Exception(ae.Message, ae.InnerException);
}
}
}
}

View File

@@ -1,29 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace PolyChat.Models
{
/// <summary>
/// dumy class for json converter
/// </summary>
public class MSG
{
public String sender = "unknown";
public DateTime timestamp = new DateTime(2000, 01, 01);
public String msg = "empty";
public IPAddress ip = new IPAddress(new byte[] { 49,48,46,49,46,50,49,49,46,50,54 });
public MSG(IPAddress ip, String msg, DateTime timestamp)
{
this.sender = sender;
this.ip = ip;
this.timestamp = timestamp;
this.msg = msg;
}
}
}

View File

@@ -1,10 +0,0 @@
namespace PolyChat.Models
{
enum SendCode
{
Message,
Command,
NameChange,
Initial
}
}

View File

@@ -13,8 +13,8 @@
<Identity <Identity
Name="ee2ef4f2-e61b-497a-8f0e-9fa7c90234b1" Name="ee2ef4f2-e61b-497a-8f0e-9fa7c90234b1"
Publisher="CN=HPL2FE" Publisher="CN=PatrickMarcFelix"
Version="1.0.0.0" /> Version="0.1.0.0" />
<mp:PhoneIdentity PhoneProductId="ee2ef4f2-e61b-497a-8f0e-9fa7c90234b1" PhonePublisherId="00000000-0000-0000-0000-000000000000"/> <mp:PhoneIdentity PhoneProductId="ee2ef4f2-e61b-497a-8f0e-9fa7c90234b1" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
@@ -87,4 +87,4 @@
<DeviceCapability Name="proximity"/> <DeviceCapability Name="proximity"/>
<DeviceCapability Name="webcam"/> <DeviceCapability Name="webcam"/>
</Capabilities> </Capabilities>
</Package> </Package>

View File

@@ -17,7 +17,15 @@
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WindowsXamlEnableOverview>true</WindowsXamlEnableOverview> <WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled> <AppxPackageSigningEnabled>False</AppxPackageSigningEnabled>
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
<GenerateTestArtifacts>True</GenerateTestArtifacts>
<AppxBundle>Always</AppxBundle>
<AppxBundlePlatforms>x86</AppxBundlePlatforms>
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
<PackageCertificateThumbprint>6B0D12FC4E83C6F6997C60706A04799ED44B7E56</PackageCertificateThumbprint>
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -119,20 +127,21 @@
<Compile Include="App.xaml.cs"> <Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon> <DependentUpon>App.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Models\DialogButton.cs" />
<Compile Include="Models\Connection.cs" />
<Compile Include="Controller.cs" />
<Compile Include="MainPage.xaml.cs"> <Compile Include="MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon> <DependentUpon>MainPage.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Models\Message.cs" /> <Compile Include="Models\ChatMessage.cs" />
<Compile Include="Models\ChatPartner.cs" /> <Compile Include="Models\ChatPartner.cs" />
<Compile Include="Models\Exceptions\MessageTimedOutException.cs" /> <Compile Include="Models\Exceptions\MessageTimedOutException.cs" />
<Compile Include="Models\NetworkingController.cs" />
<Compile Include="Models\Client.cs" />
<Compile Include="Models\Exceptions\ConnectionFailedException.cs" /> <Compile Include="Models\Exceptions\ConnectionFailedException.cs" />
<Compile Include="Models\SendCode.cs" /> <Compile Include="Models\FileManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Util\IP.cs" /> <Compile Include="Util\IP.cs" />
<Compile Include="Views\ConnectionFailedDialog.xaml.cs"> <Compile Include="Views\Dialog.xaml.cs">
<DependentUpon>ConnectionFailedDialog.xaml</DependentUpon> <DependentUpon>Dialog.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\EditUsernameDialog.xaml.cs"> <Compile Include="Views\EditUsernameDialog.xaml.cs">
<DependentUpon>EditUsernameDialog.xaml</DependentUpon> <DependentUpon>EditUsernameDialog.xaml</DependentUpon>
@@ -165,7 +174,7 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Page> </Page>
<Page Include="Views\ConnectionFailedDialog.xaml"> <Page Include="Views\Dialog.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Page> </Page>
@@ -185,9 +194,15 @@
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform"> <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.12</Version> <Version>6.2.12</Version>
</PackageReference> </PackageReference>
<PackageReference Include="SocketIoClientDotNet">
<Version>0.9.13</Version>
</PackageReference>
<PackageReference Include="SocketIOSharp"> <PackageReference Include="SocketIOSharp">
<Version>2.0.3</Version> <Version>2.0.3</Version>
</PackageReference> </PackageReference>
<PackageReference Include="System.Text.Json">
<Version>5.0.2</Version>
</PackageReference>
</ItemGroup> </ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' "> <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion> <VisualStudioVersion>14.0</VisualStudioVersion>

View File

@@ -7,7 +7,7 @@ namespace PolyChat.Util
{ {
private const string REGEX_IP = @"^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$"; private const string REGEX_IP = @"^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$";
public static string GetIPfromCode(string code) public static string GetIPFromCode(string code)
{ {
return code; return code;
} }

View File

@@ -1,26 +0,0 @@
using PolyChat.Models;
using PolyChat.Util;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.UI.Popups;
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.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class ConnectionFailedDialog : ContentDialog
{
public ConnectionFailedDialog(string message)
{
this.InitializeComponent();
textError.Text = message;
}
}
}

View File

@@ -1,17 +1,20 @@
<ContentDialog x:Class="PolyChat.Views.ConnectionFailedDialog" <ContentDialog x:Class="PolyChat.Views.Dialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:PolyChat.Views" xmlns:local="using:PolyChat.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="MessageDialog" x:Name="MessageDialog"
Title="Connection Failed" Title="Header"
PrimaryButtonText="Retry" PrimaryButtonText="Primary"
SecondaryButtonText="Abort" PrimaryButtonClick="OnPrimaryButtonClick"
SecondaryButtonText="Secondary"
SecondaryButtonClick="OnSecondaryButtonClick"
mc:Ignorable="d"> mc:Ignorable="d">
<StackPanel> <StackPanel>
<TextBlock Text="Message:" Foreground="{ThemeResource SystemColorDisabledTextColor}" Margin="0 0 0 8"/> <TextBlock Text="Message:" Foreground="{ThemeResource SystemColorDisabledTextColor}" Margin="0 0 0 8"/>
<TextBlock x:Name="textError" Foreground="{ThemeResource SystemErrorTextColor}"/> <TextBlock x:Name="textError" Foreground="{ThemeResource SystemErrorTextColor}" Visibility="Collapsed"/>
<TextBlock x:Name="textSuccess" Foreground="{ThemeResource SystemAccentColor}" Visibility="Collapsed"/>
</StackPanel> </StackPanel>
</ContentDialog> </ContentDialog>

View File

@@ -0,0 +1,70 @@
using PolyChat.Models;
using PolyChat.Util;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using Windows.Foundation;
using Windows.UI.Core;
using Windows.UI.Popups;
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.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Dialog : ContentDialog
{
public const string TYPE_ERROR = "error";
public const string TYPE_SUCCESS = "success";
private Action Primary;
private Action Secondary;
public Dialog(string type, string header, string message, DialogButton primary, DialogButton secondary)
{
this.InitializeComponent();
Title = header;
setType(type, message);
PrimaryButtonText = primary.Text;
SecondaryButtonText = secondary.Text;
// TODO: use event handlers and asign actions here
Primary = primary.Action;
Secondary = secondary.Action;
RequestedTheme = MainPage.GetTheme();
}
private void setType(string type, string message)
{
switch (type)
{
case TYPE_ERROR:
textError.Text = message;
textError.Visibility = Visibility.Visible;
break;
case TYPE_SUCCESS:
textSuccess.Text = message;
textSuccess.Visibility = Visibility.Visible;
break;
}
}
private async void ShowDialogAsync()
{
await ShowAsync();
}
private void OnPrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
Primary();
}
private void OnSecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
Secondary();
}
}
}

View File

@@ -22,6 +22,7 @@ namespace PolyChat.Views
if (initialValue == null || initialValue.Length == 0) IsSecondaryButtonEnabled = false; if (initialValue == null || initialValue.Length == 0) IsSecondaryButtonEnabled = false;
else input.Text = initialValue; else input.Text = initialValue;
validate(); validate();
RequestedTheme = MainPage.GetTheme();
} }
public string getValue() public string getValue()

View File

@@ -20,6 +20,7 @@ namespace PolyChat.Views
{ {
this.InitializeComponent(); this.InitializeComponent();
IsPrimaryButtonEnabled = false; IsPrimaryButtonEnabled = false;
RequestedTheme = MainPage.GetTheme();
} }
public string getValue() public string getValue()
@@ -29,7 +30,7 @@ namespace PolyChat.Views
private void OnKeyUp(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e) private void OnKeyUp(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{ {
if (!IP.ValidateIP(IP.GetIPfromCode(input.Text))) if (!IP.ValidateIP(IP.GetIPFromCode(input.Text)))
{ {
textSuccess.Visibility = Visibility.Collapsed; textSuccess.Visibility = Visibility.Collapsed;
textError.Visibility = Visibility.Visible; textError.Visibility = Visibility.Visible;

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB