Added WebRTC stuff - Needs Testing.

This commit is contained in:
2026-03-29 15:18:57 -04:00
parent 0bb3aa28b1
commit 8c6724038a
8 changed files with 417 additions and 170 deletions

View File

@@ -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.");
}
}