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
52 changes: 40 additions & 12 deletions subtrack.MAUI/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using subtrack.MAUI.Utilities;
using System.Globalization;
using Plugin.LocalNotification;
using Shiny.Jobs;
using Shiny;

[assembly: InternalsVisibleTo("subtrack.Tests")]

Expand All @@ -20,25 +22,51 @@ public static MauiApp CreateMauiApp()
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts => fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"));
.ConfigureFonts(fonts => fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"))
.ConfigureAndroid()
.UseLocalNotification();

builder.Services
.AddDebugServices()
.AddSubtrackServices()
.AddMauiBlazorWebView();

builder.UseLocalNotification();
builder.Services.AddMauiBlazorWebView();
#if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools();
#endif
_ = builder.Services.AddSubtrackServices();
using var sp = builder.Services.BuildServiceProvider();
var db = sp.GetRequiredService<SubtrackDbContext>();
SetupDb(sp);

sp.GetRequiredService<AutoPaymentHandler>()
.ExecuteAsync().Wait();

return builder.Build();
}

private static void SetupDb(ServiceProvider serviceProvider)
{
var db = serviceProvider.GetRequiredService<SubtrackDbContext>();

#if DEBUG
SeedDb(db);
#else
db.Database.Migrate();
#endif
sp.GetRequiredService<AutoPaymentHandler>()
.ExecuteAsync().Wait();
#endif
}

return builder.Build();
private static IServiceCollection AddDebugServices(this IServiceCollection services)
{
#if DEBUG
services.AddBlazorWebViewDeveloperTools();
#endif
return services;
}

private static MauiAppBuilder ConfigureAndroid(this MauiAppBuilder builder)
{
var notifyDueSubscriptionsJob = new JobInfo(nameof(Services.Android.NotifyDueSubscriptionsJob), typeof(Services.Android.NotifyDueSubscriptionsJob), true);
#if ANDROID
builder.UseShiny();
builder.Services.AddJob(notifyDueSubscriptionsJob);
#endif
return builder;
}

private static void SetupCulture()
Expand Down
1 change: 1 addition & 0 deletions subtrack.MAUI/Platforms/Android/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
</manifest>
57 changes: 57 additions & 0 deletions subtrack.MAUI/Services/Android/NotifyDueSubscriptionsJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using Plugin.LocalNotification;
using Shiny.Jobs;

namespace subtrack.MAUI.Services.Android;

// the user might need to turn off battery optimizations for subtrack in settings->apps->subtrack->battery saver->no restrictions
public class NotifyDueSubscriptionsJob : IJob
{
private readonly IServiceScopeFactory _serviceScopeFactory;

public NotifyDueSubscriptionsJob(IServiceScopeFactory serviceScopeFactory)
{
_serviceScopeFactory = serviceScopeFactory;
}

private static async Task EnsureNotificationsAreEnabled()
{
var hasEnabledNotifications = await LocalNotificationCenter.Current.AreNotificationsEnabled();
if (!hasEnabledNotifications)
{
await LocalNotificationCenter.Current.RequestNotificationPermission();
}
}

private static void SendNotification(int notificationId, string title, string group)
{
var sampleNotification = new NotificationRequest()
{
NotificationId = notificationId,
Title = title,
CategoryType = NotificationCategoryType.Reminder,
Group = group,
};

LocalNotificationCenter.Current.Show(sampleNotification);
}

public async Task Run(JobInfo jobInfo, CancellationToken cancellationToken)
{
while (true)
{
if (cancellationToken.IsCancellationRequested)
break;

// jobs are singletons, use this to create a scope for fetching transient/scoped dependencies
using var scope = _serviceScopeFactory.CreateScope();

await EnsureNotificationsAreEnabled();

var notificationGroup = DateTime.Today.Day.ToString();
SendNotification(1, "Netflix is due in 2 days", notificationGroup);
SendNotification(2, "Missed payment for disney", notificationGroup);

await Task.Delay(TimeSpan.FromHours(12), cancellationToken);
}
}
}
13 changes: 13 additions & 0 deletions subtrack.MAUI/subtrack.MAUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,23 @@
<PackageReference Include="CsvHelper" Version="30.0.1" />
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Plugin.LocalNotification" Version="10.1.8" />
<PackageReference Include="Shiny.Jobs" Version="3.1.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\subtrack.DAL\subtrack.DAL.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0-android'">
<PackageReference Include="Shiny.Hosting.Maui">
<Version>3.1.2</Version>
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0-windows10.0.19041.0'">
<PackageReference Include="Shiny.Hosting.Maui">
<Version>3.1.2</Version>
</PackageReference>
</ItemGroup>

</Project>