Files
Wino-Mail/Wino.Core.UWP/Services/StoreRatingService.cs
2025-02-16 11:54:23 +01:00

133 lines
4.6 KiB
C#

using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.ApplicationModel.Core;
using Windows.Services.Store;
using Windows.System;
using Wino.Core.Domain;
using Wino.Core.Domain.Interfaces;
namespace Wino.Core.UWP.Services;
public class StoreRatingService : IStoreRatingService
{
private const string RatedStorageKey = nameof(RatedStorageKey);
private const string LatestAskedKey = nameof(LatestAskedKey);
private readonly IConfigurationService _configurationService;
private readonly IMailDialogService _dialogService;
public StoreRatingService(IConfigurationService configurationService, IMailDialogService dialogService)
{
_configurationService = configurationService;
_dialogService = dialogService;
}
private bool IsAskingThresholdExceeded()
{
var latestAskedDate = _configurationService.Get(LatestAskedKey, DateTime.MinValue);
// Never asked before.
// Set the threshold and wait for the next trigger.
if (latestAskedDate == DateTime.MinValue)
{
_configurationService.Set(LatestAskedKey, DateTime.UtcNow);
}
else if (DateTime.UtcNow >= latestAskedDate.AddMinutes(30))
{
return true;
}
return false;
}
public async Task PromptRatingDialogAsync()
{
// Annoying.
if (Debugger.IsAttached) return;
// Swallow all exceptions. App should not crash in any errors.
try
{
bool isRated = _configurationService.GetRoaming(RatedStorageKey, false);
if (isRated) return;
if (!isRated)
{
if (!IsAskingThresholdExceeded()) return;
var isRateWinoApproved = await _dialogService.ShowWinoCustomMessageDialogAsync(Translator.StoreRatingDialog_Title,
Translator.StoreRatingDialog_MessageFirstLine,
Translator.Buttons_RateWino,
Domain.Enums.WinoCustomMessageDialogIcon.Question,
Translator.Buttons_No,
RatedStorageKey);
if (isRateWinoApproved)
{
// In case of failure of this call, we will navigate users to Store page directly.
try
{
await ShowPortableRatingDialogAsync();
}
catch (Exception)
{
await Launcher.LaunchUriAsync(new Uri($"ms-windows-store://review/?ProductId=9NCRCVJC50WL"));
}
}
}
}
catch (Exception) { }
finally
{
_configurationService.Set(LatestAskedKey, DateTime.UtcNow);
}
}
private async Task ShowPortableRatingDialogAsync()
{
var _storeContext = StoreContext.GetDefault();
StoreRateAndReviewResult result = await _storeContext.RequestRateAndReviewAppAsync();
// Check status
switch (result.Status)
{
case StoreRateAndReviewStatus.Succeeded:
if (result.WasUpdated)
_dialogService.InfoBarMessage(Translator.Info_ReviewSuccessTitle, Translator.Info_ReviewUpdatedMessage, Domain.Enums.InfoBarMessageType.Success);
else
_dialogService.InfoBarMessage(Translator.Info_ReviewSuccessTitle, Translator.Info_ReviewNewMessage, Domain.Enums.InfoBarMessageType.Success);
_configurationService.Set(RatedStorageKey, true);
break;
case StoreRateAndReviewStatus.CanceledByUser:
break;
case StoreRateAndReviewStatus.NetworkError:
_dialogService.InfoBarMessage(Translator.Info_ReviewNetworkErrorTitle, Translator.Info_ReviewNetworkErrorMessage, Domain.Enums.InfoBarMessageType.Warning);
break;
default:
_dialogService.InfoBarMessage(Translator.Info_ReviewUnknownErrorTitle, string.Format(Translator.Info_ReviewUnknownErrorMessage, result.ExtendedError.Message), Domain.Enums.InfoBarMessageType.Warning);
break;
}
}
public async Task LaunchStorePageForReviewAsync()
{
try
{
await CoreApplication.GetCurrentView()?.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
// TODO: Get it from package info.
await Launcher.LaunchUriAsync(new Uri($"ms-windows-store://review/?ProductId=9NCRCVJC50WL"));
});
}
catch (Exception) { }
}
}