using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using Avalonia.Controls; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using CRD.Downloader; using CRD.Downloader.Crunchyroll; using CRD.Downloader.Crunchyroll.Utils; using CRD.Utils.Files; using CRD.Utils.Structs; using DynamicData; namespace CRD.ViewModels; public partial class CalendarPageViewModel : ViewModelBase{ public ObservableCollection CalendarDays{ get; set; } [ObservableProperty] private bool _prevButtonEnabled = true; [ObservableProperty] private bool _nextButtonEnabled = true; [ObservableProperty] private bool _showLoading; [ObservableProperty] private bool _customCalendar; [ObservableProperty] private bool _showUpcomingEpisodes; [ObservableProperty] private bool _hideDubs; public ObservableCollection CalendarDubFilter{ get; } = new(){ new ComboBoxItem(){ Content = "none" }, }; [ObservableProperty] private ComboBoxItem? _currentCalendarDubFilter; public ObservableCollection CalendarLanguage{ get; } = new(){ new ComboBoxItem(){ Content = "en-us" }, new ComboBoxItem(){ Content = "es" }, new ComboBoxItem(){ Content = "es-es" }, new ComboBoxItem(){ Content = "pt-br" }, new ComboBoxItem(){ Content = "pt-pt" }, new ComboBoxItem(){ Content = "fr" }, new ComboBoxItem(){ Content = "de" }, new ComboBoxItem(){ Content = "ar" }, new ComboBoxItem(){ Content = "it" }, new ComboBoxItem(){ Content = "ru" }, new ComboBoxItem(){ Content = "hi" }, }; [ObservableProperty] private ComboBoxItem? _currentCalendarLanguage; private CalendarWeek? currentWeek; private bool loading; public CalendarPageViewModel(){ loading = true; CalendarDays = new ObservableCollection(); foreach (var languageItem in Languages.languages){ CalendarDubFilter.Add(new ComboBoxItem{ Content = languageItem.CrLocale }); } CustomCalendar = CrunchyrollManager.Instance.CrunOptions.CustomCalendar; HideDubs = CrunchyrollManager.Instance.CrunOptions.CalendarHideDubs; ShowUpcomingEpisodes = CrunchyrollManager.Instance.CrunOptions.CalendarShowUpcomingEpisodes; ComboBoxItem? dubfilter = CalendarDubFilter.FirstOrDefault(a => a.Content != null && (string)a.Content == CrunchyrollManager.Instance.CrunOptions.CalendarDubFilter) ?? null; CurrentCalendarDubFilter = dubfilter ?? CalendarDubFilter[0]; CurrentCalendarLanguage = CalendarLanguage.FirstOrDefault(a => a.Content != null && (string)a.Content == CrunchyrollManager.Instance.CrunOptions.SelectedCalendarLanguage) ?? CalendarLanguage[0]; loading = false; LoadCalendar(GetThisWeeksMondayDate(), DateTime.Now, false); } private string GetThisWeeksMondayDate(){ DateTime today = DateTime.Today; int daysToSubtract = (int)today.DayOfWeek - (int)DayOfWeek.Monday; if (daysToSubtract < 0){ daysToSubtract += 7; } DateTime monday = today.AddDays(-daysToSubtract); string formattedDate = monday.ToString("yyyy-MM-dd"); return formattedDate; } public async void LoadCalendar(string mondayDate, DateTime customCalDate, bool forceUpdate){ ShowLoading = true; CalendarWeek week; if (CustomCalendar){ if (customCalDate.Date == DateTime.Now.Date){ PrevButtonEnabled = false; NextButtonEnabled = true; } else{ PrevButtonEnabled = true; NextButtonEnabled = false; } week = await CalendarManager.Instance.BuildCustomCalendar(customCalDate, forceUpdate); } else{ PrevButtonEnabled = true; NextButtonEnabled = true; week = await CalendarManager.Instance.GetCalendarForDate(mondayDate, forceUpdate); if (currentWeek != null && currentWeek == week){ ShowLoading = false; return; } } currentWeek = week; CalendarDays.Clear(); if (week.CalendarDays != null) CalendarDays.AddRange(week.CalendarDays); RaisePropertyChanged(nameof(CalendarDays)); ShowLoading = false; if (CustomCalendar){ foreach (var calendarDay in CalendarDays){ foreach (var calendarDayCalendarEpisode in calendarDay.CalendarEpisodes){ if (calendarDayCalendarEpisode.ImageBitmap == null){ if (calendarDayCalendarEpisode.AnilistEpisode){ _ = calendarDayCalendarEpisode.LoadImage(100, 150); } else{ _ = calendarDayCalendarEpisode.LoadImage(); } } } } } else{ foreach (var calendarDay in CalendarDays){ if (HideDubs) calendarDay.CalendarEpisodes.RemoveAll(e => CrSimulcastCalendarFilter.IsDubOrAltLanguageSeason(e.SeasonName)); foreach (var e in calendarDay.CalendarEpisodes){ if (e.ImageBitmap == null){ if (e.AnilistEpisode) _ = e.LoadImage(100, 150); else _ = e.LoadImage(); } } } } } private string NextMonday(DateTime currentMonday){ DateTime nextMonday = currentMonday.AddDays(7); return nextMonday.ToString("yyyy-MM-dd"); } private string PreviousMonday(DateTime currentMonday){ DateTime nextMonday = currentMonday.AddDays(-7); return nextMonday.ToString("yyyy-MM-dd"); } [RelayCommand] public void Refresh(){ if (loading){ return; } string mondayDate; if (currentWeek is{ FirstDayOfWeekString: not null }){ mondayDate = currentWeek.FirstDayOfWeekString; } else{ mondayDate = GetThisWeeksMondayDate(); } var refreshDate = DateTime.Now; if (currentWeek?.FirstDayOfWeek != null){ refreshDate = currentWeek.FirstDayOfWeek.AddDays(6); } LoadCalendar(mondayDate, refreshDate, true); } [RelayCommand] public void PrevWeek(){ if (loading){ return; } string mondayDate; if (currentWeek is{ FirstDayOfWeek: var firstDay } && firstDay != DateTime.MinValue){ mondayDate = PreviousMonday(currentWeek.FirstDayOfWeek); } else{ mondayDate = GetThisWeeksMondayDate(); } var refreshDate = DateTime.Now; if (currentWeek?.FirstDayOfWeek != null && currentWeek.FirstDayOfWeek != DateTime.MinValue){ refreshDate = currentWeek.FirstDayOfWeek.AddDays(-1); } LoadCalendar(mondayDate, refreshDate, false); } [RelayCommand] public void NextWeek(){ if (loading){ return; } string mondayDate; if (currentWeek is{ FirstDayOfWeek: var firstDay } && firstDay != DateTime.MinValue){ mondayDate = NextMonday(currentWeek.FirstDayOfWeek); } else{ mondayDate = GetThisWeeksMondayDate(); } var refreshDate = DateTime.Now; if (currentWeek?.FirstDayOfWeek != null && currentWeek.FirstDayOfWeek != DateTime.MinValue){ refreshDate = currentWeek.FirstDayOfWeek.AddDays(13); } LoadCalendar(mondayDate, refreshDate, false); } partial void OnCurrentCalendarLanguageChanged(ComboBoxItem? value){ if (loading){ return; } if (value?.Content != null){ CrunchyrollManager.Instance.CrunOptions.SelectedCalendarLanguage = value.Content.ToString(); Refresh(); CfgManager.WriteCrSettings(); } } partial void OnCustomCalendarChanged(bool value){ if (loading){ return; } CrunchyrollManager.Instance.CrunOptions.CustomCalendar = value; LoadCalendar(GetThisWeeksMondayDate(), DateTime.Now, true); CfgManager.WriteCrSettings(); } partial void OnHideDubsChanged(bool value){ if (loading){ return; } CrunchyrollManager.Instance.CrunOptions.CalendarHideDubs = value; CfgManager.WriteCrSettings(); } partial void OnShowUpcomingEpisodesChanged(bool value){ if (loading){ return; } CrunchyrollManager.Instance.CrunOptions.CalendarShowUpcomingEpisodes = value; CfgManager.WriteCrSettings(); } partial void OnCurrentCalendarDubFilterChanged(ComboBoxItem? value){ if (loading){ return; } if (!string.IsNullOrEmpty(value?.Content + "")){ CrunchyrollManager.Instance.CrunOptions.CalendarDubFilter = value?.Content + ""; CfgManager.WriteCrSettings(); } } }