From a54e0056c2d204fae49b6d474d4437d65c03b0ab Mon Sep 17 00:00:00 2001 From: Asval Date: Sun, 22 Sep 2024 20:23:59 +0200 Subject: [PATCH] ctrl s --- FModel/Constants.cs | 1 + FModel/MainWindow.xaml.cs | 2 + .../ApiEndpoints/FModelApiEndpoint.cs | 11 +++ .../ApiEndpoints/Models/FModelResponse.cs | 22 +++++ FModel/ViewModels/UpdateViewModel.cs | 29 +++++++ .../Resources/Controls/CommitControl.xaml | 81 +++++++++++++++++++ .../Resources/Controls/CommitControl.xaml.cs | 12 +++ .../Converters/CommitMessageConverter.cs | 25 ++++++ .../Converters/DateTimeToDateConverter.cs | 24 ++++++ .../Converters/RelativeDateTimeConverter.cs | 62 ++++++++++++++ FModel/Views/Resources/Resources.xaml | 1 + FModel/Views/UpdateView.xaml | 66 +++++++++++++++ FModel/Views/UpdateView.xaml.cs | 30 +++++++ 13 files changed, 366 insertions(+) create mode 100644 FModel/ViewModels/UpdateViewModel.cs create mode 100644 FModel/Views/Resources/Controls/CommitControl.xaml create mode 100644 FModel/Views/Resources/Controls/CommitControl.xaml.cs create mode 100644 FModel/Views/Resources/Converters/CommitMessageConverter.cs create mode 100644 FModel/Views/Resources/Converters/DateTimeToDateConverter.cs create mode 100644 FModel/Views/Resources/Converters/RelativeDateTimeConverter.cs create mode 100644 FModel/Views/UpdateView.xaml create mode 100644 FModel/Views/UpdateView.xaml.cs diff --git a/FModel/Constants.cs b/FModel/Constants.cs index a0bf4597..409ddba4 100644 --- a/FModel/Constants.cs +++ b/FModel/Constants.cs @@ -21,6 +21,7 @@ public static class Constants public const string BLUE = "#528BCC"; public const string ISSUE_LINK = "https://github.com/4sval/FModel/discussions/categories/q-a"; + public const string COMMITS_LINK = "https://api.github.com/repos/4sval/FModel/commits"; public const string DONATE_LINK = "https://fmodel.app/donate"; public const string DISCORD_LINK = "https://fmodel.app/discord"; diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs index 6dcede02..150ed139 100644 --- a/FModel/MainWindow.xaml.cs +++ b/FModel/MainWindow.xaml.cs @@ -45,6 +45,8 @@ public partial class MainWindow private async void OnLoaded(object sender, RoutedEventArgs e) { + var result = new UpdateView().ShowDialog(); + var newOrUpdated = UserSettings.Default.ShowChangelog; #if !DEBUG ApplicationService.ApiEndpointView.FModelApi.CheckForUpdates(UserSettings.Default.UpdateMode, true); diff --git a/FModel/ViewModels/ApiEndpoints/FModelApiEndpoint.cs b/FModel/ViewModels/ApiEndpoints/FModelApiEndpoint.cs index 1fbe18f0..99a695f9 100644 --- a/FModel/ViewModels/ApiEndpoints/FModelApiEndpoint.cs +++ b/FModel/ViewModels/ApiEndpoints/FModelApiEndpoint.cs @@ -22,6 +22,7 @@ namespace FModel.ViewModels.ApiEndpoints; public class FModelApiEndpoint : AbstractApiProvider { + private GitHubCommit[] _commits; private News _news; private Info _infos; private Donator[] _donators; @@ -32,6 +33,16 @@ public class FModelApiEndpoint : AbstractApiProvider public FModelApiEndpoint(RestClient client) : base(client) { } + public async Task GetGitHubCommitHistoryAsync(string branch = "dev", int page = 1, int limit = 20) + { + var request = new FRestRequest(Constants.COMMITS_LINK); + request.AddParameter("sha", branch); + request.AddParameter("page", page); + request.AddParameter("per_page", limit); + var response = await _client.ExecuteAsync(request).ConfigureAwait(false); + return response.Data; + } + public async Task GetNewsAsync(CancellationToken token, string game) { var request = new FRestRequest($"https://api.fmodel.app/v1/news/{Constants.APP_VERSION}"); diff --git a/FModel/ViewModels/ApiEndpoints/Models/FModelResponse.cs b/FModel/ViewModels/ApiEndpoints/Models/FModelResponse.cs index 6c9b8dc4..bb5900e5 100644 --- a/FModel/ViewModels/ApiEndpoints/Models/FModelResponse.cs +++ b/FModel/ViewModels/ApiEndpoints/Models/FModelResponse.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Diagnostics; using CUE4Parse.UE4.Versions; @@ -8,6 +9,27 @@ using J = Newtonsoft.Json.JsonPropertyAttribute; namespace FModel.ViewModels.ApiEndpoints.Models; +public class GitHubCommit +{ + [J("sha")] public string Sha { get; private set; } + [J("commit")] public Commit Commit { get; private set; } + [J("author")] public Author Author { get; private set; } +} + +public class Commit +{ + [J("author")] public Author Author { get; set; } + [J("message")] public string Message { get; set; } +} + +public class Author +{ + [J("name")] public string Name { get; set; } + [J("date")] public DateTime Date { get; set; } + [J("avatar_url")] public string AvatarUrl { get; set; } + [J("html_url")] public string HtmlUrl { get; set; } +} + [DebuggerDisplay("{" + nameof(Messages) + "}")] public class News { diff --git a/FModel/ViewModels/UpdateViewModel.cs b/FModel/ViewModels/UpdateViewModel.cs new file mode 100644 index 00000000..4a287efa --- /dev/null +++ b/FModel/ViewModels/UpdateViewModel.cs @@ -0,0 +1,29 @@ +using System.ComponentModel; +using System.Threading.Tasks; +using System.Windows.Data; +using FModel.Framework; +using FModel.Services; +using FModel.ViewModels.ApiEndpoints.Models; +using FModel.Views.Resources.Converters; + +namespace FModel.ViewModels; + +public class UpdateViewModel : ViewModel +{ + public RangeObservableCollection Commits { get; } + public ICollectionView CommitsView { get; } + + public UpdateViewModel() + { + Commits = new RangeObservableCollection(); + CommitsView = new ListCollectionView(Commits) + { + GroupDescriptions = { new PropertyGroupDescription("Commit.Author.Date", new DateTimeToDateConverter()) } + }; + } + + public async Task Load() + { + Commits.AddRange(await ApplicationService.ApiEndpointView.FModelApi.GetGitHubCommitHistoryAsync()); + } +} diff --git a/FModel/Views/Resources/Controls/CommitControl.xaml b/FModel/Views/Resources/Controls/CommitControl.xaml new file mode 100644 index 00000000..97b6b4be --- /dev/null +++ b/FModel/Views/Resources/Controls/CommitControl.xaml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FModel/Views/Resources/Controls/CommitControl.xaml.cs b/FModel/Views/Resources/Controls/CommitControl.xaml.cs new file mode 100644 index 00000000..198c05ae --- /dev/null +++ b/FModel/Views/Resources/Controls/CommitControl.xaml.cs @@ -0,0 +1,12 @@ +using System.Windows.Controls; + +namespace FModel.Views.Resources.Controls; + +public partial class CommitControl : UserControl +{ + public CommitControl() + { + InitializeComponent(); + } +} + diff --git a/FModel/Views/Resources/Converters/CommitMessageConverter.cs b/FModel/Views/Resources/Converters/CommitMessageConverter.cs new file mode 100644 index 00000000..22b32fd3 --- /dev/null +++ b/FModel/Views/Resources/Converters/CommitMessageConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.Globalization; +using System.Windows.Data; + +namespace FModel.Views.Resources.Converters; + +public class CommitMessageConverter : IValueConverter +{ + public static readonly CommitMessageConverter Instance = new(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is string commitMessage) + { + var parts = commitMessage.Split("\n\n"); + return parameter?.ToString() == "Title" ? parts[0] : parts.Length > 1 ? parts[1] : string.Empty; + } + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } +} diff --git a/FModel/Views/Resources/Converters/DateTimeToDateConverter.cs b/FModel/Views/Resources/Converters/DateTimeToDateConverter.cs new file mode 100644 index 00000000..1c5bea71 --- /dev/null +++ b/FModel/Views/Resources/Converters/DateTimeToDateConverter.cs @@ -0,0 +1,24 @@ +using System; +using System.Globalization; +using System.Windows.Data; + +namespace FModel.Views.Resources.Converters; + +public class DateTimeToDateConverter : IValueConverter +{ + public static readonly DateTimeToDateConverter Instance = new(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is DateTime dateTime) + { + return DateOnly.FromDateTime(dateTime); + } + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } +} diff --git a/FModel/Views/Resources/Converters/RelativeDateTimeConverter.cs b/FModel/Views/Resources/Converters/RelativeDateTimeConverter.cs new file mode 100644 index 00000000..818bb4f9 --- /dev/null +++ b/FModel/Views/Resources/Converters/RelativeDateTimeConverter.cs @@ -0,0 +1,62 @@ +using System; +using System.Globalization; +using System.Windows.Data; + +namespace FModel.Views.Resources.Converters; + +public class RelativeDateTimeConverter : IValueConverter +{ + public static readonly RelativeDateTimeConverter Instance = new(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is DateTime dateTime) + { + var timeSpan = DateTime.Now - dateTime; + + int time; + string unit; + if (timeSpan.TotalMinutes < 1) + { + time = timeSpan.Seconds; + unit = "second"; + } + else if (timeSpan.TotalHours < 1) + { + time = timeSpan.Minutes; + unit = "minute"; + } + else switch (timeSpan.TotalDays) + { + case < 1: + time = timeSpan.Hours; + unit = "hour"; + break; + case < 7: + time = timeSpan.Days; + unit = "day"; + break; + case < 30: + time = timeSpan.Days / 7; + unit = "week"; + break; + case < 365: + time = timeSpan.Days / 30; + unit = "month"; + break; + default: + time = timeSpan.Days / 365; + unit = "year"; + break; + } + + return $"{time} {unit}{(time > 1 ? "s" : string.Empty)} ago"; + } + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } +} diff --git a/FModel/Views/Resources/Resources.xaml b/FModel/Views/Resources/Resources.xaml index aa279955..d560ab09 100644 --- a/FModel/Views/Resources/Resources.xaml +++ b/FModel/Views/Resources/Resources.xaml @@ -68,6 +68,7 @@ M12 5.83l2.46 2.46c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L12.7 3.7c-.39-.39-1.02-.39-1.41 0L8.12 6.88c-.39.39-.39 1.02 0 1.41.39.39 1.02.39 1.41 0L12 5.83zm0 12.34l-2.46-2.46c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41l3.17 3.18c.39.39 1.02.39 1.41 0l3.17-3.17c.39-.39.39-1.02 0-1.41-.39-.39-1.02-.39-1.41 0L12 18.17z M11.71,17.99C8.53,17.84,6,15.22,6,12c0-3.31,2.69-6,6-6c3.22,0,5.84,2.53,5.99,5.71l-2.1-0.63C15.48,9.31,13.89,8,12,8 c-2.21,0-4,1.79-4,4c0,1.89,1.31,3.48,3.08,3.89L11.71,17.99z M22,12c0,0.3-0.01,0.6-0.04,0.9l-1.97-0.59C20,12.21,20,12.1,20,12 c0-4.42-3.58-8-8-8s-8,3.58-8,8s3.58,8,8,8c0.1,0,0.21,0,0.31-0.01l0.59,1.97C12.6,21.99,12.3,22,12,22C6.48,22,2,17.52,2,12 C2,6.48,6.48,2,12,2S22,6.48,22,12z M18.23,16.26l2.27-0.76c0.46-0.15,0.45-0.81-0.01-0.95l-7.6-2.28 c-0.38-0.11-0.74,0.24-0.62,0.62l2.28,7.6c0.14,0.47,0.8,0.48,0.95,0.01l0.76-2.27l3.91,3.91c0.2,0.2,0.51,0.2,0.71,0l1.27-1.27 c0.2-0.2,0.2-0.51,0-0.71L18.23,16.26z M1.8 6q-.525 0-.887-.35Q.55 5.3.55 4.8V4q0-1.425 1.012-2.438Q2.575.55 4 .55h.8q.5 0 .85.362.35.363.35.888 0 .5-.35.85T4.8 3H4q-.425 0-.712.287Q3 3.575 3 4v.8q0 .5-.35.85T1.8 6ZM4 23.45q-1.425 0-2.438-1.012Q.55 21.425.55 20v-.8q0-.5.363-.85.362-.35.887-.35.5 0 .85.35t.35.85v.8q0 .425.288.712Q3.575 21 4 21h.8q.5 0 .85.35t.35.85q0 .525-.35.887-.35.363-.85.363Zm15.2 0q-.5 0-.85-.363-.35-.362-.35-.887 0-.5.35-.85t.85-.35h.8q.425 0 .712-.288Q21 20.425 21 20v-.8q0-.5.35-.85t.85-.35q.525 0 .888.35.362.35.362.85v.8q0 1.425-1.012 2.438Q21.425 23.45 20 23.45ZM22.2 6q-.5 0-.85-.35T21 4.8V4q0-.425-.288-.713Q20.425 3 20 3h-.8q-.5 0-.85-.35T18 1.8q0-.525.35-.888.35-.362.85-.362h.8q1.425 0 2.438 1.012Q23.45 2.575 23.45 4v.8q0 .5-.362.85-.363.35-.888.35ZM12 17.35l1-.575v-4.1l3.55-2.075V9.425l-1-.575L12 10.925 8.45 8.85l-1 .575V10.6L11 12.675v4.1Zm-1.325 2.325-4.55-2.65q-.625-.35-.975-.963-.35-.612-.35-1.337V9.45q0-.725.35-1.337.35-.613.975-.963l4.55-2.65Q11.3 4.15 12 4.15t1.325.35l4.55 2.65q.625.35.975.963.35.612.35 1.337v5.275q0 .725-.35 1.337-.35.613-.975.963l-4.55 2.65q-.625.35-1.325.35t-1.325-.35Z + M3.5 1.75v11.5c0 .09.048.173.126.217a.75.75 0 0 1-.752 1.298A1.748 1.748 0 0 1 2 13.25V1.75C2 .784 2.784 0 3.75 0h5.586c.464 0 .909.185 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v8.586A1.75 1.75 0 0 1 12.25 15h-.5a.75.75 0 0 1 0-1.5h.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177L9.513 1.573a.25.25 0 0 0-.177-.073H7.25a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5h-3a.25.25 0 0 0-.25.25Zm3.75 8.75h.5c.966 0 1.75.784 1.75 1.75v3a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1-.75-.75v-3c0-.966.784-1.75 1.75-1.75ZM6 5.25a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 6 5.25Zm.75 2.25h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM8 6.75A.75.75 0 0 1 8.75 6h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 8 6.75ZM8.75 3h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM8 9.75A.75.75 0 0 1 8.75 9h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 8 9.75Zm-1 2.5v2.25h1v-2.25a.25.25 0 0 0-.25-.25h-.5a.25.25 0 0 0-.25.25Z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FModel/Views/UpdateView.xaml.cs b/FModel/Views/UpdateView.xaml.cs new file mode 100644 index 00000000..61d3f290 --- /dev/null +++ b/FModel/Views/UpdateView.xaml.cs @@ -0,0 +1,30 @@ +using System.Diagnostics; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Navigation; +using FModel.Services; +using FModel.ViewModels; + +namespace FModel.Views; + +public partial class UpdateView +{ + public UpdateView() + { + DataContext = new UpdateViewModel(); + InitializeComponent(); + } + + private async void OnLoaded(object sender, RoutedEventArgs e) + { + if (DataContext is not UpdateViewModel viewModel) return; + await viewModel.Load(); + } + + private void OnRequestNavigate(object sender, RequestNavigateEventArgs e) + { + Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true }); + e.Handled = true; + } +} +