/ src / Ryujinx / UI / ViewModels / AboutWindowViewModel.cs
AboutWindowViewModel.cs
  1  using Avalonia.Media.Imaging;
  2  using Avalonia.Platform;
  3  using Avalonia.Styling;
  4  using Avalonia.Threading;
  5  using Ryujinx.Ava.Common;
  6  using Ryujinx.Ava.Common.Locale;
  7  using Ryujinx.Common.Utilities;
  8  using Ryujinx.UI.Common.Configuration;
  9  using System;
 10  using System.Net.Http;
 11  using System.Net.NetworkInformation;
 12  using System.Threading.Tasks;
 13  
 14  namespace Ryujinx.Ava.UI.ViewModels
 15  {
 16      public class AboutWindowViewModel : BaseModel, IDisposable
 17      {
 18          private Bitmap _githubLogo;
 19          private Bitmap _discordLogo;
 20          private Bitmap _patreonLogo;
 21          private Bitmap _twitterLogo;
 22  
 23          private string _version;
 24          private string _supporters;
 25  
 26          public Bitmap GithubLogo
 27          {
 28              get => _githubLogo;
 29              set
 30              {
 31                  _githubLogo = value;
 32                  OnPropertyChanged();
 33              }
 34          }
 35  
 36          public Bitmap DiscordLogo
 37          {
 38              get => _discordLogo;
 39              set
 40              {
 41                  _discordLogo = value;
 42                  OnPropertyChanged();
 43              }
 44          }
 45  
 46          public Bitmap PatreonLogo
 47          {
 48              get => _patreonLogo;
 49              set
 50              {
 51                  _patreonLogo = value;
 52                  OnPropertyChanged();
 53              }
 54          }
 55  
 56          public Bitmap TwitterLogo
 57          {
 58              get => _twitterLogo;
 59              set
 60              {
 61                  _twitterLogo = value;
 62                  OnPropertyChanged();
 63              }
 64          }
 65  
 66          public string Supporters
 67          {
 68              get => _supporters;
 69              set
 70              {
 71                  _supporters = value;
 72                  OnPropertyChanged();
 73              }
 74          }
 75  
 76          public string Version
 77          {
 78              get => _version;
 79              set
 80              {
 81                  _version = value;
 82                  OnPropertyChanged();
 83              }
 84          }
 85  
 86          public string Developers => LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.AboutPageDeveloperListMore, "gdkchan, Ac_K, marysaka, rip in peri peri, LDj3SNuD, emmaus, Thealexbarney, GoffyDude, TSRBerry, IsaacMarovitz");
 87  
 88          public AboutWindowViewModel()
 89          {
 90              Version = Program.Version;
 91              UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value);
 92              Dispatcher.UIThread.InvokeAsync(DownloadPatronsJson);
 93  
 94              ThemeManager.ThemeChanged += ThemeManager_ThemeChanged;
 95          }
 96  
 97          private void ThemeManager_ThemeChanged(object sender, EventArgs e)
 98          {
 99              Dispatcher.UIThread.Post(() => UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value));
100          }
101  
102          private void UpdateLogoTheme(string theme)
103          {
104              bool isDarkTheme = theme == "Dark" || (theme == "Auto" && App.DetectSystemTheme() == ThemeVariant.Dark);
105  
106              string basePath = "resm:Ryujinx.UI.Common.Resources.";
107              string themeSuffix = isDarkTheme ? "Dark.png" : "Light.png";
108  
109              GithubLogo = LoadBitmap($"{basePath}Logo_GitHub_{themeSuffix}?assembly=Ryujinx.UI.Common");
110              DiscordLogo = LoadBitmap($"{basePath}Logo_Discord_{themeSuffix}?assembly=Ryujinx.UI.Common");
111              PatreonLogo = LoadBitmap($"{basePath}Logo_Patreon_{themeSuffix}?assembly=Ryujinx.UI.Common");
112              TwitterLogo = LoadBitmap($"{basePath}Logo_Twitter_{themeSuffix}?assembly=Ryujinx.UI.Common");
113          }
114  
115          private Bitmap LoadBitmap(string uri)
116          {
117              return new Bitmap(Avalonia.Platform.AssetLoader.Open(new Uri(uri)));
118          }
119  
120          public void Dispose()
121          {
122              ThemeManager.ThemeChanged -= ThemeManager_ThemeChanged;
123              GC.SuppressFinalize(this);
124          }
125  
126          private async Task DownloadPatronsJson()
127          {
128              if (!NetworkInterface.GetIsNetworkAvailable())
129              {
130                  Supporters = LocaleManager.Instance[LocaleKeys.ConnectionError];
131  
132                  return;
133              }
134  
135              HttpClient httpClient = new();
136  
137              try
138              {
139                  string patreonJsonString = await httpClient.GetStringAsync("https://patreon.ryujinx.org/");
140  
141                  Supporters = string.Join(", ", JsonHelper.Deserialize(patreonJsonString, CommonJsonContext.Default.StringArray)) + "\n\n";
142              }
143              catch
144              {
145                  Supporters = LocaleManager.Instance[LocaleKeys.ApiError];
146              }
147          }
148      }
149  }