|
1 | 1 | using System; |
| 2 | +using System.IO; |
2 | 3 |
|
3 | 4 | using Avalonia; |
4 | 5 | using Avalonia.Controls; |
5 | 6 | using Avalonia.Input; |
6 | 7 | using Avalonia.Interactivity; |
| 8 | +using Avalonia.Layout; |
| 9 | +using Avalonia.Media; |
7 | 10 |
|
8 | 11 | namespace SourceGit.Views |
9 | 12 | { |
@@ -170,37 +173,164 @@ private void OnDescriptionTextBoxPreviewKeyDown(object _, KeyEventArgs e) |
170 | 173 | } |
171 | 174 | } |
172 | 175 |
|
173 | | - private void OnOpenCommitMessagePicker(object sender, RoutedEventArgs e) |
| 176 | + private async void OnOpenCommitMessagePicker(object sender, RoutedEventArgs e) |
174 | 177 | { |
175 | | - if (sender is Button button && DataContext is ViewModels.WorkingCopy vm) |
| 178 | + if (sender is Button button && DataContext is ViewModels.WorkingCopy vm && ShowAdvancedOptions) |
176 | 179 | { |
177 | | - var menu = vm.CreateContextMenuForCommitMessages(); |
| 180 | + var repo = vm.Repository; |
| 181 | + var menu = new ContextMenu(); |
| 182 | + |
| 183 | + var gitTemplate = await new Commands.Config(repo.FullPath).GetAsync("commit.template"); |
| 184 | + var templateCount = repo.Settings.CommitTemplates.Count; |
| 185 | + if (templateCount == 0 && string.IsNullOrEmpty(gitTemplate)) |
| 186 | + { |
| 187 | + menu.Items.Add(new MenuItem() |
| 188 | + { |
| 189 | + Header = App.Text("WorkingCopy.NoCommitTemplates"), |
| 190 | + Icon = App.CreateMenuIcon("Icons.Code"), |
| 191 | + IsEnabled = false |
| 192 | + }); |
| 193 | + } |
| 194 | + else |
| 195 | + { |
| 196 | + for (int i = 0; i < templateCount; i++) |
| 197 | + { |
| 198 | + var template = repo.Settings.CommitTemplates[i]; |
| 199 | + var item = new MenuItem(); |
| 200 | + item.Header = App.Text("WorkingCopy.UseCommitTemplate", template.Name); |
| 201 | + item.Icon = App.CreateMenuIcon("Icons.Code"); |
| 202 | + item.Click += (_, e) => |
| 203 | + { |
| 204 | + vm.ApplyCommitMessageTemplate(template); |
| 205 | + e.Handled = true; |
| 206 | + }; |
| 207 | + menu.Items.Add(item); |
| 208 | + } |
| 209 | + |
| 210 | + if (!string.IsNullOrEmpty(gitTemplate)) |
| 211 | + { |
| 212 | + if (!Path.IsPathRooted(gitTemplate)) |
| 213 | + gitTemplate = Native.OS.GetAbsPath(repo.FullPath, gitTemplate); |
| 214 | + |
| 215 | + var friendlyName = gitTemplate; |
| 216 | + if (!OperatingSystem.IsWindows()) |
| 217 | + { |
| 218 | + var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); |
| 219 | + var prefixLen = home.EndsWith('/') ? home.Length - 1 : home.Length; |
| 220 | + if (gitTemplate.StartsWith(home, StringComparison.Ordinal)) |
| 221 | + friendlyName = $"~{gitTemplate.AsSpan(prefixLen)}"; |
| 222 | + } |
| 223 | + |
| 224 | + var gitTemplateItem = new MenuItem(); |
| 225 | + gitTemplateItem.Header = App.Text("WorkingCopy.UseCommitTemplate", friendlyName); |
| 226 | + gitTemplateItem.Icon = App.CreateMenuIcon("Icons.Code"); |
| 227 | + gitTemplateItem.Click += (_, e) => |
| 228 | + { |
| 229 | + if (File.Exists(gitTemplate)) |
| 230 | + vm.CommitMessage = File.ReadAllText(gitTemplate); |
| 231 | + e.Handled = true; |
| 232 | + }; |
| 233 | + menu.Items.Add(gitTemplateItem); |
| 234 | + } |
| 235 | + } |
| 236 | + |
| 237 | + menu.Items.Add(new MenuItem() { Header = "-" }); |
| 238 | + |
| 239 | + var historiesCount = repo.Settings.CommitMessages.Count; |
| 240 | + if (historiesCount == 0) |
| 241 | + { |
| 242 | + menu.Items.Add(new MenuItem() |
| 243 | + { |
| 244 | + Header = App.Text("WorkingCopy.NoCommitHistories"), |
| 245 | + Icon = App.CreateMenuIcon("Icons.Histories"), |
| 246 | + IsEnabled = false |
| 247 | + }); |
| 248 | + } |
| 249 | + else |
| 250 | + { |
| 251 | + for (int i = 0; i < historiesCount; i++) |
| 252 | + { |
| 253 | + var dup = repo.Settings.CommitMessages[i].Trim(); |
| 254 | + var header = new TextBlock() |
| 255 | + { |
| 256 | + Text = dup.ReplaceLineEndings(" "), |
| 257 | + VerticalAlignment = VerticalAlignment.Center, |
| 258 | + TextTrimming = TextTrimming.CharacterEllipsis |
| 259 | + }; |
| 260 | + |
| 261 | + var item = new MenuItem(); |
| 262 | + item.Header = header; |
| 263 | + item.Icon = App.CreateMenuIcon("Icons.Histories"); |
| 264 | + item.Click += (_, e) => |
| 265 | + { |
| 266 | + vm.CommitMessage = dup; |
| 267 | + e.Handled = true; |
| 268 | + }; |
| 269 | + |
| 270 | + menu.Items.Add(item); |
| 271 | + } |
| 272 | + } |
| 273 | + |
178 | 274 | menu.Placement = PlacementMode.TopEdgeAlignedLeft; |
179 | 275 | menu.Open(button); |
180 | 276 | } |
181 | 277 |
|
182 | 278 | e.Handled = true; |
183 | 279 | } |
184 | 280 |
|
185 | | - private void OnOpenOpenAIHelper(object sender, RoutedEventArgs e) |
| 281 | + private async void OnOpenOpenAIHelper(object sender, RoutedEventArgs e) |
186 | 282 | { |
187 | | - if (DataContext is ViewModels.WorkingCopy vm && sender is Control control) |
| 283 | + if (DataContext is ViewModels.WorkingCopy vm && sender is Control control && ShowAdvancedOptions) |
188 | 284 | { |
189 | | - var menu = vm.CreateContextForOpenAI(); |
190 | | - menu?.Open(control); |
| 285 | + var repo = vm.Repository; |
| 286 | + |
| 287 | + if (vm.Staged == null || vm.Staged.Count == 0) |
| 288 | + { |
| 289 | + App.RaiseException(repo.FullPath, "No files added to commit!"); |
| 290 | + return; |
| 291 | + } |
| 292 | + |
| 293 | + var services = repo.GetPreferredOpenAIServices(); |
| 294 | + if (services.Count == 0) |
| 295 | + { |
| 296 | + App.RaiseException(repo.FullPath, "Bad configuration for OpenAI"); |
| 297 | + return; |
| 298 | + } |
| 299 | + |
| 300 | + if (services.Count == 1) |
| 301 | + { |
| 302 | + await App.ShowDialog(new ViewModels.AIAssistant(repo, services[0], vm.Staged, t => vm.CommitMessage = t)); |
| 303 | + return; |
| 304 | + } |
| 305 | + |
| 306 | + var menu = new ContextMenu() { Placement = PlacementMode.TopEdgeAlignedLeft }; |
| 307 | + foreach (var service in services) |
| 308 | + { |
| 309 | + var dup = service; |
| 310 | + var item = new MenuItem(); |
| 311 | + item.Header = service.Name; |
| 312 | + item.Click += async (_, e) => |
| 313 | + { |
| 314 | + await App.ShowDialog(new ViewModels.AIAssistant(repo, dup, vm.Staged, t => vm.CommitMessage = t)); |
| 315 | + e.Handled = true; |
| 316 | + }; |
| 317 | + |
| 318 | + menu.Items.Add(item); |
| 319 | + } |
| 320 | + menu.Open(control); |
191 | 321 | } |
192 | 322 |
|
193 | 323 | e.Handled = true; |
194 | 324 | } |
195 | 325 |
|
196 | | - private void OnOpenConventionalCommitHelper(object _, RoutedEventArgs e) |
| 326 | + private async void OnOpenConventionalCommitHelper(object _, RoutedEventArgs e) |
197 | 327 | { |
198 | 328 | var toplevel = TopLevel.GetTopLevel(this); |
199 | 329 | if (toplevel is Window owner) |
200 | 330 | { |
201 | 331 | var vm = new ViewModels.ConventionalCommitMessageBuilder(text => Text = text); |
202 | 332 | var builder = new ConventionalCommitMessageBuilder() { DataContext = vm }; |
203 | | - builder.ShowDialog(owner); |
| 333 | + await builder.ShowDialog(owner); |
204 | 334 | } |
205 | 335 |
|
206 | 336 | e.Handled = true; |
|
0 commit comments