/ src / Ryujinx / UI / Views / User / UserSaveManagerView.axaml.cs
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  }