Skip to content

Commit 4863423

Browse files
authored
Fix: Backported recent fixes into the servicing branch (#12338)
2 parents d31a0bd + 305b1b9 commit 4863423

File tree

10 files changed

+83
-35
lines changed

10 files changed

+83
-35
lines changed

src/Files.App/BaseLayout.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ internal set
218218
//if (!(value?.All(x => selectedItems?.Contains(x) ?? false) ?? value == selectedItems))
219219
if (value != selectedItems)
220220
{
221-
if (value?.FirstOrDefault() != selectedItems?.FirstOrDefault())
221+
if (value?.FirstOrDefault() != PreviewPaneViewModel.SelectedItem)
222222
{
223223
// Update preview pane properties
224224
PreviewPaneViewModel.IsItemSelected = value?.Count > 0;

src/Files.App/DataModels/SidebarPinnedModel.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ public async Task<LocationItem> CreateLocationItemFromPathAsync(string path)
115115
{
116116
var iconData = await FileThumbnailHelper.LoadIconFromStorageItemAsync(res.Result, 96u, ThumbnailMode.ListView);
117117
locationItem.IconData = iconData;
118-
locationItem.Icon = await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => locationItem.IconData.ToBitmapAsync());
118+
119+
if (locationItem.IconData is not null)
120+
locationItem.Icon = await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => locationItem.IconData.ToBitmapAsync());
119121
}
120122

121123
if (locationItem.IconData is null)

src/Files.App/Helpers/BitmapHelper.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,22 @@ public static async Task<BitmapImage> ToBitmapAsync(this byte[]? data, int decod
1919
return null;
2020
}
2121

22-
using var ms = new MemoryStream(data);
23-
var image = new BitmapImage();
24-
if (decodeSize > 0)
22+
try
23+
{
24+
using var ms = new MemoryStream(data);
25+
var image = new BitmapImage();
26+
if (decodeSize > 0)
27+
{
28+
image.DecodePixelWidth = decodeSize;
29+
image.DecodePixelHeight = decodeSize;
30+
}
31+
await image.SetSourceAsync(ms.AsRandomAccessStream());
32+
return image;
33+
}
34+
catch (Exception)
2535
{
26-
image.DecodePixelWidth = decodeSize;
27-
image.DecodePixelHeight = decodeSize;
36+
return null;
2837
}
29-
await image.SetSourceAsync(ms.AsRandomAccessStream());
30-
return image;
3138
}
3239

3340
/// <summary>

src/Files.App/Helpers/FileOperationsHelpers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ public static void TryCancelOperation(string operationId)
522522
{
523523
Name = x.ProcessName,
524524
Pid = x.Id,
525-
FileName = x.MainModule?.FileName,
525+
FileName = SafetyExtensions.IgnoreExceptions(() => x.MainModule?.FileName),
526526
AppName = SafetyExtensions.IgnoreExceptions(() => x.MainModule?.FileVersionInfo?.FileDescription)
527527
}).ToList();
528528
processes.ForEach(x => x.Dispose());

src/Files.App/Resources/PreviewPanePropertiesInformation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@
332332
"SectionResource": "Document",
333333
"Property": "System.Document.TotalEditingTime",
334334
"IsReadOnly": true,
335+
"DisplayFunctionName": "FormatDuration",
335336
"ID": null
336337
},
337338
{

src/Files.App/Resources/PropertiesInformation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@
434434
"SectionResource": "Document",
435435
"Property": "System.Document.TotalEditingTime",
436436
"IsReadOnly": true,
437+
"DisplayFunctionName": "FormatDuration",
437438
"ID": null
438439
},
439440
{

src/Files.App/Shell/ContextMenu.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ public async Task<bool> InvokeVerb(string? verb)
5252
if (string.IsNullOrEmpty(verb))
5353
return false;
5454

55+
var item = Items.Where(x => x.CommandString == verb).FirstOrDefault();
56+
if (item is not null && item.ID >= 0)
57+
// Prefer invocation by ID
58+
return await InvokeItem(item.ID);
59+
5560
try
5661
{
5762
var currentWindows = Win32API.GetDesktopWindows();
@@ -76,10 +81,10 @@ public async Task<bool> InvokeVerb(string? verb)
7681
return false;
7782
}
7883

79-
public async Task InvokeItem(int itemID)
84+
public async Task<bool> InvokeItem(int itemID)
8085
{
8186
if (itemID < 0)
82-
return;
87+
return false;
8388

8489
try
8590
{
@@ -93,13 +98,16 @@ public async Task InvokeItem(int itemID)
9398
pici.cbSize = (uint)Marshal.SizeOf(pici);
9499

95100
await owningThread.PostMethod(() => cMenu.InvokeCommand(pici));
96-
97101
Win32API.BringToForeground(currentWindows);
102+
103+
return true;
98104
}
99105
catch (Exception ex) when (ex is COMException or UnauthorizedAccessException)
100106
{
101107
Debug.WriteLine(ex);
102108
}
109+
110+
return false;
103111
}
104112

105113
#region FactoryMethods

src/Files.App/ViewModels/ItemViewModel.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public ListedItem CurrentFolder
104104

105105
public string WorkingDirectory { get; private set; }
106106

107-
private StorageFolderWithPath currentStorageFolder;
107+
private StorageFolderWithPath? currentStorageFolder;
108108
private StorageFolderWithPath workingRoot;
109109

110110
public delegate void WorkingDirectoryModifiedEventHandler(object sender, WorkingDirectoryModifiedEventArgs e);
@@ -1400,7 +1400,7 @@ public async Task EnumerateItemsFromSpecialFolderAsync(string path)
14001400
{
14011401
var isFtp = FtpHelpers.IsFtpPath(path);
14021402

1403-
CurrentFolder = new ListedItem(null)
1403+
CurrentFolder = new ListedItem(null!)
14041404
{
14051405
PrimaryItemAttribute = StorageItemTypes.Folder,
14061406
ItemPropertiesInitialized = true,
@@ -1569,22 +1569,22 @@ await DialogDisplayHelper.ShowDialogAsync(
15691569
if (enumFromStorageFolder)
15701570
{
15711571
var basicProps = await rootFolder?.GetBasicPropertiesAsync();
1572-
var currentFolder = library ?? new ListedItem(rootFolder.FolderRelativeId)
1572+
var currentFolder = library ?? new ListedItem(rootFolder?.FolderRelativeId ?? string.Empty)
15731573
{
15741574
PrimaryItemAttribute = StorageItemTypes.Folder,
15751575
ItemPropertiesInitialized = true,
1576-
ItemNameRaw = rootFolder.DisplayName,
1576+
ItemNameRaw = rootFolder?.DisplayName ?? string.Empty,
15771577
ItemDateModifiedReal = basicProps.DateModified,
1578-
ItemType = rootFolder.DisplayType,
1578+
ItemType = rootFolder?.DisplayType ?? string.Empty,
15791579
FileImage = null,
15801580
LoadFileIcon = false,
1581-
ItemPath = string.IsNullOrEmpty(rootFolder.Path) ? currentStorageFolder.Path : rootFolder.Path,
1581+
ItemPath = string.IsNullOrEmpty(rootFolder?.Path) ? currentStorageFolder?.Path ?? string.Empty : rootFolder.Path,
15821582
FileSize = null,
15831583
FileSizeBytes = 0,
15841584
};
15851585

15861586
if (library is null)
1587-
currentFolder.ItemDateCreatedReal = rootFolder.DateCreated;
1587+
currentFolder.ItemDateCreatedReal = rootFolder?.DateCreated ?? DateTimeOffset.Now;
15881588

15891589
CurrentFolder = currentFolder;
15901590
await EnumFromStorageFolderAsync(path, rootFolder, currentStorageFolder, cancellationToken);

src/Files.App/ViewModels/Properties/FileProperty.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,15 @@ public async static Task<List<FileProperty>> RetrieveAndInitializePropertiesAsyn
324324
private static readonly Dictionary<string, Func<object, string>> DisplayFuncs = new Dictionary<string, Func<object, string>>()
325325
{
326326
{ "DivideBy1000", input => (((uint) input)/1000).ToString() },
327-
{ "FormatDuration", input => new TimeSpan(Convert.ToInt64(input)).ToString("hh':'mm':'ss")},
327+
{ "FormatDuration", input => TimeSpanToString(new TimeSpan(Convert.ToInt64(input)))},
328328
{ "Fraction" , input => ((double)input).ToFractions(2000)},
329329
{ "AddF" , input => $"f/{(double)input}"},
330330
{ "AddISO" , input => $"ISO-{(UInt16)input}"},
331331
{ "RoundDouble" , input => $"{Math.Round((double)input)}"},
332332
{ "UnitMM" , input => $"{(double)input} mm"},
333333
};
334+
335+
private static string TimeSpanToString(TimeSpan t)
336+
=> t.Days > 0 ? (t.Days * 24 + t.Hours) + t.ToString("':'mm':'ss") : t.ToString("hh':'mm':'ss");
334337
}
335338
}

src/Files.Shared/Extensions/LinqExtensions.cs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,33 @@ public static class LinqExtensions
2222
/// <returns></returns>
2323
public static bool IsEmpty<T>(this IEnumerable<T> enumerable) => enumerable is null || !enumerable.Any();
2424

25-
public static TOut? Get<TOut, TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TOut? defaultValue = default)
25+
public static TOut? Get<TOut, TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TOut? defaultValue = default) where TKey : notnull
2626
{
2727
if (dictionary is null || key is null)
2828
return defaultValue;
2929

30-
if (!dictionary.ContainsKey(key))
30+
if (dictionary is ConcurrentDictionary<TKey, TValue> cDict)
3131
{
32-
if (defaultValue is TValue value)
33-
dictionary.Add(key, value);
32+
if (!cDict.ContainsKey(key))
33+
{
34+
if (defaultValue is TValue value)
35+
cDict.TryAdd(key, value);
3436

35-
return defaultValue;
37+
return defaultValue;
38+
}
39+
}
40+
else
41+
{
42+
lock (dictionary)
43+
{
44+
if (!dictionary.ContainsKey(key))
45+
{
46+
if (defaultValue is TValue value)
47+
dictionary.Add(key, value);
48+
49+
return defaultValue;
50+
}
51+
}
3652
}
3753

3854
if (dictionary[key] is TOut o)
@@ -46,22 +62,32 @@ public static class LinqExtensions
4662
if (dictionary is null || key is null)
4763
return defaultValueFunc();
4864

49-
if (!dictionary.ContainsKey(key))
65+
if (dictionary is ConcurrentDictionary<TKey, Task<TValue?>> cDict)
5066
{
51-
var defaultValue = defaultValueFunc();
52-
if (defaultValue is Task<TValue?> value)
67+
if (!cDict.ContainsKey(key))
5368
{
54-
if (dictionary is ConcurrentDictionary<TKey, Task<TValue?>> cDict)
55-
{
69+
var defaultValue = defaultValueFunc();
70+
if (defaultValue is Task<TValue?> value)
5671
cDict.TryAdd(key, value);
57-
}
58-
else
72+
73+
return defaultValue;
74+
}
75+
}
76+
else
77+
{
78+
lock (dictionary)
79+
{
80+
if (!dictionary.ContainsKey(key))
5981
{
60-
dictionary.Add(key, value);
82+
var defaultValue = defaultValueFunc();
83+
if (defaultValue is Task<TValue?> value)
84+
dictionary.Add(key, value);
85+
86+
return defaultValue;
6187
}
6288
}
63-
return defaultValue;
6489
}
90+
6591
return dictionary[key];
6692
}
6793

0 commit comments

Comments
 (0)