Add - History tab language selection

Add - Muxing description language selection
This commit is contained in:
Elwador 2024-06-27 22:52:12 +02:00
parent 9d66eb34c9
commit d2516d039b
13 changed files with 363 additions and 344 deletions

View File

@ -17,7 +17,7 @@ namespace CRD.Downloader;
public class CrEpisode(){
private readonly Crunchyroll crunInstance = Crunchyroll.Instance;
public async Task<CrunchyEpisode?> ParseEpisodeById(string id, string locale){
public async Task<CrunchyEpisode?> ParseEpisodeById(string id, string crLocale,bool forcedLang = false){
if (crunInstance.CmsToken?.Cms == null){
Console.Error.WriteLine("Missing CMS Access Token");
return null;
@ -26,7 +26,13 @@ public class CrEpisode(){
NameValueCollection query = HttpUtility.ParseQueryString(new UriBuilder().Query);
query["preferred_audio_language"] = "ja-JP";
query["locale"] = Languages.Locale2language(locale).CrLocale;
if (!string.IsNullOrEmpty(crLocale)){
query["locale"] = crLocale;
if (forcedLang){
query["force_locale"] = crLocale;
}
}
var request = HttpClientReq.CreateRequestMessage($"{Api.Cms}/episodes/{id}", HttpMethod.Get, true, true, query);
@ -199,6 +205,7 @@ public class CrEpisode(){
};
epMeta.AvailableSubs = item.SubtitleLocales;
epMeta.Description = item.Description;
if (episodeP.EpisodeAndLanguages.Langs.Count > 0){
epMeta.SelectedDubs = dubLang
.Where(language => episodeP.EpisodeAndLanguages.Langs.Any(epLang => epLang.CrLocale == language))

View File

@ -133,12 +133,12 @@ public class CrSeries(){
}
public async Task<CrunchySeriesList?> ListSeriesId(string id,string Locale, CrunchyMultiDownload? data){
public async Task<CrunchySeriesList?> ListSeriesId(string id,string crLocale, CrunchyMultiDownload? data){
await crunInstance.CrAuth.RefreshToken(true);
bool serieshasversions = true;
CrSeriesSearch? parsedSeries = await ParseSeriesById(id,Locale); // one piece - GRMG8ZQZR
CrSeriesSearch? parsedSeries = await ParseSeriesById(id,crLocale); // one piece - GRMG8ZQZR
if (parsedSeries == null){
Console.Error.WriteLine("Parse Data Invalid");
@ -154,7 +154,7 @@ public class CrSeries(){
var s = result[season][key];
if (data?.S != null && s.Id != data.Value.S) continue;
int fallbackIndex = 0;
var seasonData = await GetSeasonDataById(s.Id);
var seasonData = await GetSeasonDataById(s.Id,"");
if (seasonData.Data != null){
if (crunInstance.CrunOptions.History){
@ -285,7 +285,7 @@ public class CrSeries(){
return crunchySeriesList;
}
public async Task<CrunchyEpisodeList> GetSeasonDataById(string seasonID, bool log = false){
public async Task<CrunchyEpisodeList> GetSeasonDataById(string seasonID,string? crLocale,bool forcedLang = false, bool log = false){
CrunchyEpisodeList episodeList = new CrunchyEpisodeList(){ Data = new List<CrunchyEpisode>(), Total = 0, Meta = new Meta() };
if (crunInstance.CmsToken?.Cms == null){
@ -293,8 +293,20 @@ public class CrSeries(){
return episodeList;
}
NameValueCollection query;
if (log){
var showRequest = HttpClientReq.CreateRequestMessage($"{Api.Cms}/seasons/{seasonID}?preferred_audio_language=ja-JP", HttpMethod.Get, true, true, null);
query = HttpUtility.ParseQueryString(new UriBuilder().Query);
query["preferred_audio_language"] = "ja-JP";
if (!string.IsNullOrEmpty(crLocale)){
query["locale"] = crLocale;
if (forcedLang){
query["force_locale"] = crLocale;
}
}
var showRequest = HttpClientReq.CreateRequestMessage($"{Api.Cms}/seasons/{seasonID}", HttpMethod.Get, true, true, query);
var response = await HttpClientReq.Instance.SendHttpRequest(showRequest);
@ -305,9 +317,17 @@ public class CrSeries(){
}
}
var episodeRequest = new HttpRequestMessage(HttpMethod.Get, $"{Api.Cms}/seasons/{seasonID}/episodes?preferred_audio_language=ja-JP");
query = HttpUtility.ParseQueryString(new UriBuilder().Query);
episodeRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", crunInstance.Token?.access_token);
query["preferred_audio_language"] = "ja-JP";
if (!string.IsNullOrEmpty(crLocale)){
query["locale"] = crLocale;
if (forcedLang){
query["force_locale"] = crLocale;
}
}
var episodeRequest = HttpClientReq.CreateRequestMessage( $"{Api.Cms}/seasons/{seasonID}/episodes",HttpMethod.Get, true,true,query);
var episodeRequestResponse = await HttpClientReq.Instance.SendHttpRequest(episodeRequest);
@ -356,7 +376,7 @@ public class CrSeries(){
return ret;
}
public async Task<CrSeriesSearch?> ParseSeriesById(string id,string? locale,bool forced = false){
public async Task<CrSeriesSearch?> ParseSeriesById(string id,string? crLocale,bool forced = false){
if (crunInstance.CmsToken?.Cms == null){
Console.Error.WriteLine("Missing CMS Access Token");
return null;
@ -365,10 +385,10 @@ public class CrSeries(){
NameValueCollection query = HttpUtility.ParseQueryString(new UriBuilder().Query);
query["preferred_audio_language"] = "ja-JP";
if (!string.IsNullOrEmpty(locale)){
query["locale"] = Languages.Locale2language(locale).CrLocale;
if (!string.IsNullOrEmpty(crLocale)){
query["locale"] = crLocale;
if (forced){
query["force_locale"] = Languages.Locale2language(locale).CrLocale;
query["force_locale"] = crLocale;
}
}
@ -393,7 +413,7 @@ public class CrSeries(){
return seasonsList;
}
public async Task<CrSeriesBase?> SeriesById(string id){
public async Task<CrSeriesBase?> SeriesById(string id,string? crLocale,bool forced = false){
if (crunInstance.CmsToken?.Cms == null){
Console.Error.WriteLine("Missing CMS Access Token");
return null;
@ -402,6 +422,13 @@ public class CrSeries(){
NameValueCollection query = HttpUtility.ParseQueryString(new UriBuilder().Query);
query["preferred_audio_language"] = "ja-JP";
if (!string.IsNullOrEmpty(crLocale)){
query["locale"] = crLocale;
if (forced){
query["force_locale"] = crLocale;
}
}
var request = HttpClientReq.CreateRequestMessage($"{Api.Cms}/series/{id}", HttpMethod.Get, true, true, query);

View File

@ -69,7 +69,7 @@ public class Crunchyroll{
#endregion
public string DefaultLocale = "en";
public string DefaultLocale = "en-US";
public JsonSerializerSettings? SettingsJsonSerializerSettings = new(){
NullValueHandling = NullValueHandling.Ignore,
@ -159,6 +159,7 @@ public class Crunchyroll{
CrunOptions.DlVideoOnce = true;
CrunOptions.StreamEndpoint = "web/firefox";
CrunOptions.SubsAddScaledBorder = ScaledBorderAndShadowSelection.ScaledBorderAndShadowYes;
CrunOptions.HistoryLang = "";
CrunOptions.History = true;
@ -321,10 +322,10 @@ public class Crunchyroll{
return week;
}
public async Task AddEpisodeToQue(string epId, string locale, List<string> dubLang){
public async Task AddEpisodeToQue(string epId, string crLocale, List<string> dubLang){
await CrAuth.RefreshToken(true);
var episodeL = await CrEpisode.ParseEpisodeById(epId, locale);
var episodeL = await CrEpisode.ParseEpisodeById(epId, crLocale);
if (episodeL != null){
@ -336,6 +337,13 @@ public class Crunchyroll{
var sList = await CrEpisode.EpisodeData((CrunchyEpisode)episodeL);
var selected = CrEpisode.EpisodeMeta(sList, dubLang);
if (CrunOptions.IncludeVideoDescription){
if (selected.Data is{ Count: > 0 }){
var episode = await CrEpisode.ParseEpisodeById(selected.Data.First().MediaId, string.IsNullOrEmpty(CrunOptions.DescriptionLang) ? DefaultLocale : CrunOptions.DescriptionLang, true);
selected.Description = episode?.Description ?? selected.Description;
}
}
if (selected.Data is{ Count: > 0 }){
if (CrunOptions.History){
var historyEpisode = CrHistory.GetHistoryEpisodeWithDownloadDir(selected.ShowId, selected.SeasonId, selected.Data.First().MediaId);
@ -373,7 +381,7 @@ public class Crunchyroll{
}
}
public void AddSeriesToQueue(CrunchySeriesList list, CrunchyMultiDownload data){
public async Task AddSeriesToQueue(CrunchySeriesList list, CrunchyMultiDownload data){
var selected = CrSeries.ItemSelectMultiDub(list.Data, data.DubLang, data.But, data.AllEpisodes, data.E);
bool failed = false;
@ -399,6 +407,13 @@ public class Crunchyroll{
}
}
if (CrunOptions.IncludeVideoDescription){
if (crunchyEpMeta.Data is{ Count: > 0 }){
var episode = await CrEpisode.ParseEpisodeById(crunchyEpMeta.Data.First().MediaId, string.IsNullOrEmpty(CrunOptions.DescriptionLang) ? DefaultLocale : CrunOptions.DescriptionLang, true);
crunchyEpMeta.Description = episode?.Description ?? crunchyEpMeta.Description;
}
}
Queue.Add(crunchyEpMeta);
} else{
failed = true;

View File

@ -27,7 +27,7 @@ public class History(){
public async Task UpdateSeries(string seriesId, string? seasonId){
await crunInstance.CrAuth.RefreshToken(true);
CrSeriesSearch? parsedSeries = await crunInstance.CrSeries.ParseSeriesById(seriesId, "ja", true);
CrSeriesSearch? parsedSeries = await crunInstance.CrSeries.ParseSeriesById(seriesId, "ja-JP", true);
if (parsedSeries == null){
Console.Error.WriteLine("Parse Data Invalid");
@ -55,8 +55,8 @@ public class History(){
}
}
var seasonData = await crunInstance.CrSeries.GetSeasonDataById(sId);
UpdateWithSeasonData(seasonData);
var seasonData = await crunInstance.CrSeries.GetSeasonDataById(sId,string.IsNullOrEmpty(crunInstance.CrunOptions.HistoryLang) ? crunInstance.DefaultLocale : crunInstance.CrunOptions.HistoryLang,true);
await UpdateWithSeasonData(seasonData);
}
}
}
@ -152,10 +152,7 @@ public class History(){
if (historySeries != null){
var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == episode.SeasonId);
var series = await crunInstance.CrSeries.SeriesById(seriesId);
if (series?.Data != null){
historySeries.SeriesTitle = series.Data.First().Title;
}
await RefreshSeriesData(seriesId, historySeries);
if (historySeason != null){
historySeason.SeasonTitle = episode.SeasonTitle;
@ -192,12 +189,7 @@ public class History(){
crunInstance.HistoryList.Add(historySeries);
var newSeason = NewHistorySeason(episode);
var series = await crunInstance.CrSeries.SeriesById(seriesId);
if (series?.Data != null){
historySeries.SeriesDescription = series.Data.First().Description;
historySeries.ThumbnailImageUrl = GetSeriesThumbnail(series);
historySeries.SeriesTitle = series.Data.First().Title;
}
await RefreshSeriesData(seriesId, historySeries);
historySeries.Seasons.Add(newSeason);
historySeries.UpdateNewEpisodes();
@ -217,10 +209,8 @@ public class History(){
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
if (historySeries != null){
var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == firstEpisode.SeasonId);
var series = await crunInstance.CrSeries.SeriesById(seriesId);
if (series?.Data != null){
historySeries.SeriesTitle = series.Data.First().Title;
}
await RefreshSeriesData(seriesId, historySeries);
if (historySeason != null){
historySeason.SeasonTitle = firstEpisode.SeasonTitle;
@ -274,12 +264,7 @@ public class History(){
newSeason.EpisodesList.Sort(new NumericStringPropertyComparer());
var series = await crunInstance.CrSeries.SeriesById(seriesId);
if (series?.Data != null){
historySeries.SeriesDescription = series.Data.First().Description;
historySeries.ThumbnailImageUrl = GetSeriesThumbnail(series);
historySeries.SeriesTitle = series.Data.First().Title;
}
await RefreshSeriesData(seriesId, historySeries);
historySeries.Seasons.Add(newSeason);
@ -295,6 +280,15 @@ public class History(){
}
}
private async Task RefreshSeriesData(string seriesId, HistorySeries historySeries){
var series = await crunInstance.CrSeries.SeriesById(seriesId,string.IsNullOrEmpty(crunInstance.CrunOptions.HistoryLang) ? crunInstance.DefaultLocale : crunInstance.CrunOptions.HistoryLang,true);
if (series?.Data != null){
historySeries.SeriesDescription = series.Data.First().Description;
historySeries.ThumbnailImageUrl = GetSeriesThumbnail(series);
historySeries.SeriesTitle = series.Data.First().Title;
}
}
private void SortSeasons(HistorySeries series){
var sortedSeasons = series.Seasons
.OrderBy(s => s.SeasonNum != null ? int.Parse(s.SeasonNum) : 0)

View File

@ -1,106 +0,0 @@
<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){
var locale = match.Groups[1].Value; // Capture the locale part
var id = match.Groups[2].Value; // Capture the ID part
Crunchyroll.Instance.AddEpisodeToQue(id, locale, Crunchyroll.Instance.CrunOptions.DubLang);
Crunchyroll.Instance.AddEpisodeToQue(id, Languages.Locale2language(locale).CrLocale, Crunchyroll.Instance.CrunOptions.DubLang);
}
}

View File

@ -81,6 +81,9 @@ public class CrDownloadOptions{
[YamlMember(Alias = "mux_video_description", ApplyNamingConventions = false)]
public bool IncludeVideoDescription{ get; set; }
[YamlMember(Alias = "mux_description_lang", ApplyNamingConventions = false)]
public string? DescriptionLang{ get; set; }
[YamlIgnore]
public string Force{ get; set; }
@ -132,6 +135,9 @@ public class CrDownloadOptions{
[YamlMember(Alias = "history", ApplyNamingConventions = false)]
public bool History{ get; set; }
[YamlMember(Alias = "history_lang", ApplyNamingConventions = false)]
public string? HistoryLang{ get; set; }
[YamlMember(Alias = "sonarr_properties", ApplyNamingConventions = false)]
public SonarrProperties? SonarrProperties{ get; set; }

View File

@ -147,6 +147,8 @@ public class HistorySeries : INotifyPropertyChanged{
await Crunchyroll.Instance.CrHistory.UpdateSeries(SeriesId, seasonId);
FetchingData = false;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FetchingData)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SeriesTitle)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SeriesDescription)));
Crunchyroll.Instance.CrHistory.MatchHistoryEpisodesWithSonarr(false, this);
UpdateNewEpisodes();
}

View File

@ -91,7 +91,7 @@ public partial class AddDownloadPageViewModel : ViewModelBase{
}
if (currentSeriesList != null){
Crunchyroll.Instance.AddSeriesToQueue(currentSeriesList.Value, new CrunchyMultiDownload(Crunchyroll.Instance.CrunOptions.DubLang, AddAllEpisodes, false, selectedEpisodes));
await Crunchyroll.Instance.AddSeriesToQueue(currentSeriesList.Value, new CrunchyMultiDownload(Crunchyroll.Instance.CrunOptions.DubLang, AddAllEpisodes, false, selectedEpisodes));
}
@ -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, locale, Crunchyroll.Instance.CrunOptions.DubLang);
Crunchyroll.Instance.AddEpisodeToQue(id, Languages.Locale2language(locale).CrLocale, Crunchyroll.Instance.CrunOptions.DubLang);
UrlInput = "";
selectedEpisodes.Clear();
SelectedItems.Clear();
@ -142,7 +142,7 @@ public partial class AddDownloadPageViewModel : ViewModelBase{
ButtonEnabled = false;
ShowLoading = true;
var list = await Crunchyroll.Instance.CrSeries.ListSeriesId(id, "", new CrunchyMultiDownload(Crunchyroll.Instance.CrunOptions.DubLang, true));
var list = await Crunchyroll.Instance.CrSeries.ListSeriesId(id, Languages.Locale2language(locale).CrLocale, new CrunchyMultiDownload(Crunchyroll.Instance.CrunOptions.DubLang, true));
ShowLoading = false;
if (list != null){
currentSeriesList = list;

View File

@ -79,7 +79,7 @@ public partial class SeriesPageViewModel : ViewModelBase{
public async Task UpdateData(string? season){
await SelectedSeries.FetchData(season);
MessageBus.Current.SendMessage(new NavigationMessage(typeof(SeriesPageViewModel), false, true));
// MessageBus.Current.SendMessage(new NavigationMessage(typeof(SeriesPageViewModel), false, true));
}
[RelayCommand]

View File

@ -94,6 +94,13 @@ public partial class SettingsPageViewModel : ViewModelBase{
[ObservableProperty]
private ComboBoxItem _selectedHSLang;
[ObservableProperty]
private ComboBoxItem _selectedHistoryLang;
[ObservableProperty]
private ComboBoxItem _selectedDescriptionLang;
[ObservableProperty]
private string _selectedDubs = "ja-JP";
@ -228,6 +235,36 @@ public partial class SettingsPageViewModel : ViewModelBase{
new ComboBoxItem(){ Content = "none" },
};
public ObservableCollection<ComboBoxItem> HistoryLangList{ get; } = new(){
new ComboBoxItem(){ Content = "default" },
new ComboBoxItem(){ Content = "de-DE" },
new ComboBoxItem(){ Content = "en-US" },
new ComboBoxItem(){ Content = "es-419" },
new ComboBoxItem(){ Content = "es-ES" },
new ComboBoxItem(){ Content = "fr-FR" },
new ComboBoxItem(){ Content = "it-IT" },
new ComboBoxItem(){ Content = "pt-BR" },
new ComboBoxItem(){ Content = "pt-PT" },
new ComboBoxItem(){ Content = "ru-RU" },
new ComboBoxItem(){ Content = "hi-IN" },
new ComboBoxItem(){ Content = "ar-SA" },
};
public ObservableCollection<ComboBoxItem> DescriptionLangList{ get; } = new(){
new ComboBoxItem(){ Content = "default" },
new ComboBoxItem(){ Content = "de-DE" },
new ComboBoxItem(){ Content = "en-US" },
new ComboBoxItem(){ Content = "es-419" },
new ComboBoxItem(){ Content = "es-ES" },
new ComboBoxItem(){ Content = "fr-FR" },
new ComboBoxItem(){ Content = "it-IT" },
new ComboBoxItem(){ Content = "pt-BR" },
new ComboBoxItem(){ Content = "pt-PT" },
new ComboBoxItem(){ Content = "ru-RU" },
new ComboBoxItem(){ Content = "hi-IN" },
new ComboBoxItem(){ Content = "ar-SA" },
};
public ObservableCollection<ComboBoxItem> DubLangList{ get; } = new(){
};
@ -287,6 +324,12 @@ public partial class SettingsPageViewModel : ViewModelBase{
DownloadDirPath = string.IsNullOrEmpty(options.DownloadDirPath) ? CfgManager.PathVIDEOS_DIR : options.DownloadDirPath;
ComboBoxItem? descriptionLang = DescriptionLangList.FirstOrDefault(a => a.Content != null && (string)a.Content == options.DescriptionLang) ?? null;
SelectedDescriptionLang = descriptionLang ?? DescriptionLangList[0];
ComboBoxItem? historyLang = HistoryLangList.FirstOrDefault(a => a.Content != null && (string)a.Content == options.HistoryLang) ?? null;
SelectedHistoryLang = historyLang ?? HistoryLangList[0];
ComboBoxItem? hsLang = HardSubLangList.FirstOrDefault(a => a.Content != null && (string)a.Content == options.Hslang) ?? null;
SelectedHSLang = hsLang ?? HardSubLangList[0];
@ -408,6 +451,14 @@ public partial class SettingsPageViewModel : ViewModelBase{
Crunchyroll.Instance.CrunOptions.DlSubs = softSubs;
string descLang = SelectedDescriptionLang.Content + "";
Crunchyroll.Instance.CrunOptions.DescriptionLang = descLang != "default" ? descLang : "";
string historyLang = SelectedHistoryLang.Content + "";
Crunchyroll.Instance.CrunOptions.HistoryLang = historyLang != "default" ? historyLang : "";
string hslang = SelectedHSLang.Content + "";
Crunchyroll.Instance.CrunOptions.Hslang = hslang != "none" ? Languages.FindLang(hslang).Locale : hslang;

View File

@ -9,216 +9,221 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="CRD.Views.SeriesPageView">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Command="{Binding NavBack}" Margin="0 0 0 10">Back</Button>
<Image Grid.Row="1" Grid.Column="0" Margin="10" Source="{Binding SelectedSeries.ThumbnailImage}" Width="240"
Height="360">
</Image>
<Grid Grid.Row="1" Grid.Column="1">
<Grid>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" FontSize="50" Text="{Binding SelectedSeries.SeriesTitle}"></TextBlock>
<TextBlock Grid.Row="1" FontSize="20" TextWrapping="Wrap" Text="{Binding SelectedSeries.SeriesDescription}"></TextBlock>
<StackPanel Grid.Row="3" Orientation="Vertical">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0 10 10 10">
<Button Grid.Row="0" Grid.Column="0" Command="{Binding NavBack}" Margin="0 0 0 10">Back</Button>
<Button Width="34" Height="34" Margin="0 0 10 0" Background="Transparent"
BorderThickness="0" CornerRadius="50"
Command="{Binding SelectedSeries.OpenCrPage}">
<Grid>
<controls:ImageIcon Source="../Assets/crunchy_icon_round.png" Width="30" Height="30" />
</Grid>
</Button>
<Image Grid.Row="1" Grid.Column="0" Margin="10" Source="{Binding SelectedSeries.ThumbnailImage}" Width="240"
Height="360">
</Image>
<Grid Grid.Row="1" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" FontSize="50" Text="{Binding SelectedSeries.SeriesTitle}"></TextBlock>
<TextBlock Grid.Row="1" FontSize="20" TextWrapping="Wrap" Text="{Binding SelectedSeries.SeriesDescription}"></TextBlock>
<StackPanel Grid.Row="3" Orientation="Vertical">
<StackPanel Orientation="Horizontal" Margin="0 10 10 10">
<Button Width="34" Height="34" Margin="0 0 10 0" Background="Transparent"
BorderThickness="0" CornerRadius="50"
Command="{Binding SelectedSeries.OpenCrPage}">
<Grid>
<controls:ImageIcon Source="../Assets/crunchy_icon_round.png" Width="30" Height="30" />
</Grid>
</Button>
<Button Width="34" Height="34" Margin="0 0 10 0" Background="Transparent"
BorderThickness="0" CornerRadius="50"
IsVisible="{Binding SonarrAvailable}"
Command="{Binding SelectedSeries.OpenSonarrPage}">
<Grid>
<controls:ImageIcon Source="../Assets/sonarr.png" Width="30" Height="30" />
</Grid>
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button Command="{Binding UpdateData}" Margin="0 0 5 10">Fetch Series</Button>
<ToggleButton IsChecked="{Binding EditMode}" Margin="0 0 5 10">Edit</ToggleButton>
<Button Margin="0 0 5 10" FontStyle="Italic"
VerticalAlignment="Center"
Command="{Binding OpenFolderDialogAsync}">
<ToolTip.Tip>
<TextBlock Text="{Binding SelectedSeries.SeriesDownloadPath}" FontSize="15" />
</ToolTip.Tip>
<StackPanel Orientation="Horizontal">
<controls:SymbolIcon Symbol="Folder" FontSize="18" />
</StackPanel>
</Button>
</StackPanel>
<Button Width="34" Height="34" Margin="0 0 10 0" Background="Transparent"
BorderThickness="0" CornerRadius="50"
IsVisible="{Binding SonarrAvailable}"
Command="{Binding SelectedSeries.OpenSonarrPage}">
<Grid>
<controls:ImageIcon Source="../Assets/sonarr.png" Width="30" Height="30" />
</Grid>
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button Command="{Binding UpdateData}" Margin="0 0 5 10">Fetch Series</Button>
<ToggleButton IsChecked="{Binding EditMode}" Margin="0 0 5 10">Edit</ToggleButton>
<Button Margin="0 0 5 10" FontStyle="Italic"
VerticalAlignment="Center"
Command="{Binding OpenFolderDialogAsync}">
<ToolTip.Tip>
<TextBlock Text="{Binding SelectedSeries.SeriesDownloadPath}" FontSize="15" />
</ToolTip.Tip>
<StackPanel Orientation="Horizontal">
<controls:SymbolIcon Symbol="Folder" FontSize="18" />
</StackPanel>
</Button>
</StackPanel>
</Grid>
</StackPanel>
<ScrollViewer Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2">
<ItemsControl ItemsSource="{Binding SelectedSeries.Seasons}">
<ItemsControl.ItemTemplate>
<DataTemplate>
</Grid>
<controls:SettingsExpander
Header="{Binding CombinedProperty}"
ItemsSource="{Binding EpisodesList}"
Description="{Binding SeasonTitle}"
IsExpanded="False">
<ScrollViewer Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2">
<ItemsControl ItemsSource="{Binding SelectedSeries.Seasons}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:SettingsExpander.ItemTemplate>
<DataTemplate>
<controls:SettingsExpander
Header="{Binding CombinedProperty}"
ItemsSource="{Binding EpisodesList}"
Description="{Binding SeasonTitle}"
IsExpanded="False">
<controls:SettingsExpander.ItemTemplate>
<DataTemplate>
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Text="E"></TextBlock>
<TextBlock Text="{Binding Episode}"></TextBlock>
<TextBlock Text=" - "></TextBlock>
<TextBlock Text="{Binding EpisodeTitle}"></TextBlock>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
<StackPanel VerticalAlignment="Center" Margin="0 0 5 0"
IsVisible="{Binding $parent[ItemsControl].((vm:SeriesPageViewModel)DataContext).SonarrAvailable}">
<controls:ImageIcon IsVisible="{Binding SonarrHasFile}"
Source="../Assets/sonarr.png" Width="25"
Height="25" />
<controls:ImageIcon IsVisible="{Binding !SonarrHasFile}"
Source="../Assets/sonarr_inactive.png" Width="25"
Height="25" />
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Text="E"></TextBlock>
<TextBlock Text="{Binding Episode}"></TextBlock>
<TextBlock Text=" - "></TextBlock>
<TextBlock Text="{Binding EpisodeTitle}"></TextBlock>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
<Button Width="34" Height="34" 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}">
<Grid>
<Ellipse Width="25" Height="25" Fill="Gray" />
<controls:SymbolIcon Symbol="Checkmark" FontSize="18" />
</Grid>
</Button>
<StackPanel VerticalAlignment="Center" Margin="0 0 5 0"
IsVisible="{Binding $parent[ItemsControl].((vm:SeriesPageViewModel)DataContext).SonarrAvailable}">
<controls:ImageIcon IsVisible="{Binding SonarrHasFile}"
Source="../Assets/sonarr.png" Width="25"
Height="25" />
<controls:ImageIcon IsVisible="{Binding !SonarrHasFile}"
Source="../Assets/sonarr_inactive.png" Width="25"
Height="25" />
<Button Width="34" Height="34" 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}">
<Grid>
<Ellipse Width="25" Height="25" Fill="#21a556" />
<controls:SymbolIcon Symbol="Checkmark" FontSize="18" />
</Grid>
</Button>
<Button Margin="0 0 5 0" FontStyle="Italic" HorizontalAlignment="Right"
VerticalAlignment="Center" Command="{Binding DownloadEpisode}">
<StackPanel Orientation="Horizontal">
<controls:SymbolIcon Symbol="Download" FontSize="18" />
</StackPanel>
</Button>
</StackPanel>
</Grid>
</DataTemplate>
</controls:SettingsExpander.ItemTemplate>
<controls:SettingsExpander.Footer>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Text="{Binding DownloadedEpisodes}" VerticalAlignment="Center"></TextBlock>
<TextBlock Text="/" VerticalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding EpisodesList.Count}" VerticalAlignment="Center"></TextBlock>
<Button Margin="10 0 0 0" FontStyle="Italic"
VerticalAlignment="Center"
Command="{Binding $parent[UserControl].((vm:SeriesPageViewModel)DataContext).UpdateData}"
CommandParameter="{Binding SeasonId}">
<ToolTip.Tip>
<TextBlock Text="Fetch Season" FontSize="15" />
</ToolTip.Tip>
<StackPanel Orientation="Horizontal">
<controls:SymbolIcon Symbol="Refresh" FontSize="18" />
</StackPanel>
</Button>
<Button Margin="10 0 0 0" FontStyle="Italic"
VerticalAlignment="Center"
Command="{Binding $parent[UserControl].((vm:SeriesPageViewModel)DataContext).OpenFolderDialogAsync}"
CommandParameter="{Binding .}">
<ToolTip.Tip>
<TextBlock Text="{Binding SeasonDownloadPath}" FontSize="15" />
</ToolTip.Tip>
<StackPanel Orientation="Horizontal">
<controls:SymbolIcon Symbol="Folder" FontSize="18" />
</StackPanel>
</Button>
<Button Margin="10 0 0 0" FontStyle="Italic"
VerticalAlignment="Center"
Command="{Binding $parent[UserControl].((vm:SeriesPageViewModel)DataContext).RemoveSeason}"
CommandParameter="{Binding SeasonId}"
IsVisible="{Binding $parent[UserControl].((vm:SeriesPageViewModel)DataContext).EditMode}">
<ToolTip.Tip>
<TextBlock Text="Remove Season" FontSize="15" />
</ToolTip.Tip>
<StackPanel Orientation="Horizontal">
<controls:SymbolIcon Symbol="Delete" FontSize="18" />
</StackPanel>
</Button>
</StackPanel>
</controls:SettingsExpander.Footer>
</controls:SettingsExpander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<Button Width="34" Height="34" 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}">
<Grid>
<Ellipse Width="25" Height="25" Fill="Gray" />
<controls:SymbolIcon Symbol="Checkmark" FontSize="18" />
</Grid>
</Button>
<Button Width="34" Height="34" 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}">
<Grid>
<Ellipse Width="25" Height="25" Fill="#21a556" />
<controls:SymbolIcon Symbol="Checkmark" FontSize="18" />
</Grid>
</Button>
<Button Margin="0 0 5 0" FontStyle="Italic" HorizontalAlignment="Right"
VerticalAlignment="Center" Command="{Binding DownloadEpisode}">
<StackPanel Orientation="Horizontal">
<controls:SymbolIcon Symbol="Download" FontSize="18" />
</StackPanel>
</Button>
</StackPanel>
</Grid>
</DataTemplate>
</controls:SettingsExpander.ItemTemplate>
<controls:SettingsExpander.Footer>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Text="{Binding DownloadedEpisodes}" VerticalAlignment="Center"></TextBlock>
<TextBlock Text="/" VerticalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding EpisodesList.Count}" VerticalAlignment="Center"></TextBlock>
<Button Margin="10 0 0 0" FontStyle="Italic"
VerticalAlignment="Center"
Command="{Binding $parent[UserControl].((vm:SeriesPageViewModel)DataContext).UpdateData}"
CommandParameter="{Binding SeasonId}">
<ToolTip.Tip>
<TextBlock Text="Fetch Season" FontSize="15" />
</ToolTip.Tip>
<StackPanel Orientation="Horizontal">
<controls:SymbolIcon Symbol="Refresh" FontSize="18" />
</StackPanel>
</Button>
<Button Margin="10 0 0 0" FontStyle="Italic"
VerticalAlignment="Center"
Command="{Binding $parent[UserControl].((vm:SeriesPageViewModel)DataContext).OpenFolderDialogAsync}"
CommandParameter="{Binding .}">
<ToolTip.Tip>
<TextBlock Text="{Binding SeasonDownloadPath}" FontSize="15" />
</ToolTip.Tip>
<StackPanel Orientation="Horizontal">
<controls:SymbolIcon Symbol="Folder" FontSize="18" />
</StackPanel>
</Button>
<Button Margin="10 0 0 0" FontStyle="Italic"
VerticalAlignment="Center"
Command="{Binding $parent[UserControl].((vm:SeriesPageViewModel)DataContext).RemoveSeason}"
CommandParameter="{Binding SeasonId}"
IsVisible="{Binding $parent[UserControl].((vm:SeriesPageViewModel)DataContext).EditMode}">
<ToolTip.Tip>
<TextBlock Text="Remove Season" FontSize="15" />
</ToolTip.Tip>
<StackPanel Orientation="Horizontal">
<controls:SymbolIcon Symbol="Delete" FontSize="18" />
</StackPanel>
</Button>
</StackPanel>
</controls:SettingsExpander.Footer>
</controls:SettingsExpander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
<Grid IsVisible="{Binding SelectedSeries.FetchingData}"
Background="#90000000"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<controls:ProgressRing Width="100" Height="100" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Grid>
</UserControl>

View File

@ -135,6 +135,15 @@
<CheckBox IsChecked="{Binding History}"> </CheckBox>
</controls:SettingsExpander.Footer>
<controls:SettingsExpanderItem Content="History Language" Description="Use the same language as Sonarr if you plan to connect it to this downloader">
<controls:SettingsExpanderItem.Footer>
<ComboBox HorizontalContentAlignment="Center" MinWidth="210" MaxDropDownHeight="400"
ItemsSource="{Binding HistoryLangList}"
SelectedItem="{Binding SelectedHistoryLang}">
</ComboBox>
</controls:SettingsExpanderItem.Footer>
</controls:SettingsExpanderItem>
</controls:SettingsExpander>
<controls:SettingsExpander Header="Download Settings"
@ -304,6 +313,15 @@
</controls:SettingsExpanderItem.Footer>
</controls:SettingsExpanderItem>
<controls:SettingsExpanderItem Content="Episode description Language" >
<controls:SettingsExpanderItem.Footer>
<ComboBox HorizontalContentAlignment="Center" MinWidth="210" MaxDropDownHeight="400"
ItemsSource="{Binding DescriptionLangList}"
SelectedItem="{Binding SelectedDescriptionLang}">
</ComboBox>
</controls:SettingsExpanderItem.Footer>
</controls:SettingsExpanderItem>
<controls:SettingsExpanderItem Content="Additional MKVMerge Options">
<controls:SettingsExpanderItem.Footer>