Skip to content

Refactor: Remove DispatcherQueueTimer for updating date display #17322

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions src/Files.App/Data/Items/FileProperties.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright (c) Files Community
// Licensed under the MIT License.

using Files.App.Utils;
using Microsoft.UI.Dispatching;
using System.Collections.Generic;

namespace Files.App.Data.Items
{
/// <summary>
/// Manages a single, application-wide timer for updating relative date strings in file properties.
/// This centralizes the logic for date updates, reducing overhead compared to individual timers.
/// </summary>
public sealed class FileProperties
{
private static readonly List<ListedItem> _items = new();
private static readonly DispatcherQueueTimer _timer = MainWindow.Instance.DispatcherQueue.CreateTimer();
private static readonly object _lock = new();

static FileProperties()
{
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += Timer_Tick;
_timer.Start();
}

/// <summary>
/// Registers a ListedItem for potential future relative date updates.
/// </summary>
/// <param name="item">The item to register for updates</param>
public static void TryAdd(ListedItem item)
{
if (item is null)
return;

lock (_lock)
{
if (!_items.Contains(item))
_items.Add(item);
}
}

/// <summary>
/// Removes a ListedItem from the update list.
/// </summary>
/// <param name="item">The item to remove</param>
public static void Remove(ListedItem item)
{
if (item is null)
return;

lock (_lock)
{
_items.Remove(item);
}
}

private static void Timer_Tick(object? sender, object e)
{
if (App.AppModel.IsMainWindowClosed)
return;

List<ListedItem> itemsToUpdate;
lock (_lock)
{
// Only update items that have date differences (within the last 7 days)
itemsToUpdate = _items.FindAll(item =>
IsDateDiff(item.ItemDateAccessedReal) ||
IsDateDiff(item.ItemDateCreatedReal) ||
IsDateDiff(item.ItemDateModifiedReal) ||
(item is RecycleBinItem recycleBinItem && IsDateDiff(recycleBinItem.ItemDateDeletedReal)) ||
(item is IGitItem gitItem && gitItem.GitLastCommitDate is DateTimeOffset offset && IsDateDiff(offset)));
}

// Update the date strings for items that need it
foreach (var item in itemsToUpdate)
{
item.UpdateDateModified();
item.UpdateDateCreated();
item.UpdateDateAccessed();

if (item is RecycleBinItem recycleBinItem)
{
// Trigger property change for deleted date
recycleBinItem.ItemDateDeletedReal = recycleBinItem.ItemDateDeletedReal;
}

if (item is IGitItem gitItem && gitItem.GitLastCommitDate.HasValue)
{
// Trigger property change for git commit date
gitItem.GitLastCommitDate = gitItem.GitLastCommitDate;
}
}
}

private static bool IsDateDiff(DateTimeOffset offset) => (DateTimeOffset.Now - offset).TotalDays < 7;
}
}
55 changes: 46 additions & 9 deletions src/Files.App/Data/Items/ListedItem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Files Community
// Licensed under the MIT License.

using Files.App.Data.Items;
using Files.App.ViewModels.Properties;
using Files.Shared.Helpers;
using FluentFTP;
Expand Down Expand Up @@ -287,15 +288,45 @@

public string ItemDateAccessed { get; private set; }

/// <summary>
/// Updates the formatted date modified string and triggers property change notification.
/// </summary>
public void UpdateDateModified()
{
ItemDateModified = dateTimeFormatter.ToShortLabel(itemDateModifiedReal);
OnPropertyChanged(nameof(ItemDateModified));
}

/// <summary>
/// Updates the formatted date created string and triggers property change notification.
/// </summary>
public void UpdateDateCreated()
{
ItemDateCreated = dateTimeFormatter.ToShortLabel(itemDateCreatedReal);
OnPropertyChanged(nameof(ItemDateCreated));
}

/// <summary>
/// Updates the formatted date accessed string and triggers property change notification.
/// </summary>
public void UpdateDateAccessed()
{
ItemDateAccessed = dateTimeFormatter.ToShortLabel(itemDateAccessedReal);
OnPropertyChanged(nameof(ItemDateAccessed));
}

private DateTimeOffset itemDateModifiedReal;
public DateTimeOffset ItemDateModifiedReal
{
get => itemDateModifiedReal;
set
{
ItemDateModified = dateTimeFormatter.ToShortLabel(value);
itemDateModifiedReal = value;
OnPropertyChanged(nameof(ItemDateModified));
if (value != itemDateModifiedReal)
{
itemDateModifiedReal = value;
FileProperties.TryAdd(this);

Check failure on line 327 in src/Files.App/Data/Items/ListedItem.cs

View workflow job for this annotation

GitHub Actions / build (Debug, arm64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'

Check failure on line 327 in src/Files.App/Data/Items/ListedItem.cs

View workflow job for this annotation

GitHub Actions / build (Debug, x64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'

Check failure on line 327 in src/Files.App/Data/Items/ListedItem.cs

View workflow job for this annotation

GitHub Actions / build (Release, x64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'

Check failure on line 327 in src/Files.App/Data/Items/ListedItem.cs

View workflow job for this annotation

GitHub Actions / build (Release, arm64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'
UpdateDateModified();
}
}
}

Expand All @@ -305,9 +336,12 @@
get => itemDateCreatedReal;
set
{
ItemDateCreated = dateTimeFormatter.ToShortLabel(value);
itemDateCreatedReal = value;
OnPropertyChanged(nameof(ItemDateCreated));
if (value != itemDateCreatedReal)
{
itemDateCreatedReal = value;
FileProperties.TryAdd(this);

Check failure on line 342 in src/Files.App/Data/Items/ListedItem.cs

View workflow job for this annotation

GitHub Actions / build (Debug, arm64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'

Check failure on line 342 in src/Files.App/Data/Items/ListedItem.cs

View workflow job for this annotation

GitHub Actions / build (Debug, x64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'

Check failure on line 342 in src/Files.App/Data/Items/ListedItem.cs

View workflow job for this annotation

GitHub Actions / build (Release, x64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'

Check failure on line 342 in src/Files.App/Data/Items/ListedItem.cs

View workflow job for this annotation

GitHub Actions / build (Release, arm64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'
UpdateDateCreated();
}
}
}

Expand All @@ -317,9 +351,12 @@
get => itemDateAccessedReal;
set
{
ItemDateAccessed = dateTimeFormatter.ToShortLabel(value);
itemDateAccessedReal = value;
OnPropertyChanged(nameof(ItemDateAccessed));
if (value != itemDateAccessedReal)
{
itemDateAccessedReal = value;
FileProperties.TryAdd(this);

Check failure on line 357 in src/Files.App/Data/Items/ListedItem.cs

View workflow job for this annotation

GitHub Actions / build (Debug, arm64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'

Check failure on line 357 in src/Files.App/Data/Items/ListedItem.cs

View workflow job for this annotation

GitHub Actions / build (Debug, x64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'

Check failure on line 357 in src/Files.App/Data/Items/ListedItem.cs

View workflow job for this annotation

GitHub Actions / build (Release, x64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'

Check failure on line 357 in src/Files.App/Data/Items/ListedItem.cs

View workflow job for this annotation

GitHub Actions / build (Release, arm64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'
UpdateDateAccessed();
}
}
}

Expand Down
30 changes: 16 additions & 14 deletions src/Files.App/ViewModels/ShellViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,12 @@ await dispatcherQueue.EnqueueOrInvokeAsync(() =>
case nameof(UserSettingsService.GeneralSettingsService.ShowFilterHeader):
OnPropertyChanged(nameof(ShowFilterHeader));
break;
case nameof(UserSettingsService.GeneralSettingsService.DateTimeFormat):
await dispatcherQueue.EnqueueOrInvokeAsync(() =>
{
UpdateDateDisplay(true);
});
break;
}
}

Expand Down Expand Up @@ -2720,20 +2726,16 @@ public void CancelSearch()

public void UpdateDateDisplay(bool isFormatChange)
{
filesAndFolders.ToList().AsParallel().ForAll(async item =>
{
// Reassign values to update date display
if (isFormatChange || IsDateDiff(item.ItemDateAccessedReal))
await dispatcherQueue.EnqueueOrInvokeAsync(() => item.ItemDateAccessedReal = item.ItemDateAccessedReal);
if (isFormatChange || IsDateDiff(item.ItemDateCreatedReal))
await dispatcherQueue.EnqueueOrInvokeAsync(() => item.ItemDateCreatedReal = item.ItemDateCreatedReal);
if (isFormatChange || IsDateDiff(item.ItemDateModifiedReal))
await dispatcherQueue.EnqueueOrInvokeAsync(() => item.ItemDateModifiedReal = item.ItemDateModifiedReal);
if (item is RecycleBinItem recycleBinItem && (isFormatChange || IsDateDiff(recycleBinItem.ItemDateDeletedReal)))
await dispatcherQueue.EnqueueOrInvokeAsync(() => recycleBinItem.ItemDateDeletedReal = recycleBinItem.ItemDateDeletedReal);
if (item is IGitItem gitItem && gitItem.GitLastCommitDate is DateTimeOffset offset && (isFormatChange || IsDateDiff(offset)))
await dispatcherQueue.EnqueueOrInvokeAsync(() => gitItem.GitLastCommitDate = gitItem.GitLastCommitDate);
});
if (!isFormatChange)
return;

var items = filesAndFolders.ToList();
foreach (var item in items)
{
item.UpdateDateModified();
item.UpdateDateCreated();
item.UpdateDateAccessed();
}
}

private static bool IsDateDiff(DateTimeOffset offset) => (DateTimeOffset.Now - offset).TotalDays < 7;
Expand Down
14 changes: 0 additions & 14 deletions src/Files.App/Views/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ public sealed partial class MainPage : Page

private bool keyReleased = true;

private DispatcherQueueTimer _updateDateDisplayTimer;

public MainPage()
{
InitializeComponent();
Expand All @@ -51,10 +49,6 @@ public MainPage()
ViewModel.PropertyChanged += ViewModel_PropertyChanged;
UserSettingsService.OnSettingChangedEvent += UserSettingsService_OnSettingChangedEvent;

_updateDateDisplayTimer = DispatcherQueue.CreateTimer();
_updateDateDisplayTimer.Interval = TimeSpan.FromSeconds(1);
_updateDateDisplayTimer.Tick += UpdateDateDisplayTimer_Tick;

ApplySidebarWidthState();
}

Expand Down Expand Up @@ -285,18 +279,10 @@ AppLifecycleHelper.AppEnvironment is not AppEnvironment.Dev &&

private void PreviewPane_Loaded(object sender, RoutedEventArgs e)
{
_updateDateDisplayTimer.Start();
}

private void PreviewPane_Unloaded(object sender, RoutedEventArgs e)
{
_updateDateDisplayTimer.Stop();
}

private void UpdateDateDisplayTimer_Tick(object sender, object e)
{
if (!App.AppModel.IsMainWindowClosed)
InfoPane?.ViewModel.UpdateDateDisplay();
}

private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
Expand Down
20 changes: 0 additions & 20 deletions src/Files.App/Views/Properties/DetailsPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,9 @@ namespace Files.App.Views.Properties
{
public sealed partial class DetailsPage : BasePropertiesPage
{
private readonly DispatcherQueueTimer _updateDateDisplayTimer;

public DetailsPage()
{
InitializeComponent();

_updateDateDisplayTimer = DispatcherQueue.CreateTimer();
_updateDateDisplayTimer.Interval = TimeSpan.FromSeconds(1);
_updateDateDisplayTimer.Tick += UpdateDateDisplayTimer_Tick;
_updateDateDisplayTimer.Start();
}

protected override async void Properties_Loaded(object sender, RoutedEventArgs e)
Expand Down Expand Up @@ -77,21 +70,8 @@ private async void ClearPropertiesConfirmation_Click(object sender, RoutedEventA
}
}

private void UpdateDateDisplayTimer_Tick(object sender, object e)
{
if (App.AppModel.PropertiesWindowCount == 0)
return;

ViewModel.PropertySections.ForEach(section => section.ForEach(property =>
{
if (property.Value is DateTimeOffset)
property.UpdateValueText();
}));
}

public override void Dispose()
{
_updateDateDisplayTimer.Stop();
}
}
}
18 changes: 0 additions & 18 deletions src/Files.App/Views/Properties/GeneralPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,9 @@
{
public sealed partial class GeneralPage : BasePropertiesPage
{
private readonly DispatcherQueueTimer _updateDateDisplayTimer;
public GeneralPage()
{
InitializeComponent();

_updateDateDisplayTimer = DispatcherQueue.CreateTimer();
_updateDateDisplayTimer.Interval = TimeSpan.FromSeconds(1);
_updateDateDisplayTimer.Tick += UpdateDateDisplayTimer_Tick;
_updateDateDisplayTimer.Start();
}

private void ItemFileName_GettingFocus(UIElement _, GettingFocusEventArgs e)
Expand All @@ -42,17 +36,6 @@
ItemFileName.Text += match.Value;
}

private void UpdateDateDisplayTimer_Tick(object sender, object e)
{
if (App.AppModel.PropertiesWindowCount == 0)
return;

// Reassign values to update date display
ViewModel.ItemCreatedTimestampReal = ViewModel.ItemCreatedTimestampReal;
ViewModel.ItemModifiedTimestampReal = ViewModel.ItemModifiedTimestampReal;
ViewModel.ItemAccessedTimestampReal = ViewModel.ItemAccessedTimestampReal;
}

public override async Task<bool> SaveChangesAsync()
{
return BaseProperties switch
Expand All @@ -60,7 +43,7 @@
DriveProperties properties => SaveDrive(properties.Drive),
LibraryProperties properties => await SaveLibraryAsync(properties.Library),
CombinedProperties properties => await SaveCombinedAsync(properties.List),
FileProperties properties => await SaveBaseAsync(properties.Item),

Check failure on line 46 in src/Files.App/Views/Properties/GeneralPage.xaml.cs

View workflow job for this annotation

GitHub Actions / build (Debug, arm64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'

Check failure on line 46 in src/Files.App/Views/Properties/GeneralPage.xaml.cs

View workflow job for this annotation

GitHub Actions / build (Debug, x64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'

Check failure on line 46 in src/Files.App/Views/Properties/GeneralPage.xaml.cs

View workflow job for this annotation

GitHub Actions / build (Release, x64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'

Check failure on line 46 in src/Files.App/Views/Properties/GeneralPage.xaml.cs

View workflow job for this annotation

GitHub Actions / build (Release, arm64)

'FileProperties' is an ambiguous reference between 'Files.App.Data.Items.FileProperties' and 'Files.App.ViewModels.Properties.FileProperties'
FolderProperties properties => await SaveBaseAsync(properties.Item),
};

Expand Down Expand Up @@ -194,7 +177,6 @@

public override void Dispose()
{
_updateDateDisplayTimer.Stop();
}
}
}
Loading
Loading