867 lines
32 KiB
C#

using CommunityToolkit.Maui;
using CommunityToolkit.Maui.Core;
using CommunityToolkit.Maui.Core.Extensions;
using CommunityToolkit.Maui.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using gehGassi.Dto;
using gehGassi.Dto.Common;
using gehGassi.Dto.DogWalkers;
using gehGassiApp.Core.Interfaces;
using gehGassiApp.Core.Messaging;
using gehGassiApp.Domain.Banners;
using gehGassiApp.Domain.Common;
using gehGassiApp.Domain.Lookup;
using gehGassiApp.Domain.Walks;
using gehGassiApp.Helper;
using gehGassiApp.Models.PopupResults;
using gehGassiApp.Resources;
using gehGassiApp.Services;
using gehGassiApp.Views;
using gehGassiApp.Views.Messages;
using gehGassiApp.Views.Popups;
using gehGassiApp.Views.Report;
using gehGassiApp.Views.Walkers;
using gehGassiApp.Views.Walks;
using System.Collections.ObjectModel;
namespace gehGassiApp.ViewModels
{
/// <summary>
/// Viewmodel für den Home-Screen
/// </summary>
public partial class HomeViewModel : MenuViewModel
{
private readonly IWalkService _walkService;
private readonly IBannerService _bannerService;
private readonly IDialogService _dialogService;
private readonly IDogWalkerService _dogWalkerService;
private readonly IDispatcher _dispatcher;
private readonly IUserService _userService;
private readonly IFavouriteService _favouriteService;
private readonly IConversationService _conversationService;
private readonly IPopupService _popupService;
/// <summary>
/// Hilfsvariable: max. Anzahl verfügbare Walker
/// </summary>
private int _total;
/// <summary>
/// Hilfsvariable: wie viele schon geladen?
/// </summary>
private int _skip;
/// <summary>
/// Hilfsvariable: wie viele auf einmal laden?
/// </summary>
private const int _take = Core.Common.Constants.ListPageSizeDefault;
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="walkService">Instanz eines IWalkService</param>
/// <param name="bannerService">Instanz eines IBannerService</param>
/// <param name="dialogService">Instanz eines IDialogService</param>
/// <param name="dogWalkerService">Instanz eines IDogWalkerService</param>
/// <param name="dispatcher">Instanz eines IDispatcher</param>
/// <param name="userService">Instanz eines IUserService</param>
/// <param name="favouriteService">Instanz eines IFavouriteService</param>
public HomeViewModel(IWalkService walkService, IBannerService bannerService, IDialogService dialogService, IDogWalkerService dogWalkerService, IDispatcher dispatcher, IUserService userService, IFavouriteService favouriteService, IConversationService conversationService, IPopupService popupService)
{
_walkService = walkService;
_bannerService = bannerService;
_dialogService = dialogService;
_dogWalkerService = dogWalkerService;
_dispatcher = dispatcher;
_userService = userService;
_favouriteService = favouriteService;
_conversationService = conversationService;
_popupService = popupService;
Title = Text.View_Title_Home;
SelectedMenu = MenuSelected.Home;
NextWalk = null;
HasNextWalk = false;
HasNotNextWalk = false;
Walkers = new ObservableCollection<DogWalkerLookup>();
BannerMargin = new Thickness(0, 0, 0, 0);
ListMargin = new Thickness(0, 0, 0, 12);
_showAppModeNext = null;
//Event wenn Refresh für diesen View gesetzt werden soll
if (WeakReferenceMessenger.Default.IsRegistered<RefreshViewModelMessage>(this) == false)
WeakReferenceMessenger.Default.Register<RefreshViewModelMessage>(this, (recipient, message) =>
{
if (message.Value is Core.Messaging.Messages.Refresh_Home or Core.Messaging.Messages.Refresh_All)
{
_refresh = true;
}
});
}
private DateTimeOffset? _showAppModeNext;
[ObservableProperty]
private WalkWithNames _nextWalk;
[ObservableProperty]
private bool _hasNextWalk;
[ObservableProperty]
private bool _hasNotNextWalk;
[ObservableProperty]
private ObservableCollection<DogWalkerLookup> _walkers;
/// <summary>
/// First 10 walkers for the home screen display
/// </summary>
[ObservableProperty]
private ObservableCollection<DogWalkerLookup> _first10Walkers;
[ObservableProperty]
private DogWalkerLookup _selectedWalker;
[ObservableProperty]
private bool _walkersRefreshing;
[ObservableProperty]
private Banner _banner;
[ObservableProperty]
private bool _hasBanner;
[ObservableProperty]
private ObservableCollection<WalkWithNames> _nextWalks;
[ObservableProperty]
private double _nextWalkWidth;
[ObservableProperty]
private double _refreshGridHeight;
[ObservableProperty]
private Thickness _bannerMargin;
[ObservableProperty]
private Thickness _listMargin;
#region Commands
/// <summary>
/// Command zum Neuladen der Walkers
/// </summary>
/// <returns>Task</returns>
[RelayCommand]
public async Task RefreshWalkers()
{
WalkersRefreshing = true;
IsBusy = true;
_total = 0;
_skip = 0;
SelectedWalker = null;
Walkers = null;
await LoadWalkersAsync();
IsBusy = false;
WalkersRefreshing = false;
}
/// <summary>
/// Command für das Anzeigen eines Banner-Links
/// </summary>
[RelayCommand]
public async Task ShowBanner()
{
if (IsBusy)
return;
try
{
if (Banner != null && !string.IsNullOrWhiteSpace(Banner.Url))
{
using var cts = new CancellationTokenSource(Core.Common.Constants.BannerTimeout);
await _bannerService.AddClicksAsync(Banner.Id, 1, App.AppMode, CurrentLocation, SelectedLanguage, App.CurrentUser.AccessToken, cts.Token);
IsBusy = true;
var uri = new Uri(Banner.Url);
await Browser.Default.OpenAsync(uri, BrowserLaunchMode.SystemPreferred);
}
}
catch
{
// An unexpected error occured. No browser may be installed on the device.
}
finally
{
IsBusy = false;
}
}
/// <summary>
/// Command für das erstellen einer öffentlichen Anfrage
/// </summary>
/// <returns></returns>
[RelayCommand]
public async Task CreatePublicWalkRequest()
{
if (IsBusy)
return;
WeakReferenceMessenger.Default.Send(new RefreshViewModelMessage(Core.Messaging.Messages.Refresh_PublicWalkRequest));
await Shell.Current.GoToAsync($"{nameof(PublicWalkRequestCreateView)}", Core.Common.Constants.AnimateNavigation);
}
/// <summary>
/// Command für die Auswahl eines Walks
/// </summary>
/// <returns></returns>
[RelayCommand]
public async Task WalkSelected()
{
if (IsBusy)
return;
if (NextWalk != null)
{
var menu = MenuSelected.HomeWalker.ToString();
WeakReferenceMessenger.Default.Send(new RefreshViewModelMessage(Core.Messaging.Messages.Refresh_Walk));
await Shell.Current.GoToAsync($"{nameof(WalkView)}?id={NextWalk.Id}&menu={menu}", Core.Common.Constants.AnimateNavigation);
}
}
/// <summary>
/// Command für die Auswahl eines Walks
/// </summary>
/// <returns></returns>
[RelayCommand]
public async Task NextWalkSelected(string id)
{
if (IsBusy)
return;
var menu = MenuSelected.HomeWalker.ToString();
WeakReferenceMessenger.Default.Send(new RefreshViewModelMessage(Core.Messaging.Messages.Refresh_Walk));
await Shell.Current.GoToAsync($"{nameof(WalkView)}?id={id}&menu={menu}", Core.Common.Constants.AnimateNavigation);
}
/// <summary>
/// Command für die Auswahl eines Walkers
/// </summary>
/// <returns></returns>
[RelayCommand]
public async Task WalkerSelected(DogWalkerLookup value)
{
if (IsBusy || value == null)
return;
SelectedWalker = value;
var id = SelectedWalker.Id;
var menu = MenuSelected.Home.ToString();
await Shell.Current.GoToAsync($"{nameof(WalkerView)}?id={id}&menu={menu}", Core.Common.Constants.AnimateNavigation);
SelectedWalker = null;
}
/// <summary>
/// Command für das Anlegen einer Konversation.
/// Sollte bereits eine existieren, dann nur das Wechseln zu den Nachrichten
/// </summary>
/// <returns>Task</returns>
[RelayCommand]
public async Task CreateConversation(DogWalkerLookup SelectedAppUser)
{
IsBusy = true;
using var cts = new CancellationTokenSource(Core.Common.Constants.ListTimeout);
var existingConversation = await _conversationService.GetByReceipientAsync(App.CurrentAppUser.Id, SelectedAppUser.Id, App.CurrentUser.AccessToken, cts.Token);
if (existingConversation == null)
{
//Konversation anlegen
var result = await _conversationService.CreateAsync(App.CurrentAppUser.Id, SelectedAppUser.Id, App.CurrentUser.AccessToken, cts.Token);
if (result.Success)
existingConversation = result.Value;
else
{
if (result.ErrorCode == CommunicationErrors.ServerNoConnection)
{
var options = ResourceHelper.GetSnackbarAlertOptions();
await _dialogService.SnackBarAsync(Text.Err_Conversation_NotOnline, null, Text.Button_Ok, TimeSpan.FromSeconds(10), options, SnackbarAnchor);
//SelectedAppUser = null;
}
}
}
IsBusy = false;
if (existingConversation != null)
{
var stackCount = Shell.Current.Navigation.NavigationStack.Count;
if (stackCount > 1)
{
if (DeviceInfo.Platform == DevicePlatform.Android)
await Shell.Current.Navigation.PopToRootAsync();
}
#if IOS
await Shell.Current.GoToAsync($"//{nameof(ConversationsView)}/{nameof(MessagesIosView)}?cid={existingConversation.Id}&name={existingConversation.RecipientName}", Core.Common.Constants.AnimateNavigation);
#else
await Shell.Current.GoToAsync($"//{nameof(ConversationsView)}/{nameof(MessagesView)}?cid={existingConversation.Id}&name={existingConversation.RecipientName}", Core.Common.Constants.AnimateNavigation);
#endif
}
}
/// <summary>
/// Command für das Laden weiterer Listungen
/// </summary>
[RelayCommand]
public async Task LoadMore()
{
if (Walkers != null && Walkers.Count < _total && !IsBusy)
{
try
{
IsBusy = true;
//var sortOrders = new List<DynamicSortOrder>() { new() { Property = "UpdatedAt", SortDirection = SortDirection.Descending } };
var query = CreateQuery();
using var cts = new CancellationTokenSource(Core.Common.Constants.ListTimeout);
var requestsResult = await _dogWalkerService.GetDogWalkersLookupAsync(query, CurrentLocation, App.CurrentUser.AccessToken, cts.Token);
if (requestsResult.Success)
{
foreach (var request in requestsResult.Value)
{
if (CurrentLocation.Lat != null && CurrentLocation.Lng != null)
request.Distance = Location.CalculateDistance(CurrentLocation.Lat.Value, CurrentLocation.Lng.Value, request.Lat, request.Lng, DistanceUnits.Kilometers);
Walkers.Add(request);
}
}
_total = requestsResult.Total;
_skip = requestsResult.Skip + requestsResult.Take;
IsBusy = false;
}
catch (Exception ex)
{
await TrackErrorAsync(ex, true);
}
finally
{
IsBusy = false;
}
}
}
/// <summary>
/// Command für das Blockieren eines Walkers
/// </summary>
/// <returns></returns>
[RelayCommand]
public async Task Block(DogWalkerLookup value)
{
if (IsBusy || value == null)
return;
var doBlock = await _dialogService.ShowAlertAsync(Text.Block_User_Title, Text.Block_User_Desc, Text.Common_Yes, Text.Common_No);
if (doBlock)
{
IsBusy = true;
try
{
using var cts = new CancellationTokenSource(Core.Common.Constants.CreateTimeout);
var result = await _userService.BlockAppUserAsync(App.CurrentAppUser.Id, value.Id, App.CurrentUser.AccessToken, cts.Token);
if (result.Success && result.Value)
{
var isFavourite = await _favouriteService.IsFavouriteLocalAsync(value.Id, Core.Common.Constants.FavouriteCategory_Walker);
if (isFavourite)
await _favouriteService.ToggleAsync(value.Id, Core.Common.Constants.FavouriteCategory_Walker, App.CurrentAppUser.Id, App.CurrentUser.AccessToken, cts.Token);
_total = 0;
_skip = 0;
SelectedWalker = null;
Walkers = null;
HasNextWalk = false;
HasNotNextWalk = false;
NextWalks = null;
NextWalk = null;
await LoadNextWalksAsync();
await LoadWalkersAsync();
}
}
catch (Exception ex)
{
await TrackErrorAsync(ex, true);
}
finally
{
IsBusy = false;
}
}
}
/// <summary>
/// Command für das Melden eines Benutzers
/// </summary>
/// <returns></returns>
[RelayCommand]
public async Task Report(DogWalkerLookup value)
{
if (IsBusy || value == null)
return;
var reportedAppUserId = value.Id;
var section = AppUserReportSection.HomeDogOwner;
var sectionId = value.Id;
var sectionId2 = string.Empty;
var backToHome = false;
var menu = MenuSelected.Home.ToString();
await Shell.Current.GoToAsync($"{nameof(ReportView)}?reportedAppUserId={reportedAppUserId}&section={section}&sectionId={sectionId}&sectionId2={sectionId2}&backToHome={backToHome}&menu={menu}", Core.Common.Constants.AnimateNavigation);
}
#endregion
/// <summary>
/// Laden der initialen Daten
/// </summary>
/// <returns>Task</returns>
private async Task LoadAsync()
{
IsBusy = true;
CheckIsPremiumUser();
//await LoadNextWalkAsync();
await LoadNextWalksAsync();
await LoadWalkersAsync();
await LoadBannerAsync();
if (_showAppModeNext == null || _showAppModeNext < DateTimeOffset.UtcNow)
{
if (CurrentAppUser.Type == AppUserType.Both && App.AppMode == AppMode.DogOwner)
await _dialogService.ToastAsync(Resources.Text.AppMode_Note + " " + Resources.Text.Enum_AppMode_DogOwner, ToastDuration.Short, 14);
else if (CurrentAppUser.Type == AppUserType.Both && App.AppMode == AppMode.DogWalker)
await _dialogService.ToastAsync(Resources.Text.AppMode_Note + " " + Resources.Text.Enum_AppMode_DogWalker, ToastDuration.Short, 14);
_showAppModeNext = DateTimeOffset.UtcNow.AddHours(1);
}
if (ProfileNotFinished == false && NextWalk == null && (NextWalks == null || NextWalks.Count == 0))
BannerMargin = new Thickness(0, 0, 0, 0);
else
BannerMargin = new Thickness(0, 24, 0, 0);
if (ProfileNotFinished == false && Banner == null && NextWalk == null && (NextWalks == null || NextWalks.Count == 0))
ListMargin = new Thickness(0, 0, 0, 12);
else
ListMargin = new Thickness(0, 40, 0, 12);
IsBusy = false;
}
/// <summary>
/// Laden des nächsten Walks
/// </summary>
/// <returns>Task</returns>
private async Task LoadNextWalkAsync()
{
try
{
using var cts = new CancellationTokenSource(Core.Common.Constants.ListTimeout);
var nextWalkResult = await _walkService.GetNextWalkForOwnerAsync(App.CurrentAppUser.Id, DateTimeOffset.UtcNow, SelectedLanguage, App.AppMode, CurrentLocation, App.CurrentUser.AccessToken, cts.Token);
NextWalk = nextWalkResult.Value;
HasNextWalk = NextWalk != null;
HasNotNextWalk = !HasNextWalk;
}
catch (Exception ex)
{
await TrackErrorAsync(ex, true);
HasNextWalk = false;
HasNotNextWalk = true;
NextWalk = null;
}
}
/// <summary>
/// Laden eines Banners wenn verfügbar
/// </summary>
/// <returns>Task</returns>
private async Task LoadBannerAsync()
{
try
{
var currentBannerId = string.Empty;
if (Banner != null)
currentBannerId = Banner.Id;
//Banner = null;
HasBanner = false;
using var cts = new CancellationTokenSource(Core.Common.Constants.BannerTimeout);
var bannerResult = await _bannerService.GetForLocationAsync(BannerLocation.Home, currentBannerId, CurrentLocation, App.CurrentUser.AccessToken, App.AppMode, SelectedLanguage, cts.Token);
if (bannerResult.Success)
{
if (Banner != null && !string.IsNullOrWhiteSpace(Banner.Image))
{
if (Banner.Image != bannerResult.Value.Image)
{
Banner = bannerResult.Value;
}
}
else
{
Banner = bannerResult.Value;
}
HasBanner = true;
}
else
{
HasBanner = false;
//Banner = null;
}
}
catch (Exception ex)
{
await TrackErrorAsync(ex, true);
HasBanner = false;
//Banner = null;
}
}
/// <summary>
/// Laden der Walker in der Nähre
/// </summary>
/// <returns>Task</returns>
private async Task LoadWalkersAsync()
{
try
{
var query = CreateQuery();
using var cts = new CancellationTokenSource(Core.Common.Constants.ListTimeout);
var requests = await _dogWalkerService.GetDogWalkersLookupAsync(query, CurrentLocation, App.CurrentUser.AccessToken, cts.Token);
if (requests.Success && requests.Value.Any())
{
foreach (var request in requests.Value)
{
if (CurrentLocation.Lat != null && CurrentLocation.Lng != null)
request.Distance = Location.CalculateDistance(CurrentLocation.Lat.Value, CurrentLocation.Lng.Value, request.Lat, request.Lng, DistanceUnits.Kilometers);
}
// Maximale Entfernung in Kilometern
const double maxDistanceKm = 2.0;
const int minWalkersCount = 10;
// Filtern nach Entfernung (max 2km), dann Sortierung: Bewertung, dann mit Foto, dann Entfernung
var filteredWalkers = requests.Value
.Where(x => x.Distance <= maxDistanceKm)
.OrderByDescending(x => x.AverageRating)
.ThenByDescending(x => !string.IsNullOrWhiteSpace(x.Photo))
.ThenBy(x => x.Distance)
.ToList();
// Falls weniger als 10 Walker in der 1km-Zone, weitere nach Entfernung hinzufügen
if (filteredWalkers.Count < minWalkersCount)
{
var additionalWalkers = requests.Value
.Where(x => x.Distance > maxDistanceKm)
.OrderBy(x => x.Distance)
.Take(minWalkersCount - filteredWalkers.Count);
filteredWalkers.AddRange(additionalWalkers);
}
Walkers = filteredWalkers.ToObservableCollection();
// Set First10Walkers for the home screen display
First10Walkers = filteredWalkers.Take(10).ToObservableCollection();
_total = requests.Total;
_skip = requests.Skip + requests.Take;
}
else
{
_total = 0;
_skip = 0;
Walkers = null;
First10Walkers = null;
}
}
catch (Exception ex)
{
await TrackErrorAsync(ex, true);
_total = 0;
_skip = 0;
Walkers = null;
First10Walkers = null;
}
}
/// <summary>
/// Laden der nächsten Walks
/// </summary>
/// <returns>Task</returns>
private async Task LoadNextWalksAsync()
{
try
{
using var cts = new CancellationTokenSource(Core.Common.Constants.ListTimeout);
var requests = await _walkService.GetNextWalksOwnerAsync(App.CurrentAppUser.Id, DateTimeOffset.UtcNow, SelectedLanguage, 100, 0, App.CurrentUser.AccessToken, cts.Token);
if (requests.Success && requests.Value.Any())
{
foreach (var request in requests.Value)
{
if (CurrentLocation.Lat != null && CurrentLocation.Lng != null)
{
request.DistancePickup = Location.CalculateDistance(CurrentLocation.Lat.Value, CurrentLocation.Lng.Value, request.PickupAddressLat, request.PickupAddressLng, DistanceUnits.Kilometers);
request.DistanceReturn = Location.CalculateDistance(CurrentLocation.Lat.Value, CurrentLocation.Lng.Value, request.ReturnAddressLat, request.ReturnAddressLng, DistanceUnits.Kilometers);
}
if (request.BlockedOrLocked)
{
}
}
NextWalks = requests.Value.ToObservableCollection();
if (NextWalks.Count == 1)
{
HasNextWalk = true;
NextWalk = NextWalks.FirstOrDefault();
}
else
{
HasNextWalk = false;
NextWalk = null;
}
}
else
{
HasNextWalk = false;
NextWalks = null;
}
}
catch (Exception ex)
{
await TrackErrorAsync(ex, true);
HasNextWalk = false;
NextWalks = null;
}
}
#region Initialize
/// <summary>
/// Initialisieren des Viewmodels.
/// Soll überschrieben werden um lazy loading in Viewmodels ermöglicht wird
/// </summary>
/// <returns>Task</returns>
public override async Task InitializeAsync(object sender)
{
await base.InitializeAsync(sender);
IsBusy = false;
HasError = false;
ErrorMessage = string.Empty;
await TrackPageViewAsync("HomeDogOwner");
if (_refresh)
{
IsBusy = true;
_total = 0;
_skip = 0;
try
{
HasBanner = false;
//Banner = null;
}
catch (Exception ex)
{
await TrackErrorAsync(ex, true);
HasBanner = false;
//Banner = null;
}
HasNextWalk = false;
HasNotNextWalk = false;
if (LocationPermissionStatus == PermissionStatus.Unknown || LocationPermissionStatus == PermissionStatus.Denied || LocationPermissionStatus == PermissionStatus.Disabled)
{
var status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
LocationPermissionStatus = status;
}
NextWalks = null;
NextWalk = null;
SelectedWalker = null;
Walkers = null;
await Task.Delay(Core.Common.Constants.AnimationDelayList);
//await LoadAsync();
//IsBusy = false;
#pragma warning disable CS4014
Task.Run(LoadAsync);
#pragma warning restore CS4014
_refresh = false;
// AGB-Prüfung nach dem Laden der Daten
await CheckAGBAcceptanceAsync();
CheckIsPremiumUser();
// Subscription Offer Popup-Prüfung nach dem Laden der Daten
await CheckSubscriptionOfferAsync();
}
}
/// <summary>
/// Entladen des Viewmodels.
/// Soll überschrieben werden
/// </summary>
/// <returns>Task</returns>
public override Task DisappearingAsync(object sender)
{
IsBusy = false;
HasError = false;
ErrorMessage = string.Empty;
//if(Banner != null)
// Banner.Image = string.Empty;
//Banner = null;
if (Banner == null || string.IsNullOrWhiteSpace(Banner.Image))
HasBanner = false;
//HasBanner = false;
return base.DisappearingAsync(sender);
}
#endregion
#region Resumed
/// <summary>
/// Eventhandler wenn die App aus dem Sleepmode kommt
/// </summary>
/// <returns></returns>
internal override async Task AppResumed()
{
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: AppResumedMessage received");
System.Diagnostics.Debug.WriteLine($"IsMainThread: {MainThread.IsMainThread}");
await _dispatcher.DispatchAsync(async () =>
{
_total = 0;
_skip = 0;
_showAppModeNext = null;
try
{
HasBanner = false;
//Banner = null;
}
catch (Exception ex)
{
await TrackErrorAsync(ex, true);
HasBanner = false;
//Banner = null;
}
HasNextWalk = false;
HasNotNextWalk = false;
IsBusy = true;
NextWalks = null;
NextWalk = null;
SelectedWalker = null;
Walkers = null;
await LoadAsync();
IsBusy = false;
});
}
#endregion
#region private
/// <summary>
/// Erstellt ein Query-Objekt für die Anfrage der Walker
/// </summary>
/// <returns></returns>
private DogWalkerQueryDto CreateQuery()
{
var query = new DogWalkerQueryDto()
{
Skip = _skip,
Take = _take,
Language = SelectedLanguage,
AppMode = (AppModeDto)App.AppMode,
IgnoreId = App.CurrentAppUser.Id,
Name = string.Empty,
City = string.Empty,
Country = string.Empty,
MinRating = 0
};
return query;
} /// <summary>
/// Prüft, ob der Benutzer die AGB akzeptiert hat und zeigt das Popup bei Bedarf an
/// </summary>
/// <returns>Task</returns>
private async Task CheckAGBAcceptanceAsync()
{
// Zeige das Popup nur, wenn der User die AGB noch nicht akzeptiert hat
// UND das Registrierungsdatum vor dem 16.06.2024 liegt
var registrationDate = App.CurrentUser?.RegistrationDate;
var cutoffDate = new DateTime(2024, 6, 16);
if (!UserPreferencesService.HasAcceptedAGB
&& registrationDate != null
&& registrationDate.Value.Date < cutoffDate)
{
var popupResult = await _popupService.ShowPopupAsync<AGBUpdatePopup, AGBUpdateResult>(
Shell.Current
);
// Nach dem Schließen des Popups prüfen wir erneut
var result = popupResult.Result;
if (result != null && result.IsAccepted)
{
UserPreferencesService.HasAcceptedAGB = true;
}
}
} /// <summary>
/// Prüft, ob das Subscription Offer Popup angezeigt werden soll und zeigt es bei Bedarf an
/// </summary>
/// <returns>Task</returns>
private async Task CheckSubscriptionOfferAsync()
{
// Zeige das Popup nur, wenn der User kein Premium-User ist
// UND der Count <= 5 ist und noch nicht in dieser Session gezeigt wurde
if (!IsPremiumUser && UserPreferencesService.ShowSubscriptionOffer)
{
var popupResult = await _popupService.ShowPopupAsync<SubscriptionOfferPopup, SubscriptionOfferResult>(
Shell.Current
);
// Markiere als in dieser Session gezeigt
UserPreferencesService.MarkSubscriptionOfferShownThisSession();
// Erhöhe den Counter, unabhängig davon ob das Popup angenommen oder abgelehnt wurde
UserPreferencesService.IncreaseSubscriptionOfferPopupCount();
// Falls der User das Abo akzeptiert hat, ist Navigation bereits im ViewModel behandelt
var result = popupResult.Result;
if (result != null && result.IsAccepted)
{
// Navigation erfolgt bereits im SubscriptionOfferPopupViewModel
}
}
}
#endregion
}
}