diff --git a/CRD/Downloader/CrEpisode.cs b/CRD/Downloader/CrEpisode.cs index 8e02bac..5e6d19f 100644 --- a/CRD/Downloader/CrEpisode.cs +++ b/CRD/Downloader/CrEpisode.cs @@ -59,14 +59,14 @@ public class CrEpisode(){ } - public async Task EpisodeData(CrunchyEpisode dlEpisode){ + public async Task EpisodeData(CrunchyEpisode dlEpisode,bool updateHistory = false){ bool serieshasversions = true; // Dictionary episodes = new Dictionary(); CrunchyRollEpisodeData episode = new CrunchyRollEpisodeData(); - if (crunInstance.CrunOptions.History){ + if (crunInstance.CrunOptions.History && updateHistory){ await crunInstance.CrHistory.UpdateWithEpisode(dlEpisode); } diff --git a/CRD/Downloader/Crunchyroll.cs b/CRD/Downloader/Crunchyroll.cs index 1d75c7e..54a21f7 100644 --- a/CRD/Downloader/Crunchyroll.cs +++ b/CRD/Downloader/Crunchyroll.cs @@ -322,7 +322,7 @@ public class Crunchyroll{ return week; } - public async Task AddEpisodeToQue(string epId, string crLocale, List dubLang){ + public async Task AddEpisodeToQue(string epId, string crLocale, List dubLang, bool updateHistory = false){ await CrAuth.RefreshToken(true); var episodeL = await CrEpisode.ParseEpisodeById(epId, crLocale); @@ -334,7 +334,7 @@ public class Crunchyroll{ return; } - var sList = await CrEpisode.EpisodeData((CrunchyEpisode)episodeL); + var sList = await CrEpisode.EpisodeData((CrunchyEpisode)episodeL,updateHistory); var selected = CrEpisode.EpisodeMeta(sList, dubLang); if (CrunOptions.IncludeVideoDescription){ @@ -352,21 +352,21 @@ public class Crunchyroll{ if (!string.IsNullOrEmpty(historyEpisode.historyEpisode.SonarrEpisodeNumber)){ selected.EpisodeNumber = historyEpisode.historyEpisode.SonarrEpisodeNumber; } - + if (!string.IsNullOrEmpty(historyEpisode.historyEpisode.SonarrSeasonNumber)){ selected.Season = historyEpisode.historyEpisode.SonarrSeasonNumber; } } } - + if (!string.IsNullOrEmpty(historyEpisode.downloadDirPath)){ selected.DownloadPath = historyEpisode.downloadDirPath; } } - + Queue.Add(selected); - - + + if (selected.Data.Count < dubLang.Count){ Console.WriteLine("Added Episode to Queue but couldn't find all selected dubs"); MessageBus.Current.SendMessage(new ToastMessage($"Added episode to the queue but couldn't find all selected dubs", ToastType.Warning, 2)); diff --git a/CRD/Downloader/History.cs b/CRD/Downloader/History.cs index f49e3f0..ae993cc 100644 --- a/CRD/Downloader/History.cs +++ b/CRD/Downloader/History.cs @@ -450,7 +450,8 @@ public class History(){ List failedEpisodes =[]; - foreach (var historyEpisode in allHistoryEpisodes){ + Parallel.ForEach(allHistoryEpisodes, historyEpisode => + { if (updateAll || string.IsNullOrEmpty(historyEpisode.SonarrEpisodeId)){ var episode = FindClosestMatchEpisodes(episodes, historyEpisode.EpisodeTitle); if (episode != null){ @@ -464,9 +465,10 @@ public class History(){ failedEpisodes.Add(historyEpisode); } } - } + }); - foreach (var historyEpisode in failedEpisodes){ + Parallel.ForEach(failedEpisodes, historyEpisode => + { var episode = episodes.Find(ele => ele.EpisodeNumber + "" == historyEpisode.Episode && ele.SeasonNumber + "" == historyEpisode.EpisodeSeasonNum); if (episode != null){ historyEpisode.SonarrEpisodeId = episode.Id + ""; @@ -500,7 +502,7 @@ public class History(){ } } } - } + }); } } diff --git a/CRD/Styling/ControlsGalleryStyles.axaml b/CRD/Styling/ControlsGalleryStyles.axaml new file mode 100644 index 0000000..50cb62c --- /dev/null +++ b/CRD/Styling/ControlsGalleryStyles.axaml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CRD/Utils/Structs/CalendarStructs.cs b/CRD/Utils/Structs/CalendarStructs.cs index 8180129..7444790 100644 --- a/CRD/Utils/Structs/CalendarStructs.cs +++ b/CRD/Utils/Structs/CalendarStructs.cs @@ -47,7 +47,7 @@ public partial class CalendarEpisode : INotifyPropertyChanged{ if (match.Success){ var locale = match.Groups[1].Value; // Capture the locale part var id = match.Groups[2].Value; // Capture the ID part - Crunchyroll.Instance.AddEpisodeToQue(id, Languages.Locale2language(locale).CrLocale, Crunchyroll.Instance.CrunOptions.DubLang); + Crunchyroll.Instance.AddEpisodeToQue(id, Languages.Locale2language(locale).CrLocale, Crunchyroll.Instance.CrunOptions.DubLang,true); } } diff --git a/CRD/Utils/Structs/History/HistoryEpisode.cs b/CRD/Utils/Structs/History/HistoryEpisode.cs index 4daf690..8c752f7 100644 --- a/CRD/Utils/Structs/History/HistoryEpisode.cs +++ b/CRD/Utils/Structs/History/HistoryEpisode.cs @@ -48,6 +48,21 @@ public class HistoryEpisode : INotifyPropertyChanged{ WasDownloaded = !WasDownloaded; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(WasDownloaded))); } + + public void ToggleWasDownloadedSeries(HistorySeries? series){ + WasDownloaded = !WasDownloaded; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(WasDownloaded))); + + if (series?.Seasons != null){ + foreach (var historySeason in series.Seasons){ + historySeason.UpdateDownloadedSilent(); + } + series.UpdateNewEpisodes(); + } + + + CfgManager.WriteJsonToFile(CfgManager.PathCrHistory, Crunchyroll.Instance.HistoryList); + } public async Task DownloadEpisode(){ await Crunchyroll.Instance.AddEpisodeToQue(EpisodeId, Crunchyroll.Instance.DefaultLocale, Crunchyroll.Instance.CrunOptions.DubLang); diff --git a/CRD/Utils/Structs/History/HistorySeason.cs b/CRD/Utils/Structs/History/HistorySeason.cs index 1907513..ce13038 100644 --- a/CRD/Utils/Structs/History/HistorySeason.cs +++ b/CRD/Utils/Structs/History/HistorySeason.cs @@ -48,4 +48,15 @@ public class HistorySeason : INotifyPropertyChanged{ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DownloadedEpisodes))); CfgManager.WriteJsonToFile(CfgManager.PathCrHistory, Crunchyroll.Instance.HistoryList); } -} \ No newline at end of file + + public void UpdateDownloadedSilent(){ + DownloadedEpisodes = EpisodesList.FindAll(e => e.WasDownloaded).Count; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DownloadedEpisodes))); + } + +} + +public class UpdateDownloadedHistorySeason{ + public string? EpisodeId; + public HistorySeries? HistorySeries; +} diff --git a/CRD/Utils/UI/UiUpdateDownloadedHistorySeasonConverter.cs b/CRD/Utils/UI/UiUpdateDownloadedHistorySeasonConverter.cs new file mode 100644 index 0000000..11a7df6 --- /dev/null +++ b/CRD/Utils/UI/UiUpdateDownloadedHistorySeasonConverter.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using Avalonia.Data.Converters; +using CRD.Utils.Structs.History; + +namespace CRD.Utils.UI; + +public class UiUpdateDownloadedHistorySeasonConverter : IMultiValueConverter{ + + public object? Convert(IList values, Type targetType, object? parameter, CultureInfo culture){ + + if (values[0] is string stringValue1){ + Console.WriteLine(stringValue1); + } + + if (values is[string stringValue, HistorySeries historySeries]){ + + return new UpdateDownloadedHistorySeason{ + EpisodeId = stringValue, + HistorySeries = historySeries + }; + } + + return new UpdateDownloadedHistorySeason{ + EpisodeId = "", + HistorySeries = null + }; + } + +} \ No newline at end of file diff --git a/CRD/ViewModels/AddDownloadPageViewModel.cs b/CRD/ViewModels/AddDownloadPageViewModel.cs index 2771f65..d60c47a 100644 --- a/CRD/ViewModels/AddDownloadPageViewModel.cs +++ b/CRD/ViewModels/AddDownloadPageViewModel.cs @@ -119,7 +119,7 @@ public partial class AddDownloadPageViewModel : ViewModelBase{ if (match.Success){ var locale = match.Groups[1].Value; // Capture the locale part var id = match.Groups[2].Value; // Capture the ID part - Crunchyroll.Instance.AddEpisodeToQue(id, Languages.Locale2language(locale).CrLocale, Crunchyroll.Instance.CrunOptions.DubLang); + Crunchyroll.Instance.AddEpisodeToQue(id, Languages.Locale2language(locale).CrLocale, Crunchyroll.Instance.CrunOptions.DubLang,true); UrlInput = ""; selectedEpisodes.Clear(); SelectedItems.Clear(); diff --git a/CRD/ViewModels/HistoryPageViewModel.cs b/CRD/ViewModels/HistoryPageViewModel.cs index 4579554..ca1674c 100644 --- a/CRD/ViewModels/HistoryPageViewModel.cs +++ b/CRD/ViewModels/HistoryPageViewModel.cs @@ -193,12 +193,14 @@ public partial class HistoryPageViewModel : ViewModelBase{ partial void OnSelectedSeriesChanged(HistorySeries value){ 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); } - NavToSeries(); + _selectedSeries = null; } diff --git a/CRD/Views/HistoryPageView.axaml b/CRD/Views/HistoryPageView.axaml index e13f4df..a22265f 100644 --- a/CRD/Views/HistoryPageView.axaml +++ b/CRD/Views/HistoryPageView.axaml @@ -13,6 +13,7 @@ + @@ -422,8 +423,8 @@ Margin="0 0 10 0" Background="Transparent" BorderThickness="0" CornerRadius="50" IsVisible="{Binding !WasDownloaded}" - Command="{Binding $parent[controls:SettingsExpander].((history:HistorySeason)DataContext).UpdateDownloaded}" - CommandParameter="{Binding EpisodeId}"> + Command="{Binding ToggleWasDownloadedSeries}" + CommandParameter="{Binding $parent[ScrollViewer].((history:HistorySeries)DataContext)}"> @@ -436,8 +437,8 @@ Margin="0 0 10 0" Background="Transparent" BorderThickness="0" CornerRadius="50" IsVisible="{Binding WasDownloaded}" - Command="{Binding $parent[controls:SettingsExpander].((history:HistorySeason)DataContext).UpdateDownloaded}" - CommandParameter="{Binding EpisodeId}"> + Command="{Binding ToggleWasDownloadedSeries}" + CommandParameter="{Binding $parent[ScrollViewer].((history:HistorySeries)DataContext)}">