* Pixiview/UI/CircleUIs.cs:
* Pixiview.iOS/Pixiview.iOS.csproj: * Pixiview.iOS/Renderers/RoundLabelRenderer.cs: * Pixiview.iOS/Renderers/CircleImageRenderer.cs: custom round corner controls * Pixiview/App.xaml: * Pixiview/Utils/Converters.cs: * Pixiview/GlobalSuppressions.cs: * Pixiview/UI/StyleDefinition.cs: * Pixiview/UI/AdaptedPage.cs: * Pixiview.iOS/Renderers/AdaptedPageRenderer.cs: observe orientation * Pixiview/MainPage.xaml: * Pixiview/Utils/Stores.cs: * Pixiview/MainPage.xaml.cs: * Pixiview/Utils/IllustData.cs: data and UI adjust
This commit is contained in:
parent
e7fbee8d41
commit
66f0c1ba1b
@ -70,6 +70,8 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Renderers\AdaptedPageRenderer.cs" />
|
||||
<Compile Include="Services\EnvironmentService.cs" />
|
||||
<Compile Include="Renderers\CircleImageRenderer.cs" />
|
||||
<Compile Include="Renderers\RoundLabelRenderer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<InterfaceDefinition Include="Resources\LaunchScreen.storyboard" />
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Foundation;
|
||||
using Pixiview.iOS.Renderers;
|
||||
using Pixiview.UI;
|
||||
using Pixiview.Utils;
|
||||
@ -11,6 +12,9 @@ namespace Pixiview.iOS.Renderers
|
||||
{
|
||||
public class AdaptedPageRenderer : PageRenderer
|
||||
{
|
||||
UIDeviceOrientation lastOrientation;
|
||||
NSObject observer;
|
||||
|
||||
public override void ViewDidLoad()
|
||||
{
|
||||
base.ViewDidLoad();
|
||||
@ -30,6 +34,20 @@ namespace Pixiview.iOS.Renderers
|
||||
{
|
||||
SetStatusBarStyle(style);
|
||||
}
|
||||
|
||||
observer = UIDevice.Notifications.ObserveOrientationDidChange(ChangeOrientation);
|
||||
ChangeOrientation(null, null);
|
||||
}
|
||||
|
||||
public override void ViewWillDisappear(bool animated)
|
||||
{
|
||||
if (observer != null)
|
||||
{
|
||||
observer.Dispose();
|
||||
observer = null;
|
||||
}
|
||||
|
||||
base.ViewWillDisappear(animated);
|
||||
}
|
||||
|
||||
private void SetStatusBarStyle(UIStatusBarStyle style)
|
||||
@ -64,5 +82,23 @@ namespace Pixiview.iOS.Renderers
|
||||
return UIStatusBarStyle.Default;
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeOrientation(object sender, NSNotificationEventArgs e)
|
||||
{
|
||||
var current = UIDevice.CurrentDevice.Orientation;
|
||||
if (current == UIDeviceOrientation.FaceUp || current == UIDeviceOrientation.FaceDown)
|
||||
{
|
||||
//current = UIDeviceOrientation.Portrait;
|
||||
return;
|
||||
}
|
||||
if (lastOrientation != current)
|
||||
{
|
||||
lastOrientation = current;
|
||||
if (Element is AdaptedPage page)
|
||||
{
|
||||
page.OnOrientationChanged((Orientation)lastOrientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
31
Pixiview.iOS/Renderers/CircleImageRenderer.cs
Normal file
31
Pixiview.iOS/Renderers/CircleImageRenderer.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using Pixiview.iOS.Renderers;
|
||||
using Pixiview.UI;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.iOS;
|
||||
|
||||
[assembly: ExportRenderer(typeof(CircleImage), typeof(CircleImageRenderer))]
|
||||
namespace Pixiview.iOS.Renderers
|
||||
{
|
||||
public class CircleImageRenderer : ImageRenderer
|
||||
{
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
||||
if (Control != null)
|
||||
{
|
||||
Control.Layer.MasksToBounds = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void LayoutSubviews()
|
||||
{
|
||||
base.LayoutSubviews();
|
||||
|
||||
if (Control != null)
|
||||
{
|
||||
Control.Layer.CornerRadius = Control.Frame.Size.Width / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
47
Pixiview.iOS/Renderers/RoundLabelRenderer.cs
Normal file
47
Pixiview.iOS/Renderers/RoundLabelRenderer.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using System.ComponentModel;
|
||||
using Pixiview.iOS.Renderers;
|
||||
using Pixiview.UI;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.iOS;
|
||||
|
||||
[assembly: ExportRenderer(typeof(RoundLabel), typeof(RoundLabelRenderer))]
|
||||
namespace Pixiview.iOS.Renderers
|
||||
{
|
||||
public class RoundLabelRenderer : LabelRenderer
|
||||
{
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
||||
if (Control != null && Element is RoundLabel label)
|
||||
{
|
||||
int radius = label.CornerRadius;
|
||||
if (radius > 0)
|
||||
{
|
||||
Control.Layer.CornerRadius = radius;
|
||||
Control.BackgroundColor = label.BackgroundColor.ToUIColor();
|
||||
Control.Layer.MasksToBounds = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
if (e.PropertyName == RoundLabel.CornerRadiusProperty.PropertyName)
|
||||
{
|
||||
if (Control != null && Element is RoundLabel label)
|
||||
{
|
||||
int radius = label.CornerRadius;
|
||||
if (radius > 0)
|
||||
{
|
||||
Control.Layer.CornerRadius = radius;
|
||||
Control.BackgroundColor = label.BackgroundColor.ToUIColor();
|
||||
Control.Layer.MasksToBounds = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
<Application.Resources>
|
||||
<Color x:Key="WindowColor">Black</Color>
|
||||
<Color x:Key="TextColor">White</Color>
|
||||
<Color x:Key="SubTextColor">LightGray</Color>
|
||||
<Color x:Key="MainColor">#333333</Color>
|
||||
<Color x:Key="MainTextColor">White</Color>
|
||||
<Style x:Key="TitleLabel" TargetType="Label">
|
||||
|
@ -6,3 +6,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
[assembly: SuppressMessage("Style", "IDE0063:Use simple 'using' statement", Justification = "<Pending>")]
|
||||
[assembly: SuppressMessage("Style", "IDE0066:Convert switch statement to expression", Justification = "<Pending>")]
|
||||
|
@ -5,14 +5,63 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:u="clr-namespace:Pixiview.UI"
|
||||
mc:Ignorable="d"
|
||||
x:Class="Pixiview.MainPage">
|
||||
x:Class="Pixiview.MainPage"
|
||||
BackgroundColor="{DynamicResource WindowColor}"
|
||||
OrientationChanged="Page_OrientationChanged">
|
||||
<NavigationPage.TitleView>
|
||||
<u:NavigationTitle Title="Startup Name Generator"
|
||||
<u:NavigationTitle Title="Follow"
|
||||
IsLeftButtonVisible="True"
|
||||
LeftButtonClicked="NavigationTitle_LeftButtonClicked"
|
||||
RightButtonClicked="NavigationTitle_RightButtonClicked"/>
|
||||
</NavigationPage.TitleView>
|
||||
<Grid>
|
||||
|
||||
</Grid>
|
||||
<ScrollView HorizontalOptions="Fill" Padding="{Binding StatusBarPadding}">
|
||||
<u:FlowLayout ItemsSource="{Binding Illusts}"
|
||||
HorizontalOptions="Fill" Column="{Binding Columns}"
|
||||
Margin="16" RowSpacing="16" ColumnSpacing="16">
|
||||
<u:FlowLayout.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Frame HasShadow="False" Padding="0" Margin="0" CornerRadius="10"
|
||||
BackgroundColor="{DynamicResource MainColor}">
|
||||
<Grid HorizontalOptions="Fill" Margin="0, -5, 0, 0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Image BackgroundColor="LightGray"
|
||||
Source="{Binding Image}"
|
||||
HorizontalOptions="Fill"
|
||||
Aspect="AspectFit"/>
|
||||
<u:RoundLabel Text="R-18" BackgroundColor="#fd4363" Margin="6, 11, 0, 0"
|
||||
Padding="6, 2" CornerRadius="4"
|
||||
HorizontalOptions="Start" VerticalOptions="Start"
|
||||
FontSize="Micro" TextColor="White"
|
||||
IsVisible="{Binding IsRestrict}"/>
|
||||
<u:RoundLabel Text="{Binding PageCountText}"
|
||||
FontFamily="{DynamicResource IconSolidFontFamily}"
|
||||
BackgroundColor="#50000000" Margin="0, 11, 6, 0"
|
||||
Padding="6, 4" CornerRadius="6"
|
||||
HorizontalOptions="End" VerticalOptions="Start"
|
||||
FontSize="Micro" TextColor="White"
|
||||
IsVisible="{Binding IsPageVisible}"/>
|
||||
<Label Grid.Row="1" Text="{Binding Title}"
|
||||
Padding="8, 2"
|
||||
TextColor="{DynamicResource TextColor}"
|
||||
LineBreakMode="TailTruncation"
|
||||
FontSize="Small"/>
|
||||
<StackLayout Grid.Row="2" Orientation="Horizontal" Padding="8, 0, 8, 8">
|
||||
<u:CircleImage WidthRequest="30" HeightRequest="30" Aspect="AspectFill"
|
||||
Source="{Binding ProfileImage}"/>
|
||||
<Label Text="{Binding UserName}"
|
||||
VerticalOptions="Center"
|
||||
TextColor="{DynamicResource SubTextColor}"
|
||||
LineBreakMode="TailTruncation"
|
||||
FontSize="Micro"/>
|
||||
</StackLayout>
|
||||
</Grid>
|
||||
</Frame>
|
||||
</DataTemplate>
|
||||
</u:FlowLayout.ItemTemplate>
|
||||
</u:FlowLayout>
|
||||
</ScrollView>
|
||||
</u:AdaptedPage>
|
@ -1,8 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Pixiview.UI;
|
||||
using Pixiview.Utils;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Pixiview
|
||||
{
|
||||
@ -11,24 +15,115 @@ namespace Pixiview
|
||||
[DesignTimeVisible(false)]
|
||||
public partial class MainPage : AdaptedPage
|
||||
{
|
||||
public static readonly BindableProperty IllustsProperty = BindableProperty.Create(
|
||||
nameof(Illusts), typeof(IllustCollection), typeof(MainPage));
|
||||
public static readonly BindableProperty ColumnsProperty = BindableProperty.Create(
|
||||
nameof(Columns), typeof(int), typeof(MainPage), 2);
|
||||
|
||||
public IllustCollection Illusts
|
||||
{
|
||||
get => (IllustCollection)GetValue(IllustsProperty);
|
||||
set => SetValue(IllustsProperty, value);
|
||||
}
|
||||
public int Columns
|
||||
{
|
||||
get => (int)GetValue(ColumnsProperty);
|
||||
set => SetValue(ColumnsProperty, value);
|
||||
}
|
||||
|
||||
private readonly ParallelOptions parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Configs.MaxThreads };
|
||||
|
||||
private IllustData illustData;
|
||||
|
||||
public MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = this;
|
||||
}
|
||||
|
||||
public override void OnLoad()
|
||||
{
|
||||
App.DebugPrint($"folder: {Stores.PersonalFolder}");
|
||||
Task.Run(async () =>
|
||||
Task.Run(DoLoadIllusts);
|
||||
}
|
||||
|
||||
async void DoLoadIllusts()
|
||||
{
|
||||
illustData = await Stores.LoadIllustData();
|
||||
|
||||
var data = illustData.body.page.follow.Select(i =>
|
||||
{
|
||||
illustData = await Stores.LoadIllustData();
|
||||
App.DebugPrint(illustData.message);
|
||||
var illust = illustData.body.thumbnails.illust.FirstOrDefault(l => l.illustId == i.ToString());
|
||||
if (illust == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new IllustItem
|
||||
{
|
||||
ImageUrl = illust.urls.x360 ?? illust.url,
|
||||
Title = illust.illustTitle,
|
||||
IsRestrict = illust.xRestrict == 1,
|
||||
ProfileUrl = illust.profileImageUrl,
|
||||
UserName = illust.userName,
|
||||
Width = illust.width,
|
||||
Height = illust.height,
|
||||
PageCount = illust.pageCount
|
||||
};
|
||||
}).Where(i => i != null);
|
||||
|
||||
var collection = new IllustCollection(data);
|
||||
Illusts = collection;
|
||||
|
||||
DoLoadImages(collection);
|
||||
}
|
||||
|
||||
void DoLoadImages(IllustCollection collection)
|
||||
{
|
||||
Parallel.ForEach(collection, parallelOptions, illust =>
|
||||
{
|
||||
if (!collection.Running)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (illust.ImageUrl != null)
|
||||
{
|
||||
var url = Configs.GetThumbnailUrl(illust.ImageUrl);
|
||||
var image = Stores.LoadThumbnailImage(url);
|
||||
if (image != null)
|
||||
{
|
||||
illust.Image = image;
|
||||
}
|
||||
}
|
||||
|
||||
if (illust.ProfileUrl != null)
|
||||
{
|
||||
var userImage = Stores.LoadUserProfileImage(illust.ProfileUrl);
|
||||
if (userImage != null)
|
||||
{
|
||||
illust.ProfileImage = userImage;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Page_OrientationChanged(object sender, OrientationEventArgs e)
|
||||
{
|
||||
switch (e.CurrentOrientation)
|
||||
{
|
||||
case Orientation.Portrait:
|
||||
Columns = 2;
|
||||
break;
|
||||
case Orientation.Unknown:
|
||||
case Orientation.PortraitUpsideDown:
|
||||
case Orientation.LandscapeLeft:
|
||||
case Orientation.LandscapeRight:
|
||||
default:
|
||||
Columns = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationTitle_RightButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
}
|
||||
@ -38,4 +133,57 @@ namespace Pixiview
|
||||
DisplayAlert("title", "message", "Ok");
|
||||
}
|
||||
}
|
||||
|
||||
public class IllustCollection : ObservableCollection<IllustItem>
|
||||
{
|
||||
private static readonly object sync = new object();
|
||||
|
||||
public IllustCollection(IEnumerable<IllustItem> illusts) : base(illusts)
|
||||
{
|
||||
running = true;
|
||||
}
|
||||
|
||||
private bool running;
|
||||
public bool Running
|
||||
{
|
||||
get => running;
|
||||
set
|
||||
{
|
||||
lock (sync)
|
||||
{
|
||||
running = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class IllustItem : BindableObject
|
||||
{
|
||||
public static readonly BindableProperty ImageProperty = BindableProperty.Create(
|
||||
nameof(Image), typeof(ImageSource), typeof(IllustItem));
|
||||
public static readonly BindableProperty ProfileImageProperty = BindableProperty.Create(
|
||||
nameof(ProfileImage), typeof(ImageSource), typeof(IllustItem));
|
||||
|
||||
public ImageSource Image
|
||||
{
|
||||
get => (ImageSource)GetValue(ImageProperty);
|
||||
set => SetValue(ImageProperty, value);
|
||||
}
|
||||
public ImageSource ProfileImage
|
||||
{
|
||||
get => (ImageSource)GetValue(ProfileImageProperty);
|
||||
set => SetValue(ProfileImageProperty, value);
|
||||
}
|
||||
|
||||
public string ImageUrl { get; set; }
|
||||
public string Title { get; set; }
|
||||
public bool IsRestrict { get; set; }
|
||||
public string ProfileUrl { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
public int PageCount { get; set; }
|
||||
public string PageCountText => $"{StyleDefinition.IconLayer} {PageCount}";
|
||||
public bool IsPageVisible => PageCount > 1;
|
||||
}
|
||||
}
|
||||
|
@ -5,16 +5,56 @@ namespace Pixiview.UI
|
||||
{
|
||||
public class AdaptedPage : ContentPage
|
||||
{
|
||||
public event EventHandler Load;
|
||||
static readonly Thickness LandscapeLeftPadding = new Thickness(34, 0, 0, 0);
|
||||
static readonly Thickness LandscapeRightPadding = new Thickness(0, 0, 34, 0);
|
||||
|
||||
public AdaptedPage()
|
||||
public static readonly BindableProperty StatusBarPaddingProperty = BindableProperty.Create(
|
||||
nameof(StatusBarPadding), typeof(Thickness), typeof(AdaptedPage), default(Thickness));
|
||||
|
||||
public Thickness StatusBarPadding
|
||||
{
|
||||
SetDynamicResource(BackgroundColorProperty, App.WindowColor);
|
||||
get => (Thickness)GetValue(StatusBarPaddingProperty);
|
||||
set => SetValue(StatusBarPaddingProperty, value);
|
||||
}
|
||||
|
||||
public event EventHandler Load;
|
||||
public event EventHandler<OrientationEventArgs> OrientationChanged;
|
||||
|
||||
public virtual void OnLoad()
|
||||
{
|
||||
Load?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public virtual void OnOrientationChanged(Orientation orientation)
|
||||
{
|
||||
if (orientation == Orientation.LandscapeLeft || orientation == Orientation.PortraitUpsideDown)
|
||||
{
|
||||
StatusBarPadding = StyleDefinition.IsFullscreenDevice ? LandscapeLeftPadding : default;
|
||||
}
|
||||
else if (orientation == Orientation.LandscapeRight)
|
||||
{
|
||||
StatusBarPadding = StyleDefinition.IsFullscreenDevice ? LandscapeRightPadding : default;
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusBarPadding = default;
|
||||
}
|
||||
|
||||
OrientationChanged?.Invoke(this, new OrientationEventArgs { CurrentOrientation = orientation });
|
||||
}
|
||||
}
|
||||
|
||||
public class OrientationEventArgs : EventArgs
|
||||
{
|
||||
public Orientation CurrentOrientation { get; set; }
|
||||
}
|
||||
|
||||
public enum Orientation
|
||||
{
|
||||
Unknown,
|
||||
Portrait,
|
||||
PortraitUpsideDown,
|
||||
LandscapeLeft,
|
||||
LandscapeRight
|
||||
}
|
||||
}
|
||||
|
25
Pixiview/UI/CircleUIs.cs
Normal file
25
Pixiview/UI/CircleUIs.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Pixiview.UI
|
||||
{
|
||||
public class CircleImage : Image { }
|
||||
|
||||
public class RoundLabel : Label
|
||||
{
|
||||
public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(
|
||||
nameof(CornerRadius), typeof(int), typeof(RoundLabel));
|
||||
public static new readonly BindableProperty BackgroundColorProperty = BindableProperty.Create(
|
||||
nameof(BackgroundColor), typeof(Color), typeof(RoundLabel), Color.Transparent);
|
||||
|
||||
public int CornerRadius
|
||||
{
|
||||
get => (int)GetValue(CornerRadiusProperty);
|
||||
set => SetValue(CornerRadiusProperty, value);
|
||||
}
|
||||
public new Color BackgroundColor
|
||||
{
|
||||
get => (Color)GetValue(BackgroundColorProperty);
|
||||
set => SetValue(BackgroundColorProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,86 @@
|
||||
using Xamarin.Forms;
|
||||
using System;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Pixiview.UI
|
||||
{
|
||||
public static class StyleDefinition
|
||||
{
|
||||
public static readonly double FontSizeTitle = 18.0;
|
||||
public static readonly double FontSizeTitleIcon = 24.0;
|
||||
public const double FontSizeTitle = 18.0;
|
||||
public const double FontSizeTitleIcon = 24.0;
|
||||
|
||||
public static readonly Thickness HorizonLeft10 = new Thickness(10, 0, 0, 0);
|
||||
public static readonly Thickness HorizonRight10 = new Thickness(0, 0, 10, 0);
|
||||
public static readonly Thickness LeftBottom10 = new Thickness(10, 0, 0, 10);
|
||||
|
||||
public const string IconLayer = "\uf302";
|
||||
|
||||
private static bool? _isFullscreenDevice;
|
||||
public static bool IsFullscreenDevice
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_isFullscreenDevice != null)
|
||||
{
|
||||
return _isFullscreenDevice.Value;
|
||||
}
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
try
|
||||
{
|
||||
var model = DeviceInfo.Model;
|
||||
if (model == "iPhone10,3")
|
||||
{
|
||||
// iPhone X
|
||||
_isFullscreenDevice = true;
|
||||
}
|
||||
else if (model.StartsWith("iPhone"))
|
||||
{
|
||||
var vs = model.Substring(6).Split(',');
|
||||
if (vs.Length == 2 && int.TryParse(vs[0], out int main) && int.TryParse(vs[1], out int sub))
|
||||
{
|
||||
// iPhone X/XS/XR or iPhone 11
|
||||
_isFullscreenDevice = (main == 10 && sub >= 6) || (main > 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
_isFullscreenDevice = false;
|
||||
}
|
||||
}
|
||||
else if (model.StartsWith("iPad8,"))
|
||||
{
|
||||
// iPad 11-inch or 12.9-inch (3rd+)
|
||||
_isFullscreenDevice = true;
|
||||
}
|
||||
#if DEBUG
|
||||
else
|
||||
{
|
||||
// iPad or Simulator
|
||||
var name = DeviceInfo.Name;
|
||||
_isFullscreenDevice = name.StartsWith("iPhone X")
|
||||
|| name.StartsWith("iPhone 11")
|
||||
|| name.StartsWith("iPad Pro (11-inch)")
|
||||
|| name.StartsWith("iPad Pro (12.9-inch) (3rd generation)")
|
||||
|| name.StartsWith("iPad Pro (12.9-inch) (4th generation)");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
App.DebugError("device.get", $"failed to get the device model. {ex.Message}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO:
|
||||
_isFullscreenDevice = false;
|
||||
}
|
||||
if (_isFullscreenDevice == null)
|
||||
{
|
||||
_isFullscreenDevice = false;
|
||||
}
|
||||
return _isFullscreenDevice.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
20
Pixiview/Utils/Converters.cs
Normal file
20
Pixiview/Utils/Converters.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Pixiview.UI;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Pixiview.Utils
|
||||
{
|
||||
public class PageConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return StyleDefinition.IconLayer + value;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -72,11 +72,13 @@ namespace Pixiview.Utils
|
||||
public string userName;
|
||||
public int width;
|
||||
public int height;
|
||||
public int pageCount;
|
||||
public string alt;
|
||||
public IllustUrls urls;
|
||||
public string seriesId;
|
||||
public string seriesTitle;
|
||||
public string profileImageUrl;
|
||||
public int xRestrict;
|
||||
|
||||
public class IllustUrls
|
||||
{
|
||||
|
@ -6,6 +6,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Pixiview.Utils
|
||||
{
|
||||
@ -14,6 +15,7 @@ namespace Pixiview.Utils
|
||||
public static readonly string PersonalFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
|
||||
//public static readonly string CacheFolder = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache);
|
||||
private const string imageFolder = "img-master";
|
||||
private const string thumbFolder = "img-thumb";
|
||||
private const string userFolder = "user-profile";
|
||||
private const string illustFile = "illust.json";
|
||||
|
||||
@ -67,35 +69,46 @@ namespace Pixiview.Utils
|
||||
}
|
||||
}
|
||||
|
||||
public static string LoadIllustImage(string url)
|
||||
public static ImageSource LoadIllustImage(string url)
|
||||
{
|
||||
return LoadImage(url, imageFolder);
|
||||
}
|
||||
|
||||
public static string LoadUserProfileImage(string url)
|
||||
public static ImageSource LoadThumbnailImage(string url)
|
||||
{
|
||||
return LoadImage(url, thumbFolder);
|
||||
}
|
||||
|
||||
public static ImageSource LoadUserProfileImage(string url)
|
||||
{
|
||||
return LoadImage(url, userFolder);
|
||||
}
|
||||
|
||||
public static string LoadImage(string url, string folder)
|
||||
public static ImageSource LoadImage(string url, string folder)
|
||||
{
|
||||
var file = Path.Combine(PersonalFolder, imageFolder, Path.GetFileName(url));
|
||||
if (File.Exists(file))
|
||||
var file = Path.Combine(PersonalFolder, folder, Path.GetFileName(url));
|
||||
if (!File.Exists(file))
|
||||
{
|
||||
return file;
|
||||
file = DownloadImage(url, folder);
|
||||
}
|
||||
else
|
||||
if (file != null)
|
||||
{
|
||||
file = DownloadImage(url, folder).Result;
|
||||
return file;
|
||||
return ImageSource.FromFile(file);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static async Task<string> DownloadImage(string url, string folder)
|
||||
public static string DownloadImage(string url, string folder)
|
||||
{
|
||||
try
|
||||
{
|
||||
var file = Path.Combine(PersonalFolder, folder, Path.GetFileName(url));
|
||||
var directory = Path.Combine(PersonalFolder, folder);
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
var file = Path.Combine(directory, Path.GetFileName(url));
|
||||
App.DebugPrint($"download, url: {url}");
|
||||
var response = Download(url);
|
||||
if (response == null)
|
||||
{
|
||||
@ -104,11 +117,11 @@ namespace Pixiview.Utils
|
||||
using (response)
|
||||
using (var fs = File.OpenWrite(file))
|
||||
{
|
||||
await response.Content.CopyToAsync(fs);
|
||||
if (response.Headers.Date != null)
|
||||
{
|
||||
File.SetLastWriteTimeUtc(file, response.Headers.Date.Value.UtcDateTime);
|
||||
}
|
||||
response.Content.CopyToAsync(fs).Wait();
|
||||
//if (response.Headers.Date != null)
|
||||
//{
|
||||
// File.SetLastWriteTimeUtc(file, response.Headers.Date.Value.UtcDateTime);
|
||||
//}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
@ -156,6 +169,7 @@ namespace Pixiview.Utils
|
||||
})
|
||||
{
|
||||
request.Headers.Referrer = referer == null ? Configs.Referer : new Uri(referer);
|
||||
request.Headers.Add("user-agent", Configs.UserAgent);
|
||||
if (headers != null)
|
||||
{
|
||||
foreach (var (header, value) in headers)
|
||||
@ -173,6 +187,8 @@ namespace Pixiview.Utils
|
||||
public static readonly WebProxy Proxy = new WebProxy("10.0.10.100", 8088);
|
||||
public static readonly Uri Referer = new Uri("https://www.pixiv.net/");
|
||||
|
||||
public const int MaxThreads = 3;
|
||||
public const string UserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36";
|
||||
public const string UrlIllust = "https://www.pixiv.net/ajax/top/illust?mode=all&lang=zh";
|
||||
public const string Cookie = "first_visit_datetime_pc=2019-10-29+22%3A05%3A30; p_ab_id=2; p_ab_id_2=6;" +
|
||||
" p_ab_d_id=1155161977; a_type=0; b_type=1; d_type=2; module_orders_mypage=%5B%7B%22name%22%3A%22s" +
|
||||
@ -188,5 +204,20 @@ namespace Pixiview.Utils
|
||||
"SID=2603358_VHyGPeRaz7LpeoFkRsHvjXIpApCMb56a; __cfduid=d9fa2d4d1ddd30db85ebb519f9855d256158780674" +
|
||||
"7; privacy_policy_agreement=2";
|
||||
public const string UserId = "2603358";
|
||||
|
||||
public static string GetThumbnailUrl(string url)
|
||||
{
|
||||
url = url.Replace("/custom-thumb/", "/img-master/");
|
||||
var index = url.LastIndexOf("_square1200.jpg");
|
||||
if (index < 0)
|
||||
{
|
||||
index = url.LastIndexOf("_custom1200.jpg");
|
||||
}
|
||||
if (index >= 0)
|
||||
{
|
||||
return url.Substring(0, index) + "_master1200.jpg";
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user