133 lines
4.6 KiB
C#
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) { }
|
|
}
|
|
}
|