diff --git a/Directory.Packages.props b/Directory.Packages.props
index 388751b7..e824166e 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -47,6 +47,7 @@
+
@@ -67,4 +68,4 @@
-
+
\ No newline at end of file
diff --git a/Wino.Core.Domain/Translations/en_US/resources.json b/Wino.Core.Domain/Translations/en_US/resources.json
index 8eccf7fa..c84f20f3 100644
--- a/Wino.Core.Domain/Translations/en_US/resources.json
+++ b/Wino.Core.Domain/Translations/en_US/resources.json
@@ -531,6 +531,9 @@
"SettingsDiscord_Title": "Discord Channel",
"SettingsEditLinkedInbox_Description": "Add / remove accounts, rename or break the link between accounts.",
"SettingsEditLinkedInbox_Title": "Edit Linked Inbox",
+ "SettingsWindowBackdrop_Title": "Window Backdrop",
+ "SettingsWindowBackdrop_Description": "Select a backdrop effect for Wino windows.",
+ "SettingsWindowBackdrop_Disabled": "Window backdrop selection is disabled when application theme is selected other than Default.",
"SettingsElementTheme_Description": "Select a Windows theme for Wino",
"SettingsElementTheme_Title": "Element Theme",
"SettingsElementThemeSelectionDisabled": "Element theme selection is disabled when application theme is selected other than Default.",
diff --git a/Wino.Core.WinUI/AppThemes/Mica.xaml b/Wino.Core.WinUI/AppThemes/Default.xaml
similarity index 94%
rename from Wino.Core.WinUI/AppThemes/Mica.xaml
rename to Wino.Core.WinUI/AppThemes/Default.xaml
index 88df78b2..d8adf74d 100644
--- a/Wino.Core.WinUI/AppThemes/Mica.xaml
+++ b/Wino.Core.WinUI/AppThemes/Default.xaml
@@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xaml="using:Microsoft.UI.Xaml">
- Mica
+ Default
Transparent
Transparent
diff --git a/Wino.Core.WinUI/IMPLEMENTATION_SUMMARY.md b/Wino.Core.WinUI/IMPLEMENTATION_SUMMARY.md
deleted file mode 100644
index e4c7125e..00000000
--- a/Wino.Core.WinUI/IMPLEMENTATION_SUMMARY.md
+++ /dev/null
@@ -1,173 +0,0 @@
-# NewThemeService Implementation Summary
-
-## What's Been Created
-
-### 🏗️ Core Implementation
-
-1. **WindowBackdropType Enum** (`Wino.Core.Domain\Enums\WindowBackdropType.cs`)
- - Defines all supported backdrop types (Mica, MicaAlt, DesktopAcrylic, etc.)
-
-2. **INewThemeService Interface** (`Wino.Core.Domain\Interfaces\INewThemeService.cs`)
- - Extended interface with backdrop management and enhanced accent color support
- - Backward compatible with existing IThemeService functionality
-
-3. **NewThemeService Implementation** (`Wino.Core.WinUI\Services\NewThemeService.cs`)
- - Full WinUI-optimized theme service
- - Window backdrop management with WindowEx support
- - Enhanced accent color management with theme preservation
- - Proper initialization sequence for backdrop application
- - Event system for backdrop, theme, and accent color changes
-
-### 🔧 Integration Updates
-
-4. **CoreUWPContainerSetup.cs** - Updated DI registration
- - Registers both old and new theme services
- - Maintains backward compatibility
-
-5. **WinoApplication.cs** - Enhanced base application class
- - Added NewThemeService property and initialization
- - Updated service initialization order
- - Proper backdrop application timing
-
-6. **App.xaml.cs** - Updated application launch sequence
- - Loads backdrop settings before window creation
- - Applies backdrop immediately after window creation
- - Maintains proper initialization flow
-
-7. **ShellWindow.xaml** - Removed hardcoded backdrop
- - Allows NewThemeService to control backdrop dynamically
-
-### 📚 Documentation & Examples
-
-8. **Usage Example** (`Examples\NewThemeServiceExampleViewModel.cs`)
- - Complete ViewModel showing all features
- - Event handling patterns
- - Error handling best practices
- - UI binding examples
-
-9. **Comprehensive Documentation** (`README_NewThemeService.md`)
- - Feature overview and benefits
- - Usage examples and patterns
- - Configuration and best practices
- - Service registration details
-
-10. **Migration Guide** (`MIGRATION_NewThemeService.md`)
- - Step-by-step migration instructions
- - Before/after code comparisons
- - Common issues and solutions
- - Testing checklist
-
-## Key Features Delivered
-
-### ✨ Window Backdrop Management
-- **Dynamic Backdrop Control**: Switch between Mica, Acrylic, and other backdrops at runtime
-- **Persistent Settings**: Backdrop preferences saved and restored across app sessions
-- **Initialization Support**: Backdrop applied before window is shown to user
-- **Multiple Backdrop Types**:
- - `Mica` - Standard translucent material
- - `MicaAlt` - Alternative Mica variant
- - `DesktopAcrylic` - Semi-transparent acrylic
- - `AcrylicBase` & `AcrylicThin` - Acrylic variants
- - `None` - No backdrop for solid backgrounds
-
-### 🎨 Enhanced Accent Color Management
-- **Theme-Preserving Color Changes**: Change accent color without switching themes
-- **System Integration**: Automatic system accent color detection
-- **Improved API**: `SetAccentColorAsync()` with better control options
-- **Backward Compatibility**: Works with existing accent color code
-
-### 🖼️ Custom Wallpaper Support
-- **Existing Functionality**: Polished implementation from old service
-- **Thumbnail Generation**: Automatic preview image creation
-- **Persistent Storage**: Themes saved in local app data
-- **Metadata Management**: JSON-based theme configuration
-
-### ⚡ Better Initialization
-- **Startup Performance**: Backdrop settings loaded early in app lifecycle
-- **Window Creation Flow**: Proper timing between window creation and backdrop application
-- **Service Dependencies**: Correct initialization order with other services
-- **Configuration Persistence**: All settings properly saved and restored
-
-### 🔄 Backward Compatibility
-- **Dual Service Support**: Both old and new services available
-- **Gradual Migration**: Can migrate features incrementally
-- **API Compatibility**: All existing theme functionality preserved
-- **Zero Breaking Changes**: Existing code continues to work
-
-## Technical Implementation Details
-
-### Service Registration Pattern
-```csharp
-// Both services registered for compatibility
-services.AddSingleton();
-services.AddSingleton();
-```
-
-### Initialization Sequence
-1. App constructs services (including NewThemeService)
-2. OnLaunched loads saved backdrop type from configuration
-3. Window is created (ShellWindow)
-4. Backdrop is applied immediately via ApplyBackdropAsync()
-5. Service initialization completes (InitializeServicesAsync)
-6. Window is activated and shown to user
-
-### Configuration Keys
-- `WindowBackdropTypeKey`: Backdrop type preference
-- `AccentColorKey`: Custom accent color
-- `CurrentApplicationThemeKey`: Selected theme ID
-- `SelectedAppThemeKey`: Element theme (Light/Dark/Default)
-
-### Event System
-- `BackdropChanged`: Fired when backdrop type changes
-- `ElementThemeChanged`: Existing theme change events
-- `AccentColorChanged`: Existing accent color events
-
-## Benefits Over Original ThemeService
-
-### 🎯 WinUI Optimized
-- **WindowEx Integration**: Proper SystemBackdrop property usage
-- **Modern Backdrop Types**: Support for latest WinUI backdrop materials
-- **Performance**: Optimized for WinUI rendering pipeline
-
-### 💡 Enhanced User Experience
-- **Visual Polish**: Professional backdrop effects (Mica, Acrylic)
-- **Smooth Transitions**: Proper backdrop switching without flicker
-- **System Integration**: Respects system theme and accent preferences
-
-### 🔧 Developer Experience
-- **Better APIs**: Async methods with proper error handling
-- **Event System**: Rich event notifications for UI updates
-- **Clear Separation**: Theme vs backdrop vs accent color management
-- **Documentation**: Comprehensive guides and examples
-
-### 🚀 Future Ready
-- **Extensible**: Easy to add new backdrop types
-- **Modern Patterns**: Async/await, proper DI integration
-- **Maintainable**: Clean separation of concerns
-- **Testable**: Interface-based design with dependency injection
-
-## Deployment Notes
-
-### Required Steps for Integration
-1. ✅ All code files created and properly structured
-2. ✅ Service registration updated in DI container
-3. ✅ WinoApplication updated with NewThemeService support
-4. ✅ App launch sequence updated for proper backdrop initialization
-5. ✅ Hardcoded backdrop removed from XAML
-6. ✅ Backward compatibility maintained
-7. ✅ Documentation and examples provided
-
-### Testing Recommendations
-- Test all backdrop types on different system themes
-- Verify backdrop persistence across app restarts
-- Test accent color changes with different themes
-- Verify custom theme creation still works
-- Test on different Windows versions and hardware
-
-### Migration Path
-- Services can coexist during transition period
-- Teams can migrate features incrementally
-- No breaking changes to existing functionality
-- Full backward compatibility maintained
-
-This implementation provides a solid foundation for modern WinUI theming with professional backdrop effects while maintaining all existing functionality.
\ No newline at end of file
diff --git a/Wino.Core.WinUI/MIGRATION_NewThemeService.md b/Wino.Core.WinUI/MIGRATION_NewThemeService.md
deleted file mode 100644
index 1f65c425..00000000
--- a/Wino.Core.WinUI/MIGRATION_NewThemeService.md
+++ /dev/null
@@ -1,258 +0,0 @@
-# NewThemeService Migration Guide
-
-## Overview
-
-This guide helps you migrate from the original `ThemeService` to the new `NewThemeService` with enhanced backdrop management and improved accent color handling.
-
-## Quick Migration Steps
-
-### 1. Update Service Usage
-
-**Before (Old ThemeService):**
-```csharp
-var themeService = Services.GetService();
-themeService.RootTheme = ApplicationElementTheme.Dark;
-themeService.AccentColor = "#FF5722";
-```
-
-**After (NewThemeService):**
-```csharp
-var newThemeService = Services.GetService();
-newThemeService.RootTheme = ApplicationElementTheme.Dark;
-await newThemeService.SetAccentColorAsync("#FF5722", preserveTheme: true);
-
-// Plus new backdrop management
-await newThemeService.ApplyBackdropAsync(WindowBackdropType.Mica);
-```
-
-### 2. Remove Hardcoded Backdrops
-
-**Before:**
-```xaml
-
-
-
-```
-
-**After:**
-```xaml
-
-```
-
-### 3. Update App Initialization
-
-**Before:**
-```csharp
-protected override async void OnLaunched(LaunchActivatedEventArgs args)
-{
- MainWindow = new ShellWindow();
- await InitializeServicesAsync();
- MainWindow.Activate();
-}
-```
-
-**After:**
-```csharp
-protected override async void OnLaunched(LaunchActivatedEventArgs args)
-{
- // Load backdrop settings before creating window
- var newThemeService = Services.GetService();
- var configService = Services.GetService();
- var savedBackdropType = (WindowBackdropType)configService.Get("WindowBackdropTypeKey", (int)WindowBackdropType.Mica);
-
- MainWindow = new ShellWindow();
-
- // Apply backdrop immediately after window creation
- if (newThemeService != null)
- {
- await newThemeService.ApplyBackdropAsync(savedBackdropType);
- }
-
- await InitializeServicesAsync();
- MainWindow.Activate();
-}
-```
-
-### 4. Update WinoApplication Services
-
-**Before:**
-```csharp
-public IEnumerable GetActivationServices()
-{
- yield return DatabaseService;
- yield return TranslationService;
- yield return ThemeService; // Old service
-}
-```
-
-**After:**
-```csharp
-public IEnumerable GetActivationServices()
-{
- yield return DatabaseService;
- yield return TranslationService;
- yield return NewThemeService; // New service
- // yield return ThemeService; // Keep for backward compatibility but don't initialize
-}
-```
-
-## New Features Available After Migration
-
-### 1. Backdrop Management
-```csharp
-// All available backdrop types
-await newThemeService.ApplyBackdropAsync(WindowBackdropType.Mica);
-await newThemeService.ApplyBackdropAsync(WindowBackdropType.MicaAlt);
-await newThemeService.ApplyBackdropAsync(WindowBackdropType.DesktopAcrylic);
-await newThemeService.ApplyBackdropAsync(WindowBackdropType.AcrylicBase);
-await newThemeService.ApplyBackdropAsync(WindowBackdropType.AcrylicThin);
-await newThemeService.ApplyBackdropAsync(WindowBackdropType.None);
-
-// Persistent backdrop setting
-newThemeService.CurrentBackdropType = WindowBackdropType.MicaAlt;
-```
-
-### 2. Enhanced Accent Color Management
-```csharp
-// Set accent color without changing theme
-await newThemeService.SetAccentColorAsync("#FF5722", preserveTheme: true);
-
-// Get system accent color
-var systemColor = newThemeService.GetSystemAccentColorHex();
-await newThemeService.SetAccentColorAsync(systemColor);
-```
-
-### 3. Event Handling
-```csharp
-// New backdrop change events
-newThemeService.BackdropChanged += (sender, backdropType) => {
- // Handle backdrop changes
- UpdateUI(backdropType);
-};
-
-// Existing events still work
-newThemeService.ElementThemeChanged += (sender, theme) => {
- // Handle theme changes
-};
-
-newThemeService.AccentColorChanged += (sender, color) => {
- // Handle accent color changes
-};
-```
-
-## Backward Compatibility
-
-### Both Services Available
-- `IThemeService` (original) - still registered and functional
-- `INewThemeService` (new) - enhanced version with additional features
-
-### Choosing Which to Use
-```csharp
-// For new code - use NewThemeService
-var newThemeService = Services.GetService();
-
-// For existing code that needs compatibility - keep using ThemeService
-var oldThemeService = Services.GetService();
-```
-
-### Gradual Migration Strategy
-1. **Phase 1**: Register both services, initialize NewThemeService
-2. **Phase 2**: Update new features to use NewThemeService
-3. **Phase 3**: Migrate existing code gradually
-4. **Phase 4**: Eventually phase out old ThemeService (optional)
-
-## Common Migration Issues
-
-### Issue 1: Window Backdrop Not Applied
-**Problem**: Backdrop doesn't appear after migration
-**Solution**: Ensure backdrop is applied after window creation but before activation
-
-```csharp
-MainWindow = new ShellWindow();
-await newThemeService.ApplyBackdropAsync(WindowBackdropType.Mica); // Add this
-await InitializeServicesAsync();
-MainWindow.Activate();
-```
-
-### Issue 2: Accent Color Changes Don't Persist
-**Problem**: Accent color resets after app restart
-**Solution**: Use the enhanced SetAccentColorAsync method
-
-```csharp
-// Old way - might not persist properly
-newThemeService.AccentColor = "#FF5722";
-
-// New way - properly persisted
-await newThemeService.SetAccentColorAsync("#FF5722", preserveTheme: true);
-```
-
-### Issue 3: Multiple Service Initialization
-**Problem**: Both services being initialized causing conflicts
-**Solution**: Only initialize NewThemeService in GetActivationServices()
-
-```csharp
-public IEnumerable GetActivationServices()
-{
- yield return DatabaseService;
- yield return TranslationService;
- yield return NewThemeService; // Only this one
- // Don't yield ThemeService here
-}
-```
-
-## Testing Your Migration
-
-### 1. Backdrop Functionality
-- [ ] App starts with saved backdrop type
-- [ ] Backdrop changes are applied immediately
-- [ ] Backdrop changes persist after app restart
-- [ ] All backdrop types work correctly
-
-### 2. Theme Functionality
-- [ ] Light/Dark theme changes work
-- [ ] Custom themes still function
-- [ ] Theme changes persist after restart
-
-### 3. Accent Color Management
-- [ ] Custom accent colors apply correctly
-- [ ] System accent color detection works
-- [ ] Accent color changes persist
-- [ ] Theme preservation works with accent changes
-
-### 4. Backward Compatibility
-- [ ] Existing custom themes still work
-- [ ] Old theme-related code continues to function
-- [ ] No regression in existing functionality
-
-## Performance Considerations
-
-### Initialization Order
-- NewThemeService initializes backdrop settings from saved configuration
-- Window creation happens before service initialization for best performance
-- Backdrop is applied immediately after window creation
-
-### Runtime Performance
-- Backdrop changes are async operations
-- Don't change backdrop frequently (e.g., during animations)
-- Cache backdrop type to avoid unnecessary changes
-
-## Complete Migration Checklist
-
-- [ ] Update DI container registration
-- [ ] Update WinoApplication service initialization
-- [ ] Remove hardcoded SystemBackdrop from XAML
-- [ ] Update app launch sequence
-- [ ] Update settings/preferences UI for backdrop options
-- [ ] Test all backdrop types
-- [ ] Test theme and accent color functionality
-- [ ] Verify persistence across app restarts
-- [ ] Update documentation and comments
-- [ ] Train team on new features
-
-## Need Help?
-
-If you encounter issues during migration:
-1. Check the complete example in `NewThemeServiceExampleViewModel`
-2. Review the full documentation in `README_NewThemeService.md`
-3. Ensure proper initialization order in your app
-4. Verify all required using statements are included
\ No newline at end of file
diff --git a/Wino.Core.WinUI/README_NewThemeService.md b/Wino.Core.WinUI/README_NewThemeService.md
deleted file mode 100644
index 73385ae4..00000000
--- a/Wino.Core.WinUI/README_NewThemeService.md
+++ /dev/null
@@ -1,169 +0,0 @@
-# NewThemeService Documentation
-
-## Overview
-
-The `NewThemeService` is an enhanced theme management service designed specifically for WinUI applications. It extends the capabilities of the original `ThemeService` with advanced features like backdrop management, improved accent color handling, and better window initialization support.
-
-## Key Features
-
-### 🎨 Window Backdrop Management
-- **Mica**: Modern translucent material with system-aware tinting
-- **MicaAlt**: Alternative Mica variant with different tinting behavior
-- **DesktopAcrylic**: Semi-transparent acrylic background
-- **AcrylicBase & AcrylicThin**: Different acrylic variants
-- **None**: No backdrop (solid background)
-
-### 🌈 Enhanced Accent Color Management
-- Set custom accent colors without changing themes
-- Preserve theme while changing accent colors
-- Automatic system accent color detection
-- Backward-compatible color management
-
-### 🖼️ Custom Wallpaper Support
-- Create custom themes with user wallpapers
-- Automatic thumbnail generation
-- Persistent theme storage
-- Reuses existing custom theme functionality
-
-### ⚡ Improved Initialization
-- Backdrop settings applied before window creation
-- Persistent settings restoration
-- Proper service initialization order
-
-## Usage Examples
-
-### Basic Setup
-
-```csharp
-// Service is automatically registered in DI container
-var newThemeService = WinoApplication.Current.Services.GetService();
-```
-
-### Changing Window Backdrop
-
-```csharp
-// Apply different backdrop types
-await newThemeService.ApplyBackdropAsync(WindowBackdropType.Mica);
-await newThemeService.ApplyBackdropAsync(WindowBackdropType.DesktopAcrylic);
-await newThemeService.ApplyBackdropAsync(WindowBackdropType.None);
-
-// Persist the setting
-newThemeService.CurrentBackdropType = WindowBackdropType.MicaAlt;
-```
-
-### Custom Accent Color
-
-```csharp
-// Set accent color while preserving theme
-await newThemeService.SetAccentColorAsync("#FF6B47", preserveTheme: true);
-
-// Reset to system accent color
-var systemAccent = newThemeService.GetSystemAccentColorHex();
-await newThemeService.SetAccentColorAsync(systemAccent);
-```
-
-### Event Handling
-
-```csharp
-newThemeService.BackdropChanged += (sender, backdropType) => {
- Debug.WriteLine($"Backdrop changed to: {backdropType}");
-};
-
-newThemeService.ElementThemeChanged += (sender, theme) => {
- Debug.WriteLine($"Theme changed to: {theme}");
-};
-
-newThemeService.AccentColorChanged += (sender, color) => {
- Debug.WriteLine($"Accent color changed to: {color}");
-};
-```
-
-### Creating Custom Themes
-
-```csharp
-// Create custom theme with wallpaper
-var wallpaperData = await GetWallpaperBytesAsync(); // Your implementation
-var customTheme = await newThemeService.CreateNewCustomThemeAsync(
- "My Theme",
- "#FF5722",
- wallpaperData);
-
-// Apply the custom theme
-newThemeService.CurrentApplicationThemeId = customTheme.Id;
-```
-
-## Service Registration
-
-The service is automatically registered in the DI container:
-
-```csharp
-// In CoreUWPContainerSetup.cs
-services.AddSingleton();
-```
-
-## Initialization Order
-
-The service is initialized during app startup:
-
-```csharp
-// In WinoApplication.cs
-public IEnumerable GetActivationServices()
-{
- yield return DatabaseService;
- yield return TranslationService;
- yield return NewThemeService; // Initializes before window activation
-}
-```
-
-## Backdrop Application Flow
-
-1. **App Launch**: Saved backdrop type is loaded from configuration
-2. **Window Creation**: Window is created without hardcoded backdrop
-3. **Service Initialization**: NewThemeService initializes and applies saved backdrop
-4. **Runtime Changes**: User can change backdrop which is immediately applied and persisted
-
-## Backward Compatibility
-
-- The original `IThemeService` is still registered and functional
-- All existing theme functionality is preserved
-- Custom theme creation and management works as before
-- Accent color management is enhanced but compatible
-
-## Configuration Keys
-
-The service uses these persistent configuration keys:
-
-- `WindowBackdropTypeKey`: Stores the selected backdrop type (int)
-- `AccentColorKey`: Stores custom accent color (string)
-- `CurrentApplicationThemeKey`: Stores selected theme ID (Guid)
-- `SelectedAppThemeKey`: Stores element theme preference (ApplicationElementTheme)
-
-## Best Practices
-
-### ✅ Do
-- Initialize the service early in app lifecycle
-- Use async methods for backdrop changes
-- Handle backdrop change errors gracefully
-- Subscribe to events for UI updates
-- Preserve themes when changing accent colors
-
-### ❌ Don't
-- Set hardcoded SystemBackdrop in XAML
-- Change backdrop on every frame/animation
-- Ignore initialization errors
-- Forget to unsubscribe from events
-
-## Migration from Old ThemeService
-
-1. **Update DI Registration**: Both services are registered, choose which to use
-2. **Update Initialization**: Change `GetActivationServices()` to use `NewThemeService`
-3. **Remove Hardcoded Backdrops**: Remove `` from XAML
-4. **Add Backdrop Management**: Use `ApplyBackdropAsync()` for backdrop changes
-5. **Enhanced Accent Colors**: Use `SetAccentColorAsync()` for better accent color management
-
-## See Also
-
-- `INewThemeService` interface documentation
-- `WindowBackdropType` enumeration
-- `NewThemeServiceExampleViewModel` for complete usage example
-- Original `ThemeService` for backward compatibility
\ No newline at end of file
diff --git a/Wino.Core.WinUI/Services/NewThemeService.cs b/Wino.Core.WinUI/Services/NewThemeService.cs
index b019b1db..bc4907e8 100644
--- a/Wino.Core.WinUI/Services/NewThemeService.cs
+++ b/Wino.Core.WinUI/Services/NewThemeService.cs
@@ -38,6 +38,7 @@ public class NewThemeService : INewThemeService
{
public const string CustomThemeFolderName = "CustomThemes";
+ private static string _defaultThemeId = "00000000-0000-0000-0000-000000000000";
private static string _cloudsThemeId = "3b621cc2-e270-4a76-8477-737917cccda0";
private static string _forestThemeId = "8bc89b37-a7c5-4049-86e2-de1ae8858dbd";
private static string _nightyThemeId = "5b65e04e-fd7e-4c2d-8221-068d3e02d23a";
@@ -64,6 +65,7 @@ public class NewThemeService : INewThemeService
private List preDefinedThemes { get; set; } = new List()
{
+ new SystemAppTheme("Default", Guid.Parse(_defaultThemeId)),
new PreDefinedAppTheme("Nighty", Guid.Parse(_nightyThemeId), "#e1b12c", ApplicationElementTheme.Dark),
new PreDefinedAppTheme("Forest", Guid.Parse(_forestThemeId), "#16a085", ApplicationElementTheme.Dark),
new PreDefinedAppTheme("Clouds", Guid.Parse(_cloudsThemeId), "#0984e3", ApplicationElementTheme.Light),
diff --git a/Wino.Core.WinUI/Wino.Core.WinUI.csproj b/Wino.Core.WinUI/Wino.Core.WinUI.csproj
index e1afcf2f..8398273b 100644
--- a/Wino.Core.WinUI/Wino.Core.WinUI.csproj
+++ b/Wino.Core.WinUI/Wino.Core.WinUI.csproj
@@ -23,7 +23,7 @@
MSBuild:Compile
-
+
MSBuild:Compile
@@ -78,6 +78,7 @@
+
diff --git a/Wino.Mail.ViewModels/Collections/GroupedEmailCollection.cs b/Wino.Mail.ViewModels/Collections/GroupedEmailCollection.cs
index 96076530..b67dba8e 100644
--- a/Wino.Mail.ViewModels/Collections/GroupedEmailCollection.cs
+++ b/Wino.Mail.ViewModels/Collections/GroupedEmailCollection.cs
@@ -636,6 +636,8 @@ public partial class GroupedEmailCollection : ObservableObject, IRecipient Items.IndexOf(item);
+
private void RefreshThreadInUI(ThreadMailItemViewModel expander)
{
// Remove thread completely from UI
@@ -646,6 +648,53 @@ public partial class GroupedEmailCollection : ObservableObject, IRecipient
+ item.MailCopy.UniqueId == uniqueId && !item.IsDisplayedInThread);
+
+ if (standaloneMailItem != null)
+ {
+ // Check if the standalone item is visible in the UI
+ var isItemVisible = Items.Contains(standaloneMailItem);
+
+ return new MailItemContainer(standaloneMailItem)
+ {
+ IsItemVisible = isItemVisible,
+ IsThreadVisible = false // Not a threaded item
+ };
+ }
+
+ // Search in thread expanders for threaded mail items
+ foreach (var threadExpander in _threadExpanders.Values)
+ {
+ if (threadExpander.HasUniqueId(uniqueId))
+ {
+ // Find the specific mail item within the thread
+ var threadMailItem = threadExpander.ThreadEmails.FirstOrDefault(email =>
+ email.MailCopy.UniqueId == uniqueId);
+
+ if (threadMailItem != null)
+ {
+ // Check visibility: thread expander must be visible, and for individual item visibility,
+ // the thread must be expanded and the item must be in the visible Items collection
+ var isThreadVisible = Items.Contains(threadExpander);
+ var isItemVisible = isThreadVisible && threadExpander.IsThreadExpanded && Items.Contains(threadMailItem);
+
+ return new MailItemContainer(threadMailItem, threadExpander)
+ {
+ IsItemVisible = isItemVisible,
+ IsThreadVisible = isThreadVisible
+ };
+ }
+ }
+ }
+
+ // Item not found
+ return null;
+ }
+
private void AddThreadToUI(ThreadMailItemViewModel expander, string groupKey)
{
var groupHeader = GetOrCreateGroupHeader(groupKey);
diff --git a/Wino.Mail.ViewModels/Data/MailItemContainer.cs b/Wino.Mail.ViewModels/Data/MailItemContainer.cs
index 08920973..67d5f590 100644
--- a/Wino.Mail.ViewModels/Data/MailItemContainer.cs
+++ b/Wino.Mail.ViewModels/Data/MailItemContainer.cs
@@ -6,6 +6,25 @@ public class MailItemContainer
{
public MailItemViewModel ItemViewModel { get; set; }
public ThreadMailItemViewModel ThreadViewModel { get; set; }
+
+ ///
+ /// Indicates whether the mail item is currently visible in the UI's Items collection.
+ /// For threaded items, this indicates if the individual mail item is visible (thread must be expanded).
+ ///
+ public bool IsItemVisible { get; set; }
+
+ ///
+ /// Indicates whether the thread expander (if applicable) is currently visible in the UI's Items collection.
+ /// Only relevant when ThreadViewModel is not null.
+ ///
+ public bool IsThreadVisible { get; set; }
+
+ ///
+ /// Indicates whether the container can be successfully navigated to in the UI.
+ /// For standalone items: true if IsItemVisible is true.
+ /// For threaded items: true if IsThreadVisible is true (the thread expander can be navigated to).
+ ///
+ public bool CanNavigate => ThreadViewModel != null ? IsThreadVisible : IsItemVisible;
public MailItemContainer(MailItemViewModel itemViewModel, ThreadMailItemViewModel threadViewModel) : this(itemViewModel)
{
diff --git a/Wino.Mail.ViewModels/Data/ThreadMailItemViewModel.cs b/Wino.Mail.ViewModels/Data/ThreadMailItemViewModel.cs
index 980762b5..3ceb7f11 100644
--- a/Wino.Mail.ViewModels/Data/ThreadMailItemViewModel.cs
+++ b/Wino.Mail.ViewModels/Data/ThreadMailItemViewModel.cs
@@ -110,4 +110,9 @@ public partial class ThreadMailItemViewModel : ObservableRecipient, IDisposable
NotifyPropertyChanges();
}
}
+
+ ///
+ /// Checks if this thread contains an email with the specified unique ID
+ ///
+ public bool HasUniqueId(Guid uniqueId) => _threadEmails.Any(email => email.MailCopy.UniqueId == uniqueId);
}
diff --git a/Wino.Mail.WinUI/App.xaml b/Wino.Mail.WinUI/App.xaml
index 02bfd708..bcdfb7e6 100644
--- a/Wino.Mail.WinUI/App.xaml
+++ b/Wino.Mail.WinUI/App.xaml
@@ -17,7 +17,7 @@
-
+
diff --git a/Wino.Mail.WinUI/Controls/Advanced/WinoItemsView.cs b/Wino.Mail.WinUI/Controls/Advanced/WinoItemsView.cs
index 8772925f..7e1c4af9 100644
--- a/Wino.Mail.WinUI/Controls/Advanced/WinoItemsView.cs
+++ b/Wino.Mail.WinUI/Controls/Advanced/WinoItemsView.cs
@@ -2,6 +2,7 @@
using System.Windows.Input;
using CommunityToolkit.WinUI;
using Microsoft.UI.Xaml.Controls;
+using Wino.Mail.ViewModels.Data;
namespace Wino.Mail.WinUI.Controls.Advanced;
@@ -43,4 +44,44 @@ public partial class WinoItemsView : ItemsView
// Trigger when scrolled past 90% of total height
if (progress >= 0.9) LoadMoreCommand?.Execute(null);
}
+
+ public bool SelectMailItemContainer(MailItemViewModel mailItemViewModel)
+ {
+ return true;
+ }
+
+ ///
+ /// Recursively clears all selections except the given mail.
+ ///
+ /// Exceptional mail item to be not unselected.
+ /// Whether expansion states of thread containers should stay as it is or not.
+ public void ClearSelections(MailItemViewModel? exceptViewModel = null, bool preserveThreadExpanding = false)
+ {
+ if (CastedItemsSource == null) return;
+
+ foreach (var item in CastedItemsSource)
+ {
+ if (item is MailItemViewModel mailItemViewModel)
+ {
+ if (mailItemViewModel != exceptViewModel)
+ {
+ mailItemViewModel.IsSelected = false;
+ }
+ }
+ else if (item is ThreadMailItemViewModel threadMailItemViewModel)
+ {
+ threadMailItemViewModel.IsSelected = false;
+
+ if (!preserveThreadExpanding) threadMailItemViewModel.IsThreadExpanded = false;
+
+ foreach (var childMail in threadMailItemViewModel.ThreadEmails)
+ {
+ if (childMail != exceptViewModel)
+ {
+ childMail.IsSelected = false;
+ }
+ }
+ }
+ }
+ }
}
diff --git a/Wino.Mail.WinUI/ShellWindow.xaml b/Wino.Mail.WinUI/ShellWindow.xaml
index 0eb46c36..c2f6c1ad 100644
--- a/Wino.Mail.WinUI/ShellWindow.xaml
+++ b/Wino.Mail.WinUI/ShellWindow.xaml
@@ -12,16 +12,17 @@
-
+
+
-
+
ChangeSelectionMode(ItemsViewSelectionMode.Multiple);
private void FolderPivotChanged(object sender, SelectionChangedEventArgs e)
{
@@ -130,20 +127,19 @@ public sealed partial class MailListPage : MailListPageAbstract,
ViewModel.SelectedPivotChangedCommand.Execute(null);
}
- private void ChangeSelectionMode(ListViewSelectionMode mode)
+ private void ChangeSelectionMode(ItemsViewSelectionMode mode)
{
- // ItemsView doesn't have a ChangeSelectionMode method like ListView
- // The selection mode is set in XAML and doesn't need to change dynamically for ItemsView
+ MailListView.SelectionMode = mode;
if (ViewModel?.PivotFolders != null)
{
- ViewModel.PivotFolders.ForEach(a => a.IsExtendedMode = mode == ListViewSelectionMode.Extended);
+ ViewModel.PivotFolders.ForEach(a => a.IsExtendedMode = mode == ItemsViewSelectionMode.Extended);
}
}
private void SelectionModeToggleUnchecked(object sender, RoutedEventArgs e)
{
- ChangeSelectionMode(ListViewSelectionMode.Extended);
+ ChangeSelectionMode(ItemsViewSelectionMode.Extended);
}
private void SelectAllCheckboxChecked(object sender, RoutedEventArgs e)
@@ -306,46 +302,54 @@ public sealed partial class MailListPage : MailListPageAbstract,
{
if (message.SelectedMailViewModel == null) return;
- //await ViewModel.ExecuteUIThread(async () =>
- //{
- // MailListView.ClearSelections(message.SelectedMailViewModel, true);
+ await ViewModel.ExecuteUIThread(async () =>
+ {
+ MailListView.ClearSelections(message.SelectedMailViewModel, true);
- // int retriedSelectionCount = 0;
- //trySelection:
+ int retriedSelectionCount = 0;
+ trySelection:
- // bool isSelected = MailListView.SelectMailItemContainer(message.SelectedMailViewModel);
+ bool isSelected = MailListView.SelectMailItemContainer(message.SelectedMailViewModel);
- // if (!isSelected)
- // {
- // for (int i = retriedSelectionCount; i < 5;)
- // {
- // // Retry with delay until the container is realized. Max 1 second.
- // await Task.Delay(200);
+ if (!isSelected)
+ {
+ for (int i = retriedSelectionCount; i < 5;)
+ {
+ // Retry with delay until the container is realized. Max 1 second.
+ await Task.Delay(200);
- // retriedSelectionCount++;
+ retriedSelectionCount++;
- // goto trySelection;
- // }
- // }
+ goto trySelection;
+ }
+ }
- // // Automatically scroll to the selected item.
- // // This is useful when creating draft.
- // if (isSelected && message.ScrollToItem)
- // {
- // var collectionContainer = ViewModel.MailCollection.GetMailItemContainer(message.SelectedMailViewModel.UniqueId);
+ // Automatically scroll to the selected item.
+ // This is useful when creating draft.
- // // Scroll to thread if available.
- // if (collectionContainer.ThreadViewModel != null)
- // {
- // MailListView.StartBringItemIntoView(collectionContainer.ThreadViewModel, new BringIntoViewOptions());
- // }
- // else if (collectionContainer.ItemViewModel != null)
- // {
- // MailListView.StartBringItemIntoView(collectionContainer.ItemViewModel, new BringIntoViewOptions());
- // }
+ if (isSelected && message.ScrollToItem)
+ {
+ var collectionContainer = ViewModel.MailCollection.GetMailItemContainer(message.SelectedMailViewModel.MailCopy.UniqueId);
- // }
- //});
+ // Scroll to thread if available.
+ // Find the item index on the UI. This is different than ListView.
+
+ int scrollIndex = -1;
+ if (collectionContainer.ThreadViewModel != null)
+ {
+ scrollIndex = ViewModel.MailCollection.IndexOf(collectionContainer.ThreadViewModel);
+ }
+ else if (collectionContainer.ItemViewModel != null)
+ {
+ scrollIndex = ViewModel.MailCollection.IndexOf(collectionContainer.ItemViewModel);
+ }
+
+ if (scrollIndex >= 0)
+ {
+ MailListView.StartBringItemIntoView(scrollIndex, new BringIntoViewOptions() { AnimationDesired = true });
+ }
+ }
+ });
}
private void SearchBoxFocused(object sender, RoutedEventArgs e)
@@ -501,8 +505,6 @@ public sealed partial class MailListPage : MailListPageAbstract,
private void DeleteAllInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
=> ViewModel.ExecuteMailOperationCommand.Execute(MailOperation.SoftDelete);
-
-
///
/// Animates the rotation using high-performance Composition APIs
///
@@ -539,6 +541,26 @@ public sealed partial class MailListPage : MailListPageAbstract,
{
UpdateSelectAllButtonStatus();
UpdateAdaptiveness();
+
+ SynchronizeSelectedItems();
+ }
+
+ private static object _selectedItemsLock = new object();
+ private void SynchronizeSelectedItems()
+ {
+ lock (_selectedItemsLock)
+ {
+ ViewModel.SelectedItems.Clear();
+
+ foreach (var item in MailListView.SelectedItems)
+ {
+ if (item is MailItemViewModel mailItem)
+ {
+ if (!mailItem.IsSelected) mailItem.IsSelected = true;
+ if (!ViewModel.SelectedItems.Contains(mailItem)) ViewModel.SelectedItems.Add(mailItem);
+ }
+ }
+ }
}
private void ThreadContainerRightTapped(object sender, RightTappedRoutedEventArgs e)
diff --git a/Wino.Mail.WinUI/Views/Settings/PersonalizationPage.xaml b/Wino.Mail.WinUI/Views/Settings/PersonalizationPage.xaml
index 6c8076b3..776e6523 100644
--- a/Wino.Mail.WinUI/Views/Settings/PersonalizationPage.xaml
+++ b/Wino.Mail.WinUI/Views/Settings/PersonalizationPage.xaml
@@ -151,8 +151,8 @@
@@ -172,6 +172,13 @@
+
+
diff --git a/Wino.Mail.WinUI/Wino.Mail.WinUI.csproj b/Wino.Mail.WinUI/Wino.Mail.WinUI.csproj
index 666cec74..8f262f1d 100644
--- a/Wino.Mail.WinUI/Wino.Mail.WinUI.csproj
+++ b/Wino.Mail.WinUI/Wino.Mail.WinUI.csproj
@@ -112,6 +112,7 @@
+