feature: refresh list & save to gallery
This commit is contained in:
parent
190615ab03
commit
8746d311d2
@ -44,5 +44,7 @@
|
||||
<false/>
|
||||
<key>UIStatusBarStyle</key>
|
||||
<string>UIStatusBarStyleDefault</string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>需要访问您的图片库</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -76,6 +76,7 @@
|
||||
<Compile Include="Renderers\RoundImageRenderer.cs" />
|
||||
<Compile Include="GlobalSuppressions.cs" />
|
||||
<Compile Include="Renderers\AdaptedNavigationPageRenderer.cs" />
|
||||
<Compile Include="Services\FileStore.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<InterfaceDefinition Include="Resources\LaunchScreen.storyboard" />
|
||||
|
45
Pixiview.iOS/Services/FileStore.cs
Normal file
45
Pixiview.iOS/Services/FileStore.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using System.Threading.Tasks;
|
||||
using Pixiview.iOS.Services;
|
||||
using Pixiview.Utils;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.iOS;
|
||||
|
||||
[assembly: Dependency(typeof(FileStore))]
|
||||
namespace Pixiview.iOS.Services
|
||||
{
|
||||
public class FileStore : IFileStore
|
||||
{
|
||||
|
||||
public Task<string> SaveImageToGalleryAsync(ImageSource image)
|
||||
{
|
||||
IImageSourceHandler renderer;
|
||||
if (image is UriImageSource)
|
||||
{
|
||||
renderer = new ImageLoaderSourceHandler();
|
||||
}
|
||||
else if (image is FileImageSource)
|
||||
{
|
||||
renderer = new FileImageSourceHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer = new StreamImagesourceHandler();
|
||||
}
|
||||
var photo = renderer.LoadImageAsync(image).Result;
|
||||
|
||||
var task = new TaskCompletionSource<string>();
|
||||
if (photo == null)
|
||||
{
|
||||
task.SetResult(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
photo.SaveToPhotosAlbum((img, error) =>
|
||||
{
|
||||
task.SetResult(error?.ToString());
|
||||
});
|
||||
}
|
||||
return task.Task;
|
||||
}
|
||||
}
|
||||
}
|
@ -14,8 +14,8 @@
|
||||
Title="{r:Text Follow}"
|
||||
OrientationChanged="Page_OrientationChanged">
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Order="Primary" Clicked="NavigationTitle_RightButtonClicked"
|
||||
IconImageSource="{DynamicResource FontIconOption}"/>
|
||||
<ToolbarItem Order="Primary" Clicked="Refresh_Clicked"
|
||||
IconImageSource="{DynamicResource FontIconRefresh}"/>
|
||||
</ContentPage.ToolbarItems>
|
||||
<Grid>
|
||||
<ScrollView HorizontalOptions="Fill" Padding="{Binding StatusBarPadding}">
|
||||
|
@ -33,7 +33,7 @@ namespace Pixiview
|
||||
if (!page.loaded && now && Stores.NetworkAvailable)
|
||||
{
|
||||
page.loaded = true;
|
||||
Task.Run(page.DoLoadIllusts);
|
||||
Task.Run(() => page.DoLoadIllusts());
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,10 +74,7 @@ namespace Pixiview
|
||||
public override void OnLoad()
|
||||
{
|
||||
App.DebugPrint($"folder: {Stores.PersonalFolder}");
|
||||
if (!loaded)
|
||||
{
|
||||
Loading = true;
|
||||
}
|
||||
Loading = true;
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
@ -109,9 +106,9 @@ namespace Pixiview
|
||||
|
||||
#region - Illust Tasks -
|
||||
|
||||
async void DoLoadIllusts()
|
||||
void DoLoadIllusts(bool force = false)
|
||||
{
|
||||
illustData = await Stores.LoadIllustData();
|
||||
illustData = Stores.LoadIllustData(force);
|
||||
if (illustData == null)
|
||||
{
|
||||
App.DebugError("illusts.load", "failed to load illusts data.");
|
||||
@ -215,9 +212,14 @@ namespace Pixiview
|
||||
}
|
||||
}
|
||||
|
||||
private void NavigationTitle_RightButtonClicked(object sender, EventArgs e)
|
||||
private void Refresh_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
DisplayAlert("title", "message", "Ok");
|
||||
if (Loading)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Loading = true;
|
||||
Task.Run(() => DoLoadIllusts(true));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<root>
|
||||
<Title>Pixiview</Title>
|
||||
<Ok>OK</Ok>
|
||||
<Follow>已关注</Follow>
|
||||
<Preview>预览</Preview>
|
||||
<SaveSuccess>成功保存图片到照片库。</SaveSuccess>
|
||||
</root>
|
@ -10,6 +10,10 @@ namespace Pixiview.Resources
|
||||
{
|
||||
public class ResourceHelper
|
||||
{
|
||||
public static string Title => GetResource(nameof(Title));
|
||||
public static string Ok => GetResource(nameof(Ok));
|
||||
public static string SaveSuccess => GetResource(nameof(SaveSuccess));
|
||||
|
||||
static readonly Dictionary<string, LanguageResource> dict = new Dictionary<string, LanguageResource>();
|
||||
|
||||
public static string GetResource(string name, params object[] args)
|
||||
|
@ -20,6 +20,7 @@ namespace Pixiview.UI
|
||||
public static Thickness TotalBarOffset;
|
||||
|
||||
public const string IconLayer = "\uf302";
|
||||
public const string IconRefresh = "\uf2f1";
|
||||
public const string IconOption = "\uf013";
|
||||
public const string IconDownload = "\uf019";
|
||||
|
||||
|
@ -6,6 +6,7 @@ namespace Pixiview.UI.Theme
|
||||
{
|
||||
public const string TitleButton = nameof(TitleButton);
|
||||
public const string TitleLabel = nameof(TitleLabel);
|
||||
public const string FontIconRefresh = nameof(FontIconRefresh);
|
||||
public const string FontIconOption = nameof(FontIconOption);
|
||||
public const string FontIconDownload = nameof(FontIconDownload);
|
||||
|
||||
@ -27,6 +28,7 @@ namespace Pixiview.UI.Theme
|
||||
//public const string Horizon10 = nameof(Horizon10);
|
||||
public const string ScreenBottomPadding = nameof(ScreenBottomPadding);
|
||||
public const string NavigationBarHeight = nameof(NavigationBarHeight);
|
||||
public const string IconRefresh = nameof(IconRefresh);
|
||||
public const string IconOption = nameof(IconOption);
|
||||
public const string IconDownload = nameof(IconDownload);
|
||||
|
||||
@ -36,6 +38,7 @@ namespace Pixiview.UI.Theme
|
||||
Add(FontSizeTitleIcon, StyleDefinition.FontSizeTitleIcon);
|
||||
//Add(Horizon10, StyleDefinition.Horizon10);
|
||||
Add(ScreenBottomPadding, StyleDefinition.ScreenBottomPadding);
|
||||
Add(IconRefresh, StyleDefinition.IconRefresh);
|
||||
Add(IconOption, StyleDefinition.IconOption);
|
||||
Add(IconDownload, StyleDefinition.IconDownload);
|
||||
|
||||
@ -74,6 +77,12 @@ namespace Pixiview.UI.Theme
|
||||
}
|
||||
});
|
||||
|
||||
Add(FontIconRefresh, new FontImageSource
|
||||
{
|
||||
FontFamily = iconSolidFontFamily,
|
||||
Glyph = StyleDefinition.IconRefresh,
|
||||
Size = StyleDefinition.FontSizeTitle
|
||||
});
|
||||
Add(FontIconOption, new FontImageSource
|
||||
{
|
||||
FontFamily = iconSolidFontFamily,
|
||||
|
10
Pixiview/Utils/IFileStore.cs
Normal file
10
Pixiview/Utils/IFileStore.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Pixiview.Utils
|
||||
{
|
||||
public interface IFileStore
|
||||
{
|
||||
Task<string> SaveImageToGalleryAsync(ImageSource image);
|
||||
}
|
||||
}
|
@ -105,4 +105,26 @@ namespace Pixiview.Utils
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class IllustPageData
|
||||
{
|
||||
public bool error;
|
||||
public string message;
|
||||
public Body[] body;
|
||||
|
||||
public class Body
|
||||
{
|
||||
public Urls urls;
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
public class Urls
|
||||
{
|
||||
public string thumb_mini;
|
||||
public string small;
|
||||
public string regular;
|
||||
public string original;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
@ -15,8 +14,9 @@ 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 previewFolder = "img-preview";
|
||||
private const string pagesFolder = "pages";
|
||||
private const string imageFolder = "img-original";
|
||||
private const string previewFolder = "img-master";
|
||||
private const string thumbFolder = "img-thumb";
|
||||
private const string userFolder = "user-profile";
|
||||
private const string illustFile = "illust.json";
|
||||
@ -37,11 +37,10 @@ namespace Pixiview.Utils
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<IllustData> LoadIllustData()
|
||||
private static T LoadObject<T>(string file, string url, string referer = null, bool force = false, IEnumerable<(string header, string value)> headers = null)
|
||||
{
|
||||
var file = Path.Combine(PersonalFolder, illustFile);
|
||||
string content = null;
|
||||
if (File.Exists(file))
|
||||
if (!force && File.Exists(file))
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -49,44 +48,76 @@ namespace Pixiview.Utils
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
App.DebugError("illust.load", $"failed to read file: {file}, error: {ex.Message}");
|
||||
App.DebugError("load", $"failed to read file: {file}, error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
if (content == null)
|
||||
{
|
||||
var response = Download(Configs.UrlIllust, headers: new[]
|
||||
{
|
||||
("cookie", Configs.Cookie),
|
||||
("x-user-id", Configs.UserId)
|
||||
});
|
||||
var response = Download(url, referer, headers);
|
||||
if (response == null)
|
||||
{
|
||||
return null;
|
||||
return default;
|
||||
}
|
||||
using (response)
|
||||
{
|
||||
content = await response.Content.ReadAsStringAsync();
|
||||
content = response.Content.ReadAsStringAsync().Result;
|
||||
try
|
||||
{
|
||||
var folder = Path.GetDirectoryName(file);
|
||||
if (!Directory.Exists(folder))
|
||||
{
|
||||
Directory.CreateDirectory(folder);
|
||||
}
|
||||
File.WriteAllText(file, content, Encoding.UTF8);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
App.DebugError("illust.save", $"failed to save illust JSON object, error: {ex.Message}");
|
||||
App.DebugError("save", $"failed to save illust JSON object, error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<IllustData>(content);
|
||||
return JsonConvert.DeserializeObject<T>(content);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
App.DebugError("illust.load", $"failed to parse illust JSON object, error: {ex.Message}");
|
||||
return null;
|
||||
App.DebugError("load", $"failed to parse illust JSON object, error: {ex.Message}");
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
public static IllustData LoadIllustData(bool force = false)
|
||||
{
|
||||
var file = Path.Combine(PersonalFolder, illustFile);
|
||||
var result = LoadObject<IllustData>(
|
||||
file,
|
||||
Configs.UrlIllustList,
|
||||
force: force,
|
||||
headers: new[]
|
||||
{
|
||||
("cookie", Configs.Cookie),
|
||||
("x-user-id", Configs.UserId)
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public static IllustPageData LoadIllustPageData(string id, bool force = false)
|
||||
{
|
||||
var file = Path.Combine(PersonalFolder, pagesFolder, $"{id}.json");
|
||||
var result = LoadObject<IllustPageData>(
|
||||
file,
|
||||
string.Format(Configs.UrlIllustPage, id),
|
||||
string.Format(Configs.UrlIllust, id),
|
||||
force: force,
|
||||
headers: new[]
|
||||
{
|
||||
("cookie", Configs.Cookie),
|
||||
("x-user-id", Configs.UserId)
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ImageSource LoadIllustImage(string url)
|
||||
{
|
||||
return LoadImage(url, PersonalFolder, imageFolder);
|
||||
@ -110,15 +141,32 @@ namespace Pixiview.Utils
|
||||
private static ImageSource LoadImage(string url, string working, string folder)
|
||||
{
|
||||
var file = Path.Combine(working, folder, Path.GetFileName(url));
|
||||
if (!File.Exists(file))
|
||||
ImageSource image;
|
||||
if (File.Exists(file))
|
||||
{
|
||||
try
|
||||
{
|
||||
image = ImageSource.FromFile(file);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
App.DebugError("image.load", $"failed to load image from file: {file}, error: {ex.Message}");
|
||||
image = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
image = null;
|
||||
}
|
||||
if (image == null)
|
||||
{
|
||||
file = DownloadImage(url, working, folder);
|
||||
if (file != null)
|
||||
{
|
||||
return ImageSource.FromFile(file);
|
||||
}
|
||||
}
|
||||
if (file != null)
|
||||
{
|
||||
return ImageSource.FromFile(file);
|
||||
}
|
||||
return null;
|
||||
return image;
|
||||
}
|
||||
|
||||
private static string DownloadImage(string url, string working, string folder)
|
||||
@ -216,7 +264,9 @@ namespace Pixiview.Utils
|
||||
|
||||
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 UrlIllustList = "https://www.pixiv.net/ajax/top/illust?mode=all&lang=zh";
|
||||
public const string UrlIllust = "https://www.pixiv.net/artworks/{0}";
|
||||
public const string UrlIllustPage = "https://www.pixiv.net/ajax/illust/{0}/pages?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" +
|
||||
"ketch_live%22%2C%22visible%22%3Atrue%7D%2C%7B%22name%22%3A%22tag_follow%22%2C%22visible%22%3Atrue" +
|
||||
|
@ -18,6 +18,9 @@
|
||||
<Grid Margin="{Binding PageTopMargin}">
|
||||
<CarouselView ItemsSource="{Binding Illusts}" HorizontalScrollBarVisibility="Never"
|
||||
PositionChanged="CarouselView_PositionChanged">
|
||||
<CarouselView.ItemsLayout>
|
||||
<LinearItemsLayout Orientation="Horizontal" ItemSpacing="20"/>
|
||||
</CarouselView.ItemsLayout>
|
||||
<CarouselView.ItemTemplate>
|
||||
<DataTemplate x:DataType="p:IllustDetailItem">
|
||||
<Grid>
|
||||
@ -26,6 +29,10 @@
|
||||
Aspect="AspectFit"/>
|
||||
<ActivityIndicator IsRunning="True" IsEnabled="True" IsVisible="{Binding Loading}"
|
||||
Color="{DynamicResource TextColor}"/>
|
||||
<ActivityIndicator IsRunning="True" IsEnabled="True" IsVisible="{Binding Downloading}"
|
||||
Margin="10"
|
||||
HorizontalOptions="Start" VerticalOptions="Start"
|
||||
Color="{DynamicResource TextColor}"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</CarouselView.ItemTemplate>
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Pixiview.Resources;
|
||||
using Pixiview.UI;
|
||||
using Pixiview.UI.Theme;
|
||||
using Pixiview.Utils;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
@ -45,6 +47,8 @@ namespace Pixiview
|
||||
private set => SetValue(IllustItemProperty, value);
|
||||
}
|
||||
|
||||
public int CurrentPage { get; private set; }
|
||||
|
||||
public ViewIllustPage(IllustItem illust)
|
||||
{
|
||||
IllustItem = illust;
|
||||
@ -62,25 +66,51 @@ namespace Pixiview
|
||||
}
|
||||
|
||||
var items = new IllustDetailItem[illust.PageCount];
|
||||
if (items.Length > 0)
|
||||
if (items.Length > 1)
|
||||
{
|
||||
IsPageVisible = true;
|
||||
PagePositionText = $"1/{items.Length}";
|
||||
}
|
||||
|
||||
items[0] = new IllustDetailItem
|
||||
else
|
||||
{
|
||||
Image = illust.Image,
|
||||
Loading = true
|
||||
};
|
||||
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)
|
||||
{
|
||||
PagePositionText = $"{e.CurrentPosition + 1}/{Illusts.Length}";
|
||||
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)
|
||||
@ -114,9 +144,103 @@ namespace Pixiview
|
||||
}
|
||||
}
|
||||
|
||||
private void Download_Clicked(object sender, EventArgs e)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,6 +250,8 @@ namespace Pixiview
|
||||
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
|
||||
{
|
||||
@ -137,5 +263,12 @@ namespace Pixiview
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user