UserSaveManagerView.axaml.cs
1 using Avalonia.Controls; 2 using Avalonia.Interactivity; 3 using Avalonia.Threading; 4 using FluentAvalonia.UI.Controls; 5 using FluentAvalonia.UI.Navigation; 6 using LibHac; 7 using LibHac.Common; 8 using LibHac.Fs; 9 using LibHac.Fs.Shim; 10 using Ryujinx.Ava.Common; 11 using Ryujinx.Ava.Common.Locale; 12 using Ryujinx.Ava.UI.Controls; 13 using Ryujinx.Ava.UI.Helpers; 14 using Ryujinx.Ava.UI.Models; 15 using Ryujinx.Ava.UI.ViewModels; 16 using Ryujinx.HLE.FileSystem; 17 using Ryujinx.HLE.HOS.Services.Account.Acc; 18 using System; 19 using System.Collections.ObjectModel; 20 using System.Threading.Tasks; 21 using Button = Avalonia.Controls.Button; 22 using UserId = LibHac.Fs.UserId; 23 24 namespace Ryujinx.Ava.UI.Views.User 25 { 26 public partial class UserSaveManagerView : UserControl 27 { 28 internal UserSaveManagerViewModel ViewModel { get; private set; } 29 30 private AccountManager _accountManager; 31 private HorizonClient _horizonClient; 32 private VirtualFileSystem _virtualFileSystem; 33 private NavigationDialogHost _parent; 34 35 public UserSaveManagerView() 36 { 37 InitializeComponent(); 38 AddHandler(Frame.NavigatedToEvent, (s, e) => 39 { 40 NavigatedTo(e); 41 }, RoutingStrategies.Direct); 42 } 43 44 private void NavigatedTo(NavigationEventArgs arg) 45 { 46 if (Program.PreviewerDetached) 47 { 48 switch (arg.NavigationMode) 49 { 50 case NavigationMode.New: 51 var (parent, accountManager, client, virtualFileSystem) = ((NavigationDialogHost parent, AccountManager accountManager, HorizonClient client, VirtualFileSystem virtualFileSystem))arg.Parameter; 52 _accountManager = accountManager; 53 _horizonClient = client; 54 _virtualFileSystem = virtualFileSystem; 55 56 _parent = parent; 57 break; 58 } 59 60 DataContext = ViewModel = new UserSaveManagerViewModel(_accountManager); 61 ((ContentDialog)_parent.Parent).Title = $"{LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle]} - {ViewModel.SaveManagerHeading}"; 62 63 Task.Run(LoadSaves); 64 } 65 } 66 67 public void LoadSaves() 68 { 69 ViewModel.Saves.Clear(); 70 var saves = new ObservableCollection<SaveModel>(); 71 var saveDataFilter = SaveDataFilter.Make( 72 programId: default, 73 saveType: SaveDataType.Account, 74 new UserId((ulong)_accountManager.LastOpenedUser.UserId.High, (ulong)_accountManager.LastOpenedUser.UserId.Low), 75 saveDataId: default, 76 index: default); 77 78 using var saveDataIterator = new UniqueRef<SaveDataIterator>(); 79 80 _horizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref, SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure(); 81 82 Span<SaveDataInfo> saveDataInfo = stackalloc SaveDataInfo[10]; 83 84 while (true) 85 { 86 saveDataIterator.Get.ReadSaveDataInfo(out long readCount, saveDataInfo).ThrowIfFailure(); 87 88 if (readCount == 0) 89 { 90 break; 91 } 92 93 for (int i = 0; i < readCount; i++) 94 { 95 var save = saveDataInfo[i]; 96 if (save.ProgramId.Value != 0) 97 { 98 var saveModel = new SaveModel(save); 99 saves.Add(saveModel); 100 } 101 } 102 } 103 104 Dispatcher.UIThread.Post(() => 105 { 106 ViewModel.Saves = saves; 107 ViewModel.Sort(); 108 }); 109 } 110 111 private void GoBack(object sender, RoutedEventArgs e) 112 { 113 _parent?.GoBack(); 114 } 115 116 private void OpenLocation(object sender, RoutedEventArgs e) 117 { 118 if (sender is Button button) 119 { 120 if (button.DataContext is SaveModel saveModel) 121 { 122 ApplicationHelper.OpenSaveDir(saveModel.SaveId); 123 } 124 } 125 } 126 127 private async void Delete(object sender, RoutedEventArgs e) 128 { 129 if (sender is Button button) 130 { 131 if (button.DataContext is SaveModel saveModel) 132 { 133 var result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance[LocaleKeys.DeleteUserSave], 134 LocaleManager.Instance[LocaleKeys.IrreversibleActionNote], 135 LocaleManager.Instance[LocaleKeys.InputDialogYes], 136 LocaleManager.Instance[LocaleKeys.InputDialogNo], ""); 137 138 if (result == UserResult.Yes) 139 { 140 _horizonClient.Fs.DeleteSaveData(SaveDataSpaceId.User, saveModel.SaveId); 141 ViewModel.Saves.Remove(saveModel); 142 ViewModel.Sort(); 143 } 144 } 145 } 146 } 147 } 148 }