feature<Welcome>: add sort supports

This commit is contained in:
leo 2022-10-17 10:12:59 +08:00
parent 1beafbc84c
commit 918263130c
10 changed files with 101 additions and 35 deletions

View file

@ -18,6 +18,15 @@ namespace SourceGit.Models {
"preference_v4.json"); "preference_v4.json");
private static Preference instance = null; private static Preference instance = null;
/// <summary>
/// 起始页仓库列表排序方式
/// </summary>
public enum SortMethod {
ByNameASC,
ByNameDESC,
ByRecentlyOpened,
}
/// <summary> /// <summary>
/// 通用配置 /// 通用配置
/// </summary> /// </summary>
@ -68,6 +77,11 @@ namespace SourceGit.Models {
/// 上一次检测的时间(用于控制每天仅第一次启动软件时,检测) /// 上一次检测的时间(用于控制每天仅第一次启动软件时,检测)
/// </summary> /// </summary>
public int LastCheckDay { get; set; } = 0; public int LastCheckDay { get; set; } = 0;
/// <summary>
/// 起始页仓库列表排序规则
/// </summary>
public SortMethod SortBy { get; set; } = SortMethod.ByNameASC;
} }
/// <summary> /// <summary>

View file

@ -28,6 +28,7 @@ namespace SourceGit.Models {
public string Path { get; set; } = ""; public string Path { get; set; } = "";
public string GitDir { get; set; } = ""; public string GitDir { get; set; } = "";
public int Bookmark { get; set; } = 0; public int Bookmark { get; set; } = 0;
public long LastOpenTime { get; set; } = 0;
public List<SubTree> SubTrees { get; set; } = new List<SubTree>(); public List<SubTree> SubTrees { get; set; } = new List<SubTree>();
public List<string> Filters { get; set; } = new List<string>(); public List<string> Filters { get; set; } = new List<string>();
public List<string> CommitMessages { get; set; } = new List<string>(); public List<string> CommitMessages { get; set; } = new List<string>();

View file

@ -56,6 +56,7 @@ namespace SourceGit.Models {
var watcher = new Watcher(); var watcher = new Watcher();
watcher.Start(repo.Path, repo.GitDir); watcher.Start(repo.Path, repo.GitDir);
all.Add(repo.Path, watcher); all.Add(repo.Path, watcher);
repo.LastOpenTime = DateTime.Now.ToFileTime();
Opened?.Invoke(repo); Opened?.Invoke(repo);
} }

View file

@ -68,5 +68,5 @@
<Geometry x:Key="Icon.Tag.Add">M683 537h-144v-142h-142V283H239a44 44 0 00-41 41v171a56 56 0 0014 34l321 321a41 41 0 0058 0l174-174a41 41 0 000-58zm-341-109a41 41 0 110-58a41 41 0 010 58zM649 284V142h-69v142h-142v68h142v142h69v-142h142v-68h-142z</Geometry> <Geometry x:Key="Icon.Tag.Add">M683 537h-144v-142h-142V283H239a44 44 0 00-41 41v171a56 56 0 0014 34l321 321a41 41 0 0058 0l174-174a41 41 0 000-58zm-341-109a41 41 0 110-58a41 41 0 010 58zM649 284V142h-69v142h-142v68h142v142h69v-142h142v-68h-142z</Geometry>
<Geometry x:Key="Icon.VSCode">M719 85 388 417l-209-165L87 299v427l92 47 210-164L720 939 939 850V171zM186 610V412l104 104zm526 55L514 512l198-153z</Geometry> <Geometry x:Key="Icon.VSCode">M719 85 388 417l-209-165L87 299v427l92 47 210-164L720 939 939 850V171zM186 610V412l104 104zm526 55L514 512l198-153z</Geometry>
<Geometry x:Key="Icon.DragDrop">M597 256h85v85h213a43 43 0 0143 43v320L683 555l2 344 95-92L855 939H384a43 43 0 01-43-43v-213H256v-85h85V384a43 43 0 0143-43h213V256zm341 484V896a43 43 0 01-2 13l-84-145L939 740zM171 597v85H85v-85h85zm0-171v85H85v-85h85zm0-171v85H85V256h85zm0-171v85H85V85h85zm171 0v85H256V85h85zm171 0v85h-85V85h85zm171 0v85h-85V85h85z</Geometry> <Geometry x:Key="Icon.Sort">M426.7 554.7v-85.3h341.3v85.3h-341.3m0 256v-85.3h170.7v85.3h-170.7m0-512V213.3h512v85.3H426.7M256 725.3h106.7L213.3 874.7 64 725.3H170.7V298.7H64L213.3 149.3 362.7 298.7H256v426.7z</Geometry>
</ResourceDictionary> </ResourceDictionary>

View file

@ -297,13 +297,13 @@
<sys:String x:Key="Text.Merge.Into">Into :</sys:String> <sys:String x:Key="Text.Merge.Into">Into :</sys:String>
<sys:String x:Key="Text.Merge.Mode">Merge Option :</sys:String> <sys:String x:Key="Text.Merge.Mode">Merge Option :</sys:String>
<sys:String x:Key="Text.Welcome.Title">Free &amp; open source GUI tool for git users</sys:String>
<sys:String x:Key="Text.Welcome.OpenOrInit">Open Repository</sys:String> <sys:String x:Key="Text.Welcome.OpenOrInit">Open Repository</sys:String>
<sys:String x:Key="Text.Welcome.OpenTerminal">Open Terminal</sys:String> <sys:String x:Key="Text.Welcome.OpenTerminal">Open Terminal</sys:String>
<sys:String x:Key="Text.Welcome.Clone">Clone Repository</sys:String> <sys:String x:Key="Text.Welcome.Clone">Clone Repository</sys:String>
<sys:String x:Key="Text.Welcome.Repositories">REPOSITORIES</sys:String> <sys:String x:Key="Text.Welcome.Repositories">REPOSITORIES</sys:String>
<sys:String x:Key="Text.Welcome.Delete">Delete</sys:String> <sys:String x:Key="Text.Welcome.Delete">Delete</sys:String>
<sys:String x:Key="Text.Welcome.Search">Search Repositories ...</sys:String> <sys:String x:Key="Text.Welcome.Search">Search Repositories ...</sys:String>
<sys:String x:Key="Text.Welcome.Sort">Sort</sys:String>
<sys:String x:Key="Text.Pull">Pull</sys:String> <sys:String x:Key="Text.Pull">Pull</sys:String>
<sys:String x:Key="Text.Pull.Title">Pull (Fetch &amp; Merge)</sys:String> <sys:String x:Key="Text.Pull.Title">Pull (Fetch &amp; Merge)</sys:String>
@ -509,6 +509,10 @@
<sys:String x:Key="Text.Month.11">Nov</sys:String> <sys:String x:Key="Text.Month.11">Nov</sys:String>
<sys:String x:Key="Text.Month.12">Dec</sys:String> <sys:String x:Key="Text.Month.12">Dec</sys:String>
<sys:String x:Key="Text.Sort.NameAsc">By Name</sys:String>
<sys:String x:Key="Text.Sort.NameDesc">By Name Inversed</sys:String>
<sys:String x:Key="Text.Sort.RecentlyOpened">By Recently Opened</sys:String>
<sys:String x:Key="Text.NotConfigured">Git has NOT been configured. Please to go [Preference] and configure it first.</sys:String> <sys:String x:Key="Text.NotConfigured">Git has NOT been configured. Please to go [Preference] and configure it first.</sys:String>
<sys:String x:Key="Text.PathNotFound">Path[{0}] not exists!</sys:String> <sys:String x:Key="Text.PathNotFound">Path[{0}] not exists!</sys:String>
<sys:String x:Key="Text.MissingBash">Can NOT locate bash.exe. Make sure bash.exe exists under the same folder with git.exe</sys:String> <sys:String x:Key="Text.MissingBash">Can NOT locate bash.exe. Make sure bash.exe exists under the same folder with git.exe</sys:String>

View file

@ -296,13 +296,13 @@
<sys:String x:Key="Text.Merge.Into">目标分支 </sys:String> <sys:String x:Key="Text.Merge.Into">目标分支 </sys:String>
<sys:String x:Key="Text.Merge.Mode">合并方式 </sys:String> <sys:String x:Key="Text.Merge.Mode">合并方式 </sys:String>
<sys:String x:Key="Text.Welcome.Title">开源的轻量级Git图形客户端</sys:String>
<sys:String x:Key="Text.Welcome.OpenOrInit">打开本地仓库</sys:String> <sys:String x:Key="Text.Welcome.OpenOrInit">打开本地仓库</sys:String>
<sys:String x:Key="Text.Welcome.OpenTerminal">打开GIT终端</sys:String> <sys:String x:Key="Text.Welcome.OpenTerminal">打开GIT终端</sys:String>
<sys:String x:Key="Text.Welcome.Clone">克隆远程仓库</sys:String> <sys:String x:Key="Text.Welcome.Clone">克隆远程仓库</sys:String>
<sys:String x:Key="Text.Welcome.Repositories">收藏/书签</sys:String> <sys:String x:Key="Text.Welcome.Repositories">收藏/书签</sys:String>
<sys:String x:Key="Text.Welcome.Delete">删除</sys:String> <sys:String x:Key="Text.Welcome.Delete">删除</sys:String>
<sys:String x:Key="Text.Welcome.Search">快速查找仓库</sys:String> <sys:String x:Key="Text.Welcome.Search">快速查找仓库</sys:String>
<sys:String x:Key="Text.Welcome.Sort">排序</sys:String>
<sys:String x:Key="Text.Pull">拉回</sys:String> <sys:String x:Key="Text.Pull">拉回</sys:String>
<sys:String x:Key="Text.Pull.Title">拉回(拉取并合并)</sys:String> <sys:String x:Key="Text.Pull.Title">拉回(拉取并合并)</sys:String>
@ -508,6 +508,10 @@
<sys:String x:Key="Text.Month.11">11月</sys:String> <sys:String x:Key="Text.Month.11">11月</sys:String>
<sys:String x:Key="Text.Month.12">12月</sys:String> <sys:String x:Key="Text.Month.12">12月</sys:String>
<sys:String x:Key="Text.Sort.NameAsc">按名称正序</sys:String>
<sys:String x:Key="Text.Sort.NameDesc">按名称倒序</sys:String>
<sys:String x:Key="Text.Sort.RecentlyOpened">按最近访问</sys:String>
<sys:String x:Key="Text.NotConfigured">GIT尚未配置。请打开【偏好设置】配置GIT路径。</sys:String> <sys:String x:Key="Text.NotConfigured">GIT尚未配置。请打开【偏好设置】配置GIT路径。</sys:String>
<sys:String x:Key="Text.PathNotFound">路径({0})不存在或不可读取!</sys:String> <sys:String x:Key="Text.PathNotFound">路径({0})不存在或不可读取!</sys:String>
<sys:String x:Key="Text.MissingBash">无法找到bash.exe请确保其在git.exe同目录中</sys:String> <sys:String x:Key="Text.MissingBash">无法找到bash.exe请确保其在git.exe同目录中</sys:String>

View file

@ -34,14 +34,16 @@
<Rectangle Grid.Column="0" Grid.ColumnSpan="4" Fill="{DynamicResource Brush.Border0}" Height="1" VerticalAlignment="Bottom"/> <Rectangle Grid.Column="0" Grid.ColumnSpan="4" Fill="{DynamicResource Brush.Border0}" Height="1" VerticalAlignment="Bottom"/>
<!-- Main Menu --> <!-- Main Menu -->
<controls:IconButton <Button
Grid.Column="0" Grid.Column="0"
Margin="4,4,4,0" Margin="4,4,4,0"
Width="14" Width="16"
Icon="{StaticResource Icon.List}" Background="Transparent"
ToolTip="{DynamicResource Text.Launcher.Menu}" BorderThickness="0"
WindowChrome.IsHitTestVisibleInChrome="True" WindowChrome.IsHitTestVisibleInChrome="True"
Click="ToggleMainMenu"/> Click="ToggleMainMenu">
<Path Data="{StaticResource Icon.Git}" Fill="{DynamicResource Brush.Logo}"/>
</Button>
<!-- Tabs --> <!-- Tabs -->
<widgets:PageTabBar <widgets:PageTabBar

View file

@ -78,6 +78,12 @@ namespace SourceGit.Views {
} else { } else {
tabs.Replace(tabs.Current, repo.Name, repo.Path, repo.Bookmark); tabs.Replace(tabs.Current, repo.Name, repo.Path, repo.Bookmark);
} }
foreach (var tab in tabs.Tabs) {
if (tab.IsRepository) continue;
var dirty = container.Get(tabs.Current) as Widgets.Welcome;
if (dirty != null) dirty.UpdateVisibles();
}
} }
#endregion #endregion

View file

@ -11,8 +11,6 @@
d:DesignHeight="800" d:DesignWidth="800"> d:DesignHeight="800" d:DesignWidth="800">
<Grid Background="Transparent" AllowDrop="True" DragEnter="OnPageDragEnter" DragLeave="OnPageDragLeave" Drop="OnPageDrop"> <Grid Background="Transparent" AllowDrop="True" DragEnter="OnPageDragEnter" DragLeave="OnPageDragLeave" Drop="OnPageDrop">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
@ -24,34 +22,15 @@
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!-- App Name -->
<TextBlock
Grid.Row="0" Grid.Column="1"
Margin="0,64,0,0"
HorizontalAlignment="Left"
Text="SourceGit"
FontSize="28pt"
TextOptions.TextFormattingMode="Ideal"
TextOptions.TextRenderingMode="ClearType"
RenderOptions.ClearTypeHint="Enabled"/>
<!-- App Desc -->
<TextBlock
Grid.Row="1" Grid.Column="1"
HorizontalAlignment="Left"
Text="{DynamicResource Text.Welcome.Title}"
Foreground="{DynamicResource Brush.FG2}"
FontSize="18pt"
Margin="0,8"/>
<!-- Repositories Tool Bar --> <!-- Repositories Tool Bar -->
<Grid Grid.Row="2" Grid.Column="1" Margin="0,32,0,0"> <Grid Grid.Row="0" Grid.Column="1" Margin="0,100,0,0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock <TextBlock
@ -86,10 +65,19 @@
Click="OnOpenTerminalClicked"> Click="OnOpenTerminalClicked">
<Path Width="16" Height="14" Data="{StaticResource Icon.Terminal}" Fill="{DynamicResource Brush.Accent1}"/> <Path Width="16" Height="14" Data="{StaticResource Icon.Terminal}" Fill="{DynamicResource Brush.Accent1}"/>
</Button> </Button>
<Button
Grid.Column="5"
Width="32" Height="28"
Style="{DynamicResource Style.Button.Link}"
ToolTip="{DynamicResource Text.Welcome.Sort}"
Click="OnSortMethodClicked">
<Path Width="16" Height="14" Data="{StaticResource Icon.Sort}" Fill="{DynamicResource Brush.Accent1}"/>
</Button>
</Grid> </Grid>
<!-- Search Bar --> <!-- Search Bar -->
<Grid Grid.Row="3" Grid.Column="1" Margin="2,8" Height="28" VerticalAlignment="Top"> <Grid Grid.Row="1" Grid.Column="1" Margin="2,8" Height="28" VerticalAlignment="Top">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="24"/> <ColumnDefinition Width="24"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
@ -116,7 +104,7 @@
</Grid> </Grid>
<!-- Repositories List --> <!-- Repositories List -->
<Grid Grid.Row="4" Grid.Column="1" Margin="0,0,0,8" AllowDrop="True" Drop="OnDropFolder"> <Grid Grid.Row="2" Grid.Column="1" Margin="0,0,0,80" AllowDrop="True" Drop="OnDropFolder">
<Grid.Resources> <Grid.Resources>
<converters:IntToBookmarkBrush x:Key="IntToBookmarkBrush"/> <converters:IntToBookmarkBrush x:Key="IntToBookmarkBrush"/>
</Grid.Resources> </Grid.Resources>
@ -191,6 +179,6 @@
</Grid> </Grid>
<!-- Popup --> <!-- Popup -->
<widgets:PopupPanel x:Name="popup" Grid.Row="0" Grid.RowSpan="5" Grid.Column="0" Grid.ColumnSpan="3"/> <widgets:PopupPanel x:Name="popup" Grid.Row="0" Grid.RowSpan="3" Grid.Column="0" Grid.ColumnSpan="3"/>
</Grid> </Grid>
</UserControl> </UserControl>

View file

@ -67,6 +67,40 @@ namespace SourceGit.Views.Widgets {
if (MakeSureReady()) new Popups.Clone().Show(); if (MakeSureReady()) new Popups.Clone().Show();
} }
private void FillSortMenu(ContextMenu menu, Models.Preference.SortMethod desired, string label) {
var item = new MenuItem();
item.Header = App.Text(label);
item.Click += (s, ev) => {
Models.Preference.Instance.General.SortBy = desired;
UpdateVisibles();
};
if (Models.Preference.Instance.General.SortBy == desired) {
var icon = new System.Windows.Shapes.Path();
icon.Data = FindResource("Icon.Check") as Geometry;
icon.Fill = FindResource("Brush.FG1") as Brush;
icon.Width = 12;
item.Icon = icon;
}
menu.Items.Add(item);
}
private void OnSortMethodClicked(object sender, RoutedEventArgs e) {
var menu = new ContextMenu();
menu.Placement = PlacementMode.Bottom;
menu.PlacementTarget = sender as Button;
menu.StaysOpen = false;
menu.Focusable = true;
FillSortMenu(menu, Models.Preference.SortMethod.ByNameASC, "Sort.NameAsc");
FillSortMenu(menu, Models.Preference.SortMethod.ByNameDESC, "Sort.NameDesc");
FillSortMenu(menu, Models.Preference.SortMethod.ByRecentlyOpened, "Sort.RecentlyOpened");
menu.IsOpen = true;
e.Handled = true;
}
private void OnRemoveRepository(object sender, RoutedEventArgs e) { private void OnRemoveRepository(object sender, RoutedEventArgs e) {
var repo = (sender as Button).DataContext as Models.Repository; var repo = (sender as Button).DataContext as Models.Repository;
if (repo == null) return; if (repo == null) return;
@ -206,6 +240,18 @@ namespace SourceGit.Views.Widgets {
} }
} }
switch (Models.Preference.Instance.General.SortBy) {
case Models.Preference.SortMethod.ByNameASC:
visibles.Sort((l, r) => l.Name.CompareTo(r.Name));
break;
case Models.Preference.SortMethod.ByNameDESC:
visibles.Sort((l, r) => r.Name.CompareTo(l.Name));
break;
default:
visibles.Sort((l, r) => r.LastOpenTime.CompareTo(l.LastOpenTime));
break;
}
repoList.ItemsSource = visibles; repoList.ItemsSource = visibles;
} }