Fix search and global title bar issues.

This commit is contained in:
Burak Kaan Köse
2026-03-25 09:45:49 +01:00
parent 7aad6b0157
commit 0056f372b9
17 changed files with 417 additions and 168 deletions
@@ -10,6 +10,7 @@
xmlns:domain="using:Wino.Core.Domain"
xmlns:helpers="using:Wino.Helpers"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:winoControls="using:Wino.Mail.WinUI.Controls"
mc:Ignorable="d">
<Page.Resources>
@@ -20,7 +21,18 @@
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<winoControls:CalendarTitleBarContent
x:Name="CalendarToolbar"
Grid.Row="0"
Margin="4,0,7,8" />
<Border
Grid.Row="1"
Margin="4,0,7,7"
BorderBrush="{StaticResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
@@ -34,7 +46,10 @@
VisibleRange="{x:Bind ViewModel.CurrentVisibleRange, Mode=OneWay}" />
</Border>
<Canvas x:Name="CalendarOverlayCanvas" IsHitTestVisible="False">
<Canvas
x:Name="CalendarOverlayCanvas"
Grid.RowSpan="2"
IsHitTestVisible="False">
<Grid
x:Name="TeachingTipPositionerGrid"
Background="Transparent"
@@ -1,24 +1,53 @@
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Navigation;
using Windows.Foundation;
using Wino.Core.Domain;
using Wino.Calendar.Controls;
using Wino.Calendar.Views.Abstract;
using Wino.Core.Domain.Entities.Calendar;
using Wino.Core.Domain.Models.Calendar;
using Wino.Core.Domain.Interfaces;
using Wino.Mail.WinUI;
using Wino.Mail.WinUI.Interfaces;
using Wino.Mail.WinUI.Models;
using Wino.Messaging.Client.Calendar;
namespace Wino.Calendar.Views;
public sealed partial class CalendarPage : CalendarPageAbstract
public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearchHost
{
private const int PopupDialogOffset = 12;
private ICalendarShellClient CalendarShellClient { get; } = WinoApplication.Current.Services.GetRequiredService<ICalendarShellClient>();
private CancellationTokenSource? _searchCancellationTokenSource;
private long _calendarTypeSelectorChangedToken;
public ObservableCollection<TitleBarSearchSuggestion> SearchSuggestions { get; } = [];
public string SearchText { get; set; } = string.Empty;
public string SearchPlaceholderText => Translator.SearchBarPlaceholder;
public CalendarPage()
{
InitializeComponent();
_calendarTypeSelectorChangedToken = CalendarToolbar.RegisterSelectedTypeChanged(CalendarTypeSelectorSelectedTypeChanged);
CalendarToolbar.PreviousDateRequested += CalendarToolbarPreviousDateRequested;
CalendarToolbar.NextDateRequested += CalendarToolbarNextDateRequested;
ViewModel.PropertyChanged += ViewModelPropertyChanged;
CalendarShellClient.PropertyChanged += CalendarShellClientPropertyChanged;
CalendarShellClient.StatePersistenceService.StatePropertyChanged += CalendarStatePersistenceServiceChanged;
Unloaded += CalendarPageUnloaded;
RefreshCalendarToolbar();
}
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
@@ -29,6 +58,7 @@ public sealed partial class CalendarPage : CalendarPageAbstract
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
RefreshCalendarToolbar();
if (e.NavigationMode == NavigationMode.Back && ViewModel.RestoreVisibleState())
{
@@ -46,6 +76,67 @@ public sealed partial class CalendarPage : CalendarPageAbstract
WeakReferenceMessenger.Default.Send(new LoadCalendarMessage(request));
}
public async Task OnTitleBarSearchTextChangedAsync()
{
_searchCancellationTokenSource?.Cancel();
_searchCancellationTokenSource?.Dispose();
_searchCancellationTokenSource = null;
SearchSuggestions.Clear();
if (string.IsNullOrWhiteSpace(SearchText))
return;
_searchCancellationTokenSource = new CancellationTokenSource();
var cancellationToken = _searchCancellationTokenSource.Token;
try
{
await Task.Delay(150, cancellationToken);
var results = await ViewModel.SearchCalendarItemsAsync(SearchText, 6, cancellationToken);
if (cancellationToken.IsCancellationRequested)
return;
foreach (var result in results)
{
var subtitleParts = new[]
{
result.AssignedCalendar?.MailAccount?.Name,
result.AssignedCalendar?.Name,
result.LocalStartDate.ToString("g")
}.Where(part => !string.IsNullOrWhiteSpace(part));
SearchSuggestions.Add(new TitleBarSearchSuggestion(result.Title, string.Join(" • ", subtitleParts), result));
}
}
catch (OperationCanceledException)
{
}
}
public void OnTitleBarSearchSuggestionChosen(TitleBarSearchSuggestion suggestion)
{
SearchText = suggestion.Title;
}
public async Task OnTitleBarSearchSubmittedAsync(string queryText, TitleBarSearchSuggestion? chosenSuggestion)
{
SearchText = queryText;
if (chosenSuggestion?.Tag is CalendarItem selectedItem)
{
ViewModel.OpenCalendarSearchResult(selectedItem);
return;
}
var result = (await ViewModel.SearchCalendarItemsAsync(queryText, 1, CancellationToken.None)).FirstOrDefault();
if (result != null)
{
ViewModel.OpenCalendarSearchResult(result);
}
}
private void CalendarSurfaceEmptySlotTapped(object sender, CalendarEmptySlotTappedEventArgs e)
{
if (ViewModel.DisplayDetailsCalendarItemViewModel != null)
@@ -111,4 +202,69 @@ public sealed partial class CalendarPage : CalendarPageAbstract
private void EndTimeDurationSubmitted(ComboBox sender, ComboBoxTextSubmittedEventArgs args)
=> ViewModel.SelectedEndTimeString = args.Text;
private void CalendarTypeSelectorSelectedTypeChanged(DependencyObject sender, DependencyProperty dp)
{
var selectedType = CalendarToolbar.SelectedType;
if (CalendarShellClient.StatePersistenceService.CalendarDisplayType != selectedType)
{
CalendarShellClient.StatePersistenceService.CalendarDisplayType = selectedType;
}
}
private void CalendarToolbarPreviousDateRequested(object? sender, EventArgs e)
=> CalendarShellClient.PreviousDateRangeCommand.Execute(null);
private void CalendarToolbarNextDateRequested(object? sender, EventArgs e)
=> CalendarShellClient.NextDateRangeCommand.Execute(null);
private void ViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(ViewModel.VisibleDateRangeText))
{
RefreshCalendarToolbar();
}
}
private void CalendarShellClientPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(ICalendarShellClient.VisibleDateRangeText))
{
RefreshCalendarToolbar();
}
}
private void CalendarStatePersistenceServiceChanged(object? sender, string propertyName)
{
if (propertyName == nameof(IStatePersistanceService.CalendarDisplayType) ||
propertyName == nameof(IStatePersistanceService.DayDisplayCount))
{
RefreshCalendarToolbar();
}
}
private void RefreshCalendarToolbar()
{
CalendarToolbar.VisibleDateRangeText = CalendarShellClient.VisibleDateRangeText;
CalendarToolbar.TodayClickedCommand = CalendarShellClient.TodayClickedCommand;
CalendarToolbar.DisplayDayCount = CalendarShellClient.StatePersistenceService.DayDisplayCount;
if (CalendarToolbar.SelectedType != CalendarShellClient.StatePersistenceService.CalendarDisplayType)
{
CalendarToolbar.SelectedType = CalendarShellClient.StatePersistenceService.CalendarDisplayType;
}
}
private void CalendarPageUnloaded(object sender, RoutedEventArgs e)
{
CalendarToolbar.UnregisterSelectedTypeChanged(_calendarTypeSelectorChangedToken);
CalendarToolbar.PreviousDateRequested -= CalendarToolbarPreviousDateRequested;
CalendarToolbar.NextDateRequested -= CalendarToolbarNextDateRequested;
ViewModel.PropertyChanged -= ViewModelPropertyChanged;
CalendarShellClient.PropertyChanged -= CalendarShellClientPropertyChanged;
CalendarShellClient.StatePersistenceService.StatePropertyChanged -= CalendarStatePersistenceServiceChanged;
_searchCancellationTokenSource?.Cancel();
_searchCancellationTokenSource?.Dispose();
Unloaded -= CalendarPageUnloaded;
}
}