feature: single illust bookmark sync
This commit is contained in:
parent
1589d6b089
commit
d6c235d6ef
@ -81,6 +81,7 @@
|
||||
<Compile Include="Renderers\RoundImageRenderer.cs" />
|
||||
<Compile Include="Renderers\AdaptedPageRenderer.cs" />
|
||||
<Compile Include="Renderers\HybridWebViewRenderer.cs" />
|
||||
<Compile Include="Renderers\OptionPickerRenderer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\AboutResources.txt" />
|
||||
|
29
Pixiview.Android/Renderers/OptionPickerRenderer.cs
Normal file
29
Pixiview.Android/Renderers/OptionPickerRenderer.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using Android.Content;
|
||||
using Android.Graphics.Drawables;
|
||||
using Pixiview.Droid.Renderers;
|
||||
using Pixiview.UI;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(OptionPicker), typeof(OptionPickerRenderer))]
|
||||
namespace Pixiview.Droid.Renderers
|
||||
{
|
||||
public class OptionPickerRenderer : PickerRenderer
|
||||
{
|
||||
public OptionPickerRenderer(Context context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
||||
if (e.NewElement != null)
|
||||
{
|
||||
var drawable = new ColorDrawable(e.NewElement.BackgroundColor.ToAndroid());
|
||||
Control.Gravity = Android.Views.GravityFlags.Right;
|
||||
Control.SetBackground(drawable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -84,6 +84,7 @@
|
||||
<Compile Include="Renderers\AppShellSection\AppAppearanceTracker.cs" />
|
||||
<Compile Include="Renderers\BlurryPanelRenderer.cs" />
|
||||
<Compile Include="Renderers\HybridWebViewRenderer.cs" />
|
||||
<Compile Include="Renderers\OptionPickerRenderer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<InterfaceDefinition Include="Resources\LaunchScreen.storyboard" />
|
||||
|
22
Pixiview.iOS/Renderers/OptionPickerRenderer.cs
Normal file
22
Pixiview.iOS/Renderers/OptionPickerRenderer.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using Pixiview.iOS.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.iOS;
|
||||
|
||||
[assembly: ExportRenderer(typeof(Picker), typeof(OptionPickerRenderer))]
|
||||
namespace Pixiview.iOS.Renderers
|
||||
{
|
||||
public class OptionPickerRenderer : PickerRenderer
|
||||
{
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
||||
var control = Control;
|
||||
if (control != null)
|
||||
{
|
||||
control.TextAlignment = UIKit.UITextAlignment.Right;
|
||||
control.BorderStyle = UIKit.UITextBorderStyle.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Pixiview.Illust;
|
||||
using Pixiview.Resources;
|
||||
using Pixiview.UI.Theme;
|
||||
@ -35,10 +34,8 @@ namespace Pixiview
|
||||
Configs.SetCookie(Preferences.Get(Configs.CookieKey, null));
|
||||
Configs.SetUserId(Preferences.Get(Configs.UserIdKey, null));
|
||||
|
||||
// login info
|
||||
Task.Run(() => AppShell.Current.DoLoginInformation());
|
||||
|
||||
Configs.IsOnR18 = Preferences.Get(Configs.IsOnR18Key, false);
|
||||
Configs.SyncFavType = (SyncType)Preferences.Get(Configs.SyncFavTypeKey, 0);
|
||||
var isProxied = Preferences.Get(Configs.IsProxiedKey, false);
|
||||
if (isProxied)
|
||||
{
|
||||
|
@ -50,6 +50,8 @@ namespace Pixiview
|
||||
public event EventHandler<BarHeightEventArgs> NavigationBarHeightChanged;
|
||||
public event EventHandler<BarHeightEventArgs> StatusBarHeightChanged;
|
||||
|
||||
private bool firstLoading = true;
|
||||
|
||||
public AppShell()
|
||||
{
|
||||
BindingContext = this;
|
||||
@ -58,6 +60,16 @@ namespace Pixiview
|
||||
App.DebugPrint($"folder: {Stores.PersonalFolder}");
|
||||
}
|
||||
|
||||
protected override void OnNavigated(ShellNavigatedEventArgs args)
|
||||
{
|
||||
if (firstLoading)
|
||||
{
|
||||
firstLoading = false;
|
||||
// login info
|
||||
Task.Run(() => DoLoginInformation(true));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetNavigationBarHeight(double height)
|
||||
{
|
||||
NavigationBarOffset = new Thickness(0, height, 0, 0);
|
||||
@ -153,10 +165,14 @@ namespace Pixiview
|
||||
Preferences.Set(Configs.ProfileIdKey, userId);
|
||||
Preferences.Set(Configs.ProfileImageKey, img);
|
||||
}
|
||||
UserProfileName = name;
|
||||
UserProfileId = $"@{userId}";
|
||||
UserProfileName = name ?? ResourceHelper.Guest;
|
||||
UserProfileId = string.IsNullOrEmpty(userId)
|
||||
? string.Empty
|
||||
: $"@{userId}";
|
||||
|
||||
UserProfileImage = Stores.LoadUserProfileImage(img);
|
||||
UserProfileImage = img == null
|
||||
? StyleDefinition.ProfileNone
|
||||
: Stores.LoadUserProfileImage(img);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -837,6 +837,8 @@ namespace Pixiview.Illust
|
||||
[JsonProperty]
|
||||
public string Id { get; set; }
|
||||
[JsonProperty]
|
||||
public string BookmarkId { get; set; }
|
||||
[JsonProperty]
|
||||
public DateTime FavoriteDateUtc { get; set; }
|
||||
[JsonProperty]
|
||||
public string ImageUrl { get; set; }
|
||||
|
@ -133,6 +133,7 @@ namespace Pixiview.Illust
|
||||
private readonly object sync = new object();
|
||||
private int downloaded = 0;
|
||||
private int pageCount;
|
||||
private bool isPreloading;
|
||||
|
||||
public ViewIllustPage(IllustItem illust, bool save)
|
||||
{
|
||||
@ -383,28 +384,7 @@ namespace Pixiview.Illust
|
||||
if (i == 0 && illustItem.ImageUrl == null)
|
||||
{
|
||||
// maybe open from a link
|
||||
var preload = Stores.LoadIllustPreloadData(illustItem.Id);
|
||||
if (preload != null && preload.illust.TryGetValue(illustItem.Id, out var illust))
|
||||
{
|
||||
illust.CopyToItem(illustItem);
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
var count = illustItem.PageCount;
|
||||
pageCount = count;
|
||||
Title = illustItem.Title;
|
||||
IsAnimateSliderVisible = illustItem.IsAnimeVisible;
|
||||
if (count > 1)
|
||||
{
|
||||
IsPageVisible = true;
|
||||
ProgressVisible = true;
|
||||
PagePositionText = $"1/{count}";
|
||||
}
|
||||
});
|
||||
if (preload.user.TryGetValue(illust.userId, out var user))
|
||||
{
|
||||
illustItem.ProfileUrl = user.image;
|
||||
}
|
||||
}
|
||||
DoForcePreload(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -434,13 +414,7 @@ namespace Pixiview.Illust
|
||||
private void DoLoadImage(int index, bool force = false)
|
||||
{
|
||||
var items = Illusts;
|
||||
if (index == 0 && force)
|
||||
{
|
||||
// error, refresh all
|
||||
Task.Run(() => DoLoadImages(true));
|
||||
return;
|
||||
}
|
||||
if (index < 0 || index >= items.Length)
|
||||
if (index < 0 || (!force && index >= items.Length))
|
||||
{
|
||||
App.DebugPrint($"invalid index: {index}");
|
||||
return;
|
||||
@ -525,12 +499,13 @@ namespace Pixiview.Illust
|
||||
}
|
||||
}
|
||||
|
||||
private void Favorite_Clicked(object sender, EventArgs e)
|
||||
private async void Favorite_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var favorites = Stores.Favorites;
|
||||
var illust = IllustItem;
|
||||
var index = favorites.FindIndex(i => i.Id == illust.Id);
|
||||
if (index < 0)
|
||||
bool add = index < 0;
|
||||
if (add)
|
||||
{
|
||||
illust.IsFavorite = true;
|
||||
illust.FavoriteDateUtc = DateTime.UtcNow;
|
||||
@ -543,6 +518,40 @@ namespace Pixiview.Illust
|
||||
favorites.RemoveAt(index);
|
||||
FavoriteIcon = fontIconNotLove;
|
||||
}
|
||||
|
||||
if (Configs.SyncFavType == SyncType.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (Configs.SyncFavType == SyncType.Prompt)
|
||||
{
|
||||
var ok = await DisplayAlert(
|
||||
ResourceHelper.Title,
|
||||
ResourceHelper.ConfirmSyncFavorite,
|
||||
ResourceHelper.Yes,
|
||||
ResourceHelper.No);
|
||||
if (!ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (add)
|
||||
{
|
||||
var id = await Task.Run(() => Stores.AddBookmark(illust.Id));
|
||||
if (id != null)
|
||||
{
|
||||
illust.BookmarkId = id;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var bookmarkId = illust.BookmarkId;
|
||||
if (!string.IsNullOrEmpty(bookmarkId))
|
||||
{
|
||||
_ = Task.Run(() => Stores.DeleteBookmark(bookmarkId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Image_Tapped(object sender, EventArgs e)
|
||||
@ -582,9 +591,47 @@ namespace Pixiview.Illust
|
||||
CurrentAnimeFrame = e.FrameIndex;
|
||||
}
|
||||
|
||||
private void DoForcePreload(bool force)
|
||||
{
|
||||
isPreloading = true;
|
||||
var illustItem = IllustItem;
|
||||
// force to reload
|
||||
var preload = Stores.LoadIllustPreloadData(illustItem.Id, force);
|
||||
if (preload != null && preload.illust.TryGetValue(illustItem.Id, out var illust))
|
||||
{
|
||||
illust.CopyToItem(illustItem);
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
var count = illustItem.PageCount;
|
||||
pageCount = count;
|
||||
Title = illustItem.Title;
|
||||
IsAnimateSliderVisible = illustItem.IsAnimeVisible;
|
||||
if (count > 1)
|
||||
{
|
||||
IsPageVisible = true;
|
||||
ProgressVisible = true;
|
||||
PagePositionText = $"1/{count}";
|
||||
}
|
||||
});
|
||||
if (preload.user.TryGetValue(illust.userId, out var user))
|
||||
{
|
||||
illustItem.ProfileUrl = user.image;
|
||||
}
|
||||
}
|
||||
isPreloading = false;
|
||||
}
|
||||
|
||||
private void Refresh_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
Task.Run(() => DoLoadImage(CurrentPage, true));
|
||||
if (isPreloading)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Task.Run(() =>
|
||||
{
|
||||
DoForcePreload(true);
|
||||
DoLoadImage(CurrentPage, true);
|
||||
});
|
||||
}
|
||||
|
||||
private async void More_Clicked(object sender, EventArgs e)
|
||||
|
@ -15,6 +15,8 @@
|
||||
<TableSection Title="{r:Text Illusts}">
|
||||
<u:OptionSwitchCell Title="{r:Text R18}"
|
||||
IsToggled="{Binding IsOnR18, Mode=TwoWay}"/>
|
||||
<u:OptionDropCell x:Name="optionFavSync" Title="{r:Text SyncType}"
|
||||
SelectedIndex="{Binding SyncFavType, Mode=TwoWay}"/>
|
||||
</TableSection>
|
||||
<TableSection Title="{r:Text Proxy}">
|
||||
<u:OptionSwitchCell Title="{r:Text Enabled}"
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Pixiview.Resources;
|
||||
using Pixiview.UI;
|
||||
using Pixiview.Utils;
|
||||
using Xamarin.Essentials;
|
||||
@ -10,6 +11,8 @@ namespace Pixiview
|
||||
{
|
||||
public static readonly BindableProperty IsOnR18Property = BindableProperty.Create(
|
||||
nameof(IsOnR18), typeof(bool), typeof(OptionPage));
|
||||
public static readonly BindableProperty SyncFavTypeProperty = BindableProperty.Create(
|
||||
nameof(SyncFavType), typeof(int), typeof(OptionPage), -1);
|
||||
public static readonly BindableProperty IsProxiedProperty = BindableProperty.Create(
|
||||
nameof(IsProxied), typeof(bool), typeof(OptionPage));
|
||||
public static readonly BindableProperty HostProperty = BindableProperty.Create(
|
||||
@ -24,6 +27,11 @@ namespace Pixiview
|
||||
get => (bool)GetValue(IsOnR18Property);
|
||||
set => SetValue(IsOnR18Property, value);
|
||||
}
|
||||
public int SyncFavType
|
||||
{
|
||||
get => (int)GetValue(SyncFavTypeProperty);
|
||||
set => SetValue(SyncFavTypeProperty, value);
|
||||
}
|
||||
public bool IsProxied
|
||||
{
|
||||
get => (bool)GetValue(IsProxiedProperty);
|
||||
@ -49,6 +57,14 @@ namespace Pixiview
|
||||
{
|
||||
BindingContext = this;
|
||||
InitializeComponent();
|
||||
|
||||
optionFavSync.Items = new[]
|
||||
{
|
||||
ResourceHelper.SyncNo,
|
||||
ResourceHelper.SyncPrompt,
|
||||
ResourceHelper.SyncAuto,
|
||||
};
|
||||
SyncFavType = 0;
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
@ -56,6 +72,7 @@ namespace Pixiview
|
||||
base.OnAppearing();
|
||||
|
||||
IsOnR18 = Configs.IsOnR18;
|
||||
SyncFavType = (int)Configs.SyncFavType;
|
||||
var proxy = Configs.Proxy;
|
||||
if (proxy != null)
|
||||
{
|
||||
@ -78,6 +95,7 @@ namespace Pixiview
|
||||
base.OnDisappearing();
|
||||
|
||||
var r18 = IsOnR18;
|
||||
var syncType = SyncFavType;
|
||||
var proxied = IsProxied;
|
||||
|
||||
if (Configs.IsOnR18 != r18)
|
||||
@ -87,6 +105,13 @@ namespace Pixiview
|
||||
App.DebugPrint($"r-18 filter: {r18}");
|
||||
}
|
||||
|
||||
if ((int)Configs.SyncFavType != syncType)
|
||||
{
|
||||
Preferences.Set(Configs.SyncFavTypeKey, syncType);
|
||||
Configs.SyncFavType = (SyncType)syncType;
|
||||
App.DebugPrint($"favorite sync type changed to {Configs.SyncFavType}");
|
||||
}
|
||||
|
||||
var proxy = Configs.Proxy;
|
||||
var h = Host?.Trim();
|
||||
_ = int.TryParse(Port, out int pt);
|
||||
|
@ -29,6 +29,10 @@
|
||||
<male_r18>{0} 最受欢迎</male_r18>
|
||||
<General>一般</General>
|
||||
<R18>R-18</R18>
|
||||
<SyncType>收藏同步类型</SyncType>
|
||||
<SyncNo>不同步</SyncNo>
|
||||
<SyncPrompt>提示同步</SyncPrompt>
|
||||
<SyncAuto>自动同步</SyncAuto>
|
||||
<Follow>已关注</Follow>
|
||||
<Recommends>推荐</Recommends>
|
||||
<ByUser>按用户</ByUser>
|
||||
@ -53,4 +57,5 @@
|
||||
<AlreadySavedVideo>视频已保存,是否继续?</AlreadySavedVideo>
|
||||
<ExportSuccess>视频已导出到照片库。</ExportSuccess>
|
||||
<FailedResponse>无法获取返回结果。</FailedResponse>
|
||||
<ConfirmSyncFavorite>要同步收藏吗?</ConfirmSyncFavorite>
|
||||
</root>
|
@ -17,6 +17,9 @@ namespace Pixiview.Resources
|
||||
public static string Yes => GetResource(nameof(Yes));
|
||||
public static string No => GetResource(nameof(No));
|
||||
public static string R18 => GetResource(nameof(R18));
|
||||
public static string SyncNo => GetResource(nameof(SyncNo));
|
||||
public static string SyncPrompt => GetResource(nameof(SyncPrompt));
|
||||
public static string SyncAuto => GetResource(nameof(SyncAuto));
|
||||
public static string Operation => GetResource(nameof(Operation));
|
||||
public static string SaveOriginal => GetResource(nameof(SaveOriginal));
|
||||
public static string Share => GetResource(nameof(Share));
|
||||
@ -34,6 +37,7 @@ namespace Pixiview.Resources
|
||||
public static string AlreadySavedVideo => GetResource(nameof(AlreadySavedVideo));
|
||||
public static string ExportSuccess => GetResource(nameof(ExportSuccess));
|
||||
public static string FailedResponse => GetResource(nameof(FailedResponse));
|
||||
public static string ConfirmSyncFavorite => GetResource(nameof(ConfirmSyncFavorite));
|
||||
|
||||
static readonly Dictionary<string, LanguageResource> dict = new Dictionary<string, LanguageResource>();
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
using Pixiview.UI.Theme;
|
||||
using System.Collections;
|
||||
using Pixiview.UI.Theme;
|
||||
using Pixiview.Utils;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Pixiview.UI
|
||||
{
|
||||
public class OptionEntry : Entry { }
|
||||
public class OptionPicker : Picker { }
|
||||
|
||||
public abstract class OptionCell : ViewCell
|
||||
{
|
||||
@ -27,8 +29,8 @@ namespace Pixiview.UI
|
||||
Padding = new Thickness(20, 0),
|
||||
ColumnDefinitions =
|
||||
{
|
||||
new ColumnDefinition { Width = new GridLength(.2, GridUnitType.Star) },
|
||||
new ColumnDefinition { Width = new GridLength(.8, GridUnitType.Star) }
|
||||
new ColumnDefinition { Width = new GridLength(.3, GridUnitType.Star) },
|
||||
new ColumnDefinition { Width = new GridLength(.7, GridUnitType.Star) }
|
||||
},
|
||||
Children =
|
||||
{
|
||||
@ -65,6 +67,35 @@ namespace Pixiview.UI
|
||||
}.Binding(Switch.IsToggledProperty, nameof(IsToggled), BindingMode.TwoWay);
|
||||
}
|
||||
|
||||
public class OptionDropCell : OptionCell
|
||||
{
|
||||
public static readonly BindableProperty ItemsProperty = BindableProperty.Create(
|
||||
nameof(Items), typeof(IList), typeof(OptionDropCell));
|
||||
public static readonly BindableProperty SelectedIndexProperty = BindableProperty.Create(
|
||||
nameof(SelectedIndex), typeof(int), typeof(OptionDropCell));
|
||||
|
||||
public IList Items
|
||||
{
|
||||
get => (IList)GetValue(ItemsProperty);
|
||||
set => SetValue(ItemsProperty, value);
|
||||
}
|
||||
public int SelectedIndex
|
||||
{
|
||||
get => (int)GetValue(SelectedIndexProperty);
|
||||
set => SetValue(SelectedIndexProperty, value);
|
||||
}
|
||||
|
||||
protected override View Content => new OptionPicker
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.Fill,
|
||||
VerticalOptions = LayoutOptions.Center
|
||||
}
|
||||
.Binding(Picker.ItemsSourceProperty, nameof(Items))
|
||||
.Binding(Picker.SelectedIndexProperty, nameof(SelectedIndex), BindingMode.TwoWay)
|
||||
.DynamicResource(Picker.TextColorProperty, ThemeBase.TextColor)
|
||||
.DynamicResource(VisualElement.BackgroundColorProperty, ThemeBase.OptionTintColor);
|
||||
}
|
||||
|
||||
public class OptionEntryCell : OptionCell
|
||||
{
|
||||
public static readonly BindableProperty TextProperty = BindableProperty.Create(
|
||||
|
@ -13,12 +13,14 @@ namespace Pixiview.Utils
|
||||
{
|
||||
public static T LoadObject<T>(string file, string url, string referer, out string error,
|
||||
bool force = false,
|
||||
bool nojson = false,
|
||||
HttpContent post = null,
|
||||
Action<HttpRequestHeaders> header = null,
|
||||
Func<T, string> namehandler = null,
|
||||
Func<string, string> action = null)
|
||||
{
|
||||
string content = null;
|
||||
if (!force && file != null && File.Exists(file))
|
||||
if (post == null && !force && file != null && File.Exists(file))
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -31,6 +33,11 @@ namespace Pixiview.Utils
|
||||
}
|
||||
if (content == null)
|
||||
{
|
||||
bool noToken = string.IsNullOrEmpty(Configs.CsrfToken);
|
||||
if (noToken)
|
||||
{
|
||||
post = null;
|
||||
}
|
||||
var response = Download(url, headers =>
|
||||
{
|
||||
if (referer != null)
|
||||
@ -44,6 +51,11 @@ namespace Pixiview.Utils
|
||||
{
|
||||
headers.Add("Cookie", cookie);
|
||||
}
|
||||
if (post != null && !noToken)
|
||||
{
|
||||
headers.Add("Origin", Configs.Referer);
|
||||
headers.Add("X-Csrf-Token", Configs.CsrfToken);
|
||||
}
|
||||
if (header == null)
|
||||
{
|
||||
var userId = Configs.UserId;
|
||||
@ -56,12 +68,18 @@ namespace Pixiview.Utils
|
||||
{
|
||||
header(headers);
|
||||
}
|
||||
});
|
||||
}, post);
|
||||
if (response == null)
|
||||
{
|
||||
error = "response is null";
|
||||
return default;
|
||||
}
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
App.DebugPrint($"http failed with code: {response.StatusCode}");
|
||||
error = response.StatusCode.ToString();
|
||||
return default;
|
||||
}
|
||||
using (response)
|
||||
{
|
||||
try
|
||||
@ -124,7 +142,14 @@ namespace Pixiview.Utils
|
||||
try
|
||||
{
|
||||
error = null;
|
||||
return JsonConvert.DeserializeObject<T>(content);
|
||||
if (nojson)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>("{}");
|
||||
}
|
||||
else
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(content);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -172,7 +197,7 @@ namespace Pixiview.Utils
|
||||
}
|
||||
}
|
||||
|
||||
private static HttpResponseMessage Download(string url, Action<HttpRequestHeaders> headerAction)
|
||||
private static HttpResponseMessage Download(string url, Action<HttpRequestHeaders> headerAction, HttpContent post = null)
|
||||
{
|
||||
App.DebugPrint($"GET: {url}");
|
||||
var uri = new Uri(url);
|
||||
@ -194,7 +219,7 @@ namespace Pixiview.Utils
|
||||
};
|
||||
return TryCount(() =>
|
||||
{
|
||||
using (var request = new HttpRequestMessage(HttpMethod.Get, uri.PathAndQuery)
|
||||
using (var request = new HttpRequestMessage(post == null ? HttpMethod.Get : HttpMethod.Post, uri.PathAndQuery)
|
||||
{
|
||||
Version = new Version(2, 0)
|
||||
})
|
||||
@ -207,6 +232,10 @@ namespace Pixiview.Utils
|
||||
}
|
||||
headers.Add("Accept-Language", Configs.AcceptLanguage);
|
||||
//headers.Add("Accept-Encoding", Configs.AcceptEncoding);
|
||||
if (post != null)
|
||||
{
|
||||
request.Content = post;
|
||||
}
|
||||
return client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).Result;
|
||||
}
|
||||
});
|
||||
|
@ -14,6 +14,12 @@ namespace Pixiview.Utils
|
||||
public T body;
|
||||
}
|
||||
|
||||
public class BookmarkResultData
|
||||
{
|
||||
public string last_bookmark_id;
|
||||
public string stacc_status_id;
|
||||
}
|
||||
|
||||
public class Illust
|
||||
{
|
||||
public string illustId;
|
||||
@ -30,6 +36,7 @@ namespace Pixiview.Utils
|
||||
public int width;
|
||||
public int height;
|
||||
public int pageCount;
|
||||
public IllustBookmark bookmarkData;
|
||||
public string alt;
|
||||
public IllustUrls urls;
|
||||
public string seriesId;
|
||||
@ -46,11 +53,19 @@ namespace Pixiview.Utils
|
||||
public string x540;
|
||||
}
|
||||
|
||||
public class IllustBookmark
|
||||
{
|
||||
public string id;
|
||||
[JsonProperty("private")]
|
||||
public bool isPrivate;
|
||||
}
|
||||
|
||||
public IllustItem ConvertToItem(ImageSource image = null)
|
||||
{
|
||||
return new IllustItem
|
||||
{
|
||||
Id = illustId,
|
||||
BookmarkId = bookmarkData?.id,
|
||||
Title = illustTitle,
|
||||
RankTitle = illustTitle,
|
||||
IllustType = (IllustType)illustType,
|
||||
@ -167,9 +182,11 @@ namespace Pixiview.Utils
|
||||
public int responseCount;
|
||||
public int viewCount;
|
||||
public bool isOriginal;
|
||||
public IllustBookmark bookmarkData;
|
||||
|
||||
public IllustItem CopyToItem(IllustItem item)
|
||||
{
|
||||
item.BookmarkId = bookmarkData?.id;
|
||||
item.Title = illustTitle;
|
||||
item.RankTitle = illustTitle;
|
||||
item.IllustType = (IllustType)illustType;
|
||||
@ -194,6 +211,13 @@ namespace Pixiview.Utils
|
||||
[JsonIgnore]
|
||||
public string Url => urls.regular;
|
||||
|
||||
public class IllustBookmark
|
||||
{
|
||||
public string id;
|
||||
[JsonProperty("private")]
|
||||
public bool isPrivate;
|
||||
}
|
||||
|
||||
public class IllustUrls
|
||||
{
|
||||
public string mini;
|
||||
|
@ -41,6 +41,8 @@ namespace Pixiview.Utils
|
||||
public string attr;
|
||||
public bool is_bookmarked;
|
||||
public bool bookmarkable;
|
||||
public string bookmark_id;
|
||||
public string bookmark_illust_restrict;
|
||||
|
||||
public class ContentType
|
||||
{
|
||||
@ -94,6 +96,7 @@ namespace Pixiview.Utils
|
||||
return new IllustItem
|
||||
{
|
||||
Id = illust_id.ToString(),
|
||||
BookmarkId = bookmark_id,
|
||||
Title = title,
|
||||
RankTitle = $"#{rank} {title}",
|
||||
IllustType = (IllustType)type,
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Pixiview.Illust;
|
||||
@ -310,9 +311,75 @@ namespace Pixiview.Utils
|
||||
{
|
||||
App.DebugPrint($"error when load global data, is null");
|
||||
}
|
||||
else
|
||||
{
|
||||
App.DebugPrint($"current csrf token: {result.token}");
|
||||
Configs.CsrfToken = result.token;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string AddBookmark(string id)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Configs.CsrfToken))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var content = new StringContent(
|
||||
"{\"illust_id\":\"" + id + "\",\"restrict\":0,\"comment\":\"\",\"tags\":[]}",
|
||||
Encoding.UTF8,
|
||||
Configs.AcceptJson);
|
||||
var result = HttpUtility.LoadObject<IllustResponse<BookmarkResultData>>(
|
||||
null,
|
||||
Configs.BookmarkAdd,
|
||||
Configs.Referer,
|
||||
out string error,
|
||||
force: true,
|
||||
post: content);
|
||||
if (error != null)
|
||||
{
|
||||
App.DebugPrint($"failed to add bookmark, error: {error}");
|
||||
}
|
||||
else if (result == null || result.error)
|
||||
{
|
||||
App.DebugPrint($"failed to add bookmark, message: {result.message}");
|
||||
}
|
||||
App.DebugPrint($"successs, bookmark id: {result.body.last_bookmark_id}, status: {result.body.stacc_status_id}");
|
||||
return result.body.last_bookmark_id;
|
||||
}
|
||||
|
||||
public static bool DeleteBookmark(string id)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Configs.CsrfToken))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var content = new StringContent(
|
||||
"mode=delete_illust_bookmark&bookmark_id=" + id,
|
||||
Encoding.UTF8,
|
||||
Configs.AcceptUrlEncoded);
|
||||
var result = HttpUtility.LoadObject<object>(
|
||||
null,
|
||||
Configs.BookmarkRpc,
|
||||
Configs.Referer,
|
||||
out string error,
|
||||
force: true,
|
||||
nojson: true,
|
||||
post: content);
|
||||
if (error != null)
|
||||
{
|
||||
App.DebugPrint($"failed to delete bookmark, error: {error}");
|
||||
return false;
|
||||
}
|
||||
else if (result == null)
|
||||
{
|
||||
App.DebugPrint("failed to delete bookmark, result is null");
|
||||
return false;
|
||||
}
|
||||
App.DebugPrint($"successs, delete bookmark");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static IllustPreloadBody LoadIllustPreloadData(string id, bool force = false)
|
||||
{
|
||||
var file = Path.Combine(CacheFolder, preloadsFolder, $"{id}.json");
|
||||
@ -512,6 +579,13 @@ namespace Pixiview.Utils
|
||||
}
|
||||
}
|
||||
|
||||
public enum SyncType
|
||||
{
|
||||
None = 0,
|
||||
Prompt,
|
||||
AutoSync
|
||||
}
|
||||
|
||||
public static class Configs
|
||||
{
|
||||
public const string ProfileNameKey = "name";
|
||||
@ -520,6 +594,7 @@ namespace Pixiview.Utils
|
||||
public const string CookieKey = "cookies";
|
||||
public const string UserIdKey = "user_id";
|
||||
public const string IsOnR18Key = "is_on_r18";
|
||||
public const string SyncFavTypeKey = "sync_fav_type";
|
||||
public const string IsProxiedKey = "is_proxied";
|
||||
public const string HostKey = "host";
|
||||
public const string PortKey = "port";
|
||||
@ -535,12 +610,14 @@ namespace Pixiview.Utils
|
||||
public const string RefererIllustUser = "https://www.pixiv.net/users/{0}/illustrations";
|
||||
|
||||
public static bool IsOnR18;
|
||||
public static SyncType SyncFavType;
|
||||
public static WebProxy Proxy;
|
||||
public static string Prefix => Proxy == null ?
|
||||
"https://hk.tsanie.us/reverse/" :
|
||||
"https://www.pixiv.net/";
|
||||
public static string UserId { get; private set; }
|
||||
public static string Cookie { get; private set; }
|
||||
public static string CsrfToken;
|
||||
|
||||
public static void SetUserId(string userId, bool save = false)
|
||||
{
|
||||
@ -613,6 +690,7 @@ namespace Pixiview.Utils
|
||||
public const int SuffixGlobalLength = 32;
|
||||
public const string SuffixPreload = " id=\"meta-preload-data\" content='";
|
||||
public const int SuffixPreloadLength = 33; // SuffixPreload.Length
|
||||
|
||||
public static string UrlIllustList => Prefix + "ajax/top/illust?mode=all&lang=zh";
|
||||
public static string UrlIllust => Prefix + "artworks/{0}";
|
||||
public static string UrlIllustRanking => Prefix + "ranking.php?{0}";
|
||||
@ -622,9 +700,14 @@ namespace Pixiview.Utils
|
||||
public static string UrlIllustUgoira => Prefix + "ajax/illust/{0}/ugoira_meta?lang=zh";
|
||||
public static string UrlIllustRecommendsInit => Prefix + "ajax/illust/{0}/recommend/init?limit=18&lang=zh";
|
||||
public static string UrlIllustRecommendsList => Prefix + "ajax/illust/recommend/illusts?{0}lang=zh";
|
||||
|
||||
public static string BookmarkAdd => Prefix + "ajax/illusts/bookmarks/add";
|
||||
public static string BookmarkRpc => Prefix + "rpc/index.php";
|
||||
|
||||
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.138 Safari/537.36";
|
||||
public const string AcceptImage = "image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5";
|
||||
public const string AcceptJson = "application/json";
|
||||
public const string AcceptUrlEncoded = "application/x-www-form-urlencoded";
|
||||
//public const string AcceptEncoding = "gzip, deflate";
|
||||
public const string AcceptLanguage = "zh-cn";
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user