From c4922af7417f9cb6bcd7c34f5d17efbb779b76ac Mon Sep 17 00:00:00 2001 From: Elwador <75888166+Elwador@users.noreply.github.com> Date: Fri, 12 Jul 2024 15:53:44 +0200 Subject: [PATCH] Add - Added add date to history series Add - History sorting by add date Add - Sorting by ascending/descending Add - Calendar hide dubs Add - Custom calendar dub filter Chg - Changed the calendar options --- CRD/Downloader/CrEpisode.cs | 52 ++++++---- CRD/Downloader/Crunchyroll.cs | 2 + CRD/Downloader/History.cs | 61 +++++++++--- CRD/Utils/Enums/EnumCollection.cs | 2 + CRD/Utils/Structs/CrDownloadOptions.cs | 9 ++ CRD/Utils/Structs/History/HistorySeries.cs | 3 + CRD/ViewModels/AddDownloadPageViewModel.cs | 2 +- CRD/ViewModels/CalendarPageViewModel.cs | 107 +++++++++++++++++++-- CRD/ViewModels/HistoryPageViewModel.cs | 42 ++++++-- CRD/Views/CalendarPageView.axaml | 92 +++++++++++++++--- CRD/Views/HistoryPageView.axaml | 19 ++-- 11 files changed, 326 insertions(+), 65 deletions(-) diff --git a/CRD/Downloader/CrEpisode.cs b/CRD/Downloader/CrEpisode.cs index 057a150..03e5263 100644 --- a/CRD/Downloader/CrEpisode.cs +++ b/CRD/Downloader/CrEpisode.cs @@ -239,30 +239,46 @@ public class CrEpisode(){ return retMeta; } - public async Task GetNewEpisodes(string? crLocale){ - - NameValueCollection query = HttpUtility.ParseQueryString(new UriBuilder().Query); + public async Task GetNewEpisodes(string? crLocale, int requestAmount){ + CrBrowseEpisodeBase? complete = new CrBrowseEpisodeBase(); + complete.Data =[]; - if (!string.IsNullOrEmpty(crLocale)){ - query["locale"] = crLocale; - } + var i = 0; - query["n"] = "200"; - query["sort_by"] = "newly_added"; - query["type"] = "episode"; + do{ + NameValueCollection query = HttpUtility.ParseQueryString(new UriBuilder().Query); - var request = HttpClientReq.CreateRequestMessage($"{Api.Browse}", HttpMethod.Get, true, false, query); + if (!string.IsNullOrEmpty(crLocale)){ + query["locale"] = crLocale; + } - var response = await HttpClientReq.Instance.SendHttpRequest(request); + query["start"] = i + ""; + query["n"] = "50"; + query["sort_by"] = "newly_added"; + query["type"] = "episode"; - if (!response.IsOk){ - Console.Error.WriteLine("Series Request Failed"); - return null; - } + var request = HttpClientReq.CreateRequestMessage($"{Api.Browse}", HttpMethod.Get, true, false, query); - CrBrowseEpisodeBase? series = Helpers.Deserialize(response.ResponseContent, crunInstance.SettingsJsonSerializerSettings); - + var response = await HttpClientReq.Instance.SendHttpRequest(request); - return series; + if (!response.IsOk){ + Console.Error.WriteLine("Series Request Failed"); + return null; + } + + CrBrowseEpisodeBase? series = Helpers.Deserialize(response.ResponseContent, crunInstance.SettingsJsonSerializerSettings); + + if (series != null){ + complete.Total = series.Total; + if (series.Data != null) complete.Data.AddRange(series.Data); + } else{ + break; + } + + i += 50; + } while (i < requestAmount); + + + return complete; } } \ No newline at end of file diff --git a/CRD/Downloader/Crunchyroll.cs b/CRD/Downloader/Crunchyroll.cs index 1546aa5..0db5654 100644 --- a/CRD/Downloader/Crunchyroll.cs +++ b/CRD/Downloader/Crunchyroll.cs @@ -159,10 +159,12 @@ public class Crunchyroll{ CrunOptions.AccentColor = Colors.SlateBlue.ToString(); CrunOptions.Theme = "System"; CrunOptions.SelectedCalendarLanguage = "default"; + CrunOptions.CalendarDubFilter = "none"; CrunOptions.DlVideoOnce = true; CrunOptions.StreamEndpoint = "web/firefox"; CrunOptions.SubsAddScaledBorder = ScaledBorderAndShadowSelection.ScaledBorderAndShadowYes; CrunOptions.HistoryLang = ""; + CrunOptions.History = true; diff --git a/CRD/Downloader/History.cs b/CRD/Downloader/History.cs index 4cc5871..e39ac88 100644 --- a/CRD/Downloader/History.cs +++ b/CRD/Downloader/History.cs @@ -151,6 +151,8 @@ public class History(){ var seriesId = episode.SeriesId; var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId); if (historySeries != null){ + historySeries.HistorySeriesAddDate ??= DateTime.Now; + var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == episode.SeasonId); await RefreshSeriesData(seriesId, historySeries); @@ -184,6 +186,7 @@ public class History(){ SeriesTitle = episode.SeriesTitle, SeriesId = episode.SeriesId, Seasons =[], + HistorySeriesAddDate = DateTime.Now, }; crunInstance.HistoryList.Add(historySeries); var newSeason = NewHistorySeason(episode); @@ -208,6 +211,8 @@ public class History(){ var seriesId = firstEpisode.SeriesId; var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId); if (historySeries != null){ + historySeries.HistorySeriesAddDate ??= DateTime.Now; + var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == firstEpisode.SeasonId); await RefreshSeriesData(seriesId, historySeries); @@ -255,6 +260,7 @@ public class History(){ SeriesTitle = firstEpisode.SeriesTitle, SeriesId = firstEpisode.SeriesId, Seasons =[], + HistorySeriesAddDate = DateTime.Now, }; crunInstance.HistoryList.Add(historySeries); @@ -307,9 +313,13 @@ public class History(){ public void SortItems(){ var currentSortingType = Crunchyroll.Instance.CrunOptions.HistoryPageProperties?.SelectedSorting ?? SortingType.SeriesTitle; + var sortingDir = Crunchyroll.Instance.CrunOptions.HistoryPageProperties != null && Crunchyroll.Instance.CrunOptions.HistoryPageProperties.Ascending; + DateTime today = DateTime.UtcNow.Date; switch (currentSortingType){ case SortingType.SeriesTitle: - var sortedList = Crunchyroll.Instance.HistoryList.OrderBy(s => s.SeriesTitle).ToList(); + var sortedList = sortingDir + ? Crunchyroll.Instance.HistoryList.OrderByDescending(s => s.SeriesTitle).ToList() + : Crunchyroll.Instance.HistoryList.OrderBy(s => s.SeriesTitle).ToList(); Crunchyroll.Instance.HistoryList.Clear(); @@ -320,23 +330,47 @@ public class History(){ case SortingType.NextAirDate: - DateTime today = DateTime.UtcNow.Date; - - var sortedSeriesDates = Crunchyroll.Instance.HistoryList - .OrderByDescending(s => s.SonarrNextAirDate == "Today") - .ThenBy(s => s.SonarrNextAirDate == "Today" ? s.SeriesTitle : null) - .ThenBy(s => { - var date = ParseDate(s.SonarrNextAirDate, today); - return date.HasValue ? date.Value : DateTime.MaxValue; - }) - .ThenBy(s => s.SeriesTitle) - .ToList(); + var sortedSeriesDates = sortingDir + ? Crunchyroll.Instance.HistoryList + .OrderByDescending(s => { + var date = ParseDate(s.SonarrNextAirDate, today); + return date.HasValue ? date.Value : DateTime.MinValue; + }) + .ThenByDescending(s => s.SonarrNextAirDate == "Today" ? 1 : 0) + .ThenBy(s => string.IsNullOrEmpty(s.SonarrNextAirDate) ? 1 : 0) + .ThenBy(s => s.SeriesTitle) + .ToList() + : Crunchyroll.Instance.HistoryList + .OrderByDescending(s => s.SonarrNextAirDate == "Today") + .ThenBy(s => s.SonarrNextAirDate == "Today" ? s.SeriesTitle : null) + .ThenBy(s => { + var date = ParseDate(s.SonarrNextAirDate, today); + return date.HasValue ? date.Value : DateTime.MaxValue; + }) + .ThenBy(s => s.SeriesTitle) + .ToList(); Crunchyroll.Instance.HistoryList.Clear(); Crunchyroll.Instance.HistoryList.AddRange(sortedSeriesDates); + return; + + case SortingType.HistorySeriesAddDate: + + var sortedSeriesAddDates = Crunchyroll.Instance.HistoryList + .OrderBy(s => sortingDir + ? -(s.HistorySeriesAddDate?.Date.Ticks ?? DateTime.MinValue.Ticks) + : s.HistorySeriesAddDate?.Date.Ticks ?? DateTime.MaxValue.Ticks) + .ThenBy(s => s.SeriesTitle) + .ToList(); + + + Crunchyroll.Instance.HistoryList.Clear(); + + Crunchyroll.Instance.HistoryList.AddRange(sortedSeriesAddDates); + return; } } @@ -353,6 +387,8 @@ public class History(){ return null; } + + private string GetSeriesThumbnail(CrSeriesBase series){ // var series = await crunInstance.CrSeries.SeriesById(seriesId); @@ -496,6 +532,7 @@ public class History(){ if (ele == null){ return false; } + return !string.IsNullOrEmpty(historyEpisode.EpisodeDescription) && !string.IsNullOrEmpty(ele.Overview) && Helpers.CalculateCosineSimilarity(ele.Overview, historyEpisode.EpisodeDescription) > 0.8; }); diff --git a/CRD/Utils/Enums/EnumCollection.cs b/CRD/Utils/Enums/EnumCollection.cs index ef01b85..36c7c23 100644 --- a/CRD/Utils/Enums/EnumCollection.cs +++ b/CRD/Utils/Enums/EnumCollection.cs @@ -184,6 +184,8 @@ public enum SortingType{ SeriesTitle, [EnumMember(Value = "Next Air Date")] NextAirDate, + [EnumMember(Value = "History Series Add Date")] + HistorySeriesAddDate, } public enum SonarrCoverType{ diff --git a/CRD/Utils/Structs/CrDownloadOptions.cs b/CRD/Utils/Structs/CrDownloadOptions.cs index 0b3cc59..02119a6 100644 --- a/CRD/Utils/Structs/CrDownloadOptions.cs +++ b/CRD/Utils/Structs/CrDownloadOptions.cs @@ -131,6 +131,15 @@ public class CrDownloadOptions{ [YamlMember(Alias = "calendar_language", ApplyNamingConventions = false)] public string? SelectedCalendarLanguage{ get; set; } + + [YamlMember(Alias = "calendar_dub_filter", ApplyNamingConventions = false)] + public string? CalendarDubFilter{ get; set; } + + [YamlMember(Alias = "calendar_custom", ApplyNamingConventions = false)] + public bool CustomCalendar{ get; set; } + + [YamlMember(Alias = "calendar_hide_dubs", ApplyNamingConventions = false)] + public bool CalendarHideDubs{ get; set; } [YamlMember(Alias = "history", ApplyNamingConventions = false)] public bool History{ get; set; } diff --git a/CRD/Utils/Structs/History/HistorySeries.cs b/CRD/Utils/Structs/History/HistorySeries.cs index cab8543..ffaf00a 100644 --- a/CRD/Utils/Structs/History/HistorySeries.cs +++ b/CRD/Utils/Structs/History/HistorySeries.cs @@ -49,6 +49,9 @@ public class HistorySeries : INotifyPropertyChanged{ [JsonProperty("series_download_path")] public string? SeriesDownloadPath{ get; set; } + [JsonProperty("history_series_add_date")] + public DateTime? HistorySeriesAddDate{ get; set; } + public event PropertyChangedEventHandler? PropertyChanged; [JsonIgnore] diff --git a/CRD/ViewModels/AddDownloadPageViewModel.cs b/CRD/ViewModels/AddDownloadPageViewModel.cs index d8c5aba..8e86735 100644 --- a/CRD/ViewModels/AddDownloadPageViewModel.cs +++ b/CRD/ViewModels/AddDownloadPageViewModel.cs @@ -75,7 +75,7 @@ public partial class AddDownloadPageViewModel : ViewModelBase{ } private async Task UpdateSearch(string value){ - var searchResults = await Crunchyroll.Instance.CrSeries.Search(value, ""); + var searchResults = await Crunchyroll.Instance.CrSeries.Search(value, Crunchyroll.Instance.CrunOptions.HistoryLang); var searchItems = searchResults?.Data?.First().Items; SearchItems.Clear(); diff --git a/CRD/ViewModels/CalendarPageViewModel.cs b/CRD/ViewModels/CalendarPageViewModel.cs index 5079f97..f7b1fee 100644 --- a/CRD/ViewModels/CalendarPageViewModel.cs +++ b/CRD/ViewModels/CalendarPageViewModel.cs @@ -15,15 +15,24 @@ namespace CRD.ViewModels; public partial class CalendarPageViewModel : ViewModelBase{ public ObservableCollection CalendarDays{ get; set; } - [ObservableProperty] - private ComboBoxItem? _currentCalendarLanguage; + [ObservableProperty] - private bool _showLoading = false; + private bool _showLoading; [ObservableProperty] - private bool _customCalendar = false; + private bool _customCalendar; + + [ObservableProperty] + private bool _hideDubs; + public ObservableCollection CalendarDubFilter{ get; } = new(){ + new ComboBoxItem(){ Content = "none" }, + }; + + [ObservableProperty] + private ComboBoxItem? _currentCalendarDubFilter; + public ObservableCollection CalendarLanguage{ get; } = new(){ new ComboBoxItem(){ Content = "en-us" }, new ComboBoxItem(){ Content = "es" }, @@ -37,13 +46,30 @@ public partial class CalendarPageViewModel : ViewModelBase{ new ComboBoxItem(){ Content = "ru" }, new ComboBoxItem(){ Content = "hi" }, }; + + [ObservableProperty] + private ComboBoxItem? _currentCalendarLanguage; private CalendarWeek? currentWeek; + private bool loading = true; + public CalendarPageViewModel(){ CalendarDays = new ObservableCollection(); + + foreach (var languageItem in Languages.languages){ + CalendarDubFilter.Add(new ComboBoxItem{ Content = languageItem.CrLocale }); + } + + CustomCalendar = Crunchyroll.Instance.CrunOptions.CustomCalendar; + HideDubs = Crunchyroll.Instance.CrunOptions.CalendarHideDubs; + + ComboBoxItem? dubfilter = CalendarDubFilter.FirstOrDefault(a => a.Content != null && (string)a.Content == Crunchyroll.Instance.CrunOptions.CalendarDubFilter) ?? null; + CurrentCalendarDubFilter = dubfilter ?? CalendarDubFilter[0]; + CurrentCalendarLanguage = CalendarLanguage.FirstOrDefault(a => a.Content != null && (string)a.Content == Crunchyroll.Instance.CrunOptions.SelectedCalendarLanguage) ?? CalendarLanguage[0]; - // LoadCalendar(GetThisWeeksMondayDate(), false); + loading = false; + LoadCalendar(GetThisWeeksMondayDate(), false); } private string GetThisWeeksMondayDate(){ @@ -69,6 +95,12 @@ public partial class CalendarPageViewModel : ViewModelBase{ } public async void LoadCalendar(string mondayDate, bool forceUpdate){ + + if (CustomCalendar){ + BuildCustomCalendar(); + return; + } + ShowLoading = true; CalendarWeek week = await Crunchyroll.Instance.GetCalendarForDate(mondayDate, forceUpdate); if (currentWeek != null && currentWeek == week){ @@ -81,8 +113,14 @@ public partial class CalendarPageViewModel : ViewModelBase{ CalendarDays.AddRange(week.CalendarDays); RaisePropertyChanged(nameof(CalendarDays)); ShowLoading = false; + foreach (var calendarDay in CalendarDays){ - foreach (var calendarDayCalendarEpisode in calendarDay.CalendarEpisodes){ + var episodesCopy = new List(calendarDay.CalendarEpisodes); + foreach (var calendarDayCalendarEpisode in episodesCopy){ + if (calendarDayCalendarEpisode.SeasonName != null && HideDubs && calendarDayCalendarEpisode.SeasonName.EndsWith("Dub)")){ + calendarDay.CalendarEpisodes.Remove(calendarDayCalendarEpisode); + continue; + } if (calendarDayCalendarEpisode.ImageBitmap == null){ calendarDayCalendarEpisode.LoadImage(); } @@ -104,6 +142,10 @@ public partial class CalendarPageViewModel : ViewModelBase{ [RelayCommand] public void Refresh(){ + if (loading){ + return; + } + if (CustomCalendar){ BuildCustomCalendar(); return; @@ -122,6 +164,10 @@ public partial class CalendarPageViewModel : ViewModelBase{ [RelayCommand] public void PrevWeek(){ + if (loading){ + return; + } + string mondayDate; if (currentWeek is{ FirstDayOfWeek: not null }){ @@ -135,6 +181,10 @@ public partial class CalendarPageViewModel : ViewModelBase{ [RelayCommand] public void NextWeek(){ + if (loading){ + return; + } + string mondayDate; if (currentWeek is{ FirstDayOfWeek: not null }){ @@ -148,6 +198,10 @@ public partial class CalendarPageViewModel : ViewModelBase{ partial void OnCurrentCalendarLanguageChanged(ComboBoxItem? value){ + if (loading){ + return; + } + if (value?.Content != null){ Crunchyroll.Instance.CrunOptions.SelectedCalendarLanguage = value.Content.ToString(); Refresh(); @@ -156,15 +210,45 @@ public partial class CalendarPageViewModel : ViewModelBase{ } partial void OnCustomCalendarChanged(bool value){ + if (loading){ + return; + } + if (CustomCalendar){ BuildCustomCalendar(); + } else{ + LoadCalendar(GetThisWeeksMondayDate(), true); } + + Crunchyroll.Instance.CrunOptions.CustomCalendar = value; + CfgManager.WriteSettingsToFile(); + } + + partial void OnHideDubsChanged(bool value){ + if (loading){ + return; + } + + Crunchyroll.Instance.CrunOptions.CalendarHideDubs = value; + CfgManager.WriteSettingsToFile(); + } + + partial void OnCurrentCalendarDubFilterChanged(ComboBoxItem? value){ + if (loading){ + return; + } + + if (!string.IsNullOrEmpty(value?.Content + "")){ + Crunchyroll.Instance.CrunOptions.CalendarDubFilter = value?.Content + ""; + CfgManager.WriteSettingsToFile(); + } + } private async void BuildCustomCalendar(){ ShowLoading = true; - var newEpisodesBase = await Crunchyroll.Instance.CrEpisode.GetNewEpisodes(Crunchyroll.Instance.CrunOptions.HistoryLang); + var newEpisodesBase = await Crunchyroll.Instance.CrEpisode.GetNewEpisodes(Crunchyroll.Instance.CrunOptions.HistoryLang,200); CalendarWeek week = new CalendarWeek(); week.CalendarDays = new List(); @@ -189,10 +273,17 @@ public partial class CalendarPageViewModel : ViewModelBase{ foreach (var crBrowseEpisode in newEpisodes){ var episodeAirDate = crBrowseEpisode.EpisodeMetadata.EpisodeAirDate; - if (crBrowseEpisode.EpisodeMetadata.SeasonTitle != null && crBrowseEpisode.EpisodeMetadata.SeasonTitle.EndsWith("Dub)")){ + if (HideDubs && crBrowseEpisode.EpisodeMetadata.SeasonTitle != null && crBrowseEpisode.EpisodeMetadata.SeasonTitle.EndsWith("Dub)")){ continue; } + var dubFilter = CurrentCalendarDubFilter?.Content + ""; + if (!string.IsNullOrEmpty(dubFilter) && dubFilter != "none"){ + if (crBrowseEpisode.EpisodeMetadata.AudioLocale != null && crBrowseEpisode.EpisodeMetadata.AudioLocale.GetEnumMemberValue() != dubFilter){ + continue; + } + } + var calendarDay = week.CalendarDays.FirstOrDefault(day => day.DateTime != null && day.DateTime.Value.Date == episodeAirDate.Date); if (calendarDay != null){ diff --git a/CRD/ViewModels/HistoryPageViewModel.cs b/CRD/ViewModels/HistoryPageViewModel.cs index f3be215..82cc0b3 100644 --- a/CRD/ViewModels/HistoryPageViewModel.cs +++ b/CRD/ViewModels/HistoryPageViewModel.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Avalonia; using Avalonia.Controls; using Avalonia.Platform.Storage; +using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using CRD.Downloader; @@ -41,9 +42,9 @@ public partial class HistoryPageViewModel : ViewModelBase{ public ObservableCollection ViewsList{ get; } =[]; [ObservableProperty] - public ComboBoxItem _selectedSorting; + public SortingListElement _selectedSorting; - public ObservableCollection SortingList{ get; } =[]; + public ObservableCollection SortingList{ get; } =[]; [ObservableProperty] public double _posterWidth; @@ -81,6 +82,9 @@ public partial class HistoryPageViewModel : ViewModelBase{ private SortingType currentSortingType = SortingType.NextAirDate; + [ObservableProperty] + public static bool _sortDir = false; + public HistoryPageViewModel(){ Items = Crunchyroll.Instance.HistoryList; @@ -89,6 +93,7 @@ public partial class HistoryPageViewModel : ViewModelBase{ currentViewType = properties?.SelectedView ?? HistoryViewType.Posters; currentSortingType = properties?.SelectedSorting ?? SortingType.SeriesTitle; ScaleValue = properties?.ScaleValue ?? 0.73; + SortDir = properties?.Ascending ?? false; foreach (HistoryViewType viewType in Enum.GetValues(typeof(HistoryViewType))){ var combobox = new ComboBoxItem{ Content = viewType }; @@ -99,7 +104,7 @@ public partial class HistoryPageViewModel : ViewModelBase{ } foreach (SortingType sortingType in Enum.GetValues(typeof(SortingType))){ - var combobox = new ComboBoxItem{ Content = sortingType.GetEnumMemberValue() }; + var combobox = new SortingListElement(){ SortingTitle = sortingType.GetEnumMemberValue(), SelectedSorting = sortingType }; SortingList.Add(combobox); if (sortingType == currentSortingType){ SelectedSorting = combobox; @@ -147,9 +152,23 @@ public partial class HistoryPageViewModel : ViewModelBase{ UpdateSettings(); } - partial void OnSelectedSortingChanged(ComboBoxItem value){ - if (TryParseEnum(value.Content + "", out var sortingType)){ - currentSortingType = sortingType; + + partial void OnSelectedSortingChanged(SortingListElement? oldValue, SortingListElement? newValue){ + if (newValue == null){ + if (Crunchyroll.Instance.CrunOptions.HistoryPageProperties != null){ + Crunchyroll.Instance.CrunOptions.HistoryPageProperties.Ascending = !Crunchyroll.Instance.CrunOptions.HistoryPageProperties.Ascending; + SortDir = Crunchyroll.Instance.CrunOptions.HistoryPageProperties.Ascending; + } + + Dispatcher.UIThread.InvokeAsync(() => { + SelectedSorting = oldValue ?? SortingList.First(); + RaisePropertyChanged(nameof(SelectedSorting)); + }); + return; + } + + if (newValue.SelectedSorting != null){ + currentSortingType = newValue.SelectedSorting; if (Crunchyroll.Instance.CrunOptions.HistoryPageProperties != null) Crunchyroll.Instance.CrunOptions.HistoryPageProperties.SelectedSorting = currentSortingType; Crunchyroll.Instance.CrHistory.SortItems(); } else{ @@ -195,13 +214,13 @@ public partial class HistoryPageViewModel : ViewModelBase{ Crunchyroll.Instance.SelectedSeries = value; NavToSeries(); - + if (!string.IsNullOrEmpty(value.SonarrSeriesId) && Crunchyroll.Instance.CrunOptions.SonarrProperties is{ SonarrEnabled: true }){ Crunchyroll.Instance.CrHistory.MatchHistoryEpisodesWithSonarr(true, SelectedSeries); CfgManager.WriteJsonToFile(CfgManager.PathCrHistory, Crunchyroll.Instance.HistoryList); } - + _selectedSeries = null; } @@ -313,4 +332,11 @@ public class HistoryPageProperties(){ public SortingType? SelectedSorting{ get; set; } public HistoryViewType SelectedView{ get; set; } public double? ScaleValue{ get; set; } + + public bool Ascending{ get; set; } +} + +public class SortingListElement(){ + public SortingType SelectedSorting{ get; set; } + public string? SortingTitle{ get; set; } } \ No newline at end of file diff --git a/CRD/Views/CalendarPageView.axaml b/CRD/Views/CalendarPageView.axaml index 50df0a9..e1fe8f4 100644 --- a/CRD/Views/CalendarPageView.axaml +++ b/CRD/Views/CalendarPageView.axaml @@ -13,7 +13,7 @@ - + @@ -36,18 +36,86 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -65,7 +133,7 @@ - + @@ -94,7 +162,7 @@ - + @@ -147,7 +215,7 @@ - + diff --git a/CRD/Views/HistoryPageView.axaml b/CRD/Views/HistoryPageView.axaml index ee75fd3..a95a20d 100644 --- a/CRD/Views/HistoryPageView.axaml +++ b/CRD/Views/HistoryPageView.axaml @@ -114,14 +114,23 @@ Placement="BottomEdgeAlignedRight" PlacementTarget="{Binding ElementName=DropdownButtonSorting}"> - + + + + + + + + + - +