net-9 upgrade v1

This commit is contained in:
Max Mannstein 2025-08-14 10:34:58 +02:00
parent 3b4f83e994
commit 806edf7676
29 changed files with 347 additions and 400 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
gehGassiApp/.DS_Store vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
gehGassiApp/gehGassiApp.Domain/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

View File

@ -387,6 +387,11 @@ public static class MauiProgram
builder.Services.AddTransient<ReportViewModel>();
builder.Services.AddTransient<SubscriptionsViewModel>();
// Popup ViewModels - NEW PATTERN
builder.Services.AddTransientPopup<AGBUpdatePopup, AGBUpdatePopupViewModel>();
builder.Services.AddTransientPopup<SubscriptionOfferPopup, SubscriptionOfferPopupViewModel>();
builder.Services.AddTransientPopup<SubscriptionSuccessPopup, SubscriptionSuccessPopupViewModel>();
#endregion
#region Views

View File

@ -0,0 +1,17 @@
namespace gehGassiApp.Models.PopupResults;
public class AGBUpdateResult
{
public bool IsAccepted { get; set; }
// Factory Methods für bessere Usability
public static AGBUpdateResult Accepted() => new()
{
IsAccepted = true
};
public static AGBUpdateResult Declined() => new()
{
IsAccepted = false
};
}

View File

@ -0,0 +1,17 @@
namespace gehGassiApp.Models.PopupResults;
public class SubscriptionOfferResult
{
public bool IsAccepted { get; set; }
// Factory Methods für bessere Usability
public static SubscriptionOfferResult Accepted() => new()
{
IsAccepted = true
};
public static SubscriptionOfferResult Declined() => new()
{
IsAccepted = false
};
}

View File

@ -0,0 +1,17 @@
namespace gehGassiApp.Models.PopupResults;
public class SubscriptionSuccessResult
{
public bool HasOpenedStrayz { get; set; }
// Factory Methods für bessere Usability
public static SubscriptionSuccessResult StrayzOpened() => new()
{
HasOpenedStrayz = true
};
public static SubscriptionSuccessResult Closed() => new()
{
HasOpenedStrayz = false
};
}

View File

@ -2,6 +2,7 @@
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Gms.Tasks;
using Android.OS;
using Android.Views;
using CommunityToolkit.Mvvm.Messaging;
@ -24,7 +25,7 @@ namespace gehGassiApp;
Android.Content.Intent.CategoryDefault,
Android.Content.Intent.CategoryBrowsable
})]
public class MainActivity : MauiAppCompatActivity, Android.Gms.Tasks.IOnSuccessListener
public class MainActivity : MauiAppCompatActivity, IOnSuccessListener
{
//Service der die Installation des Gerätes am PNS ermöglicht
IDeviceInstallationService _deviceInstallationService;

View File

@ -1,4 +1,5 @@
using CommunityToolkit.Maui.Core;
using CommunityToolkit.Maui;
using CommunityToolkit.Maui.Core;
using CommunityToolkit.Maui.Core.Extensions;
using CommunityToolkit.Maui.Views;
using CommunityToolkit.Mvvm.ComponentModel;
@ -14,6 +15,7 @@ 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;
@ -40,6 +42,7 @@ namespace gehGassiApp.ViewModels
private readonly IUserService _userService;
private readonly IFavouriteService _favouriteService;
private readonly IConversationService _conversationService;
private readonly IPopupService _popupService;
/// <summary>
/// Hilfsvariable: max. Anzahl verfügbare Walker
/// </summary>
@ -64,7 +67,7 @@ namespace gehGassiApp.ViewModels
/// <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)
public HomeViewModel(IWalkService walkService, IBannerService bannerService, IDialogService dialogService, IDogWalkerService dogWalkerService, IDispatcher dispatcher, IUserService userService, IFavouriteService favouriteService, IConversationService conversationService, IPopupService popupService)
{
_walkService = walkService;
_bannerService = bannerService;
@ -74,6 +77,7 @@ namespace gehGassiApp.ViewModels
_userService = userService;
_favouriteService = favouriteService;
_conversationService = conversationService;
_popupService = popupService;
Title = Text.View_Title_Home;
SelectedMenu = MenuSelected.Home;
@ -797,11 +801,13 @@ namespace gehGassiApp.ViewModels
&& registrationDate != null
&& registrationDate.Value.Date < cutoffDate)
{
var popup = new AGBUpdatePopup();
var result = await Shell.Current.CurrentPage.ShowPopupAsync(popup);
var popupResult = await _popupService.ShowPopupAsync<AGBUpdatePopup, AGBUpdateResult>(
Shell.Current
);
// Nach dem Schließen des Popups prüfen wir erneut
if (result is bool accepted && accepted)
var result = popupResult.Result;
if (result != null && result.IsAccepted)
{
UserPreferencesService.HasAcceptedAGB = true;
}
@ -816,14 +822,22 @@ namespace gehGassiApp.ViewModels
// 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);
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
}
}
}

View File

@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
using CommunityToolkit.Maui;
using CommunityToolkit.Maui.Core;
using CommunityToolkit.Maui.Core.Extensions;
using CommunityToolkit.Maui.Views;
@ -10,6 +11,7 @@ using gehGassiApp.Core.Messaging;
using gehGassiApp.Domain.Banners;
using gehGassiApp.Domain.Common;
using gehGassiApp.Domain.Walks;
using gehGassiApp.Models.PopupResults;
using gehGassiApp.Resources;
using gehGassiApp.Services;
using gehGassiApp.Views.Popups;
@ -28,6 +30,7 @@ namespace gehGassiApp.ViewModels
private readonly IDispatcher _dispatcher;
private readonly IUserService _userService;
private readonly IFavouriteService _favouriteService;
private readonly IPopupService _popupService;
/// <summary>
/// Hilfsvariable: max. Anzahl verfügbare öffentlichen Anfragen
@ -55,7 +58,7 @@ namespace gehGassiApp.ViewModels
/// <param name="userService">Instanz eines IUserService</param>
/// <param name="favouriteService">Instanz eines IFavouriteService</param>
public HomeWalkerViewModel(IWalkService walkService, IBannerService bannerService,
IPublicWalkRequestService publicWalkRequestService, IPublicWalkResponseService publicWalkResponseService, IDialogService dialogService, IDispatcher dispatcher, IUserService userService, IFavouriteService favouriteService)
IPublicWalkRequestService publicWalkRequestService, IPublicWalkResponseService publicWalkResponseService, IDialogService dialogService, IDispatcher dispatcher, IUserService userService, IFavouriteService favouriteService, IPopupService popupService)
{
_walkService = walkService;
_bannerService = bannerService;
@ -65,6 +68,7 @@ namespace gehGassiApp.ViewModels
_dispatcher = dispatcher;
_userService = userService;
_favouriteService = favouriteService;
_popupService = popupService;
Title = Text.View_Title_Home;
SelectedMenu = MenuSelected.HomeWalker;
BannerMargin = new Thickness(0, 0, 0, 0);
@ -364,11 +368,13 @@ namespace gehGassiApp.ViewModels
&& registrationDate != null
&& registrationDate.Value.Date < cutoffDate)
{
var popup = new AGBUpdatePopup();
var result = await Shell.Current.CurrentPage.ShowPopupAsync(popup);
var popupResult = await _popupService.ShowPopupAsync<AGBUpdatePopup, AGBUpdateResult>(
Shell.Current
);
// Nach dem Schließen des Popups prüfen wir erneut
if (result is bool accepted && accepted)
var result = popupResult.Result;
if (result != null && result.IsAccepted)
{
UserPreferencesService.HasAcceptedAGB = true;
}

View File

@ -153,35 +153,6 @@ namespace gehGassiApp.ViewModels.Onboarding
//await ShowSubscriptionSuccessPopup();
//await CheckAGBStatus();
}
[RelayCommand]
private async Task CheckAGBStatus()
{
// Prüfe, ob AGB-Popup angezeigt werden muss
if (!AGBUpdatePopupViewModel.HasUserAcceptedCurrentAGB())
{
// Popup und ViewModel erstellen
var popup = new AGBUpdatePopup();
var viewModel = new AGBUpdatePopupViewModel(popup);
popup.BindingContext = viewModel;
// Popup anzeigen und auf Ergebnis warten
var result = await Shell.Current.CurrentPage.ShowPopupAsync(popup);
// result ist true wenn akzeptiert, false wenn abgelehnt
if (result is bool accepted)
{
if (accepted)
{
await Shell.Current.DisplayAlert("Info", "Danke für die Zustimmung!", "OK");
}
else
{
// User hat abgelehnt - weitere Aktionen
await Shell.Current.DisplayAlert("Info", "AGB wurden abgelehnt", "OK");
}
}
}
}
}
public class OnboardingItemViewModel

View File

@ -1,97 +1,109 @@
using CommunityToolkit.Maui.Core;
using CommunityToolkit.Maui;
using CommunityToolkit.Maui.Core;
using CommunityToolkit.Maui.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using gehGassiApp.Models.PopupResults;
using gehGassiApp.Resources;
using gehGassiApp.Services;
using gehGassiApp.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace gehGassiApp.ViewModels.Popups
{ public partial class AGBUpdatePopupViewModel : ObservableObject
namespace gehGassiApp.ViewModels.Popups;
public partial class AGBUpdatePopupViewModel : ObservableObject, IQueryAttributable
{
#region Properties
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(AcceptButtonColor))]
private bool _hasAccepted = false;
// Computed Property für Button-Farbe
readonly IPopupService _popupService;
public Color AcceptButtonColor => HasAccepted ? Color.FromArgb("#2E7D32") : Color.FromArgb("#BDBDBD");
#endregion
#region Constructor
public AGBUpdatePopupViewModel(IPopupService popupService)
{
private readonly Popup _popup;
private const string AGB_URL = "https://gehgassi.app/agb"; // Ersetze mit eurer tatsächlichen AGB-URL
_popupService = popupService;
// Initialisiere die AGB-Status
HasAccepted = HasUserAcceptedCurrentAGB();
}
#endregion
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(AcceptButtonColor))]
private bool _hasAccepted = false;
#region IQueryAttributable Implementation
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
// Falls Parameter benötigt werden, hier implementieren
}
#endregion
// Computed Property für Button-Farbe
public Color AcceptButtonColor => HasAccepted ? Color.FromArgb("#2E7D32") : Color.FromArgb("#BDBDBD");
#region Static Methods
/// <summary>
/// Prüft, ob der User bereits den aktuellen AGB zugestimmt hat
/// </summary>
public static bool HasUserAcceptedCurrentAGB()
{
return UserPreferencesService.HasAcceptedAGB;
}
public AGBUpdatePopupViewModel(Popup popup)
/// <summary>
/// Markiert die aktuellen AGB als vom User akzeptiert
/// </summary>
private static void MarkAGBAsAccepted()
{
UserPreferencesService.HasAcceptedAGB = true;
}
#endregion
#region Commands
/// <summary>
/// Öffnet die vollständigen AGB im Browser
/// </summary>
[RelayCommand]
private async Task OpenAGB()
{
try
{
_popup = popup;
var menu = MenuSelected.More.ToString();
var title = Text.View_Title_Privacy;
await Shell.Current.GoToAsync($"{nameof(ShowTextPageView)}?code={Core.Common.Constants.PagePrivacy}&menu={menu}&title={title}", Core.Common.Constants.AnimateNavigation);
}
/// <summary>
/// Prüft, ob der User bereits den aktuellen AGB zugestimmt hat
/// </summary>
public static bool HasUserAcceptedCurrentAGB()
catch (Exception ex)
{
return UserPreferencesService.HasAcceptedAGB;
}
// Fallback: Zeige Error-Dialog
await Shell.Current.DisplayAlert(
"Fehler",
"Die Nutzungsbedingungen konnten nicht geöffnet werden. Bitte versuchen Sie es später erneut.",
"OK");
/// <summary>
/// Markiert die aktuellen AGB als vom User akzeptiert
/// </summary>
private static void MarkAGBAsAccepted()
{
UserPreferencesService.HasAcceptedAGB = true;
}
/// <summary>
/// Öffnet die vollständigen AGB im Browser
/// </summary>
[RelayCommand]
private async Task OpenAGB()
{
try
{
var menu = MenuSelected.More.ToString();
var title = Text.View_Title_Privacy;
await Shell.Current.GoToAsync($"{nameof(ShowTextPageView)}?code={Core.Common.Constants.PagePrivacy}&menu={menu}&title={title}", Core.Common.Constants.AnimateNavigation);
}
catch (Exception ex)
{
// Fallback: Zeige Error-Dialog
await Shell.Current.DisplayAlert(
"Fehler",
"Die Nutzungsbedingungen konnten nicht geöffnet werden. Bitte versuchen Sie es später erneut.",
"OK");
// Optional: Logging
System.Diagnostics.Debug.WriteLine($"Error opening AGB URL: {ex.Message}");
}
}
/// <summary>
/// User hat die AGB akzeptiert
/// </summary>
[RelayCommand]
private async Task Accept()
{
if (!HasAccepted)
{
await Shell.Current.DisplayAlert(
"Hinweis",
"Bitte bestätige zuerst, dass du die Nutzungsbedingungen gelesen hast und ihnen zustimmst.",
"OK");
return;
}
// AGB als akzeptiert markieren
MarkAGBAsAccepted();
// Popup schließen
await _popup.CloseAsync(true);
// Optional: Logging
System.Diagnostics.Debug.WriteLine($"Error opening AGB URL: {ex.Message}");
}
}
/// <summary>
/// User hat die AGB akzeptiert
/// </summary>
[RelayCommand]
private async Task Accept()
{
if (!HasAccepted)
{
await Shell.Current.DisplayAlert(
"Hinweis",
"Bitte bestätige zuerst, dass du die Nutzungsbedingungen gelesen hast und ihnen zustimmst.",
"OK");
return;
}
// AGB als akzeptiert markieren
MarkAGBAsAccepted();
var result = AGBUpdateResult.Accepted();
// ✅ Toolkit übernimmt das Popup-Closing
await _popupService.ClosePopupAsync(Shell.Current, result);
}
#endregion
}

View File

@ -1,57 +0,0 @@
using CommunityToolkit.Maui.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace gehGassiApp.ViewModels.Popups
{
/// <summary>
/// ViewModel für das Zahlungshinweis-Popup
///
/// Verwendung:
/// // Prüfen ob bereits angezeigt
/// if (!PaymentInfoPopupViewModel.HasInfoBeenShown())
/// {
/// var popup = new PaymentInfoPopup();
/// await Shell.Current.CurrentPage.ShowPopupAsync(popup);
/// }
/// </summary>
public partial class PaymentInfoPopupViewModel : ObservableObject
{
private readonly Popup _popup;
private const string PAYMENT_INFO_SHOWN_KEY = "payment_info_july_shown_2025";
public PaymentInfoPopupViewModel(Popup popup)
{
_popup = popup;
}
/// <summary>
/// Prüft, ob der Zahlungshinweis bereits angezeigt wurde
/// </summary>
public static bool HasInfoBeenShown()
{
return Preferences.Get(PAYMENT_INFO_SHOWN_KEY, false);
}
/// <summary>
/// Markiert den Hinweis als angezeigt
/// </summary>
private static void MarkInfoAsShown()
{
Preferences.Set(PAYMENT_INFO_SHOWN_KEY, true);
}
/// <summary>
/// User hat den Hinweis zur Kenntnis genommen
/// </summary>
[RelayCommand]
private async Task Acknowledge()
{
// Hinweis als angezeigt markieren
MarkInfoAsShown();
// Popup schließen
await _popup.CloseAsync(true);
}
}
}

View File

@ -1,61 +1,58 @@
using CommunityToolkit.Maui.Views;
using CommunityToolkit.Maui;
using CommunityToolkit.Maui.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using gehGassiApp.Models.PopupResults;
using gehGassiApp.Views.Subscriptions;
namespace gehGassiApp.ViewModels.Popups
namespace gehGassiApp.ViewModels.Popups;
public partial class SubscriptionOfferPopupViewModel : ObservableObject, IQueryAttributable
{
public partial class SubscriptionOfferPopupViewModel : ObservableObject
#region Dependencies
private readonly IPopupService _popupService;
#endregion
#region Constructor
public SubscriptionOfferPopupViewModel(IPopupService popupService)
{
private readonly Popup _popup;
private const string SUBSCRIPTION_OFFER_SHOWN_KEY = "subscription_offer_shown_v2025";
public SubscriptionOfferPopupViewModel(Popup popup)
{
_popup = popup;
}
/// <summary>
/// Prüft, ob das Abo-Angebot bereits angezeigt wurde
/// </summary>
public static bool HasOfferBeenShown()
{
return Preferences.Get(SUBSCRIPTION_OFFER_SHOWN_KEY, false);
}
/// <summary>
/// Markiert das Angebot als angezeigt
/// </summary>
private static void MarkOfferAsShown()
{
//Preferences.Set(SUBSCRIPTION_OFFER_SHOWN_KEY, true);
}
/// <summary>
/// User möchte Abo abschließen
/// </summary>
[RelayCommand]
private async Task Accept()
{
// Angebot als angezeigt markieren
MarkOfferAsShown();
// Popup schließen mit true (User will Abo)
await _popup.CloseAsync(true);
await Shell.Current.GoToAsync($"{nameof(SubscriptionsView)}", Core.Common.Constants.AnimateNavigation);
}
/// <summary>
/// User möchte später entscheiden
/// </summary>
[RelayCommand]
private async Task Decline()
{
// Angebot als angezeigt markieren
MarkOfferAsShown();
// Popup schließen mit false (User will kein Abo)
await _popup.CloseAsync(false);
}
_popupService = popupService;
}
#endregion
#region IQueryAttributable Implementation
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
// Falls Parameter benötigt werden, hier implementieren
}
#endregion
#region Commands
/// <summary>
/// User möchte Abo abschließen
/// </summary>
[RelayCommand]
private async Task Accept()
{
var result = SubscriptionOfferResult.Accepted();
// Popup schließen mit Result
await _popupService.ClosePopupAsync(Shell.Current, result);
// Navigation zu Subscriptions
await Shell.Current.GoToAsync($"{nameof(SubscriptionsView)}", Core.Common.Constants.AnimateNavigation);
}
/// <summary>
/// User möchte später entscheiden
/// </summary>
[RelayCommand]
private async Task Decline()
{
var result = SubscriptionOfferResult.Declined();
// Popup schließen mit Result
await _popupService.ClosePopupAsync(Shell.Current, result);
}
#endregion
}

View File

@ -1,53 +1,74 @@
using CommunityToolkit.Maui.Views;
using CommunityToolkit.Maui;
using CommunityToolkit.Maui.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using gehGassiApp.Models.PopupResults;
namespace gehGassiApp.ViewModels.Popups
namespace gehGassiApp.ViewModels.Popups;
public partial class SubscriptionSuccessPopupViewModel : ObservableObject, IQueryAttributable
{
public partial class SubscriptionSuccessPopupViewModel : ObservableObject
#region Constants
private const string STRAYZ_URL = "https://www.strayz.de/pages/fuer-hunde";
#endregion
#region Dependencies
private readonly IPopupService _popupService;
#endregion
#region Constructor
public SubscriptionSuccessPopupViewModel(IPopupService popupService)
{
private readonly Popup _popup;
private const string STRAYZ_URL = "https://www.strayz.de/pages/fuer-hunde"; // Ersetze mit der tatsächlichen STRAYZ-URL
_popupService = popupService;
}
#endregion
#region IQueryAttributable Implementation
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
// Falls Parameter benötigt werden, hier implementieren
}
#endregion
public SubscriptionSuccessPopupViewModel(Popup popup)
#region Commands
/// <summary>
/// Öffnet die STRAYZ-Partnerseite
/// </summary>
[RelayCommand]
private async Task OpenStrayz()
{
try
{
_popup = popup;
// Öffne STRAYZ-Seite im Browser
await Browser.OpenAsync(STRAYZ_URL, BrowserLaunchMode.External);
var result = SubscriptionSuccessResult.StrayzOpened();
// Popup schließen mit Result
await _popupService.ClosePopupAsync(Shell.Current, result);
}
/// <summary>
/// Öffnet die STRAYZ-Partnerseite
/// </summary>
[RelayCommand]
private async Task OpenStrayz()
catch (Exception ex)
{
try
{
// Öffne STRAYZ-Seite im Browser
await Browser.OpenAsync(STRAYZ_URL, BrowserLaunchMode.External);
// Fehlerbehandlung
await Shell.Current.DisplayAlert(
"Fehler",
"Die STRAYZ-Seite konnte nicht geöffnet werden. Bitte versuche es später erneut oder besuche strayz.de direkt.",
"OK");
// Popup schließen
await _popup.CloseAsync(true);
}
catch (Exception ex)
{
// Fehlerbehandlung
await Shell.Current.DisplayAlert(
"Fehler",
"Die STRAYZ-Seite konnte nicht geöffnet werden. Bitte versuche es später erneut oder besuche strayz.de direkt.",
"OK");
System.Diagnostics.Debug.WriteLine($"Error opening STRAYZ URL: {ex.Message}");
}
}
/// <summary>
/// Popup schließen ohne STRAYZ zu öffnen
/// </summary>
[RelayCommand]
private async Task Close()
{
await _popup.CloseAsync(false);
System.Diagnostics.Debug.WriteLine($"Error opening STRAYZ URL: {ex.Message}");
}
}
/// <summary>
/// Popup schließen ohne STRAYZ zu öffnen
/// </summary>
[RelayCommand]
private async Task Close()
{
var result = SubscriptionSuccessResult.Closed();
// Popup schließen mit Result
await _popupService.ClosePopupAsync(Shell.Current, result);
}
#endregion
}

View File

@ -1,3 +1,4 @@
using CommunityToolkit.Maui;
using CommunityToolkit.Maui.Core.Extensions;
using CommunityToolkit.Maui.Views;
using CommunityToolkit.Mvvm.ComponentModel;
@ -8,6 +9,7 @@ using gehGassiApp.Core.Messaging;
using gehGassiApp.Domain.Common;
using gehGassiApp.Domain.Subscriptions;
using gehGassiApp.Models;
using gehGassiApp.Models.PopupResults;
using gehGassiApp.Resources;
using gehGassiApp.Services;
using gehGassiApp.Views;
@ -30,6 +32,7 @@ namespace gehGassiApp.ViewModels.Subscriptions
private readonly ISubscriptionValidationService _subscriptionValidationService;
private readonly IDispatcher _dispatcher;
private readonly IDialogService _dialogService;
private readonly IPopupService _popupService;
/// <summary>
/// ERstellt eine Instanz
@ -38,12 +41,13 @@ namespace gehGassiApp.ViewModels.Subscriptions
/// <param name="subscriptionValidationService">Instanz eines ISubscriptionValidationService</param>
/// <param name="dispatcher">Instanz eines IDispatcher</param>
/// <param name="dialogService">Instanz eines IDialogService</param>
public SubscriptionsViewModel(ISubscriptionService subscriptionService, ISubscriptionValidationService subscriptionValidationService, IDispatcher dispatcher, IDialogService dialogService)
public SubscriptionsViewModel(ISubscriptionService subscriptionService, ISubscriptionValidationService subscriptionValidationService, IDispatcher dispatcher, IDialogService dialogService, IPopupService popupService)
{
_subscriptionService = subscriptionService;
_subscriptionValidationService = subscriptionValidationService;
_dispatcher = dispatcher;
_dialogService = dialogService;
_popupService = popupService;
Title = Text.View_Title_Subscriptions;
SelectedMenu = MenuSelected.More;
@ -205,8 +209,15 @@ namespace gehGassiApp.ViewModels.Subscriptions
await LoadAsync();
if (MySubscriptions != null && MySubscriptions.Any())
{
var popup = new SubscriptionSuccessPopup();
await Shell.Current.CurrentPage.ShowPopupAsync(popup);
var popupResult = await _popupService.ShowPopupAsync<SubscriptionSuccessPopup, SubscriptionSuccessResult>(
Shell.Current
);
var result = popupResult.Result;
if (result != null && result.HasOpenedStrayz)
{
// User hat STRAYZ geöffnet
}
}
}
else
@ -425,8 +436,15 @@ namespace gehGassiApp.ViewModels.Subscriptions
IsBusy = false;
if (MySubscriptions != null && MySubscriptions.Any())
{
var popup = new SubscriptionSuccessPopup();
await Shell.Current.CurrentPage.ShowPopupAsync(popup);
var popupResult = await _popupService.ShowPopupAsync<SubscriptionSuccessPopup, SubscriptionSuccessResult>(
Shell.Current
);
var result = popupResult.Result;
if (result != null && result.HasOpenedStrayz)
{
// User hat STRAYZ geöffnet
}
}
}

View File

@ -5,8 +5,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:res="clr-namespace:gehGassiApp.Resources"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
CanBeDismissedByTappingOutsideOfPopup="False"
Color="Transparent">
xmlns:viewModels="clr-namespace:gehGassiApp.ViewModels.Popups"
x:DataType="viewModels:AGBUpdatePopupViewModel"
CanBeDismissedByTappingOutsideOfPopup="False">
<!-- Popup Content -->
<Border
Padding="0"

View File

@ -5,9 +5,9 @@ namespace gehGassiApp.Views.Popups;
public partial class AGBUpdatePopup : Popup
{
public AGBUpdatePopup()
public AGBUpdatePopup(AGBUpdatePopupViewModel viewModel)
{
InitializeComponent();
BindingContext = new AGBUpdatePopupViewModel(this);
BindingContext = viewModel;
}
}

View File

@ -1,98 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<toolkit:Popup
x:Class="gehGassiApp.Views.Popups.PaymentInfoPopup"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:res="clr-namespace:gehGassiApp.Resources"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
CanBeDismissedByTappingOutsideOfPopup="True"
Color="Transparent">
<!-- Popup Content -->
<Border
Padding="0"
BackgroundColor="White"
StrokeShape="RoundRectangle 16"
StrokeThickness="0"
WidthRequest="350">
<!-- Drop Shadow Effect -->
<Border.Shadow>
<Shadow
Brush="{AppThemeBinding Light={StaticResource Grey_Dark},
Dark={StaticResource Grey_Dark_Dark}}"
Opacity="0.3"
Radius="8"
Offset="0,4" />
</Border.Shadow>
<Grid RowDefinitions="Auto,Auto,Auto">
<!-- Header -->
<Border
Grid.Row="0"
Padding="20,16"
BackgroundColor="{AppThemeBinding Light={StaticResource Primary_DarkBlue},
Dark={StaticResource Primary_DarkBlue_Dark}}"
StrokeShape="RoundRectangle 16,16,0,0"
StrokeThickness="0">
<Label
Style="{StaticResource H4}"
Text="Zahlungshinweis"
TextColor="{AppThemeBinding Light={StaticResource Primary_White},
Dark={StaticResource Primary_White_Dark}}"
VerticalOptions="Center" />
</Border>
<!-- Content Bereich -->
<VerticalStackLayout
Grid.Row="1"
Padding="20,20"
Spacing="16">
<!-- Info Icon -->
<Label
FontFamily="MaterialIconsRegular"
FontSize="48"
HorizontalOptions="Center"
Text="info"
TextColor="{AppThemeBinding Light={StaticResource Primary_DarkBlue},
Dark={StaticResource Primary_DarkBlue_Dark}}" />
<!-- Info Text -->
<Label
HorizontalTextAlignment="Center"
LineHeight="1.4"
Style="{StaticResource BodyM}"
Text="Leider sind diese Funktionen im Juli nicht verfügbar. Wir arbeiten aber fleißig an einer Lösung."
TextColor="{AppThemeBinding Light={StaticResource Grey_Dark},
Dark={StaticResource Grey_Dark_Dark}}" />
<!-- Additional Info -->
<Label
HorizontalTextAlignment="Center"
LineHeight="1.4"
Style="{StaticResource BodyM}"
Text="Im Juli sind nur Barzahlungen verfügbar."
TextColor="{AppThemeBinding Light={StaticResource Primary_DarkBlue},
Dark={StaticResource Primary_DarkBlue_Dark}}"
FontAttributes="Bold" />
</VerticalStackLayout>
<!-- Action Button -->
<Button
Grid.Row="2"
Margin="20,0,20,20"
BackgroundColor="{AppThemeBinding Light={StaticResource Primary_DarkBlue},
Dark={StaticResource Primary_DarkBlue_Dark}}"
Command="{Binding AcknowledgeCommand}"
CornerRadius="12"
FontAttributes="Bold"
FontSize="{StaticResource FontLabelM}"
Text="Verstanden"
TextColor="White" />
</Grid>
</Border>
</toolkit:Popup>

View File

@ -1,13 +0,0 @@
using CommunityToolkit.Maui.Views;
using gehGassiApp.ViewModels.Popups;
namespace gehGassiApp.Views.Popups;
public partial class PaymentInfoPopup : Popup
{
public PaymentInfoPopup()
{
InitializeComponent();
BindingContext = new PaymentInfoPopupViewModel(this);
}
}

View File

@ -5,8 +5,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:res="clr-namespace:gehGassiApp.Resources"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
CanBeDismissedByTappingOutsideOfPopup="True"
Color="Transparent">
xmlns:viewModels="clr-namespace:gehGassiApp.ViewModels.Popups"
x:DataType="viewModels:SubscriptionOfferPopupViewModel"
CanBeDismissedByTappingOutsideOfPopup="True">
<!-- Popup Content -->
<Border

View File

@ -5,9 +5,9 @@ namespace gehGassiApp.Views.Popups;
public partial class SubscriptionOfferPopup : Popup
{
public SubscriptionOfferPopup()
public SubscriptionOfferPopup(SubscriptionOfferPopupViewModel viewModel)
{
InitializeComponent();
BindingContext = new SubscriptionOfferPopupViewModel(this);
BindingContext = viewModel;
}
}

View File

@ -5,9 +5,10 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:res="clr-namespace:gehGassiApp.Resources"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:viewModels="clr-namespace:gehGassiApp.ViewModels.Popups"
x:DataType="viewModels:SubscriptionSuccessPopupViewModel"
CanBeDismissedByTappingOutsideOfPopup="True"
VerticalOptions="Center"
Color="Transparent">
VerticalOptions="Center">
<!-- Popup Content -->
<Border

View File

@ -5,9 +5,9 @@ namespace gehGassiApp.Views.Popups;
public partial class SubscriptionSuccessPopup : Popup
{
public SubscriptionSuccessPopup()
public SubscriptionSuccessPopup(SubscriptionSuccessPopupViewModel viewModel)
{
InitializeComponent();
BindingContext = new SubscriptionSuccessPopupViewModel(this);
BindingContext = viewModel;
}
}

View File

@ -705,9 +705,28 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0-android'">
<PackageReference Include="Xamarin.AndroidX.Lifecycle.Runtime.Ktx" Version="2.9.1" />
<PackageReference Include="Xamarin.AndroidX.Lifecycle.Runtime.Ktx.Android" Version="2.9.1" />
<PackageReference Include="Xamarin.AndroidX.SavedState" Version="1.3.1" />
<PackageReference Include="Xamarin.AndroidX.SavedState.SavedState.Ktx" Version="1.3.1" />
<PackageReference Include="Xamarin.AndroidX.Activity.Ktx">
<Version>1.10.1.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.Lifecycle.Common">
<Version>2.9.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.Lifecycle.Runtime">
<Version>2.9.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.Lifecycle.ViewModel">
<Version>2.9.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData.Core">
<Version>2.9.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.Fragment">
<Version>1.8.8</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.Collection.Ktx">
<Version>1.5.0.2</Version>
</PackageReference>
@ -717,9 +736,6 @@
<PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData.Ktx">
<Version>2.9.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.SavedState">
<Version>1.3.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Messaging">
<Version>125.0.0</Version>
</PackageReference>