Added WebRTC stuff - Needs Testing.
This commit is contained in:
@@ -15,7 +15,7 @@ public partial class MainPage : ContentPage
|
||||
private string? _currentChannelName;
|
||||
|
||||
private readonly Dictionary<string, List<ChatMessage>> _messagesByChannel = new();
|
||||
private readonly List<ChannelItem> _channels = new();
|
||||
private readonly List<ChannelItem> _channels = [];
|
||||
|
||||
public MainPage(string username)
|
||||
{
|
||||
@@ -41,6 +41,11 @@ public partial class MainPage : ContentPage
|
||||
_wsc.Send("GET_SERVER_KEY");
|
||||
_wsc.Send("GET_CHANNELS");
|
||||
hybridWebView.SetInvokeJavaScriptTarget(this);
|
||||
|
||||
Loaded += async (_, _) =>
|
||||
{
|
||||
await InitializeRtcPageAsync();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -66,6 +71,12 @@ public partial class MainPage : ContentPage
|
||||
Console.WriteLine("Server public key not loaded yet.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(_currentChannelId))
|
||||
{
|
||||
Console.WriteLine("No channel selected yet.");
|
||||
return;
|
||||
}
|
||||
|
||||
var encrypted = E2EeHelper.EncryptForRecipient(text, _serverPublicKey);
|
||||
|
||||
@@ -152,49 +163,79 @@ public partial class MainPage : ContentPage
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == "encrypted_rtc_signal")
|
||||
{
|
||||
var payload = JsonSerializer.Deserialize<SocketRtcSignalMessage>(e.Data);
|
||||
if (payload is null)
|
||||
return;
|
||||
|
||||
if (payload.RecipientUsername != _username)
|
||||
return;
|
||||
|
||||
var privateKey = KeyStorage.LoadPrivateKey(_username);
|
||||
|
||||
var decryptedJson = E2EeHelper.DecryptForRecipient(
|
||||
new EncryptedPayload
|
||||
{
|
||||
CipherText = payload.CipherText,
|
||||
Nonce = payload.Nonce,
|
||||
Tag = payload.Tag,
|
||||
EncryptedKey = payload.EncryptedKey
|
||||
},
|
||||
privateKey
|
||||
);
|
||||
|
||||
MainThread.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
await SendRtcSignalToJsAsync(decryptedJson);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != "encrypted_chat")
|
||||
return;
|
||||
|
||||
var payload = JsonSerializer.Deserialize<SocketEncryptedMessage>(e.Data);
|
||||
if (payload is null)
|
||||
var pyload = JsonSerializer.Deserialize<SocketEncryptedMessage>(e.Data);
|
||||
if (pyload is null)
|
||||
return;
|
||||
|
||||
if (payload.RecipientUsername != _username)
|
||||
if (pyload.RecipientUsername != _username)
|
||||
return;
|
||||
|
||||
Console.WriteLine($"[{_username}] received encrypted payload for {payload.RecipientUsername}");
|
||||
Console.WriteLine($"[{_username}] received encrypted payload for {pyload.RecipientUsername}");
|
||||
|
||||
var privateKey = KeyStorage.LoadPrivateKey(_username);
|
||||
var privKey = KeyStorage.LoadPrivateKey(_username);
|
||||
|
||||
var decryptedText = E2EeHelper.DecryptForRecipient(
|
||||
new EncryptedPayload
|
||||
{
|
||||
CipherText = payload.CipherText,
|
||||
Nonce = payload.Nonce,
|
||||
Tag = payload.Tag,
|
||||
EncryptedKey = payload.EncryptedKey
|
||||
CipherText = pyload.CipherText,
|
||||
Nonce = pyload.Nonce,
|
||||
Tag = pyload.Tag,
|
||||
EncryptedKey = pyload.EncryptedKey
|
||||
},
|
||||
privateKey
|
||||
privKey
|
||||
);
|
||||
|
||||
Console.WriteLine($"[{_username}] decrypted message from {payload.SenderUsername}: {decryptedText}");
|
||||
Console.WriteLine($"[{_username}] decrypted message from {pyload.SenderUsername}: {decryptedText}");
|
||||
|
||||
var message = new ChatMessage
|
||||
{
|
||||
SenderUsername = payload.SenderUsername,
|
||||
SenderUsername = pyload.SenderUsername,
|
||||
Text = decryptedText,
|
||||
Timestamp = DateTime.Now
|
||||
};
|
||||
|
||||
if (!_messagesByChannel.ContainsKey(payload.ChannelId))
|
||||
if (!_messagesByChannel.ContainsKey(pyload.ChannelId))
|
||||
{
|
||||
_messagesByChannel[payload.ChannelId] = [];
|
||||
_messagesByChannel[pyload.ChannelId] = [];
|
||||
}
|
||||
|
||||
_messagesByChannel[payload.ChannelId].Add(message);
|
||||
_messagesByChannel[pyload.ChannelId].Add(message);
|
||||
|
||||
if (payload.ChannelId == _currentChannelId)
|
||||
if (pyload.ChannelId == _currentChannelId)
|
||||
{
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
@@ -296,14 +337,14 @@ public partial class MainPage : ContentPage
|
||||
{
|
||||
MessagesScrollView.IsVisible = true;
|
||||
RtcView.IsVisible = false;
|
||||
ViewSwapped.Text = "Swap to Message View";
|
||||
ViewSwapped.Text = "Swap to Web View";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
MessagesScrollView.IsVisible = false;
|
||||
RtcView.IsVisible = true;
|
||||
ViewSwapped.Text = "Swap to Web View";
|
||||
ViewSwapped.Text = "Swap to Message View";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,62 +357,56 @@ public partial class MainPage : ContentPage
|
||||
{
|
||||
await DisplayAlertAsync("Raw Message Received", e.Message, "OK");
|
||||
}
|
||||
|
||||
#region syncs
|
||||
public async void DoSyncWork()
|
||||
{
|
||||
await DisplayAlertAsync("Sync Work", "Sync Work", "OK");
|
||||
}
|
||||
|
||||
public async void DoSyncWorkParams(int i, string s)
|
||||
{
|
||||
await DisplayAlertAsync("Sync Work", $"{i}:{s}", "OK");
|
||||
}
|
||||
|
||||
public string DoSyncWorkReturn()
|
||||
{
|
||||
return "Hello from C#!";
|
||||
}
|
||||
|
||||
public SyncReturn DoSyncWorkParamsReturn(int i, string s)
|
||||
{
|
||||
return new SyncReturn
|
||||
{
|
||||
Message = $"Hello from C#! {s}",
|
||||
Value = i
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region asyncs
|
||||
|
||||
public async Task DoAsyncWork()
|
||||
public void SendRtcSignal(string json)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
public async Task DoAsyncWorkParams(int i, string s)
|
||||
{
|
||||
await DisplayAlertAsync("Sync Work", $"{i}:{s}", "OK");
|
||||
}
|
||||
public async Task<string> DoAsyncWorkReturn()
|
||||
{
|
||||
return "Hello from C#!";
|
||||
}
|
||||
|
||||
public async Task<SyncReturn> DoAsyncWorkParamsReturn(int i, string s)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
return new SyncReturn
|
||||
if (string.IsNullOrWhiteSpace(_serverPublicKey))
|
||||
{
|
||||
Message = $"Hello from C# ASync! {s}",
|
||||
Value = i
|
||||
};
|
||||
}
|
||||
Console.WriteLine("Server public key not loaded yet.");
|
||||
return;
|
||||
}
|
||||
|
||||
#endregion
|
||||
public class SyncReturn
|
||||
RtcSignalMessage? rtcSignal;
|
||||
try
|
||||
{
|
||||
rtcSignal = JsonSerializer.Deserialize<RtcSignalMessage>(json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Failed to parse RTC signal from JS: {ex.Message}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rtcSignal is null)
|
||||
return;
|
||||
|
||||
var encrypted = E2EeHelper.EncryptForRecipient(json, _serverPublicKey);
|
||||
|
||||
var payload = new SocketRtcSignalMessage
|
||||
{
|
||||
Type = "encrypted_rtc_signal",
|
||||
SenderUsername = _username,
|
||||
RecipientUsername = rtcSignal.To,
|
||||
CipherText = encrypted.CipherText,
|
||||
Nonce = encrypted.Nonce,
|
||||
Tag = encrypted.Tag,
|
||||
EncryptedKey = encrypted.EncryptedKey
|
||||
};
|
||||
|
||||
_wsc.Send(JsonSerializer.Serialize(payload));
|
||||
Console.WriteLine($"[{_username}] sent RTC signal: {rtcSignal.Type} -> {rtcSignal.To}");
|
||||
}
|
||||
|
||||
private async Task SendRtcSignalToJsAsync(string rawJson)
|
||||
{
|
||||
public string? Message { get; set; }
|
||||
public int Value { get; set; }
|
||||
var jsArg = JsonSerializer.Serialize(rawJson);
|
||||
await hybridWebView.EvaluateJavaScriptAsync($"window.handleRtcSignal({jsArg})");
|
||||
}
|
||||
|
||||
private async Task InitializeRtcPageAsync()
|
||||
{
|
||||
var jsArg = JsonSerializer.Serialize(_username);
|
||||
await hybridWebView.EvaluateJavaScriptAsync($"window.currentUsername = {jsArg};");
|
||||
Console.WriteLine($"[{_username}] RTC page initialized.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user