Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions src/ArcadePointsBot/App.axaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AvaloniaApplication1.App"
xmlns:oldLocal="using:AvaloniaApplication1"
x:Class="ArcadePointsBot.App"
xmlns:local="using:ArcadePointsBot"
xmlns:models="using:AvaloniaApplication1.Models"
xmlns:models="using:ArcadePointsBot.Models"
RequestedThemeVariant="Dark">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->

<Application.Resources>
<oldLocal:WorkerStatus x:Key="WorkerStatus1">Stopped</oldLocal:WorkerStatus>
<oldLocal:WorkerStatus x:Key="WorkerStatusErr">Errored</oldLocal:WorkerStatus>
<oldLocal:WorkerStatus x:Key="WorkerStatusStart">Starting</oldLocal:WorkerStatus>
<oldLocal:WorkerStatus x:Key="WorkerStatusRunning">Running</oldLocal:WorkerStatus>
<local:WorkerStatus x:Key="WorkerStatus1">Stopped</local:WorkerStatus>
<local:WorkerStatus x:Key="WorkerStatusErr">Errored</local:WorkerStatus>
<local:WorkerStatus x:Key="WorkerStatusStart">Starting</local:WorkerStatus>
<local:WorkerStatus x:Key="WorkerStatusRunning">Running</local:WorkerStatus>

<models:KeyboardActionType x:Key="ActionType1">Press</models:KeyboardActionType>
<models:ActionType x:Key="KeyboardAction">Keyboard</models:ActionType>
Expand Down
159 changes: 79 additions & 80 deletions src/ArcadePointsBot/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,28 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core;
using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml;
using Avalonia.Styling;
using Avalonia.Themes.Fluent;
using AvaloniaApplication1.Auth;
using AvaloniaApplication1.Config;
using AvaloniaApplication1.Data.Abstractions.Repositories;
using AvaloniaApplication1.Data.Contexts;
using AvaloniaApplication1.Data.Repositories;
using AvaloniaApplication1.Services;
using AvaloniaApplication1.Util;
using AvaloniaApplication1.ViewModels;
using AvaloniaApplication1.Views;
using ArcadePointsBot.Auth;
using ArcadePointsBot.Config;
using ArcadePointsBot.Data.Abstractions.Repositories;
using ArcadePointsBot.Data.Contexts;
using ArcadePointsBot.Data.Repositories;
using ArcadePointsBot.Services;
using ArcadePointsBot.ViewModels;
using ArcadePointsBot.Views;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ReactiveUI;
using Serilog;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace AvaloniaApplication1;
namespace ArcadePointsBot;
public partial class App : Application
{
public IHost? GlobalHost { get; private set; }
Expand Down Expand Up @@ -65,6 +59,11 @@ public override async void OnFrameworkInitializationCompleted()
{
GlobalHost = CreateAppBuilder().Build();
EnsureDb(GlobalHost.Services);


var lang = GlobalHost.Services.GetRequiredService<IConfiguration>().GetValue<string>("lang");
ArcadePointsBot.Resources.L10n.Culture = new System.Globalization.CultureInfo(lang ?? "en-US");

if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
// Line below is needed to remove Avalonia data validation.
Expand All @@ -82,82 +81,82 @@ public override async void OnFrameworkInitializationCompleted()
GlobalHost = null;
};
}

DataTemplates.Add(GlobalHost.Services.GetRequiredService<ViewLocator>());

base.OnFrameworkInitializationCompleted();

await GlobalHost.StartAsync();
}


public static IHostBuilder CreateAppBuilder() => Host
.CreateDefaultBuilder(Environment.GetCommandLineArgs())
.UseSerilog((ctx, svc, cfg) =>

public static IHostBuilder CreateAppBuilder() => Host
.CreateDefaultBuilder(Environment.GetCommandLineArgs())
.UseSerilog((ctx, svc, cfg) =>
{
cfg
.ReadFrom.Configuration(ctx.Configuration)
.ReadFrom.Services(svc)
.Enrich.FromLogContext();
})
.ConfigureAppConfiguration(WithApplicationConfiguration)
.ConfigureServices(WithApplicationServices);

private static void WithApplicationConfiguration(HostBuilderContext context, IConfigurationBuilder configurationBuilder)
{
if (Design.IsDesignMode)
return;
configurationBuilder.Sources.Clear();
configurationBuilder
.SetBasePath(Directory.GetCurrentDirectory())
.Add<WritableJsonConfigurationSource>(s =>
{
s.Path = "appsettings.json";
s.Optional = false;
s.ReloadOnChange = true;
s.FileProvider = null;
s.ResolveFileProvider();
})
.AddJsonFile("appsettings.Development.json", true, true);

if (context.HostingEnvironment.IsDevelopment())
{
cfg
.ReadFrom.Configuration(ctx.Configuration)
.ReadFrom.Services(svc)
.Enrich.FromLogContext();
})
.ConfigureAppConfiguration(WithApplicationConfiguration)
.ConfigureServices(WithApplicationServices);

private static void WithApplicationConfiguration(HostBuilderContext context, IConfigurationBuilder configurationBuilder)
configurationBuilder.AddUserSecrets(Assembly.GetExecutingAssembly());
}

configurationBuilder.AddEnvironmentVariables();
}
private static void WithApplicationServices(HostBuilderContext context, IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
{
if (Design.IsDesignMode)
return;
configurationBuilder.Sources.Clear();
configurationBuilder
.SetBasePath(Directory.GetCurrentDirectory())
.Add<WritableJsonConfigurationSource>(s =>
{
s.Path = "appsettings.json";
s.Optional = false;
s.ReloadOnChange = true;
s.FileProvider = null;
s.ResolveFileProvider();
})
.AddJsonFile("appsettings.Development.json", true, true);

if (context.HostingEnvironment.IsDevelopment())
{
configurationBuilder.AddUserSecrets(Assembly.GetExecutingAssembly());
}
var dbPath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "ArcadePointsBot.db");
options.UseSqlite($"Data Source={dbPath}");
});

configurationBuilder.AddEnvironmentVariables();
}
private static void WithApplicationServices(HostBuilderContext context, IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
services.AddOptions<TwitchAuthConfig>().BindConfiguration("TwitchAuthConfig");

services.Configure<TwitchAuthConfig>(options =>
{
var rawConfig = context.Configuration;
options.PropertyChanged += (o, e) =>
{
var dbPath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "ArcadePointsBot.db");
options.UseSqlite($"Data Source={dbPath}");
});
if (e is not PropertyChangedEventArgsEx args) throw new InvalidOperationException();
rawConfig["TwitchAuthConfig:" + args.PropertyName!] = args.Value?.ToString();
};
});

services.AddOptions<TwitchAuthConfig>().BindConfiguration("TwitchAuthConfig");
services.AddSingleton<IObserver<Exception>, GlobalRxExceptionHandler>();
services.AddSingleton<IAuthenticationService, TwitchAuthenticationService>();
services.AddScoped<TwitchPointRewardService>();

services.Configure<TwitchAuthConfig>(options =>
{
var rawConfig = context.Configuration;
options.PropertyChanged += (o, e) =>
{
if (e is not PropertyChangedEventArgsEx args) throw new InvalidOperationException();
rawConfig["TwitchAuthConfig:" + args.PropertyName!] = args.Value?.ToString();
};
});

services.AddSingleton<IObserver<Exception>, GlobalRxExceptionHandler>();
services.AddSingleton<IAuthenticationService, TwitchAuthenticationService>();
services.AddScoped<TwitchPointRewardService>();

services.AddScoped(typeof(IEntityRepository<,>), typeof(DataEntityRepository<,>));
services.AddScoped<IRewardRepository, RewardRepository>();

services.AddSingleton<TwitchWorker>();

services.AddTransient<ViewLocator>();
services.AddTransient<MainWindowViewModel>();
services.AddTransient<CreateRewardWindowViewModel>();
}
services.AddScoped(typeof(IEntityRepository<,>), typeof(DataEntityRepository<,>));
services.AddScoped<IRewardRepository, RewardRepository>();

services.AddSingleton<TwitchWorker>();

services.AddTransient<ViewLocator>();
services.AddTransient<MainWindowViewModel>();
services.AddTransient<CreateRewardWindowViewModel>();
}
}
15 changes: 14 additions & 1 deletion src/ArcadePointsBot/ArcadePointsBot.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
<AvaloniaResource Include="Assets\**" />
</ItemGroup>


<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App"></FrameworkReference>
<PackageReference Include="Avalonia" Version="11.0.5" />
Expand Down Expand Up @@ -47,6 +46,20 @@
</PackageReference>
</ItemGroup>

<ItemGroup>
<Compile Update="Resources\L10n.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>L10n.resx</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Resources\L10n.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>L10n.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<None Update="appsettings.Development.json">
Expand Down
2 changes: 1 addition & 1 deletion src/ArcadePointsBot/Auth/IAuthenticationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Text;
using System.Threading.Tasks;

namespace AvaloniaApplication1.Auth;
namespace ArcadePointsBot.Auth;

public interface IAuthenticationService
{
Expand Down
2 changes: 1 addition & 1 deletion src/ArcadePointsBot/Auth/TwitchAuthConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;

namespace AvaloniaApplication1.Auth;
namespace ArcadePointsBot.Auth;
public class TwitchAuthConfig : INotifyPropertyChanged
{
private DateTimeOffset? accessTokenExpiration;
Expand Down
2 changes: 1 addition & 1 deletion src/ArcadePointsBot/Auth/TwitchAuthenticationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Net.Http;
using System.Threading.Tasks;

namespace AvaloniaApplication1.Auth
namespace ArcadePointsBot.Auth
{
internal class TwitchAuthenticationService : IAuthenticationService
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using AvaloniaApplication1.Auth;
using ArcadePointsBot.Auth;
using Microsoft.Extensions.Configuration.Json;
using System;
using System.Collections.Generic;
Expand All @@ -9,7 +9,7 @@
using System.Text.Json.Nodes;
using System.Threading.Tasks;

namespace AvaloniaApplication1.Config
namespace ArcadePointsBot.Config
{
internal class WritableJsonConfigurationProvider : JsonConfigurationProvider
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System.Text;
using System.Threading.Tasks;

namespace AvaloniaApplication1.Config
namespace ArcadePointsBot.Config
{
internal class WritableJsonConfigurationSource : JsonConfigurationSource
{
Expand Down
2 changes: 1 addition & 1 deletion src/ArcadePointsBot/Data/Abstractions/IEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Text;
using System.Threading.Tasks;

namespace AvaloniaApplication1.Data.Abstractions;
namespace ArcadePointsBot.Data.Abstractions;

public interface IEntity<TId>
{
Expand Down
2 changes: 1 addition & 1 deletion src/ArcadePointsBot/Data/Abstractions/IUnitOfWork.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System.Threading;
using System.Threading.Tasks;

namespace AvaloniaApplication1.Data.Abstractions
namespace ArcadePointsBot.Data.Abstractions
{
public interface IUnitOfWork
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Text;
using System.Threading.Tasks;

namespace AvaloniaApplication1.Data.Abstractions.Repositories;
namespace ArcadePointsBot.Data.Abstractions.Repositories;

public interface IEntityRepository<T, TId> : IReadRepository<T>, IWriteRepository<T, TId> where T : IEntity<TId>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using AvaloniaApplication1.Models;
using ArcadePointsBot.Models;

namespace AvaloniaApplication1.Data.Abstractions.Repositories
namespace ArcadePointsBot.Data.Abstractions.Repositories
{
public interface IRewardRepository : IEntityRepository<TwitchReward, string>
{
Expand Down
8 changes: 4 additions & 4 deletions src/ArcadePointsBot/Data/Contexts/ApplicationDbContext.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using AvaloniaApplication1.Data.Abstractions;
using AvaloniaApplication1.Models;
using AvaloniaApplication1.ViewModels;
using ArcadePointsBot.Data.Abstractions;
using ArcadePointsBot.Models;
using ArcadePointsBot.ViewModels;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using System;
Expand All @@ -9,7 +9,7 @@
using System.Text;
using System.Threading.Tasks;

namespace AvaloniaApplication1.Data.Contexts;
namespace ArcadePointsBot.Data.Contexts;

public class ApplicationDbContext : DbContext, IUnitOfWork
{
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#nullable disable

namespace AvaloniaApplication1.Data.Migrations
namespace ArcadePointsBot.Data.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
Expand Down
Loading