- tweak: Rework loading status

This commit is contained in:
2025-06-22 10:40:42 +03:00
parent 875dacaa18
commit 37ca8fecf3
15 changed files with 251 additions and 70 deletions

View File

@@ -35,6 +35,7 @@
<entry key="Nebula.Launcher/Views/Popup/LogPopupView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Popup/MessagePopupView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Popup/TfaView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/ServerCompoundEntryView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/ServerContainer.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/ServerEntryView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/ServerList.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />

View File

@@ -49,7 +49,7 @@ public partial class ServerListView : UserControl
{
if (rawView is ServerEntryModelView serverEntryModelView)
{
serverEntryModelView.UpdateStatusIfNecessary();
//serverEntryModelView.UpdateStatusIfNecessary();
}
}
}
@@ -61,9 +61,10 @@ public partial class ServerListView : UserControl
if(IsLoading)
return;
foreach (IFilterConsumer? serverView in ServerList.Items)
foreach (var serverView in ServerList.Items)
{
serverView?.ProcessFilter(filter);
if(serverView is IFilterConsumer filterConsumer)
filterConsumer.ProcessFilter(filter);
}
}
@@ -83,7 +84,8 @@ public partial class ServerListView : UserControl
foreach (var serverEntry in _provider.GetServers())
{
ServerList.Items.Add(serverEntry);
serverEntry.ProcessFilter(_currentFilter);
if(serverEntry is IFilterConsumer serverFilter)
serverFilter.ProcessFilter(_currentFilter);
}
foreach (var error in _provider.GetErrors())

View File

@@ -23,13 +23,13 @@ public sealed partial class FavoriteServerListProvider : IServerListProvider, IS
[GenerateProperty] private IServiceProvider ServiceProvider { get; }
[GenerateProperty] private ServerViewContainer ServerViewContainer { get; }
private List<IFilterConsumer> _serverLists = [];
private List<IListEntryModelView> _serverLists = [];
private string[] rawServerLists = [];
public bool IsLoaded { get; private set; }
public Action? OnLoaded { get; set; }
public Action? Dirty { get; set; }
public IEnumerable<IFilterConsumer> GetServers()
public IEnumerable<IListEntryModelView> GetServers()
{
return _serverLists;
}
@@ -45,12 +45,12 @@ public sealed partial class FavoriteServerListProvider : IServerListProvider, IS
_serverLists.Clear();
var servers = GetFavoriteEntries();
_serverLists.AddRange(
servers.Select(s =>
var serverEntries = servers.Select(s =>
ServerViewContainer.Get(s.ToRobustUrl())
)
);
_serverLists.AddRange(serverEntries);
_serverLists.Add(new AddFavoriteButton(ServiceProvider));
IsLoaded = true;
@@ -67,7 +67,7 @@ public sealed partial class FavoriteServerListProvider : IServerListProvider, IS
var servers = GetFavoriteEntries();
servers.Add(robustUrl.ToString());
ConfigurationService.SetConfigValue(LauncherConVar.Favorites, servers.ToArray());
ServerViewContainer.Get(robustUrl).IsFavorite = true;
if(ServerViewContainer.Get(robustUrl) is IFavoriteEntryModelView favoriteView) favoriteView.IsFavorite = true;
}
public void RemoveFavorite(ServerEntryModelView entryModelView)
@@ -77,6 +77,13 @@ public sealed partial class FavoriteServerListProvider : IServerListProvider, IS
ConfigurationService.SetConfigValue(LauncherConVar.Favorites, servers.ToArray());
}
public void RemoveFavorite(RobustUrl url)
{
var servers = GetFavoriteEntries();
servers.Remove(url.ToString());
ConfigurationService.SetConfigValue(LauncherConVar.Favorites, servers.ToArray());
}
private List<string> GetFavoriteEntries()
{
return rawServerLists.ToList();
@@ -103,7 +110,7 @@ public sealed partial class FavoriteServerListProvider : IServerListProvider, IS
private void InitialiseInDesignMode(){}
}
public class AddFavoriteButton: Border, IFilterConsumer{
public class AddFavoriteButton: Border, IListEntryModelView{
private Button _addFavoriteButton = new Button();
public AddFavoriteButton(IServiceProvider serviceProvider)
@@ -120,8 +127,5 @@ public class AddFavoriteButton: Border, IFilterConsumer{
_addFavoriteButton.Content = "Add Favorite";
Child = _addFavoriteButton;
}
public void ProcessFilter(ServerFilter? serverFilter)
{
}
public bool IsFavorite { get; set; }
}

View File

@@ -24,7 +24,7 @@ public sealed partial class HubServerListProvider : IServerListProvider
public Action? OnLoaded { get; set; }
private CancellationTokenSource? _cts;
private readonly List<ServerEntryModelView> _servers = [];
private readonly List<IListEntryModelView> _servers = [];
private readonly List<Exception> _errors = [];
public HubServerListProvider With(string hubUrl)
@@ -33,7 +33,7 @@ public sealed partial class HubServerListProvider : IServerListProvider
return this;
}
public IEnumerable<IFilterConsumer> GetServers()
public IEnumerable<IListEntryModelView> GetServers()
{
return _servers;
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Nebula.Launcher.ViewModels;
using Nebula.Launcher.ViewModels.Pages;
namespace Nebula.Launcher.ServerListProviders;
@@ -9,7 +10,7 @@ public interface IServerListProvider
public bool IsLoaded { get; }
public Action? OnLoaded { get; set; }
public IEnumerable<IFilterConsumer> GetServers();
public IEnumerable<IListEntryModelView> GetServers();
public IEnumerable<Exception> GetErrors();
public void LoadServerList();

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using Nebula.Launcher.Controls;
using Nebula.Launcher.ViewModels;
using Nebula.Launcher.ViewModels.Pages;
namespace Nebula.Launcher.ServerListProviders;
@@ -9,7 +10,7 @@ public sealed class TestServerList : IServerListProvider
{
public bool IsLoaded => true;
public Action? OnLoaded { get; set; }
public IEnumerable<IFilterConsumer> GetServers()
public IEnumerable<IListEntryModelView> GetServers()
{
return [new ServerEntryModelView(),new ServerEntryModelView()];
}

View File

@@ -125,12 +125,6 @@ public static class ConfigControlHelper{
public static object? CreateDefaultValue(Type type)
{
if (type == typeof(string))
return string.Empty;
if (type == typeof(int))
return 0;
if (type == typeof(float))
return 0f;
if(type.IsValueType)
return Activator.CreateInstance(type);

View File

@@ -29,9 +29,7 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase, IContentHol
[ObservableProperty] private string _serverText = "";
[ObservableProperty] private string _searchText = "";
[GenerateProperty] private ContentService ContentService { get; } = default!;
[GenerateProperty] private CancellationService CancellationService { get; } = default!;
[GenerateProperty] private FileService FileService { get; } = default!;
[GenerateProperty] private DebugService DebugService { get; } = default!;
[GenerateProperty] private PopupMessageService PopupService { get; } = default!;
[GenerateProperty] private IServiceProvider ServiceProvider { get; }
[GenerateProperty, DesignConstruct] private ViewHelperService ViewHelperService { get; } = default!;

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.Extensions.DependencyInjection;
using Nebula.Launcher.Controls;
@@ -89,7 +90,8 @@ public partial class ServerOverviewModel : ViewModelBase
{
foreach (var entry in ServerViewContainer.Items)
{
entry.ProcessFilter(CurrentFilter);
if(entry is IFilterConsumer filterConsumer)
filterConsumer.ProcessFilter(CurrentFilter);
}
}
@@ -109,6 +111,7 @@ public partial class ServerOverviewModel : ViewModelBase
public void UpdateRequired()
{
ServerViewContainer.Clear();
CurrentServerList.RefreshFromProvider();
CurrentServerList.RequireStatusUpdate();
CurrentServerList.ApplyFilter(CurrentFilter);
@@ -150,25 +153,25 @@ public class ServerViewContainer
foreach (var favorite in favorites)
{
if (_entries.TryGetValue(favorite, out var entry))
if (_entries.TryGetValue(favorite, out var entry) && entry is IFavoriteEntryModelView favoriteView)
{
entry.IsFavorite = true;
favoriteView.IsFavorite = true;
}
}
}
private readonly Dictionary<string, ServerEntryModelView> _entries = new();
private readonly Dictionary<string, IListEntryModelView> _entries = new();
public ICollection<ServerEntryModelView> Items => _entries.Values;
public ICollection<IListEntryModelView> Items => _entries.Values;
public void Clear()
{
_entries.Clear();
}
public ServerEntryModelView Get(RobustUrl url, ServerStatus? serverStatus = null)
public IListEntryModelView Get(RobustUrl url, ServerStatus? serverStatus = null)
{
ServerEntryModelView? entry;
IListEntryModelView? entry;
lock (_entries)
{
@@ -177,9 +180,13 @@ public class ServerViewContainer
return entry;
}
if (serverStatus is not null)
entry = _viewHelperService.GetViewModel<ServerEntryModelView>().WithData(url, serverStatus);
else
entry = _viewHelperService.GetViewModel<ServerCompoundEntryViewModel>().LoadServerEntry(url, CancellationToken.None);
if(favorites.Contains(url.ToString())) entry.IsFavorite = true;
if(favorites.Contains(url.ToString()) && entry is IFavoriteEntryModelView favoriteEntryModelView)
favoriteEntryModelView.IsFavorite = true;
_entries.Add(url.ToString(), entry);
}
@@ -188,6 +195,16 @@ public class ServerViewContainer
}
}
public interface IListEntryModelView
{
}
public interface IFavoriteEntryModelView
{
public bool IsFavorite { get; set; }
}
public class ServerComparer : IComparer<ServerHubInfo>, IComparer<ServerStatus>, IComparer<(RobustUrl,ServerStatus)>
{
public int Compare(ServerHubInfo? x, ServerHubInfo? y)

View File

@@ -0,0 +1,89 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Media;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.Extensions.DependencyInjection;
using Nebula.Launcher.ServerListProviders;
using Nebula.Launcher.ViewModels.Pages;
using Nebula.Launcher.Views;
using Nebula.Shared.Models;
using Nebula.Shared.Services;
using BindingFlags = System.Reflection.BindingFlags;
namespace Nebula.Launcher.ViewModels;
[ViewModelRegister(typeof(ServerCompoundEntryView), false)]
[ConstructGenerator]
public sealed partial class ServerCompoundEntryViewModel :
ViewModelBase, IFavoriteEntryModelView, IFilterConsumer, IListEntryModelView
{
[ObservableProperty] private ServerEntryModelView _currentEntry;
[ObservableProperty] private Control? _entryControl;
[ObservableProperty] private string _name = "Loading...";
[ObservableProperty] private bool _isFavorite;
[ObservableProperty] private bool _loading = true;
[GenerateProperty] private RestService RestService { get; }
[GenerateProperty] private IServiceProvider ServiceProvider{ get; }
[GenerateProperty] private FavoriteServerListProvider FavoriteServerListProvider { get; }
private RobustUrl? _url;
protected override void InitialiseInDesignMode()
{
}
protected override void Initialise()
{
}
public ServerCompoundEntryViewModel LoadServerEntry(RobustUrl url, CancellationToken cancellationToken)
{
Task.Run(async () =>
{
try
{
_url = url;
Name = $"Loading {url}...";
var status = await RestService.GetAsync<ServerStatus>(url.StatusUri, cancellationToken);
await Dispatcher.UIThread.InvokeAsync(() =>
{
CurrentEntry = ServiceProvider.GetService<ServerEntryModelView>()!.WithData(url, status);
CurrentEntry.IsFavorite = IsFavorite;
CurrentEntry.Loading = false;
Loading = false;
});
}
catch (Exception e)
{
var error = new Exception("Unable to load server entry", e);
Name = e.Message;
}
}, cancellationToken);
return this;
}
public void ToggleFavorites()
{
if (_url == null)
return;
IsFavorite = !IsFavorite;
if(IsFavorite)
FavoriteServerListProvider.AddFavorite(_url);
else
FavoriteServerListProvider.RemoveFavorite(_url);
}
public void ProcessFilter(ServerFilter? serverFilter)
{
if(CurrentEntry is IFilterConsumer filterConsumer)
filterConsumer.ProcessFilter(serverFilter);
}
}

View File

@@ -21,22 +21,21 @@ namespace Nebula.Launcher.ViewModels;
[ViewModelRegister(typeof(ServerEntryView), false)]
[ConstructGenerator]
public partial class ServerEntryModelView : ViewModelBase, IFilterConsumer
public partial class ServerEntryModelView : ViewModelBase, IFilterConsumer, IListEntryModelView, IFavoriteEntryModelView
{
[ObservableProperty] private string _description = "Fetching info...";
[ObservableProperty] private bool _expandInfo;
[ObservableProperty] private bool _isFavorite;
[ObservableProperty] private bool _isVisible;
[ObservableProperty] private bool _runVisible = true;
[ObservableProperty] private bool _tagDataVisible;
[ObservableProperty] private bool _loading;
private ILogger _logger;
private bool _isStatusFromHub;
private ServerInfo? _serverInfo;
private ContentLogConsumer _currentContentLogConsumer;
private ProcessRunHandler<GameProcessStartInfoProvider>? _currentInstance;
[ObservableProperty] private bool _tagDataVisible;
public LogPopupModelView CurrLog;
public RobustUrl Address { get; private set; }
[GenerateProperty] private ConfigurationService ConfigurationService { get; } = default!;
@@ -120,39 +119,14 @@ public partial class ServerEntryModelView : ViewModelBase, IFilterConsumer
OnPropertyChanged(nameof(Status));
}
public void UpdateStatusIfNecessary()
{
if(_isStatusFromHub) return;
FetchStatus();
}
public ServerEntryModelView WithData(RobustUrl url, ServerStatus? serverStatus)
public ServerEntryModelView WithData(RobustUrl url, ServerStatus serverStatus)
{
Address = url;
_isStatusFromHub = serverStatus is not null;
if (_isStatusFromHub)
SetStatus(serverStatus!);
else
FetchStatus();
SetStatus(serverStatus);
return this;
}
private async void FetchStatus()
{
try
{
SetStatus(await RestService.GetAsync<ServerStatus>(Address.StatusUri, CancellationService.Token));
}
catch (Exception e)
{
_logger.Error(e);
Status = new ServerStatus("ErrorLand", $"ERROR: {e.Message}", [], "", -1, -1, -1, false,
DateTime.Now,
-1);
}
}
public void OpenContentViewer()
{
MainViewModel.RequirePage<ContentBrowserViewModel>().Go(Address, ContentPath.Empty);

View File

@@ -0,0 +1,73 @@
<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"
xmlns:viewModels="clr-namespace:Nebula.Launcher.ViewModels"
xmlns:views="clr-namespace:Nebula.Launcher.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Nebula.Launcher.Views.ServerCompoundEntryView"
x:DataType="viewModels:ServerCompoundEntryViewModel">
<Design.DataContext>
<viewModels:ServerCompoundEntryViewModel />
</Design.DataContext>
<Panel>
<Border IsVisible="{Binding Loading}"
Background="{StaticResource DefaultGrad}"
BoxShadow="-2 0 5 -1 #121212"
CornerRadius="10"
Margin="5">
<Grid ColumnDefinitions="*,80,50,50" RowDefinitions="35,*,*">
<Border
Background="Transparent"
BoxShadow="0 3 3 -2 #121212"
CornerRadius="10"
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="0"/>
<ScrollViewer
Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalScrollBarVisibility="Hidden"
Margin="10,0,0,0"
VerticalScrollBarVisibility="Disabled"
x:Name="AutoScrollViewer">
<Label VerticalAlignment="Center">
<TextBlock Text="{Binding Name}" />
</Label>
</ScrollViewer>
<Panel
Grid.Column="2"
Grid.Row="0"
Margin="5,0,0,0">
<Button
Command="{Binding ToggleFavorites}"
CornerRadius="10,10,10,10"
HorizontalAlignment="Stretch"
IsVisible="{Binding !IsFavorite}"
VerticalAlignment="Stretch">
<Svg Margin="4" Path="/Assets/svg/star.svg" />
</Button>
<Button
Command="{Binding ToggleFavorites}"
CornerRadius="10,10,10,10"
HorizontalAlignment="Stretch"
IsVisible="{Binding IsFavorite}"
VerticalAlignment="Stretch">
<Svg Margin="4" Path="/Assets/svg/starfull.svg" />
</Button>
</Panel>
</Grid>
</Border>
<Panel IsVisible="{Binding !Loading}">
<views:ServerEntryView IsVisible="{Binding !Loading}" DataContext="{Binding CurrentEntry}"/>
</Panel>
</Panel>
</UserControl>

View File

@@ -0,0 +1,17 @@
using Avalonia.Controls;
using Nebula.Launcher.ViewModels;
namespace Nebula.Launcher.Views;
public partial class ServerCompoundEntryView : UserControl
{
public ServerCompoundEntryView()
{
InitializeComponent();
}
public ServerCompoundEntryView(ServerCompoundEntryViewModel viewModel) : this()
{
DataContext = viewModel;
}
}

View File

@@ -1,3 +1,4 @@
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Net;
using System.Text;
@@ -24,12 +25,14 @@ public class RestService
_logger = debug.GetLogger(this);
}
[Pure]
public async Task<T> GetAsync<T>(Uri uri, CancellationToken cancellationToken) where T : notnull
{
var response = await _client.GetAsync(uri, cancellationToken);
return await ReadResult<T>(response, cancellationToken, uri);
}
[Pure]
public async Task<T> GetAsyncDefault<T>(Uri uri, T defaultValue, CancellationToken cancellationToken) where T : notnull
{
try
@@ -43,6 +46,7 @@ public class RestService
}
}
[Pure]
public async Task<K> PostAsync<K, T>(T information, Uri uri, CancellationToken cancellationToken) where K : notnull
{
var json = JsonSerializer.Serialize(information, _serializerOptions);
@@ -51,6 +55,7 @@ public class RestService
return await ReadResult<K>(response, cancellationToken, uri);
}
[Pure]
public async Task<T> PostAsync<T>(Stream stream, Uri uri, CancellationToken cancellationToken) where T : notnull
{
using var multipartFormContent =
@@ -60,12 +65,14 @@ public class RestService
return await ReadResult<T>(response, cancellationToken, uri);
}
[Pure]
public async Task<T> DeleteAsync<T>(Uri uri, CancellationToken cancellationToken) where T : notnull
{
var response = await _client.DeleteAsync(uri, cancellationToken);
return await ReadResult<T>(response, cancellationToken, uri);
}
[Pure]
private async Task<T> ReadResult<T>(HttpResponseMessage response, CancellationToken cancellationToken, Uri uri) where T : notnull
{
var content = await response.Content.ReadAsStringAsync(cancellationToken);

View File

@@ -9,6 +9,8 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AConsole_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Ffd57398b7dc3a8ce7da2786f2c67289c3d974658a9e90d0c1e84db3d965fbf1_003FConsole_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AControl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F57361bc4e5442f644ff63ec7e745da2eb4bbb6c769d1fb683bab5f6f952b1ab_003FControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADecorator_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Feecfe7fcb95caaf3978fdce4ae36e346b34986d1d844b0dce2fcb67e5952c_003FDecorator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADesign_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F9a2912aa19f1b0ab2229159cec21d718356660fc49cd8e5257a66b584b69b_003FDesign_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADispatcher_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fe6d04341b5ca8c55e2be617e1b6fc5a12cc8647f7272d94f614ae7fb1c0e8d_003FDispatcher_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADrawingContext_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F7f67edd2b798d6c80b015913cde68b729bfe416b62cf075ea3953ffeff639c_003FDrawingContext_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnumerable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fcae7ff14a5884c649c9045d4ef4f987ea0928_003Fa6_003F6011c781_003FEnumerable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFileShare_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa6b7f037ba7b44df80b8d3aa7e58eeb2e8e938_003F54_003Fc3f4f140_003FFileShare_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@@ -18,6 +20,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fc439425da351c75ac7d966a1cc8324b51a9c471865af79d2f2f3fcb65e392_003FHttpClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpContent_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F9657cc383c70851dc2bdcf91eff27f21196844abfe552fc9c3243ff36974cd_003FHttpContent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpResponseMessage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F4cfeb8b377bc81e1fbb5f7d7a02492cb6ac23e88c8c9d7155944f0716f3d4b_003FHttpResponseMessage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIDispatcherImpl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F22d92db124764b1ab49745245c66f01b1e1a00_003F0f_003F01061787_003FIDispatcherImpl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIDisposable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa6b7f037ba7b44df80b8d3aa7e58eeb2e8e938_003F98_003Fd1b23281_003FIDisposable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIndex_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F2a1a813823579c69832f1304f97761e7be433bd6aa928f351d138050b56a38_003FIndex_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInt32_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fa882d183338544fdbcbdfc7b6d3dcb78916630765551644a221b5be9c45a121b_003FInt32_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>