"Refactor UI and logging: Update UI text and wrapping for better readability, switch logging to Debug for consistency, and clean up unused imports and code alignment across multiple services"

This commit is contained in:
iTob 2026-06-30 17:58:52 +02:00
parent d0db293bb8
commit 9ad55bd90a
14 changed files with 229 additions and 261 deletions

View File

@ -1,15 +1,11 @@
using System.Windows; using System.Windows;
using CamBooth.App.Core.AppSettings; using CamBooth.App.Core.AppSettings;
using CamBooth.App.Core.Logging; using CamBooth.App.Core.Logging;
using CamBooth.App.Features.Camera; using CamBooth.App.Features.Camera;
using CamBooth.App.Features.PhotoPrismUpload; using CamBooth.App.Features.PhotoPrismUpload;
using CamBooth.App.Features.PictureGallery; using CamBooth.App.Features.PictureGallery;
using EDSDKLib.API.Base; using EDSDKLib.API.Base;
using EOSDigital.API; using EOSDigital.API;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -20,134 +16,134 @@ namespace CamBooth.App;
/// </summary> /// </summary>
public partial class App : Application public partial class App : Application
{ {
private IServiceProvider? _serviceProvider; private IServiceProvider? _serviceProvider;
protected override void OnStartup(StartupEventArgs e) protected override void OnStartup(StartupEventArgs e)
{ {
base.OnStartup(e); base.OnStartup(e);
var configuration = BuildConfiguration(); var configuration = BuildConfiguration();
var services = new ServiceCollection(); var services = new ServiceCollection();
RegisterServices(services, configuration); RegisterServices(services, configuration);
_serviceProvider = services.BuildServiceProvider(); _serviceProvider = services.BuildServiceProvider();
StartBackgroundServices(); StartBackgroundServices();
_serviceProvider.GetRequiredService<MainWindow>().Show(); _serviceProvider.GetRequiredService<MainWindow>().Show();
} }
protected override void OnSessionEnding(SessionEndingCancelEventArgs e) protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
{ {
TryShutdownCamera("OnSessionEnding"); TryShutdownCamera("OnSessionEnding");
base.OnSessionEnding(e); base.OnSessionEnding(e);
} }
protected override void OnExit(ExitEventArgs e) protected override void OnExit(ExitEventArgs e)
{ {
try try
{ {
_serviceProvider?.GetService<PhotoPrismUploadQueueService>() _serviceProvider?.GetService<PhotoPrismUploadQueueService>()
?.StopAsync().Wait(TimeSpan.FromSeconds(10)); ?.StopAsync().Wait(TimeSpan.FromSeconds(10));
} }
catch (Exception ex) catch (Exception ex)
{ {
System.Diagnostics.Debug.WriteLine($"Error stopping upload service: {ex.Message}"); System.Diagnostics.Debug.WriteLine($"Error stopping upload service: {ex.Message}");
} }
TryShutdownCamera("OnExit"); TryShutdownCamera("OnExit");
try try
{ {
(_serviceProvider as IDisposable)?.Dispose(); (_serviceProvider as IDisposable)?.Dispose();
} }
catch (Exception ex) catch (Exception ex)
{ {
System.Diagnostics.Debug.WriteLine($"Error disposing service provider: {ex.Message}"); System.Diagnostics.Debug.WriteLine($"Error disposing service provider: {ex.Message}");
} }
base.OnExit(e); base.OnExit(e);
} }
private static IConfiguration BuildConfiguration() private static IConfiguration BuildConfiguration()
{ {
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"; var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
.SetBasePath(AppContext.BaseDirectory) .SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("Core/AppSettings/app.settings.json", optional: false, reloadOnChange: true); .AddJsonFile("Core/AppSettings/app.settings.json", optional: false, reloadOnChange: true);
if (environment == "Development") if (environment == "Development")
builder.AddJsonFile("Core/AppSettings/app.settings.dev.json", optional: true, reloadOnChange: true); builder.AddJsonFile("Core/AppSettings/app.settings.dev.json", optional: true, reloadOnChange: true);
return builder.Build(); return builder.Build();
} }
private static void RegisterServices(ServiceCollection services, IConfiguration configuration) private static void RegisterServices(ServiceCollection services, IConfiguration configuration)
{ {
services.AddSingleton(configuration); services.AddSingleton(configuration);
services.AddSingleton<Logger>(); services.AddSingleton<Logger>();
services.AddSingleton<AppSettingsService>(); services.AddSingleton<AppSettingsService>();
services.AddSingleton<PictureGalleryService>(); services.AddSingleton<PictureGalleryService>();
services.AddSingleton<CameraService>(); services.AddSingleton<CameraService>();
services.AddSingleton<PhotoPrismAuthService>(); services.AddSingleton<PhotoPrismAuthService>();
services.AddSingleton<PhotoPrismUploadService>(); services.AddSingleton<PhotoPrismUploadService>();
services.AddSingleton<PhotoPrismUploadQueueService>(); services.AddSingleton<PhotoPrismUploadQueueService>();
services.AddSingleton<MainWindowViewModel>(); services.AddSingleton<MainWindowViewModel>();
services.AddTransient<MainWindow>(); services.AddTransient<MainWindow>();
RegisterCameraApi(services, configuration); RegisterCameraApi(services, configuration);
} }
private static void RegisterCameraApi(ServiceCollection services, IConfiguration configuration) private static void RegisterCameraApi(ServiceCollection services, IConfiguration configuration)
{ {
var useMockCamera = bool.Parse(configuration["AppSettings:UseMockCamera"] ?? "false"); var useMockCamera = bool.Parse(configuration["AppSettings:UseMockCamera"] ?? "false");
try try
{ {
ICanonAPI canonApi = useMockCamera ? new CanonAPIMock() : new CanonAPI(); ICanonAPI canonApi = useMockCamera ? new CanonAPIMock() : new CanonAPI();
services.AddSingleton(canonApi); services.AddSingleton(canonApi);
} }
catch (DllNotFoundException ex) catch (DllNotFoundException ex)
{ {
MessageBox.Show( MessageBox.Show(
$"EDSDK konnte nicht geladen werden. Verwende Mock-Kamera.\n\nFehler: {ex.Message}", $"EDSDK konnte nicht geladen werden. Verwende Mock-Kamera.\n\nFehler: {ex.Message}",
"DLL nicht gefunden", MessageBoxButton.OK, MessageBoxImage.Warning); "DLL nicht gefunden", MessageBoxButton.OK, MessageBoxImage.Warning);
services.AddSingleton<ICanonAPI>(new CanonAPIMock()); services.AddSingleton<ICanonAPI>(new CanonAPIMock());
} }
} }
private void StartBackgroundServices() private void StartBackgroundServices()
{ {
try try
{ {
var logger = _serviceProvider!.GetRequiredService<Logger>(); var logger = _serviceProvider!.GetRequiredService<Logger>();
var uploadQueueService = _serviceProvider.GetRequiredService<PhotoPrismUploadQueueService>(); var uploadQueueService = _serviceProvider.GetRequiredService<PhotoPrismUploadQueueService>();
uploadQueueService.Start(); uploadQueueService.Start();
uploadQueueService.ScanAndQueueFailedUploads(); uploadQueueService.ScanAndQueueFailedUploads();
logger.Info("PhotoPrism UploadQueueService gestartet"); logger.Info("PhotoPrism UploadQueueService gestartet");
} }
catch (Exception ex) catch (Exception ex)
{ {
System.Diagnostics.Debug.WriteLine($"Error starting background services: {ex.Message}"); System.Diagnostics.Debug.WriteLine($"Error starting background services: {ex.Message}");
} }
} }
private void TryShutdownCamera(string source) private void TryShutdownCamera(string source)
{ {
try try
{ {
var cameraService = _serviceProvider?.GetService<CameraService>(); var cameraService = _serviceProvider?.GetService<CameraService>();
cameraService?.CloseSession(); cameraService?.CloseSession();
} }
catch (Exception ex) catch (Exception ex)
{ {
System.Diagnostics.Debug.WriteLine($"Error closing camera session ({source}): {ex.Message}"); System.Diagnostics.Debug.WriteLine($"Error closing camera session ({source}): {ex.Message}");
} }
} }
} }

View File

@ -71,7 +71,7 @@ public class CameraService : IDisposable
if (attempt < maxRetries - 1) if (attempt < maxRetries - 1)
{ {
System.Threading.Thread.Sleep(retryDelayMs); Thread.Sleep(retryDelayMs);
RefreshCameraList(); RefreshCameraList();
} }
} }
@ -143,9 +143,7 @@ public class CameraService : IDisposable
try try
{ {
await Task.Run(() => sdkCamera.SendCommand(CameraCommand.PressShutterButton, (int)ShutterButton.Halfway)); await Task.Run(() => sdkCamera.SendCommand(CameraCommand.PressShutterButton, (int)ShutterButton.Halfway));
var completed = await Task.WhenAny(focusCompleted.Task, Task.Delay(focusTimeoutMs)); await Task.WhenAny(focusCompleted.Task, Task.Delay(focusTimeoutMs));
if (completed != focusCompleted.Task)
_logger.Info("Autofocus timeout reached, continuing.");
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -286,13 +284,13 @@ public class CameraService : IDisposable
private void MainCamera_DownloadReady(ICamera sender, IDownloadInfo info) private void MainCamera_DownloadReady(ICamera sender, IDownloadInfo info)
{ {
_logger.Info("Download ready"); _logger.Debug("Download ready");
try try
{ {
info.FileName = $"img_{Guid.NewGuid()}.jpg"; info.FileName = $"img_{Guid.NewGuid()}.jpg";
sender.DownloadFile(info, _appSettings.PictureLocation); sender.DownloadFile(info, _appSettings.PictureLocation);
var savedPath = Path.Combine(_appSettings.PictureLocation!, info.FileName); var savedPath = Path.Combine(_appSettings.PictureLocation!, info.FileName);
_logger.Info($"Download complete: {savedPath}"); _logger.Debug($"Download complete: {savedPath}");
Application.Current.Dispatcher.Invoke(() => Application.Current.Dispatcher.Invoke(() =>
{ {

View File

@ -1,20 +1,15 @@
using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Threading; using System.Windows.Threading;
using CamBooth.App.Core.Logging; using CamBooth.App.Core.Logging;
using CamBooth.App.Features.Camera; using CamBooth.App.Features.Camera;
using EOSDigital.API;
namespace CamBooth.App.Features.LiveView; namespace CamBooth.App.Features.LiveView;
public partial class LiveViewPage : Page, IDisposable public partial class LiveViewPage : IDisposable
{ {
private readonly CameraService _cameraService; private readonly CameraService _cameraService;
private readonly Logger _logger; private readonly Logger _logger;

View File

@ -41,35 +41,4 @@ public partial class ModernTimerControl : UserControl
StatusText.Text = "Zeit abgelaufen!"; StatusText.Text = "Zeit abgelaufen!";
} }
} }
public void StartTimer(int durationInSeconds)
{
_remainingTime = durationInSeconds;
TimerText.Text = TimeSpan.FromSeconds(_remainingTime).ToString(@"mm\:ss");
StatusText.Text = "Timer läuft...";
_timer.Start();
ShowTimer();
}
public void StopTimer()
{
_timer.Stop();
StatusText.Text = "Timer angehalten";
}
public void ShowTimer()
{
var fadeInAnimation = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(300));
TimerContainer.BeginAnimation(OpacityProperty, fadeInAnimation);
}
public void HideTimer()
{
var fadeOutAnimation = new DoubleAnimation(1, 0, TimeSpan.FromMilliseconds(300));
TimerContainer.BeginAnimation(OpacityProperty, fadeOutAnimation);
}
} }

View File

@ -54,16 +54,21 @@
</Grid> </Grid>
<!-- Instruction text below the ring --> <!-- Instruction text below the ring -->
<TextBlock x:Name="InstructionText" <Border Background="#CC101010"
FontSize="46" CornerRadius="16"
FontWeight="Bold" Padding="28,14"
Foreground="#D4AF37" HorizontalAlignment="Center"
HorizontalAlignment="Center" Margin="0,24,0,0">
TextAlignment="Center" <TextBlock x:Name="InstructionText"
TextWrapping="Wrap" FontSize="46"
MaxWidth="900" FontWeight="Bold"
Margin="0,24,0,0" Foreground="#D4AF37"
Text="Lächeln! 😊"/> HorizontalAlignment="Center"
TextAlignment="Center"
TextWrapping="Wrap"
MaxWidth="900"
Text="Lächeln! 😊"/>
</Border>
</StackPanel> </StackPanel>
</Border> </Border>

View File

@ -10,104 +10,104 @@ namespace CamBooth.App.Features.LiveView;
public partial class TimerControlRectangleAnimation : UserControl public partial class TimerControlRectangleAnimation : UserControl
{ {
// Ellipse diameter=320, StrokeThickness=12 → circumference = π*320/12 ≈ 83.78 dash-units // Ellipse diameter=320, StrokeThickness=12 → circumference = π*320/12 ≈ 83.78 dash-units
private static readonly double RingFullDashUnits = Math.PI * 320.0 / 12.0; private static readonly double RingFullDashUnits = Math.PI * 320.0 / 12.0;
public static event Action? OnTimerEllapsed; public static event Action? OnTimerEllapsed;
private readonly DispatcherTimer _ticker = new() { Interval = TimeSpan.FromSeconds(1) }; private readonly DispatcherTimer _ticker = new() { Interval = TimeSpan.FromSeconds(1) };
private readonly Random _random = new(); private readonly Random _random = new();
private int _remainingTime; private int _remainingTime;
private double _totalDuration; private double _totalDuration;
private static readonly string[] Instructions = private static readonly string[] Instructions =
[ [
"Lächeln! 😊", "Hasenohren machen! 🐰", "Zunge rausstrecken! 👅", "Lächeln! 😊", "Hasenohren machen! 🐰", "Zunge rausstrecken! 👅",
"Grimasse ziehen! 😝", "Daumen hoch! 👍", "Peace-Zeichen! ✌️", "Grimasse ziehen! 😝", "Daumen hoch! 👍", "Peace-Zeichen! ✌️",
"Lustig gucken! 🤪", "Crazy Face! 🤯", "Küsschen! 😘", "Lustig gucken! 🤪", "Crazy Face! 🤯", "Küsschen! 😘",
"Winken! 👋", "Herz mit den Händen! ❤️", "Überrascht schauen! 😲", "Winken! 👋", "Herz mit den Händen! ❤️", "Überrascht schauen! 😲",
"Cool bleiben! 😎", "Lachen! 😄", "Zähne zeigen! 😁", "Cool bleiben! 😎", "Lachen! 😄", "Zähne zeigen! 😁",
"Schnute ziehen! 😗", "Arm hochstrecken! 🙌", "Gruppe umarmen! 🤗" "Schnute ziehen! 😗", "Arm hochstrecken! 🙌", "Gruppe umarmen! 🤗"
]; ];
public TimerControlRectangleAnimation() public TimerControlRectangleAnimation()
{ {
InitializeComponent(); InitializeComponent();
_ticker.Tick += OnTick; _ticker.Tick += OnTick;
} }
public void StartTimer(int durationInSeconds) public void StartTimer(int durationInSeconds)
{ {
_totalDuration = durationInSeconds; _totalDuration = durationInSeconds;
_remainingTime = durationInSeconds; _remainingTime = durationInSeconds;
CountdownNumber.Text = _remainingTime.ToString(); CountdownNumber.Text = _remainingTime.ToString();
InstructionText.Text = Instructions[_random.Next(Instructions.Length)]; InstructionText.Text = Instructions[_random.Next(Instructions.Length)];
// Reset ring offset so ring appears full // Reset ring offset so ring appears full
CountdownRing.StrokeDashOffset = 0; CountdownRing.StrokeDashOffset = 0;
CountdownRing.StrokeDashArray = new DoubleCollection { RingFullDashUnits, RingFullDashUnits }; CountdownRing.StrokeDashArray = new DoubleCollection { RingFullDashUnits, RingFullDashUnits };
FadeIn(); FadeIn();
StartRingAnimation(); StartRingAnimation();
_ticker.Start(); _ticker.Start();
} }
private void OnTick(object? sender, EventArgs e) private void OnTick(object? sender, EventArgs e)
{ {
_remainingTime--; _remainingTime--;
if (_remainingTime > 0) if (_remainingTime > 0)
{
CountdownNumber.Text = _remainingTime.ToString();
AnimateNumberPop();
}
else
{
_ticker.Stop();
CountdownNumber.Text = "0";
AnimateNumberPop();
StopRingAnimation();
OnTimerEllapsed?.Invoke();
}
}
private void FadeIn()
{
TimerContainer.BeginAnimation(OpacityProperty,
new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(300)));
}
private void StartRingAnimation()
{
// StrokeDashOffset IS a DependencyProperty — animate directly, no Storyboard needed.
// Pattern: dash=C, gap=C. Offset 0 → full ring; offset C → empty ring.
CountdownRing.BeginAnimation(Shape.StrokeDashOffsetProperty,
new DoubleAnimation(0, RingFullDashUnits,
new Duration(TimeSpan.FromSeconds(_totalDuration)))
{ {
FillBehavior = FillBehavior.HoldEnd CountdownNumber.Text = _remainingTime.ToString();
}); AnimateNumberPop();
} }
else
{
_ticker.Stop();
CountdownNumber.Text = "0";
AnimateNumberPop();
StopRingAnimation();
OnTimerEllapsed?.Invoke();
}
}
private void StopRingAnimation() => private void FadeIn()
CountdownRing.BeginAnimation(Shape.StrokeDashOffsetProperty, null); {
TimerContainer.BeginAnimation(OpacityProperty,
new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(300)));
}
private void AnimateNumberPop() private void StartRingAnimation()
{ {
var easing = new BackEase { Amplitude = 0.4, EasingMode = EasingMode.EaseOut }; // StrokeDashOffset IS a DependencyProperty — animate directly, no Storyboard needed.
CountdownNumberScale.ScaleX = 1.4; // Pattern: dash=C, gap=C. Offset 0 → full ring; offset C → empty ring.
CountdownNumberScale.ScaleY = 1.4; CountdownRing.BeginAnimation(Shape.StrokeDashOffsetProperty,
CountdownNumberScale.BeginAnimation(ScaleTransform.ScaleXProperty, new DoubleAnimation(0, RingFullDashUnits,
new DoubleAnimation(1.4, 1.0, TimeSpan.FromMilliseconds(450)) { EasingFunction = easing }); new Duration(TimeSpan.FromSeconds(_totalDuration)))
CountdownNumberScale.BeginAnimation(ScaleTransform.ScaleYProperty, {
new DoubleAnimation(1.4, 1.0, TimeSpan.FromMilliseconds(450)) { EasingFunction = easing }); FillBehavior = FillBehavior.HoldEnd
} });
} }
private void StopRingAnimation() =>
CountdownRing.BeginAnimation(Shape.StrokeDashOffsetProperty, null);
private void AnimateNumberPop()
{
var easing = new BackEase { Amplitude = 0.4, EasingMode = EasingMode.EaseOut };
CountdownNumberScale.ScaleX = 1.4;
CountdownNumberScale.ScaleY = 1.4;
CountdownNumberScale.BeginAnimation(ScaleTransform.ScaleXProperty,
new DoubleAnimation(1.4, 1.0, TimeSpan.FromMilliseconds(450)) { EasingFunction = easing });
CountdownNumberScale.BeginAnimation(ScaleTransform.ScaleYProperty,
new DoubleAnimation(1.4, 1.0, TimeSpan.FromMilliseconds(450)) { EasingFunction = easing });
}
}

View File

@ -37,7 +37,7 @@ public class PhotoPrismAuthService
{ {
try try
{ {
_logger.Info("Starte PhotoPrism-Authentifizierung..."); _logger.Debug("Starte PhotoPrism-Authentifizierung...");
if (!ValidateConfiguration()) if (!ValidateConfiguration())
return false; return false;

View File

@ -134,7 +134,7 @@ public class PhotoPrismUploadQueueService : IDisposable
{ {
if (_uploadQueue.Contains(photoPath)) return; if (_uploadQueue.Contains(photoPath)) return;
_uploadQueue.Enqueue(photoPath); _uploadQueue.Enqueue(photoPath);
_logger.Info($"Neues Foto in PhotoPrism-Queue: {Path.GetFileName(photoPath)}"); _logger.Debug($"Neues Foto in PhotoPrism-Queue: {Path.GetFileName(photoPath)}");
} }
} }
@ -151,7 +151,7 @@ public class PhotoPrismUploadQueueService : IDisposable
private async Task ProcessQueueAsync(CancellationToken cancellationToken) private async Task ProcessQueueAsync(CancellationToken cancellationToken)
{ {
_logger.Info("PhotoPrism Upload-Queue-Verarbeitung gestartet"); _logger.Debug("PhotoPrism Upload-Queue-Verarbeitung gestartet");
try try
{ {
@ -203,7 +203,7 @@ public class PhotoPrismUploadQueueService : IDisposable
if (success) if (success)
{ {
_uploadTracker.MarkAsUploaded(filePath); _uploadTracker.MarkAsUploaded(filePath);
_logger.Info($"✅ PhotoPrism Upload erfolgreich: {fileName}"); _logger.Debug($"✅ PhotoPrism Upload erfolgreich: {fileName}");
} }
else else
{ {

View File

@ -140,7 +140,7 @@ public class PhotoPrismUploadService : IDisposable
return false; return false;
} }
_logger.Info($"Starte Upload: {Path.GetFileName(imagePath)}"); _logger.Debug($"Starte Upload: {Path.GetFileName(imagePath)}");
_logger.Debug($" Authentifiziert: {_isAuthenticated}"); _logger.Debug($" Authentifiziert: {_isAuthenticated}");
_logger.Debug($" Token vorhanden: {!string.IsNullOrEmpty(_authService.AccessToken)}"); _logger.Debug($" Token vorhanden: {!string.IsNullOrEmpty(_authService.AccessToken)}");

View File

@ -53,7 +53,7 @@ public class PhotoPrismUploadTracker
}; };
SaveToDisk(); SaveToDisk();
_logger.Info($"Bild als hochgeladen markiert: {key}"); _logger.Debug($"Bild als hochgeladen markiert: {key}");
} }
/// <summary> /// <summary>

View File

@ -76,12 +76,13 @@ public partial class PictureGalleryPage : Page
var qrSubLabel = new TextBlock var qrSubLabel = new TextBlock
{ {
Text = "zum Fotoalbum", Text = "📱 Handy-Kamera draufhalten",
Foreground = new SolidColorBrush(Colors.White), Foreground = new SolidColorBrush(Colors.White),
FontSize = 11, FontSize = 12,
FontWeight = FontWeights.Bold, FontWeight = FontWeights.Bold,
TextAlignment = TextAlignment.Center, TextAlignment = TextAlignment.Center,
Margin = new Thickness(4, 0, 4, 2) TextWrapping = TextWrapping.Wrap,
Margin = new Thickness(4, 0, 4, 4)
}; };
qrContainer.Children.Add(qrSubLabel); qrContainer.Children.Add(qrSubLabel);

View File

@ -103,7 +103,7 @@ public class PictureGalleryService
try try
{ {
this.thumbnails.Add(creationTime, PictureGalleryService.CreateThumbnail(picturePath, 244, 0)); this.thumbnails.Add(creationTime, PictureGalleryService.CreateThumbnail(picturePath, 244, 0));
this._logger.Info($"Thumbnail '{picturePath}' successfully created"); this._logger.Debug($"Thumbnail '{picturePath}' successfully created");
} }
catch (Exception e) catch (Exception e)
{ {
@ -115,7 +115,7 @@ public class PictureGalleryService
} }
while ((loop < cacheSize || cacheSize == 0) && loop < picturePaths.Count); while ((loop < cacheSize || cacheSize == 0) && loop < picturePaths.Count);
}); });
this._logger.Info("Loading thumbnails into cache completed"); this._logger.Debug("Loading thumbnails into cache completed");
} }

View File

@ -253,13 +253,13 @@
</Grid> </Grid>
<!-- Text --> <!-- Text -->
<TextBlock Text="Herunterladen" <TextBlock Text="Fotos"
Foreground="White" Foreground="White"
FontSize="10" FontSize="10"
FontWeight="Bold" FontWeight="Bold"
TextAlignment="Center" TextAlignment="Center"
Margin="0,0,0,2"/> Margin="0,0,0,2"/>
<TextBlock Text="Fotos" <TextBlock Text="aufs Handy"
Foreground="#D4AF37" Foreground="#D4AF37"
FontSize="8" FontSize="8"
FontWeight="SemiBold" FontWeight="SemiBold"
@ -525,7 +525,7 @@
<!-- QR-Code Dialog --> <!-- QR-Code Dialog -->
<core:BaseDialogOverlay x:Name="QRCodeOverlay" <core:BaseDialogOverlay x:Name="QRCodeOverlay"
DialogTitle="Online-Fotoalbum" DialogTitle="Alle Fotos aufs Handy"
Grid.RowSpan="2" Grid.RowSpan="2"
Panel.ZIndex="200"/> Panel.ZIndex="200"/>

View File

@ -233,10 +233,14 @@ public partial class MainWindow : Window
}); });
content.Children.Add(new System.Windows.Controls.TextBlock content.Children.Add(new System.Windows.Controls.TextBlock
{ {
Text = "Mit einem QR-Code-Scanner scannen", Text = "Nimm dein Handy und halte die Kamera auf den Code.\n" +
"Tippe dann auf den Link, der erscheint - schon siehst du alle Fotos.",
Foreground = Brushes.White, Foreground = Brushes.White,
FontSize = 16, FontSize = 18,
TextAlignment = TextAlignment.Center LineHeight = 26,
TextAlignment = TextAlignment.Center,
TextWrapping = TextWrapping.Wrap,
MaxWidth = 420
}); });
QRCodeOverlay.DialogContent = content; QRCodeOverlay.DialogContent = content;