diff options
19 files changed, 576 insertions, 0 deletions
diff --git a/.idea/.idea.MatrixRoomUtils/.idea/avalonia.xml b/.idea/.idea.MatrixRoomUtils/.idea/avalonia.xml new file mode 100644 index 0000000..ae7a314 --- /dev/null +++ b/.idea/.idea.MatrixRoomUtils/.idea/avalonia.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="AvaloniaProject"> + <option name="projectPerEditor"> + <map> + <entry key="MatrixRoomUtils.Desktop/App.axaml" value="MatrixRoomUtils.Desktop/MatrixRoomUtils.Desktop.csproj" /> + <entry key="MatrixRoomUtils.Desktop/LoginWindow.axaml" value="MatrixRoomUtils.Desktop/MatrixRoomUtils.Desktop.csproj" /> + <entry key="MatrixRoomUtils.Desktop/MainWindow.axaml" value="MatrixRoomUtils.Desktop/MatrixRoomUtils.Desktop.csproj" /> + <entry key="MatrixRoomUtils.Desktop/RoomListEntry.axaml" value="MatrixRoomUtils.Desktop/MatrixRoomUtils.Desktop.csproj" /> + </map> + </option> + </component> +</project> \ No newline at end of file diff --git a/MatrixRoomUtils.Desktop/App.axaml b/MatrixRoomUtils.Desktop/App.axaml new file mode 100644 index 0000000..9c99838 --- /dev/null +++ b/MatrixRoomUtils.Desktop/App.axaml @@ -0,0 +1,10 @@ +<Application xmlns="https://github.com/avaloniaui" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + x:Class="MatrixRoomUtils.Desktop.App" + RequestedThemeVariant="Default"> + <!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. --> + + <Application.Styles> + <FluentTheme /> + </Application.Styles> +</Application> \ No newline at end of file diff --git a/MatrixRoomUtils.Desktop/App.axaml.cs b/MatrixRoomUtils.Desktop/App.axaml.cs new file mode 100644 index 0000000..3dfcdee --- /dev/null +++ b/MatrixRoomUtils.Desktop/App.axaml.cs @@ -0,0 +1,43 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; +using MatrixRoomUtils.Core.Services; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace MatrixRoomUtils.Desktop; + +public partial class App : Application { + public IHost host { get; set; } + + public override void Initialize() { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() { + host = Host.CreateDefaultBuilder().ConfigureServices((ctx, services) => { + services.AddScoped<MRUDesktopConfiguration>(); + services.AddScoped<TieredStorageService>(x => + new( + cacheStorageProvider: new FileStorageProvider(x.GetService<MRUDesktopConfiguration>().CacheStoragePath), + dataStorageProvider: new FileStorageProvider(x.GetService<MRUDesktopConfiguration>().CacheStoragePath) + ) + ); + services.AddRoryLibMatrixServices(); + // foreach (var commandClass in new ClassCollector<ICommand>().ResolveFromAllAccessibleAssemblies()) { + // Console.WriteLine($"Adding command {commandClass.Name}"); + // services.AddScoped(typeof(ICommand), commandClass); + // } + services.AddScoped<MRUStorageWrapper>(); + services.AddScoped<MainWindow>(); + services.AddSingleton(this); + }).UseConsoleLifetime().Build(); + + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { + var scopeFac = host.Services.GetService<IServiceScopeFactory>(); + var scope = scopeFac.CreateScope(); + desktop.MainWindow = scope.ServiceProvider.GetRequiredService<MainWindow>(); + } + base.OnFrameworkInitializationCompleted(); + } +} diff --git a/MatrixRoomUtils.Desktop/FileStorageProvider.cs b/MatrixRoomUtils.Desktop/FileStorageProvider.cs new file mode 100644 index 0000000..36025eb --- /dev/null +++ b/MatrixRoomUtils.Desktop/FileStorageProvider.cs @@ -0,0 +1,35 @@ +using System.Text.Json; +using MatrixRoomUtils.Core.Extensions; +using MatrixRoomUtils.Core.Interfaces.Services; +using Microsoft.Extensions.Logging; + +namespace MatrixRoomUtils.Desktop; + +public class FileStorageProvider : IStorageProvider { + private readonly ILogger<FileStorageProvider> _logger; + + public string TargetPath { get; } + + /// <summary> + /// Creates a new instance of <see cref="FileStorageProvider" />. + /// </summary> + /// <param name="targetPath"></param> + public FileStorageProvider(string targetPath) { + new Logger<FileStorageProvider>(new LoggerFactory()).LogInformation("test"); + Console.WriteLine($"Initialised FileStorageProvider with path {targetPath}"); + TargetPath = targetPath; + if(!Directory.Exists(targetPath)) { + Directory.CreateDirectory(targetPath); + } + } + + public async Task SaveObjectAsync<T>(string key, T value) => await File.WriteAllTextAsync(Path.Join(TargetPath, key), ObjectExtensions.ToJson(value)); + + public async Task<T?> LoadObjectAsync<T>(string key) => JsonSerializer.Deserialize<T>(await File.ReadAllTextAsync(Path.Join(TargetPath, key))); + + public async Task<bool> ObjectExistsAsync(string key) => File.Exists(Path.Join(TargetPath, key)); + + public async Task<List<string>> GetAllKeysAsync() => Directory.GetFiles(TargetPath).Select(Path.GetFileName).ToList(); + + public async Task DeleteObjectAsync(string key) => File.Delete(Path.Join(TargetPath, key)); +} \ No newline at end of file diff --git a/MatrixRoomUtils.Desktop/LoginWindow.axaml b/MatrixRoomUtils.Desktop/LoginWindow.axaml new file mode 100644 index 0000000..d61bfd3 --- /dev/null +++ b/MatrixRoomUtils.Desktop/LoginWindow.axaml @@ -0,0 +1,15 @@ +<Window xmlns="https://github.com/avaloniaui" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:desktop="clr-namespace:MatrixRoomUtils.Desktop" + mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + x:Class="MatrixRoomUtils.Desktop.LoginWindow" + Title="LoginWindow" + x:DataType="desktop:LoginWindow"> + <StackPanel> + <TextBox Text="{Binding Username, Mode=TwoWay}" /> + <MaskedTextBox Text="{Binding Password, Mode=TwoWay}" /> + <Button Click="Login">Login</Button> + </StackPanel> +</Window> diff --git a/MatrixRoomUtils.Desktop/LoginWindow.axaml.cs b/MatrixRoomUtils.Desktop/LoginWindow.axaml.cs new file mode 100644 index 0000000..1f31b05 --- /dev/null +++ b/MatrixRoomUtils.Desktop/LoginWindow.axaml.cs @@ -0,0 +1,36 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Interactivity; +using Avalonia.Markup.Xaml; + +namespace MatrixRoomUtils.Desktop; + +public partial class LoginWindow : Window { + private readonly MRUStorageWrapper _storage; + + public LoginWindow(MRUStorageWrapper storage) { + _storage = storage; + InitializeComponent(); +#if DEBUG + this.AttachDevTools(); +#endif + } + + private void InitializeComponent() { + AvaloniaXamlLoader.Load(this); + } + + public string Username { get; set; } + public string Password { get; set; } + // ReSharper disable once AsyncVoidMethod + private async void Login(object? sender, RoutedEventArgs e) { + var res = await _storage.Login(Username.Split(':')[1], Username.Split(':')[0][1..], Password); + if (res is not null) { + await _storage.AddToken(res); + Close(); + } + else { + Password = ""; + } + } +} diff --git a/MatrixRoomUtils.Desktop/MRUDesktopConfiguration.cs b/MatrixRoomUtils.Desktop/MRUDesktopConfiguration.cs new file mode 100644 index 0000000..d321591 --- /dev/null +++ b/MatrixRoomUtils.Desktop/MRUDesktopConfiguration.cs @@ -0,0 +1,44 @@ +using System.Collections; +using ArcaneLibs.Extensions; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace MatrixRoomUtils.Desktop; + +public class MRUDesktopConfiguration { + private static ILogger<MRUDesktopConfiguration> _logger; + + public MRUDesktopConfiguration(ILogger<MRUDesktopConfiguration> logger, IConfiguration config, HostBuilderContext host) { + _logger = logger; + logger.LogInformation($"Loading configuration for environment: {host.HostingEnvironment.EnvironmentName}..."); + config.GetSection("MRUDesktop").Bind(this); + DataStoragePath = ExpandPath(DataStoragePath); + CacheStoragePath = ExpandPath(CacheStoragePath); + } + + public string DataStoragePath { get; set; } = ""; + public string CacheStoragePath { get; set; } = ""; + + private static string ExpandPath(string path, bool retry = true) { + _logger.LogInformation($"Expanding path `{path}`"); + + if (path.StartsWith("~")) { + path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), path[1..]); + } + + Environment.GetEnvironmentVariables().Cast<DictionaryEntry>().OrderByDescending(x => x.Key.ToString().Length).ToList().ForEach(x => { + path = path.Replace($"${x.Key}", x.Value.ToString()); + }); + + _logger.LogInformation($"Expanded path to `{path}`"); + int tries = 0; + while(retry && path.ContainsAnyOf("~$".Split())) { + if(tries++ > 100) + throw new Exception($"Path `{path}` contains unrecognised environment variables"); + path = ExpandPath(path, false); + } + + return path; + } +} diff --git a/MatrixRoomUtils.Desktop/MRUStorageWrapper.cs b/MatrixRoomUtils.Desktop/MRUStorageWrapper.cs new file mode 100644 index 0000000..27403dc --- /dev/null +++ b/MatrixRoomUtils.Desktop/MRUStorageWrapper.cs @@ -0,0 +1,132 @@ +using MatrixRoomUtils.Core; +using MatrixRoomUtils.Core.Responses; +using MatrixRoomUtils.Core.Services; + +namespace MatrixRoomUtils.Desktop; + +public class MRUStorageWrapper { + private readonly TieredStorageService _storageService; + private readonly HomeserverProviderService _homeserverProviderService; + + public MRUStorageWrapper( + TieredStorageService storageService, + HomeserverProviderService homeserverProviderService + ) { + _storageService = storageService; + _homeserverProviderService = homeserverProviderService; + } + + public async Task<List<LoginResponse>?> GetAllTokens() { + if(!await _storageService.DataStorageProvider.ObjectExistsAsync("mru.tokens")) { + return null; + } + return await _storageService.DataStorageProvider.LoadObjectAsync<List<LoginResponse>>("mru.tokens") ?? + new List<LoginResponse>(); + } + + public async Task<LoginResponse?> GetCurrentToken() { + if(!await _storageService.DataStorageProvider.ObjectExistsAsync("token")) { + return null; + } + var currentToken = await _storageService.DataStorageProvider.LoadObjectAsync<LoginResponse>("token"); + var allTokens = await GetAllTokens(); + if (allTokens is null or { Count: 0 }) { + await SetCurrentToken(null); + return null; + } + + if (currentToken is null) { + await SetCurrentToken(currentToken = allTokens[0]); + } + + if (!allTokens.Any(x => x.AccessToken == currentToken.AccessToken)) { + await SetCurrentToken(currentToken = allTokens[0]); + } + + return currentToken; + } + + public async Task AddToken(LoginResponse loginResponse) { + var tokens = await GetAllTokens(); + if (tokens == null) { + tokens = new List<LoginResponse>(); + } + + tokens.Add(loginResponse); + await _storageService.DataStorageProvider.SaveObjectAsync("mru.tokens", tokens); + } + + private async Task<AuthenticatedHomeServer?> GetCurrentSession() { + var token = await GetCurrentToken(); + if (token == null) { + return null; + } + + return await _homeserverProviderService.GetAuthenticatedWithToken(token.Homeserver, token.AccessToken); + } + + public async Task<AuthenticatedHomeServer?> GetCurrentSessionOrPrompt() { + AuthenticatedHomeServer? session = null; + + try { + //catch if the token is invalid + session = await GetCurrentSession(); + } + catch (MatrixException e) { + if (e.ErrorCode == "M_UNKNOWN_TOKEN") { + var token = await GetCurrentToken(); + // _navigationManager.NavigateTo("/InvalidSession?ctx=" + token.AccessToken); + return null; + } + + throw; + } + + if (session is null) { + // _navigationManager.NavigateTo("/Login"); + var wnd = new LoginWindow(this); + wnd.Show(); + while (wnd.IsVisible) await Task.Delay(100); + session = await GetCurrentSession(); + } + + return session; + } + + public class Settings { + public DeveloperSettings DeveloperSettings { get; set; } = new(); + } + + public class DeveloperSettings { + public bool EnableLogViewers { get; set; } = false; + public bool EnableConsoleLogging { get; set; } = true; + public bool EnablePortableDevtools { get; set; } = false; + } + + public async Task RemoveToken(LoginResponse auth) { + var tokens = await GetAllTokens(); + if (tokens == null) { + return; + } + + tokens.RemoveAll(x => x.AccessToken == auth.AccessToken); + await _storageService.DataStorageProvider.SaveObjectAsync("mru.tokens", tokens); + } + + public async Task SetCurrentToken(LoginResponse? auth) { + _storageService.DataStorageProvider.SaveObjectAsync("token", auth); + } + + public async Task<LoginResponse?> Login(string homeserver, string username, string password) { + try { + return await _homeserverProviderService.Login(homeserver, username, password); + } + catch (MatrixException e) { + if (e.ErrorCode == "M_FORBIDDEN") { + return null; + } + + throw; + } + } +} diff --git a/MatrixRoomUtils.Desktop/MainWindow.axaml b/MatrixRoomUtils.Desktop/MainWindow.axaml new file mode 100644 index 0000000..bc01bee --- /dev/null +++ b/MatrixRoomUtils.Desktop/MainWindow.axaml @@ -0,0 +1,17 @@ +<Window xmlns="https://github.com/avaloniaui" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + x:Class="MatrixRoomUtils.Desktop.MainWindow" + Title="Rory&::MatrixRoomUtils"> + <!-- <Interaction.Behaviors> --> + <!-- <EventTriggerBehavior EventName="Loaded"> --> + <!-- <InvokeCommandAction Command="{Binding LoadedCommand}"></InvokeCommandAction> --> + <!-- </EventTriggerBehavior> --> + <!-- </Interaction.Behaviors> --> + <StackPanel> + <Label FontSize="24">Rooms</Label> + <StackPanel x:Name="roomList" Orientation="Vertical"/> + </StackPanel> +</Window> diff --git a/MatrixRoomUtils.Desktop/MainWindow.axaml.cs b/MatrixRoomUtils.Desktop/MainWindow.axaml.cs new file mode 100644 index 0000000..41e0888 --- /dev/null +++ b/MatrixRoomUtils.Desktop/MainWindow.axaml.cs @@ -0,0 +1,41 @@ +using Avalonia.Controls; +using Avalonia.Interactivity; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace MatrixRoomUtils.Desktop; + +public partial class MainWindow : Window { + private readonly ILogger<MainWindow> _logger; + private readonly MRUStorageWrapper _storageWrapper; + private readonly MRUDesktopConfiguration _configuration; + + public MainWindow(ILogger<MainWindow> logger, IServiceScopeFactory scopeFactory) { + _logger = logger; + _configuration = scopeFactory.CreateScope().ServiceProvider.GetRequiredService<MRUDesktopConfiguration>(); + _storageWrapper = scopeFactory.CreateScope().ServiceProvider.GetRequiredService<MRUStorageWrapper>(); + _logger.LogInformation("Initialising MainWindow"); + + InitializeComponent(); + + _logger.LogInformation("Cache location: " + _configuration.CacheStoragePath); + _logger.LogInformation("Data location: " + _configuration.DataStoragePath); + + + for (int i = 0; i < 100; i++) { + roomList.Children.Add(new RoomListEntry()); + } + } + + // ReSharper disable once AsyncVoidMethod + protected override async void OnLoaded(RoutedEventArgs e) { + _logger.LogInformation("async onloaded override"); + var hs = await _storageWrapper.GetCurrentSessionOrPrompt(); + base.OnLoaded(e); + } + + // public Command + // protected void LoadedCommand() { + // _logger.LogInformation("async command"); + // } +} diff --git a/MatrixRoomUtils.Desktop/MatrixRoomUtils.Desktop.csproj b/MatrixRoomUtils.Desktop/MatrixRoomUtils.Desktop.csproj new file mode 100644 index 0000000..5b6d3f6 --- /dev/null +++ b/MatrixRoomUtils.Desktop/MatrixRoomUtils.Desktop.csproj @@ -0,0 +1,49 @@ +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> + <OutputType>WinExe</OutputType> + <TargetFramework>net7.0</TargetFramework> + <Nullable>enable</Nullable> + <BuiltInComInteropSupport>true</BuiltInComInteropSupport> + <ApplicationManifest>app.manifest</ApplicationManifest> + <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault> + + <LangVersion>preview</LangVersion> + <ImplicitUsings>enable</ImplicitUsings> + <InvariantGlobalization>true</InvariantGlobalization> + <PublishTrimmed>true</PublishTrimmed> + <PublishReadyToRun>true</PublishReadyToRun> + <PublishSingleFile>true</PublishSingleFile> + <PublishReadyToRunShowWarnings>true</PublishReadyToRunShowWarnings> + <PublishTrimmedShowLinkerSizeComparison>true</PublishTrimmedShowLinkerSizeComparison> + <PublishTrimmedShowLinkerSizeComparisonWarnings>true</PublishTrimmedShowLinkerSizeComparisonWarnings> + </PropertyGroup> + + + <ItemGroup> + <PackageReference Include="Avalonia" Version="11.0.0" /> + <PackageReference Include="Avalonia.Desktop" Version="11.0.0" /> + <PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0" /> + <PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.0" /> + <!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.--> + <PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0" /> + </ItemGroup> + + + <ItemGroup> + <ProjectReference Include="..\MatrixRoomUtils.Core\MatrixRoomUtils.Core.csproj" /> + </ItemGroup> + + <ItemGroup> + <PackageReference Include="ArcaneLibs" Version="1.0.0-preview3020494760.012ed3f" /> + <PackageReference Include="Avalonia.Xaml.Behaviors" Version="11.0.0.1" /> + <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" /> + </ItemGroup> + <ItemGroup> + <Content Include="appsettings*.json"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> + <Content Update="appsettings.Local.json"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> + </ItemGroup> +</Project> diff --git a/MatrixRoomUtils.Desktop/Program.cs b/MatrixRoomUtils.Desktop/Program.cs new file mode 100644 index 0000000..74ab579 --- /dev/null +++ b/MatrixRoomUtils.Desktop/Program.cs @@ -0,0 +1,31 @@ +using Avalonia; +using Microsoft.Extensions.Hosting; +using Tmds.DBus.Protocol; + +namespace MatrixRoomUtils.Desktop; + +internal class Program { + private static IHost appHost; + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + [STAThread] + public static async Task Main(string[] args) { + try { + BuildAvaloniaApp() + .StartWithClassicDesktopLifetime(args); + } + catch (DBusException e) { } + catch (Exception e) { + Console.WriteLine(e); + throw; + } + } + + // Avalonia configuration, don't remove; also used by visual designer. + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure<App>() + .UsePlatformDetect() + .WithInterFont() + .LogToTrace(); +} diff --git a/MatrixRoomUtils.Desktop/Properties/launchSettings.json b/MatrixRoomUtils.Desktop/Properties/launchSettings.json new file mode 100644 index 0000000..997e294 --- /dev/null +++ b/MatrixRoomUtils.Desktop/Properties/launchSettings.json @@ -0,0 +1,26 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "Default": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + + } + }, + "Development": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + } + }, + "Local config": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Local" + } + } + } +} diff --git a/MatrixRoomUtils.Desktop/RoomListEntry.axaml b/MatrixRoomUtils.Desktop/RoomListEntry.axaml new file mode 100644 index 0000000..c80ef2f --- /dev/null +++ b/MatrixRoomUtils.Desktop/RoomListEntry.axaml @@ -0,0 +1,11 @@ +<UserControl xmlns="https://github.com/avaloniaui" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + mc:Ignorable="d" d:DesignWidth="250" d:DesignHeight="32" + x:Class="MatrixRoomUtils.Desktop.RoomListEntry"> + <StackPanel Orientation="Horizontal"> + <Image MaxWidth="64" x:Name="RoomIcon"></Image> + <Label x:Name="RoomName"></Label> + </StackPanel> +</UserControl> diff --git a/MatrixRoomUtils.Desktop/RoomListEntry.axaml.cs b/MatrixRoomUtils.Desktop/RoomListEntry.axaml.cs new file mode 100644 index 0000000..490316d --- /dev/null +++ b/MatrixRoomUtils.Desktop/RoomListEntry.axaml.cs @@ -0,0 +1,17 @@ +using Avalonia.Controls; +using Avalonia.Interactivity; +using Avalonia.Media.Imaging; + +namespace MatrixRoomUtils.Desktop; + +public partial class RoomListEntry : UserControl { + public RoomListEntry() { + InitializeComponent(); + } + + protected override void OnLoaded(RoutedEventArgs e) { + base.OnLoaded(e); + RoomName.Content = "asdf"; + RoomIcon.Source = new Bitmap("/home/root@Rory/giphy.gif"); + } +} diff --git a/MatrixRoomUtils.Desktop/app.manifest b/MatrixRoomUtils.Desktop/app.manifest new file mode 100644 index 0000000..35ffb0d --- /dev/null +++ b/MatrixRoomUtils.Desktop/app.manifest @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> + <!-- This manifest is used on Windows only. + Don't remove it as it might cause problems with window transparency and embeded controls. + For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests --> + <assemblyIdentity version="1.0.0.0" name="MatrixRoomUtils.Desktop.Desktop"/> + + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <!-- A list of the Windows versions that this application has been tested on + and is designed to work with. Uncomment the appropriate elements + and Windows will automatically select the most compatible environment. --> + + <!-- Windows 10 --> + <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /> + </application> + </compatibility> +</assembly> diff --git a/MatrixRoomUtils.Desktop/appsettings.Development.json b/MatrixRoomUtils.Desktop/appsettings.Development.json new file mode 100644 index 0000000..20b09a7 --- /dev/null +++ b/MatrixRoomUtils.Desktop/appsettings.Development.json @@ -0,0 +1,13 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + }, + "MRUDesktop": { + "DataStoragePath": "mru-desktop/data", + "CacheStoragePath": "mru-desktop/cache" + } +} diff --git a/MatrixRoomUtils.Desktop/appsettings.json b/MatrixRoomUtils.Desktop/appsettings.json new file mode 100644 index 0000000..4164e87 --- /dev/null +++ b/MatrixRoomUtils.Desktop/appsettings.json @@ -0,0 +1,13 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + }, + "MRUDesktop": { + "DataStoragePath": "~/.local/share/mru-desktop", + "CacheStoragePath": "~/.cache/mru-desktop" + } +} diff --git a/MatrixRoomUtils.sln b/MatrixRoomUtils.sln index a29cf89..ff16a2b 100755 --- a/MatrixRoomUtils.sln +++ b/MatrixRoomUtils.sln @@ -10,6 +10,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixRoomUtils.Web.Server" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixRoomUtils.Bot", "MatrixRoomUtils.Bot\MatrixRoomUtils.Bot.csproj", "{B397700A-4ABB-4CAF-8DB8-06E01F44514B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixRoomUtils.DebugDataValidationApi", "MatrixRoomUtils.DebugDataValidationApi\MatrixRoomUtils.DebugDataValidationApi.csproj", "{FB0CF653-FD25-4701-9477-1E80221346DB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixRoomUtils.Desktop", "MatrixRoomUtils.Desktop\MatrixRoomUtils.Desktop.csproj", "{27C08A4F-5AF0-4C2C-AFCB-050E3388C116}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -36,5 +40,13 @@ Global {B397700A-4ABB-4CAF-8DB8-06E01F44514B}.Debug|Any CPU.Build.0 = Debug|Any CPU {B397700A-4ABB-4CAF-8DB8-06E01F44514B}.Release|Any CPU.ActiveCfg = Release|Any CPU {B397700A-4ABB-4CAF-8DB8-06E01F44514B}.Release|Any CPU.Build.0 = Release|Any CPU + {FB0CF653-FD25-4701-9477-1E80221346DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB0CF653-FD25-4701-9477-1E80221346DB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB0CF653-FD25-4701-9477-1E80221346DB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB0CF653-FD25-4701-9477-1E80221346DB}.Release|Any CPU.Build.0 = Release|Any CPU + {27C08A4F-5AF0-4C2C-AFCB-050E3388C116}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {27C08A4F-5AF0-4C2C-AFCB-050E3388C116}.Debug|Any CPU.Build.0 = Debug|Any CPU + {27C08A4F-5AF0-4C2C-AFCB-050E3388C116}.Release|Any CPU.ActiveCfg = Release|Any CPU + {27C08A4F-5AF0-4C2C-AFCB-050E3388C116}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal |