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
This commit is contained in:
Elwador 2024-07-12 15:53:44 +02:00
parent acdbc7467b
commit c4922af741
11 changed files with 326 additions and 65 deletions

View File

@ -239,30 +239,46 @@ public class CrEpisode(){
return retMeta;
}
public async Task<CrBrowseEpisodeBase?> GetNewEpisodes(string? crLocale){
public async Task<CrBrowseEpisodeBase?> GetNewEpisodes(string? crLocale, int requestAmount){
CrBrowseEpisodeBase? complete = new CrBrowseEpisodeBase();
complete.Data =[];
NameValueCollection query = HttpUtility.ParseQueryString(new UriBuilder().Query);
var i = 0;
if (!string.IsNullOrEmpty(crLocale)){
query["locale"] = crLocale;
}
do{
NameValueCollection query = HttpUtility.ParseQueryString(new UriBuilder().Query);
query["n"] = "200";
query["sort_by"] = "newly_added";
query["type"] = "episode";
if (!string.IsNullOrEmpty(crLocale)){
query["locale"] = crLocale;
}
var request = HttpClientReq.CreateRequestMessage($"{Api.Browse}", HttpMethod.Get, true, false, query);
query["start"] = i + "";
query["n"] = "50";
query["sort_by"] = "newly_added";
query["type"] = "episode";
var response = await HttpClientReq.Instance.SendHttpRequest(request);
var request = HttpClientReq.CreateRequestMessage($"{Api.Browse}", HttpMethod.Get, true, false, query);
if (!response.IsOk){
Console.Error.WriteLine("Series Request Failed");
return null;
}
var response = await HttpClientReq.Instance.SendHttpRequest(request);
CrBrowseEpisodeBase? series = Helpers.Deserialize<CrBrowseEpisodeBase>(response.ResponseContent, crunInstance.SettingsJsonSerializerSettings);
if (!response.IsOk){
Console.Error.WriteLine("Series Request Failed");
return null;
}
CrBrowseEpisodeBase? series = Helpers.Deserialize<CrBrowseEpisodeBase>(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 series;
return complete;
}
}

View File

@ -159,11 +159,13 @@ 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;
CfgManager.UpdateSettingsFromFile();

View File

@ -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;
});

View File

@ -184,6 +184,8 @@ public enum SortingType{
SeriesTitle,
[EnumMember(Value = "Next Air Date")]
NextAirDate,
[EnumMember(Value = "History Series Add Date")]
HistorySeriesAddDate,
}
public enum SonarrCoverType{

View File

@ -132,6 +132,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; }

View File

@ -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]

View File

@ -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();

View File

@ -15,14 +15,23 @@ namespace CRD.ViewModels;
public partial class CalendarPageViewModel : ViewModelBase{
public ObservableCollection<CalendarDay> 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<ComboBoxItem> CalendarDubFilter{ get; } = new(){
new ComboBoxItem(){ Content = "none" },
};
[ObservableProperty]
private ComboBoxItem? _currentCalendarDubFilter;
public ObservableCollection<ComboBoxItem> CalendarLanguage{ get; } = new(){
new ComboBoxItem(){ Content = "en-us" },
@ -38,12 +47,29 @@ public partial class CalendarPageViewModel : ViewModelBase{
new ComboBoxItem(){ Content = "hi" },
};
[ObservableProperty]
private ComboBoxItem? _currentCalendarLanguage;
private CalendarWeek? currentWeek;
private bool loading = true;
public CalendarPageViewModel(){
CalendarDays = new ObservableCollection<CalendarDay>();
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<CalendarEpisode>(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<CalendarDay>();
@ -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){

View File

@ -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<ComboBoxItem> ViewsList{ get; } =[];
[ObservableProperty]
public ComboBoxItem _selectedSorting;
public SortingListElement _selectedSorting;
public ObservableCollection<ComboBoxItem> SortingList{ get; } =[];
public ObservableCollection<SortingListElement> 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<SortingType>(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{
@ -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; }
}

View File

@ -36,18 +36,86 @@
<StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center"
Margin="0 10 0 0">
<Button HorizontalAlignment="Center" Command="{Binding Refresh}">
<Button Margin="5 0 5 0" HorizontalAlignment="Center" Command="{Binding Refresh}">
<StackPanel Orientation="Horizontal">
<controls:SymbolIcon Symbol="Refresh" FontSize="18" />
</StackPanel>
</Button>
<ComboBox HorizontalAlignment="Center" Margin="10 0 0 0" MinWidth="200"
SelectedItem="{Binding CurrentCalendarLanguage}"
ItemsSource="{Binding CalendarLanguage}">
</ComboBox>
<CheckBox IsChecked="{Binding CustomCalendar}"
Content="Custom Calendar" Margin="5 0 0 0">
</CheckBox>
<!-- <ComboBox HorizontalAlignment="Center" Margin="10 0 0 0" MinWidth="200" -->
<!-- SelectedItem="{Binding CurrentCalendarLanguage}" -->
<!-- ItemsSource="{Binding CalendarLanguage}"> -->
<!-- </ComboBox> -->
<!-- <CheckBox IsChecked="{Binding CustomCalendar}" -->
<!-- Content="Custom Calendar" Margin="5 0 0 0"> -->
<!-- </CheckBox> -->
<StackPanel Margin="5 0 5 0">
<ToggleButton x:Name="CalendarSettings" HorizontalContentAlignment="Stretch">
<StackPanel Orientation="Horizontal">
<controls:SymbolIcon Symbol="Settings" FontSize="18" />
</StackPanel>
</ToggleButton>
<Popup IsLightDismissEnabled="True"
MaxWidth="400"
MaxHeight="600"
IsOpen="{Binding IsChecked, ElementName=CalendarSettings, Mode=TwoWay}"
Placement="Bottom"
PlacementTarget="{Binding ElementName=CalendarSettings}">
<Border BorderThickness="1" Background="{DynamicResource ComboBoxDropDownBackground}">
<StackPanel>
<controls:SettingsExpander IsVisible="{Binding !CustomCalendar}" Header="Simulcast Calendar Language">
<controls:SettingsExpander.Footer>
<ComboBox HorizontalAlignment="Center" Margin="10 0 0 0" MinWidth="200"
SelectedItem="{Binding CurrentCalendarLanguage}"
ItemsSource="{Binding CalendarLanguage}">
</ComboBox>
</controls:SettingsExpander.Footer>
</controls:SettingsExpander>
<controls:SettingsExpander Header="Custom Calendar">
<controls:SettingsExpander.Footer>
<CheckBox IsChecked="{Binding CustomCalendar}"
Content="Enabled" Margin="5 0 0 0">
</CheckBox>
</controls:SettingsExpander.Footer>
</controls:SettingsExpander>
<controls:SettingsExpander IsVisible="{Binding CustomCalendar}" Header="Custom Calendar Dub Filter">
<controls:SettingsExpander.Footer>
<ComboBox HorizontalAlignment="Center" Margin="10 0 0 0" MinWidth="200"
SelectedItem="{Binding CurrentCalendarDubFilter}"
ItemsSource="{Binding CalendarDubFilter}">
</ComboBox>
</controls:SettingsExpander.Footer>
</controls:SettingsExpander>
<controls:SettingsExpander Header="Calendar ">
<controls:SettingsExpander.Footer>
<CheckBox IsChecked="{Binding HideDubs}"
Content="Hide Dubs" Margin="5 0 0 0">
</CheckBox>
</controls:SettingsExpander.Footer>
</controls:SettingsExpander>
</StackPanel>
</Border>
</Popup>
</StackPanel>
</StackPanel>
@ -94,7 +162,7 @@
</StackPanel>
</Border>
<ScrollViewer Grid.Row="1" >
<ScrollViewer Grid.Row="1">
<ItemsControl ItemsSource="{Binding CalendarEpisodes}">
<ItemsControl.ItemTemplate>
<DataTemplate>

View File

@ -114,9 +114,18 @@
Placement="BottomEdgeAlignedRight"
PlacementTarget="{Binding ElementName=DropdownButtonSorting}">
<Border BorderThickness="1" Background="{DynamicResource ComboBoxDropDownBackground}">
<ListBox SelectionMode="Single" Width="210"
<ListBox SelectionMode="Single,Toggle" Width="210"
MaxHeight="400"
ItemsSource="{Binding SortingList}" SelectedItem="{Binding SelectedSorting}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left">
<controls:SymbolIcon IsVisible="{Binding !$parent[UserControl].((vm:HistoryPageViewModel)DataContext).SortDir}" Symbol="ChevronUp" FontSize="12" Margin="0 0 10 0"/>
<controls:SymbolIcon IsVisible="{Binding $parent[UserControl].((vm:HistoryPageViewModel)DataContext).SortDir}" Symbol="ChevronDown" FontSize="12" Margin="0 0 10 0"/>
<TextBlock Text="{Binding SortingTitle}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</Popup>
@ -199,10 +208,8 @@
<Button
Background="Transparent"
BorderThickness="0"
Width="{Binding $parent[UserControl].((vm:HistoryPageViewModel)DataContext).PosterWidth}"
Height="{Binding $parent[UserControl].((vm:HistoryPageViewModel)DataContext).PosterHeight}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
FontStyle="Italic"
VerticalAlignment="Center"
Command="{Binding $parent[UserControl].((vm:HistoryPageViewModel)DataContext).RemoveSeries}"
CommandParameter="{Binding SeriesId}"
IsEnabled="{Binding !$parent[UserControl].((vm:HistoryPageViewModel)DataContext).FetchingData}">