2 Commits

Author SHA1 Message Date
a1ddf380dd remade into 1 project 2026-03-14 18:40:42 -04:00
eb927b3038 remade into 1 project 2026-03-14 18:33:38 -04:00
42 changed files with 1971 additions and 1946 deletions

25
.dockerignore Normal file
View File

@@ -0,0 +1,25 @@
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.idea
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

184
.gitignore vendored
View File

@@ -1,93 +1,93 @@
############################################
# .NET Build
############################################
bin/
obj/
out/
publish/
############################################
# Visual Studio
############################################
.vs/
*.user
*.suo
*.userprefs
*.csproj.user
*.dbmdl
*.cache
*.pdb
*.opendb
############################################
# Rider / JetBrains
############################################
.idea/
*.sln.iml
############################################
# VSCode
############################################
.vscode/
############################################
# NuGet
############################################
*.nupkg
*.snupkg
packages/
.nuget/
.nuget/packages/
############################################
# Logs
############################################
*.log
logs/
############################################
# OS files
############################################
.DS_Store
Thumbs.db
############################################
# Local secrets / environment
############################################
.env
.env.*
secrets.json
appsettings.Development.json
############################################
# E2EE private keys
############################################
keys/*
!keys/.gitkeep
############################################
# Local test databases / data folders
############################################
data/
*.db
*.sqlite
*.sqlite3
############################################
# Temporary files
############################################
*.tmp
*.temp
*.bak
############################################
# .NET Build
############################################
bin/
obj/
out/
publish/
############################################
# Visual Studio
############################################
.vs/
*.user
*.suo
*.userprefs
*.csproj.user
*.dbmdl
*.cache
*.pdb
*.opendb
############################################
# Rider / JetBrains
############################################
.idea/
*.sln.iml
############################################
# VSCode
############################################
.vscode/
############################################
# NuGet
############################################
*.nupkg
*.snupkg
packages/
.nuget/
.nuget/packages/
############################################
# Logs
############################################
*.log
logs/
############################################
# OS files
############################################
.DS_Store
Thumbs.db
############################################
# Local secrets / environment
############################################
.env
.env.*
secrets.json
appsettings.Development.json
############################################
# E2EE private keys
############################################
keys/*
!keys/.gitkeep
############################################
# Local test databases / data folders
############################################
data/
*.db
*.sqlite
*.sqlite3
############################################
# Temporary files
############################################
*.tmp
*.temp
*.bak
*.swp

124
Relay.sln
View File

@@ -1,62 +1,62 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RelayCore", "RelayCore\RelayCore.csproj", "{346BE501-DE74-4E88-9787-4722FBC8BD0D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RelayClient", "RelayClient\RelayClient.csproj", "{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RelayServer", "RelayServer\RelayServer.csproj", "{38995780-E9AA-44D6-B62D-07CCA45E4E4C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Debug|x64.ActiveCfg = Debug|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Debug|x64.Build.0 = Debug|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Debug|x86.ActiveCfg = Debug|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Debug|x86.Build.0 = Debug|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Release|Any CPU.Build.0 = Release|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Release|x64.ActiveCfg = Release|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Release|x64.Build.0 = Release|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Release|x86.ActiveCfg = Release|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Release|x86.Build.0 = Release|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Debug|x64.ActiveCfg = Debug|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Debug|x64.Build.0 = Debug|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Debug|x86.ActiveCfg = Debug|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Debug|x86.Build.0 = Debug|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Release|Any CPU.Build.0 = Release|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Release|x64.ActiveCfg = Release|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Release|x64.Build.0 = Release|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Release|x86.ActiveCfg = Release|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Release|x86.Build.0 = Release|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Debug|x64.ActiveCfg = Debug|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Debug|x64.Build.0 = Debug|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Debug|x86.ActiveCfg = Debug|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Debug|x86.Build.0 = Debug|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Release|Any CPU.Build.0 = Release|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Release|x64.ActiveCfg = Release|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Release|x64.Build.0 = Release|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Release|x86.ActiveCfg = Release|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RelayCore", "RelayCore\RelayCore.csproj", "{346BE501-DE74-4E88-9787-4722FBC8BD0D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RelayClient", "RelayClient\RelayClient.csproj", "{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RelayServer", "RelayServer\RelayServer.csproj", "{38995780-E9AA-44D6-B62D-07CCA45E4E4C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Debug|x64.ActiveCfg = Debug|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Debug|x64.Build.0 = Debug|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Debug|x86.ActiveCfg = Debug|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Debug|x86.Build.0 = Debug|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Release|Any CPU.Build.0 = Release|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Release|x64.ActiveCfg = Release|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Release|x64.Build.0 = Release|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Release|x86.ActiveCfg = Release|Any CPU
{346BE501-DE74-4E88-9787-4722FBC8BD0D}.Release|x86.Build.0 = Release|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Debug|x64.ActiveCfg = Debug|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Debug|x64.Build.0 = Debug|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Debug|x86.ActiveCfg = Debug|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Debug|x86.Build.0 = Debug|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Release|Any CPU.Build.0 = Release|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Release|x64.ActiveCfg = Release|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Release|x64.Build.0 = Release|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Release|x86.ActiveCfg = Release|Any CPU
{AB9DA5AB-55DC-4DE4-834C-E1E1BCD0C3CD}.Release|x86.Build.0 = Release|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Debug|x64.ActiveCfg = Debug|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Debug|x64.Build.0 = Debug|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Debug|x86.ActiveCfg = Debug|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Debug|x86.Build.0 = Debug|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Release|Any CPU.Build.0 = Release|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Release|x64.ActiveCfg = Release|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Release|x64.Build.0 = Release|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Release|x86.ActiveCfg = Release|Any CPU
{38995780-E9AA-44D6-B62D-07CCA45E4E4C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

184
RelayClient/.gitignore vendored
View File

@@ -1,93 +1,93 @@
############################################
# .NET Build
############################################
bin/
obj/
out/
publish/
############################################
# Visual Studio
############################################
.vs/
*.user
*.suo
*.userprefs
*.csproj.user
*.dbmdl
*.cache
*.pdb
*.opendb
############################################
# Rider / JetBrains
############################################
.idea/
*.sln.iml
############################################
# VSCode
############################################
.vscode/
############################################
# NuGet
############################################
*.nupkg
*.snupkg
packages/
.nuget/
.nuget/packages/
############################################
# Logs
############################################
*.log
logs/
############################################
# OS files
############################################
.DS_Store
Thumbs.db
############################################
# Local secrets / environment
############################################
.env
.env.*
secrets.json
appsettings.Development.json
############################################
# E2EE private keys
############################################
keys/*
!keys/.gitkeep
############################################
# Local test databases / data folders
############################################
data/
*.db
*.sqlite
*.sqlite3
############################################
# Temporary files
############################################
*.tmp
*.temp
*.bak
############################################
# .NET Build
############################################
bin/
obj/
out/
publish/
############################################
# Visual Studio
############################################
.vs/
*.user
*.suo
*.userprefs
*.csproj.user
*.dbmdl
*.cache
*.pdb
*.opendb
############################################
# Rider / JetBrains
############################################
.idea/
*.sln.iml
############################################
# VSCode
############################################
.vscode/
############################################
# NuGet
############################################
*.nupkg
*.snupkg
packages/
.nuget/
.nuget/packages/
############################################
# Logs
############################################
*.log
logs/
############################################
# OS files
############################################
.DS_Store
Thumbs.db
############################################
# Local secrets / environment
############################################
.env
.env.*
secrets.json
appsettings.Development.json
############################################
# E2EE private keys
############################################
keys/*
!keys/.gitkeep
############################################
# Local test databases / data folders
############################################
data/
*.db
*.sqlite
*.sqlite3
############################################
# Temporary files
############################################
*.tmp
*.temp
*.bak
*.swp

View File

@@ -1,14 +1,14 @@
<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:RelayClient"
x:Class="RelayClient.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:RelayClient"
x:Class="RelayClient.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@@ -1,16 +1,16 @@
using Microsoft.Extensions.DependencyInjection;
namespace RelayClient;
public partial class App : Application
{
public App()
{
InitializeComponent();
}
protected override Window CreateWindow(IActivationState? activationState)
{
return new Window(new AppShell());
}
using Microsoft.Extensions.DependencyInjection;
namespace RelayClient;
public partial class App : Application
{
public App()
{
InitializeComponent();
}
protected override Window CreateWindow(IActivationState? activationState)
{
return new Window(new AppShell());
}
}

View File

@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="RelayClient.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:RelayClient"
Title="RelayClient">
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />
</Shell>
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="RelayClient.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:RelayClient"
Title="RelayClient">
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />
</Shell>

View File

@@ -1,9 +1,9 @@
namespace RelayClient;
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
}
namespace RelayClient;
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
}
}

View File

@@ -1,36 +1,36 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="RelayClient.MainPage">
<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Image
Source="dotnet_bot.png"
HeightRequest="185"
Aspect="AspectFit"
SemanticProperties.Description="dot net bot in a submarine number ten" />
<Label
Text="Hello, World!"
Style="{StaticResource Headline}"
SemanticProperties.HeadingLevel="Level1" />
<Label
Text="Welcome to &#10;.NET Multi-platform App UI"
Style="{StaticResource SubHeadline}"
SemanticProperties.HeadingLevel="Level2"
SemanticProperties.Description="Welcome to dot net Multi platform App U I" />
<Button
x:Name="CounterBtn"
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Clicked="OnCounterClicked"
HorizontalOptions="Fill" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="RelayClient.MainPage">
<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Image
Source="dotnet_bot.png"
HeightRequest="185"
Aspect="AspectFit"
SemanticProperties.Description="dot net bot in a submarine number ten" />
<Label
Text="Hello, World!"
Style="{StaticResource Headline}"
SemanticProperties.HeadingLevel="Level1" />
<Label
Text="Welcome to &#10;.NET Multi-platform App UI"
Style="{StaticResource SubHeadline}"
SemanticProperties.HeadingLevel="Level2"
SemanticProperties.Description="Welcome to dot net Multi platform App U I" />
<Button
x:Name="CounterBtn"
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Clicked="OnCounterClicked"
HorizontalOptions="Fill" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>

View File

@@ -1,23 +1,23 @@
namespace RelayClient;
public partial class MainPage : ContentPage
{
int count = 0;
public MainPage()
{
InitializeComponent();
}
private void OnCounterClicked(object? sender, EventArgs e)
{
count++;
if (count == 1)
CounterBtn.Text = $"Clicked {count} time";
else
CounterBtn.Text = $"Clicked {count} times";
SemanticScreenReader.Announce(CounterBtn.Text);
}
namespace RelayClient;
public partial class MainPage : ContentPage
{
int count = 0;
public MainPage()
{
InitializeComponent();
}
private void OnCounterClicked(object? sender, EventArgs e)
{
count++;
if (count == 1)
CounterBtn.Text = $"Clicked {count} time";
else
CounterBtn.Text = $"Clicked {count} times";
SemanticScreenReader.Announce(CounterBtn.Text);
}
}

View File

@@ -1,25 +1,25 @@
using Microsoft.Extensions.Logging;
using Microsoft.Maui.Hosting;
namespace RelayClient;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
using Microsoft.Extensions.Logging;
using Microsoft.Maui.Hosting;
namespace RelayClient;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>

View File

@@ -1,12 +1,12 @@
using Android.App;
using Android.Content.PM;
using Android.OS;
namespace RelayClient;
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode |
ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
using Android.App;
using Android.Content.PM;
using Android.OS;
namespace RelayClient;
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode |
ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
}

View File

@@ -1,15 +1,15 @@
using Android.App;
using Android.Runtime;
namespace RelayClient;
[Application]
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
: base(handle, ownership)
{
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
using Android.App;
using Android.Runtime;
namespace RelayClient;
[Application]
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
: base(handle, ownership)
{
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#512BD4</color>
<color name="colorPrimaryDark">#2B0B98</color>
<color name="colorAccent">#2B0B98</color>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#512BD4</color>
<color name="colorPrimaryDark">#2B0B98</color>
<color name="colorAccent">#2B0B98</color>
</resources>

View File

@@ -1,9 +1,9 @@
using Foundation;
namespace RelayClient;
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
using Foundation;
namespace RelayClient;
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

View File

@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<!-- See https://aka.ms/maui-publish-app-store#add-entitlements for more information about adding entitlements.-->
<dict>
<!-- App Sandbox must be enabled to distribute a MacCatalyst app through the Mac App Store. -->
<key>com.apple.security.app-sandbox</key>
<true/>
<!-- When App Sandbox is enabled, this value is required to open outgoing network connections. -->
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<!-- See https://aka.ms/maui-publish-app-store#add-entitlements for more information about adding entitlements.-->
<dict>
<!-- App Sandbox must be enabled to distribute a MacCatalyst app through the Mac App Store. -->
<key>com.apple.security.app-sandbox</key>
<true/>
<!-- When App Sandbox is enabled, this value is required to open outgoing network connections. -->
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>

View File

@@ -1,40 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- The Mac App Store requires you specify if the app uses encryption. -->
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/itsappusesnonexemptencryption -->
<!-- <key>ITSAppUsesNonExemptEncryption</key> -->
<!-- Please indicate <true/> or <false/> here. -->
<!-- Specify the category for your app here. -->
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype -->
<!-- <key>LSApplicationCategoryType</key> -->
<!-- <string>public.app-category.YOUR-CATEGORY-HERE</string> -->
<key>UIDeviceFamily</key>
<array>
<integer>2</integer>
</array>
<key>LSApplicationCategoryType</key>
<string>public.app-category.lifestyle</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/appicon.appiconset</string>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- The Mac App Store requires you specify if the app uses encryption. -->
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/itsappusesnonexemptencryption -->
<!-- <key>ITSAppUsesNonExemptEncryption</key> -->
<!-- Please indicate <true/> or <false/> here. -->
<!-- Specify the category for your app here. -->
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype -->
<!-- <key>LSApplicationCategoryType</key> -->
<!-- <string>public.app-category.YOUR-CATEGORY-HERE</string> -->
<key>UIDeviceFamily</key>
<array>
<integer>2</integer>
</array>
<key>LSApplicationCategoryType</key>
<string>public.app-category.lifestyle</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/appicon.appiconset</string>
</dict>
</plist>

View File

@@ -1,15 +1,15 @@
using ObjCRuntime;
using UIKit;
namespace RelayClient;
public class Program
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, typeof(AppDelegate));
}
using ObjCRuntime;
using UIKit;
namespace RelayClient;
public class Program
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, typeof(AppDelegate));
}
}

View File

@@ -1,8 +1,8 @@
<maui:MauiWinUIApplication
x:Class="RelayClient.WinUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:maui="using:Microsoft.Maui"
xmlns:local="using:RelayClient.WinUI">
</maui:MauiWinUIApplication>
<maui:MauiWinUIApplication
x:Class="RelayClient.WinUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:maui="using:Microsoft.Maui"
xmlns:local="using:RelayClient.WinUI">
</maui:MauiWinUIApplication>

View File

@@ -1,23 +1,23 @@
using Microsoft.UI.Xaml;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace RelayClient.WinUI;
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public partial class App : MauiWinUIApplication
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
using Microsoft.UI.Xaml;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace RelayClient.WinUI;
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public partial class App : MauiWinUIApplication
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

View File

@@ -1,46 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity Name="maui-package-name-placeholder" Publisher="CN=User Name" Version="0.0.0.0" />
<mp:PhoneIdentity PhoneProductId="19688391-335B-479B-9E8A-8026C5759DFE" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>$placeholder$</DisplayName>
<PublisherDisplayName>User Name</PublisherDisplayName>
<Logo>$placeholder$.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="$placeholder$"
Description="$placeholder$"
Square150x150Logo="$placeholder$.png"
Square44x44Logo="$placeholder$.png"
BackgroundColor="transparent">
<uap:DefaultTile Square71x71Logo="$placeholder$.png" Wide310x150Logo="$placeholder$.png" Square310x310Logo="$placeholder$.png" />
<uap:SplashScreen Image="$placeholder$.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity Name="maui-package-name-placeholder" Publisher="CN=User Name" Version="0.0.0.0" />
<mp:PhoneIdentity PhoneProductId="19688391-335B-479B-9E8A-8026C5759DFE" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>$placeholder$</DisplayName>
<PublisherDisplayName>User Name</PublisherDisplayName>
<Logo>$placeholder$.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="$placeholder$"
Description="$placeholder$"
Square150x150Logo="$placeholder$.png"
Square44x44Logo="$placeholder$.png"
BackgroundColor="transparent">
<uap:DefaultTile Square71x71Logo="$placeholder$.png" Wide310x150Logo="$placeholder$.png" Square310x310Logo="$placeholder$.png" />
<uap:SplashScreen Image="$placeholder$.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="RelayClient.WinUI.app"/>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<!-- The combination of below two tags have the following effect:
1) Per-Monitor for >= Windows 10 Anniversary Update
2) System < Windows 10 Anniversary Update
-->
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
</assembly>
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="RelayClient.WinUI.app"/>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<!-- The combination of below two tags have the following effect:
1) Per-Monitor for >= Windows 10 Anniversary Update
2) System < Windows 10 Anniversary Update
-->
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
</assembly>

View File

@@ -1,9 +1,9 @@
using Foundation;
namespace RelayClient;
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
using Foundation;
namespace RelayClient;
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

View File

@@ -1,32 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/appicon.appiconset</string>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/appicon.appiconset</string>
</dict>
</plist>

View File

@@ -1,15 +1,15 @@
using ObjCRuntime;
using UIKit;
namespace RelayClient;
public class Program
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, typeof(AppDelegate));
}
using ObjCRuntime;
using UIKit;
namespace RelayClient;
public class Program
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, typeof(AppDelegate));
}
}

View File

@@ -1,51 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the minimum required version of the Apple Privacy Manifest for .NET MAUI apps.
The contents below are needed because of APIs that are used in the .NET framework and .NET MAUI SDK.
You are responsible for adding extra entries as needed for your application.
More information: https://aka.ms/maui-privacy-manifest
-->
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>E174.1</string>
</array>
</dict>
<!--
The entry below is only needed when you're using the Preferences API in your app.
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict> -->
</array>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the minimum required version of the Apple Privacy Manifest for .NET MAUI apps.
The contents below are needed because of APIs that are used in the .NET framework and .NET MAUI SDK.
You are responsible for adding extra entries as needed for your application.
More information: https://aka.ms/maui-privacy-manifest
-->
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>E174.1</string>
</array>
</dict>
<!--
The entry below is only needed when you're using the Preferences API in your app.
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict> -->
</array>
</dict>
</plist>

View File

@@ -1,8 +1,8 @@
{
"profiles": {
"Windows Machine": {
"commandName": "Project",
"nativeDebugging": false
}
}
{
"profiles": {
"Windows Machine": {
"commandName": "Project",
"nativeDebugging": false
}
}
}

View File

@@ -1,46 +1,46 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0-android;net10.0-ios;net10.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">
$(TargetFrameworks);net10.0-windows10.0.19041.0
</TargetFrameworks>
<OutputType>Exe</OutputType>
<RootNamespace>RelayClient</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<MauiXamlInflator>SourceGen</MauiXamlInflator>
<ApplicationTitle>RelayClient</ApplicationTitle>
<ApplicationId>com.companyname.relayclient</ApplicationId>
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<WindowsPackageType>None</WindowsPackageType>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
</PropertyGroup>
<ItemGroup>
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />
<MauiImage Include="Resources\Images\*" />
<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185" />
<MauiFont Include="Resources\Fonts\*" />
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.0" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0-android;net10.0-ios;net10.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">
$(TargetFrameworks);net10.0-windows10.0.19041.0
</TargetFrameworks>
<OutputType>Exe</OutputType>
<RootNamespace>RelayClient</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<MauiXamlInflator>SourceGen</MauiXamlInflator>
<ApplicationTitle>RelayClient</ApplicationTitle>
<ApplicationId>com.companyname.relayclient</ApplicationId>
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<WindowsPackageType>None</WindowsPackageType>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
</PropertyGroup>
<ItemGroup>
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />
<MauiImage Include="Resources\Images\*" />
<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185" />
<MauiFont Include="Resources\Fonts\*" />
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.0" />
</ItemGroup>
</Project>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="456" height="456" fill="#512BD4" />
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="456" height="456" fill="#512BD4" />
</svg>

Before

Width:  |  Height:  |  Size: 231 B

After

Width:  |  Height:  |  Size: 228 B

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<path d="m 105.50037,281.60863 c -2.70293,0 -5.00091,-0.90042 -6.893127,-2.70209 -1.892214,-1.84778 -2.837901,-4.04181 -2.837901,-6.58209 0,-2.58722 0.945687,-4.80389 2.837901,-6.65167 1.892217,-1.84778 4.190197,-2.77167 6.893127,-2.77167 2.74819,0 5.06798,0.92389 6.96019,2.77167 1.93749,1.84778 2.90581,4.06445 2.90581,6.65167 0,2.54028 -0.96832,4.73431 -2.90581,6.58209 -1.89221,1.80167 -4.212,2.70209 -6.96019,2.70209 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<path d="M 213.56111,280.08446 H 195.99044 L 149.69953,207.0544 c -1.17121,-1.84778 -2.14037,-3.76515 -2.90581,-5.75126 h -0.40578 c 0.36051,2.12528 0.54076,6.67515 0.54076,13.6496 v 65.13172 h -15.54349 v -99.36009 h 18.71925 l 44.7374,71.29798 c 1.89222,2.95695 3.1087,4.98917 3.64945,6.09751 h 0.26996 c -0.45021,-2.6325 -0.67573,-7.09015 -0.67573,-13.37293 v -64.02256 h 15.47557 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<path d="m 289.25134,280.08446 h -54.40052 v -99.36009 h 52.23835 v 13.99669 h -36.15411 v 28.13085 h 33.31621 v 13.9271 h -33.31621 v 29.37835 h 38.31628 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<path d="M 366.56466,194.72106 H 338.7222 v 85.3634 h -16.08423 v -85.3634 h -27.77455 v -13.99669 h 71.70124 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<path d="m 105.50037,281.60863 c -2.70293,0 -5.00091,-0.90042 -6.893127,-2.70209 -1.892214,-1.84778 -2.837901,-4.04181 -2.837901,-6.58209 0,-2.58722 0.945687,-4.80389 2.837901,-6.65167 1.892217,-1.84778 4.190197,-2.77167 6.893127,-2.77167 2.74819,0 5.06798,0.92389 6.96019,2.77167 1.93749,1.84778 2.90581,4.06445 2.90581,6.65167 0,2.54028 -0.96832,4.73431 -2.90581,6.58209 -1.89221,1.80167 -4.212,2.70209 -6.96019,2.70209 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<path d="M 213.56111,280.08446 H 195.99044 L 149.69953,207.0544 c -1.17121,-1.84778 -2.14037,-3.76515 -2.90581,-5.75126 h -0.40578 c 0.36051,2.12528 0.54076,6.67515 0.54076,13.6496 v 65.13172 h -15.54349 v -99.36009 h 18.71925 l 44.7374,71.29798 c 1.89222,2.95695 3.1087,4.98917 3.64945,6.09751 h 0.26996 c -0.45021,-2.6325 -0.67573,-7.09015 -0.67573,-13.37293 v -64.02256 h 15.47557 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<path d="m 289.25134,280.08446 h -54.40052 v -99.36009 h 52.23835 v 13.99669 h -36.15411 v 28.13085 h 33.31621 v 13.9271 h -33.31621 v 29.37835 h 38.31628 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<path d="M 366.56466,194.72106 H 338.7222 v 85.3634 h -16.08423 v -85.3634 h -27.77455 v -13.99669 h 71.70124 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,15 +1,15 @@
Any raw assets you want to be deployed with your application can be placed in
this directory (and child directories). Deployment of the asset to your application
is automatically handled by the following `MauiAsset` Build Action within your `.csproj`.
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
These files will be deployed with your package and will be accessible using Essentials:
async Task LoadMauiAsset()
{
using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
using var reader = new StreamReader(stream);
var contents = reader.ReadToEnd();
}
Any raw assets you want to be deployed with your application can be placed in
this directory (and child directories). Deployment of the asset to your application
is automatically handled by the following `MauiAsset` Build Action within your `.csproj`.
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
These files will be deployed with your package and will be accessible using Essentials:
async Task LoadMauiAsset()
{
using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
using var reader = new StreamReader(stream);
var contents = reader.ReadToEnd();
}

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<path d="m 105.50037,281.60863 c -2.70293,0 -5.00091,-0.90042 -6.893127,-2.70209 -1.892214,-1.84778 -2.837901,-4.04181 -2.837901,-6.58209 0,-2.58722 0.945687,-4.80389 2.837901,-6.65167 1.892217,-1.84778 4.190197,-2.77167 6.893127,-2.77167 2.74819,0 5.06798,0.92389 6.96019,2.77167 1.93749,1.84778 2.90581,4.06445 2.90581,6.65167 0,2.54028 -0.96832,4.73431 -2.90581,6.58209 -1.89221,1.80167 -4.212,2.70209 -6.96019,2.70209 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<path d="M 213.56111,280.08446 H 195.99044 L 149.69953,207.0544 c -1.17121,-1.84778 -2.14037,-3.76515 -2.90581,-5.75126 h -0.40578 c 0.36051,2.12528 0.54076,6.67515 0.54076,13.6496 v 65.13172 h -15.54349 v -99.36009 h 18.71925 l 44.7374,71.29798 c 1.89222,2.95695 3.1087,4.98917 3.64945,6.09751 h 0.26996 c -0.45021,-2.6325 -0.67573,-7.09015 -0.67573,-13.37293 v -64.02256 h 15.47557 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<path d="m 289.25134,280.08446 h -54.40052 v -99.36009 h 52.23835 v 13.99669 h -36.15411 v 28.13085 h 33.31621 v 13.9271 h -33.31621 v 29.37835 h 38.31628 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<path d="M 366.56466,194.72106 H 338.7222 v 85.3634 h -16.08423 v -85.3634 h -27.77455 v -13.99669 h 71.70124 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<path d="m 105.50037,281.60863 c -2.70293,0 -5.00091,-0.90042 -6.893127,-2.70209 -1.892214,-1.84778 -2.837901,-4.04181 -2.837901,-6.58209 0,-2.58722 0.945687,-4.80389 2.837901,-6.65167 1.892217,-1.84778 4.190197,-2.77167 6.893127,-2.77167 2.74819,0 5.06798,0.92389 6.96019,2.77167 1.93749,1.84778 2.90581,4.06445 2.90581,6.65167 0,2.54028 -0.96832,4.73431 -2.90581,6.58209 -1.89221,1.80167 -4.212,2.70209 -6.96019,2.70209 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<path d="M 213.56111,280.08446 H 195.99044 L 149.69953,207.0544 c -1.17121,-1.84778 -2.14037,-3.76515 -2.90581,-5.75126 h -0.40578 c 0.36051,2.12528 0.54076,6.67515 0.54076,13.6496 v 65.13172 h -15.54349 v -99.36009 h 18.71925 l 44.7374,71.29798 c 1.89222,2.95695 3.1087,4.98917 3.64945,6.09751 h 0.26996 c -0.45021,-2.6325 -0.67573,-7.09015 -0.67573,-13.37293 v -64.02256 h 15.47557 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<path d="m 289.25134,280.08446 h -54.40052 v -99.36009 h 52.23835 v 13.99669 h -36.15411 v 28.13085 h 33.31621 v 13.9271 h -33.31621 v 29.37835 h 38.31628 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
<path d="M 366.56466,194.72106 H 338.7222 v 85.3634 h -16.08423 v -85.3634 h -27.77455 v -13.99669 h 71.70124 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,44 +1,44 @@
<?xml version="1.0" encoding="UTF-8" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<!-- Note: For Android please see also Platforms\Android\Resources\values\colors.xml -->
<Color x:Key="Primary">#512BD4</Color>
<Color x:Key="PrimaryDark">#ac99ea</Color>
<Color x:Key="PrimaryDarkText">#242424</Color>
<Color x:Key="Secondary">#DFD8F7</Color>
<Color x:Key="SecondaryDarkText">#9880e5</Color>
<Color x:Key="Tertiary">#2B0B98</Color>
<Color x:Key="White">White</Color>
<Color x:Key="Black">Black</Color>
<Color x:Key="Magenta">#D600AA</Color>
<Color x:Key="MidnightBlue">#190649</Color>
<Color x:Key="OffBlack">#1f1f1f</Color>
<Color x:Key="Gray100">#E1E1E1</Color>
<Color x:Key="Gray200">#C8C8C8</Color>
<Color x:Key="Gray300">#ACACAC</Color>
<Color x:Key="Gray400">#919191</Color>
<Color x:Key="Gray500">#6E6E6E</Color>
<Color x:Key="Gray600">#404040</Color>
<Color x:Key="Gray900">#212121</Color>
<Color x:Key="Gray950">#141414</Color>
<SolidColorBrush x:Key="PrimaryBrush" Color="{StaticResource Primary}"/>
<SolidColorBrush x:Key="SecondaryBrush" Color="{StaticResource Secondary}"/>
<SolidColorBrush x:Key="TertiaryBrush" Color="{StaticResource Tertiary}"/>
<SolidColorBrush x:Key="WhiteBrush" Color="{StaticResource White}"/>
<SolidColorBrush x:Key="BlackBrush" Color="{StaticResource Black}"/>
<SolidColorBrush x:Key="Gray100Brush" Color="{StaticResource Gray100}"/>
<SolidColorBrush x:Key="Gray200Brush" Color="{StaticResource Gray200}"/>
<SolidColorBrush x:Key="Gray300Brush" Color="{StaticResource Gray300}"/>
<SolidColorBrush x:Key="Gray400Brush" Color="{StaticResource Gray400}"/>
<SolidColorBrush x:Key="Gray500Brush" Color="{StaticResource Gray500}"/>
<SolidColorBrush x:Key="Gray600Brush" Color="{StaticResource Gray600}"/>
<SolidColorBrush x:Key="Gray900Brush" Color="{StaticResource Gray900}"/>
<SolidColorBrush x:Key="Gray950Brush" Color="{StaticResource Gray950}"/>
<?xml version="1.0" encoding="UTF-8" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<!-- Note: For Android please see also Platforms\Android\Resources\values\colors.xml -->
<Color x:Key="Primary">#512BD4</Color>
<Color x:Key="PrimaryDark">#ac99ea</Color>
<Color x:Key="PrimaryDarkText">#242424</Color>
<Color x:Key="Secondary">#DFD8F7</Color>
<Color x:Key="SecondaryDarkText">#9880e5</Color>
<Color x:Key="Tertiary">#2B0B98</Color>
<Color x:Key="White">White</Color>
<Color x:Key="Black">Black</Color>
<Color x:Key="Magenta">#D600AA</Color>
<Color x:Key="MidnightBlue">#190649</Color>
<Color x:Key="OffBlack">#1f1f1f</Color>
<Color x:Key="Gray100">#E1E1E1</Color>
<Color x:Key="Gray200">#C8C8C8</Color>
<Color x:Key="Gray300">#ACACAC</Color>
<Color x:Key="Gray400">#919191</Color>
<Color x:Key="Gray500">#6E6E6E</Color>
<Color x:Key="Gray600">#404040</Color>
<Color x:Key="Gray900">#212121</Color>
<Color x:Key="Gray950">#141414</Color>
<SolidColorBrush x:Key="PrimaryBrush" Color="{StaticResource Primary}"/>
<SolidColorBrush x:Key="SecondaryBrush" Color="{StaticResource Secondary}"/>
<SolidColorBrush x:Key="TertiaryBrush" Color="{StaticResource Tertiary}"/>
<SolidColorBrush x:Key="WhiteBrush" Color="{StaticResource White}"/>
<SolidColorBrush x:Key="BlackBrush" Color="{StaticResource Black}"/>
<SolidColorBrush x:Key="Gray100Brush" Color="{StaticResource Gray100}"/>
<SolidColorBrush x:Key="Gray200Brush" Color="{StaticResource Gray200}"/>
<SolidColorBrush x:Key="Gray300Brush" Color="{StaticResource Gray300}"/>
<SolidColorBrush x:Key="Gray400Brush" Color="{StaticResource Gray400}"/>
<SolidColorBrush x:Key="Gray500Brush" Color="{StaticResource Gray500}"/>
<SolidColorBrush x:Key="Gray600Brush" Color="{StaticResource Gray600}"/>
<SolidColorBrush x:Key="Gray900Brush" Color="{StaticResource Gray900}"/>
<SolidColorBrush x:Key="Gray950Brush" Color="{StaticResource Gray950}"/>
</ResourceDictionary>

View File

@@ -1,434 +1,434 @@
<?xml version="1.0" encoding="UTF-8" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<Style TargetType="ActivityIndicator">
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
</Style>
<Style TargetType="IndicatorView">
<Setter Property="IndicatorColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}"/>
<Setter Property="SelectedIndicatorColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray100}}"/>
</Style>
<Style TargetType="Border">
<Setter Property="Stroke" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
<Setter Property="StrokeShape" Value="Rectangle"/>
<Setter Property="StrokeThickness" Value="1"/>
</Style>
<Style TargetType="BoxView">
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
</Style>
<Style TargetType="Button">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource PrimaryDarkText}}" />
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource PrimaryDark}}" />
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="BorderWidth" Value="0"/>
<Setter Property="CornerRadius" Value="8"/>
<Setter Property="Padding" Value="14,10"/>
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver" />
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="CheckBox">
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="DatePicker">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="Editor">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14" />
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="Entry">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14" />
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="ImageButton">
<Setter Property="Opacity" Value="1" />
<Setter Property="BorderColor" Value="Transparent"/>
<Setter Property="BorderWidth" Value="0"/>
<Setter Property="CornerRadius" Value="0"/>
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="Opacity" Value="0.5" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver" />
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="Label">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
<Setter Property="FontSize" Value="14" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="Label" x:Key="Headline">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource MidnightBlue}, Dark={StaticResource White}}" />
<Setter Property="FontSize" Value="32" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
<Style TargetType="Label" x:Key="SubHeadline">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource MidnightBlue}, Dark={StaticResource White}}" />
<Setter Property="FontSize" Value="24" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
<Style TargetType="Picker">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
<Setter Property="TitleColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14" />
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
<Setter Property="TitleColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="ProgressBar">
<Setter Property="ProgressColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="ProgressColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="RadioButton">
<Setter Property="BackgroundColor" Value="Transparent"/>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="RefreshView">
<Setter Property="RefreshColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
</Style>
<Style TargetType="SearchBar">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
<Setter Property="PlaceholderColor" Value="{StaticResource Gray500}" />
<Setter Property="CancelButtonColor" Value="{StaticResource Gray500}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
<Setter Property="FontSize" Value="14" />
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="SearchHandler">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
<Setter Property="PlaceholderColor" Value="{StaticResource Gray500}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
<Setter Property="FontSize" Value="14" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="Shadow">
<Setter Property="Radius" Value="15" />
<Setter Property="Opacity" Value="0.5" />
<Setter Property="Brush" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource White}}" />
<Setter Property="Offset" Value="10,10" />
</Style>
<Style TargetType="Slider">
<Setter Property="MinimumTrackColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
<Setter Property="MaximumTrackColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}" />
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="MinimumTrackColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"/>
<Setter Property="MaximumTrackColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"/>
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="SwipeItem">
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
</Style>
<Style TargetType="Switch">
<Setter Property="OnColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
<Setter Property="ThumbColor" Value="{StaticResource White}" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="OnColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="On">
<VisualState.Setters>
<Setter Property="OnColor" Value="{AppThemeBinding Light={StaticResource Secondary}, Dark={StaticResource Gray200}}" />
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Off">
<VisualState.Setters>
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="TimePicker">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
<Setter Property="BackgroundColor" Value="Transparent"/>
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<!--
<Style TargetType="TitleBar">
<Setter Property="MinimumHeightRequest" Value="32"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="TitleActiveStates">
<VisualState x:Name="TitleBarTitleActive">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="ForegroundColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="TitleBarTitleInactive">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
<Setter Property="ForegroundColor" Value="{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
-->
<Style TargetType="Page" ApplyToDerivedTypes="True">
<Setter Property="Padding" Value="0"/>
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
</Style>
<Style TargetType="Shell" ApplyToDerivedTypes="True">
<Setter Property="Shell.BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
<Setter Property="Shell.ForegroundColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource SecondaryDarkText}}" />
<Setter Property="Shell.TitleColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource SecondaryDarkText}}" />
<Setter Property="Shell.DisabledColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}" />
<Setter Property="Shell.UnselectedColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray200}}" />
<Setter Property="Shell.NavBarHasShadow" Value="False" />
<Setter Property="Shell.TabBarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
<Setter Property="Shell.TabBarForegroundColor" Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
<Setter Property="Shell.TabBarTitleColor" Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
<Setter Property="Shell.TabBarUnselectedColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
</Style>
<Style TargetType="NavigationPage">
<Setter Property="BarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
<Setter Property="BarTextColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource White}}" />
<Setter Property="IconColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource White}}" />
</Style>
<Style TargetType="TabbedPage">
<Setter Property="BarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Gray950}}" />
<Setter Property="BarTextColor" Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
<Setter Property="UnselectedTabColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}" />
<Setter Property="SelectedTabColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
</Style>
</ResourceDictionary>
<?xml version="1.0" encoding="UTF-8" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<Style TargetType="ActivityIndicator">
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
</Style>
<Style TargetType="IndicatorView">
<Setter Property="IndicatorColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}"/>
<Setter Property="SelectedIndicatorColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray100}}"/>
</Style>
<Style TargetType="Border">
<Setter Property="Stroke" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
<Setter Property="StrokeShape" Value="Rectangle"/>
<Setter Property="StrokeThickness" Value="1"/>
</Style>
<Style TargetType="BoxView">
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
</Style>
<Style TargetType="Button">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource PrimaryDarkText}}" />
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource PrimaryDark}}" />
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="BorderWidth" Value="0"/>
<Setter Property="CornerRadius" Value="8"/>
<Setter Property="Padding" Value="14,10"/>
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver" />
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="CheckBox">
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="DatePicker">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="Editor">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14" />
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="Entry">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14" />
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="ImageButton">
<Setter Property="Opacity" Value="1" />
<Setter Property="BorderColor" Value="Transparent"/>
<Setter Property="BorderWidth" Value="0"/>
<Setter Property="CornerRadius" Value="0"/>
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="Opacity" Value="0.5" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver" />
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="Label">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
<Setter Property="FontSize" Value="14" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="Label" x:Key="Headline">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource MidnightBlue}, Dark={StaticResource White}}" />
<Setter Property="FontSize" Value="32" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
<Style TargetType="Label" x:Key="SubHeadline">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource MidnightBlue}, Dark={StaticResource White}}" />
<Setter Property="FontSize" Value="24" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
<Style TargetType="Picker">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
<Setter Property="TitleColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14" />
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
<Setter Property="TitleColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="ProgressBar">
<Setter Property="ProgressColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="ProgressColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="RadioButton">
<Setter Property="BackgroundColor" Value="Transparent"/>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="RefreshView">
<Setter Property="RefreshColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
</Style>
<Style TargetType="SearchBar">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
<Setter Property="PlaceholderColor" Value="{StaticResource Gray500}" />
<Setter Property="CancelButtonColor" Value="{StaticResource Gray500}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
<Setter Property="FontSize" Value="14" />
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="SearchHandler">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
<Setter Property="PlaceholderColor" Value="{StaticResource Gray500}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
<Setter Property="FontSize" Value="14" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="Shadow">
<Setter Property="Radius" Value="15" />
<Setter Property="Opacity" Value="0.5" />
<Setter Property="Brush" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource White}}" />
<Setter Property="Offset" Value="10,10" />
</Style>
<Style TargetType="Slider">
<Setter Property="MinimumTrackColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
<Setter Property="MaximumTrackColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}" />
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="MinimumTrackColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"/>
<Setter Property="MaximumTrackColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"/>
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="SwipeItem">
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
</Style>
<Style TargetType="Switch">
<Setter Property="OnColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
<Setter Property="ThumbColor" Value="{StaticResource White}" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="OnColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="On">
<VisualState.Setters>
<Setter Property="OnColor" Value="{AppThemeBinding Light={StaticResource Secondary}, Dark={StaticResource Gray200}}" />
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Off">
<VisualState.Setters>
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="TimePicker">
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
<Setter Property="BackgroundColor" Value="Transparent"/>
<Setter Property="FontFamily" Value="OpenSansRegular"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="MinimumHeightRequest" Value="44"/>
<Setter Property="MinimumWidthRequest" Value="44"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<!--
<Style TargetType="TitleBar">
<Setter Property="MinimumHeightRequest" Value="32"/>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="TitleActiveStates">
<VisualState x:Name="TitleBarTitleActive">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="ForegroundColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="TitleBarTitleInactive">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
<Setter Property="ForegroundColor" Value="{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
-->
<Style TargetType="Page" ApplyToDerivedTypes="True">
<Setter Property="Padding" Value="0"/>
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
</Style>
<Style TargetType="Shell" ApplyToDerivedTypes="True">
<Setter Property="Shell.BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
<Setter Property="Shell.ForegroundColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource SecondaryDarkText}}" />
<Setter Property="Shell.TitleColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource SecondaryDarkText}}" />
<Setter Property="Shell.DisabledColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}" />
<Setter Property="Shell.UnselectedColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray200}}" />
<Setter Property="Shell.NavBarHasShadow" Value="False" />
<Setter Property="Shell.TabBarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
<Setter Property="Shell.TabBarForegroundColor" Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
<Setter Property="Shell.TabBarTitleColor" Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
<Setter Property="Shell.TabBarUnselectedColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
</Style>
<Style TargetType="NavigationPage">
<Setter Property="BarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
<Setter Property="BarTextColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource White}}" />
<Setter Property="IconColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource White}}" />
</Style>
<Style TargetType="TabbedPage">
<Setter Property="BarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Gray950}}" />
<Setter Property="BarTextColor" Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
<Setter Property="UnselectedTabColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}" />
<Setter Property="SelectedTabColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
</Style>
</ResourceDictionary>

184
RelayCore/.gitignore vendored
View File

@@ -1,93 +1,93 @@
############################################
# .NET Build
############################################
bin/
obj/
out/
publish/
############################################
# Visual Studio
############################################
.vs/
*.user
*.suo
*.userprefs
*.csproj.user
*.dbmdl
*.cache
*.pdb
*.opendb
############################################
# Rider / JetBrains
############################################
.idea/
*.sln.iml
############################################
# VSCode
############################################
.vscode/
############################################
# NuGet
############################################
*.nupkg
*.snupkg
packages/
.nuget/
.nuget/packages/
############################################
# Logs
############################################
*.log
logs/
############################################
# OS files
############################################
.DS_Store
Thumbs.db
############################################
# Local secrets / environment
############################################
.env
.env.*
secrets.json
appsettings.Development.json
############################################
# E2EE private keys
############################################
keys/*
!keys/.gitkeep
############################################
# Local test databases / data folders
############################################
data/
*.db
*.sqlite
*.sqlite3
############################################
# Temporary files
############################################
*.tmp
*.temp
*.bak
############################################
# .NET Build
############################################
bin/
obj/
out/
publish/
############################################
# Visual Studio
############################################
.vs/
*.user
*.suo
*.userprefs
*.csproj.user
*.dbmdl
*.cache
*.pdb
*.opendb
############################################
# Rider / JetBrains
############################################
.idea/
*.sln.iml
############################################
# VSCode
############################################
.vscode/
############################################
# NuGet
############################################
*.nupkg
*.snupkg
packages/
.nuget/
.nuget/packages/
############################################
# Logs
############################################
*.log
logs/
############################################
# OS files
############################################
.DS_Store
Thumbs.db
############################################
# Local secrets / environment
############################################
.env
.env.*
secrets.json
appsettings.Development.json
############################################
# E2EE private keys
############################################
keys/*
!keys/.gitkeep
############################################
# Local test databases / data folders
############################################
data/
*.db
*.sqlite
*.sqlite3
############################################
# Temporary files
############################################
*.tmp
*.temp
*.bak
*.swp

View File

@@ -1,82 +1,82 @@
using System.Security.Cryptography;
using System.Text;
namespace RelayCore;
public static class E2EeHelper
{
public static (string publicKey, string privateKey) GenerateRsaKeyPair()
{
using var rsa = RSA.Create(2048);
var publicKey = Convert.ToBase64String(rsa.ExportSubjectPublicKeyInfo());
var privateKey = Convert.ToBase64String(rsa.ExportPkcs8PrivateKey());
return (publicKey, privateKey);
}
public static EncryptedMessagePayload EncryptForRecipient(string plainText, string recipientPublicKeyBase64)
{
var aesKey = RandomNumberGenerator.GetBytes(32);
var nonce = RandomNumberGenerator.GetBytes(12);
var plainBytes = Encoding.UTF8.GetBytes(plainText);
var cipherBytes = new byte[plainBytes.Length];
var tag = new byte[16];
using (var aes = new AesGcm(aesKey, 16))
{
aes.Encrypt(nonce, plainBytes, cipherBytes, tag);
}
var recipientPublicKey = Convert.FromBase64String(recipientPublicKeyBase64);
byte[] encryptedKey;
using (var rsa = RSA.Create())
{
rsa.ImportSubjectPublicKeyInfo(recipientPublicKey, out _);
encryptedKey = rsa.Encrypt(aesKey, RSAEncryptionPadding.OaepSHA256);
}
return new EncryptedMessagePayload
{
CipherText = Convert.ToBase64String(cipherBytes),
Nonce = Convert.ToBase64String(nonce),
Tag = Convert.ToBase64String(tag),
EncryptedKey = Convert.ToBase64String(encryptedKey)
};
}
public static string DecryptForRecipient(EncryptedMessagePayload payload, string recipientPrivateKeyBase64)
{
var encryptedKey = Convert.FromBase64String(payload.EncryptedKey);
var privateKey = Convert.FromBase64String(recipientPrivateKeyBase64);
byte[] aesKey;
using (var rsa = RSA.Create())
{
rsa.ImportPkcs8PrivateKey(privateKey, out _);
aesKey = rsa.Decrypt(encryptedKey, RSAEncryptionPadding.OaepSHA256);
}
var nonce = Convert.FromBase64String(payload.Nonce);
var tag = Convert.FromBase64String(payload.Tag);
var cipherBytes = Convert.FromBase64String(payload.CipherText);
var plainBytes = new byte[cipherBytes.Length];
using (var aes = new AesGcm(aesKey, 16))
{
aes.Decrypt(nonce, cipherBytes, tag, plainBytes);
}
return Encoding.UTF8.GetString(plainBytes);
}
}
public class EncryptedMessagePayload
{
public required string CipherText { get; set; }
public required string Nonce { get; set; }
public required string Tag { get; set; }
public required string EncryptedKey { get; set; }
using System.Security.Cryptography;
using System.Text;
namespace RelayCore;
public static class E2EeHelper
{
public static (string publicKey, string privateKey) GenerateRsaKeyPair()
{
using var rsa = RSA.Create(2048);
var publicKey = Convert.ToBase64String(rsa.ExportSubjectPublicKeyInfo());
var privateKey = Convert.ToBase64String(rsa.ExportPkcs8PrivateKey());
return (publicKey, privateKey);
}
public static EncryptedMessagePayload EncryptForRecipient(string plainText, string recipientPublicKeyBase64)
{
var aesKey = RandomNumberGenerator.GetBytes(32);
var nonce = RandomNumberGenerator.GetBytes(12);
var plainBytes = Encoding.UTF8.GetBytes(plainText);
var cipherBytes = new byte[plainBytes.Length];
var tag = new byte[16];
using (var aes = new AesGcm(aesKey, 16))
{
aes.Encrypt(nonce, plainBytes, cipherBytes, tag);
}
var recipientPublicKey = Convert.FromBase64String(recipientPublicKeyBase64);
byte[] encryptedKey;
using (var rsa = RSA.Create())
{
rsa.ImportSubjectPublicKeyInfo(recipientPublicKey, out _);
encryptedKey = rsa.Encrypt(aesKey, RSAEncryptionPadding.OaepSHA256);
}
return new EncryptedMessagePayload
{
CipherText = Convert.ToBase64String(cipherBytes),
Nonce = Convert.ToBase64String(nonce),
Tag = Convert.ToBase64String(tag),
EncryptedKey = Convert.ToBase64String(encryptedKey)
};
}
public static string DecryptForRecipient(EncryptedMessagePayload payload, string recipientPrivateKeyBase64)
{
var encryptedKey = Convert.FromBase64String(payload.EncryptedKey);
var privateKey = Convert.FromBase64String(recipientPrivateKeyBase64);
byte[] aesKey;
using (var rsa = RSA.Create())
{
rsa.ImportPkcs8PrivateKey(privateKey, out _);
aesKey = rsa.Decrypt(encryptedKey, RSAEncryptionPadding.OaepSHA256);
}
var nonce = Convert.FromBase64String(payload.Nonce);
var tag = Convert.FromBase64String(payload.Tag);
var cipherBytes = Convert.FromBase64String(payload.CipherText);
var plainBytes = new byte[cipherBytes.Length];
using (var aes = new AesGcm(aesKey, 16))
{
aes.Decrypt(nonce, cipherBytes, tag, plainBytes);
}
return Encoding.UTF8.GetString(plainBytes);
}
}
public class EncryptedMessagePayload
{
public required string CipherText { get; set; }
public required string Nonce { get; set; }
public required string Tag { get; set; }
public required string EncryptedKey { get; set; }
}

View File

@@ -1,109 +1,109 @@
using System;
using System.Security.Cryptography;
using System.Text;
using Konscious.Security.Cryptography;
namespace PasswordHasher
{
/// <summary>
/// Provides secure password hashing functionality using Argon2id algorithm
/// </summary>
public class PasswordHasher
{
/// <summary>
/// Size of the salt in bytes
/// </summary>
private const int SaltSize = 16;
/// <summary>
/// Size of the hash in bytes
/// </summary>
private const int HashSize = 32;
/// <summary>
/// Number of threads to use for parallel computation
/// </summary>
private const int DegreeOfParallelism = 1;
/// <summary>
/// Number of iterations for the Argon2id algorithm
/// </summary>
private const int Iterations = 2;
/// <summary>
/// Memory size in KB to use
/// </summary>
private const int MemorySize = 19456; // 19 MB
/// <summary>
/// Generates a secure hash of a password using Argon2id with a random salt
/// </summary>
/// <param name="password">The plain text password to hash</param>
/// <returns>A Base64 string containing the combined salt and hash</returns>
/// <exception cref="ArgumentNullException">Thrown when password is null</exception>
public string HashPassword(string password)
{
// Generate a random salt
byte[] salt = new byte[SaltSize];
using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
// Create hash
byte[] hash = HashPassword(password, salt);
// Combine salt and hash
var combinedBytes = new byte[salt.Length + hash.Length];
Array.Copy(salt, 0, combinedBytes, 0, salt.Length);
Array.Copy(hash, 0, combinedBytes, salt.Length, hash.Length);
// Convert to base64 for storage
return Convert.ToBase64String(combinedBytes);
}
/// <summary>
/// Generates a password hash using Argon2id with a specific salt
/// </summary>
/// <param name="password">The plain text password</param>
/// <param name="salt">The salt to use for hashing</param>
/// <returns>A byte array containing the password hash</returns>
private byte[] HashPassword(string password, byte[] salt)
{
var argon2 = new Argon2id(Encoding.UTF8.GetBytes(password))
{
Salt = salt,
DegreeOfParallelism = DegreeOfParallelism,
Iterations = Iterations,
MemorySize = MemorySize
};
return argon2.GetBytes(HashSize);
}
/// <summary>
/// Verifies if a password matches a stored hash
/// </summary>
/// <param name="password">The plain text password to verify</param>
/// <param name="hashedPassword">The stored hash in Base64 format</param>
/// <returns>True if the password matches the hash, false otherwise</returns>
/// <exception cref="ArgumentNullException">Thrown when password or hashedPassword are null</exception>
/// <exception cref="FormatException">Thrown when hashedPassword is not in valid Base64 format</exception>
public bool VerifyPassword(string password, string hashedPassword)
{
// Decode the stored hash
byte[] combinedBytes = Convert.FromBase64String(hashedPassword);
// Extract salt and hash
byte[] salt = new byte[SaltSize];
byte[] hash = new byte[HashSize];
Array.Copy(combinedBytes, 0, salt, 0, SaltSize);
Array.Copy(combinedBytes, SaltSize, hash, 0, HashSize);
// Compute hash for the input password
byte[] newHash = HashPassword(password, salt);
// Compare the hashes
return CryptographicOperations.FixedTimeEquals(hash, newHash);
}
}
using System;
using System.Security.Cryptography;
using System.Text;
using Konscious.Security.Cryptography;
namespace PasswordHasher
{
/// <summary>
/// Provides secure password hashing functionality using Argon2id algorithm
/// </summary>
public class PasswordHasher
{
/// <summary>
/// Size of the salt in bytes
/// </summary>
private const int SaltSize = 16;
/// <summary>
/// Size of the hash in bytes
/// </summary>
private const int HashSize = 32;
/// <summary>
/// Number of threads to use for parallel computation
/// </summary>
private const int DegreeOfParallelism = 1;
/// <summary>
/// Number of iterations for the Argon2id algorithm
/// </summary>
private const int Iterations = 2;
/// <summary>
/// Memory size in KB to use
/// </summary>
private const int MemorySize = 19456; // 19 MB
/// <summary>
/// Generates a secure hash of a password using Argon2id with a random salt
/// </summary>
/// <param name="password">The plain text password to hash</param>
/// <returns>A Base64 string containing the combined salt and hash</returns>
/// <exception cref="ArgumentNullException">Thrown when password is null</exception>
public string HashPassword(string password)
{
// Generate a random salt
byte[] salt = new byte[SaltSize];
using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
// Create hash
byte[] hash = HashPassword(password, salt);
// Combine salt and hash
var combinedBytes = new byte[salt.Length + hash.Length];
Array.Copy(salt, 0, combinedBytes, 0, salt.Length);
Array.Copy(hash, 0, combinedBytes, salt.Length, hash.Length);
// Convert to base64 for storage
return Convert.ToBase64String(combinedBytes);
}
/// <summary>
/// Generates a password hash using Argon2id with a specific salt
/// </summary>
/// <param name="password">The plain text password</param>
/// <param name="salt">The salt to use for hashing</param>
/// <returns>A byte array containing the password hash</returns>
private byte[] HashPassword(string password, byte[] salt)
{
var argon2 = new Argon2id(Encoding.UTF8.GetBytes(password))
{
Salt = salt,
DegreeOfParallelism = DegreeOfParallelism,
Iterations = Iterations,
MemorySize = MemorySize
};
return argon2.GetBytes(HashSize);
}
/// <summary>
/// Verifies if a password matches a stored hash
/// </summary>
/// <param name="password">The plain text password to verify</param>
/// <param name="hashedPassword">The stored hash in Base64 format</param>
/// <returns>True if the password matches the hash, false otherwise</returns>
/// <exception cref="ArgumentNullException">Thrown when password or hashedPassword are null</exception>
/// <exception cref="FormatException">Thrown when hashedPassword is not in valid Base64 format</exception>
public bool VerifyPassword(string password, string hashedPassword)
{
// Decode the stored hash
byte[] combinedBytes = Convert.FromBase64String(hashedPassword);
// Extract salt and hash
byte[] salt = new byte[SaltSize];
byte[] hash = new byte[HashSize];
Array.Copy(combinedBytes, 0, salt, 0, SaltSize);
Array.Copy(combinedBytes, SaltSize, hash, 0, HashSize);
// Compute hash for the input password
byte[] newHash = HashPassword(password, salt);
// Compare the hashes
return CryptographicOperations.FixedTimeEquals(hash, newHash);
}
}
}

View File

@@ -1,298 +1,298 @@
using SurrealDb.Net;
using SurrealDb.Net.Models;
using SurrealDb.Net.Models.Auth;
using System.Text.Json;
using PasswordHasher;
using RelayCore;
using var db = new SurrealDbClient("ws://127.0.0.1:8000/rpc");
await db.SignIn(new RootAuth { Username = "root", Password = "secret" });
await db.Use("test", "test");
var keeper = await CreateUserAsync(db, "Keeper317", "Keeper317@gmail.com", "password");
var kira = await CreateUserAsync(db, "Ru_Kira", "jduesling13@gmail.com", "password");
Console.WriteLine($"Keeper created: {ToJsonString(keeper)}");
Console.WriteLine($"Kira created: {ToJsonString(kira)}");
var keeperKeys = E2EeHelper.GenerateRsaKeyPair();
var kiraKeys = E2EeHelper.GenerateRsaKeyPair();
KeyStorage.SavePrivateKey("Keeper317", keeperKeys.privateKey);
KeyStorage.SavePrivateKey("Ru_Kira", kiraKeys.privateKey);
await db.Create("user_keys", new UserKeys
{
UserId = keeper.Id.ToString(),
PublicKey = keeperKeys.publicKey,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
});
await db.Create("user_keys", new UserKeys
{
UserId = kira.Id.ToString(),
PublicKey = kiraKeys.publicKey,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
});
Console.WriteLine("Public keys stored for both users.");
var conversation = await db.Create("conversations", new Conversations
{
CreatedByUserId = keeper.Id.ToString(),
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow,
Title = "Keeper317 + Ru_Kira",
IsDirectMessage = true
});
Console.WriteLine($"Conversation created: {ToJsonString(conversation)}");
await db.Create("conversation_members", new ConversationMembers
{
ConversationId = conversation.Id.ToString(),
UserId = keeper.Id.ToString(),
JoinedAt = DateTime.UtcNow
});
await db.Create("conversation_members", new ConversationMembers
{
ConversationId = conversation.Id.ToString(),
UserId = kira.Id.ToString(),
JoinedAt = DateTime.UtcNow
});
Console.WriteLine("Conversation members added.");
var encrypted = E2EeHelper.EncryptForRecipient("hello from Keeper317", kiraKeys.publicKey);
var savedMessage = await db.Create("messages", new Messages
{
ConversationId = conversation.Id.ToString(),
SenderUserId = keeper.Id.ToString(),
RecipientUserId = kira.Id.ToString(),
CipherText = encrypted.CipherText,
Nonce = encrypted.Nonce,
Tag = encrypted.Tag,
EncryptedKey = encrypted.EncryptedKey,
CreatedAt = DateTime.UtcNow
});
Console.WriteLine($"Encrypted message saved: {ToJsonString(savedMessage)}");
var decrypted = E2EeHelper.DecryptForRecipient(encrypted, kiraKeys.privateKey);
Console.WriteLine($"Decrypted for Ru_Kira: {decrypted}");
return;
static string ToJsonString(object? o)
{
return JsonSerializer.Serialize(o, new JsonSerializerOptions { WriteIndented = true });
}
static async Task<Users> CreateUserAsync(SurrealDbClient db, string username, string email, string rawPassword)
{
var now = DateTime.UtcNow;
var user = new Users
{
Username = username,
Email = email,
CreatedAt = now,
UpdatedAt = now,
LastLogin = now,
TwoFactorEnabled = false,
EmailVerified = false,
AccountStatus = (int)AccountStatuses.Active,
OnlineStatus = (int)OnlineStatuses.Online,
};
var created = await db.Create("users", user);
var hasher = new PasswordHasher.PasswordHasher();
var passwordHash = hasher.HashPassword(created.Id.ToString() + rawPassword);
var updated = await db.Merge<PasswordHash, Users>(new PasswordHash
{
Id = created.Id,
Password = passwordHash
});
return updated;
}
public static class KeyStorage
{
public static void SavePrivateKey(string username, string privateKey)
{
Directory.CreateDirectory("keys");
File.WriteAllText(Path.Combine("keys", $"{username}.private.key"), privateKey);
}
public static string LoadPrivateKey(string username)
{
return File.ReadAllText(Path.Combine("keys", $"{username}.private.key"));
}
public static bool PrivateKeyExists(string username)
{
return File.Exists(Path.Combine("keys", $"{username}.private.key"));
}
}
public class ResponsibilityMerge : Record
{
public bool Marketing { get; set; }
}
public class Group
{
public bool Marketing { get; set; }
public int Count { get; set; }
}
public class Users : Record
{
public required string Username { get; set; }
public string? Password { get; set; }
public required string Email { get; set; }
public required DateTime CreatedAt { get; set; }
public required DateTime UpdatedAt { get; set; }
public required DateTime LastLogin { get; set; }
public bool TwoFactorEnabled { get; set; }
public bool EmailVerified { get; set; }
public required int AccountStatus { get; set; }
public required int OnlineStatus { get; set; }
}
public class PasswordHash : Record
{
public string? Password { get; set; }
}
public class Sessions : Record
{
public required string UserId { get; set; }
public required string TokenHash { get; set; }
public required DateTime IssuedAt { get; set; }
public required DateTime ExpiresAt { get; set; }
public DateTime? LastUsedAt { get; set; }
public bool Revoked { get; set; }
public required string DeviceName { get; set; }
public required string IpAddress { get; set; }
public required string UserAgent { get; set; }
}
public class PasswordReset : Record
{
public required string UserId { get; set; }
public required string TokenHash { get; set; }
public required DateTime CreatedAt { get; set; }
public required DateTime ExpiresAt { get; set; }
public bool Revoked { get; set; }
}
public class Licenses : Record
{
public required string UserId { get; set; }
public required int LicenseType { get; set; }
public required int Status { get; set; }
public required DateTime CreatedAt { get; set; }
public required DateTime StartsAt { get; set; }
public required DateTime UpdatedAt { get; set; }
public required DateTime ExpiresAt { get; set; }
}
public class AuthAudits : Record
{
public required string UserId { get; set; }
public required int EventType { get; set; }
public bool Success { get; set; }
public required string IpAddress { get; set; }
public required string UserAgent { get; set; }
public required string Details { get; set; }
public required DateTime CreatedAt { get; set; }
}
public class UserKeys : Record
{
public required string UserId { get; set; }
public required string PublicKey { get; set; }
public required DateTime CreatedAt { get; set; }
public required DateTime UpdatedAt { get; set; }
}
public class Conversations : Record
{
public required string CreatedByUserId { get; set; }
public required DateTime CreatedAt { get; set; }
public required DateTime UpdatedAt { get; set; }
public string? Title { get; set; }
public bool IsDirectMessage { get; set; }
}
public class ConversationMembers : Record
{
public required string ConversationId { get; set; }
public required string UserId { get; set; }
public required DateTime JoinedAt { get; set; }
}
public class Messages : Record
{
public required string ConversationId { get; set; }
public required string SenderUserId { get; set; }
public required string RecipientUserId { get; set; }
public required string CipherText { get; set; }
public required string Nonce { get; set; }
public required string Tag { get; set; }
public required string EncryptedKey { get; set; }
public required DateTime CreatedAt { get; set; }
}
enum AccountStatuses
{
Active,
Suspended,
Banned,
Deleted
}
enum OnlineStatuses
{
Online,
Busy,
DND,
Invisible,
Offline
}
enum LicenseStatuses
{
Active,
Expired,
Renewable,
Revoked
}
enum LicenseType
{
Free,
Basic,
Advanced,
Pro,
Enterprise
}
enum LogEvents
{
LoginSuccess,
LoginFailure,
LogoutSuccess,
LogoutFailure,
PasswordResetSuccess,
PasswordResetFailure,
using SurrealDb.Net;
using SurrealDb.Net.Models;
using SurrealDb.Net.Models.Auth;
using System.Text.Json;
using PasswordHasher;
using RelayCore;
using var db = new SurrealDbClient("ws://127.0.0.1:8000/rpc");
await db.SignIn(new RootAuth { Username = "root", Password = "secret" });
await db.Use("test", "test");
var keeper = await CreateUserAsync(db, "Keeper317", "Keeper317@gmail.com", "password");
var kira = await CreateUserAsync(db, "Ru_Kira", "jduesling13@gmail.com", "password");
Console.WriteLine($"Keeper created: {ToJsonString(keeper)}");
Console.WriteLine($"Kira created: {ToJsonString(kira)}");
var keeperKeys = E2EeHelper.GenerateRsaKeyPair();
var kiraKeys = E2EeHelper.GenerateRsaKeyPair();
KeyStorage.SavePrivateKey("Keeper317", keeperKeys.privateKey);
KeyStorage.SavePrivateKey("Ru_Kira", kiraKeys.privateKey);
await db.Create("user_keys", new UserKeys
{
UserId = keeper.Id.ToString(),
PublicKey = keeperKeys.publicKey,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
});
await db.Create("user_keys", new UserKeys
{
UserId = kira.Id.ToString(),
PublicKey = kiraKeys.publicKey,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
});
Console.WriteLine("Public keys stored for both users.");
var conversation = await db.Create("conversations", new Conversations
{
CreatedByUserId = keeper.Id.ToString(),
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow,
Title = "Keeper317 + Ru_Kira",
IsDirectMessage = true
});
Console.WriteLine($"Conversation created: {ToJsonString(conversation)}");
await db.Create("conversation_members", new ConversationMembers
{
ConversationId = conversation.Id.ToString(),
UserId = keeper.Id.ToString(),
JoinedAt = DateTime.UtcNow
});
await db.Create("conversation_members", new ConversationMembers
{
ConversationId = conversation.Id.ToString(),
UserId = kira.Id.ToString(),
JoinedAt = DateTime.UtcNow
});
Console.WriteLine("Conversation members added.");
var encrypted = E2EeHelper.EncryptForRecipient("hello from Keeper317", kiraKeys.publicKey);
var savedMessage = await db.Create("messages", new Messages
{
ConversationId = conversation.Id.ToString(),
SenderUserId = keeper.Id.ToString(),
RecipientUserId = kira.Id.ToString(),
CipherText = encrypted.CipherText,
Nonce = encrypted.Nonce,
Tag = encrypted.Tag,
EncryptedKey = encrypted.EncryptedKey,
CreatedAt = DateTime.UtcNow
});
Console.WriteLine($"Encrypted message saved: {ToJsonString(savedMessage)}");
var decrypted = E2EeHelper.DecryptForRecipient(encrypted, kiraKeys.privateKey);
Console.WriteLine($"Decrypted for Ru_Kira: {decrypted}");
return;
static string ToJsonString(object? o)
{
return JsonSerializer.Serialize(o, new JsonSerializerOptions { WriteIndented = true });
}
static async Task<Users> CreateUserAsync(SurrealDbClient db, string username, string email, string rawPassword)
{
var now = DateTime.UtcNow;
var user = new Users
{
Username = username,
Email = email,
CreatedAt = now,
UpdatedAt = now,
LastLogin = now,
TwoFactorEnabled = false,
EmailVerified = false,
AccountStatus = (int)AccountStatuses.Active,
OnlineStatus = (int)OnlineStatuses.Online,
};
var created = await db.Create("users", user);
var hasher = new PasswordHasher.PasswordHasher();
var passwordHash = hasher.HashPassword(created.Id.ToString() + rawPassword);
var updated = await db.Merge<PasswordHash, Users>(new PasswordHash
{
Id = created.Id,
Password = passwordHash
});
return updated;
}
public static class KeyStorage
{
public static void SavePrivateKey(string username, string privateKey)
{
Directory.CreateDirectory("keys");
File.WriteAllText(Path.Combine("keys", $"{username}.private.key"), privateKey);
}
public static string LoadPrivateKey(string username)
{
return File.ReadAllText(Path.Combine("keys", $"{username}.private.key"));
}
public static bool PrivateKeyExists(string username)
{
return File.Exists(Path.Combine("keys", $"{username}.private.key"));
}
}
public class ResponsibilityMerge : Record
{
public bool Marketing { get; set; }
}
public class Group
{
public bool Marketing { get; set; }
public int Count { get; set; }
}
public class Users : Record
{
public required string Username { get; set; }
public string? Password { get; set; }
public required string Email { get; set; }
public required DateTime CreatedAt { get; set; }
public required DateTime UpdatedAt { get; set; }
public required DateTime LastLogin { get; set; }
public bool TwoFactorEnabled { get; set; }
public bool EmailVerified { get; set; }
public required int AccountStatus { get; set; }
public required int OnlineStatus { get; set; }
}
public class PasswordHash : Record
{
public string? Password { get; set; }
}
public class Sessions : Record
{
public required string UserId { get; set; }
public required string TokenHash { get; set; }
public required DateTime IssuedAt { get; set; }
public required DateTime ExpiresAt { get; set; }
public DateTime? LastUsedAt { get; set; }
public bool Revoked { get; set; }
public required string DeviceName { get; set; }
public required string IpAddress { get; set; }
public required string UserAgent { get; set; }
}
public class PasswordReset : Record
{
public required string UserId { get; set; }
public required string TokenHash { get; set; }
public required DateTime CreatedAt { get; set; }
public required DateTime ExpiresAt { get; set; }
public bool Revoked { get; set; }
}
public class Licenses : Record
{
public required string UserId { get; set; }
public required int LicenseType { get; set; }
public required int Status { get; set; }
public required DateTime CreatedAt { get; set; }
public required DateTime StartsAt { get; set; }
public required DateTime UpdatedAt { get; set; }
public required DateTime ExpiresAt { get; set; }
}
public class AuthAudits : Record
{
public required string UserId { get; set; }
public required int EventType { get; set; }
public bool Success { get; set; }
public required string IpAddress { get; set; }
public required string UserAgent { get; set; }
public required string Details { get; set; }
public required DateTime CreatedAt { get; set; }
}
public class UserKeys : Record
{
public required string UserId { get; set; }
public required string PublicKey { get; set; }
public required DateTime CreatedAt { get; set; }
public required DateTime UpdatedAt { get; set; }
}
public class Conversations : Record
{
public required string CreatedByUserId { get; set; }
public required DateTime CreatedAt { get; set; }
public required DateTime UpdatedAt { get; set; }
public string? Title { get; set; }
public bool IsDirectMessage { get; set; }
}
public class ConversationMembers : Record
{
public required string ConversationId { get; set; }
public required string UserId { get; set; }
public required DateTime JoinedAt { get; set; }
}
public class Messages : Record
{
public required string ConversationId { get; set; }
public required string SenderUserId { get; set; }
public required string RecipientUserId { get; set; }
public required string CipherText { get; set; }
public required string Nonce { get; set; }
public required string Tag { get; set; }
public required string EncryptedKey { get; set; }
public required DateTime CreatedAt { get; set; }
}
enum AccountStatuses
{
Active,
Suspended,
Banned,
Deleted
}
enum OnlineStatuses
{
Online,
Busy,
DND,
Invisible,
Offline
}
enum LicenseStatuses
{
Active,
Expired,
Renewable,
Revoked
}
enum LicenseType
{
Free,
Basic,
Advanced,
Pro,
Enterprise
}
enum LogEvents
{
LoginSuccess,
LoginFailure,
LogoutSuccess,
LogoutFailure,
PasswordResetSuccess,
PasswordResetFailure,
}

View File

@@ -1,16 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Konscious.Security.Cryptography.Argon2" Version="1.3.1" />
<PackageReference Include="SurrealDb.Net" Version="0.9.0" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Konscious.Security.Cryptography.Argon2" Version="1.3.1" />
<PackageReference Include="SurrealDb.Net" Version="0.9.0" />
</ItemGroup>
</Project>

184
RelayServer/.gitignore vendored
View File

@@ -1,93 +1,93 @@
############################################
# .NET Build
############################################
bin/
obj/
out/
publish/
############################################
# Visual Studio
############################################
.vs/
*.user
*.suo
*.userprefs
*.csproj.user
*.dbmdl
*.cache
*.pdb
*.opendb
############################################
# Rider / JetBrains
############################################
.idea/
*.sln.iml
############################################
# VSCode
############################################
.vscode/
############################################
# NuGet
############################################
*.nupkg
*.snupkg
packages/
.nuget/
.nuget/packages/
############################################
# Logs
############################################
*.log
logs/
############################################
# OS files
############################################
.DS_Store
Thumbs.db
############################################
# Local secrets / environment
############################################
.env
.env.*
secrets.json
appsettings.Development.json
############################################
# E2EE private keys
############################################
keys/*
!keys/.gitkeep
############################################
# Local test databases / data folders
############################################
data/
*.db
*.sqlite
*.sqlite3
############################################
# Temporary files
############################################
*.tmp
*.temp
*.bak
############################################
# .NET Build
############################################
bin/
obj/
out/
publish/
############################################
# Visual Studio
############################################
.vs/
*.user
*.suo
*.userprefs
*.csproj.user
*.dbmdl
*.cache
*.pdb
*.opendb
############################################
# Rider / JetBrains
############################################
.idea/
*.sln.iml
############################################
# VSCode
############################################
.vscode/
############################################
# NuGet
############################################
*.nupkg
*.snupkg
packages/
.nuget/
.nuget/packages/
############################################
# Logs
############################################
*.log
logs/
############################################
# OS files
############################################
.DS_Store
Thumbs.db
############################################
# Local secrets / environment
############################################
.env
.env.*
secrets.json
appsettings.Development.json
############################################
# E2EE private keys
############################################
keys/*
!keys/.gitkeep
############################################
# Local test databases / data folders
############################################
data/
*.db
*.sqlite
*.sqlite3
############################################
# Temporary files
############################################
*.tmp
*.temp
*.bak
*.swp

View File

@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>