mirror of
https://github.com/Crunchy-DL/Crunchy-Downloader.git
synced 2026-03-11 17:45:39 +00:00
Add - Added edit button for history overview and series
Chg - Detect special episodes in series to ignore them from new episodes Chg - History always tries to take the original version to not have multiple versions of the same season Fix - Updater failed because it couldn't update itself (for the fix you need to download the new updater)
This commit is contained in:
parent
76ddd9241a
commit
3e33843bc0
8 changed files with 197 additions and 73 deletions
|
|
@ -137,7 +137,7 @@ public class CrSeries(Crunchyroll crunInstance){
|
||||||
var s = result[season][key];
|
var s = result[season][key];
|
||||||
if (data?.S != null && s.Id != data.Value.S) continue;
|
if (data?.S != null && s.Id != data.Value.S) continue;
|
||||||
int fallbackIndex = 0;
|
int fallbackIndex = 0;
|
||||||
var seasonData = await GetSeasonDataById(s);
|
var seasonData = await GetSeasonDataById(s.Id);
|
||||||
if (seasonData.Data != null){
|
if (seasonData.Data != null){
|
||||||
|
|
||||||
if (crunInstance.CrunOptions.History){
|
if (crunInstance.CrunOptions.History){
|
||||||
|
|
@ -268,7 +268,7 @@ public class CrSeries(Crunchyroll crunInstance){
|
||||||
return crunchySeriesList;
|
return crunchySeriesList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<CrunchyEpisodeList> GetSeasonDataById(SeriesSearchItem item, bool log = false){
|
public async Task<CrunchyEpisodeList> GetSeasonDataById(string seasonID, bool log = false){
|
||||||
CrunchyEpisodeList episodeList = new CrunchyEpisodeList(){ Data = new List<CrunchyEpisode>(), Total = 0, Meta = new Meta() };
|
CrunchyEpisodeList episodeList = new CrunchyEpisodeList(){ Data = new List<CrunchyEpisode>(), Total = 0, Meta = new Meta() };
|
||||||
|
|
||||||
if (crunInstance.CmsToken?.Cms == null){
|
if (crunInstance.CmsToken?.Cms == null){
|
||||||
|
|
@ -277,7 +277,7 @@ public class CrSeries(Crunchyroll crunInstance){
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log){
|
if (log){
|
||||||
var showRequest = HttpClientReq.CreateRequestMessage($"{Api.Cms}/seasons/{item.Id}?preferred_audio_language=ja-JP", HttpMethod.Get, true, true, null);
|
var showRequest = HttpClientReq.CreateRequestMessage($"{Api.Cms}/seasons/{seasonID}?preferred_audio_language=ja-JP", HttpMethod.Get, true, true, null);
|
||||||
|
|
||||||
var response = await HttpClientReq.Instance.SendHttpRequest(showRequest);
|
var response = await HttpClientReq.Instance.SendHttpRequest(showRequest);
|
||||||
|
|
||||||
|
|
@ -290,7 +290,7 @@ public class CrSeries(Crunchyroll crunInstance){
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
|
|
||||||
var episodeRequest = new HttpRequestMessage(HttpMethod.Get, $"{Api.Cms}/seasons/{item.Id}/episodes?preferred_audio_language=ja-JP");
|
var episodeRequest = new HttpRequestMessage(HttpMethod.Get, $"{Api.Cms}/seasons/{seasonID}/episodes?preferred_audio_language=ja-JP");
|
||||||
|
|
||||||
episodeRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", crunInstance.Token?.access_token);
|
episodeRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", crunInstance.Token?.access_token);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace CRD.Downloader;
|
||||||
public class History(Crunchyroll crunInstance){
|
public class History(Crunchyroll crunInstance){
|
||||||
public async Task UpdateSeries(string seriesId, string? seasonId){
|
public async Task UpdateSeries(string seriesId, string? seasonId){
|
||||||
await crunInstance.CrAuth.RefreshToken(true);
|
await crunInstance.CrAuth.RefreshToken(true);
|
||||||
|
|
||||||
CrSeriesSearch? parsedSeries = await crunInstance.CrSeries.ParseSeriesById(seriesId, "ja");
|
CrSeriesSearch? parsedSeries = await crunInstance.CrSeries.ParseSeriesById(seriesId, "ja");
|
||||||
|
|
||||||
if (parsedSeries == null){
|
if (parsedSeries == null){
|
||||||
|
|
@ -35,7 +35,20 @@ public class History(Crunchyroll crunInstance){
|
||||||
foreach (var key in result[season].Keys){
|
foreach (var key in result[season].Keys){
|
||||||
var s = result[season][key];
|
var s = result[season][key];
|
||||||
if (!string.IsNullOrEmpty(seasonId) && s.Id != seasonId) continue;
|
if (!string.IsNullOrEmpty(seasonId) && s.Id != seasonId) continue;
|
||||||
var seasonData = await crunInstance.CrSeries.GetSeasonDataById(s);
|
|
||||||
|
var sId = s.Id;
|
||||||
|
if (s.Versions is{ Count: > 0 }){
|
||||||
|
foreach (var sVersion in s.Versions){
|
||||||
|
if (sVersion.Original == true){
|
||||||
|
if (sVersion.Guid != null){
|
||||||
|
sId = sVersion.Guid;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var seasonData = await crunInstance.CrSeries.GetSeasonDataById(sId);
|
||||||
UpdateWithSeasonData(seasonData);
|
UpdateWithSeasonData(seasonData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -107,7 +120,7 @@ public class History(Crunchyroll crunInstance){
|
||||||
|
|
||||||
historySeries.Seasons.Add(newSeason);
|
historySeries.Seasons.Add(newSeason);
|
||||||
|
|
||||||
historySeries.Seasons = historySeries.Seasons.OrderBy(s => s.SeasonNum).ToList();
|
historySeries.Seasons = historySeries.Seasons.OrderBy(s => s.SeasonNum != null ? int.Parse(s.SeasonNum) : 0).ToList();
|
||||||
}
|
}
|
||||||
historySeries.UpdateNewEpisodes();
|
historySeries.UpdateNewEpisodes();
|
||||||
} else{
|
} else{
|
||||||
|
|
@ -148,15 +161,24 @@ public class History(Crunchyroll crunInstance){
|
||||||
|
|
||||||
if (historySeason != null){
|
if (historySeason != null){
|
||||||
foreach (var crunchyEpisode in seasonData.Data){
|
foreach (var crunchyEpisode in seasonData.Data){
|
||||||
if (historySeason.EpisodesList.All(e => e.EpisodeId != crunchyEpisode.Id)){
|
|
||||||
|
var historyEpisode = historySeason.EpisodesList.Find(e => e.EpisodeId == crunchyEpisode.Id);
|
||||||
|
|
||||||
|
if (historyEpisode == null){
|
||||||
var newHistoryEpisode = new HistoryEpisode{
|
var newHistoryEpisode = new HistoryEpisode{
|
||||||
EpisodeTitle = crunchyEpisode.Title,
|
EpisodeTitle = crunchyEpisode.Title,
|
||||||
EpisodeId = crunchyEpisode.Id,
|
EpisodeId = crunchyEpisode.Id,
|
||||||
Episode = crunchyEpisode.Episode,
|
Episode = crunchyEpisode.Episode,
|
||||||
|
SpecialEpisode = !int.TryParse(crunchyEpisode.Episode, out _),
|
||||||
};
|
};
|
||||||
|
|
||||||
historySeason.EpisodesList.Add(newHistoryEpisode);
|
historySeason.EpisodesList.Add(newHistoryEpisode);
|
||||||
|
} else{
|
||||||
|
//Update existing episode
|
||||||
|
historyEpisode.EpisodeTitle = crunchyEpisode.Title;
|
||||||
|
historyEpisode.SpecialEpisode = !int.TryParse(crunchyEpisode.Episode, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
historySeason.EpisodesList.Sort(new NumericStringPropertyComparer());
|
historySeason.EpisodesList.Sort(new NumericStringPropertyComparer());
|
||||||
|
|
@ -167,7 +189,7 @@ public class History(Crunchyroll crunInstance){
|
||||||
|
|
||||||
historySeries.Seasons.Add(newSeason);
|
historySeries.Seasons.Add(newSeason);
|
||||||
|
|
||||||
historySeries.Seasons = historySeries.Seasons.OrderBy(s => s.SeasonNum).ToList();
|
historySeries.Seasons = historySeries.Seasons.OrderBy(s => s.SeasonNum != null ? int.Parse(s.SeasonNum) : 0).ToList();
|
||||||
}
|
}
|
||||||
historySeries.UpdateNewEpisodes();
|
historySeries.UpdateNewEpisodes();
|
||||||
} else{
|
} else{
|
||||||
|
|
@ -190,6 +212,7 @@ public class History(Crunchyroll crunInstance){
|
||||||
|
|
||||||
|
|
||||||
newHistorySeries.Seasons.Add(newSeason);
|
newHistorySeries.Seasons.Add(newSeason);
|
||||||
|
|
||||||
newHistorySeries.UpdateNewEpisodes();
|
newHistorySeries.UpdateNewEpisodes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -235,6 +258,7 @@ public class History(Crunchyroll crunInstance){
|
||||||
EpisodeTitle = crunchyEpisode.Title,
|
EpisodeTitle = crunchyEpisode.Title,
|
||||||
EpisodeId = crunchyEpisode.Id,
|
EpisodeId = crunchyEpisode.Id,
|
||||||
Episode = crunchyEpisode.Episode,
|
Episode = crunchyEpisode.Episode,
|
||||||
|
SpecialEpisode = !int.TryParse(crunchyEpisode.Episode, out _),
|
||||||
};
|
};
|
||||||
|
|
||||||
newSeason.EpisodesList.Add(newHistoryEpisode);
|
newSeason.EpisodesList.Add(newHistoryEpisode);
|
||||||
|
|
@ -255,6 +279,7 @@ public class History(Crunchyroll crunInstance){
|
||||||
EpisodeTitle = episode.Title,
|
EpisodeTitle = episode.Title,
|
||||||
EpisodeId = episode.Id,
|
EpisodeId = episode.Id,
|
||||||
Episode = episode.Episode,
|
Episode = episode.Episode,
|
||||||
|
SpecialEpisode = !int.TryParse(episode.Episode, out _),
|
||||||
};
|
};
|
||||||
|
|
||||||
newSeason.EpisodesList.Add(newHistoryEpisode);
|
newSeason.EpisodesList.Add(newHistoryEpisode);
|
||||||
|
|
@ -269,7 +294,7 @@ public class NumericStringPropertyComparer : IComparer<HistoryEpisode>{
|
||||||
if (int.TryParse(x.Episode, out int xInt) && int.TryParse(y.Episode, out int yInt)){
|
if (int.TryParse(x.Episode, out int xInt) && int.TryParse(y.Episode, out int yInt)){
|
||||||
return xInt.CompareTo(yInt);
|
return xInt.CompareTo(yInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to string comparison if not parseable as integers
|
// Fall back to string comparison if not parseable as integers
|
||||||
return String.Compare(x.Episode, y.Episode, StringComparison.Ordinal);
|
return String.Compare(x.Episode, y.Episode, StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
@ -328,7 +353,7 @@ public class HistorySeries : INotifyPropertyChanged{
|
||||||
|
|
||||||
// Iterate over the Episodes from the end to the beginning
|
// Iterate over the Episodes from the end to the beginning
|
||||||
for (int j = Seasons[i].EpisodesList.Count - 1; j >= 0 && !foundWatched; j--){
|
for (int j = Seasons[i].EpisodesList.Count - 1; j >= 0 && !foundWatched; j--){
|
||||||
if (!Seasons[i].EpisodesList[j].WasDownloaded){
|
if (!Seasons[i].EpisodesList[j].WasDownloaded && !Seasons[i].EpisodesList[j].SpecialEpisode){
|
||||||
count++;
|
count++;
|
||||||
} else{
|
} else{
|
||||||
foundWatched = true;
|
foundWatched = true;
|
||||||
|
|
@ -351,7 +376,7 @@ public class HistorySeries : INotifyPropertyChanged{
|
||||||
|
|
||||||
// Iterate over the Episodes from the end to the beginning
|
// Iterate over the Episodes from the end to the beginning
|
||||||
for (int j = Seasons[i].EpisodesList.Count - 1; j >= 0 && !foundWatched; j--){
|
for (int j = Seasons[i].EpisodesList.Count - 1; j >= 0 && !foundWatched; j--){
|
||||||
if (!Seasons[i].EpisodesList[j].WasDownloaded){
|
if (!Seasons[i].EpisodesList[j].WasDownloaded && !Seasons[i].EpisodesList[j].SpecialEpisode){
|
||||||
//ADD to download queue
|
//ADD to download queue
|
||||||
await Seasons[i].EpisodesList[j].DownloadEpisode();
|
await Seasons[i].EpisodesList[j].DownloadEpisode();
|
||||||
} else{
|
} else{
|
||||||
|
|
@ -419,8 +444,11 @@ public partial class HistoryEpisode : INotifyPropertyChanged{
|
||||||
[JsonProperty("episode_was_downloaded")]
|
[JsonProperty("episode_was_downloaded")]
|
||||||
public bool WasDownloaded{ get; set; }
|
public bool WasDownloaded{ get; set; }
|
||||||
|
|
||||||
public event PropertyChangedEventHandler? PropertyChanged;
|
[JsonProperty("episode_special_episode")]
|
||||||
|
public bool SpecialEpisode{ get; set; }
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler? PropertyChanged;
|
||||||
|
|
||||||
public void ToggleWasDownloaded(){
|
public void ToggleWasDownloaded(){
|
||||||
WasDownloaded = !WasDownloaded;
|
WasDownloaded = !WasDownloaded;
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(WasDownloaded)));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(WasDownloaded)));
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ public struct SeriesSearchItem{
|
||||||
[JsonProperty("season_number")] public int SeasonNumber{ get; set; }
|
[JsonProperty("season_number")] public int SeasonNumber{ get; set; }
|
||||||
public Dictionary<object, object> Images{ get; set; }
|
public Dictionary<object, object> Images{ get; set; }
|
||||||
[JsonProperty("mature_blocked")] public bool MatureBlocked{ get; set; }
|
[JsonProperty("mature_blocked")] public bool MatureBlocked{ get; set; }
|
||||||
public List<Version> Versions{ get; set; }
|
public List<Version>? Versions{ get; set; }
|
||||||
public string Title{ get; set; }
|
public string Title{ get; set; }
|
||||||
[JsonProperty("is_subbed")] public bool IsSubbed{ get; set; }
|
[JsonProperty("is_subbed")] public bool IsSubbed{ get; set; }
|
||||||
public string Id{ get; set; }
|
public string Id{ get; set; }
|
||||||
|
|
|
||||||
|
|
@ -4,59 +4,77 @@ using System.Linq;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using CRD.Downloader;
|
using CRD.Downloader;
|
||||||
|
using CRD.Utils;
|
||||||
using CRD.Views;
|
using CRD.Views;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace CRD.ViewModels;
|
namespace CRD.ViewModels;
|
||||||
|
|
||||||
public partial class HistoryPageViewModel : ViewModelBase{
|
public partial class HistoryPageViewModel : ViewModelBase{
|
||||||
|
|
||||||
public ObservableCollection<HistorySeries> Items{ get; }
|
public ObservableCollection<HistorySeries> Items{ get; }
|
||||||
[ObservableProperty] private bool? _showLoading = false;
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool? _showLoading = false;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public HistorySeries _selectedSeries;
|
public HistorySeries _selectedSeries;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public static bool _editMode;
|
||||||
|
|
||||||
public HistoryPageViewModel(){
|
public HistoryPageViewModel(){
|
||||||
Items = Crunchyroll.Instance.HistoryList;
|
Items = Crunchyroll.Instance.HistoryList;
|
||||||
|
|
||||||
foreach (var historySeries in Items){
|
foreach (var historySeries in Items){
|
||||||
if (historySeries.ThumbnailImage == null){
|
if (historySeries.ThumbnailImage == null){
|
||||||
historySeries.LoadImage();
|
historySeries.LoadImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
historySeries.UpdateNewEpisodes();
|
historySeries.UpdateNewEpisodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
partial void OnSelectedSeriesChanged(HistorySeries value){
|
partial void OnSelectedSeriesChanged(HistorySeries value){
|
||||||
Crunchyroll.Instance.SelectedSeries = value;
|
Crunchyroll.Instance.SelectedSeries = value;
|
||||||
MessageBus.Current.SendMessage(new NavigationMessage(typeof(SeriesPageViewModel),false,false));
|
MessageBus.Current.SendMessage(new NavigationMessage(typeof(SeriesPageViewModel), false, false));
|
||||||
_selectedSeries = null;
|
_selectedSeries = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
public void NavToSeries(){
|
|
||||||
MessageBus.Current.SendMessage(new NavigationMessage(typeof(SeriesPageViewModel),false,false));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public void RemoveSeries(string? seriesId){
|
||||||
|
|
||||||
|
HistorySeries? objectToRemove = Crunchyroll.Instance.HistoryList.ToList().Find(se => se.SeriesId == seriesId) ?? null;
|
||||||
|
if (objectToRemove != null) {
|
||||||
|
Crunchyroll.Instance.HistoryList.Remove(objectToRemove);
|
||||||
|
Items.Remove(objectToRemove);
|
||||||
|
}
|
||||||
|
CfgManager.WriteJsonToFile(CfgManager.PathCrHistory, Crunchyroll.Instance.HistoryList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public void NavToSeries(){
|
||||||
|
MessageBus.Current.SendMessage(new NavigationMessage(typeof(SeriesPageViewModel), false, false));
|
||||||
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async void RefreshAll(){
|
public async void RefreshAll(){
|
||||||
for (int i = 0; i < Items.Count; i++) {
|
for (int i = 0; i < Items.Count; i++){
|
||||||
ShowLoading = true;
|
ShowLoading = true;
|
||||||
await Items[i].FetchData("");
|
await Items[i].FetchData("");
|
||||||
Items[i].UpdateNewEpisodes();
|
Items[i].UpdateNewEpisodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowLoading = false;
|
ShowLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async void AddMissingToQueue(){
|
public async void AddMissingToQueue(){
|
||||||
for (int i = 0; i < Items.Count; i++) {
|
for (int i = 0; i < Items.Count; i++){
|
||||||
await Items[i].AddNewMissingToDownloads();
|
await Items[i].AddNewMissingToDownloads();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowLoading = false;
|
ShowLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -23,9 +24,25 @@ public partial class MainWindowViewModel : ViewModelBase{
|
||||||
_faTheme = App.Current.Styles[0] as FluentAvaloniaTheme;
|
_faTheme = App.Current.Styles[0] as FluentAvaloniaTheme;
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
|
CleanUpOldUpdater();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CleanUpOldUpdater() {
|
||||||
|
string backupFilePath = Path.Combine(Directory.GetCurrentDirectory(), "Updater.exe.bak");
|
||||||
|
|
||||||
|
if (File.Exists(backupFilePath)) {
|
||||||
|
try {
|
||||||
|
File.Delete(backupFilePath);
|
||||||
|
Console.WriteLine($"Deleted old updater file: {backupFilePath}");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Console.WriteLine($"Failed to delete old updater file: {ex.Message}");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Console.WriteLine("No old updater file found to delete.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public async void Init(){
|
public async void Init(){
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Threading.Tasks;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using CRD.Downloader;
|
using CRD.Downloader;
|
||||||
|
using CRD.Utils;
|
||||||
using CRD.Views;
|
using CRD.Views;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
|
|
@ -14,6 +15,9 @@ public partial class SeriesPageViewModel : ViewModelBase{
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public HistorySeries _selectedSeries;
|
public HistorySeries _selectedSeries;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public static bool _editMode;
|
||||||
|
|
||||||
public SeriesPageViewModel(){
|
public SeriesPageViewModel(){
|
||||||
_selectedSeries = Crunchyroll.Instance.SelectedSeries;
|
_selectedSeries = Crunchyroll.Instance.SelectedSeries;
|
||||||
|
|
||||||
|
|
@ -29,6 +33,19 @@ public partial class SeriesPageViewModel : ViewModelBase{
|
||||||
MessageBus.Current.SendMessage(new NavigationMessage(typeof(SeriesPageViewModel),false,true));
|
MessageBus.Current.SendMessage(new NavigationMessage(typeof(SeriesPageViewModel),false,true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public void RemoveSeason(string? season){
|
||||||
|
|
||||||
|
HistorySeason? objectToRemove = SelectedSeries.Seasons.Find(se => se.SeasonId == season) ?? null;
|
||||||
|
if (objectToRemove != null) {
|
||||||
|
SelectedSeries.Seasons.Remove(objectToRemove);
|
||||||
|
}
|
||||||
|
CfgManager.WriteJsonToFile(CfgManager.PathCrHistory, Crunchyroll.Instance.HistoryList);
|
||||||
|
MessageBus.Current.SendMessage(new NavigationMessage(typeof(SeriesPageViewModel),false,true));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public void NavBack(){
|
public void NavBack(){
|
||||||
SelectedSeries.UpdateNewEpisodes();
|
SelectedSeries.UpdateNewEpisodes();
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
xmlns:vm="clr-namespace:CRD.ViewModels"
|
xmlns:vm="clr-namespace:CRD.ViewModels"
|
||||||
xmlns:ui="clr-namespace:CRD.Utils.UI"
|
xmlns:ui="clr-namespace:CRD.Utils.UI"
|
||||||
|
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
x:DataType="vm:HistoryPageViewModel"
|
x:DataType="vm:HistoryPageViewModel"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="CRD.Views.HistoryPageView">
|
x:Class="CRD.Views.HistoryPageView">
|
||||||
|
|
@ -23,6 +24,7 @@
|
||||||
<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal" Margin="20 0 0 0 ">
|
<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal" Margin="20 0 0 0 ">
|
||||||
<Button Command="{Binding RefreshAll}" Margin="10">Refresh All</Button>
|
<Button Command="{Binding RefreshAll}" Margin="10">Refresh All</Button>
|
||||||
<Button Command="{Binding AddMissingToQueue}" Margin="10">Add To Queue</Button>
|
<Button Command="{Binding AddMissingToQueue}" Margin="10">Add To Queue</Button>
|
||||||
|
<ToggleButton IsChecked="{Binding EditMode}" Margin="10">Edit</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<Grid Grid.Row="1" Grid.Column="0">
|
<Grid Grid.Row="1" Grid.Column="0">
|
||||||
|
|
@ -44,20 +46,43 @@
|
||||||
</ListBox.ItemsPanel>
|
</ListBox.ItemsPanel>
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" MaxWidth="250" Width="250"
|
|
||||||
MaxHeight="400" Height="400" Margin="5">
|
<Grid>
|
||||||
<Grid>
|
|
||||||
<Image Source="{Binding ThumbnailImage}" Width="240" Height="360"></Image>
|
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" MaxWidth="250" Width="250"
|
||||||
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Right" IsVisible="{Binding NewEpisodes, Converter={StaticResource UiIntToVisibilityConverter}}">
|
MaxHeight="400" Height="400" Margin="5">
|
||||||
<TextBlock VerticalAlignment="Center" TextAlignment="Center" Margin="0 0 5 0" Width="30" Height="30"
|
<Grid>
|
||||||
Background="Black" Opacity="0.8" Text="{Binding NewEpisodes}"
|
<Image Source="{Binding ThumbnailImage}" Width="240" Height="360"></Image>
|
||||||
Padding="0,5,0,0"/>
|
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Right" IsVisible="{Binding NewEpisodes, Converter={StaticResource UiIntToVisibilityConverter}}">
|
||||||
</StackPanel>
|
<TextBlock VerticalAlignment="Center" TextAlignment="Center" Margin="0 0 5 0" Width="30" Height="30"
|
||||||
</Grid>
|
Background="Black" Opacity="0.8" Text="{Binding NewEpisodes}"
|
||||||
<TextBlock HorizontalAlignment="Center" Text="{Binding SeriesTitle}" TextWrapping="NoWrap"
|
Padding="0,5,0,0"/>
|
||||||
Margin="4,0,0,0">
|
</StackPanel>
|
||||||
</TextBlock>
|
</Grid>
|
||||||
</StackPanel>
|
<TextBlock HorizontalAlignment="Center" Text="{Binding SeriesTitle}" TextWrapping="NoWrap"
|
||||||
|
Margin="4,0,0,0">
|
||||||
|
</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" MaxWidth="250" Width="250"
|
||||||
|
MaxHeight="400" Height="400" Background="#90000000" IsVisible="{Binding $parent[UserControl].((vm:HistoryPageViewModel)DataContext).EditMode}">
|
||||||
|
<Button MaxWidth="250" Width="250" MaxHeight="400" Height="400" FontStyle="Italic"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Command="{Binding $parent[UserControl].((vm:HistoryPageViewModel)DataContext).RemoveSeries}"
|
||||||
|
CommandParameter="{Binding SeriesId}"
|
||||||
|
>
|
||||||
|
<ToolTip.Tip>
|
||||||
|
<TextBlock Text="Remove Series" FontSize="15" />
|
||||||
|
</ToolTip.Tip>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<controls:SymbolIcon Symbol="Delete" FontSize="32" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListBox.ItemTemplate>
|
</ListBox.ItemTemplate>
|
||||||
</ListBox>
|
</ListBox>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
x:DataType="vm:SeriesPageViewModel"
|
x:DataType="vm:SeriesPageViewModel"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="CRD.Views.SeriesPageView">
|
x:Class="CRD.Views.SeriesPageView">
|
||||||
|
|
||||||
<Grid Margin="10">
|
<Grid Margin="10">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
|
|
@ -28,26 +28,24 @@
|
||||||
Height="360">
|
Height="360">
|
||||||
</Image>
|
</Image>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Grid Grid.Row="1" Grid.Column="1">
|
<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>
|
|
||||||
<Button Grid.Row="3" Command="{Binding UpdateData}" Margin="0 0 0 10">Fetch Series</Button>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<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="Horizontal">
|
||||||
|
<Button Command="{Binding UpdateData}" Margin="0 0 5 10">Fetch Series</Button>
|
||||||
|
<ToggleButton IsChecked="{Binding EditMode}" Margin="0 0 0 10">Edit</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
<ScrollViewer Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2">
|
<ScrollViewer Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2">
|
||||||
|
|
@ -58,11 +56,10 @@
|
||||||
<controls:SettingsExpander
|
<controls:SettingsExpander
|
||||||
Header="{Binding CombinedProperty}"
|
Header="{Binding CombinedProperty}"
|
||||||
ItemsSource="{Binding EpisodesList}"
|
ItemsSource="{Binding EpisodesList}"
|
||||||
|
|
||||||
Description="{Binding SeasonTitle}"
|
Description="{Binding SeasonTitle}"
|
||||||
IsExpanded="False">
|
IsExpanded="False">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<controls:SettingsExpander.ItemTemplate>
|
<controls:SettingsExpander.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
|
|
@ -83,20 +80,28 @@
|
||||||
|
|
||||||
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
|
<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].((downloader:HistorySeason)DataContext).UpdateDownloaded}" CommandParameter="{Binding EpisodeId}">
|
<Button Width="34" Height="34" Margin="0 0 10 0" Background="Transparent"
|
||||||
<Grid >
|
BorderThickness="0" CornerRadius="50"
|
||||||
|
IsVisible="{Binding !WasDownloaded}"
|
||||||
|
Command="{Binding $parent[controls:SettingsExpander].((downloader:HistorySeason)DataContext).UpdateDownloaded}"
|
||||||
|
CommandParameter="{Binding EpisodeId}">
|
||||||
|
<Grid>
|
||||||
<Ellipse Width="25" Height="25" Fill="Gray" />
|
<Ellipse Width="25" Height="25" Fill="Gray" />
|
||||||
<controls:SymbolIcon Symbol="Checkmark" FontSize="18" />
|
<controls:SymbolIcon Symbol="Checkmark" FontSize="18" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Button>
|
</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].((downloader:HistorySeason)DataContext).UpdateDownloaded}" CommandParameter="{Binding EpisodeId}">
|
<Button Width="34" Height="34" Margin="0 0 10 0" Background="Transparent"
|
||||||
<Grid >
|
BorderThickness="0" CornerRadius="50"
|
||||||
|
IsVisible="{Binding WasDownloaded}"
|
||||||
|
Command="{Binding $parent[controls:SettingsExpander].((downloader:HistorySeason)DataContext).UpdateDownloaded}"
|
||||||
|
CommandParameter="{Binding EpisodeId}">
|
||||||
|
<Grid>
|
||||||
<Ellipse Width="25" Height="25" Fill="#21a556" />
|
<Ellipse Width="25" Height="25" Fill="#21a556" />
|
||||||
<controls:SymbolIcon Symbol="Checkmark" FontSize="18" />
|
<controls:SymbolIcon Symbol="Checkmark" FontSize="18" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button Margin="0 0 5 0" FontStyle="Italic" HorizontalAlignment="Right"
|
<Button Margin="0 0 5 0" FontStyle="Italic" HorizontalAlignment="Right"
|
||||||
VerticalAlignment="Center" Command="{Binding DownloadEpisode}">
|
VerticalAlignment="Center" Command="{Binding DownloadEpisode}">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
|
|
@ -114,8 +119,10 @@
|
||||||
<TextBlock Text="{Binding DownloadedEpisodes}" VerticalAlignment="Center"></TextBlock>
|
<TextBlock Text="{Binding DownloadedEpisodes}" VerticalAlignment="Center"></TextBlock>
|
||||||
<TextBlock Text="/" VerticalAlignment="Center"></TextBlock>
|
<TextBlock Text="/" VerticalAlignment="Center"></TextBlock>
|
||||||
<TextBlock Text="{Binding EpisodesList.Count}" VerticalAlignment="Center"></TextBlock>
|
<TextBlock Text="{Binding EpisodesList.Count}" VerticalAlignment="Center"></TextBlock>
|
||||||
<Button Margin="10 0 0 0" FontStyle="Italic"
|
<Button Margin="10 0 0 0" FontStyle="Italic"
|
||||||
VerticalAlignment="Center" Command="{Binding $parent[UserControl].((vm:SeriesPageViewModel)DataContext).UpdateData}" CommandParameter="{Binding SeasonId}" >
|
VerticalAlignment="Center"
|
||||||
|
Command="{Binding $parent[UserControl].((vm:SeriesPageViewModel)DataContext).UpdateData}"
|
||||||
|
CommandParameter="{Binding SeasonId}">
|
||||||
<ToolTip.Tip>
|
<ToolTip.Tip>
|
||||||
<TextBlock Text="Fetch Season" FontSize="15" />
|
<TextBlock Text="Fetch Season" FontSize="15" />
|
||||||
</ToolTip.Tip>
|
</ToolTip.Tip>
|
||||||
|
|
@ -123,6 +130,18 @@
|
||||||
<controls:SymbolIcon Symbol="Refresh" FontSize="18" />
|
<controls:SymbolIcon Symbol="Refresh" FontSize="18" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Button>
|
</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>
|
</StackPanel>
|
||||||
</controls:SettingsExpander.Footer>
|
</controls:SettingsExpander.Footer>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue