Max Mannstein 4478fa2457 Update visual assets and refactor codebase
This commit includes a complete replacement of the binary content of the image files, significantly updating the visual assets of the application to enhance user experience and align with new design standards.

Key changes include:
- Resetting session state for the subscription offer popup in `App.xaml.cs`.
- Replacing buttons with touch-friendly labels in `Step2ExternalControl.xaml` and `Step3Control.xaml`.
- Updating image sources and bindings in `WalkerListControl.xaml` to reflect premium subscription status.
- Adding a new converter class `PremiumToChatImageConverter` in `CommonConverters.cs`.
- Modifying various view models to manage premium user status and subscription offers.
- Enhancing UI layouts across multiple XAML files for improved visibility and functionality.
- Updating localized strings in `Text.Designer.cs` and incrementing the app version in `Info.plist`.

These changes aim to improve the overall functionality, maintainability, and user experience of the application.
2025-07-01 15:53:21 +02:00

819 lines
30 KiB
C#

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.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;
/// <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)
{
_walkService = walkService;
_bannerService = bannerService;
_dialogService = dialogService;
_dogWalkerService = dogWalkerService;
_dispatcher = dispatcher;
_userService = userService;
_favouriteService = favouriteService;
_conversationService = conversationService;
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;
[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);
}
Walkers = requests.Value.ToObservableCollection();
_total = requests.Total;
_skip = requests.Skip + requests.Take;
}
else
{
_total = 0;
_skip = 0;
Walkers = null;
}
}
catch (Exception ex)
{
await TrackErrorAsync(ex, true);
_total = 0;
_skip = 0;
Walkers = 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 popup = new AGBUpdatePopup();
var result = await Shell.Current.CurrentPage.ShowPopupAsync(popup);
// Nach dem Schließen des Popups prüfen wir erneut
if (result is bool accepted && accepted)
{
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 popup = new SubscriptionOfferPopup();
var result = await Shell.Current.CurrentPage.ShowPopupAsync(popup);
// Markiere als in dieser Session gezeigt
UserPreferencesService.MarkSubscriptionOfferShownThisSession();
// Erhöhe den Counter, unabhängig davon ob das Popup angenommen oder abgelehnt wurde
UserPreferencesService.IncreaseSubscriptionOfferPopupCount();
}
}
#endregion
}
}