Initial v2 launch notification.
This commit is contained in:
@@ -51,6 +51,11 @@ public interface INotificationBuilder
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void CreateStoreUpdateNotification();
|
void CreateStoreUpdateNotification();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shows the one-time release migration notification.
|
||||||
|
/// </summary>
|
||||||
|
void CreateReleaseMigrationNotification();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a calendar reminder toast for the specified calendar item.
|
/// Creates a calendar reminder toast for the specified calendar item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -704,6 +704,8 @@
|
|||||||
"Notifications_WinoUpdatedTitle": "Wino Mail has been updated.",
|
"Notifications_WinoUpdatedTitle": "Wino Mail has been updated.",
|
||||||
"Notifications_StoreUpdateAvailableTitle": "Update available",
|
"Notifications_StoreUpdateAvailableTitle": "Update available",
|
||||||
"Notifications_StoreUpdateAvailableMessage": "A newer version of Wino Mail is ready to install from Microsoft Store.",
|
"Notifications_StoreUpdateAvailableMessage": "A newer version of Wino Mail is ready to install from Microsoft Store.",
|
||||||
|
"Notifications_ReleaseMigrationTitle": "New Wino Mail & Calendar",
|
||||||
|
"Notifications_ReleaseMigrationMessage": "Wino Mail got updated to the next version. Please re-create your accounts and start using the next version including calendar, mail templates, shortcuts, and a bunch of other improvements.",
|
||||||
"OnlineSearchFailed_Message": "Failed to perform search\n{0}\n\nListing offline mails.",
|
"OnlineSearchFailed_Message": "Failed to perform search\n{0}\n\nListing offline mails.",
|
||||||
"OnlineSearchTry_Line1": "Can't find what you are looking for?",
|
"OnlineSearchTry_Line1": "Can't find what you are looking for?",
|
||||||
"OnlineSearchTry_Line2": "Try online search.",
|
"OnlineSearchTry_Line2": "Try online search.",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<Identity
|
<Identity
|
||||||
Name="58272BurakKSE.WinoMailPreview"
|
Name="58272BurakKSE.WinoMailPreview"
|
||||||
Publisher="CN=51FBDAF3-E212-4149-89A2-A2636B3BC911"
|
Publisher="CN=51FBDAF3-E212-4149-89A2-A2636B3BC911"
|
||||||
Version="2.0.6.0" />
|
Version="2.0.7.0" />
|
||||||
|
|
||||||
<mp:PhoneIdentity PhoneProductId="7b7e90e9-cc55-4409-9769-99b4b5ed6e9b" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
<mp:PhoneIdentity PhoneProductId="7b7e90e9-cc55-4409-9769-99b4b5ed6e9b" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||||
|
|
||||||
|
|||||||
@@ -233,6 +233,17 @@ public class NotificationBuilder : INotificationBuilder
|
|||||||
ShowNotification(builder, "store-update-available");
|
ShowNotification(builder, "store-update-available");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CreateReleaseMigrationNotification()
|
||||||
|
{
|
||||||
|
var builder = CreateBuilder();
|
||||||
|
builder.AddText(Translator.Notifications_ReleaseMigrationTitle);
|
||||||
|
builder.AddText(Translator.Notifications_ReleaseMigrationMessage);
|
||||||
|
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
||||||
|
builder.AddButton(CreateDismissButton());
|
||||||
|
|
||||||
|
ShowNotification(builder, "release-migration-v2");
|
||||||
|
}
|
||||||
|
|
||||||
public Task CreateCalendarReminderNotificationAsync(CalendarItem calendarItem, long reminderDurationInSeconds)
|
public Task CreateCalendarReminderNotificationAsync(CalendarItem calendarItem, long reminderDurationInSeconds)
|
||||||
{
|
{
|
||||||
if (calendarItem == null)
|
if (calendarItem == null)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
@@ -14,13 +15,16 @@ public sealed class ReleaseLocalAccountDataCleanupService
|
|||||||
|
|
||||||
private readonly IConfigurationService _configurationService;
|
private readonly IConfigurationService _configurationService;
|
||||||
private readonly IApplicationConfiguration _applicationConfiguration;
|
private readonly IApplicationConfiguration _applicationConfiguration;
|
||||||
|
private readonly INotificationBuilder _notificationBuilder;
|
||||||
private readonly ILogger _logger = Log.ForContext<ReleaseLocalAccountDataCleanupService>();
|
private readonly ILogger _logger = Log.ForContext<ReleaseLocalAccountDataCleanupService>();
|
||||||
|
|
||||||
public ReleaseLocalAccountDataCleanupService(IConfigurationService configurationService,
|
public ReleaseLocalAccountDataCleanupService(IConfigurationService configurationService,
|
||||||
IApplicationConfiguration applicationConfiguration)
|
IApplicationConfiguration applicationConfiguration,
|
||||||
|
INotificationBuilder notificationBuilder)
|
||||||
{
|
{
|
||||||
_configurationService = configurationService;
|
_configurationService = configurationService;
|
||||||
_applicationConfiguration = applicationConfiguration;
|
_applicationConfiguration = applicationConfiguration;
|
||||||
|
_notificationBuilder = notificationBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RunIfNeededAsync()
|
public async Task RunIfNeededAsync()
|
||||||
@@ -45,44 +49,70 @@ public sealed class ReleaseLocalAccountDataCleanupService
|
|||||||
Path.Combine(publisherPath, LegacyDatabaseFileName)
|
Path.Combine(publisherPath, LegacyDatabaseFileName)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var hadLegacyData = false;
|
||||||
|
|
||||||
foreach (var targetPath in cleanupTargets)
|
foreach (var targetPath in cleanupTargets)
|
||||||
{
|
{
|
||||||
await DeletePathIfExistsAsync(localFolderPath, targetPath).ConfigureAwait(false);
|
hadLegacyData |= await DeletePathIfExistsAsync(targetPath, localFolderPath, publisherPath).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_configurationService.Set(CleanupCompletedSettingKey, true);
|
_configurationService.Set(CleanupCompletedSettingKey, true);
|
||||||
|
|
||||||
|
if (hadLegacyData)
|
||||||
|
{
|
||||||
|
_notificationBuilder.CreateReleaseMigrationNotification();
|
||||||
|
}
|
||||||
|
|
||||||
_logger.Information("Completed one-time local account data cleanup for release migration.");
|
_logger.Information("Completed one-time local account data cleanup for release migration.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeletePathIfExistsAsync(string localFolderPath, string targetPath)
|
private async Task<bool> DeletePathIfExistsAsync(string targetPath, params string[] allowedRootPaths)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var fullTargetPath = Path.GetFullPath(targetPath);
|
var fullTargetPath = Path.GetFullPath(targetPath);
|
||||||
var fullLocalFolderPath = Path.GetFullPath(localFolderPath);
|
if (!allowedRootPaths.Any(rootPath => IsPathUnderAllowedRoot(fullTargetPath, rootPath)))
|
||||||
|
|
||||||
if (!fullTargetPath.StartsWith(fullLocalFolderPath, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
_logger.Warning("Skipped startup cleanup for path outside local folder: {TargetPath}", fullTargetPath);
|
_logger.Warning("Skipped startup cleanup for path outside allowed roots: {TargetPath}", fullTargetPath);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var targetExists = Directory.Exists(fullTargetPath) || File.Exists(fullTargetPath);
|
||||||
|
|
||||||
if (Directory.Exists(fullTargetPath))
|
if (Directory.Exists(fullTargetPath))
|
||||||
{
|
{
|
||||||
await Task.Run(() => Directory.Delete(fullTargetPath, recursive: true)).ConfigureAwait(false);
|
await Task.Run(() => Directory.Delete(fullTargetPath, recursive: true)).ConfigureAwait(false);
|
||||||
_logger.Information("Deleted legacy startup cleanup directory {TargetPath}", fullTargetPath);
|
_logger.Information("Deleted legacy startup cleanup directory {TargetPath}", fullTargetPath);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (File.Exists(fullTargetPath))
|
if (File.Exists(fullTargetPath))
|
||||||
{
|
{
|
||||||
File.Delete(fullTargetPath);
|
File.Delete(fullTargetPath);
|
||||||
_logger.Information("Deleted legacy startup cleanup file {TargetPath}", fullTargetPath);
|
_logger.Information("Deleted legacy startup cleanup file {TargetPath}", fullTargetPath);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return targetExists;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Warning(ex, "Failed to delete legacy startup cleanup path {TargetPath}", targetPath);
|
_logger.Warning(ex, "Failed to delete legacy startup cleanup path {TargetPath}", targetPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsPathUnderAllowedRoot(string fullTargetPath, string rootPath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(rootPath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var fullRootPath = Path.GetFullPath(rootPath);
|
||||||
|
var relativePath = Path.GetRelativePath(fullRootPath, fullTargetPath);
|
||||||
|
|
||||||
|
return relativePath != "." &&
|
||||||
|
!relativePath.StartsWith("..", StringComparison.Ordinal) &&
|
||||||
|
!Path.IsPathRooted(relativePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user