feature: add dirty state indicator icon to repository tab (#1227)

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo 2025-04-30 11:01:39 +08:00
parent 847a1e727b
commit 80aead3a17
No known key found for this signature in database
5 changed files with 71 additions and 10 deletions

View file

@ -14,8 +14,8 @@ namespace SourceGit.Models
public enum BisectCommitFlag public enum BisectCommitFlag
{ {
None = 0, None = 0,
Good = 1, Good = 1 << 0,
Bad = 2, Bad = 1 << 1,
} }
public class Bisect public class Bisect

12
src/Models/DirtyState.cs Normal file
View file

@ -0,0 +1,12 @@
using System;
namespace SourceGit.Models
{
[Flags]
public enum DirtyState
{
None = 0,
HasLocalChanges = 1 << 0,
HasPendingPullOrPush = 1 << 1,
}
}

View file

@ -1,5 +1,8 @@
using System; using System;
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Media;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
@ -18,6 +21,12 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _data, value); set => SetProperty(ref _data, value);
} }
public IBrush DirtyBrush
{
get => _dirtyBrush;
private set => SetProperty(ref _dirtyBrush, value);
}
public Popup Popup public Popup Popup
{ {
get => _popup; get => _popup;
@ -56,6 +65,26 @@ namespace SourceGit.ViewModels
App.CopyText(_node.Id); App.CopyText(_node.Id);
} }
public void ChangeDirtyState(Models.DirtyState flag, bool remove)
{
if (remove)
{
if (_dirtyState.HasFlag(flag))
_dirtyState -= flag;
}
else
{
_dirtyState |= flag;
}
if (_dirtyState.HasFlag(Models.DirtyState.HasLocalChanges))
DirtyBrush = Brushes.Gray;
else if (_dirtyState.HasFlag(Models.DirtyState.HasPendingPullOrPush))
DirtyBrush = Brushes.RoyalBlue;
else
DirtyBrush = null;
}
public bool CanCreatePopup() public bool CanCreatePopup()
{ {
return _popup == null || !_popup.InProgress; return _popup == null || !_popup.InProgress;
@ -104,6 +133,8 @@ namespace SourceGit.ViewModels
private RepositoryNode _node = null; private RepositoryNode _node = null;
private object _data = null; private object _data = null;
private IBrush _dirtyBrush = null;
private Models.DirtyState _dirtyState = Models.DirtyState.None;
private Popup _popup = null; private Popup _popup = null;
} }
} }

View file

@ -994,6 +994,8 @@ namespace SourceGit.ViewModels
if (_workingCopy != null) if (_workingCopy != null)
_workingCopy.HasRemotes = remotes.Count > 0; _workingCopy.HasRemotes = remotes.Count > 0;
GetOwnerPage()?.ChangeDirtyState(Models.DirtyState.HasPendingPullOrPush, !CurrentBranch.TrackStatus.IsVisible);
}); });
} }
@ -1101,6 +1103,7 @@ namespace SourceGit.ViewModels
{ {
LocalChangesCount = changes.Count; LocalChangesCount = changes.Count;
OnPropertyChanged(nameof(InProgressContext)); OnPropertyChanged(nameof(InProgressContext));
GetOwnerPage()?.ChangeDirtyState(Models.DirtyState.HasLocalChanges, changes.Count == 0);
}); });
} }

View file

@ -68,14 +68,29 @@
Data="{StaticResource Icons.Repositories}" Data="{StaticResource Icons.Repositories}"
IsVisible="{Binding !Node.IsRepository}" IsVisible="{Binding !Node.IsRepository}"
IsHitTestVisible="False"/> IsHitTestVisible="False"/>
<TextBlock Grid.Column="1"
Classes="primary" <Grid Grid.Column="1"
HorizontalAlignment="Stretch" VerticalAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center"
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Decrease}}" ColumnDefinitions="Auto,*"
TextAlignment="Center" IsHitTestVisible="False"
Text="{Binding Node.Name}" IsVisible="{Binding Node.IsRepository}">
IsVisible="{Binding Node.IsRepository}" <Ellipse Grid.Column="0"
IsHitTestVisible="False"/> Width="8" Height="8"
Margin="0,0,6,0"
VerticalAlignment="Center"
IsVisible="{Binding DirtyBrush, Converter={x:Static ObjectConverters.IsNotNull}}"
Fill="{Binding DirtyBrush}"/>
<TextBlock Grid.Column="1"
Classes="primary"
VerticalAlignment="Center"
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Decrease}}"
TextAlignment="Center"
Text="{Binding Node.Name}"
IsVisible="{Binding Node.IsRepository}"
IsHitTestVisible="False"/>
</Grid>
<TextBlock Grid.Column="1" <TextBlock Grid.Column="1"
Classes="primary" Classes="primary"
HorizontalAlignment="Stretch" VerticalAlignment="Center" HorizontalAlignment="Stretch" VerticalAlignment="Center"