378 lines
12 KiB
C#
378 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Pixiview.Resources;
|
|
using Pixiview.Utils;
|
|
using Xamarin.Essentials;
|
|
using Xamarin.Forms;
|
|
|
|
namespace Pixiview.Illust
|
|
{
|
|
public partial class RankingPage : IllustRankingDataCollectionPage
|
|
{
|
|
private static readonly string[] segmentDates = { "daily", "weekly", "monthly", "male" };
|
|
private static readonly object sync = new object();
|
|
|
|
public static readonly BindableProperty SegmentDateProperty = BindableProperty.Create(
|
|
nameof(SegmentDate), typeof(int), typeof(RankingPage), propertyChanged: OnSegmentDatePropertyChanged);
|
|
public static readonly BindableProperty SegmentTypeProperty = BindableProperty.Create(
|
|
nameof(SegmentType), typeof(int), typeof(RankingPage), propertyChanged: OnSegmentTypePropertyChanged);
|
|
public static readonly BindableProperty MaximumDateProperty = BindableProperty.Create(
|
|
nameof(MaximumDate), typeof(DateTime), typeof(RankingPage), DateTime.Now);
|
|
public static readonly BindableProperty SelectedDateProperty = BindableProperty.Create(
|
|
nameof(SelectedDate), typeof(DateTime), typeof(RankingPage), DateTime.Now);
|
|
|
|
private static void OnSegmentDatePropertyChanged(BindableObject obj, object old, object @new)
|
|
{
|
|
var page = (RankingPage)obj;
|
|
var index = (int)@new;
|
|
if (index == 2)
|
|
{
|
|
// monthly
|
|
var typeIndex = page.SegmentType;
|
|
if (typeIndex == 1)
|
|
{
|
|
// r-18
|
|
page.SegmentType = 0;
|
|
}
|
|
}
|
|
}
|
|
private static void OnSegmentTypePropertyChanged(BindableObject obj, object old, object @new)
|
|
{
|
|
var page = (RankingPage)obj;
|
|
var index = (int)@new;
|
|
if (index == 1)
|
|
{
|
|
// r-18
|
|
var dateIndex = page.SegmentDate;
|
|
if (dateIndex == 2)
|
|
{
|
|
// monthly
|
|
page.SegmentDate = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
public int SegmentDate
|
|
{
|
|
get => (int)GetValue(SegmentDateProperty);
|
|
set => SetValue(SegmentDateProperty, value);
|
|
}
|
|
public int SegmentType
|
|
{
|
|
get => (int)GetValue(SegmentTypeProperty);
|
|
set => SetValue(SegmentTypeProperty, value);
|
|
}
|
|
public DateTime MaximumDate
|
|
{
|
|
get => (DateTime)GetValue(MaximumDateProperty);
|
|
set => SetValue(MaximumDateProperty, value);
|
|
}
|
|
public DateTime SelectedDate
|
|
{
|
|
get => (DateTime)GetValue(SelectedDateProperty);
|
|
set => SetValue(SelectedDateProperty, value);
|
|
}
|
|
public Command<string> ToolbarCommand { get; private set; }
|
|
|
|
private double lastScrollY = double.MinValue;
|
|
public bool previousEnabled;
|
|
public bool dateEnabled;
|
|
public bool nextEnabled;
|
|
|
|
private bool isFilterVisible;
|
|
private string lastQueryKey;
|
|
private string queryDate;
|
|
private string previousDate;
|
|
private string nextDate;
|
|
private int currentPage;
|
|
private int nextPage;
|
|
|
|
private string QueryKey => segmentDates[SegmentDate] + (SegmentType == 1 ? "_r18" : string.Empty);
|
|
|
|
public RankingPage()
|
|
{
|
|
Resources.Add("cardView", GetCardViewTemplate());
|
|
ToolbarCommand = new Command<string>(OnDateTrigger, OnCanDateTrigger);
|
|
InitializeComponent();
|
|
gridFilter.TranslationY = -100;
|
|
panelFilter.TranslationY = -100;
|
|
|
|
lastQueryKey = QueryKey;
|
|
queryDate = null; // $"{now.Year}{now.Month:00}{now.Day:00}";
|
|
currentPage = 1;
|
|
|
|
datePicker.MinimumDate = new DateTime(2007, 9, 13);
|
|
MaximumDate = DateTime.Now;
|
|
}
|
|
|
|
protected override void DoIllustsLoaded(IllustCollection collection)
|
|
{
|
|
var now = IllustCollection;
|
|
if (now == null)
|
|
{
|
|
IllustCollection = collection;
|
|
Illusts = collection;
|
|
}
|
|
else
|
|
{
|
|
now = new IllustCollection(now.Concat(collection));
|
|
IllustCollection = now;
|
|
Illusts = now;
|
|
}
|
|
}
|
|
|
|
protected override IEnumerable<IllustItem> DoGetIllustList(IllustRankingData data)
|
|
{
|
|
return data.contents.Select(i => i.ConvertToItem());
|
|
}
|
|
|
|
protected override IllustRankingData DoLoadIllustData(bool force)
|
|
{
|
|
var data = Stores.LoadIllustRankingData(lastQueryKey, queryDate, currentPage, force);
|
|
if (data != null)
|
|
{
|
|
//if (data.contents.Length * data.page < data.rank_total)
|
|
//{
|
|
// nextPage = currentPage + 1;
|
|
//}
|
|
if (int.TryParse(data.next, out int next))
|
|
{
|
|
nextPage = next;
|
|
}
|
|
var date = data.date;
|
|
DateTime now;
|
|
if (date.Length == 8 && int.TryParse(date, out _))
|
|
{
|
|
queryDate = date;
|
|
now = new DateTime(
|
|
int.Parse(date.Substring(0, 4)),
|
|
int.Parse(date.Substring(4, 2)),
|
|
int.Parse(date.Substring(6, 2)));
|
|
SelectedDate = now;
|
|
//date = now.ToShortDateString();
|
|
date = now.ToString("yyyy-MM-dd");
|
|
}
|
|
else
|
|
{
|
|
now = default;
|
|
}
|
|
date = ResourceHelper.GetResource(data.mode, date);
|
|
|
|
var prev = data.prev_date;
|
|
if (int.TryParse(prev, out _))
|
|
{
|
|
previousDate = prev;
|
|
previousEnabled = true;
|
|
}
|
|
else
|
|
{
|
|
previousDate = null;
|
|
previousEnabled = false;
|
|
}
|
|
var next_ = data.next_date;
|
|
if (int.TryParse(next_, out _))
|
|
{
|
|
nextDate = next_;
|
|
nextEnabled = true;
|
|
}
|
|
else
|
|
{
|
|
nextDate = null;
|
|
nextEnabled = false;
|
|
if (now != default)
|
|
{
|
|
MaximumDate = now;
|
|
}
|
|
}
|
|
dateEnabled = true;
|
|
MainThread.BeginInvokeOnMainThread(() =>
|
|
{
|
|
ToolbarCommand.ChangeCanExecute();
|
|
Title = date;
|
|
});
|
|
|
|
}
|
|
return data;
|
|
}
|
|
|
|
private async void ToggleFilterPanel(bool flag)
|
|
{
|
|
ViewExtensions.CancelAnimations(gridFilter);
|
|
ViewExtensions.CancelAnimations(panelFilter);
|
|
if (flag)
|
|
{
|
|
isFilterVisible = true;
|
|
await Task.WhenAll(
|
|
labelCaret.RotateTo(180, easing: Easing.CubicOut),
|
|
gridFilter.TranslateTo(0, 0, easing: Easing.CubicOut),
|
|
gridFilter.FadeTo(1, easing: Easing.CubicOut),
|
|
panelFilter.TranslateTo(0, 0, easing: Easing.CubicOut),
|
|
panelFilter.FadeTo(1, easing: Easing.CubicOut)
|
|
);
|
|
}
|
|
else
|
|
{
|
|
isFilterVisible = false;
|
|
await Task.WhenAll(
|
|
labelCaret.RotateTo(0, easing: Easing.CubicIn),
|
|
gridFilter.TranslateTo(0, -100, easing: Easing.CubicIn),
|
|
gridFilter.FadeTo(0, easing: Easing.CubicIn),
|
|
panelFilter.TranslateTo(0, -100, easing: Easing.CubicIn),
|
|
panelFilter.FadeTo(0, easing: Easing.CubicIn)
|
|
);
|
|
}
|
|
}
|
|
|
|
private void OnDateTrigger(string action)
|
|
{
|
|
if (IsLoading)
|
|
{
|
|
return;
|
|
}
|
|
if (action == "select")
|
|
{
|
|
datePicker.Focus();
|
|
}
|
|
else
|
|
{
|
|
var date = action == "prev" ? previousDate : nextDate;
|
|
if (date == null)
|
|
{
|
|
return;
|
|
}
|
|
if (isFilterVisible)
|
|
{
|
|
ToggleFilterPanel(false);
|
|
}
|
|
// release
|
|
var collection = IllustCollection;
|
|
if (collection != null)
|
|
{
|
|
collection.Running = false;
|
|
IllustCollection = null;
|
|
}
|
|
previousEnabled = false;
|
|
dateEnabled = false;
|
|
nextEnabled = false;
|
|
queryDate = date;
|
|
currentPage = 1;
|
|
StartLoad(true);
|
|
}
|
|
}
|
|
|
|
private bool OnCanDateTrigger(string action)
|
|
{
|
|
switch (action)
|
|
{
|
|
case "prev":
|
|
return previousEnabled;
|
|
case "next":
|
|
return nextEnabled;
|
|
default:
|
|
return dateEnabled;
|
|
}
|
|
}
|
|
|
|
private void DatePicker_DateSelected(object sender, DateChangedEventArgs e)
|
|
{
|
|
if (IsLoading)
|
|
{
|
|
return;
|
|
}
|
|
// release
|
|
var collection = IllustCollection;
|
|
if (collection != null)
|
|
{
|
|
collection.Running = false;
|
|
IllustCollection = null;
|
|
}
|
|
previousEnabled = false;
|
|
dateEnabled = false;
|
|
nextEnabled = false;
|
|
queryDate = e.NewDate.ToString("yyyyMMdd");
|
|
currentPage = 1;
|
|
StartLoad(true);
|
|
}
|
|
|
|
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
|
|
{
|
|
ToggleFilterPanel(!isFilterVisible);
|
|
}
|
|
|
|
private void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
|
|
{
|
|
var y = e.ScrollY;
|
|
if (y > lastScrollY)
|
|
{
|
|
// down
|
|
if (isFilterVisible)
|
|
{
|
|
ToggleFilterPanel(false);
|
|
}
|
|
}
|
|
lastScrollY = y;
|
|
|
|
var bottomOffset = scrollView.ContentSize.Height - (scrollView.LayoutAreaOverride.Height * 2);
|
|
if (y > 0 && y + topOffset > bottomOffset)
|
|
{
|
|
bool refresh = false;
|
|
lock (sync)
|
|
{
|
|
if (IsLoading)
|
|
{
|
|
return;
|
|
}
|
|
App.DebugPrint("bottom arrived.");
|
|
if (nextPage == currentPage + 1)
|
|
{
|
|
currentPage = nextPage;
|
|
refresh = true;
|
|
App.DebugPrint($"loading page {nextPage}");
|
|
}
|
|
}
|
|
if (refresh)
|
|
{
|
|
App.DebugPrint($"start to load page {nextPage}");
|
|
StartLoad(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Filter_Clicked(object sender, EventArgs e)
|
|
{
|
|
var query = QueryKey;
|
|
ToggleFilterPanel(false);
|
|
|
|
bool refresh = false;
|
|
lock (sync)
|
|
{
|
|
if (IsLoading)
|
|
{
|
|
return;
|
|
}
|
|
if (lastQueryKey != query)
|
|
{
|
|
// release
|
|
var collection = IllustCollection;
|
|
if (collection != null)
|
|
{
|
|
collection.Running = false;
|
|
IllustCollection = null;
|
|
}
|
|
// query changed.
|
|
currentPage = 1;
|
|
lastQueryKey = query;
|
|
refresh = true;
|
|
App.DebugPrint($"query changed: {query}");
|
|
}
|
|
}
|
|
if (refresh)
|
|
{
|
|
StartLoad(true);
|
|
}
|
|
}
|
|
}
|
|
}
|