Skip to content

Commit dd00d0e

Browse files
committed
refactor: move context menu creation from ViewModels to Views (PART 5)
Signed-off-by: leo <longshuang@msn.cn>
1 parent f2830e9 commit dd00d0e

File tree

2 files changed

+191
-170
lines changed

2 files changed

+191
-170
lines changed

src/ViewModels/StashesPage.cs

Lines changed: 66 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.IO;
43
using System.Threading.Tasks;
54

6-
using Avalonia.Controls;
7-
using Avalonia.Platform.Storage;
85
using Avalonia.Threading;
9-
106
using CommunityToolkit.Mvvm.ComponentModel;
117

128
namespace SourceGit.ViewModels
139
{
1410
public class StashesPage : ObservableObject, IDisposable
1511
{
12+
public string RepositoryPath
13+
{
14+
get => _repo.FullPath;
15+
}
16+
1617
public List<Models.Stash> Stashes
1718
{
1819
get => _stashes;
@@ -140,184 +141,84 @@ public void Dispose()
140141
_diffContext = null;
141142
}
142143

143-
public ContextMenu MakeContextMenu(Models.Stash stash)
144+
public void ClearSearchFilter()
144145
{
145-
var apply = new MenuItem();
146-
apply.Header = App.Text("StashCM.Apply");
147-
apply.Icon = App.CreateMenuIcon("Icons.CheckCircled");
148-
apply.Click += (_, ev) =>
149-
{
150-
Apply(stash);
151-
ev.Handled = true;
152-
};
153-
154-
var drop = new MenuItem();
155-
drop.Header = App.Text("StashCM.Drop");
156-
drop.Icon = App.CreateMenuIcon("Icons.Clear");
157-
drop.Tag = "Back/Delete";
158-
drop.Click += (_, ev) =>
159-
{
160-
Drop(stash);
161-
ev.Handled = true;
162-
};
163-
164-
var patch = new MenuItem();
165-
patch.Header = App.Text("StashCM.SaveAsPatch");
166-
patch.Icon = App.CreateMenuIcon("Icons.Diff");
167-
patch.Click += async (_, e) =>
168-
{
169-
var storageProvider = App.GetStorageProvider();
170-
if (storageProvider == null)
171-
return;
172-
173-
var options = new FilePickerSaveOptions();
174-
options.Title = App.Text("StashCM.SaveAsPatch");
175-
options.DefaultExtension = ".patch";
176-
options.FileTypeChoices = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }];
177-
178-
var storageFile = await storageProvider.SaveFilePickerAsync(options);
179-
if (storageFile != null)
180-
{
181-
var opts = new List<Models.DiffOption>();
182-
foreach (var c in _changes)
183-
{
184-
if (_untracked.Contains(c))
185-
opts.Add(new Models.DiffOption(Models.Commit.EmptyTreeSHA1, _selectedStash.Parents[2], c));
186-
else
187-
opts.Add(new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, c));
188-
}
189-
190-
var succ = await Commands.SaveChangesAsPatch.ProcessStashChangesAsync(_repo.FullPath, opts, storageFile.Path.LocalPath);
191-
if (succ)
192-
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
193-
}
146+
SearchFilter = string.Empty;
147+
}
194148

195-
e.Handled = true;
196-
};
149+
public void Apply(Models.Stash stash)
150+
{
151+
if (_repo.CanCreatePopup())
152+
_repo.ShowPopup(new ApplyStash(_repo, stash));
153+
}
197154

198-
var copy = new MenuItem();
199-
copy.Header = App.Text("StashCM.CopyMessage");
200-
copy.Icon = App.CreateMenuIcon("Icons.Copy");
201-
copy.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C";
202-
copy.Click += async (_, ev) =>
203-
{
204-
await App.CopyTextAsync(stash.Message);
205-
ev.Handled = true;
206-
};
207-
208-
var menu = new ContextMenu();
209-
menu.Items.Add(apply);
210-
menu.Items.Add(drop);
211-
menu.Items.Add(new MenuItem { Header = "-" });
212-
menu.Items.Add(patch);
213-
menu.Items.Add(new MenuItem { Header = "-" });
214-
menu.Items.Add(copy);
215-
return menu;
155+
public void Drop(Models.Stash stash)
156+
{
157+
if (_repo.CanCreatePopup())
158+
_repo.ShowPopup(new DropStash(_repo, stash));
216159
}
217160

218-
public ContextMenu MakeContextMenuForChange()
161+
public async Task SaveStashAsPathAsync(Models.Stash stash, string saveTo)
219162
{
220-
if (_selectedChanges is not { Count: 1 })
221-
return null;
222-
223-
var change = _selectedChanges[0];
224-
var openWithMerger = new MenuItem();
225-
openWithMerger.Header = App.Text("OpenInExternalMergeTool");
226-
openWithMerger.Icon = App.CreateMenuIcon("Icons.OpenWith");
227-
openWithMerger.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+D" : "Ctrl+Shift+D";
228-
openWithMerger.Click += (_, ev) =>
229-
{
230-
var toolType = Preferences.Instance.ExternalMergeToolType;
231-
var toolPath = Preferences.Instance.ExternalMergeToolPath;
232-
var opt = new Models.DiffOption($"{_selectedStash.SHA}^", _selectedStash.SHA, change);
233-
new Commands.DiffTool(_repo.FullPath, toolType, toolPath, opt).Open();
234-
ev.Handled = true;
235-
};
236-
237-
var fullPath = Path.Combine(_repo.FullPath, change.Path);
238-
var explore = new MenuItem();
239-
explore.Header = App.Text("RevealFile");
240-
explore.Icon = App.CreateMenuIcon("Icons.Explore");
241-
explore.IsEnabled = File.Exists(fullPath);
242-
explore.Click += (_, ev) =>
243-
{
244-
Native.OS.OpenInFileManager(fullPath, true);
245-
ev.Handled = true;
246-
};
247-
248-
var resetToThisRevision = new MenuItem();
249-
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
250-
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
251-
resetToThisRevision.Click += async (_, ev) =>
163+
var opts = new List<Models.DiffOption>();
164+
var changes = await new Commands.CompareRevisions(_repo.FullPath, $"{stash.SHA}^", stash.SHA)
165+
.ReadAsync()
166+
.ConfigureAwait(false);
167+
168+
foreach (var c in changes)
169+
opts.Add(new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, c));
170+
171+
if (stash.Parents.Count == 3)
252172
{
253-
var log = _repo.CreateLog($"Reset File to '{_selectedStash.SHA}'");
173+
var untracked = await new Commands.CompareRevisions(_repo.FullPath, Models.Commit.EmptyTreeSHA1, stash.Parents[2])
174+
.ReadAsync()
175+
.ConfigureAwait(false);
254176

255-
if (_untracked.Contains(change))
256-
{
257-
await Commands.SaveRevisionFile.RunAsync(_repo.FullPath, _selectedStash.Parents[2], change.Path, fullPath);
258-
}
259-
else if (change.Index == Models.ChangeState.Added)
260-
{
261-
await Commands.SaveRevisionFile.RunAsync(_repo.FullPath, _selectedStash.SHA, change.Path, fullPath);
262-
}
263-
else
264-
{
265-
await new Commands.Checkout(_repo.FullPath)
266-
.Use(log)
267-
.FileWithRevisionAsync(change.Path, $"{_selectedStash.SHA}");
268-
}
177+
foreach (var c in untracked)
178+
opts.Add(new Models.DiffOption(Models.Commit.EmptyTreeSHA1, _selectedStash.Parents[2], c));
269179

270-
log.Complete();
271-
ev.Handled = true;
272-
};
180+
changes.AddRange(untracked);
181+
}
273182

274-
var copyPath = new MenuItem();
275-
copyPath.Header = App.Text("CopyPath");
276-
copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
277-
copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C";
278-
copyPath.Click += async (_, ev) =>
279-
{
280-
await App.CopyTextAsync(change.Path);
281-
ev.Handled = true;
282-
};
283-
284-
var copyFullPath = new MenuItem();
285-
copyFullPath.Header = App.Text("CopyFullPath");
286-
copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
287-
copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C";
288-
copyFullPath.Click += async (_, e) =>
289-
{
290-
await App.CopyTextAsync(Native.OS.GetAbsPath(_repo.FullPath, change.Path));
291-
e.Handled = true;
292-
};
293-
294-
var menu = new ContextMenu();
295-
menu.Items.Add(openWithMerger);
296-
menu.Items.Add(explore);
297-
menu.Items.Add(new MenuItem { Header = "-" });
298-
menu.Items.Add(resetToThisRevision);
299-
menu.Items.Add(new MenuItem { Header = "-" });
300-
menu.Items.Add(copyPath);
301-
menu.Items.Add(copyFullPath);
302-
303-
return menu;
183+
var succ = await Commands.SaveChangesAsPatch.ProcessStashChangesAsync(_repo.FullPath, opts, saveTo);
184+
if (succ)
185+
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
304186
}
305187

306-
public void ClearSearchFilter()
188+
public void OpenChangeWithExternalDiffTool(Models.Change change)
307189
{
308-
SearchFilter = string.Empty;
309-
}
190+
Models.DiffOption opt;
191+
if (_untracked.Contains(change))
192+
opt = new Models.DiffOption(Models.Commit.EmptyTreeSHA1, _selectedStash.Parents[2], change);
193+
else
194+
opt = new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, change);
310195

311-
public void Apply(Models.Stash stash)
312-
{
313-
if (_repo.CanCreatePopup())
314-
_repo.ShowPopup(new ApplyStash(_repo, stash));
196+
var toolType = Preferences.Instance.ExternalMergeToolType;
197+
var toolPath = Preferences.Instance.ExternalMergeToolPath;
198+
new Commands.DiffTool(_repo.FullPath, toolType, toolPath, opt).Open();
315199
}
316200

317-
public void Drop(Models.Stash stash)
201+
public async Task CheckoutSingleFileAsync(Models.Change change)
318202
{
319-
if (_repo.CanCreatePopup())
320-
_repo.ShowPopup(new DropStash(_repo, stash));
203+
var fullPath = Native.OS.GetAbsPath(_repo.FullPath, change.Path);
204+
var log = _repo.CreateLog($"Reset File to '{_selectedStash.SHA}'");
205+
206+
if (_untracked.Contains(change))
207+
{
208+
await Commands.SaveRevisionFile.RunAsync(_repo.FullPath, _selectedStash.Parents[2], change.Path, fullPath);
209+
}
210+
else if (change.Index == Models.ChangeState.Added)
211+
{
212+
await Commands.SaveRevisionFile.RunAsync(_repo.FullPath, _selectedStash.SHA, change.Path, fullPath);
213+
}
214+
else
215+
{
216+
await new Commands.Checkout(_repo.FullPath)
217+
.Use(log)
218+
.FileWithRevisionAsync(change.Path, $"{_selectedStash.SHA}");
219+
}
220+
221+
log.Complete();
321222
}
322223

323224
private void RefreshVisible()

0 commit comments

Comments
 (0)