mirror of
https://fastgit.cc/github.com/sourcegit-scm/sourcegit
synced 2026-04-23 10:22:13 +08:00
refactor: move context menu creation from ViewModels to Views (PART 9)
Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
@@ -844,10 +844,6 @@
|
||||
<v:NameHighlightedTextBlock Text="{Binding}" VerticalAlignment="Center"/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="vm:CommitMessageRecord">
|
||||
<TextBlock Text="{Binding Subject}" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="vm:FilterModeInGraph">
|
||||
<v:FilterModeInGraph/>
|
||||
</DataTemplate>
|
||||
|
||||
@@ -11,13 +11,13 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
{
|
||||
public record CommitMessageRecord(string subject)
|
||||
{
|
||||
public string Subject { get; set; } = subject;
|
||||
}
|
||||
|
||||
public class WorkingCopy : ObservableObject, IDisposable
|
||||
{
|
||||
public Repository Repository
|
||||
{
|
||||
get => _repo;
|
||||
}
|
||||
|
||||
public bool IncludeUntracked
|
||||
{
|
||||
get => _repo.IncludeUntracked;
|
||||
@@ -564,6 +564,11 @@ namespace SourceGit.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyCommitMessageTemplate(Models.CommitTemplate tmpl)
|
||||
{
|
||||
CommitMessage = tmpl.Apply(_repo.CurrentBranch, _staged);
|
||||
}
|
||||
|
||||
public void Commit()
|
||||
{
|
||||
DoCommit(false, false);
|
||||
@@ -1602,137 +1607,6 @@ namespace SourceGit.ViewModels
|
||||
return menu;
|
||||
}
|
||||
|
||||
public ContextMenu CreateContextMenuForCommitMessages()
|
||||
{
|
||||
var menu = new ContextMenu();
|
||||
|
||||
var gitTemplate = new Commands.Config(_repo.FullPath).GetAsync("commit.template").Result;
|
||||
var templateCount = _repo.Settings.CommitTemplates.Count;
|
||||
if (templateCount == 0 && string.IsNullOrEmpty(gitTemplate))
|
||||
{
|
||||
menu.Items.Add(new MenuItem()
|
||||
{
|
||||
Header = App.Text("WorkingCopy.NoCommitTemplates"),
|
||||
Icon = App.CreateMenuIcon("Icons.Code"),
|
||||
IsEnabled = false
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < templateCount; i++)
|
||||
{
|
||||
var template = _repo.Settings.CommitTemplates[i];
|
||||
var item = new MenuItem();
|
||||
item.Header = App.Text("WorkingCopy.UseCommitTemplate", template.Name);
|
||||
item.Icon = App.CreateMenuIcon("Icons.Code");
|
||||
item.Click += (_, e) =>
|
||||
{
|
||||
CommitMessage = template.Apply(_repo.CurrentBranch, _staged);
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(item);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(gitTemplate))
|
||||
{
|
||||
if (!Path.IsPathRooted(gitTemplate))
|
||||
gitTemplate = Native.OS.GetAbsPath(_repo.FullPath, gitTemplate);
|
||||
|
||||
var friendlyName = gitTemplate;
|
||||
if (!OperatingSystem.IsWindows())
|
||||
{
|
||||
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
var prefixLen = home.EndsWith('/') ? home.Length - 1 : home.Length;
|
||||
if (gitTemplate.StartsWith(home, StringComparison.Ordinal))
|
||||
friendlyName = $"~{gitTemplate.AsSpan(prefixLen)}";
|
||||
}
|
||||
|
||||
var gitTemplateItem = new MenuItem();
|
||||
gitTemplateItem.Header = App.Text("WorkingCopy.UseCommitTemplate", friendlyName);
|
||||
gitTemplateItem.Icon = App.CreateMenuIcon("Icons.Code");
|
||||
gitTemplateItem.Click += (_, e) =>
|
||||
{
|
||||
if (File.Exists(gitTemplate))
|
||||
CommitMessage = File.ReadAllText(gitTemplate);
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(gitTemplateItem);
|
||||
}
|
||||
}
|
||||
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
|
||||
var historiesCount = _repo.Settings.CommitMessages.Count;
|
||||
if (historiesCount == 0)
|
||||
{
|
||||
menu.Items.Add(new MenuItem()
|
||||
{
|
||||
Header = App.Text("WorkingCopy.NoCommitHistories"),
|
||||
Icon = App.CreateMenuIcon("Icons.Histories"),
|
||||
IsEnabled = false
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < historiesCount; i++)
|
||||
{
|
||||
var dup = _repo.Settings.CommitMessages[i].Trim();
|
||||
var message = dup.ReplaceLineEndings(" ");
|
||||
var item = new MenuItem();
|
||||
item.Header = new CommitMessageRecord(message);
|
||||
item.Icon = App.CreateMenuIcon("Icons.Histories");
|
||||
item.Click += (_, e) =>
|
||||
{
|
||||
CommitMessage = dup;
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
menu.Items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
public ContextMenu CreateContextForOpenAI()
|
||||
{
|
||||
if (_staged == null || _staged.Count == 0)
|
||||
{
|
||||
App.RaiseException(_repo.FullPath, "No files added to commit!");
|
||||
return null;
|
||||
}
|
||||
|
||||
var services = _repo.GetPreferredOpenAIServices();
|
||||
if (services.Count == 0)
|
||||
{
|
||||
App.RaiseException(_repo.FullPath, "Bad configuration for OpenAI");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (services.Count == 1)
|
||||
{
|
||||
_ = App.ShowDialog(new AIAssistant(_repo, services[0], _staged, t => CommitMessage = t));
|
||||
return null;
|
||||
}
|
||||
|
||||
var menu = new ContextMenu() { Placement = PlacementMode.TopEdgeAlignedLeft };
|
||||
foreach (var service in services)
|
||||
{
|
||||
var dup = service;
|
||||
var item = new MenuItem();
|
||||
item.Header = service.Name;
|
||||
item.Click += async (_, e) =>
|
||||
{
|
||||
await App.ShowDialog(new AIAssistant(_repo, dup, _staged, t => CommitMessage = t));
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
menu.Items.Add(item);
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
private List<Models.Change> GetVisibleChanges(List<Models.Change> changes)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_filter))
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
@@ -170,11 +173,104 @@ namespace SourceGit.Views
|
||||
}
|
||||
}
|
||||
|
||||
private void OnOpenCommitMessagePicker(object sender, RoutedEventArgs e)
|
||||
private async void OnOpenCommitMessagePicker(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button button && DataContext is ViewModels.WorkingCopy vm)
|
||||
if (sender is Button button && DataContext is ViewModels.WorkingCopy vm && ShowAdvancedOptions)
|
||||
{
|
||||
var menu = vm.CreateContextMenuForCommitMessages();
|
||||
var repo = vm.Repository;
|
||||
var menu = new ContextMenu();
|
||||
|
||||
var gitTemplate = await new Commands.Config(repo.FullPath).GetAsync("commit.template");
|
||||
var templateCount = repo.Settings.CommitTemplates.Count;
|
||||
if (templateCount == 0 && string.IsNullOrEmpty(gitTemplate))
|
||||
{
|
||||
menu.Items.Add(new MenuItem()
|
||||
{
|
||||
Header = App.Text("WorkingCopy.NoCommitTemplates"),
|
||||
Icon = App.CreateMenuIcon("Icons.Code"),
|
||||
IsEnabled = false
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < templateCount; i++)
|
||||
{
|
||||
var template = repo.Settings.CommitTemplates[i];
|
||||
var item = new MenuItem();
|
||||
item.Header = App.Text("WorkingCopy.UseCommitTemplate", template.Name);
|
||||
item.Icon = App.CreateMenuIcon("Icons.Code");
|
||||
item.Click += (_, e) =>
|
||||
{
|
||||
vm.ApplyCommitMessageTemplate(template);
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(item);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(gitTemplate))
|
||||
{
|
||||
if (!Path.IsPathRooted(gitTemplate))
|
||||
gitTemplate = Native.OS.GetAbsPath(repo.FullPath, gitTemplate);
|
||||
|
||||
var friendlyName = gitTemplate;
|
||||
if (!OperatingSystem.IsWindows())
|
||||
{
|
||||
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
var prefixLen = home.EndsWith('/') ? home.Length - 1 : home.Length;
|
||||
if (gitTemplate.StartsWith(home, StringComparison.Ordinal))
|
||||
friendlyName = $"~{gitTemplate.AsSpan(prefixLen)}";
|
||||
}
|
||||
|
||||
var gitTemplateItem = new MenuItem();
|
||||
gitTemplateItem.Header = App.Text("WorkingCopy.UseCommitTemplate", friendlyName);
|
||||
gitTemplateItem.Icon = App.CreateMenuIcon("Icons.Code");
|
||||
gitTemplateItem.Click += (_, e) =>
|
||||
{
|
||||
if (File.Exists(gitTemplate))
|
||||
vm.CommitMessage = File.ReadAllText(gitTemplate);
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(gitTemplateItem);
|
||||
}
|
||||
}
|
||||
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
|
||||
var historiesCount = repo.Settings.CommitMessages.Count;
|
||||
if (historiesCount == 0)
|
||||
{
|
||||
menu.Items.Add(new MenuItem()
|
||||
{
|
||||
Header = App.Text("WorkingCopy.NoCommitHistories"),
|
||||
Icon = App.CreateMenuIcon("Icons.Histories"),
|
||||
IsEnabled = false
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < historiesCount; i++)
|
||||
{
|
||||
var dup = repo.Settings.CommitMessages[i].Trim();
|
||||
var header = new TextBlock()
|
||||
{
|
||||
Text = dup.ReplaceLineEndings(" "),
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
TextTrimming = TextTrimming.CharacterEllipsis
|
||||
};
|
||||
|
||||
var item = new MenuItem();
|
||||
item.Header = header;
|
||||
item.Icon = App.CreateMenuIcon("Icons.Histories");
|
||||
item.Click += (_, e) =>
|
||||
{
|
||||
vm.CommitMessage = dup;
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
menu.Items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
menu.Placement = PlacementMode.TopEdgeAlignedLeft;
|
||||
menu.Open(button);
|
||||
}
|
||||
@@ -182,25 +278,59 @@ namespace SourceGit.Views
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnOpenOpenAIHelper(object sender, RoutedEventArgs e)
|
||||
private async void OnOpenOpenAIHelper(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.WorkingCopy vm && sender is Control control)
|
||||
if (DataContext is ViewModels.WorkingCopy vm && sender is Control control && ShowAdvancedOptions)
|
||||
{
|
||||
var menu = vm.CreateContextForOpenAI();
|
||||
menu?.Open(control);
|
||||
var repo = vm.Repository;
|
||||
|
||||
if (vm.Staged == null || vm.Staged.Count == 0)
|
||||
{
|
||||
App.RaiseException(repo.FullPath, "No files added to commit!");
|
||||
return;
|
||||
}
|
||||
|
||||
var services = repo.GetPreferredOpenAIServices();
|
||||
if (services.Count == 0)
|
||||
{
|
||||
App.RaiseException(repo.FullPath, "Bad configuration for OpenAI");
|
||||
return;
|
||||
}
|
||||
|
||||
if (services.Count == 1)
|
||||
{
|
||||
await App.ShowDialog(new ViewModels.AIAssistant(repo, services[0], vm.Staged, t => vm.CommitMessage = t));
|
||||
return;
|
||||
}
|
||||
|
||||
var menu = new ContextMenu() { Placement = PlacementMode.TopEdgeAlignedLeft };
|
||||
foreach (var service in services)
|
||||
{
|
||||
var dup = service;
|
||||
var item = new MenuItem();
|
||||
item.Header = service.Name;
|
||||
item.Click += async (_, e) =>
|
||||
{
|
||||
await App.ShowDialog(new ViewModels.AIAssistant(repo, dup, vm.Staged, t => vm.CommitMessage = t));
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
menu.Items.Add(item);
|
||||
}
|
||||
menu.Open(control);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnOpenConventionalCommitHelper(object _, RoutedEventArgs e)
|
||||
private async void OnOpenConventionalCommitHelper(object _, RoutedEventArgs e)
|
||||
{
|
||||
var toplevel = TopLevel.GetTopLevel(this);
|
||||
if (toplevel is Window owner)
|
||||
{
|
||||
var vm = new ViewModels.ConventionalCommitMessageBuilder(text => Text = text);
|
||||
var builder = new ConventionalCommitMessageBuilder() { DataContext = vm };
|
||||
builder.ShowDialog(owner);
|
||||
await builder.ShowDialog(owner);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
|
||||
Reference in New Issue
Block a user