Add - Downloader remembers the Window Size and Position https://github.com/Crunchy-DL/Crunchy-Downloader/discussions/78
Chg - Adjusted the subscription check if the end date has passed but crunchyroll still thinks it's active https://github.com/Crunchy-DL/Crunchy-Downloader/issues/80
This commit is contained in:
parent
6aa10cb2c2
commit
9c6ad2d7e8
|
@ -44,7 +44,6 @@ public class CrAuth{
|
||||||
PreferredContentAudioLanguage = "ja-JP",
|
PreferredContentAudioLanguage = "ja-JP",
|
||||||
PreferredContentSubtitleLanguage = "de-DE"
|
PreferredContentSubtitleLanguage = "de-DE"
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void JsonTokenToFileAndVariable(string content){
|
private void JsonTokenToFileAndVariable(string content){
|
||||||
|
@ -52,7 +51,7 @@ public class CrAuth{
|
||||||
|
|
||||||
|
|
||||||
if (crunInstance.Token != null && crunInstance.Token.expires_in != null){
|
if (crunInstance.Token != null && crunInstance.Token.expires_in != null){
|
||||||
crunInstance.Token.expires = DateTime.Now.AddMilliseconds((double)crunInstance.Token.expires_in);
|
crunInstance.Token.expires = DateTime.Now.AddSeconds((double)crunInstance.Token.expires_in);
|
||||||
|
|
||||||
CfgManager.WriteTokenToYamlFile(crunInstance.Token, CfgManager.PathCrToken);
|
CfgManager.WriteTokenToYamlFile(crunInstance.Token, CfgManager.PathCrToken);
|
||||||
}
|
}
|
||||||
|
@ -82,7 +81,8 @@ public class CrAuth{
|
||||||
if (response.ResponseContent.Contains("invalid_credentials")){
|
if (response.ResponseContent.Contains("invalid_credentials")){
|
||||||
MessageBus.Current.SendMessage(new ToastMessage($"Failed to login - because of invalid login credentials", ToastType.Error, 10));
|
MessageBus.Current.SendMessage(new ToastMessage($"Failed to login - because of invalid login credentials", ToastType.Error, 10));
|
||||||
} else{
|
} else{
|
||||||
MessageBus.Current.SendMessage(new ToastMessage($"Failed to login - {response.ResponseContent.Substring(0,response.ResponseContent.Length < 200 ? response.ResponseContent.Length : 200)}", ToastType.Error, 10));
|
MessageBus.Current.SendMessage(new ToastMessage($"Failed to login - {response.ResponseContent.Substring(0, response.ResponseContent.Length < 200 ? response.ResponseContent.Length : 200)}",
|
||||||
|
ToastType.Error, 10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,20 +119,27 @@ public class CrAuth{
|
||||||
if (subsc is{ SubscriptionProducts:{ Count: 0 }, ThirdPartySubscriptionProducts.Count: > 0 }){
|
if (subsc is{ SubscriptionProducts:{ Count: 0 }, ThirdPartySubscriptionProducts.Count: > 0 }){
|
||||||
var thirdPartySub = subsc.ThirdPartySubscriptionProducts.First();
|
var thirdPartySub = subsc.ThirdPartySubscriptionProducts.First();
|
||||||
var expiration = thirdPartySub.InGrace ? thirdPartySub.InGraceExpirationDate : thirdPartySub.ExpirationDate;
|
var expiration = thirdPartySub.InGrace ? thirdPartySub.InGraceExpirationDate : thirdPartySub.ExpirationDate;
|
||||||
var remaining = expiration - DateTime.UtcNow;
|
var remaining = expiration - DateTime.Now;
|
||||||
crunInstance.Profile.HasPremium = remaining > TimeSpan.Zero;
|
crunInstance.Profile.HasPremium = true;
|
||||||
|
if (crunInstance.Profile.Subscription != null){
|
||||||
crunInstance.Profile.Subscription.IsActive = remaining > TimeSpan.Zero;
|
crunInstance.Profile.Subscription.IsActive = remaining > TimeSpan.Zero;
|
||||||
crunInstance.Profile.Subscription.NextRenewalDate = expiration;
|
crunInstance.Profile.Subscription.NextRenewalDate = expiration;
|
||||||
|
}
|
||||||
} else if (subsc is{ SubscriptionProducts:{ Count: 0 }, NonrecurringSubscriptionProducts.Count: > 0 }){
|
} else if (subsc is{ SubscriptionProducts:{ Count: 0 }, NonrecurringSubscriptionProducts.Count: > 0 }){
|
||||||
var nonRecurringSub = subsc.NonrecurringSubscriptionProducts.First();
|
var nonRecurringSub = subsc.NonrecurringSubscriptionProducts.First();
|
||||||
var remaining = nonRecurringSub.EndDate - DateTime.UtcNow;
|
var remaining = nonRecurringSub.EndDate - DateTime.Now;
|
||||||
crunInstance.Profile.HasPremium = remaining > TimeSpan.Zero;
|
crunInstance.Profile.HasPremium = true;
|
||||||
|
if (crunInstance.Profile.Subscription != null){
|
||||||
crunInstance.Profile.Subscription.IsActive = remaining > TimeSpan.Zero;
|
crunInstance.Profile.Subscription.IsActive = remaining > TimeSpan.Zero;
|
||||||
crunInstance.Profile.Subscription.NextRenewalDate = nonRecurringSub.EndDate;
|
crunInstance.Profile.Subscription.NextRenewalDate = nonRecurringSub.EndDate;
|
||||||
|
}
|
||||||
} else if (subsc is{ SubscriptionProducts:{ Count: 0 }, FunimationSubscriptions.Count: > 0 }){
|
} else if (subsc is{ SubscriptionProducts:{ Count: 0 }, FunimationSubscriptions.Count: > 0 }){
|
||||||
crunInstance.Profile.HasPremium = true;
|
crunInstance.Profile.HasPremium = true;
|
||||||
|
} else if (subsc is{ SubscriptionProducts.Count: > 0 }){
|
||||||
|
crunInstance.Profile.HasPremium = true;
|
||||||
} else{
|
} else{
|
||||||
crunInstance.Profile.HasPremium = subsc.IsActive;
|
crunInstance.Profile.HasPremium = false;
|
||||||
|
Console.Error.WriteLine($"No subscription available:\n {JsonConvert.SerializeObject(subsc, Formatting.Indented)} ");
|
||||||
}
|
}
|
||||||
} else{
|
} else{
|
||||||
crunInstance.Profile.HasPremium = false;
|
crunInstance.Profile.HasPremium = false;
|
||||||
|
@ -175,7 +182,6 @@ public class CrAuth{
|
||||||
|
|
||||||
await GetProfile();
|
await GetProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RefreshToken(bool needsToken){
|
public async Task RefreshToken(bool needsToken){
|
||||||
|
@ -213,7 +219,5 @@ public class CrAuth{
|
||||||
} else{
|
} else{
|
||||||
Console.Error.WriteLine("Refresh Token Auth Failed");
|
Console.Error.WriteLine("Refresh Token Auth Failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -59,7 +59,7 @@ public class CrEpisode(){
|
||||||
CrunchyRollEpisodeData episode = new CrunchyRollEpisodeData();
|
CrunchyRollEpisodeData episode = new CrunchyRollEpisodeData();
|
||||||
|
|
||||||
if (crunInstance.CrunOptions.History && updateHistory){
|
if (crunInstance.CrunOptions.History && updateHistory){
|
||||||
await crunInstance.History.UpdateWithEpisode(dlEpisode);
|
await crunInstance.History.UpdateWithSeasonData(new List<CrunchyEpisode>(){dlEpisode});
|
||||||
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == dlEpisode.SeriesId);
|
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == dlEpisode.SeriesId);
|
||||||
if (historySeries != null){
|
if (historySeries != null){
|
||||||
CrunchyrollManager.Instance.History.MatchHistorySeriesWithSonarr(false);
|
CrunchyrollManager.Instance.History.MatchHistorySeriesWithSonarr(false);
|
||||||
|
|
|
@ -16,26 +16,6 @@ namespace CRD.Downloader.Crunchyroll;
|
||||||
public class CrSeries(){
|
public class CrSeries(){
|
||||||
private readonly CrunchyrollManager crunInstance = CrunchyrollManager.Instance;
|
private readonly CrunchyrollManager crunInstance = CrunchyrollManager.Instance;
|
||||||
|
|
||||||
public async Task<List<CrunchyEpMeta>> DownloadFromSeriesId(string id, CrunchyMultiDownload data){
|
|
||||||
var series = await ListSeriesId(id, "", data);
|
|
||||||
|
|
||||||
if (series != null){
|
|
||||||
var selected = ItemSelectMultiDub(series.Value.Data, data.DubLang, data.But, data.AllEpisodes, data.E);
|
|
||||||
|
|
||||||
foreach (var crunchyEpMeta in selected.Values){
|
|
||||||
if (crunchyEpMeta.Data == null) continue;
|
|
||||||
var languages = crunchyEpMeta.Data.Select((a) =>
|
|
||||||
$" {a.Lang?.Name ?? "Unknown Language"}");
|
|
||||||
|
|
||||||
Console.WriteLine($"[S{crunchyEpMeta.Season}E{crunchyEpMeta.EpisodeNumber} - {crunchyEpMeta.EpisodeTitle} [{string.Join(", ", languages)}]");
|
|
||||||
}
|
|
||||||
|
|
||||||
return selected.Values.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new List<CrunchyEpMeta>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, CrunchyEpMeta> ItemSelectMultiDub(Dictionary<string, EpisodeAndLanguage> eps, List<string> dubLang, bool? but, bool? all, List<string>? e){
|
public Dictionary<string, CrunchyEpMeta> ItemSelectMultiDub(Dictionary<string, EpisodeAndLanguage> eps, List<string> dubLang, bool? but, bool? all, List<string>? e){
|
||||||
var ret = new Dictionary<string, CrunchyEpMeta>();
|
var ret = new Dictionary<string, CrunchyEpMeta>();
|
||||||
|
|
||||||
|
@ -143,26 +123,32 @@ public class CrSeries(){
|
||||||
|
|
||||||
CrSeriesSearch? parsedSeries = await ParseSeriesById(id, crLocale); // one piece - GRMG8ZQZR
|
CrSeriesSearch? parsedSeries = await ParseSeriesById(id, crLocale); // one piece - GRMG8ZQZR
|
||||||
|
|
||||||
if (parsedSeries == null){
|
if (parsedSeries == null || parsedSeries.Data == null){
|
||||||
Console.Error.WriteLine("Parse Data Invalid");
|
Console.Error.WriteLine("Parse Data Invalid");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = ParseSeriesResult(parsedSeries);
|
// var result = ParseSeriesResult(parsedSeries);
|
||||||
Dictionary<string, EpisodeAndLanguage> episodes = new Dictionary<string, EpisodeAndLanguage>();
|
Dictionary<string, EpisodeAndLanguage> episodes = new Dictionary<string, EpisodeAndLanguage>();
|
||||||
|
|
||||||
|
if (crunInstance.CrunOptions.History){
|
||||||
|
crunInstance.History.CRUpdateSeries(id,"");
|
||||||
|
}
|
||||||
|
|
||||||
foreach (int season in result.Keys){
|
var cachedSeasonID = "";
|
||||||
foreach (var key in result[season].Keys){
|
var seasonData = new CrunchyEpisodeList();
|
||||||
var s = result[season][key];
|
|
||||||
|
foreach (var s in parsedSeries.Data){
|
||||||
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.Id, "");
|
if (cachedSeasonID != s.Id){
|
||||||
if (seasonData.Data != null){
|
seasonData = await GetSeasonDataById(s.Id, "");
|
||||||
if (crunInstance.CrunOptions.History){
|
cachedSeasonID = s.Id;
|
||||||
crunInstance.History.UpdateWithSeasonData(seasonData, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (seasonData.Data != null){
|
||||||
|
|
||||||
|
|
||||||
foreach (var episode in seasonData.Data){
|
foreach (var episode in seasonData.Data){
|
||||||
// Prepare the episode array
|
// Prepare the episode array
|
||||||
EpisodeAndLanguage item;
|
EpisodeAndLanguage item;
|
||||||
|
@ -205,7 +191,6 @@ public class CrSeries(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (crunInstance.CrunOptions.History){
|
if (crunInstance.CrunOptions.History){
|
||||||
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == id);
|
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == id);
|
||||||
|
|
|
@ -22,25 +22,20 @@ public class History(){
|
||||||
public async Task CRUpdateSeries(string seriesId, string? seasonId){
|
public async Task CRUpdateSeries(string seriesId, string? seasonId){
|
||||||
await crunInstance.CrAuth.RefreshToken(true);
|
await crunInstance.CrAuth.RefreshToken(true);
|
||||||
|
|
||||||
CrSeriesSearch? parsedSeries = await crunInstance.CrSeries.ParseSeriesById(seriesId, "ja-JP", true);
|
CrSeriesSearch? parsedSeries = await crunInstance.CrSeries.ParseSeriesById(seriesId, "en-US", true);
|
||||||
|
|
||||||
if (parsedSeries == null){
|
if (parsedSeries == null){
|
||||||
Console.Error.WriteLine("Parse Data Invalid");
|
Console.Error.WriteLine("Parse Data Invalid");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = crunInstance.CrSeries.ParseSeriesResult(parsedSeries);
|
if (parsedSeries.Data != null){
|
||||||
Dictionary<string, EpisodeAndLanguage> episodes = new Dictionary<string, EpisodeAndLanguage>();
|
foreach (var s in parsedSeries.Data){
|
||||||
|
|
||||||
foreach (int season in result.Keys){
|
|
||||||
foreach (var key in result[season].Keys){
|
|
||||||
var s = result[season][key];
|
|
||||||
if (!string.IsNullOrEmpty(seasonId) && s.Id != seasonId) continue;
|
if (!string.IsNullOrEmpty(seasonId) && s.Id != seasonId) continue;
|
||||||
|
|
||||||
var sId = s.Id;
|
var sId = s.Id;
|
||||||
if (s.Versions is{ Count: > 0 }){
|
if (s.Versions is{ Count: > 0 }){
|
||||||
foreach (var sVersion in s.Versions){
|
foreach (var sVersion in s.Versions.Where(sVersion => sVersion.Original == true)){
|
||||||
if (sVersion.Original == true){
|
|
||||||
if (sVersion.Guid != null){
|
if (sVersion.Guid != null){
|
||||||
sId = sVersion.Guid;
|
sId = sVersion.Guid;
|
||||||
}
|
}
|
||||||
|
@ -48,13 +43,12 @@ public class History(){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var seasonData = await crunInstance.CrSeries.GetSeasonDataById(sId, string.IsNullOrEmpty(crunInstance.CrunOptions.HistoryLang) ? crunInstance.DefaultLocale : crunInstance.CrunOptions.HistoryLang, true);
|
var seasonData = await crunInstance.CrSeries.GetSeasonDataById(sId, string.IsNullOrEmpty(crunInstance.CrunOptions.HistoryLang) ? crunInstance.DefaultLocale : crunInstance.CrunOptions.HistoryLang, true);
|
||||||
await UpdateWithSeasonData(seasonData);
|
if (seasonData.Data != null) await UpdateWithSeasonData(seasonData.Data);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
|
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
|
||||||
|
|
||||||
if (historySeries != null){
|
if (historySeries != null){
|
||||||
|
@ -63,6 +57,7 @@ public class History(){
|
||||||
CfgManager.UpdateHistoryFile();
|
CfgManager.UpdateHistoryFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void SetAsDownloaded(string? seriesId, string? seasonId, string episodeId){
|
public void SetAsDownloaded(string? seriesId, string? seasonId, string episodeId){
|
||||||
|
@ -212,116 +207,43 @@ public class History(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task UpdateWithEpisode(CrunchyEpisode episodeParam){
|
public async Task UpdateWithSeasonData(List<CrunchyEpisode>? episodeList, bool skippVersionCheck = true){
|
||||||
var episode = episodeParam;
|
if (episodeList != null){
|
||||||
|
|
||||||
if (episode.Versions != null){
|
|
||||||
var version = episode.Versions.Find(a => a.Original);
|
|
||||||
if (version.AudioLocale != episode.AudioLocale){
|
|
||||||
var crEpisode = await crunInstance.CrEpisode.ParseEpisodeById(version.Guid, "");
|
|
||||||
if (crEpisode != null){
|
|
||||||
episode = crEpisode.Value;
|
|
||||||
} else{
|
|
||||||
MessageBus.Current.SendMessage(new ToastMessage($"Couldn't update download History", ToastType.Warning, 1));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (historySeason != null){
|
|
||||||
historySeason.SeasonTitle = episode.SeasonTitle;
|
|
||||||
historySeason.SeasonNum = Helpers.ExtractNumberAfterS(episode.Identifier) ?? episode.SeasonNumber + "";
|
|
||||||
historySeason.SpecialSeason = CheckStringForSpecial(episode.Identifier);
|
|
||||||
if (historySeason.EpisodesList.All(e => e.EpisodeId != episode.Id)){
|
|
||||||
var newHistoryEpisode = new HistoryEpisode{
|
|
||||||
EpisodeTitle = episode.Identifier.Contains("|M|") ? episode.SeasonTitle : episode.Title,
|
|
||||||
EpisodeDescription = episode.Description,
|
|
||||||
EpisodeId = episode.Id,
|
|
||||||
Episode = episode.Episode,
|
|
||||||
EpisodeSeasonNum = Helpers.ExtractNumberAfterS(episode.Identifier) ?? episode.SeasonNumber + "",
|
|
||||||
SpecialEpisode = !int.TryParse(episode.Episode, out _),
|
|
||||||
};
|
|
||||||
|
|
||||||
historySeason.EpisodesList.Add(newHistoryEpisode);
|
|
||||||
|
|
||||||
historySeason.EpisodesList.Sort(new NumericStringPropertyComparer());
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
var newSeason = NewHistorySeason(episode);
|
|
||||||
|
|
||||||
historySeries.Seasons.Add(newSeason);
|
|
||||||
newSeason.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
historySeries.UpdateNewEpisodes();
|
|
||||||
} else{
|
|
||||||
historySeries = new HistorySeries{
|
|
||||||
SeriesTitle = episode.SeriesTitle,
|
|
||||||
SeriesId = episode.SeriesId,
|
|
||||||
Seasons =[],
|
|
||||||
HistorySeriesAddDate = DateTime.Now,
|
|
||||||
};
|
|
||||||
crunInstance.HistoryList.Add(historySeries);
|
|
||||||
var newSeason = NewHistorySeason(episode);
|
|
||||||
|
|
||||||
await RefreshSeriesData(seriesId, historySeries);
|
|
||||||
|
|
||||||
historySeries.Seasons.Add(newSeason);
|
|
||||||
historySeries.UpdateNewEpisodes();
|
|
||||||
historySeries.Init();
|
|
||||||
newSeason.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
SortItems();
|
|
||||||
SortSeasons(historySeries);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task UpdateWithSeasonData(CrunchyEpisodeList seasonData, bool skippVersionCheck = true){
|
|
||||||
if (seasonData.Data != null){
|
|
||||||
if (!skippVersionCheck){
|
if (!skippVersionCheck){
|
||||||
if (seasonData.Data.First().Versions != null){
|
var episodeVersions = episodeList.First().Versions;
|
||||||
var version = seasonData.Data.First().Versions.Find(a => a.Original);
|
if (episodeVersions != null){
|
||||||
if (version.AudioLocale != seasonData.Data.First().AudioLocale){
|
var version = episodeVersions.Find(a => a.Original);
|
||||||
CRUpdateSeries(seasonData.Data.First().SeriesId, version.SeasonGuid);
|
if (version.AudioLocale != episodeList.First().AudioLocale){
|
||||||
|
await CRUpdateSeries(episodeList.First().SeriesId, version.SeasonGuid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else{
|
} else{
|
||||||
CRUpdateSeries(seasonData.Data.First().SeriesId, "");
|
await CRUpdateSeries(episodeList.First().SeriesId, "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var firstEpisode = seasonData.Data.First();
|
var firstEpisode = episodeList.First();
|
||||||
var seriesId = firstEpisode.SeriesId;
|
var seriesId = firstEpisode.SeriesId;
|
||||||
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
|
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
|
||||||
if (historySeries != null){
|
if (historySeries != null){
|
||||||
historySeries.HistorySeriesAddDate ??= DateTime.Now;
|
historySeries.HistorySeriesAddDate ??= DateTime.Now;
|
||||||
|
|
||||||
var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == firstEpisode.SeasonId);
|
|
||||||
|
|
||||||
await RefreshSeriesData(seriesId, historySeries);
|
await RefreshSeriesData(seriesId, historySeries);
|
||||||
|
|
||||||
|
var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == firstEpisode.SeasonId);
|
||||||
|
|
||||||
if (historySeason != null){
|
if (historySeason != null){
|
||||||
historySeason.SeasonTitle = firstEpisode.SeasonTitle;
|
historySeason.SeasonTitle = firstEpisode.SeasonTitle;
|
||||||
historySeason.SeasonNum = Helpers.ExtractNumberAfterS(firstEpisode.Identifier) ?? firstEpisode.SeasonNumber + "";
|
historySeason.SeasonNum = Helpers.ExtractNumberAfterS(firstEpisode.Identifier) ?? firstEpisode.SeasonNumber + "";
|
||||||
historySeason.SpecialSeason = CheckStringForSpecial(firstEpisode.Identifier);
|
historySeason.SpecialSeason = CheckStringForSpecial(firstEpisode.Identifier);
|
||||||
foreach (var crunchyEpisode in seasonData.Data){
|
foreach (var crunchyEpisode in episodeList){
|
||||||
var historyEpisode = historySeason.EpisodesList.Find(e => e.EpisodeId == crunchyEpisode.Id);
|
var historyEpisode = historySeason.EpisodesList.Find(e => e.EpisodeId == crunchyEpisode.Id);
|
||||||
|
|
||||||
if (historyEpisode == null){
|
if (historyEpisode == null){
|
||||||
var newHistoryEpisode = new HistoryEpisode{
|
var newHistoryEpisode = new HistoryEpisode{
|
||||||
EpisodeTitle = crunchyEpisode.Identifier.Contains("|M|") ? crunchyEpisode.SeasonTitle : crunchyEpisode.Title,
|
EpisodeTitle = GetEpisodeTitle(crunchyEpisode),
|
||||||
EpisodeDescription = crunchyEpisode.Description,
|
EpisodeDescription = crunchyEpisode.Description,
|
||||||
EpisodeId = crunchyEpisode.Id,
|
EpisodeId = crunchyEpisode.Id,
|
||||||
Episode = crunchyEpisode.Episode,
|
Episode = crunchyEpisode.Episode,
|
||||||
|
@ -332,7 +254,7 @@ public class History(){
|
||||||
historySeason.EpisodesList.Add(newHistoryEpisode);
|
historySeason.EpisodesList.Add(newHistoryEpisode);
|
||||||
} else{
|
} else{
|
||||||
//Update existing episode
|
//Update existing episode
|
||||||
historyEpisode.EpisodeTitle = crunchyEpisode.Identifier.Contains("|M|") ? crunchyEpisode.SeasonTitle : crunchyEpisode.Title;
|
historyEpisode.EpisodeTitle = GetEpisodeTitle(crunchyEpisode);
|
||||||
historyEpisode.SpecialEpisode = !int.TryParse(crunchyEpisode.Episode, out _);
|
historyEpisode.SpecialEpisode = !int.TryParse(crunchyEpisode.Episode, out _);
|
||||||
historyEpisode.EpisodeDescription = crunchyEpisode.Description;
|
historyEpisode.EpisodeDescription = crunchyEpisode.Description;
|
||||||
historyEpisode.EpisodeId = crunchyEpisode.Id;
|
historyEpisode.EpisodeId = crunchyEpisode.Id;
|
||||||
|
@ -343,7 +265,7 @@ public class History(){
|
||||||
|
|
||||||
historySeason.EpisodesList.Sort(new NumericStringPropertyComparer());
|
historySeason.EpisodesList.Sort(new NumericStringPropertyComparer());
|
||||||
} else{
|
} else{
|
||||||
var newSeason = NewHistorySeason(seasonData, firstEpisode);
|
var newSeason = NewHistorySeason(episodeList, firstEpisode);
|
||||||
|
|
||||||
newSeason.EpisodesList.Sort(new NumericStringPropertyComparer());
|
newSeason.EpisodesList.Sort(new NumericStringPropertyComparer());
|
||||||
|
|
||||||
|
@ -361,7 +283,7 @@ public class History(){
|
||||||
};
|
};
|
||||||
crunInstance.HistoryList.Add(historySeries);
|
crunInstance.HistoryList.Add(historySeries);
|
||||||
|
|
||||||
var newSeason = NewHistorySeason(seasonData, firstEpisode);
|
var newSeason = NewHistorySeason(episodeList, firstEpisode);
|
||||||
|
|
||||||
newSeason.EpisodesList.Sort(new NumericStringPropertyComparer());
|
newSeason.EpisodesList.Sort(new NumericStringPropertyComparer());
|
||||||
|
|
||||||
|
@ -381,6 +303,34 @@ public class History(){
|
||||||
|
|
||||||
private CrSeriesBase? cachedSeries;
|
private CrSeriesBase? cachedSeries;
|
||||||
|
|
||||||
|
private string GetEpisodeTitle(CrunchyEpisode crunchyEpisode){
|
||||||
|
if (crunchyEpisode.Identifier.Contains("|M|")){
|
||||||
|
if (string.IsNullOrEmpty(crunchyEpisode.Title)){
|
||||||
|
if (crunchyEpisode.SeasonTitle.StartsWith(crunchyEpisode.SeriesTitle)){
|
||||||
|
var splitTitle = crunchyEpisode.SeasonTitle.Split(new[]{ crunchyEpisode.SeriesTitle }, StringSplitOptions.None);
|
||||||
|
var titlePart = splitTitle.Length > 1 ? splitTitle[1] : splitTitle[0];
|
||||||
|
var cleanedTitle = Regex.Replace(titlePart, @"^[^a-zA-Z]+", "");
|
||||||
|
|
||||||
|
return cleanedTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return crunchyEpisode.SeasonTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crunchyEpisode.Title.StartsWith(crunchyEpisode.SeriesTitle)){
|
||||||
|
var splitTitle = crunchyEpisode.Title.Split(new[]{ crunchyEpisode.SeriesTitle }, StringSplitOptions.None);
|
||||||
|
var titlePart = splitTitle.Length > 1 ? splitTitle[1] : splitTitle[0];
|
||||||
|
var cleanedTitle = Regex.Replace(titlePart, @"^[^a-zA-Z]+", "");
|
||||||
|
|
||||||
|
return cleanedTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return crunchyEpisode.Title;
|
||||||
|
}
|
||||||
|
|
||||||
|
return crunchyEpisode.Title;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task RefreshSeriesData(string seriesId, HistorySeries historySeries){
|
private async Task RefreshSeriesData(string seriesId, HistorySeries historySeries){
|
||||||
if (cachedSeries == null || (cachedSeries.Data != null && cachedSeries.Data.First().Id != seriesId)){
|
if (cachedSeries == null || (cachedSeries.Data != null && cachedSeries.Data.First().Id != seriesId)){
|
||||||
cachedSeries = await crunInstance.CrSeries.SeriesById(seriesId, string.IsNullOrEmpty(crunInstance.CrunOptions.HistoryLang) ? crunInstance.DefaultLocale : crunInstance.CrunOptions.HistoryLang, true);
|
cachedSeries = await crunInstance.CrSeries.SeriesById(seriesId, string.IsNullOrEmpty(crunInstance.CrunOptions.HistoryLang) ? crunInstance.DefaultLocale : crunInstance.CrunOptions.HistoryLang, true);
|
||||||
|
@ -418,7 +368,7 @@ public class History(){
|
||||||
public void SortItems(){
|
public void SortItems(){
|
||||||
var currentSortingType = CrunchyrollManager.Instance.CrunOptions.HistoryPageProperties?.SelectedSorting ?? SortingType.SeriesTitle;
|
var currentSortingType = CrunchyrollManager.Instance.CrunOptions.HistoryPageProperties?.SelectedSorting ?? SortingType.SeriesTitle;
|
||||||
var sortingDir = CrunchyrollManager.Instance.CrunOptions.HistoryPageProperties != null && CrunchyrollManager.Instance.CrunOptions.HistoryPageProperties.Ascending;
|
var sortingDir = CrunchyrollManager.Instance.CrunOptions.HistoryPageProperties != null && CrunchyrollManager.Instance.CrunOptions.HistoryPageProperties.Ascending;
|
||||||
DateTime today = DateTime.UtcNow.Date;
|
DateTime today = DateTime.Now.Date;
|
||||||
switch (currentSortingType){
|
switch (currentSortingType){
|
||||||
case SortingType.SeriesTitle:
|
case SortingType.SeriesTitle:
|
||||||
var sortedList = sortingDir
|
var sortedList = sortingDir
|
||||||
|
@ -479,7 +429,7 @@ public class History(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DateTime? ParseDate(string dateStr, DateTime today){
|
public DateTime? ParseDate(string dateStr, DateTime today){
|
||||||
if (dateStr == "Today"){
|
if (dateStr == "Today"){
|
||||||
return today;
|
return today;
|
||||||
}
|
}
|
||||||
|
@ -502,7 +452,7 @@ public class History(){
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool CheckStringForSpecial(string identifier){
|
private bool CheckStringForSpecial(string identifier){
|
||||||
if (string.IsNullOrEmpty(identifier)){
|
if (string.IsNullOrEmpty(identifier)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -514,7 +464,7 @@ public class History(){
|
||||||
return Regex.IsMatch(identifier, pattern);
|
return Regex.IsMatch(identifier, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HistorySeason NewHistorySeason(CrunchyEpisodeList seasonData, CrunchyEpisode firstEpisode){
|
private HistorySeason NewHistorySeason(List<CrunchyEpisode> seasonData, CrunchyEpisode firstEpisode){
|
||||||
var newSeason = new HistorySeason{
|
var newSeason = new HistorySeason{
|
||||||
SeasonTitle = firstEpisode.SeasonTitle,
|
SeasonTitle = firstEpisode.SeasonTitle,
|
||||||
SeasonId = firstEpisode.SeasonId,
|
SeasonId = firstEpisode.SeasonId,
|
||||||
|
@ -523,9 +473,9 @@ public class History(){
|
||||||
SpecialSeason = CheckStringForSpecial(firstEpisode.Identifier)
|
SpecialSeason = CheckStringForSpecial(firstEpisode.Identifier)
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var crunchyEpisode in seasonData.Data!){
|
foreach (var crunchyEpisode in seasonData){
|
||||||
var newHistoryEpisode = new HistoryEpisode{
|
var newHistoryEpisode = new HistoryEpisode{
|
||||||
EpisodeTitle = crunchyEpisode.Identifier.Contains("|M|") ? crunchyEpisode.SeasonTitle : crunchyEpisode.Title,
|
EpisodeTitle = GetEpisodeTitle(crunchyEpisode),
|
||||||
EpisodeDescription = crunchyEpisode.Description,
|
EpisodeDescription = crunchyEpisode.Description,
|
||||||
EpisodeId = crunchyEpisode.Id,
|
EpisodeId = crunchyEpisode.Id,
|
||||||
Episode = crunchyEpisode.Episode,
|
Episode = crunchyEpisode.Episode,
|
||||||
|
@ -539,30 +489,7 @@ public class History(){
|
||||||
return newSeason;
|
return newSeason;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HistorySeason NewHistorySeason(CrunchyEpisode episode){
|
public void MatchHistorySeriesWithSonarr(bool updateAll){
|
||||||
var newSeason = new HistorySeason{
|
|
||||||
SeasonTitle = episode.SeasonTitle,
|
|
||||||
SeasonId = episode.SeasonId,
|
|
||||||
SeasonNum = Helpers.ExtractNumberAfterS(episode.Identifier) ?? episode.SeasonNumber + "",
|
|
||||||
EpisodesList =[],
|
|
||||||
};
|
|
||||||
|
|
||||||
var newHistoryEpisode = new HistoryEpisode{
|
|
||||||
EpisodeTitle = episode.Identifier.Contains("|M|") ? episode.SeasonTitle : episode.Title,
|
|
||||||
EpisodeDescription = episode.Description,
|
|
||||||
EpisodeId = episode.Id,
|
|
||||||
Episode = episode.Episode,
|
|
||||||
EpisodeSeasonNum = Helpers.ExtractNumberAfterS(episode.Identifier) ?? episode.SeasonNumber + "",
|
|
||||||
SpecialEpisode = !int.TryParse(episode.Episode, out _),
|
|
||||||
};
|
|
||||||
|
|
||||||
newSeason.EpisodesList.Add(newHistoryEpisode);
|
|
||||||
|
|
||||||
|
|
||||||
return newSeason;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async void MatchHistorySeriesWithSonarr(bool updateAll){
|
|
||||||
if (crunInstance.CrunOptions.SonarrProperties is{ SonarrEnabled: false }){
|
if (crunInstance.CrunOptions.SonarrProperties is{ SonarrEnabled: false }){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -604,7 +531,7 @@ public class History(){
|
||||||
// Create a copy of the episodes list for each thread
|
// Create a copy of the episodes list for each thread
|
||||||
var episodesCopy = new List<SonarrEpisode>(episodes);
|
var episodesCopy = new List<SonarrEpisode>(episodes);
|
||||||
|
|
||||||
var episode = FindClosestMatchEpisodes(episodesCopy, historyEpisode.EpisodeTitle);
|
var episode = FindClosestMatchEpisodes(episodesCopy, historyEpisode.EpisodeTitle ?? string.Empty);
|
||||||
if (episode != null){
|
if (episode != null){
|
||||||
historyEpisode.SonarrEpisodeId = episode.Id + "";
|
historyEpisode.SonarrEpisodeId = episode.Id + "";
|
||||||
historyEpisode.SonarrEpisodeNumber = episode.EpisodeNumber + "";
|
historyEpisode.SonarrEpisodeNumber = episode.EpisodeNumber + "";
|
||||||
|
|
|
@ -22,6 +22,7 @@ public class CfgManager{
|
||||||
public static readonly string PathCrToken = WorkingDirectory + "/config/cr_token.yml";
|
public static readonly string PathCrToken = WorkingDirectory + "/config/cr_token.yml";
|
||||||
public static readonly string PathCrDownloadOptions = WorkingDirectory + "/config/settings.yml";
|
public static readonly string PathCrDownloadOptions = WorkingDirectory + "/config/settings.yml";
|
||||||
public static readonly string PathCrHistory = WorkingDirectory + "/config/history.json";
|
public static readonly string PathCrHistory = WorkingDirectory + "/config/history.json";
|
||||||
|
public static readonly string PathWindowSettings= WorkingDirectory + "/config/windowSettings.json";
|
||||||
|
|
||||||
public static readonly string PathFFMPEG = WorkingDirectory + "/lib/ffmpeg.exe";
|
public static readonly string PathFFMPEG = WorkingDirectory + "/lib/ffmpeg.exe";
|
||||||
public static readonly string PathMKVMERGE = WorkingDirectory + "/lib/mkvmerge.exe";
|
public static readonly string PathMKVMERGE = WorkingDirectory + "/lib/mkvmerge.exe";
|
||||||
|
|
|
@ -322,7 +322,7 @@ public class HistorySeries : INotifyPropertyChanged{
|
||||||
await CrunchyrollManager.Instance.History.CRUpdateSeries(SeriesId, seasonId);
|
await CrunchyrollManager.Instance.History.CRUpdateSeries(SeriesId, seasonId);
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SeriesTitle)));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SeriesTitle)));
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SeriesDescription)));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SeriesDescription)));
|
||||||
CrunchyrollManager.Instance.History.MatchHistoryEpisodesWithSonarr(false, this);
|
// CrunchyrollManager.Instance.History.MatchHistoryEpisodesWithSonarr(false, this);
|
||||||
UpdateNewEpisodes();
|
UpdateNewEpisodes();
|
||||||
FetchingData = false;
|
FetchingData = false;
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FetchingData)));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FetchingData)));
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using CRD.Views;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace CRD.Utils.Structs;
|
namespace CRD.Utils.Structs;
|
||||||
|
@ -98,3 +100,29 @@ public class FrameData{
|
||||||
public class StringItem{
|
public class StringItem{
|
||||||
public string stringValue{ get; set; }
|
public string stringValue{ get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class WindowSettings{
|
||||||
|
public double Width{ get; set; }
|
||||||
|
public double Height{ get; set; }
|
||||||
|
public int ScreenIndex{ get; set; }
|
||||||
|
public int PosX{ get; set; }
|
||||||
|
public int PosY{ get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ToastMessage(string message, ToastType type, int i){
|
||||||
|
public string? Message{ get; set; } = message;
|
||||||
|
public int Seconds{ get; set; } = i;
|
||||||
|
public ToastType Type{ get; set; } = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NavigationMessage{
|
||||||
|
public Type? ViewModelType{ get; }
|
||||||
|
public bool Back{ get; }
|
||||||
|
public bool Refresh{ get; }
|
||||||
|
|
||||||
|
public NavigationMessage(Type? viewModelType, bool back, bool refresh){
|
||||||
|
ViewModelType = viewModelType;
|
||||||
|
Back = back;
|
||||||
|
Refresh = refresh;
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,18 +30,28 @@ public partial class AccountPageViewModel : ViewModelBase{
|
||||||
|
|
||||||
private static DispatcherTimer? _timer;
|
private static DispatcherTimer? _timer;
|
||||||
private DateTime _targetTime;
|
private DateTime _targetTime;
|
||||||
|
|
||||||
private bool IsCancelled = false;
|
private bool IsCancelled = false;
|
||||||
private bool UnknownEndDate = false;
|
private bool UnknownEndDate = false;
|
||||||
|
private bool EndedButMaybeActive = false;
|
||||||
|
|
||||||
public AccountPageViewModel(){
|
public AccountPageViewModel(){
|
||||||
UpdatetProfile();
|
UpdatetProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Timer_Tick(object sender, EventArgs e){
|
private void Timer_Tick(object sender, EventArgs e){
|
||||||
var remaining = _targetTime - DateTime.UtcNow;
|
var remaining = _targetTime - DateTime.Now;
|
||||||
if (remaining <= TimeSpan.Zero){
|
if (remaining <= TimeSpan.Zero){
|
||||||
RemainingTime = "No active Subscription";
|
RemainingTime = "No active Subscription";
|
||||||
_timer.Stop();
|
_timer.Stop();
|
||||||
|
if (UnknownEndDate){
|
||||||
|
RemainingTime = "Unknown Subscription end date";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EndedButMaybeActive){
|
||||||
|
RemainingTime = "Subscription maybe ended";
|
||||||
|
}
|
||||||
|
|
||||||
if (CrunchyrollManager.Instance.Profile.Subscription != null){
|
if (CrunchyrollManager.Instance.Profile.Subscription != null){
|
||||||
Console.Error.WriteLine(JsonConvert.SerializeObject(CrunchyrollManager.Instance.Profile.Subscription, Formatting.Indented));
|
Console.Error.WriteLine(JsonConvert.SerializeObject(CrunchyrollManager.Instance.Profile.Subscription, Formatting.Indented));
|
||||||
}
|
}
|
||||||
|
@ -51,25 +61,26 @@ public partial class AccountPageViewModel : ViewModelBase{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdatetProfile(){
|
public void UpdatetProfile(){
|
||||||
ProfileName = CrunchyrollManager.Instance.Profile.Username; // Default or fetched user name
|
ProfileName = CrunchyrollManager.Instance.Profile.Username ?? "???"; // Default or fetched user name
|
||||||
LoginLogoutText = CrunchyrollManager.Instance.Profile.Username == "???" ? "Login" : "Logout"; // Default state
|
LoginLogoutText = CrunchyrollManager.Instance.Profile.Username == "???" ? "Login" : "Logout"; // Default state
|
||||||
LoadProfileImage("https://static.crunchyroll.com/assets/avatar/170x170/" + CrunchyrollManager.Instance.Profile.Avatar);
|
LoadProfileImage("https://static.crunchyroll.com/assets/avatar/170x170/" + CrunchyrollManager.Instance.Profile.Avatar);
|
||||||
|
|
||||||
|
|
||||||
if (CrunchyrollManager.Instance.Profile.Subscription != null && CrunchyrollManager.Instance.Profile.Subscription?.SubscriptionProducts != null){
|
var subscriptions = CrunchyrollManager.Instance.Profile.Subscription;
|
||||||
if (CrunchyrollManager.Instance.Profile.Subscription?.SubscriptionProducts.Count >= 1){
|
|
||||||
var sub = CrunchyrollManager.Instance.Profile.Subscription?.SubscriptionProducts.First();
|
if (subscriptions != null){
|
||||||
if (sub != null){
|
if (subscriptions.SubscriptionProducts is{ Count: >= 1 }){
|
||||||
|
var sub = subscriptions.SubscriptionProducts.First();
|
||||||
IsCancelled = sub.IsCancelled;
|
IsCancelled = sub.IsCancelled;
|
||||||
}
|
EndedButMaybeActive = !subscriptions.IsActive;
|
||||||
}else if (CrunchyrollManager.Instance.Profile.Subscription?.ThirdPartySubscriptionProducts.Count >= 1){
|
} else if (subscriptions.ThirdPartySubscriptionProducts is{ Count: >= 1 }){
|
||||||
var sub = CrunchyrollManager.Instance.Profile.Subscription?.ThirdPartySubscriptionProducts.First();
|
var sub = subscriptions.ThirdPartySubscriptionProducts.First();
|
||||||
if (sub != null){
|
|
||||||
IsCancelled = !sub.AutoRenew;
|
IsCancelled = !sub.AutoRenew;
|
||||||
}
|
EndedButMaybeActive = !subscriptions.IsActive;
|
||||||
}else if(CrunchyrollManager.Instance.Profile.Subscription?.NonrecurringSubscriptionProducts.Count >= 1){
|
} else if (subscriptions.NonrecurringSubscriptionProducts is{ Count: >= 1 }){
|
||||||
IsCancelled = true;
|
IsCancelled = true;
|
||||||
}else if(CrunchyrollManager.Instance.Profile.Subscription?.FunimationSubscriptions.Count >= 1){
|
EndedButMaybeActive = !subscriptions.IsActive;
|
||||||
|
} else if (subscriptions.FunimationSubscriptions is{ Count: >= 1 }){
|
||||||
IsCancelled = true;
|
IsCancelled = true;
|
||||||
UnknownEndDate = true;
|
UnknownEndDate = true;
|
||||||
}
|
}
|
||||||
|
@ -82,24 +93,27 @@ public partial class AccountPageViewModel : ViewModelBase{
|
||||||
_timer.Tick += Timer_Tick;
|
_timer.Tick += Timer_Tick;
|
||||||
_timer.Start();
|
_timer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else{
|
} else{
|
||||||
RemainingTime = "No active Subscription";
|
RemainingTime = "No active Subscription";
|
||||||
if (_timer != null){
|
if (_timer != null){
|
||||||
_timer.Stop();
|
_timer.Stop();
|
||||||
_timer.Tick -= Timer_Tick;
|
_timer.Tick -= Timer_Tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
RaisePropertyChanged(nameof(RemainingTime));
|
RaisePropertyChanged(nameof(RemainingTime));
|
||||||
|
|
||||||
if (CrunchyrollManager.Instance.Profile.Subscription != null){
|
if (CrunchyrollManager.Instance.Profile.Subscription != null){
|
||||||
Console.Error.WriteLine(JsonConvert.SerializeObject(CrunchyrollManager.Instance.Profile.Subscription, Formatting.Indented));
|
Console.Error.WriteLine(JsonConvert.SerializeObject(CrunchyrollManager.Instance.Profile.Subscription, Formatting.Indented));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UnknownEndDate){
|
if (UnknownEndDate){
|
||||||
RemainingTime = "Unknown Subscription end date";
|
RemainingTime = "Unknown Subscription end date";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EndedButMaybeActive){
|
||||||
|
RemainingTime = "Subscription maybe ended";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
|
|
|
@ -1,13 +1,20 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.Platform;
|
||||||
|
using CRD.Utils;
|
||||||
|
using CRD.Utils.Structs;
|
||||||
using CRD.Utils.Updater;
|
using CRD.Utils.Updater;
|
||||||
using CRD.ViewModels;
|
using CRD.ViewModels;
|
||||||
|
using CRD.Views;
|
||||||
using CRD.Views.Utils;
|
using CRD.Views.Utils;
|
||||||
using FluentAvalonia.Core;
|
using FluentAvalonia.Core;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
using FluentAvalonia.UI.Windowing;
|
using FluentAvalonia.UI.Windowing;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ContentDialogUpdateViewModel = CRD.ViewModels.Utils.ContentDialogUpdateViewModel;
|
using ContentDialogUpdateViewModel = CRD.ViewModels.Utils.ContentDialogUpdateViewModel;
|
||||||
|
|
||||||
|
@ -45,6 +52,9 @@ public partial class MainWindow : AppWindow{
|
||||||
AvaloniaXamlLoader.Load(this);
|
AvaloniaXamlLoader.Load(this);
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
Opened += OnOpened;
|
||||||
|
Closing += OnClosing;
|
||||||
|
|
||||||
TitleBar.ExtendsContentIntoTitleBar = true;
|
TitleBar.ExtendsContentIntoTitleBar = true;
|
||||||
TitleBar.TitleBarHitTestType = TitleBarHitTestType.Complex;
|
TitleBar.TitleBarHitTestType = TitleBarHitTestType.Complex;
|
||||||
|
|
||||||
|
@ -62,6 +72,7 @@ public partial class MainWindow : AppWindow{
|
||||||
if (viewModel is SeriesPageViewModel){
|
if (viewModel is SeriesPageViewModel){
|
||||||
((SeriesPageViewModel)viewModel).SetStorageProvider(StorageProvider);
|
((SeriesPageViewModel)viewModel).SetStorageProvider(StorageProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
navigationStack.Push(viewModel);
|
navigationStack.Push(viewModel);
|
||||||
nv.Content = viewModel;
|
nv.Content = viewModel;
|
||||||
} else if (!message.Back && message.ViewModelType != null){
|
} else if (!message.Back && message.ViewModelType != null){
|
||||||
|
@ -69,6 +80,7 @@ public partial class MainWindow : AppWindow{
|
||||||
if (viewModel is SeriesPageViewModel){
|
if (viewModel is SeriesPageViewModel){
|
||||||
((SeriesPageViewModel)viewModel).SetStorageProvider(StorageProvider);
|
((SeriesPageViewModel)viewModel).SetStorageProvider(StorageProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
navigationStack.Push(viewModel);
|
navigationStack.Push(viewModel);
|
||||||
nv.Content = viewModel;
|
nv.Content = viewModel;
|
||||||
} else{
|
} else{
|
||||||
|
@ -117,9 +129,10 @@ public partial class MainWindow : AppWindow{
|
||||||
break;
|
break;
|
||||||
case "History":
|
case "History":
|
||||||
navView.Content = Activator.CreateInstance(typeof(HistoryPageViewModel));
|
navView.Content = Activator.CreateInstance(typeof(HistoryPageViewModel));
|
||||||
if ( navView.Content is HistoryPageViewModel){
|
if (navView.Content is HistoryPageViewModel){
|
||||||
((HistoryPageViewModel)navView.Content).SetStorageProvider(StorageProvider);
|
((HistoryPageViewModel)navView.Content).SetStorageProvider(StorageProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
navigationStack.Clear();
|
navigationStack.Clear();
|
||||||
navigationStack.Push(navView.Content);
|
navigationStack.Push(navView.Content);
|
||||||
selectedNavVieItem = selectedItem;
|
selectedNavVieItem = selectedItem;
|
||||||
|
@ -159,22 +172,55 @@ public partial class MainWindow : AppWindow{
|
||||||
|
|
||||||
_ = await dialog.ShowAsync();
|
_ = await dialog.ShowAsync();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class ToastMessage(string message, ToastType type, int i){
|
private void OnOpened(object sender, EventArgs e){
|
||||||
public string? Message{ get; set; } = message;
|
if (File.Exists(CfgManager.PathWindowSettings)){
|
||||||
public int Seconds{ get; set; } = i;
|
var settings = JsonConvert.DeserializeObject<WindowSettings>(File.ReadAllText(CfgManager.PathWindowSettings));
|
||||||
public ToastType Type{ get; set; } = type;
|
if (settings != null){
|
||||||
}
|
Width = settings.Width;
|
||||||
|
Height = settings.Height;
|
||||||
|
|
||||||
public class NavigationMessage{
|
var screens = Screens.All;
|
||||||
public Type? ViewModelType{ get; }
|
if (settings.ScreenIndex >= 0 && settings.ScreenIndex < screens.Count){
|
||||||
public bool Back{ get; }
|
var screen = screens[settings.ScreenIndex];
|
||||||
public bool Refresh{ get; }
|
var screenBounds = screen.Bounds;
|
||||||
|
|
||||||
public NavigationMessage(Type? viewModelType, bool back, bool refresh){
|
var topLeft = screenBounds.TopLeft;
|
||||||
ViewModelType = viewModelType;
|
var bottomRight = screenBounds.BottomRight;
|
||||||
Back = back;
|
|
||||||
Refresh = refresh;
|
if (settings.PosX >= topLeft.X && settings.PosX <= bottomRight.X - Width &&
|
||||||
|
settings.PosY >= topLeft.Y && settings.PosY <= bottomRight.Y - Height){
|
||||||
|
Position = new PixelPoint(settings.PosX, settings.PosY);
|
||||||
|
} else{
|
||||||
|
Position = new PixelPoint(topLeft.X, topLeft.Y + 31);
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
var primaryScreen = screens?[0].Bounds ?? new PixelRect(0, 0, 1000, 600); // Default size if no screens
|
||||||
|
Position = new PixelPoint(primaryScreen.TopLeft.X, primaryScreen.TopLeft.Y + 31);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnClosing(object sender, System.ComponentModel.CancelEventArgs e){
|
||||||
|
var screens = Screens.All;
|
||||||
|
int screenIndex = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < screens.Count; i++){
|
||||||
|
if (screens[i].Bounds.Contains(Position)){
|
||||||
|
screenIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var settings = new WindowSettings{
|
||||||
|
Width = Width,
|
||||||
|
Height = Height,
|
||||||
|
ScreenIndex = screenIndex,
|
||||||
|
PosX = Position.X,
|
||||||
|
PosY = Position.Y
|
||||||
|
};
|
||||||
|
|
||||||
|
File.WriteAllText(CfgManager.PathWindowSettings, JsonConvert.SerializeObject(settings, Formatting.Indented));
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue