Skip to content
Open
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
6 changes: 6 additions & 0 deletions src/Models/RepositorySettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ public string DefaultRemote
set;
} = string.Empty;

public string ProfileName
{
get;
set;
} = string.Empty;

public int PreferredMergeMode
{
get;
Expand Down
43 changes: 43 additions & 0 deletions src/Models/UserProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Avalonia.Collections;
using CommunityToolkit.Mvvm.ComponentModel;

namespace SourceGit.Models
{


public record UserProfileTargetFile(string File, Commit Revision);


public class UserProfile : ObservableObject
{
public string ProfileName
{
get => _profileName;
set => SetProperty(ref _profileName, value);
}

public string UserName
{
get => _userName;
set => SetProperty(ref _userName, value);
}

public string Email
{
get => _email;
set => SetProperty(ref _email, value);
}

public string Key
{
get => _key;
set => SetProperty(ref _key, value);
}


private string _profileName = string.Empty;
private string _userName = string.Empty;
private string _email = string.Empty;
private string _key = string.Empty;
}
}
6 changes: 6 additions & 0 deletions src/Resources/Locales/en_US.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@
<x:String x:Key="Text.Configure.Git.AutoFetchIntervalSuffix" xml:space="preserve">Minute(s)</x:String>
<x:String x:Key="Text.Configure.Git.ConventionalTypesOverride" xml:space="preserve">Conventional Commit Types</x:String>
<x:String x:Key="Text.Configure.Git.DefaultRemote" xml:space="preserve">Default Remote</x:String>
<x:String x:Key="Text.Configure.Git.UserProfile" xml:space="preserve">User Profile</x:String>
<x:String x:Key="Text.Configure.Git.PreferredMergeMode" xml:space="preserve">Preferred Merge Mode</x:String>
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">ISSUE TRACKER</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleAzure" xml:space="preserve">Add Azure DevOps Rule</x:String>
Expand All @@ -266,6 +267,11 @@
<x:String x:Key="Text.Configure.Proxy.Placeholder" xml:space="preserve">HTTP proxy used by this repository</x:String>
<x:String x:Key="Text.Configure.User" xml:space="preserve">User Name</x:String>
<x:String x:Key="Text.Configure.User.Placeholder" xml:space="preserve">User name for this repository</x:String>
<x:String x:Key="Text.Configure.UserProfile" xml:space="preserve">USER PROFILE</x:String>
<x:String x:Key="Text.Configure.UserProfile.ProfileName" xml:space="preserve">Profile Name</x:String>
<x:String x:Key="Text.Configure.UserProfile.UserName" xml:space="preserve">User Name</x:String>
<x:String x:Key="Text.Configure.UserProfile.Email" xml:space="preserve">Email Address</x:String>
<x:String x:Key="Text.Configure.UserProfile.Key" xml:space="preserve">User Signing Key</x:String>
<x:String x:Key="Text.ConfigureCustomActionControls" xml:space="preserve">Edit Custom Action Controls</x:String>
<x:String x:Key="Text.ConfigureCustomActionControls.CheckedValue" xml:space="preserve">Checked Value:</x:String>
<x:String x:Key="Text.ConfigureCustomActionControls.CheckedValue.Tip" xml:space="preserve">When checked, this value will be used in command-line arguments</x:String>
Expand Down
6 changes: 6 additions & 0 deletions src/ViewModels/Preferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,12 @@ public AvaloniaList<Models.CustomAction> CustomActions
set;
} = [];

public AvaloniaList<Models.UserProfile> UserProfiles
{
get;
set;
} = [];

public AvaloniaList<AI.Service> OpenAIServices
{
get;
Expand Down
42 changes: 42 additions & 0 deletions src/ViewModels/RepositoryConfigure.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;

using Avalonia.Collections;
using Avalonia.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using SourceGit.Models;
using SourceGit.Views;

namespace SourceGit.ViewModels
{
Expand All @@ -26,6 +30,11 @@ public List<string> Remotes
get;
}

public List<string> UserProfileNames
{
get;
}

public string DefaultRemote
{
get => _repo.Settings.DefaultRemote;
Expand All @@ -39,6 +48,25 @@ public string DefaultRemote
}
}

public string ProfileName
{
set
{
foreach(var profile in _profiles)
{
if (profile.ProfileName == value)
{
UserName = profile.UserName;
UserEmail = profile.Email;
GPGUserSigningKey = profile.Key;
OnPropertyChanged(nameof(UserName));
OnPropertyChanged(nameof(UserEmail));
OnPropertyChanged(nameof(GPGUserSigningKey));
}
}
}
}

public int PreferredMergeMode
{
get => _repo.Settings.PreferredMergeMode;
Expand Down Expand Up @@ -154,6 +182,15 @@ public RepositoryConfigure(Repository repo)
foreach (var remote in _repo.Remotes)
Remotes.Add(remote.Name);

UserProfileNames = new List<string>();
_profiles = new List<UserProfile>();
foreach (var profile in Preferences.Instance.UserProfiles)
{
UserProfileNames.Add(profile.ProfileName);
_profiles.Add(profile);
}


AvailableOpenAIServices = new List<string>() { "---" };
foreach (var service in Preferences.Instance.OpenAIServices)
AvailableOpenAIServices.Add(service.Name);
Expand Down Expand Up @@ -346,5 +383,10 @@ private async Task ApplyIssueTrackerChangesAsync()
private Models.CommitTemplate _selectedCommitTemplate = null;
private Models.IssueTracker _selectedIssueTracker = null;
private Models.CustomAction _selectedCustomAction = null;

public List<UserProfile> _profiles
{
get;
}
}
}
112 changes: 112 additions & 0 deletions src/Views/Preferences.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,118 @@
</Grid>
</TabItem>

<TabItem>
<TabItem.Header>
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Configure.UserProfile}"/>
</TabItem.Header>

<Grid MinHeight="360" Margin="0,8,0,16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<Border Grid.Column="0"
BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}"
Background="{DynamicResource Brush.Contents}">
<Grid RowDefinitions="*,1,Auto">
<ListBox Grid.Row="0"
Background="Transparent"
ItemsSource="{Binding UserProfiles}"
SelectedItem="{Binding #ThisControl.SelectedUserProfile, Mode=TwoWay}"
SelectionMode="Single">
<ListBox.Styles>
<Style Selector="ListBoxItem">
<Setter Property="MinHeight" Value="0"/>
<Setter Property="Height" Value="26"/>
<Setter Property="Padding" Value="4,2"/>
</Style>
</ListBox.Styles>

<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>

<ListBox.ItemTemplate>
<DataTemplate DataType="m:UserProfile">
<Grid Margin="4,0" ColumnDefinitions="Auto,*">
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.User}" Fill="{DynamicResource Brush.FG1}"/>
<TextBlock Grid.Column="1" Text="{Binding ProfileName}" Margin="6,0,0,0" TextTrimming="CharacterEllipsis"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

<Rectangle Grid.Row="1" Height="1" Fill="{DynamicResource Brush.Border2}" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"/>

<Grid Grid.Row="2" ColumnDefinitions="Auto,Auto,*,Auto,Auto" Background="{DynamicResource Brush.ToolBar}">
<Button Grid.Column="0"
Classes="icon_button"
Width="28" Height="28"
Click="OnAddUserProfile">
<Path Width="14" Height="14" Data="{StaticResource Icons.Plus}"/>
</Button>
<Button Grid.Column="1"
Classes="icon_button"
Width="28" Height="28"
Click="OnRemoveSelectedUserProfile">
<Path Width="14" Height="14" Data="{StaticResource Icons.Minus}"/>
</Button>
<Button Grid.Column="3"
Classes="icon_button"
Width="28" Height="28"
Click="OnMoveSelectedUserProfileUp"
IsVisible="{Binding #ThisControl.SelectedUserProfile, Converter={x:Static ObjectConverters.IsNotNull}}">
<Path Width="14" Height="14" Margin="0,6,0,0" Data="{StaticResource Icons.Up}"/>
</Button>
<Button Grid.Column="4"
Classes="icon_button"
Width="28" Height="28"
Click="OnMoveSelectedUserProfileDown"
IsVisible="{Binding #ThisControl.SelectedUserProfile, Converter={x:Static ObjectConverters.IsNotNull}}">
<Path Width="14" Height="14" Margin="0,6,0,0" Data="{StaticResource Icons.Down}"/>
</Button>
</Grid>
</Grid>
</Border>

<ContentControl Grid.Column="1" Margin="16,0,0,0">
<ContentControl.Content>
<Binding Path="SelectedUserProfile" ElementName="ThisControl">
<Binding.TargetNullValue>
<Path Width="64" Height="64"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="{DynamicResource Brush.FG2}"
Data="{StaticResource Icons.Empty}"/>
</Binding.TargetNullValue>
</Binding>
</ContentControl.Content>

<ContentControl.DataTemplates>
<DataTemplate DataType="m:UserProfile">
<StackPanel Orientation="Vertical">
<TextBlock Text="{DynamicResource Text.Configure.UserProfile.ProfileName}"/>
<TextBox Margin="0,4,0,0" CornerRadius="3" Height="28" Text="{Binding ProfileName, Mode=TwoWay}"/>

<TextBlock Margin="0,12,0,0" Text="{DynamicResource Text.Configure.UserProfile.UserName}"/>
<TextBox Margin="0,4,0,0" CornerRadius="3" Height="28" Text="{Binding UserName, Mode=TwoWay}"/>

<TextBlock Margin="0,12,0,0" Text="{DynamicResource Text.Configure.UserProfile.Email}"/>
<TextBox Margin="0,4,0,0" CornerRadius="3" Height="28" Text="{Binding Email, Mode=TwoWay}"/>

<TextBlock Margin="0,12,0,0" Text="{DynamicResource Text.Configure.UserProfile.Key}"/>
<TextBox Margin="0,4,0,0" CornerRadius="3" Height="28" Text="{Binding Key, Mode=TwoWay}"/>

</StackPanel>
</DataTemplate>
</ContentControl.DataTemplates>
</ContentControl>
</Grid>
</TabItem>

<TabItem>
<TabItem.Header>
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preferences.GPG}"/>
Expand Down
52 changes: 52 additions & 0 deletions src/Views/Preferences.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ public Models.CustomAction SelectedCustomAction
set => SetValue(SelectedCustomActionProperty, value);
}

public static readonly StyledProperty<Models.UserProfile> SelectedUserProfileProperty =
AvaloniaProperty.Register<Preferences, Models.UserProfile>(nameof(SelectedUserProfile));

public Models.UserProfile SelectedUserProfile
{
get => GetValue(SelectedUserProfileProperty);
set => SetValue(SelectedUserProfileProperty, value);
}

public Preferences()
{
var pref = ViewModels.Preferences.Instance;
Expand Down Expand Up @@ -495,6 +504,49 @@ private async void EditCustomActionControls(object sender, RoutedEventArgs e)
e.Handled = true;
}

private void OnAddUserProfile(object sender, RoutedEventArgs e)
{
var action = new Models.UserProfile() { ProfileName = "New Profile" };
ViewModels.Preferences.Instance.UserProfiles.Add(action);
SelectedUserProfile = action;

e.Handled = true;
}

private void OnRemoveSelectedUserProfile(object sender, RoutedEventArgs e)
{
if (SelectedUserProfile == null)
return;

ViewModels.Preferences.Instance.UserProfiles.Remove(SelectedUserProfile);
SelectedUserProfile = null;
e.Handled = true;
}

private void OnMoveSelectedUserProfileUp(object sender, RoutedEventArgs e)
{
if (SelectedUserProfile == null)
return;

var idx = ViewModels.Preferences.Instance.UserProfiles.IndexOf(SelectedUserProfile);
if (idx > 0)
ViewModels.Preferences.Instance.UserProfiles.Move(idx - 1, idx);

e.Handled = true;
}

private void OnMoveSelectedUserProfileDown(object sender, RoutedEventArgs e)
{
if (SelectedUserProfile == null)
return;

var idx = ViewModels.Preferences.Instance.UserProfiles.IndexOf(SelectedUserProfile);
if (idx < ViewModels.Preferences.Instance.UserProfiles.Count - 1)
ViewModels.Preferences.Instance.UserProfiles.Move(idx + 1, idx);

e.Handled = true;
}

private void UpdateGitVersion()
{
GitVersion = Native.OS.GitVersionString;
Expand Down
Loading