272 lines
7.0 KiB
C#
272 lines
7.0 KiB
C#
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");
|
||
}
|
||
}
|
||
}
|
||
|