Fix - Hisory table new episodes not updating correctly

Fix - History table view collapses when adding an episode
This commit is contained in:
Elwador 2024-06-28 05:28:45 +02:00
parent d2516d039b
commit 51a436e320
11 changed files with 189 additions and 21 deletions

View File

@ -59,14 +59,14 @@ public class CrEpisode(){
} }
public async Task<CrunchyRollEpisodeData> EpisodeData(CrunchyEpisode dlEpisode){ public async Task<CrunchyRollEpisodeData> EpisodeData(CrunchyEpisode dlEpisode,bool updateHistory = false){
bool serieshasversions = true; bool serieshasversions = true;
// Dictionary<string, EpisodeAndLanguage> episodes = new Dictionary<string, EpisodeAndLanguage>(); // Dictionary<string, EpisodeAndLanguage> episodes = new Dictionary<string, EpisodeAndLanguage>();
CrunchyRollEpisodeData episode = new CrunchyRollEpisodeData(); CrunchyRollEpisodeData episode = new CrunchyRollEpisodeData();
if (crunInstance.CrunOptions.History){ if (crunInstance.CrunOptions.History && updateHistory){
await crunInstance.CrHistory.UpdateWithEpisode(dlEpisode); await crunInstance.CrHistory.UpdateWithEpisode(dlEpisode);
} }

View File

@ -322,7 +322,7 @@ public class Crunchyroll{
return week; return week;
} }
public async Task AddEpisodeToQue(string epId, string crLocale, List<string> dubLang){ public async Task AddEpisodeToQue(string epId, string crLocale, List<string> dubLang, bool updateHistory = false){
await CrAuth.RefreshToken(true); await CrAuth.RefreshToken(true);
var episodeL = await CrEpisode.ParseEpisodeById(epId, crLocale); var episodeL = await CrEpisode.ParseEpisodeById(epId, crLocale);
@ -334,7 +334,7 @@ public class Crunchyroll{
return; return;
} }
var sList = await CrEpisode.EpisodeData((CrunchyEpisode)episodeL); var sList = await CrEpisode.EpisodeData((CrunchyEpisode)episodeL,updateHistory);
var selected = CrEpisode.EpisodeMeta(sList, dubLang); var selected = CrEpisode.EpisodeMeta(sList, dubLang);
if (CrunOptions.IncludeVideoDescription){ if (CrunOptions.IncludeVideoDescription){
@ -352,21 +352,21 @@ public class Crunchyroll{
if (!string.IsNullOrEmpty(historyEpisode.historyEpisode.SonarrEpisodeNumber)){ if (!string.IsNullOrEmpty(historyEpisode.historyEpisode.SonarrEpisodeNumber)){
selected.EpisodeNumber = historyEpisode.historyEpisode.SonarrEpisodeNumber; selected.EpisodeNumber = historyEpisode.historyEpisode.SonarrEpisodeNumber;
} }
if (!string.IsNullOrEmpty(historyEpisode.historyEpisode.SonarrSeasonNumber)){ if (!string.IsNullOrEmpty(historyEpisode.historyEpisode.SonarrSeasonNumber)){
selected.Season = historyEpisode.historyEpisode.SonarrSeasonNumber; selected.Season = historyEpisode.historyEpisode.SonarrSeasonNumber;
} }
} }
} }
if (!string.IsNullOrEmpty(historyEpisode.downloadDirPath)){ if (!string.IsNullOrEmpty(historyEpisode.downloadDirPath)){
selected.DownloadPath = historyEpisode.downloadDirPath; selected.DownloadPath = historyEpisode.downloadDirPath;
} }
} }
Queue.Add(selected); Queue.Add(selected);
if (selected.Data.Count < dubLang.Count){ if (selected.Data.Count < dubLang.Count){
Console.WriteLine("Added Episode to Queue but couldn't find all selected dubs"); 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)); MessageBus.Current.SendMessage(new ToastMessage($"Added episode to the queue but couldn't find all selected dubs", ToastType.Warning, 2));

View File

@ -450,7 +450,8 @@ public class History(){
List<HistoryEpisode> failedEpisodes =[]; List<HistoryEpisode> failedEpisodes =[];
foreach (var historyEpisode in allHistoryEpisodes){ Parallel.ForEach(allHistoryEpisodes, historyEpisode =>
{
if (updateAll || string.IsNullOrEmpty(historyEpisode.SonarrEpisodeId)){ if (updateAll || string.IsNullOrEmpty(historyEpisode.SonarrEpisodeId)){
var episode = FindClosestMatchEpisodes(episodes, historyEpisode.EpisodeTitle); var episode = FindClosestMatchEpisodes(episodes, historyEpisode.EpisodeTitle);
if (episode != null){ if (episode != null){
@ -464,9 +465,10 @@ public class History(){
failedEpisodes.Add(historyEpisode); 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); var episode = episodes.Find(ele => ele.EpisodeNumber + "" == historyEpisode.Episode && ele.SeasonNumber + "" == historyEpisode.EpisodeSeasonNum);
if (episode != null){ if (episode != null){
historyEpisode.SonarrEpisodeId = episode.Id + ""; historyEpisode.SonarrEpisodeId = episode.Id + "";
@ -500,7 +502,7 @@ public class History(){
} }
} }
} }
} });
} }
} }

View File

@ -0,0 +1,106 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="using:FluentAvalonia.UI.Controls"
xmlns:uip="using:FluentAvalonia.UI.Controls.Primitives">
<!--
NavView style in MainView for main app navigation
While you are free to copy this into your own apps
if you want an MS store like NavView, this will NOT
be an officially supported thing in the main library
-->
<Style Selector="ui|NavigationView.SampleAppNav">
<Setter Property="IsPaneToggleButtonVisible" Value="False" />
<Setter Property="OpenPaneLength" Value="72" />
<Setter Property="IsPaneOpen" Value="True" />
</Style>
<Style Selector="ui|NavigationView.SampleAppNav /template/ Button#NavigationViewBackButton">
<Setter Property="Width" Value="{DynamicResource NavigationBackButtonWidth}" />
</Style>
<Style Selector="ui|NavigationView.SampleAppNav[IsBackButtonVisible=False] SplitView /template/ ContentPresenter#PART_PanePresenter">
<Setter Property="Margin" Value="0 40 0 0" />
</Style>
<Style Selector="ui|NavigationViewItem.SampleAppNav uip|NavigationViewItemPresenter">
<Setter Property="Width" Value="72" />
<Setter Property="MinHeight" Value="60" />
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
<Setter Property="Foreground" Value="{DynamicResource TextFillColorSecondaryBrush}" />
<Setter Property="Template">
<ControlTemplate>
<Border Name="LayoutRoot"
Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding CornerRadius}"
Margin="4 2"
TemplatedControl.IsTemplateFocusTarget="True">
<Panel>
<Panel HorizontalAlignment="Left"
VerticalAlignment="Center">
<Border Name="SelectionIndicator"
Background="{DynamicResource NavigationViewSelectionIndicatorForeground}"
Width="3"
Opacity="0"
VerticalAlignment="Center"
Height="20"
CornerRadius="{StaticResource ControlCornerRadius}"/>
</Panel>
<DockPanel>
<ContentPresenter Name="ContentPresenter"
Grid.Row="1"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
FontSize="10"
Padding="0 4"
Margin="0 -15 0 3"
DockPanel.Dock="Bottom"
IsVisible="False">
<ContentPresenter.Styles>
<Style Selector="TextBlock">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</ContentPresenter.Styles>
</ContentPresenter>
<Viewbox Name="IconBox"
Height="28"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ContentPresenter Name="Icon"
Content="{Binding TemplateSettings.Icon, RelativeSource={RelativeSource TemplatedParent}}" />
</Viewbox>
</DockPanel>
</Panel>
</Border>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="ui|NavigationViewItem.SampleAppNav uip|NavigationViewItemPresenter:pointerover /template/ ContentPresenter#ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}" />
</Style>
<Style Selector="ui|NavigationViewItem.SampleAppNav uip|NavigationViewItemPresenter:pointerover /template/ ContentPresenter#Icon">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}" />
</Style>
<Style Selector="ui|NavigationViewItem.SampleAppNav uip|NavigationViewItemPresenter:pressed /template/ ContentPresenter#ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorSecondaryBrush}" />
</Style>
<Style Selector="ui|NavigationViewItem.SampleAppNav uip|NavigationViewItemPresenter:pressed /template/ ContentPresenter#Icon">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorSecondaryBrush}" />
</Style>
<Style Selector="ui|NavigationViewItem.SampleAppNav uip|NavigationViewItemPresenter:selected /template/ ContentPresenter#ContentPresenter">
<Setter Property="IsVisible" Value="False" />
</Style>
<Style Selector="ui|NavigationViewItem.SampleAppNav uip|NavigationViewItemPresenter:selected /template/ ContentPresenter#Icon">
<Setter Property="Foreground" Value="{DynamicResource AccentFillColorDefaultBrush}" />
</Style>
</Styles>

View File

@ -47,7 +47,7 @@ public partial class CalendarEpisode : INotifyPropertyChanged{
if (match.Success){ if (match.Success){
var locale = match.Groups[1].Value; // Capture the locale part var locale = match.Groups[1].Value; // Capture the locale part
var id = match.Groups[2].Value; // Capture the ID 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);
} }
} }

View File

@ -48,6 +48,21 @@ public class HistoryEpisode : INotifyPropertyChanged{
WasDownloaded = !WasDownloaded; WasDownloaded = !WasDownloaded;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(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(){ public async Task DownloadEpisode(){
await Crunchyroll.Instance.AddEpisodeToQue(EpisodeId, Crunchyroll.Instance.DefaultLocale, Crunchyroll.Instance.CrunOptions.DubLang); await Crunchyroll.Instance.AddEpisodeToQue(EpisodeId, Crunchyroll.Instance.DefaultLocale, Crunchyroll.Instance.CrunOptions.DubLang);

View File

@ -48,4 +48,15 @@ public class HistorySeason : INotifyPropertyChanged{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DownloadedEpisodes))); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DownloadedEpisodes)));
CfgManager.WriteJsonToFile(CfgManager.PathCrHistory, Crunchyroll.Instance.HistoryList); CfgManager.WriteJsonToFile(CfgManager.PathCrHistory, Crunchyroll.Instance.HistoryList);
} }
}
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;
}

View File

@ -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<object?> 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
};
}
}

View File

@ -119,7 +119,7 @@ public partial class AddDownloadPageViewModel : ViewModelBase{
if (match.Success){ if (match.Success){
var locale = match.Groups[1].Value; // Capture the locale part var locale = match.Groups[1].Value; // Capture the locale part
var id = match.Groups[2].Value; // Capture the ID 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 = ""; UrlInput = "";
selectedEpisodes.Clear(); selectedEpisodes.Clear();
SelectedItems.Clear(); SelectedItems.Clear();

View File

@ -193,12 +193,14 @@ public partial class HistoryPageViewModel : ViewModelBase{
partial void OnSelectedSeriesChanged(HistorySeries value){ partial void OnSelectedSeriesChanged(HistorySeries value){
Crunchyroll.Instance.SelectedSeries = value; Crunchyroll.Instance.SelectedSeries = value;
NavToSeries();
if (!string.IsNullOrEmpty(value.SonarrSeriesId) && Crunchyroll.Instance.CrunOptions.SonarrProperties is{ SonarrEnabled: true }){ if (!string.IsNullOrEmpty(value.SonarrSeriesId) && Crunchyroll.Instance.CrunOptions.SonarrProperties is{ SonarrEnabled: true }){
Crunchyroll.Instance.CrHistory.MatchHistoryEpisodesWithSonarr(true, SelectedSeries); Crunchyroll.Instance.CrHistory.MatchHistoryEpisodesWithSonarr(true, SelectedSeries);
CfgManager.WriteJsonToFile(CfgManager.PathCrHistory, Crunchyroll.Instance.HistoryList); CfgManager.WriteJsonToFile(CfgManager.PathCrHistory, Crunchyroll.Instance.HistoryList);
} }
NavToSeries();
_selectedSeries = null; _selectedSeries = null;
} }

View File

@ -13,6 +13,7 @@
<UserControl.Resources> <UserControl.Resources>
<ui:UiIntToVisibilityConverter x:Key="UiIntToVisibilityConverter" /> <ui:UiIntToVisibilityConverter x:Key="UiIntToVisibilityConverter" />
<ui:UiSonarrIdToVisibilityConverter x:Key="UiSonarrIdToVisibilityConverter" /> <ui:UiSonarrIdToVisibilityConverter x:Key="UiSonarrIdToVisibilityConverter" />
<ui:UiUpdateDownloadedHistorySeasonConverter x:Key="UiUpdateDownloadedHistorySeasonConverter" />
</UserControl.Resources> </UserControl.Resources>
<Grid> <Grid>
@ -422,8 +423,8 @@
Margin="0 0 10 0" Background="Transparent" Margin="0 0 10 0" Background="Transparent"
BorderThickness="0" CornerRadius="50" BorderThickness="0" CornerRadius="50"
IsVisible="{Binding !WasDownloaded}" IsVisible="{Binding !WasDownloaded}"
Command="{Binding $parent[controls:SettingsExpander].((history:HistorySeason)DataContext).UpdateDownloaded}" Command="{Binding ToggleWasDownloadedSeries}"
CommandParameter="{Binding EpisodeId}"> CommandParameter="{Binding $parent[ScrollViewer].((history:HistorySeries)DataContext)}">
<Grid> <Grid>
<Ellipse Width="25" Height="25" <Ellipse Width="25" Height="25"
Fill="Gray" /> Fill="Gray" />
@ -436,8 +437,8 @@
Margin="0 0 10 0" Background="Transparent" Margin="0 0 10 0" Background="Transparent"
BorderThickness="0" CornerRadius="50" BorderThickness="0" CornerRadius="50"
IsVisible="{Binding WasDownloaded}" IsVisible="{Binding WasDownloaded}"
Command="{Binding $parent[controls:SettingsExpander].((history:HistorySeason)DataContext).UpdateDownloaded}" Command="{Binding ToggleWasDownloadedSeries}"
CommandParameter="{Binding EpisodeId}"> CommandParameter="{Binding $parent[ScrollViewer].((history:HistorySeries)DataContext)}">
<Grid> <Grid>
<Ellipse Width="25" Height="25" <Ellipse Width="25" Height="25"
Fill="#21a556" /> Fill="#21a556" />