Implementate notifiche

This commit is contained in:
2025-09-09 11:43:07 +02:00
parent 54be40518a
commit dfb86e3cd7
36 changed files with 338 additions and 33 deletions

View File

@@ -2,7 +2,7 @@
using IntegryApiClient.Core.Domain.RestClient.Contacts;
using Microsoft.Extensions.Logging;
using salesbook.Maui.Core.RestClient.IntegryApi.Dto;
using salesbook.Shared.Core.Interface;
using salesbook.Shared.Core.Interface.IntegryApi;
namespace salesbook.Maui.Core.RestClient.IntegryApi;

View File

@@ -7,6 +7,8 @@ using salesbook.Shared.Core.Helpers.Enum;
using salesbook.Shared.Core.Interface;
using Sentry.Protocol;
using System.Linq.Expressions;
using salesbook.Shared.Core.Interface.IntegryApi;
using salesbook.Shared.Core.Interface.System.Network;
namespace salesbook.Maui.Core.Services;

View File

@@ -1,5 +1,6 @@
using salesbook.Shared.Core.Helpers;
using salesbook.Shared.Core.Interface;
using salesbook.Shared.Core.Interface.IntegryApi;
namespace salesbook.Maui.Core.Services;

View File

@@ -1,4 +1,5 @@
using salesbook.Shared.Core.Interface;
using salesbook.Shared.Core.Interface.System.Network;
namespace salesbook.Maui.Core.System.Network;

View File

@@ -1,16 +1,37 @@
using salesbook.Shared.Core.Interface;
using salesbook.Shared.Core.Interface.IntegryApi;
using Shiny;
using Shiny.Notifications;
using Shiny.Push;
namespace salesbook.Maui.Core.System.Notification;
public class FirebaseNotificationService(IPushManager pushManager, IIntegryNotificationRestClient integryNotificationRestClient) : IFirebaseNotificationService
public class FirebaseNotificationService(
IPushManager pushManager,
IIntegryNotificationRestClient integryNotificationRestClient,
INotificationManager notificationManager
) : IFirebaseNotificationService
{
public async Task InitFirebase()
{
var (accessState, token) = await pushManager.RequestAccess();
CreateNotificationChannel();
var (accessState, token) = await pushManager.RequestAccess();
if (accessState == AccessState.Denied || token is null) return;
await integryNotificationRestClient.Register(token);
}
private void CreateNotificationChannel()
{
var channel = new Channel
{
Identifier = "salesbook_push",
Description = "Notifiche push di SalesBook",
Importance = ChannelImportance.High,
Actions = []
};
notificationManager.AddChannel(channel);
}
}

View File

@@ -0,0 +1,9 @@
using salesbook.Shared.Core.Interface.System.Notification;
using Shiny.Notifications;
namespace salesbook.Maui.Core.System.Notification;
public class ShinyNotificationManager(INotificationManager notificationManager) : IShinyNotificationManager
{
public Task RequestAccess() => notificationManager.RequestAccess();
}

View File

@@ -1,4 +1,3 @@
using AutoMapper;
using CommunityToolkit.Maui;
using CommunityToolkit.Mvvm.Messaging;
using IntegryApiClient.MAUI;
@@ -16,6 +15,9 @@ using salesbook.Shared.Core.Dto;
using salesbook.Shared.Core.Dto.PageState;
using salesbook.Shared.Core.Helpers;
using salesbook.Shared.Core.Interface;
using salesbook.Shared.Core.Interface.IntegryApi;
using salesbook.Shared.Core.Interface.System.Network;
using salesbook.Shared.Core.Interface.System.Notification;
using salesbook.Shared.Core.Messages.Activity.Copy;
using salesbook.Shared.Core.Messages.Activity.New;
using salesbook.Shared.Core.Messages.Back;
@@ -29,7 +31,7 @@ namespace salesbook.Maui
{
private const string AppToken = "f0484398-1f8b-42f5-ab79-5282c164e1d8";
public static MauiApp CreateMauiApp()
public static MauiAppBuilder CreateMauiAppBuilder()
{
InteractiveRenderSettings.ConfigureBlazorHybridRenderModes();
@@ -38,6 +40,7 @@ namespace salesbook.Maui
.UseMauiApp<App>()
.UseIntegry(appToken: AppToken, useLoginAzienda: true)
.UseMauiCommunityToolkit()
.UseShiny()
.UseSentry(options =>
{
options.Dsn = "https://453b6b38f94fd67e40e0d5306d6caff8@o4508499810254848.ingest.de.sentry.io/4509605099667536";
@@ -82,6 +85,7 @@ namespace salesbook.Maui
builder.Services.AddPush<PushNotificationDelegate>();
builder.Services.AddSingleton<IIntegryNotificationRestClient, IntegryNotificationRestClient>();
builder.Services.AddSingleton<IFirebaseNotificationService, FirebaseNotificationService>();
builder.Services.AddSingleton<IShinyNotificationManager, ShinyNotificationManager>();
#if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools();
@@ -93,7 +97,7 @@ namespace salesbook.Maui
builder.Services.AddSingleton<INetworkService, NetworkService>();
builder.Services.AddSingleton<LocalDbService>();
return builder.Build();
return builder;
}
}
}

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="it.integry.salesbook">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:usesCleartextTraffic="true" android:supportsRtl="true">
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
@@ -15,4 +15,10 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
</manifest>

View File

@@ -0,0 +1,13 @@
using salesbook.Maui.Core;
using salesbook.Shared.Core.Interface.System.Battery;
namespace salesbook.Maui;
public static class AndroidModule
{
public static MauiAppBuilder RegisterAndroidAppServices(this MauiAppBuilder mauiAppBuilder)
{
mauiAppBuilder.Services.AddSingleton<IBatteryOptimizationManagerService, BatteryOptimizationManagerService>();
return mauiAppBuilder;
}
}

View File

@@ -0,0 +1,28 @@
using Android.App;
using Android.Content;
using Android.OS;
using Android.Provider;
using salesbook.Shared.Core.Interface.System.Battery;
using Application = Android.App.Application;
namespace salesbook.Maui.Core;
public class BatteryOptimizationManagerService : IBatteryOptimizationManagerService
{
public bool IsBatteryOptimizationEnabled()
{
var packageName = AppInfo.PackageName;
var pm = (PowerManager)Application.Context.GetSystemService(Context.PowerService)!;
return !pm.IsIgnoringBatteryOptimizations(packageName);
}
public void OpenBatteryOptimizationSettings(Action<bool> onCompleted)
{
var packageName = AppInfo.PackageName;
var intent = new Intent(Settings.ActionRequestIgnoreBatteryOptimizations);
intent.SetData(Android.Net.Uri.Parse("package:" + packageName));
((MainActivity)Platform.CurrentActivity!).StartActivityForResult(intent, (result, _) => { onCompleted(result == Result.Ok); });
}
}

View File

@@ -1,19 +1,42 @@
using Android.App;
using Android.Content;
using Android.Content.PM;
namespace salesbook.Maui
{
[Activity(Theme = "@style/Maui.SplashTheme",
[Activity(
Theme = "@style/Maui.SplashTheme",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode |
ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
[IntentFilter([Shiny.ShinyPushIntents.NotificationClickAction],
Categories = new[]
{
[IntentFilter(
[
Shiny.ShinyPushIntents.NotificationClickAction
],
Categories =
[
"android.intent.category.DEFAULT"
}
]
)]
public class MainActivity : MauiAppCompatActivity
{
private readonly IDictionary<int, Action<Result, Intent>> _onActivityResultSubscriber =
new Dictionary<int, Action<Result, Intent>>();
public void StartActivityForResult(Intent intent, Action<Result, Intent> onResultAction)
{
var requestCode = new Random(DateTime.Now.Millisecond).Next();
_onActivityResultSubscriber.Add(requestCode, onResultAction);
StartActivityForResult(intent, requestCode);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if (_onActivityResultSubscriber.TryGetValue(requestCode, out var value))
value(resultCode, data);
base.OnActivityResult(requestCode, resultCode, data);
}
}
}

View File

@@ -1,16 +1,16 @@
using Android.App;
using Android.Runtime;
namespace salesbook.Maui
{
[Application(HardwareAccelerated = true)]
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
: base(handle, ownership)
{
}
namespace salesbook.Maui;
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
[Application(HardwareAccelerated = true)]
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
: base(handle, ownership)
{
}
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiAppBuilder()
.RegisterAndroidAppServices().Build();
}

View File

@@ -1,10 +1,24 @@
using Foundation;
using UIKit;
namespace salesbook.Maui
{
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiAppBuilder()
.RegisterIosAppServices().Build();
[Export("application:didRegisterForRemoteNotificationsWithDeviceToken:")]
public void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
=> global::Shiny.Hosting.Host.Lifecycle.OnRegisteredForRemoteNotifications(deviceToken);
[Export("application:didFailToRegisterForRemoteNotificationsWithError:")]
public void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
=> global::Shiny.Hosting.Host.Lifecycle.OnFailedToRegisterForRemoteNotifications(error);
[Export("application:didReceiveRemoteNotification:fetchCompletionHandler:")]
public void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
=> global::Shiny.Hosting.Host.Lifecycle.OnDidReceiveRemoteNotification(userInfo, completionHandler);
}
}

View File

@@ -0,0 +1,12 @@
using salesbook.Shared.Core.Interface.System.Battery;
namespace salesbook.Maui.Core;
public class BatteryOptimizationManagerService : IBatteryOptimizationManagerService
{
public bool IsBatteryOptimizationEnabled() => true;
public void OpenBatteryOptimizationSettings(Action<bool> onCompleted)
{
}
}

View File

@@ -0,0 +1,110 @@
<?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>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>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array>
<!--user info-->
<dict>
<key>NSPrivacyCollectedDataTypeUserID</key>
<string>NSPrivacyCollectedDataTypeLocation</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true />
<key>NSPrivacyCollectedDataTypeTracking</key>
<false />
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
<dict>
<key>NSPrivacyCollectedDataTypeEmailAddress</key>
<string>NSPrivacyCollectedDataTypeLocation</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true />
<key>NSPrivacyCollectedDataTypeTracking</key>
<false />
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
<dict>
<key>NSPrivacyCollectedDataTypePhoneNumber</key>
<string>NSPrivacyCollectedDataTypeLocation</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true />
<key>NSPrivacyCollectedDataTypeTracking</key>
<false />
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
<!--crashlytics/analytics-->
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeOtherDiagnosticData</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<false />
<key>NSPrivacyCollectedDataTypeTracking</key>
<false />
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeCrashData</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true />
<key>NSPrivacyCollectedDataTypeTracking</key>
<false />
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,13 @@
using salesbook.Maui.Core;
using salesbook.Shared.Core.Interface.System.Battery;
namespace salesbook.Maui;
public static class iOSModule
{
public static MauiAppBuilder RegisterIosAppServices(this MauiAppBuilder mauiAppBuilder)
{
mauiAppBuilder.Services.AddSingleton<IBatteryOptimizationManagerService, BatteryOptimizationManagerService>();
return mauiAppBuilder;
}
}

View File

@@ -83,14 +83,16 @@
<ProvisioningType>manual</ProvisioningType>
</PropertyGroup>
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' OR $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">
<ItemGroup Condition="$(TargetFramework.Contains('-ios'))">
<!--
<BundleResource Include="Platforms\iOS\PrivacyInfo.xcprivacy" LogicalName="PrivacyInfo.xcprivacy" />
<CustomEntitlements Include="keychain-access-groups" Type="StringArray" Value="%24(AppIdentifierPrefix)$(ApplicationId)" Visible="false" />
// For scheduled notifications, you need to setup "Time Sensitive Notifications" in the Apple Developer Portal for your app provisioning and uncomment below
// <CustomEntitlements Include="com.apple.developer.usernotifications.time-sensitive" Type="Boolean" Value="true" Visible="false" />
-->
<CustomEntitlements Include="aps-environment" Type="string" Value="development" Condition="'$(Configuration)' == 'Debug'" Visible="false" />
<CustomEntitlements Include="aps-environment" Type="string" Value="production" Condition="'$(Configuration)' == 'Release'" Visible="false" />
-->
</ItemGroup>
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' OR $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">
<BundleResource Include="Platforms\iOS\PrivacyInfo.xcprivacy" LogicalName="PrivacyInfo.xcprivacy" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0-android'">
@@ -138,6 +140,7 @@
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.81" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.6" />
<PackageReference Include="Sentry.Maui" Version="5.11.2" />
<PackageReference Include="Shiny.Hosting.Maui" Version="3.3.4" />
<PackageReference Include="Shiny.Notifications" Version="3.3.4" />
<PackageReference Include="Shiny.Push" Version="3.3.4" />
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />

View File

@@ -1,5 +1,7 @@
@using System.Globalization
@using salesbook.Shared.Core.Interface
@using salesbook.Shared.Core.Interface.IntegryApi
@using salesbook.Shared.Core.Interface.System.Network
@using salesbook.Shared.Core.Messages.Back
@inherits LayoutComponentBase
@inject IJSRuntime JS
@@ -55,7 +57,7 @@
private bool _showWarning;
private DateTime _lastApiCheck = DateTime.MinValue;
private const int DelaySeconds = 60;
private const int DelaySeconds = 180;
private CancellationTokenSource? _cts;

View File

@@ -11,6 +11,7 @@
@using salesbook.Shared.Core.Dto.PageState
@using salesbook.Shared.Core.Entity
@using salesbook.Shared.Core.Interface
@using salesbook.Shared.Core.Interface.IntegryApi
@inject JobSteps JobSteps
@inject IManageDataService ManageData
@inject IIntegryApiService IntegryApiService

View File

@@ -2,10 +2,13 @@
@attribute [Authorize]
@using salesbook.Shared.Core.Interface
@using salesbook.Shared.Components.Layout.Spinner
@using salesbook.Shared.Core.Interface.System.Network
@using salesbook.Shared.Core.Interface.System.Notification
@using salesbook.Shared.Core.Services
@inject IFormFactor FormFactor
@inject INetworkService NetworkService
@inject IFirebaseNotificationService FirebaseNotificationService
@inject IShinyNotificationManager NotificationManager
@inject PreloadService PreloadService
<SpinnerLayout FullScreen="true" />
@@ -14,6 +17,8 @@
{
protected override async Task OnInitializedAsync()
{
await CheckAndRequestPermissions();
try
{
await FirebaseNotificationService.InitFirebase();
@@ -35,6 +40,14 @@
NavigationManager.NavigateTo("/Calendar");
}
private async Task CheckAndRequestPermissions()
{
await NotificationManager.RequestAccess();
// if (BatteryOptimizationManagerService.IsBatteryOptimizationEnabled())
// BatteryOptimizationManagerService.OpenBatteryOptimizationSettings(_ => { });
}
private Task StartSyncUser()
{
return Task.Run(() =>

View File

@@ -1,6 +1,7 @@
@page "/login"
@using salesbook.Shared.Components.Layout.Spinner
@using salesbook.Shared.Core.Interface
@using salesbook.Shared.Core.Interface.System.Network
@using salesbook.Shared.Core.Services
@inject IUserAccountService UserAccountService
@inject AppAuthenticationStateProvider AuthenticationStateProvider

View File

@@ -3,6 +3,7 @@
@using salesbook.Shared.Components.Layout
@using salesbook.Shared.Core.Authorization.Enum
@using salesbook.Shared.Core.Interface
@using salesbook.Shared.Core.Interface.System.Network
@using salesbook.Shared.Core.Services
@inject AppAuthenticationStateProvider AuthenticationStateProvider
@inject INetworkService NetworkService

View File

@@ -10,6 +10,7 @@
@using salesbook.Shared.Core.Dto.Activity
@using salesbook.Shared.Core.Dto.JobProgress
@using salesbook.Shared.Core.Dto.PageState
@using salesbook.Shared.Core.Interface.IntegryApi
@implements IAsyncDisposable
@inject IManageDataService ManageData
@inject IMapper Mapper

View File

@@ -2,6 +2,7 @@
@using salesbook.Shared.Core.Dto
@using salesbook.Shared.Core.Interface
@using salesbook.Shared.Components.Layout.Overlay
@using salesbook.Shared.Core.Interface.IntegryApi
@inject IIntegryApiService IntegryApiService
<div class="bottom-sheet-backdrop @(IsSheetVisible ? "show" : "")" @onclick="CloseBottomSheet"></div>

View File

@@ -1,5 +1,6 @@
@using salesbook.Shared.Core.Dto
@using salesbook.Shared.Core.Interface
@using salesbook.Shared.Core.Interface.IntegryApi
@inject IIntegryApiService IntegryApiService
@inject IAttachedService AttachedService

View File

@@ -9,6 +9,8 @@
@using salesbook.Shared.Core.Dto.Contact
@using salesbook.Shared.Core.Entity
@using salesbook.Shared.Core.Interface
@using salesbook.Shared.Core.Interface.IntegryApi
@using salesbook.Shared.Core.Interface.System.Network
@using salesbook.Shared.Core.Messages.Activity.Copy
@inject IManageDataService ManageData
@inject INetworkService NetworkService

View File

@@ -5,6 +5,8 @@
@using salesbook.Shared.Core.Entity
@using salesbook.Shared.Components.SingleElements.BottomSheet
@using salesbook.Shared.Core.Dto.Contact
@using salesbook.Shared.Core.Interface.IntegryApi
@using salesbook.Shared.Core.Interface.System.Network
@inject IManageDataService ManageData
@inject INetworkService NetworkService
@inject IIntegryApiService IntegryApiService

View File

@@ -2,6 +2,8 @@
@using salesbook.Shared.Components.Layout
@using salesbook.Shared.Core.Interface
@using salesbook.Shared.Components.Layout.Overlay
@using salesbook.Shared.Core.Interface.IntegryApi
@using salesbook.Shared.Core.Interface.System.Network
@inject IManageDataService ManageData
@inject INetworkService NetworkService
@inject IIntegryApiService IntegryApiService

View File

@@ -4,7 +4,7 @@ using salesbook.Shared.Core.Dto.Contact;
using salesbook.Shared.Core.Dto.JobProgress;
using salesbook.Shared.Core.Entity;
namespace salesbook.Shared.Core.Interface;
namespace salesbook.Shared.Core.Interface.IntegryApi;
public interface IIntegryApiService
{

View File

@@ -1,6 +1,6 @@
using Microsoft.Extensions.Logging;
namespace salesbook.Shared.Core.Interface;
namespace salesbook.Shared.Core.Interface.IntegryApi;
public interface IIntegryNotificationRestClient
{

View File

@@ -0,0 +1,8 @@
namespace salesbook.Shared.Core.Interface.System.Battery;
public interface IBatteryOptimizationManagerService
{
bool IsBatteryOptimizationEnabled();
void OpenBatteryOptimizationSettings(Action<bool> onCompleted);
}

View File

@@ -1,4 +1,4 @@
namespace salesbook.Shared.Core.Interface;
namespace salesbook.Shared.Core.Interface.System.Network;
public interface INetworkService
{

View File

@@ -0,0 +1,6 @@
namespace salesbook.Shared.Core.Interface.System.Notification;
public interface IShinyNotificationManager
{
Task RequestAccess();
}

View File

@@ -7,6 +7,7 @@ using salesbook.Shared.Core.Entity;
using salesbook.Shared.Core.Interface;
using System.Net.Http.Headers;
using salesbook.Shared.Core.Dto.Contact;
using salesbook.Shared.Core.Interface.IntegryApi;
namespace salesbook.Shared.Core.Services;

View File

@@ -1,4 +1,5 @@
using salesbook.Shared.Core.Interface;
using salesbook.Shared.Core.Interface.System.Network;
namespace salesbook.Web.Core.Services;

View File

@@ -5,6 +5,8 @@ using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using MudBlazor.Services;
using salesbook.Shared.Components;
using salesbook.Shared.Core.Interface;
using salesbook.Shared.Core.Interface.IntegryApi;
using salesbook.Shared.Core.Interface.System.Network;
using salesbook.Shared.Core.Services;
using salesbook.Web.Core.Services;