275 lines
9.3 KiB
C#
275 lines
9.3 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using Pixiview.Resources;
|
|
using Pixiview.UI;
|
|
using Pixiview.Utils;
|
|
using Xamarin.Essentials;
|
|
using Xamarin.Forms;
|
|
|
|
namespace Pixiview
|
|
{
|
|
public partial class ViewIllustPage : AdaptedPage
|
|
{
|
|
public static readonly BindableProperty IllustsProperty = BindableProperty.Create(
|
|
nameof(Illusts), typeof(IllustDetailItem[]), typeof(ViewIllustPage));
|
|
public static readonly BindableProperty PagePositionTextProperty = BindableProperty.Create(
|
|
nameof(PagePositionText), typeof(string), typeof(ViewIllustPage));
|
|
public static readonly BindableProperty IsPageVisibleProperty = BindableProperty.Create(
|
|
nameof(IsPageVisible), typeof(bool), typeof(ViewIllustPage));
|
|
public static readonly BindableProperty PageTopMarginProperty = BindableProperty.Create(
|
|
nameof(PageTopMargin), typeof(Thickness), typeof(ViewIllustPage));
|
|
public static readonly BindableProperty IllustItemProperty = BindableProperty.Create(
|
|
nameof(IllustItem), typeof(IllustItem), typeof(ViewIllustPage));
|
|
|
|
public IllustDetailItem[] Illusts
|
|
{
|
|
get => (IllustDetailItem[])GetValue(IllustsProperty);
|
|
set => SetValue(IllustsProperty, value);
|
|
}
|
|
public string PagePositionText
|
|
{
|
|
get => (string)GetValue(PagePositionTextProperty);
|
|
set => SetValue(PagePositionTextProperty, value);
|
|
}
|
|
public bool IsPageVisible
|
|
{
|
|
get => (bool)GetValue(IsPageVisibleProperty);
|
|
set => SetValue(IsPageVisibleProperty, value);
|
|
}
|
|
public Thickness PageTopMargin
|
|
{
|
|
get => (Thickness)GetValue(PageTopMarginProperty);
|
|
set => SetValue(PageTopMarginProperty, value);
|
|
}
|
|
public IllustItem IllustItem
|
|
{
|
|
get => (IllustItem)GetValue(IllustItemProperty);
|
|
private set => SetValue(IllustItemProperty, value);
|
|
}
|
|
|
|
public int CurrentPage { get; private set; }
|
|
|
|
public ViewIllustPage(IllustItem illust)
|
|
{
|
|
IllustItem = illust;
|
|
BindingContext = this;
|
|
|
|
InitializeComponent();
|
|
}
|
|
|
|
public override void OnLoad()
|
|
{
|
|
var illust = IllustItem;
|
|
if (illust == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var items = new IllustDetailItem[illust.PageCount];
|
|
if (items.Length > 1)
|
|
{
|
|
IsPageVisible = true;
|
|
PagePositionText = $"1/{items.Length}";
|
|
}
|
|
else
|
|
{
|
|
IsPageVisible = false;
|
|
}
|
|
|
|
for (var i = 0; i < items.Length; i++)
|
|
{
|
|
items[i] = new IllustDetailItem();
|
|
if (i == 0)
|
|
{
|
|
items[i].Image = illust.Image;
|
|
}
|
|
}
|
|
|
|
Illusts = items;
|
|
UpdatePageTopMargin(CurrentOrientation);
|
|
Task.Run(DoLoadImages);
|
|
}
|
|
|
|
private void CarouselView_PositionChanged(object sender, PositionChangedEventArgs e)
|
|
{
|
|
var index = e.CurrentPosition;
|
|
CurrentPage = index;
|
|
var items = Illusts;
|
|
var length = items.Length;
|
|
PagePositionText = $"{index + 1}/{length}";
|
|
|
|
var item = items[index];
|
|
if (!item.Loading && item.Image == null)
|
|
{
|
|
Task.Run(() => DoLoadImage(index));
|
|
}
|
|
if (index < length - 1)
|
|
{
|
|
item = items[index + 1];
|
|
if (!item.Loading && item.Image == null)
|
|
{
|
|
Task.Run(() => DoLoadImage(index + 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Page_OrientationChanged(object sender, OrientationEventArgs e)
|
|
{
|
|
UpdatePageTopMargin(e.CurrentOrientation);
|
|
}
|
|
|
|
private void UpdatePageTopMargin(Orientation orientation)
|
|
{
|
|
switch (orientation)
|
|
{
|
|
case Orientation.Portrait:
|
|
PageTopMargin = StyleDefinition.TotalBarOffset;
|
|
break;
|
|
case Orientation.PortraitUpsideDown:
|
|
if (DeviceInfo.Idiom == DeviceIdiom.Phone)
|
|
{
|
|
PageTopMargin = StyleDefinition.NavigationBarOffset;
|
|
}
|
|
else
|
|
{
|
|
PageTopMargin = StyleDefinition.TotalBarOffset;
|
|
}
|
|
break;
|
|
case Orientation.Unknown:
|
|
case Orientation.LandscapeLeft:
|
|
case Orientation.LandscapeRight:
|
|
default:
|
|
PageTopMargin = StyleDefinition.NavigationBarOffset;
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void DoLoadImages()
|
|
{
|
|
var pages = Stores.LoadIllustPageData(IllustItem.Id);
|
|
if (pages == null)
|
|
{
|
|
App.DebugError("illustPage.load", $"failed to load illust page data, id: {IllustItem.Id}");
|
|
return;
|
|
}
|
|
var items = Illusts;
|
|
if (pages.body.Length > items.Length)
|
|
{
|
|
App.DebugPrint($"local page count ({items.Length}) is not equals the remote one ({pages.body.Length})");
|
|
var tmp = new IllustDetailItem[pages.body.Length];
|
|
items.CopyTo(items, 0);
|
|
for (var i = items.Length; i < tmp.Length; i++)
|
|
{
|
|
tmp[i] = new IllustDetailItem();
|
|
}
|
|
items = tmp;
|
|
}
|
|
|
|
for (var i = 0; i < items.Length; i++)
|
|
{
|
|
var item = items[i];
|
|
var p = pages.body[i];
|
|
item.PreviewUrl = p.urls.regular;
|
|
item.OriginalUrl = p.urls.original;
|
|
}
|
|
|
|
DoLoadImage(0);
|
|
if (items.Length > 1)
|
|
{
|
|
DoLoadImage(1);
|
|
}
|
|
}
|
|
|
|
private void DoLoadImage(int index)
|
|
{
|
|
var items = Illusts;
|
|
if (index < 0 || index >= items.Length)
|
|
{
|
|
App.DebugPrint($"invalid index: {index}");
|
|
return;
|
|
}
|
|
|
|
var item = items[index];
|
|
if (item.Loading || (index > 0 && item.Image != null))
|
|
{
|
|
App.DebugPrint($"skipped, loading or already loaded, index: {index}, loading: {item.Loading}");
|
|
return;
|
|
}
|
|
item.Loading = true;
|
|
var image = Stores.LoadPreviewImage(item.PreviewUrl);
|
|
if (image != null)
|
|
{
|
|
item.Image = image;
|
|
}
|
|
item.Loading = false;
|
|
}
|
|
|
|
private async void Download_Clicked(object sender, EventArgs e)
|
|
{
|
|
var status = await Permissions.CheckStatusAsync<Permissions.Photos>();
|
|
if (status != PermissionStatus.Granted)
|
|
{
|
|
status = await Permissions.RequestAsync<Permissions.Photos>();
|
|
if (status != PermissionStatus.Granted)
|
|
{
|
|
App.DebugPrint("access denied to gallery.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
var item = Illusts[CurrentPage];
|
|
if (item.Downloading)
|
|
{
|
|
return;
|
|
}
|
|
item.Downloading = true;
|
|
_ = Task.Run(() => DoLoadOriginalImage(item));
|
|
}
|
|
|
|
private void DoLoadOriginalImage(IllustDetailItem item)
|
|
{
|
|
var image = Stores.LoadIllustImage(item.OriginalUrl);
|
|
if (image != null)
|
|
{
|
|
Device.BeginInvokeOnMainThread(async () =>
|
|
{
|
|
var service = DependencyService.Get<IFileStore>();
|
|
var result = await service.SaveImageToGalleryAsync(image);
|
|
|
|
string message = result ?? ResourceHelper.SaveSuccess;
|
|
await DisplayAlert(ResourceHelper.Title, message, ResourceHelper.Ok);
|
|
});
|
|
}
|
|
item.Downloading = false;
|
|
}
|
|
}
|
|
|
|
public class IllustDetailItem : BindableObject
|
|
{
|
|
public static readonly BindableProperty ImageProperty = BindableProperty.Create(
|
|
nameof(Image), typeof(ImageSource), typeof(IllustDetailItem));
|
|
public static readonly BindableProperty LoadingProperty = BindableProperty.Create(
|
|
nameof(Loading), typeof(bool), typeof(IllustDetailItem));
|
|
public static readonly BindableProperty DownloadingProperty = BindableProperty.Create(
|
|
nameof(Downloading), typeof(bool), typeof(IllustDetailItem));
|
|
|
|
public ImageSource Image
|
|
{
|
|
get => (ImageSource)GetValue(ImageProperty);
|
|
set => SetValue(ImageProperty, value);
|
|
}
|
|
public bool Loading
|
|
{
|
|
get => (bool)GetValue(LoadingProperty);
|
|
set => SetValue(LoadingProperty, value);
|
|
}
|
|
public bool Downloading
|
|
{
|
|
get => (bool)GetValue(DownloadingProperty);
|
|
set => SetValue(DownloadingProperty, value);
|
|
}
|
|
public string PreviewUrl { get; set; }
|
|
public string OriginalUrl { get; set; }
|
|
}
|
|
}
|