Skip to content

Commit a7e4679

Browse files
authored
Feature: Added Git columns to the details layout (#12485)
1 parent 34853e1 commit a7e4679

File tree

15 files changed

+1024
-134
lines changed

15 files changed

+1024
-134
lines changed

src/Files.App/Data/Models/ColumnViewModel.cs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public bool IsHidden
1919
[LiteDB.BsonIgnore]
2020
public double MaxLength
2121
{
22-
get => UserCollapsed ? 0 : NormalMaxLength;
22+
get => UserCollapsed || IsHidden ? 0 : NormalMaxLength;
2323
}
2424

2525
private double normalMaxLength = 800;
@@ -44,10 +44,12 @@ public double NormalMinLength
4444
}
4545

4646
[LiteDB.BsonIgnore]
47-
public double MinLength => UserCollapsed ? 0 : NormalMinLength;
47+
public double MinLength
48+
=> UserCollapsed || IsHidden ? 0 : NormalMinLength;
4849

4950
[LiteDB.BsonIgnore]
50-
public Visibility Visibility => UserCollapsed ? Visibility.Collapsed : Visibility.Visible;
51+
public Visibility Visibility
52+
=> UserCollapsed || IsHidden ? Visibility.Collapsed : Visibility.Visible;
5153

5254
private bool userCollapsed;
5355

@@ -64,15 +66,15 @@ public bool UserCollapsed
6466
[LiteDB.BsonIgnore]
6567
public GridLength Length
6668
{
67-
get => UserCollapsed ? new GridLength(0) : UserLength;
69+
get => UserCollapsed || IsHidden ? new GridLength(0) : UserLength;
6870
}
6971

7072
private const int gridSplitterWidth = 12;
7173

7274
[LiteDB.BsonIgnore]
7375
public GridLength LengthIncludingGridSplitter
7476
{
75-
get => UserCollapsed
77+
get => UserCollapsed || IsHidden
7678
? new(0)
7779
: new(UserLength.Value + (IsResizeable ? gridSplitterWidth : 0));
7880
}
@@ -104,17 +106,13 @@ public double UserLengthPixels
104106

105107
public void Hide()
106108
{
107-
UserCollapsed = true;
108109
IsHidden = true;
109-
110110
UpdateVisibility();
111111
}
112112

113113
public void Show()
114114
{
115-
UserCollapsed = false;
116115
IsHidden = false;
117-
118116
UpdateVisibility();
119117
}
120118

src/Files.App/Data/Models/ColumnsViewModel.cs

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,48 @@ public class ColumnsViewModel : ObservableObject
1212
UserLength = new GridLength(24, GridUnitType.Pixel),
1313
IsResizeable = false,
1414
};
15-
1615
[LiteDB.BsonIgnore]
1716
public ColumnViewModel IconColumn
1817
{
1918
get => iconColumn;
2019
set => SetProperty(ref iconColumn, value);
2120
}
2221

22+
private ColumnViewModel _GitStatusColumn = new();
23+
public ColumnViewModel GitStatusColumn
24+
{
25+
get => _GitStatusColumn;
26+
set => SetProperty(ref _GitStatusColumn, value);
27+
}
28+
29+
private ColumnViewModel _GitLastCommitDateColumn = new();
30+
public ColumnViewModel GitLastCommitDateColumn
31+
{
32+
get => _GitLastCommitDateColumn;
33+
set => SetProperty(ref _GitLastCommitDateColumn, value);
34+
}
35+
36+
private ColumnViewModel _GitLastCommitMessageColumn = new();
37+
public ColumnViewModel GitLastCommitMessageColumn
38+
{
39+
get => _GitLastCommitMessageColumn;
40+
set => SetProperty(ref _GitLastCommitMessageColumn, value);
41+
}
42+
43+
private ColumnViewModel _GitCommitAuthorColumn = new();
44+
public ColumnViewModel GitCommitAuthorColumn
45+
{
46+
get => _GitCommitAuthorColumn;
47+
set => SetProperty(ref _GitCommitAuthorColumn, value);
48+
}
49+
50+
private ColumnViewModel _GitLastCommitShaColumn = new();
51+
public ColumnViewModel GitLastCommitShaColumn
52+
{
53+
get => _GitLastCommitShaColumn;
54+
set => SetProperty(ref _GitLastCommitShaColumn, value);
55+
}
56+
2357
private ColumnViewModel tagColumn = new();
2458
public ColumnViewModel TagColumn
2559
{
@@ -31,7 +65,6 @@ public ColumnViewModel TagColumn
3165
{
3266
NormalMaxLength = 1000d
3367
};
34-
3568
public ColumnViewModel NameColumn
3669
{
3770
get => nameColumn;
@@ -43,7 +76,6 @@ public ColumnViewModel NameColumn
4376
UserLength = new GridLength(50),
4477
NormalMaxLength = 80,
4578
};
46-
4779
public ColumnViewModel StatusColumn
4880
{
4981
get => statusColumn;
@@ -61,7 +93,6 @@ public ColumnViewModel DateModifiedColumn
6193
{
6294
NormalMaxLength = 500,
6395
};
64-
6596
public ColumnViewModel OriginalPathColumn
6697
{
6798
get => originalPathColumn;
@@ -86,7 +117,6 @@ public ColumnViewModel DateDeletedColumn
86117
{
87118
UserCollapsed = true
88119
};
89-
90120
public ColumnViewModel DateCreatedColumn
91121
{
92122
get => dateCreatedColumn;
@@ -105,11 +135,13 @@ public ColumnViewModel SizeColumn
105135
IconColumn.Length.Value +
106136
TagColumn.Length.Value +
107137
NameColumn.Length.Value +
108-
DateModifiedColumn.Length.Value + OriginalPathColumn.Length.Value +
138+
DateModifiedColumn.Length.Value +
139+
OriginalPathColumn.Length.Value +
109140
ItemTypeColumn.Length.Value +
110141
DateDeletedColumn.Length.Value +
111142
DateCreatedColumn.Length.Value +
112-
SizeColumn.Length.Value + StatusColumn.Length.Value;
143+
SizeColumn.Length.Value +
144+
StatusColumn.Length.Value;
113145

114146
public void SetDesiredSize(double width)
115147
{

src/Files.App/Data/Models/FolderSettingsViewModel.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,11 @@ public static void SetLayoutPreferencesForPath(string folderPath, LayoutPreferen
360360
userSettingsService.FoldersSettingsService.ShowTypeColumn = !prefs.ColumnsViewModel.ItemTypeColumn.UserCollapsed;
361361
userSettingsService.FoldersSettingsService.ShowSizeColumn = !prefs.ColumnsViewModel.SizeColumn.UserCollapsed;
362362
userSettingsService.FoldersSettingsService.ShowFileTagColumn = !prefs.ColumnsViewModel.TagColumn.UserCollapsed;
363+
userSettingsService.FoldersSettingsService.ShowGitStatusColumn = !prefs.ColumnsViewModel.GitStatusColumn.UserCollapsed;
364+
userSettingsService.FoldersSettingsService.ShowGitLastCommitDateColumn = !prefs.ColumnsViewModel.GitLastCommitDateColumn.UserCollapsed;
365+
userSettingsService.FoldersSettingsService.ShowGitLastCommitMessageColumn = !prefs.ColumnsViewModel.GitLastCommitMessageColumn.UserCollapsed;
366+
userSettingsService.FoldersSettingsService.ShowGitCommitAuthorColumn = !prefs.ColumnsViewModel.GitCommitAuthorColumn.UserCollapsed;
367+
userSettingsService.FoldersSettingsService.ShowGitLastCommitShaColumn = !prefs.ColumnsViewModel.GitLastCommitShaColumn.UserCollapsed;
363368
userSettingsService.FoldersSettingsService.ShowDateDeletedColumn = !prefs.ColumnsViewModel.DateDeletedColumn.UserCollapsed;
364369
userSettingsService.FoldersSettingsService.ShowOriginalPathColumn = !prefs.ColumnsViewModel.OriginalPathColumn.UserCollapsed;
365370
userSettingsService.FoldersSettingsService.ShowSyncStatusColumn = !prefs.ColumnsViewModel.StatusColumn.UserCollapsed;
@@ -370,6 +375,11 @@ public static void SetLayoutPreferencesForPath(string folderPath, LayoutPreferen
370375
userSettingsService.FoldersSettingsService.TypeColumnWidth = prefs.ColumnsViewModel.ItemTypeColumn.UserLengthPixels;
371376
userSettingsService.FoldersSettingsService.SizeColumnWidth = prefs.ColumnsViewModel.SizeColumn.UserLengthPixels;
372377
userSettingsService.FoldersSettingsService.TagColumnWidth = prefs.ColumnsViewModel.TagColumn.UserLengthPixels;
378+
userSettingsService.FoldersSettingsService.GitStatusColumnWidth = prefs.ColumnsViewModel.GitStatusColumn.UserLengthPixels;
379+
userSettingsService.FoldersSettingsService.GitLastCommitDateColumnWidth = prefs.ColumnsViewModel.GitLastCommitDateColumn.UserLengthPixels;
380+
userSettingsService.FoldersSettingsService.GitLastCommitMessageColumnWidth = prefs.ColumnsViewModel.GitLastCommitMessageColumn.UserLengthPixels;
381+
userSettingsService.FoldersSettingsService.GitCommitAuthorColumnWidth = prefs.ColumnsViewModel.GitCommitAuthorColumn.UserLengthPixels;
382+
userSettingsService.FoldersSettingsService.GitLastCommitShaColumnWidth = prefs.ColumnsViewModel.GitLastCommitShaColumn.UserLengthPixels;
373383
userSettingsService.FoldersSettingsService.DateDeletedColumnWidth = prefs.ColumnsViewModel.DateDeletedColumn.UserLengthPixels;
374384
userSettingsService.FoldersSettingsService.OriginalPathColumnWidth = prefs.ColumnsViewModel.OriginalPathColumn.UserLengthPixels;
375385
userSettingsService.FoldersSettingsService.SyncStatusColumnWidth = prefs.ColumnsViewModel.StatusColumn.UserLengthPixels;
@@ -573,6 +583,11 @@ public void SetDefaultLayoutPreferences(ColumnsViewModel columns)
573583
userSettingsService.FoldersSettingsService.ShowTypeColumn = !columns.ItemTypeColumn.UserCollapsed;
574584
userSettingsService.FoldersSettingsService.ShowSizeColumn = !columns.SizeColumn.UserCollapsed;
575585
userSettingsService.FoldersSettingsService.ShowFileTagColumn = !columns.TagColumn.UserCollapsed;
586+
userSettingsService.FoldersSettingsService.ShowGitStatusColumn = !columns.GitStatusColumn.UserCollapsed;
587+
userSettingsService.FoldersSettingsService.ShowGitLastCommitDateColumn = !columns.GitLastCommitDateColumn.UserCollapsed;
588+
userSettingsService.FoldersSettingsService.ShowGitLastCommitMessageColumn = !columns.GitLastCommitMessageColumn.UserCollapsed;
589+
userSettingsService.FoldersSettingsService.ShowGitCommitAuthorColumn = !columns.GitCommitAuthorColumn.UserCollapsed;
590+
userSettingsService.FoldersSettingsService.ShowGitLastCommitShaColumn = !columns.GitLastCommitShaColumn.UserCollapsed;
576591
userSettingsService.FoldersSettingsService.ShowDateDeletedColumn = !columns.DateDeletedColumn.UserCollapsed;
577592
userSettingsService.FoldersSettingsService.ShowOriginalPathColumn = !columns.OriginalPathColumn.UserCollapsed;
578593
userSettingsService.FoldersSettingsService.ShowSyncStatusColumn = !columns.StatusColumn.UserCollapsed;
@@ -583,6 +598,11 @@ public void SetDefaultLayoutPreferences(ColumnsViewModel columns)
583598
userSettingsService.FoldersSettingsService.TypeColumnWidth = columns.ItemTypeColumn.UserLengthPixels;
584599
userSettingsService.FoldersSettingsService.SizeColumnWidth = columns.SizeColumn.UserLengthPixels;
585600
userSettingsService.FoldersSettingsService.TagColumnWidth = columns.TagColumn.UserLengthPixels;
601+
userSettingsService.FoldersSettingsService.GitStatusColumnWidth = columns.GitStatusColumn.UserLengthPixels;
602+
userSettingsService.FoldersSettingsService.GitLastCommitDateColumnWidth = columns.GitLastCommitDateColumn.UserLengthPixels;
603+
userSettingsService.FoldersSettingsService.GitLastCommitMessageColumnWidth = columns.GitLastCommitMessageColumn.UserLengthPixels;
604+
userSettingsService.FoldersSettingsService.GitCommitAuthorColumnWidth = columns.GitCommitAuthorColumn.UserLengthPixels;
605+
userSettingsService.FoldersSettingsService.GitLastCommitShaColumnWidth = columns.GitLastCommitShaColumn.UserLengthPixels;
586606
userSettingsService.FoldersSettingsService.DateDeletedColumnWidth = columns.DateDeletedColumn.UserLengthPixels;
587607
userSettingsService.FoldersSettingsService.OriginalPathColumnWidth = columns.OriginalPathColumn.UserLengthPixels;
588608
userSettingsService.FoldersSettingsService.SyncStatusColumnWidth = columns.StatusColumn.UserLengthPixels;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using LibGit2Sharp;
2+
3+
namespace Files.App.Data.Models
4+
{
5+
/// <summary>
6+
/// Represents a model for Git items
7+
/// </summary>
8+
internal class GitItemModel
9+
{
10+
/// <summary>
11+
/// Gets or initializes file change kind
12+
/// </summary>
13+
/// <remarks>
14+
/// This is often showed as A(Add), D(Delete), M(Modified), U(Untracked) in VS Code.
15+
/// </remarks>
16+
public ChangeKind Status { get; init; }
17+
18+
/// <summary>
19+
/// Gets or initializes file change kind humanized string
20+
/// </summary>
21+
/// <remarks>
22+
/// This is often showed as A(Add), D(Delete), M(Modified), U(Untracked) in VS Code.
23+
/// </remarks>
24+
public string? StatusHumanized { get; init; }
25+
26+
/// <summary>
27+
/// Gets or initializes file last commit information including author, committed date, and SHA.
28+
/// </summary>
29+
public Commit? LastCommit { get; init; }
30+
31+
/// <summary>
32+
/// Gets or initializes file path
33+
/// </summary>
34+
public string? Path { get; init; }
35+
}
36+
}

src/Files.App/Data/Models/ItemViewModel.cs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ public void UpdateGroupOptions()
852852
FilesAndFolders.GetExtendedGroupHeaderInfo = groupInfoSelector.Item2;
853853
}
854854

855-
public Dictionary<string, BitmapImage> DefaultIcons = new ();
855+
public Dictionary<string, BitmapImage> DefaultIcons = new();
856856

857857
private uint currentDefaultIconSize = 0;
858858

@@ -1193,6 +1193,31 @@ await SafetyExtensions.IgnoreExceptions(() =>
11931193
gp.InitializeExtendedGroupHeaderInfoAsync();
11941194
}));
11951195
}
1196+
1197+
if (item.IsGitItem &&
1198+
GitHelpers.IsRepositoryEx(item.ItemPath, out var repoPath) &&
1199+
!string.IsNullOrEmpty(repoPath))
1200+
{
1201+
cts.Token.ThrowIfCancellationRequested();
1202+
await SafetyExtensions.IgnoreExceptions(() =>
1203+
{
1204+
var repo = new LibGit2Sharp.Repository(repoPath);
1205+
GitItemModel gitItemModel = GitHelpers.GetGitInformationForItem(repo, item.ItemPath);
1206+
1207+
return dispatcherQueue.EnqueueOrInvokeAsync(() =>
1208+
{
1209+
var gitItem = item.AsGitItem;
1210+
gitItem.UnmergedGitStatusLabel = gitItemModel.StatusHumanized;
1211+
gitItem.GitLastCommitDate = gitItemModel.LastCommit?.Author.When;
1212+
gitItem.GitLastCommitMessage = gitItemModel.LastCommit?.MessageShort;
1213+
gitItem.GitLastCommitAuthor = gitItemModel.LastCommit?.Author.Name;
1214+
gitItem.GitLastCommitSha = gitItemModel.LastCommit?.Sha.Substring(0, 7);
1215+
1216+
repo.Dispose();
1217+
},
1218+
Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
1219+
});
1220+
}
11961221
}
11971222
}, cts.Token);
11981223
}
@@ -1363,8 +1388,14 @@ private async Task RapidAddItemsToCollection(string? path, LibraryItem? library
13631388
case 0:
13641389
currentStorageFolder ??= await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderWithPathFromPathAsync(path));
13651390
var syncStatus = await CheckCloudDriveSyncStatusAsync(currentStorageFolder?.Item);
1366-
PageTypeUpdated?.Invoke(this, new PageTypeUpdatedEventArgs() { IsTypeCloudDrive = syncStatus != CloudDriveSyncStatus.NotSynced && syncStatus != CloudDriveSyncStatus.Unknown });
1391+
PageTypeUpdated?.Invoke(this, new PageTypeUpdatedEventArgs()
1392+
{
1393+
IsTypeCloudDrive = syncStatus != CloudDriveSyncStatus.NotSynced && syncStatus != CloudDriveSyncStatus.Unknown,
1394+
IsTypeGitRepository = GitDirectory is not null
1395+
});
13671396
WatchForDirectoryChanges(path, syncStatus);
1397+
if (GitDirectory is not null)
1398+
WatchForGitChanges();
13681399
break;
13691400

13701401
// Enumerated with StorageFolder
@@ -1936,9 +1967,6 @@ private void WatchForDirectoryChanges(string path, CloudDriveSyncStatus syncStat
19361967
Debug.WriteLine("aWatcherAction done: {0}", rand);
19371968
});
19381969

1939-
if (GitDirectory is not null)
1940-
WatchForGitChanges(hasSyncStatus);
1941-
19421970
watcherCTS.Token.Register(() =>
19431971
{
19441972
if (aWatcherAction is not null)
@@ -1956,7 +1984,7 @@ private void WatchForDirectoryChanges(string path, CloudDriveSyncStatus syncStat
19561984
});
19571985
}
19581986

1959-
private void WatchForGitChanges(bool hasSyncStatus)
1987+
private void WatchForGitChanges()
19601988
{
19611989
var hWatchDir = NativeFileOperationsHelper.CreateFileFromApp(
19621990
GitDirectory!,
@@ -1979,9 +2007,6 @@ private void WatchForGitChanges(bool hasSyncStatus)
19792007
var rand = Guid.NewGuid();
19802008
var notifyFilters = FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_CREATION;
19812009

1982-
if (hasSyncStatus)
1983-
notifyFilters |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1984-
19852010
var overlapped = new OVERLAPPED();
19862011
overlapped.hEvent = CreateEvent(IntPtr.Zero, false, false, null);
19872012
const uint INFINITE = 0xFFFFFFFF;
@@ -2255,9 +2280,9 @@ private async Task AddFileOrFolderAsync(ListedItem? item)
22552280

22562281
// FILE_ATTRIBUTE_DIRECTORY
22572282
if ((findData.dwFileAttributes & 0x10) > 0)
2258-
listedItem = await Win32StorageEnumerator.GetFolder(findData, Directory.GetParent(fileOrFolderPath).FullName, addFilesCTS.Token);
2283+
listedItem = await Win32StorageEnumerator.GetFolder(findData, Directory.GetParent(fileOrFolderPath).FullName, GitDirectory is not null, addFilesCTS.Token);
22592284
else
2260-
listedItem = await Win32StorageEnumerator.GetFile(findData, Directory.GetParent(fileOrFolderPath).FullName, addFilesCTS.Token);
2285+
listedItem = await Win32StorageEnumerator.GetFile(findData, Directory.GetParent(fileOrFolderPath).FullName, GitDirectory is not null, addFilesCTS.Token);
22612286

22622287
await AddFileOrFolderAsync(listedItem);
22632288

@@ -2446,6 +2471,8 @@ public class PageTypeUpdatedEventArgs
24462471
public bool IsTypeCloudDrive { get; set; }
24472472

24482473
public bool IsTypeRecycleBin { get; set; }
2474+
2475+
public bool IsTypeGitRepository { get; set; }
24492476
}
24502477

24512478
public class WorkingDirectoryModifiedEventArgs : EventArgs

src/Files.App/Files.App.csproj

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFramework>net7.0-windows10.0.22621.0</TargetFramework>
44
<OutputType>WinExe</OutputType>
@@ -25,8 +25,6 @@
2525
<Configurations>Debug;Release;Stable;Preview;Store</Configurations>
2626
<TieredCompilation>true</TieredCompilation>
2727
<TieredPgo>true</TieredPgo>
28-
<!--<ImplicitUsings>disable</ImplicitUsings>
29-
<DisableImplicitNamespaceImports>true</DisableImplicitNamespaceImports>-->
3028
</PropertyGroup>
3129
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
3230
<DefineConstants>TRACE;DEBUG;NETFX_CORE;DISABLE_XAML_GENERATED_MAIN</DefineConstants>

0 commit comments

Comments
 (0)