feature: long press to save original illust
This commit is contained in:
parent
e2ecabc224
commit
59cc3a77c9
58
Pixiview.iOS/Effects/LongPressEffectImplement.cs
Normal file
58
Pixiview.iOS/Effects/LongPressEffectImplement.cs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Pixiview.iOS.Effects;
|
||||||
|
using Pixiview.Utils;
|
||||||
|
using UIKit;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Platform.iOS;
|
||||||
|
|
||||||
|
[assembly: ResolutionGroupName("Pixiview")]
|
||||||
|
[assembly: ExportEffect(typeof(LongPressEffectImplement), "LongPressEffect")]
|
||||||
|
namespace Pixiview.iOS.Effects
|
||||||
|
{
|
||||||
|
public class LongPressEffectImplement : PlatformEffect
|
||||||
|
{
|
||||||
|
private bool attached;
|
||||||
|
private readonly UILongPressGestureRecognizer longPressGesture;
|
||||||
|
|
||||||
|
public LongPressEffectImplement()
|
||||||
|
{
|
||||||
|
longPressGesture = new UILongPressGestureRecognizer(OnLongPressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAttached()
|
||||||
|
{
|
||||||
|
if (!attached)
|
||||||
|
{
|
||||||
|
attached = true;
|
||||||
|
Container.AddGestureRecognizer(longPressGesture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDetached()
|
||||||
|
{
|
||||||
|
if (attached)
|
||||||
|
{
|
||||||
|
attached = false;
|
||||||
|
Container.RemoveGestureRecognizer(longPressGesture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnLongPressed(UILongPressGestureRecognizer e)
|
||||||
|
{
|
||||||
|
if (e.State != UIGestureRecognizerState.Began)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var element = Element;
|
||||||
|
if (element != null)
|
||||||
|
{
|
||||||
|
var command = LongPressEffect.GetCommand(element);
|
||||||
|
if (command != null)
|
||||||
|
{
|
||||||
|
var o = LongPressEffect.GetCommandParameter(element);
|
||||||
|
command.Execute(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -79,6 +79,7 @@
|
|||||||
<Compile Include="Renderers\AppShellRenderer.cs" />
|
<Compile Include="Renderers\AppShellRenderer.cs" />
|
||||||
<Compile Include="Renderers\AppShellSection\AppShellSectionRootHeader.cs" />
|
<Compile Include="Renderers\AppShellSection\AppShellSectionRootHeader.cs" />
|
||||||
<Compile Include="Renderers\SegmentedControlRenderer.cs" />
|
<Compile Include="Renderers\SegmentedControlRenderer.cs" />
|
||||||
|
<Compile Include="Effects\LongPressEffectImplement.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<InterfaceDefinition Include="Resources\LaunchScreen.storyboard" />
|
<InterfaceDefinition Include="Resources\LaunchScreen.storyboard" />
|
||||||
@ -148,6 +149,7 @@
|
|||||||
<Folder Include="Renderers\" />
|
<Folder Include="Renderers\" />
|
||||||
<Folder Include="Services\" />
|
<Folder Include="Services\" />
|
||||||
<Folder Include="Renderers\AppShellSection\" />
|
<Folder Include="Renderers\AppShellSection\" />
|
||||||
|
<Folder Include="Effects\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<BundleResource Include="Resources\fa-light-300.ttf" />
|
<BundleResource Include="Resources\fa-light-300.ttf" />
|
||||||
|
@ -29,29 +29,28 @@ namespace Pixiview.iOS.Services
|
|||||||
#region - Theme -
|
#region - Theme -
|
||||||
|
|
||||||
[SuppressMessage("Code Notifications", "XI0002:Notifies you from using newer Apple APIs when targeting an older OS version", Justification = "<Pending>")]
|
[SuppressMessage("Code Notifications", "XI0002:Notifies you from using newer Apple APIs when targeting an older OS version", Justification = "<Pending>")]
|
||||||
public Theme GetApplicationTheme()
|
public OSAppTheme GetApplicationTheme()
|
||||||
{
|
{
|
||||||
if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
|
if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
|
||||||
{
|
{
|
||||||
var currentController = Platform.GetCurrentUIViewController();
|
var currentController = Platform.GetCurrentUIViewController();
|
||||||
if (currentController == null)
|
if (currentController == null)
|
||||||
{
|
{
|
||||||
return Theme.Light;
|
return OSAppTheme.Unspecified;
|
||||||
}
|
}
|
||||||
|
|
||||||
var style = currentController.TraitCollection.UserInterfaceStyle;
|
var style = currentController.TraitCollection.UserInterfaceStyle;
|
||||||
if (style == UIUserInterfaceStyle.Dark)
|
if (style == UIUserInterfaceStyle.Dark)
|
||||||
{
|
{
|
||||||
return Theme.Dark;
|
return OSAppTheme.Dark;
|
||||||
}
|
}
|
||||||
else
|
else if (style == UIUserInterfaceStyle.Light)
|
||||||
{
|
{
|
||||||
return Theme.Light;
|
return OSAppTheme.Light;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return OSAppTheme.Unspecified;
|
||||||
return Theme.Light;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStatusBarStyle(StatusBarStyles style)
|
public void SetStatusBarStyle(StatusBarStyles style)
|
||||||
|
@ -11,7 +11,7 @@ namespace Pixiview
|
|||||||
public class App : Application
|
public class App : Application
|
||||||
{
|
{
|
||||||
// public properties
|
// public properties
|
||||||
public static Theme CurrentTheme { get; private set; }
|
public static OSAppTheme CurrentTheme { get; private set; }
|
||||||
public static PlatformCulture CurrentCulture { get; private set; }
|
public static PlatformCulture CurrentCulture { get; private set; }
|
||||||
public static Dictionary<string, object> ExtraResources { get; private set; }
|
public static Dictionary<string, object> ExtraResources { get; private set; }
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ namespace Pixiview
|
|||||||
CurrentCulture = new PlatformCulture(ci.Name.ToLower());
|
CurrentCulture = new PlatformCulture(ci.Name.ToLower());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetTheme(Theme theme, bool force = false)
|
private void SetTheme(OSAppTheme theme, bool force = false)
|
||||||
{
|
{
|
||||||
if (force || theme != CurrentTheme)
|
if (force || theme != CurrentTheme)
|
||||||
{
|
{
|
||||||
@ -51,7 +51,7 @@ namespace Pixiview
|
|||||||
}
|
}
|
||||||
DebugPrint($"application theme: {theme}");
|
DebugPrint($"application theme: {theme}");
|
||||||
ThemeBase themeInstance;
|
ThemeBase themeInstance;
|
||||||
if (theme == Theme.Dark)
|
if (theme == OSAppTheme.Dark)
|
||||||
{
|
{
|
||||||
themeInstance = DarkTheme.Instance;
|
themeInstance = DarkTheme.Instance;
|
||||||
}
|
}
|
||||||
|
@ -363,7 +363,6 @@ namespace Pixiview.Illust
|
|||||||
|
|
||||||
public class IllustCollection : List<IllustItem>
|
public class IllustCollection : List<IllustItem>
|
||||||
{
|
{
|
||||||
private static readonly object sync = new object();
|
|
||||||
private static IllustCollection empty;
|
private static IllustCollection empty;
|
||||||
|
|
||||||
public static IllustCollection Empty
|
public static IllustCollection Empty
|
||||||
@ -387,7 +386,8 @@ namespace Pixiview.Illust
|
|||||||
running = true;
|
running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool running;
|
private readonly object sync = new object();
|
||||||
|
private volatile bool running;
|
||||||
public bool Running
|
public bool Running
|
||||||
{
|
{
|
||||||
get => running;
|
get => running;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
xmlns:mdl="clr-namespace:Pixiview.Illust"
|
xmlns:mdl="clr-namespace:Pixiview.Illust"
|
||||||
xmlns:u="clr-namespace:Pixiview.UI"
|
xmlns:u="clr-namespace:Pixiview.UI"
|
||||||
|
xmlns:util="clr-namespace:Pixiview.Utils"
|
||||||
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
|
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
|
||||||
x:Class="Pixiview.Illust.ViewIllustPage"
|
x:Class="Pixiview.Illust.ViewIllustPage"
|
||||||
ios:Page.UseSafeArea="False"
|
ios:Page.UseSafeArea="False"
|
||||||
@ -11,7 +12,7 @@
|
|||||||
Title="{Binding IllustItem.Title}">
|
Title="{Binding IllustItem.Title}">
|
||||||
<ContentPage.ToolbarItems>
|
<ContentPage.ToolbarItems>
|
||||||
<ToolbarItem Order="Primary" Clicked="Favorite_Clicked"
|
<ToolbarItem Order="Primary" Clicked="Favorite_Clicked"
|
||||||
IconImageSource="{Binding IsFavorite}"/>
|
IconImageSource="{Binding FavoriteIcon}"/>
|
||||||
</ContentPage.ToolbarItems>
|
</ContentPage.ToolbarItems>
|
||||||
<Grid Padding="{Binding PageTopMargin}">
|
<Grid Padding="{Binding PageTopMargin}">
|
||||||
<CarouselView ItemsSource="{Binding Illusts}" HorizontalScrollBarVisibility="Never"
|
<CarouselView ItemsSource="{Binding Illusts}" HorizontalScrollBarVisibility="Never"
|
||||||
@ -24,7 +25,13 @@
|
|||||||
<Grid>
|
<Grid>
|
||||||
<Image Source="{Binding Image}"
|
<Image Source="{Binding Image}"
|
||||||
HorizontalOptions="Fill" VerticalOptions="Fill"
|
HorizontalOptions="Fill" VerticalOptions="Fill"
|
||||||
Aspect="AspectFit"/>
|
Aspect="AspectFit"
|
||||||
|
util:LongPressEffect.Command="{Binding LongPressed}"
|
||||||
|
util:LongPressEffect.CommandParameter="{Binding .}">
|
||||||
|
<Image.Effects>
|
||||||
|
<util:LongPressEffect/>
|
||||||
|
</Image.Effects>
|
||||||
|
</Image>
|
||||||
<Frame HasShadow="False" Margin="0" Padding="20" CornerRadius="8"
|
<Frame HasShadow="False" Margin="0" Padding="20" CornerRadius="8"
|
||||||
IsVisible="{Binding Loading}"
|
IsVisible="{Binding Loading}"
|
||||||
HorizontalOptions="Center" VerticalOptions="Center"
|
HorizontalOptions="Center" VerticalOptions="Center"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Input;
|
||||||
using Pixiview.Resources;
|
using Pixiview.Resources;
|
||||||
using Pixiview.UI;
|
using Pixiview.UI;
|
||||||
using Pixiview.UI.Theme;
|
using Pixiview.UI.Theme;
|
||||||
@ -13,8 +14,8 @@ namespace Pixiview.Illust
|
|||||||
[QueryProperty("IllustId", "id")]
|
[QueryProperty("IllustId", "id")]
|
||||||
public partial class ViewIllustPage : AdaptedPage
|
public partial class ViewIllustPage : AdaptedPage
|
||||||
{
|
{
|
||||||
public static readonly BindableProperty IsFavoriteProperty = BindableProperty.Create(
|
public static readonly BindableProperty FavoriteIconProperty = BindableProperty.Create(
|
||||||
nameof(IsFavorite), typeof(ImageSource), typeof(ViewIllustPage));
|
nameof(FavoriteIcon), typeof(ImageSource), typeof(ViewIllustPage));
|
||||||
public static readonly BindableProperty IllustsProperty = BindableProperty.Create(
|
public static readonly BindableProperty IllustsProperty = BindableProperty.Create(
|
||||||
nameof(Illusts), typeof(IllustDetailItem[]), typeof(ViewIllustPage));
|
nameof(Illusts), typeof(IllustDetailItem[]), typeof(ViewIllustPage));
|
||||||
public static readonly BindableProperty PagePositionTextProperty = BindableProperty.Create(
|
public static readonly BindableProperty PagePositionTextProperty = BindableProperty.Create(
|
||||||
@ -24,7 +25,11 @@ namespace Pixiview.Illust
|
|||||||
public static readonly BindableProperty IllustItemProperty = BindableProperty.Create(
|
public static readonly BindableProperty IllustItemProperty = BindableProperty.Create(
|
||||||
nameof(IllustItem), typeof(IllustItem), typeof(ViewIllustPage));
|
nameof(IllustItem), typeof(IllustItem), typeof(ViewIllustPage));
|
||||||
|
|
||||||
public ImageSource IsFavorite => (ImageSource)GetValue(IsFavoriteProperty);
|
public ImageSource FavoriteIcon
|
||||||
|
{
|
||||||
|
get => (ImageSource)GetValue(FavoriteIconProperty);
|
||||||
|
set => SetValue(FavoriteIconProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
public IllustDetailItem[] Illusts
|
public IllustDetailItem[] Illusts
|
||||||
{
|
{
|
||||||
@ -50,22 +55,24 @@ namespace Pixiview.Illust
|
|||||||
public int CurrentPage { get; private set; }
|
public int CurrentPage { get; private set; }
|
||||||
|
|
||||||
private readonly IIllustCollectionPage collectionPage;
|
private readonly IIllustCollectionPage collectionPage;
|
||||||
private readonly object fontIconLove;
|
private readonly ICommand longPressed;
|
||||||
private readonly object fontIconNotLove;
|
private readonly ImageSource fontIconLove;
|
||||||
|
private readonly ImageSource fontIconNotLove;
|
||||||
|
|
||||||
public ViewIllustPage(IllustItem illust, IIllustCollectionPage page)
|
public ViewIllustPage(IllustItem illust, IIllustCollectionPage page)
|
||||||
{
|
{
|
||||||
IllustItem = illust;
|
IllustItem = illust;
|
||||||
collectionPage = page;
|
collectionPage = page;
|
||||||
|
longPressed = new Command<IllustDetailItem>(Illust_LongPressed);
|
||||||
BindingContext = this;
|
BindingContext = this;
|
||||||
|
|
||||||
fontIconLove = Application.Current.Resources[ThemeBase.FontIconLove];
|
fontIconLove = (ImageSource)Application.Current.Resources[ThemeBase.FontIconLove];
|
||||||
fontIconNotLove = Application.Current.Resources[ThemeBase.FontIconNotLove];
|
fontIconNotLove = (ImageSource)Application.Current.Resources[ThemeBase.FontIconNotLove];
|
||||||
if (page.Favorites != null)
|
if (page.Favorites != null)
|
||||||
{
|
{
|
||||||
SetValue(IsFavoriteProperty, page.Favorites.Any(i => i.Id == illust.Id)
|
FavoriteIcon = page.Favorites.Any(i => i.Id == illust.Id)
|
||||||
? fontIconLove
|
? fontIconLove
|
||||||
: fontIconNotLove);
|
: fontIconNotLove;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@ -81,38 +88,6 @@ namespace Pixiview.Illust
|
|||||||
OnOrientationChanged(CurrentOrientation);
|
OnOrientationChanged(CurrentOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadIllust(IllustItem illust)
|
|
||||||
{
|
|
||||||
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].Loading = true;
|
|
||||||
items[i].Image = illust.Image;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Illusts = items;
|
|
||||||
Task.Run(DoLoadImages);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnAppearing()
|
protected override void OnAppearing()
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
base.OnAppearing();
|
||||||
@ -135,27 +110,39 @@ namespace Pixiview.Illust
|
|||||||
Screen.SetHomeIndicatorAutoHidden(Shell.Current, false);
|
Screen.SetHomeIndicatorAutoHidden(Shell.Current, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CarouselView_PositionChanged(object sender, PositionChangedEventArgs e)
|
private void LoadIllust(IllustItem illust)
|
||||||
{
|
{
|
||||||
var index = e.CurrentPosition;
|
if (illust == null)
|
||||||
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));
|
return;
|
||||||
}
|
}
|
||||||
if (index < length - 1)
|
|
||||||
|
var items = new IllustDetailItem[illust.PageCount];
|
||||||
|
if (items.Length > 1)
|
||||||
{
|
{
|
||||||
item = items[index + 1];
|
IsPageVisible = true;
|
||||||
if (!item.Loading && item.Image == null)
|
PagePositionText = $"1/{items.Length}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IsPageVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < items.Length; i++)
|
||||||
|
{
|
||||||
|
items[i] = new IllustDetailItem
|
||||||
{
|
{
|
||||||
Task.Run(() => DoLoadImage(index + 1));
|
LongPressed = longPressed
|
||||||
|
};
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
items[i].Loading = true;
|
||||||
|
items[i].Image = illust.Image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Illusts = items;
|
||||||
|
Task.Run(DoLoadImages);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DoLoadImages()
|
private void DoLoadImages()
|
||||||
@ -174,7 +161,10 @@ namespace Pixiview.Illust
|
|||||||
items.CopyTo(items, 0);
|
items.CopyTo(items, 0);
|
||||||
for (var i = items.Length; i < tmp.Length; i++)
|
for (var i = items.Length; i < tmp.Length; i++)
|
||||||
{
|
{
|
||||||
tmp[i] = new IllustDetailItem();
|
tmp[i] = new IllustDetailItem
|
||||||
|
{
|
||||||
|
LongPressed = longPressed
|
||||||
|
};
|
||||||
}
|
}
|
||||||
items = tmp;
|
items = tmp;
|
||||||
}
|
}
|
||||||
@ -221,6 +211,29 @@ namespace Pixiview.Illust
|
|||||||
item.Loading = false;
|
item.Loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 Favorite_Clicked(object sender, EventArgs e)
|
private void Favorite_Clicked(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (collectionPage.Favorites == null)
|
if (collectionPage.Favorites == null)
|
||||||
@ -232,36 +245,55 @@ namespace Pixiview.Illust
|
|||||||
{
|
{
|
||||||
collectionPage.Favorites.Insert(0, IllustItem);
|
collectionPage.Favorites.Insert(0, IllustItem);
|
||||||
IllustItem.IsFavorite = true;
|
IllustItem.IsFavorite = true;
|
||||||
SetValue(IsFavoriteProperty, fontIconLove);
|
FavoriteIcon = fontIconLove;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
collectionPage.Favorites.RemoveAt(index);
|
collectionPage.Favorites.RemoveAt(index);
|
||||||
IllustItem.IsFavorite = false;
|
IllustItem.IsFavorite = false;
|
||||||
SetValue(IsFavoriteProperty, fontIconNotLove);
|
FavoriteIcon = fontIconNotLove;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Download_Clicked(object sender, EventArgs e)
|
private async void Illust_LongPressed(IllustDetailItem item)
|
||||||
{
|
{
|
||||||
var status = await Permissions.CheckStatusAsync<Permissions.Photos>();
|
var saveOriginal = ResourceHelper.SaveOriginal;
|
||||||
if (status != PermissionStatus.Granted)
|
var result = await DisplayActionSheet(
|
||||||
|
IllustItem.Title,
|
||||||
|
ResourceHelper.Cancel,
|
||||||
|
saveOriginal);
|
||||||
|
if (result == saveOriginal)
|
||||||
{
|
{
|
||||||
status = await Permissions.RequestAsync<Permissions.Photos>();
|
if (Stores.CheckIllustImage(item.OriginalUrl))
|
||||||
|
{
|
||||||
|
var flag = await DisplayAlert(ResourceHelper.Operation,
|
||||||
|
ResourceHelper.AlreadySavedQuestion,
|
||||||
|
ResourceHelper.Yes,
|
||||||
|
ResourceHelper.No);
|
||||||
|
if (!flag)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var status = await Permissions.CheckStatusAsync<Permissions.Photos>();
|
||||||
if (status != PermissionStatus.Granted)
|
if (status != PermissionStatus.Granted)
|
||||||
{
|
{
|
||||||
App.DebugPrint("access denied to gallery.");
|
status = await Permissions.RequestAsync<Permissions.Photos>();
|
||||||
|
if (status != PermissionStatus.Granted)
|
||||||
|
{
|
||||||
|
App.DebugPrint("access denied to gallery.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item == null || item.Downloading)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
item.Downloading = true;
|
||||||
|
_ = Task.Run(() => DoLoadOriginalImage(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = Illusts[CurrentPage];
|
|
||||||
if (item.Downloading)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
item.Downloading = true;
|
|
||||||
_ = Task.Run(() => DoLoadOriginalImage(item));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DoLoadOriginalImage(IllustDetailItem item)
|
private void DoLoadOriginalImage(IllustDetailItem item)
|
||||||
@ -306,6 +338,7 @@ namespace Pixiview.Illust
|
|||||||
get => (bool)GetValue(DownloadingProperty);
|
get => (bool)GetValue(DownloadingProperty);
|
||||||
set => SetValue(DownloadingProperty, value);
|
set => SetValue(DownloadingProperty, value);
|
||||||
}
|
}
|
||||||
|
public ICommand LongPressed { get; set; }
|
||||||
public string PreviewUrl { get; set; }
|
public string PreviewUrl { get; set; }
|
||||||
public string OriginalUrl { get; set; }
|
public string OriginalUrl { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
<root>
|
<root>
|
||||||
<Title>Pixiview</Title>
|
<Title>Pixiview</Title>
|
||||||
<Ok>OK</Ok>
|
<Ok>OK</Ok>
|
||||||
|
<Cancel>取消</Cancel>
|
||||||
|
<Yes>是</Yes>
|
||||||
|
<No>否</No>
|
||||||
<R18>R-18</R18>
|
<R18>R-18</R18>
|
||||||
<Follow>已关注</Follow>
|
<Follow>已关注</Follow>
|
||||||
<Recommends>推荐</Recommends>
|
<Recommends>推荐</Recommends>
|
||||||
@ -11,5 +14,8 @@
|
|||||||
<Favorites>收藏夹</Favorites>
|
<Favorites>收藏夹</Favorites>
|
||||||
<Option>选项</Option>
|
<Option>选项</Option>
|
||||||
<Preview>预览</Preview>
|
<Preview>预览</Preview>
|
||||||
|
<Operation>操作</Operation>
|
||||||
|
<SaveOriginal>保存原图</SaveOriginal>
|
||||||
<SaveSuccess>成功保存图片到照片库。</SaveSuccess>
|
<SaveSuccess>成功保存图片到照片库。</SaveSuccess>
|
||||||
|
<AlreadySavedQuestion>原图已保存,是否继续?</AlreadySavedQuestion>
|
||||||
</root>
|
</root>
|
@ -12,8 +12,14 @@ namespace Pixiview.Resources
|
|||||||
{
|
{
|
||||||
public static string Title => GetResource(nameof(Title));
|
public static string Title => GetResource(nameof(Title));
|
||||||
public static string Ok => GetResource(nameof(Ok));
|
public static string Ok => GetResource(nameof(Ok));
|
||||||
|
public static string Cancel => GetResource(nameof(Cancel));
|
||||||
|
public static string Yes => GetResource(nameof(Yes));
|
||||||
|
public static string No => GetResource(nameof(No));
|
||||||
public static string R18 => GetResource(nameof(R18));
|
public static string R18 => GetResource(nameof(R18));
|
||||||
|
public static string Operation => GetResource(nameof(Operation));
|
||||||
|
public static string SaveOriginal => GetResource(nameof(SaveOriginal));
|
||||||
public static string SaveSuccess => GetResource(nameof(SaveSuccess));
|
public static string SaveSuccess => GetResource(nameof(SaveSuccess));
|
||||||
|
public static string AlreadySavedQuestion => GetResource(nameof(AlreadySavedQuestion));
|
||||||
|
|
||||||
static readonly Dictionary<string, LanguageResource> dict = new Dictionary<string, LanguageResource>();
|
static readonly Dictionary<string, LanguageResource> dict = new Dictionary<string, LanguageResource>();
|
||||||
|
|
||||||
|
@ -83,16 +83,12 @@ namespace Pixiview.UI
|
|||||||
public static bool IsBusy => _instance?.isBusy == true;
|
public static bool IsBusy => _instance?.isBusy == true;
|
||||||
|
|
||||||
private static readonly object sync = new object();
|
private static readonly object sync = new object();
|
||||||
private static Tap _instance;
|
private static readonly Tap _instance = new Tap();
|
||||||
|
|
||||||
private Tap() { }
|
private Tap() { }
|
||||||
|
|
||||||
public static Tap Start()
|
public static Tap Start()
|
||||||
{
|
{
|
||||||
if (_instance == null)
|
|
||||||
{
|
|
||||||
_instance = new Tap();
|
|
||||||
}
|
|
||||||
lock (sync)
|
lock (sync)
|
||||||
{
|
{
|
||||||
_instance.isBusy = true;
|
_instance.isBusy = true;
|
||||||
@ -100,7 +96,7 @@ namespace Pixiview.UI
|
|||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool isBusy = false;
|
private volatile bool isBusy = false;
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Pixiview.UI;
|
using Pixiview.UI;
|
||||||
using Pixiview.UI.Theme;
|
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Pixiview.Utils
|
namespace Pixiview.Utils
|
||||||
|
@ -7,7 +7,7 @@ namespace Pixiview.Utils
|
|||||||
{
|
{
|
||||||
EnvironmentParameter GetEnvironment();
|
EnvironmentParameter GetEnvironment();
|
||||||
|
|
||||||
Theme GetApplicationTheme();
|
OSAppTheme GetApplicationTheme();
|
||||||
void SetStatusBarStyle(StatusBarStyles style);
|
void SetStatusBarStyle(StatusBarStyles style);
|
||||||
void SetStatusBarColor(Color color);
|
void SetStatusBarColor(Color color);
|
||||||
|
|
||||||
@ -22,10 +22,4 @@ namespace Pixiview.Utils
|
|||||||
public string IconSolidFontFamily { get; set; }
|
public string IconSolidFontFamily { get; set; }
|
||||||
public string IconLeft { get; set; }
|
public string IconLeft { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Theme
|
|
||||||
{
|
|
||||||
Light,
|
|
||||||
Dark
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
26
Pixiview/Utils/LongPressEffect.cs
Normal file
26
Pixiview/Utils/LongPressEffect.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using System.Windows.Input;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Pixiview.Utils
|
||||||
|
{
|
||||||
|
public class LongPressEffect : RoutingEffect
|
||||||
|
{
|
||||||
|
private const string Command = nameof(Command);
|
||||||
|
private const string CommandParameter = nameof(CommandParameter);
|
||||||
|
|
||||||
|
public static readonly BindableProperty CommandProperty = BindableProperty.CreateAttached(
|
||||||
|
Command, typeof(ICommand), typeof(LongPressEffect), null);
|
||||||
|
public static readonly BindableProperty CommandParameterProperty = BindableProperty.CreateAttached(
|
||||||
|
CommandParameter, typeof(object), typeof(LongPressEffect), null);
|
||||||
|
|
||||||
|
public static ICommand GetCommand(BindableObject view) => (ICommand)view.GetValue(CommandProperty);
|
||||||
|
public static void SetCommand(BindableObject view, ICommand command) => view.SetValue(CommandProperty, command);
|
||||||
|
|
||||||
|
public static object GetCommandParameter(BindableObject view) => view.GetValue(CommandParameterProperty);
|
||||||
|
public static void SetCommandParameter(BindableObject view, object value) => view.SetValue(CommandParameterProperty, value);
|
||||||
|
|
||||||
|
public LongPressEffect() : base("Pixiview.LongPressEffect")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -182,7 +182,10 @@ namespace Pixiview.Utils
|
|||||||
public static IllustFavorite LoadFavoritesIllusts()
|
public static IllustFavorite LoadFavoritesIllusts()
|
||||||
{
|
{
|
||||||
var file = Path.Combine(PersonalFolder, favoriteFile);
|
var file = Path.Combine(PersonalFolder, favoriteFile);
|
||||||
return ReadObject<IllustFavorite>(file);
|
lock (sync)
|
||||||
|
{
|
||||||
|
return ReadObject<IllustFavorite>(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SaveFavoritesIllusts(IllustFavorite data)
|
public static void SaveFavoritesIllusts(IllustFavorite data)
|
||||||
@ -214,6 +217,12 @@ namespace Pixiview.Utils
|
|||||||
return LoadImage(url, CacheFolder, userFolder);
|
return LoadImage(url, CacheFolder, userFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool CheckIllustImage(string url)
|
||||||
|
{
|
||||||
|
var file = Path.Combine(PersonalFolder, imageFolder, Path.GetFileName(url));
|
||||||
|
return File.Exists(file);
|
||||||
|
}
|
||||||
|
|
||||||
private static ImageSource LoadImage(string url, string working, string folder)
|
private static ImageSource LoadImage(string url, string working, string folder)
|
||||||
{
|
{
|
||||||
var file = Path.Combine(working, folder, Path.GetFileName(url));
|
var file = Path.Combine(working, folder, Path.GetFileName(url));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user