231 lines
7.3 KiB
C#
231 lines
7.3 KiB
C#
using CommunityToolkit.Maui.Alerts;
|
|
using CommunityToolkit.Maui.Storage;
|
|
using Microsoft.Maui.Controls;
|
|
using Microsoft.Maui.Storage;
|
|
|
|
namespace FrymasterBadgeApp;
|
|
|
|
public partial class SettingsPage : ContentPage
|
|
{
|
|
private const string PhotoPathKey = "PhotoBasePath";
|
|
private const string LogoPathKey = "LogoBasePath";
|
|
private const string ImagesPathKey = "ImagesBasePath";
|
|
private const string ThemePrefKey = "AppTheme";
|
|
|
|
public SettingsPage()
|
|
{
|
|
InitializeComponent();
|
|
LoadCurrentSettings();
|
|
LoadCurrentThemePreference();
|
|
|
|
ThemePicker.SelectedIndexChanged += (s, e) => ApplyThemeSelection();
|
|
|
|
Shell.SetBackButtonBehavior(
|
|
this,
|
|
new BackButtonBehavior
|
|
{
|
|
TextOverride = "Back",
|
|
Command = new Command(async () => await Shell.Current.GoToAsync("..")),
|
|
}
|
|
);
|
|
}
|
|
|
|
private void LoadCurrentSettings()
|
|
{
|
|
PathEntry.Text = Preferences.Default.Get(PhotoPathKey, @"C:\FrymasterData\photos");
|
|
LogoPathEntry.Text = Preferences.Default.Get(LogoPathKey, @"C:\FrymasterData\logos");
|
|
ImagesPathEntry.Text = Preferences.Default.Get(ImagesPathKey, @"C:\FrymasterData\images");
|
|
}
|
|
|
|
private void LoadCurrentThemePreference()
|
|
{
|
|
var pref = Preferences.Default.Get(ThemePrefKey, "System");
|
|
switch (pref)
|
|
{
|
|
case "Light":
|
|
ThemePicker.SelectedIndex = 1;
|
|
Application.Current.UserAppTheme = AppTheme.Light;
|
|
break;
|
|
case "Dark":
|
|
ThemePicker.SelectedIndex = 2;
|
|
Application.Current.UserAppTheme = AppTheme.Dark;
|
|
break;
|
|
default:
|
|
ThemePicker.SelectedIndex = 0;
|
|
Application.Current.UserAppTheme = AppTheme.Unspecified;
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void ApplyThemeSelection()
|
|
{
|
|
if (ThemePicker == null)
|
|
return;
|
|
|
|
var sel = ThemePicker.SelectedIndex;
|
|
switch (sel)
|
|
{
|
|
case 1: // Light
|
|
Application.Current.UserAppTheme = AppTheme.Light;
|
|
Preferences.Default.Set(ThemePrefKey, "Light");
|
|
break;
|
|
case 2: // Dark
|
|
Application.Current.UserAppTheme = AppTheme.Dark;
|
|
Preferences.Default.Set(ThemePrefKey, "Dark");
|
|
break;
|
|
default: // System
|
|
Application.Current.UserAppTheme = AppTheme.Unspecified;
|
|
Preferences.Default.Set(ThemePrefKey, "System");
|
|
break;
|
|
}
|
|
}
|
|
|
|
private async void OnPickPhotoFolderClicked(object sender, EventArgs e) =>
|
|
await PickFolderAsync(r => PathEntry.Text = r.Folder.Path, "Select Photos Folder");
|
|
|
|
private async void OnPickLogoFolderClicked(object sender, EventArgs e) =>
|
|
await PickFolderAsync(r => LogoPathEntry.Text = r.Folder.Path, "Select Logos Folder");
|
|
|
|
private async void OnPickImagesFolderClicked(object sender, EventArgs e) =>
|
|
await PickFolderAsync(r => ImagesPathEntry.Text = r.Folder.Path, "Select Images Folder");
|
|
|
|
private async Task PickFolderAsync(Action<FolderPickerResult> onSuccess, string title)
|
|
{
|
|
try
|
|
{
|
|
var result = await FolderPicker.Default.PickAsync(title, CancellationToken.None);
|
|
if (result.IsSuccessful)
|
|
{
|
|
onSuccess(result);
|
|
VerifyDirectory(result.Folder.Path);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await DisplayAlert("Error", ex.Message, "OK");
|
|
}
|
|
}
|
|
|
|
private async void OnSaveClicked(object sender, EventArgs e)
|
|
{
|
|
AppLogger.Info("Save settings clicked - start");
|
|
|
|
var photoPath = PathEntry?.Text?.Trim();
|
|
var logoPath = LogoPathEntry?.Text?.Trim();
|
|
var imagesPath = ImagesPathEntry?.Text?.Trim();
|
|
|
|
AppLogger.Info(
|
|
$"Paths collected → Photos: '{photoPath ?? "null"}', Logos: '{logoPath ?? "null"}', Images: '{imagesPath ?? "null"}'"
|
|
);
|
|
|
|
if (
|
|
string.IsNullOrWhiteSpace(photoPath)
|
|
|| string.IsNullOrWhiteSpace(logoPath)
|
|
|| string.IsNullOrWhiteSpace(imagesPath)
|
|
)
|
|
{
|
|
AppLogger.Warning("Validation failed - one or more paths empty");
|
|
await DisplayAlert("Error", "All folders must be selected.", "OK");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
AppLogger.Info("Saving preferences...");
|
|
|
|
Preferences.Default.Set(PhotoPathKey, photoPath);
|
|
Preferences.Default.Set(LogoPathKey, logoPath);
|
|
Preferences.Default.Set(ImagesPathKey, imagesPath);
|
|
|
|
AppLogger.Info("Preferences saved OK");
|
|
|
|
StatusLabel.Text = "Settings saved successfully!";
|
|
StatusLabel.TextColor = Colors.Green;
|
|
|
|
// Toast is optional & wrapped — comment out if still crashes
|
|
try
|
|
{
|
|
await MainThread.InvokeOnMainThreadAsync(async () =>
|
|
{
|
|
await Toast
|
|
.Make("Settings saved ✓", CommunityToolkit.Maui.Core.ToastDuration.Short)
|
|
.Show();
|
|
});
|
|
}
|
|
catch (Exception toastEx)
|
|
{
|
|
AppLogger.Warn("Toast failed (non-critical)");
|
|
}
|
|
|
|
// NO auto-navigation — let user press back button manually
|
|
// This avoids 90% of known Shell navigation crashes
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AppLogger.Error("Critical save failure", ex);
|
|
|
|
StatusLabel.Text = $"Save failed: {ex.Message}";
|
|
StatusLabel.TextColor = Colors.Red;
|
|
|
|
await DisplayAlert(
|
|
"Save Error",
|
|
$"{ex.GetType().Name}: {ex.Message}\n\nCheck logs for details.",
|
|
"OK"
|
|
);
|
|
}
|
|
finally
|
|
{
|
|
AppLogger.Info("Save settings handler finished");
|
|
}
|
|
}
|
|
|
|
// private static void SafeCreateDirectory(string? path)
|
|
// {
|
|
// if (string.IsNullOrWhiteSpace(path)) return;
|
|
|
|
// try
|
|
// {
|
|
// if (!Directory.Exists(path))
|
|
// {
|
|
// AppLogger.Info($"Creating directory: {path}");
|
|
// Directory.CreateDirectory(path);
|
|
// }
|
|
// else
|
|
// {
|
|
// AppLogger.Info($"Directory already exists: {path}");
|
|
// }
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
// AppLogger.Error($"Failed to create/verify directory '{path}'", ex);
|
|
// throw; // rethrow so main catch can handle it
|
|
// }
|
|
// }
|
|
|
|
// Helper - prevents crash on invalid paths
|
|
private static void SafeCreateDirectory(string path)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(path))
|
|
return;
|
|
|
|
try
|
|
{
|
|
Directory.CreateDirectory(path);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Log but don't crash the app
|
|
System.Diagnostics.Debug.WriteLine(
|
|
$"Directory creation failed for '{path}': {ex.Message}"
|
|
);
|
|
// You could also show a warning here if needed
|
|
}
|
|
}
|
|
|
|
private static void VerifyDirectory(string path)
|
|
{
|
|
if (!Directory.Exists(path))
|
|
Directory.CreateDirectory(path);
|
|
}
|
|
}
|