2025-11-15 14:52:01 +01:00
|
|
|
using System;
|
2025-10-26 14:53:22 +01:00
|
|
|
using System.Collections.Generic;
|
2025-10-18 11:45:10 +02:00
|
|
|
using System.Windows.Input;
|
|
|
|
|
using CommunityToolkit.WinUI;
|
2025-10-03 15:46:38 +02:00
|
|
|
using Microsoft.UI.Xaml.Controls;
|
2025-10-18 22:16:28 +02:00
|
|
|
using Wino.Mail.ViewModels.Data;
|
2025-10-03 15:46:38 +02:00
|
|
|
|
|
|
|
|
namespace Wino.Mail.WinUI.Controls.Advanced;
|
|
|
|
|
|
2025-10-26 14:53:22 +01:00
|
|
|
[Obsolete("ItemsView sucks. Hard to deal with virtualization issues. Use ListView. This control is here to wise up anyone who tries to use it.")]
|
2025-10-03 15:46:38 +02:00
|
|
|
public partial class WinoItemsView : ItemsView
|
|
|
|
|
{
|
2025-10-18 11:45:10 +02:00
|
|
|
private const string PART_ScrollView = nameof(PART_ScrollView);
|
|
|
|
|
|
|
|
|
|
private ScrollView? _internalScrollView;
|
|
|
|
|
|
|
|
|
|
[GeneratedDependencyProperty]
|
2025-11-14 18:51:48 +01:00
|
|
|
public partial ICommand? LoadMoreCommand { get; set; }
|
2025-10-18 11:45:10 +02:00
|
|
|
|
2025-10-03 15:46:38 +02:00
|
|
|
public IEnumerable<object>? CastedItemsSource => ItemsSource as IEnumerable<object>;
|
|
|
|
|
|
|
|
|
|
public WinoItemsView()
|
|
|
|
|
{
|
|
|
|
|
DefaultStyleKey = typeof(ItemsView);
|
|
|
|
|
}
|
2025-10-18 11:45:10 +02:00
|
|
|
|
|
|
|
|
protected override void OnApplyTemplate()
|
|
|
|
|
{
|
|
|
|
|
base.OnApplyTemplate();
|
|
|
|
|
|
|
|
|
|
_internalScrollView = GetTemplateChild("PART_ScrollView") as ScrollView ?? throw new System.Exception("Can't find the ScrollView in WinoItemsView.");
|
|
|
|
|
|
|
|
|
|
_internalScrollView.ViewChanged -= InternalScrollViewPositionChanged;
|
|
|
|
|
_internalScrollView.ViewChanged += InternalScrollViewPositionChanged;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void InternalScrollViewPositionChanged(ScrollView sender, object args)
|
|
|
|
|
{
|
|
|
|
|
if (_internalScrollView == null) return;
|
|
|
|
|
|
|
|
|
|
// No need to raise init request if there are no items in the list.
|
|
|
|
|
if (ItemsSource == null) return;
|
|
|
|
|
|
|
|
|
|
double progress = sender.VerticalOffset / sender.ScrollableHeight;
|
|
|
|
|
|
|
|
|
|
// Trigger when scrolled past 90% of total height
|
|
|
|
|
if (progress >= 0.9) LoadMoreCommand?.Execute(null);
|
|
|
|
|
}
|
2025-10-18 22:16:28 +02:00
|
|
|
|
|
|
|
|
public bool SelectMailItemContainer(MailItemViewModel mailItemViewModel)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Recursively clears all selections except the given mail.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="exceptViewModel">Exceptional mail item to be not unselected.</param>
|
|
|
|
|
/// <param name="preserveThreadExpanding">Whether expansion states of thread containers should stay as it is or not.</param>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-10-03 15:46:38 +02:00
|
|
|
}
|