Added support for one click unsubscribe with confirmation dialog.

This commit is contained in:
Aleh Khantsevich
2024-05-01 14:23:23 +02:00
parent 2bcb6a146b
commit e2f0c73bab
5 changed files with 118 additions and 22 deletions

View File

@@ -2,6 +2,8 @@
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
@@ -47,7 +49,7 @@ namespace Wino.Mail.ViewModels
#region Properties
public bool ShouldDisplayDownloadProgress => IsIndetermineProgress || (CurrentDownloadPercentage > 0 && CurrentDownloadPercentage <= 100);
public bool CanUnsubscribe => CurrentRenderModel?.CanUnsubscribe ?? false;
public bool CanUnsubscribe => CurrentRenderModel?.UnsubscribeInfo?.CanUnsubscribe ?? false;
public bool IsJunkMail => initializedMailItemViewModel?.AssignedFolder != null && initializedMailItemViewModel.AssignedFolder.SpecialFolderType == SpecialFolderType.Junk;
public bool IsImageRenderingDisabled
@@ -172,18 +174,60 @@ namespace Wino.Mail.ViewModels
[RelayCommand]
private async Task UnsubscribeAsync()
{
if (!CurrentRenderModel?.CanUnsubscribe ?? false) return;
if (!(CurrentRenderModel?.UnsubscribeInfo?.CanUnsubscribe ?? false)) return;
// TODO: Support for List-Unsubscribe-Post header. It can be done without launching browser.
// https://certified-senders.org/wp-content/uploads/2017/07/CSA_one-click_list-unsubscribe.pdf
bool confirmed;
// TODO: Sometimes unsubscribe link can be a mailto: link.
// or sometimes with mailto AND http link. We need to handle this.
// Try to unsubscribe by http first.
if (CurrentRenderModel.UnsubscribeInfo.HttpLink is not null)
{
if (!Uri.IsWellFormedUriString(CurrentRenderModel.UnsubscribeInfo.HttpLink, UriKind.RelativeOrAbsolute))
{
DialogService.InfoBarMessage(Translator.Info_UnsubscribeLinkInvalidTitle, Translator.Info_UnsubscribeLinkInvalidMessage, InfoBarMessageType.Error);
return;
}
if (Uri.IsWellFormedUriString(CurrentRenderModel.UnsubscribeLink, UriKind.RelativeOrAbsolute))
await NativeAppService.LaunchUriAsync(new Uri((CurrentRenderModel.UnsubscribeLink)));
else
DialogService.InfoBarMessage(Translator.Info_UnsubscribeLinkInvalidTitle, Translator.Info_UnsubscribeLinkInvalidMessage, InfoBarMessageType.Error);
// Support for List-Unsubscribe-Post header. It can be done without launching browser.
// https://datatracker.ietf.org/doc/html/rfc8058
if (CurrentRenderModel.UnsubscribeInfo.IsOneClick)
{
confirmed = await DialogService.ShowConfirmationDialogAsync(string.Format(Translator.DialogMessage_UnsubscribeConfirmationOneClickMessage, FromName), Translator.DialogMessage_UnsubscribeConfirmationTitle, Translator.Unsubscribe);
if (!confirmed) return;
using var httpClient = new HttpClient();
var unsubscribeRequest = new HttpRequestMessage(HttpMethod.Post, CurrentRenderModel.UnsubscribeInfo.HttpLink)
{
Content = new StringContent("List-Unsubscribe=One-Click", Encoding.UTF8, "application/x-www-form-urlencoded")
};
var result = await httpClient.SendAsync(unsubscribeRequest);
if (result.IsSuccessStatusCode)
{
DialogService.InfoBarMessage(Translator.Unsubscribe, string.Format(Translator.Info_UnsubscribeSuccessMessage, FromName), InfoBarMessageType.Success);
}
else
{
DialogService.InfoBarMessage(Translator.GeneralTitle_Error, Translator.Info_UnsubscribeErrorMessage, InfoBarMessageType.Error);
}
}
else
{
confirmed = await DialogService.ShowConfirmationDialogAsync(string.Format(Translator.DialogMessage_UnsubscribeConfirmationGoToWebsiteMessage, FromName), Translator.DialogMessage_UnsubscribeConfirmationTitle, Translator.DialogMessage_UnsubscribeConfirmationGoToWebsiteConfirmButton);
if (!confirmed) return;
await NativeAppService.LaunchUriAsync(new Uri(CurrentRenderModel.UnsubscribeInfo.HttpLink));
}
}
else if (CurrentRenderModel.UnsubscribeInfo.MailToLink is not null)
{
confirmed = await DialogService.ShowConfirmationDialogAsync(string.Format(Translator.DialogMessage_UnsubscribeConfirmationMailtoMessage, FromName, new string(CurrentRenderModel.UnsubscribeInfo.MailToLink.Skip(7).ToArray())), Translator.DialogMessage_UnsubscribeConfirmationTitle, Translator.Unsubscribe);
if (!confirmed) return;
// TODO:Implement mailto link support.
DialogService.InfoBarMessage(Translator.GeneralTitle_Error, "Mailto unsubscribe is not supported yet.", InfoBarMessageType.Error);
}
}
[RelayCommand]