cambooth/src/CamBooth/CamBooth.App/Features/PictureGallery/PictureGalleryPage.xaml.cs

272 lines
7.0 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using CamBooth.App.Core.AppSettings;
using CamBooth.App.Core.Logging;
using CamBooth.App.Features.PhotoPrismUpload;
namespace CamBooth.App.Features.PictureGallery;
public partial class PictureGalleryPage : Page
{
private readonly AppSettingsService _appSettingsService;
private readonly Logger _logger;
private readonly PictureGalleryService _pictureGalleryService;
private readonly PhotoPrismUploadService _photoPrismUploadService;
private int _currentPage = 1;
private int _itemsPerPage = 11;
private int _totalPages = 1;
// QR Code wird nur einmal erstellt und dann wiederverwendet
private Border? _qrCodeBorder = null;
public PictureGalleryPage(AppSettingsService appSettingsService, Logger logger, PictureGalleryService pictureGalleryService, PhotoPrismUploadService photoPrismUploadService)
{
this._appSettingsService = appSettingsService;
this._logger = logger;
this._pictureGalleryService = pictureGalleryService;
this._photoPrismUploadService = photoPrismUploadService;
this.InitializeComponent();
this.Initialize();
}
private async void Initialize()
{
try
{
// QR-Code nur einmal beim Initialisieren erstellen
CreateQRCodeBorder();
_currentPage = 1;
CalculateTotalPages();
LoadCurrentPage();
UpdatePagerControls();
}
catch (Exception e)
{
this._logger.Error(e.Message);
}
}
private void CreateQRCodeBorder()
{
try
{
var qrCodeImage = this._photoPrismUploadService.GenerateAlbumQRCode();
if (qrCodeImage != null)
{
// QR-Code Container mit Label
var qrContainer = new StackPanel { Orientation = Orientation.Vertical };
var qrImageControl = new Image
{
Source = qrCodeImage,
Width = 220,
Margin = new Thickness(4)
};
var qrSubLabel = new TextBlock
{
Text = "zum Fotoalbum",
Foreground = new SolidColorBrush(Colors.White),
FontSize = 11,
FontWeight = FontWeights.Bold,
TextAlignment = TextAlignment.Center,
Margin = new Thickness(4, 0, 4, 2)
};
qrContainer.Children.Add(qrSubLabel);
qrContainer.Children.Add(qrImageControl);
_qrCodeBorder = new Border
{
Background = new SolidColorBrush(Colors.Black),
BorderBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#D4AF37")),
BorderThickness = new Thickness(2),
CornerRadius = new CornerRadius(6),
Padding = new Thickness(4),
Child = qrContainer,
Margin = new Thickness(4)
};
this._logger.Debug("✅ PhotoPrism QR-Code statisch erstellt");
}
}
catch (Exception ex)
{
this._logger.Warning($"PhotoPrism QR-Code konnte nicht generiert werden: {ex.Message}");
}
}
private void LoadPictures(int startIndex, int count)
{
this.Dispatcher.Invoke(
() =>
{
// Clear existing items
this.PicturesPanel.Items.Clear();
// Füge den statischen QR-Code als erstes Element hinzu
if (_qrCodeBorder != null)
{
this.PicturesPanel.Items.Add(_qrCodeBorder);
}
// Jetzt die regulären Bilder hinzufügen
int totalThumbnails = this._pictureGalleryService.ThumbnailsOrderedByNewestDescending.Count;
int endIndex = Math.Min(startIndex + count, totalThumbnails);
for (int i = startIndex; i < endIndex; i++)
{
BitmapImage thumbnail = this._pictureGalleryService.ThumbnailsOrderedByNewestDescending[i];
TextBlock? textBlock = new();
Hyperlink? hyperlink = new();
hyperlink.Click += this.Hyperlink_OnClick;
hyperlink.Tag = thumbnail.UriSource;
hyperlink.TextDecorations = null;
Image? imageControl = new()
{
Source = thumbnail,
Width = 392,
Margin = new Thickness(4)
};
hyperlink.Inlines.Add(new InlineUIContainer(imageControl));
textBlock.Inlines.Add(hyperlink);
this.PicturesPanel.Items.Add(textBlock);
}
});
}
public void CloseOpenDialog()
{
if (Dispatcher.CheckAccess())
PhotoDialogOverlay.Hide();
else
Dispatcher.Invoke(() => PhotoDialogOverlay.Hide());
}
public async Task ShowPhotoDialogAsync(string picturePath)
{
var imageToShow = new Image
{
MaxHeight = 570,
MaxWidth = 800,
Stretch = System.Windows.Media.Stretch.Uniform,
HorizontalAlignment = HorizontalAlignment.Center,
Source = PictureGalleryService.CreateThumbnail(picturePath, 900, 600)
};
PhotoDialogOverlay.DialogContent = imageToShow;
await PhotoDialogOverlay.ShowAsync();
}
private void Hyperlink_OnClick(object sender, RoutedEventArgs e)
{
Uri? picturePathUri = ((Hyperlink)sender).Tag as Uri;
if (picturePathUri is null)
{
return;
}
string picturePath = Uri.UnescapeDataString(picturePathUri.AbsolutePath);
_ = this.ShowPhotoDialogAsync(picturePath);
}
private void CalculateTotalPages()
{
int totalItems = this._pictureGalleryService.ThumbnailsOrderedByNewestDescending.Count;
_totalPages = totalItems > 0 ? (int)Math.Ceiling((double)totalItems / _itemsPerPage) : 1;
}
private void LoadCurrentPage()
{
int startIndex = (_currentPage - 1) * _itemsPerPage;
LoadPictures(startIndex, _itemsPerPage);
}
private void UpdatePagerControls()
{
this.Dispatcher.Invoke(() =>
{
PageInfoText.Text = $"Seite {_currentPage} von {_totalPages}";
FirstPageButton.IsEnabled = _currentPage > 1;
PreviousPageButton.IsEnabled = _currentPage > 1;
NextPageButton.IsEnabled = _currentPage < _totalPages;
LastPageButton.IsEnabled = _currentPage < _totalPages;
// Visual feedback for disabled buttons
FirstPageButton.Opacity = FirstPageButton.IsEnabled ? 1.0 : 0.5;
PreviousPageButton.Opacity = PreviousPageButton.IsEnabled ? 1.0 : 0.5;
NextPageButton.Opacity = NextPageButton.IsEnabled ? 1.0 : 0.5;
LastPageButton.Opacity = LastPageButton.IsEnabled ? 1.0 : 0.5;
});
}
private void FirstPageButton_Click(object sender, RoutedEventArgs e)
{
_currentPage = 1;
LoadCurrentPage();
UpdatePagerControls();
GalleryScrollViewer.ScrollToTop();
}
private void PreviousPageButton_Click(object sender, RoutedEventArgs e)
{
if (_currentPage > 1)
{
_currentPage--;
LoadCurrentPage();
UpdatePagerControls();
GalleryScrollViewer.ScrollToTop();
}
}
private void NextPageButton_Click(object sender, RoutedEventArgs e)
{
if (_currentPage < _totalPages)
{
_currentPage++;
LoadCurrentPage();
UpdatePagerControls();
GalleryScrollViewer.ScrollToTop();
}
}
private void LastPageButton_Click(object sender, RoutedEventArgs e)
{
_currentPage = _totalPages;
LoadCurrentPage();
UpdatePagerControls();
GalleryScrollViewer.ScrollToTop();
}
private void CloseGallery_Click(object sender, RoutedEventArgs e)
{
// Finde das MainWindow über die Window.GetWindow Methode
var window = Window.GetWindow(this);
if (window is MainWindow mainWindow)
{
mainWindow.ClosePicturePanel();
}
else
{
_logger.Warning("MainWindow konnte nicht gefunden werden, um die Galerie zu schließen");
}
}
}