diff --git a/Pixiview.Android/Pixiview.Android.csproj b/Pixiview.Android/Pixiview.Android.csproj
index fff1223..47aaf0d 100644
--- a/Pixiview.Android/Pixiview.Android.csproj
+++ b/Pixiview.Android/Pixiview.Android.csproj
@@ -80,6 +80,7 @@
+
@@ -95,10 +96,6 @@
-
-
-
-
@@ -207,6 +204,10 @@
+
+
+
+
diff --git a/Pixiview.Android/Renderers/HybridWebViewRenderer.cs b/Pixiview.Android/Renderers/HybridWebViewRenderer.cs
new file mode 100644
index 0000000..5f41826
--- /dev/null
+++ b/Pixiview.Android/Renderers/HybridWebViewRenderer.cs
@@ -0,0 +1,117 @@
+using Android.Content;
+using Android.Webkit;
+using Pixiview.Droid.Renderers;
+using Pixiview.Login;
+using Pixiview.Utils;
+using Xamarin.Forms;
+using Xamarin.Forms.Platform.Android;
+
+[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
+namespace Pixiview.Droid.Renderers
+{
+ public class HybridWebViewRenderer : WebViewRenderer
+ {
+ public HybridWebViewRenderer(Context context) : base(context)
+ {
+ }
+
+ protected override void OnElementChanged(ElementChangedEventArgs e)
+ {
+ base.OnElementChanged(e);
+
+ if (e.NewElement is HybridWebView webView)
+ {
+ Control.SetWebViewClient(new PixivWebViewClient(this));
+ Control.LoadUrl(webView.Uri);
+ }
+ }
+
+ private class PixivWebViewClient : FormsWebViewClient
+ {
+ private readonly HybridWebView webView;
+
+ public PixivWebViewClient(HybridWebViewRenderer renderer) : base(renderer)
+ {
+ if (renderer.Element is HybridWebView view)
+ {
+ webView = view;
+ }
+ }
+
+ //public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, IWebResourceRequest request)
+ //{
+ // var uri = request.Url;
+ // if (uri.Host == "www.pixiv.net" && uri.Path == "/")
+ // {
+ // var client = new HttpClient(new HttpClientHandler { UseCookies = false })
+ // {
+ // BaseAddress = new Uri($"{uri.Scheme}://{uri.Host}"),
+ // Timeout = TimeSpan.FromSeconds(30)
+ // };
+ // var pathAndQuery = uri.Path;
+ // if (!string.IsNullOrEmpty(uri.Query))
+ // {
+ // pathAndQuery += "?" + uri.EncodedQuery;
+ // }
+ // using (var req = new HttpRequestMessage(
+ // request.Method == "POST" ? HttpMethod.Post : HttpMethod.Get,
+ // pathAndQuery))
+ // {
+ // var headers = req.Headers;
+ // if (request.RequestHeaders != null)
+ // {
+ // foreach (var h in request.RequestHeaders)
+ // {
+ // headers.Add(h.Key, h.Value);
+ // }
+ // }
+
+ // using (var response = client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead).Result)
+ // {
+ // if (response.Headers.TryGetValues("x-userid", out var vals))
+ // {
+ // Configs.SetUserId(string.Join(';', vals), true);
+ // }
+ // }
+ // }
+ // return true;
+ // }
+ // return base.ShouldOverrideUrlLoading(view, request);
+ //}
+
+ public override void OnPageFinished(Android.Webkit.WebView view, string url)
+ {
+ base.OnPageFinished(view, url);
+
+ if (url == "https://www.pixiv.net/" ||
+ url == "https://www.pixiv.net/en/")
+ {
+ var cookieManager = CookieManager.Instance;
+ var cookie = cookieManager.GetCookie(url);
+ Configs.SetCookie(cookie, true);
+
+ // user-id
+ if (cookie != null)
+ {
+ var index = cookie.IndexOf("PHPSESSID=");
+ if (index >= 0)
+ {
+ var session = cookie.Substring(index + 10);
+ index = session.IndexOf('_');
+ if (index > 0)
+ {
+ session = session.Substring(0, index);
+ Configs.SetUserId(session, true);
+ }
+ }
+ }
+
+ if (webView != null)
+ {
+ webView.OnLoginHandle();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Pixiview.Android/Resources/Resource.designer.cs b/Pixiview.Android/Resources/Resource.designer.cs
index e9756e4..f0122b8 100644
--- a/Pixiview.Android/Resources/Resource.designer.cs
+++ b/Pixiview.Android/Resources/Resource.designer.cs
@@ -8337,65 +8337,65 @@ namespace Pixiview.Droid
// aapt resource value: 0x7F070069
public const int navigation_empty_icon = 2131165289;
- // aapt resource value: 0x7F07006A
- public const int notification_action_background = 2131165290;
-
// aapt resource value: 0x7F07006B
- public const int notification_bg = 2131165291;
+ public const int notification_action_background = 2131165291;
// aapt resource value: 0x7F07006C
- public const int notification_bg_low = 2131165292;
+ public const int notification_bg = 2131165292;
// aapt resource value: 0x7F07006D
- public const int notification_bg_low_normal = 2131165293;
+ public const int notification_bg_low = 2131165293;
// aapt resource value: 0x7F07006E
- public const int notification_bg_low_pressed = 2131165294;
+ public const int notification_bg_low_normal = 2131165294;
// aapt resource value: 0x7F07006F
- public const int notification_bg_normal = 2131165295;
+ public const int notification_bg_low_pressed = 2131165295;
// aapt resource value: 0x7F070070
- public const int notification_bg_normal_pressed = 2131165296;
+ public const int notification_bg_normal = 2131165296;
// aapt resource value: 0x7F070071
- public const int notification_icon_background = 2131165297;
+ public const int notification_bg_normal_pressed = 2131165297;
// aapt resource value: 0x7F070072
- public const int notification_template_icon_bg = 2131165298;
+ public const int notification_icon_background = 2131165298;
// aapt resource value: 0x7F070073
- public const int notification_template_icon_low_bg = 2131165299;
+ public const int notification_template_icon_bg = 2131165299;
// aapt resource value: 0x7F070074
- public const int notification_tile_bg = 2131165300;
+ public const int notification_template_icon_low_bg = 2131165300;
// aapt resource value: 0x7F070075
- public const int notify_panel_notification_icon_bg = 2131165301;
+ public const int notification_tile_bg = 2131165301;
// aapt resource value: 0x7F070076
- public const int segmented_control_background = 2131165302;
+ public const int notify_panel_notification_icon_bg = 2131165302;
+
+ // aapt resource value: 0x7F07006A
+ public const int no_profile = 2131165290;
// aapt resource value: 0x7F070077
- public const int segmented_control_first_background = 2131165303;
+ public const int segmented_control_background = 2131165303;
// aapt resource value: 0x7F070078
- public const int segmented_control_last_background = 2131165304;
+ public const int segmented_control_first_background = 2131165304;
// aapt resource value: 0x7F070079
- public const int splash_logo = 2131165305;
+ public const int segmented_control_last_background = 2131165305;
// aapt resource value: 0x7F07007A
- public const int splash_screen = 2131165306;
+ public const int splash_logo = 2131165306;
// aapt resource value: 0x7F07007B
- public const int tooltip_frame_dark = 2131165307;
+ public const int splash_screen = 2131165307;
// aapt resource value: 0x7F07007C
- public const int tooltip_frame_light = 2131165308;
+ public const int tooltip_frame_dark = 2131165308;
// aapt resource value: 0x7F07007D
- public const int userprofile = 2131165309;
+ public const int tooltip_frame_light = 2131165309;
static Drawable()
{
diff --git a/Pixiview.Android/Resources/drawable/no_profile.png b/Pixiview.Android/Resources/drawable/no_profile.png
new file mode 100644
index 0000000..9c4e4fb
Binary files /dev/null and b/Pixiview.Android/Resources/drawable/no_profile.png differ
diff --git a/Pixiview.Android/Resources/drawable/userprofile.jpg b/Pixiview.Android/Resources/drawable/userprofile.jpg
deleted file mode 100644
index 91428d8..0000000
Binary files a/Pixiview.Android/Resources/drawable/userprofile.jpg and /dev/null differ
diff --git a/Pixiview.iOS/Pixiview.iOS.csproj b/Pixiview.iOS/Pixiview.iOS.csproj
index 35d2c29..894b5e9 100644
--- a/Pixiview.iOS/Pixiview.iOS.csproj
+++ b/Pixiview.iOS/Pixiview.iOS.csproj
@@ -167,7 +167,7 @@
-
+
\ No newline at end of file
diff --git a/Pixiview.iOS/Renderers/HybridWebViewRenderer.cs b/Pixiview.iOS/Renderers/HybridWebViewRenderer.cs
index a3cdf90..933bde7 100644
--- a/Pixiview.iOS/Renderers/HybridWebViewRenderer.cs
+++ b/Pixiview.iOS/Renderers/HybridWebViewRenderer.cs
@@ -64,7 +64,7 @@ namespace Pixiview.iOS.Renderers
public override async void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
var url = webView.Url;
- if (url.Host == "www.pixiv.net" && url.Path == "/")
+ if (url.Host == "www.pixiv.net" && (url.Path == "/" || url.Path == "/en/"))
{
var store = webView.Configuration.WebsiteDataStore.HttpCookieStore;
var result = await Configs.RequestCookieContainer(store);
diff --git a/Pixiview.iOS/Resources/no_profile.png b/Pixiview.iOS/Resources/no_profile.png
new file mode 100644
index 0000000..9c4e4fb
Binary files /dev/null and b/Pixiview.iOS/Resources/no_profile.png differ
diff --git a/Pixiview.iOS/Resources/userprofile.jpg b/Pixiview.iOS/Resources/userprofile.jpg
deleted file mode 100644
index 91428d8..0000000
Binary files a/Pixiview.iOS/Resources/userprofile.jpg and /dev/null differ
diff --git a/Pixiview/App.cs b/Pixiview/App.cs
index 3f522f0..037dd68 100644
--- a/Pixiview/App.cs
+++ b/Pixiview/App.cs
@@ -3,6 +3,7 @@ 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;
@@ -34,6 +35,9 @@ 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);
var isProxied = Preferences.Get(Configs.IsProxiedKey, false);
if (isProxied)
diff --git a/Pixiview/AppShell.xaml b/Pixiview/AppShell.xaml
index 16eb2b4..5d7d4df 100644
--- a/Pixiview/AppShell.xaml
+++ b/Pixiview/AppShell.xaml
@@ -20,16 +20,16 @@
-
+
-
+ Text="{Binding UserProfileName}" TextColor="{DynamicResource TextColor}"/>
+ Text="{Binding UserProfileId}" TextColor="{DynamicResource SubTextColor}"/>
diff --git a/Pixiview/AppShell.xaml.cs b/Pixiview/AppShell.xaml.cs
index 4360359..90c7db8 100644
--- a/Pixiview/AppShell.xaml.cs
+++ b/Pixiview/AppShell.xaml.cs
@@ -1,5 +1,8 @@
using System;
+using System.Threading.Tasks;
using Pixiview.Login;
+using Pixiview.Resources;
+using Pixiview.UI;
using Pixiview.Utils;
using Xamarin.Essentials;
using Xamarin.Forms;
@@ -14,11 +17,35 @@ namespace Pixiview
public static Thickness HalfNavigationBarOffset { get; private set; }
public static Thickness TotalBarOffset { get; private set; }
+ public static readonly BindableProperty UserProfileImageProperty = BindableProperty.Create(
+ nameof(UserProfileImage), typeof(ImageSource), typeof(AppShell), StyleDefinition.ProfileNone);
+ public static readonly BindableProperty UserProfileNameProperty = BindableProperty.Create(
+ nameof(UserProfileName), typeof(string), typeof(AppShell), ResourceHelper.Guest);
+ public static readonly BindableProperty UserProfileIdProperty = BindableProperty.Create(
+ nameof(UserProfileId), typeof(string), typeof(AppShell));
+
+ public ImageSource UserProfileImage
+ {
+ get => (ImageSource)GetValue(UserProfileImageProperty);
+ set => SetValue(UserProfileImageProperty, value);
+ }
+ public string UserProfileName
+ {
+ get => (string)GetValue(UserProfileNameProperty);
+ set => SetValue(UserProfileNameProperty, value);
+ }
+ public string UserProfileId
+ {
+ get => (string)GetValue(UserProfileIdProperty);
+ set => SetValue(UserProfileIdProperty, value);
+ }
+
public event EventHandler NavigationBarHeightChanged;
public event EventHandler StatusBarHeightChanged;
public AppShell()
{
+ BindingContext = this;
InitializeComponent();
App.DebugPrint($"folder: {Stores.PersonalFolder}");
@@ -47,7 +74,14 @@ namespace Pixiview
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
- PushToLogin(null);
+ if (UserProfileId != null)
+ {
+ return;
+ }
+ PushToLogin(()=>
+ {
+ Task.Run(() => DoLoginInformation(true));
+ });
}
private bool isLoginOpened;
@@ -73,6 +107,38 @@ namespace Pixiview
await Navigation.PushModalAsync(loginPage);
});
}
+
+ public void DoLoginInformation(bool force = false)
+ {
+ string name = null;
+ string userId = null;
+ string img = null;
+ if (!force)
+ {
+ name = Preferences.Get(Configs.ProfileNameKey, null);
+ userId = Preferences.Get(Configs.ProfileIdKey, null);
+ img = Preferences.Get(Configs.ProfileImageKey, null);
+ }
+ if (name == null || userId == null)
+ {
+ var global = Stores.LoadGlobalData(force);
+ if (global == null || global.userData == null)
+ {
+ App.DebugError("login.info", "user data is null");
+ return;
+ }
+ name = global.userData.name;
+ userId = global.userData.pixivId;
+ img = global.userData.profileImg;
+ Preferences.Set(Configs.ProfileNameKey, name);
+ Preferences.Set(Configs.ProfileIdKey, userId);
+ Preferences.Set(Configs.ProfileImageKey, img);
+ }
+ UserProfileName = name;
+ UserProfileId = $"@{userId}";
+
+ UserProfileImage = Stores.LoadUserProfileImage(img);
+ }
}
public class BarHeightEventArgs : EventArgs
diff --git a/Pixiview/Illust/IllustCollectionPage.cs b/Pixiview/Illust/IllustCollectionPage.cs
index 2a3018c..61ca47e 100644
--- a/Pixiview/Illust/IllustCollectionPage.cs
+++ b/Pixiview/Illust/IllustCollectionPage.cs
@@ -73,9 +73,11 @@ namespace Pixiview.Illust
protected readonly Command commandIllustImageTapped;
protected DateTime lastUpdated;
protected double topOffset;
+ protected string lastError;
private T illustData;
private ParallelTask task;
+ private bool isTrying;
public IllustCollectionPage()
{
@@ -530,15 +532,31 @@ namespace Pixiview.Illust
illustData = DoLoadIllustData(force);
if (illustData == null)
{
- AppShell.Current.PushToLogin(()=>
+ if (isTrying)
{
- StartLoad(true);
- });
+ MainThread.BeginInvokeOnMainThread(() =>
+ {
+ DisplayAlert(ResourceHelper.Title,
+ ResourceHelper.FailedResponse + "\n" + lastError?.Substring(0, 40),
+ ResourceHelper.Ok);
+ });
+ isTrying = false;
+ }
+ else
+ {
+ isTrying = true;
+ AppShell.Current.PushToLogin(() =>
+ {
+ Task.Run(() => AppShell.Current.DoLoginInformation(true));
+ StartLoad(true);
+ });
+ }
//App.DebugError("illusts.load", "failed to load illusts data.");
IsLoading = false;
IsBottomLoading = false;
return;
}
+ isTrying = false;
if (force && IsFavoriteVisible)
{
var now = DateTime.Now;
diff --git a/Pixiview/Illust/RankingPage.xaml.cs b/Pixiview/Illust/RankingPage.xaml.cs
index 7c6cd16..449e8be 100644
--- a/Pixiview/Illust/RankingPage.xaml.cs
+++ b/Pixiview/Illust/RankingPage.xaml.cs
@@ -160,7 +160,7 @@ namespace Pixiview.Illust
protected override IllustRankingData DoLoadIllustData(bool force)
{
- var data = Stores.LoadIllustRankingData(lastQueryKey, queryDate, currentPage, force);
+ var data = Stores.LoadIllustRankingData(lastQueryKey, queryDate, currentPage, out lastError, force);
if (data != null)
{
if (int.TryParse(data.next, out int next))
diff --git a/Pixiview/Illust/ViewIllustPage.xaml.cs b/Pixiview/Illust/ViewIllustPage.xaml.cs
index 6e6f355..8b4bb80 100644
--- a/Pixiview/Illust/ViewIllustPage.xaml.cs
+++ b/Pixiview/Illust/ViewIllustPage.xaml.cs
@@ -331,16 +331,23 @@ namespace Pixiview.Illust
}
Illusts = items;
- Task.Run(DoLoadImages);
+ Task.Run(() => DoLoadImages());
}
- private void DoLoadImages()
+ private void DoLoadImages(bool force = false)
{
var illustItem = IllustItem;
- var pages = Stores.LoadIllustPageData(illustItem.Id);
+ var pages = Stores.LoadIllustPageData(illustItem.Id, out string error, force);
if (pages == null)
{
App.DebugError("illustPage.load", $"failed to load illust page data, id: {illustItem.Id}");
+ if (error != null)
+ {
+ MainThread.BeginInvokeOnMainThread(() =>
+ {
+ DisplayAlert(ResourceHelper.Title, error, ResourceHelper.Ok);
+ });
+ }
return;
}
var items = Illusts;
@@ -385,9 +392,13 @@ namespace Pixiview.Illust
var count = illustItem.PageCount;
pageCount = count;
Title = illustItem.Title;
- IsPageVisible = count > 1;
IsAnimateSliderVisible = illustItem.IsAnimeVisible;
- ProgressVisible = count > 1;
+ if (count > 1)
+ {
+ IsPageVisible = true;
+ ProgressVisible = true;
+ PagePositionText = $"1/{count}";
+ }
});
if (preload.user.TryGetValue(illust.userId, out var user))
{
@@ -423,6 +434,12 @@ 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)
{
App.DebugPrint($"invalid index: {index}");
diff --git a/Pixiview/Login/HybridWebView.cs b/Pixiview/Login/HybridWebView.cs
index 67c9961..a361ee5 100644
--- a/Pixiview/Login/HybridWebView.cs
+++ b/Pixiview/Login/HybridWebView.cs
@@ -1,4 +1,5 @@
using System;
+using Xamarin.Essentials;
using Xamarin.Forms;
namespace Pixiview.Login
@@ -29,7 +30,10 @@ namespace Pixiview.Login
public void OnLoginHandle()
{
- LoginHandle?.Invoke(this, EventArgs.Empty);
+ if (LoginHandle != null)
+ {
+ MainThread.BeginInvokeOnMainThread(() => LoginHandle(this, EventArgs.Empty));
+ }
}
}
}
diff --git a/Pixiview/OptionPage.xaml b/Pixiview/OptionPage.xaml
index 67d45df..9d86cc4 100644
--- a/Pixiview/OptionPage.xaml
+++ b/Pixiview/OptionPage.xaml
@@ -5,6 +5,10 @@
xmlns:r="clr-namespace:Pixiview.Resources"
x:Class="Pixiview.OptionPage"
Title="{r:Text Option}">
+
+
+
@@ -24,6 +28,11 @@
Text="{Binding Port, Mode=TwoWay}"
Keyboard="Numeric" Placeholder="8080"/>
+
+
+
diff --git a/Pixiview/OptionPage.xaml.cs b/Pixiview/OptionPage.xaml.cs
index 770e9d9..0d0ee2c 100644
--- a/Pixiview/OptionPage.xaml.cs
+++ b/Pixiview/OptionPage.xaml.cs
@@ -1,4 +1,5 @@
-using Pixiview.UI;
+using System;
+using Pixiview.UI;
using Pixiview.Utils;
using Xamarin.Essentials;
using Xamarin.Forms;
@@ -15,6 +16,8 @@ namespace Pixiview
nameof(Host), typeof(string), typeof(OptionPage));
public static readonly BindableProperty PortProperty = BindableProperty.Create(
nameof(Port), typeof(string), typeof(OptionPage));
+ public static readonly BindableProperty CookieProperty = BindableProperty.Create(
+ nameof(Cookie), typeof(string), typeof(OptionPage));
public bool IsOnR18
{
@@ -36,6 +39,11 @@ namespace Pixiview
get => (string)GetValue(PortProperty);
set => SetValue(PortProperty, value);
}
+ public string Cookie
+ {
+ get => (string)GetValue(CookieProperty);
+ set => SetValue(CookieProperty, value);
+ }
public OptionPage()
{
@@ -47,14 +55,22 @@ namespace Pixiview
{
base.OnAppearing();
- IsOnR18 = Preferences.Get(Configs.IsOnR18Key, false);
- IsProxied = Preferences.Get(Configs.IsProxiedKey, false);
- Host = Preferences.Get(Configs.HostKey, string.Empty);
- int pt = Preferences.Get(Configs.PortKey, 0);
- if (pt > 0)
+ IsOnR18 = Configs.IsOnR18;
+ var proxy = Configs.Proxy;
+ if (proxy != null)
{
- Port = pt.ToString();
+ IsProxied = true;
+ Host = proxy.Address.Host;
+ Port = proxy.Address.Port.ToString();
}
+ else
+ {
+ IsProxied = false;
+ Host = string.Empty;
+ Port = string.Empty;
+ }
+
+ Cookie = Configs.Cookie;
}
protected override void OnDisappearing()
@@ -63,30 +79,70 @@ namespace Pixiview
var r18 = IsOnR18;
var proxied = IsProxied;
+
+ if (Configs.IsOnR18 != r18)
+ {
+ Preferences.Set(Configs.IsOnR18Key, r18);
+ Configs.IsOnR18 = r18;
+ App.DebugPrint($"r-18 filter: {r18}");
+ }
+
+ var proxy = Configs.Proxy;
var h = Host?.Trim();
-
- Preferences.Set(Configs.IsOnR18Key, r18);
- Configs.IsOnR18 = r18;
- App.DebugPrint($"r-18 filter: {r18}");
-
- Preferences.Set(Configs.IsProxiedKey, proxied);
- Preferences.Set(Configs.HostKey, h);
- var p = Port;
- if (int.TryParse(p, out int pt) && pt > 0)
+ _ = int.TryParse(Port, out int pt);
+ if (proxied)
{
- Preferences.Set(Configs.PortKey, pt);
+ if (proxy == null ||
+ proxy.Address.Host != h ||
+ proxy.Address.Port != pt)
+ {
+ Preferences.Set(Configs.IsProxiedKey, true);
+ Preferences.Set(Configs.HostKey, h);
+ if (pt > 0)
+ {
+ Preferences.Set(Configs.PortKey, pt);
+ }
+ if (!string.IsNullOrEmpty(h) && pt > 0)
+ {
+ Configs.Proxy = new System.Net.WebProxy(h, pt);
+ App.DebugPrint($"set proxy to: {h}:{pt}");
+ }
+ }
}
-
- if (proxied && !string.IsNullOrEmpty(h) && pt > 0)
- {
- Configs.Proxy = new System.Net.WebProxy(h, pt);
- App.DebugPrint($"set proxy to: {h}:{pt}");
- }
- else
+ else if (proxy != null)
{
+ Preferences.Set(Configs.HostKey, false);
+ if (pt > 0)
+ {
+ Preferences.Set(Configs.PortKey, pt);
+ }
Configs.Proxy = null;
- App.DebugPrint($"clear proxy");
}
+
+ var cookie = Cookie;
+ if (Configs.Cookie != cookie)
+ {
+ Configs.SetCookie(cookie, true);
+ var index = cookie.IndexOf("PHPSESSID=");
+ if (index >= 0)
+ {
+ var session = cookie.Substring(index + 10);
+ index = session.IndexOf('_');
+ if (index > 0)
+ {
+ session = session.Substring(0, index);
+ Configs.SetUserId(session, true);
+ }
+ }
+ }
+ }
+
+ private async void ShareCookie_Clicked(object sender, EventArgs e)
+ {
+ await Share.RequestAsync(new ShareTextRequest
+ {
+ Text = Cookie
+ });
}
}
}
diff --git a/Pixiview/Resources/Languages/zh-CN.xml b/Pixiview/Resources/Languages/zh-CN.xml
index 35f916b..11b8187 100644
--- a/Pixiview/Resources/Languages/zh-CN.xml
+++ b/Pixiview/Resources/Languages/zh-CN.xml
@@ -1,6 +1,7 @@
Pixiview
+ 游客
OK
取消
是
@@ -12,6 +13,8 @@
启用
主机
端口
+ 隐私
+ Cookie
今日
本周
本月
@@ -49,4 +52,5 @@
无法导出视频,请先下载完成。
视频已保存,是否继续?
视频已导出到照片库。
+ 无法获取返回结果。
\ No newline at end of file
diff --git a/Pixiview/Resources/ResourceHelper.cs b/Pixiview/Resources/ResourceHelper.cs
index 2fc9224..a6fff42 100644
--- a/Pixiview/Resources/ResourceHelper.cs
+++ b/Pixiview/Resources/ResourceHelper.cs
@@ -11,6 +11,7 @@ namespace Pixiview.Resources
public class ResourceHelper
{
public static string Title => GetResource(nameof(Title));
+ public static string Guest => GetResource(nameof(Guest));
public static string Ok => GetResource(nameof(Ok));
public static string Cancel => GetResource(nameof(Cancel));
public static string Yes => GetResource(nameof(Yes));
@@ -32,6 +33,7 @@ namespace Pixiview.Resources
public static string CantExportVideo => GetResource(nameof(CantExportVideo));
public static string AlreadySavedVideo => GetResource(nameof(AlreadySavedVideo));
public static string ExportSuccess => GetResource(nameof(ExportSuccess));
+ public static string FailedResponse => GetResource(nameof(FailedResponse));
static readonly Dictionary dict = new Dictionary();
diff --git a/Pixiview/UI/StyleDefinition.cs b/Pixiview/UI/StyleDefinition.cs
index 920a059..9da44b2 100644
--- a/Pixiview/UI/StyleDefinition.cs
+++ b/Pixiview/UI/StyleDefinition.cs
@@ -16,6 +16,7 @@ namespace Pixiview.UI
public static readonly Color ColorRedBackground = Color.FromRgb(0xfd, 0x43, 0x63);
public static readonly Color ColorDownloadBackground = Color.FromRgb(0xd7, 0xd9, 0xe0);
public static readonly ImageSource DownloadBackground = ImageSource.FromFile("download.png");
+ public static readonly ImageSource ProfileNone = ImageSource.FromFile("no_profile.png");
public static readonly double FontSizeMicro = Device.GetNamedSize(NamedSize.Micro, typeof(Label));
public static readonly double FontSizeSmall = Device.GetNamedSize(NamedSize.Small, typeof(Label));
diff --git a/Pixiview/Utils/Extensions.cs b/Pixiview/Utils/Extensions.cs
index 9e0d222..4a8f695 100644
--- a/Pixiview/Utils/Extensions.cs
+++ b/Pixiview/Utils/Extensions.cs
@@ -97,6 +97,10 @@ namespace Pixiview.Utils
{
public static ParallelTask Start(int from, int toExclusive, int maxCount, Predicate action)
{
+ if (toExclusive <= from)
+ {
+ return null;
+ }
var task = new ParallelTask(from, toExclusive, maxCount, action);
Task.Run(task.Start);
return task;
diff --git a/Pixiview/Utils/HttpUtility.cs b/Pixiview/Utils/HttpUtility.cs
index 01833ca..a9fd6a3 100644
--- a/Pixiview/Utils/HttpUtility.cs
+++ b/Pixiview/Utils/HttpUtility.cs
@@ -11,7 +11,7 @@ namespace Pixiview.Utils
{
public class HttpUtility
{
- public static T LoadObject(string file, string url, string referer,
+ public static T LoadObject(string file, string url, string referer, out string error,
bool force = false,
Action header = null,
Func namehandler = null,
@@ -59,6 +59,7 @@ namespace Pixiview.Utils
});
if (response == null)
{
+ error = "response is null";
return default;
}
using (response)
@@ -73,7 +74,8 @@ namespace Pixiview.Utils
}
catch (Exception ex)
{
- App.DebugError("load.strea", $"failed to read stream, error: {ex.Message}");
+ App.DebugError("load.stream", $"failed to read stream, error: {ex.Message}");
+ error = ex.Message;
return default;
}
@@ -89,7 +91,9 @@ namespace Pixiview.Utils
}
catch (Exception ex)
{
- App.DebugError("load", $"failed to parse illust JSON object, error: {ex.Message}");
+ App.DebugError("load", $"failed to parse illust JSON object, content: {content}, error: {ex.Message}");
+ error = content;
+ return default;
}
}
@@ -112,17 +116,20 @@ namespace Pixiview.Utils
if (rtn)
{
+ error = null;
return result;
}
}
}
try
{
+ error = null;
return JsonConvert.DeserializeObject(content);
}
catch (Exception ex)
{
- App.DebugError("load", $"failed to parse illust JSON object, error: {ex.Message}");
+ App.DebugError("load", $"failed to parse illust JSON object, content: {content}, error: {ex.Message}");
+ error = content;
return default;
}
}
diff --git a/Pixiview/Utils/IllustLegacy.cs b/Pixiview/Utils/IllustLegacy.cs
index 99a6ca5..1d8033c 100644
--- a/Pixiview/Utils/IllustLegacy.cs
+++ b/Pixiview/Utils/IllustLegacy.cs
@@ -115,4 +115,24 @@ namespace Pixiview.Utils
}
}
}
+
+ public class IllustGlobalData
+ {
+ public string token;
+ public string oneSignalAppId;
+ public UserData userData;
+
+ public class UserData
+ {
+ public string id;
+ public string pixivId;
+ public string name;
+ public string profileImg;
+ public string profileImgBig;
+ public bool premium;
+ public int xRestrict;
+ public bool adult;
+ public bool safeMode;
+ }
+ }
}
diff --git a/Pixiview/Utils/Stores.cs b/Pixiview/Utils/Stores.cs
index 9ac7c08..6a0123d 100644
--- a/Pixiview/Utils/Stores.cs
+++ b/Pixiview/Utils/Stores.cs
@@ -4,7 +4,6 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Text;
-using System.Threading.Tasks;
using Newtonsoft.Json;
using Pixiview.Illust;
using Xamarin.Essentials;
@@ -22,6 +21,7 @@ namespace Pixiview.Utils
#endif
private const string favoriteFile = "favorites.json";
+ private const string globalFile = "global.json";
private const string imageFolder = "img-original";
private const string previewFolder = "img-master";
private const string ugoiraFolder = "img-zip-ugoira";
@@ -199,6 +199,7 @@ namespace Pixiview.Utils
file,
Configs.UrlIllustList,
Configs.Referer,
+ out _,
force: force);
if (result == null || result.error)
{
@@ -207,7 +208,7 @@ namespace Pixiview.Utils
return result;
}
- public static IllustRankingData LoadIllustRankingData(string mode, string date, int page, bool force = false)
+ public static IllustRankingData LoadIllustRankingData(string mode, string date, int page, out string error, bool force = false)
{
var file = Path.Combine(CacheFolder, mode, $"{date}_{page}.json");
string query = $"mode={mode}";
@@ -229,6 +230,7 @@ namespace Pixiview.Utils
file,
string.Format(Configs.UrlIllustRanking, query),
referer,
+ out error,
namehandler: rst =>
{
return Path.Combine(CacheFolder, mode, $"{rst.date}_{page}.json");
@@ -252,6 +254,7 @@ namespace Pixiview.Utils
file,
string.Format(Configs.UrlIllustRecommendsInit, id),
string.Format(Configs.RefererIllust, id),
+ out _,
force: force);
if (result == null || result.error)
{
@@ -270,7 +273,8 @@ namespace Pixiview.Utils
var result = HttpUtility.LoadObject(
null,
string.Format(Configs.UrlIllustRecommendsList, ps),
- string.Format(Configs.RefererIllust, id));
+ string.Format(Configs.RefererIllust, id),
+ out _);
if (result == null || result.error)
{
App.DebugPrint($"error when load recommends list data: {result?.message}");
@@ -278,6 +282,37 @@ namespace Pixiview.Utils
return result;
}
+ public static IllustGlobalData LoadGlobalData(bool force = false)
+ {
+ var file = Path.Combine(PersonalFolder, globalFile);
+ var result = HttpUtility.LoadObject(
+ file,
+ Configs.Prefix,
+ null,
+ out _,
+ force: force,
+ header: h => { },
+ action: content =>
+ {
+ var index = content.IndexOf(Configs.SuffixGlobal);
+ if (index > 0)
+ {
+ index += Configs.SuffixGlobalLength;
+ var end = content.IndexOf('\'', index);
+ if (end > index)
+ {
+ content = content.Substring(index, end - index);
+ }
+ }
+ return content;
+ });
+ if (result == null)
+ {
+ App.DebugPrint($"error when load global data, is null");
+ }
+ return result;
+ }
+
public static IllustPreloadBody LoadIllustPreloadData(string id, bool force = false)
{
var file = Path.Combine(CacheFolder, preloadsFolder, $"{id}.json");
@@ -285,6 +320,7 @@ namespace Pixiview.Utils
file,
string.Format(Configs.UrlIllust, id),
null,
+ out _,
force: force,
action: content =>
{
@@ -307,18 +343,22 @@ namespace Pixiview.Utils
return result;
}
- public static IllustPageData LoadIllustPageData(string id, bool force = false)
+ public static IllustPageData LoadIllustPageData(string id, out string error, bool force = false)
{
var file = Path.Combine(CacheFolder, pagesFolder, $"{id}.json");
var result = HttpUtility.LoadObject(
file,
string.Format(Configs.UrlIllustPage, id),
string.Format(Configs.RefererIllust, id),
+ out _,
force: force);
if (result == null || result.error)
{
- App.DebugPrint($"error when load page data: {result?.message}, force({force})");
+ error = result?.message ?? "result is null";
+ App.DebugPrint($"error when load page data: {error}, force({force})");
+ return null;
}
+ error = null;
return result;
}
@@ -329,6 +369,7 @@ namespace Pixiview.Utils
file,
string.Format(Configs.UrlIllustUgoira, id),
string.Format(Configs.RefererIllust, id),
+ out _,
force: force);
if (result == null || result.error)
{
@@ -342,7 +383,8 @@ namespace Pixiview.Utils
var list = HttpUtility.LoadObject(
null,
string.Format(Configs.UrlIllustUserAll, userId),
- string.Format(Configs.RefererIllustUser, userId));
+ string.Format(Configs.RefererIllustUser, userId),
+ out _);
if (list == null || list.error)
{
App.DebugPrint($"error when load user data: {list?.message}");
@@ -360,7 +402,8 @@ namespace Pixiview.Utils
var result = HttpUtility.LoadObject(
null,
string.Format(Configs.UrlIllustUserArtworks, userId, ps, firstPage ? 1 : 0),
- string.Format(Configs.RefererIllustUser, userId));
+ string.Format(Configs.RefererIllustUser, userId),
+ out _);
if (result == null || result.error)
{
App.DebugPrint($"error when load user illust data: {result?.message}");
@@ -471,6 +514,9 @@ namespace Pixiview.Utils
public static class Configs
{
+ public const string ProfileNameKey = "name";
+ public const string ProfileIdKey = "pixiv_id";
+ public const string ProfileImageKey = "profile_img";
public const string CookieKey = "cookies";
public const string UserIdKey = "user_id";
public const string IsOnR18Key = "is_on_r18";
@@ -490,7 +536,7 @@ namespace Pixiview.Utils
public static bool IsOnR18;
public static WebProxy Proxy;
- private static string Prefix => Proxy == null ?
+ public static string Prefix => Proxy == null ?
"https://hk.tsanie.us/reverse/" :
"https://www.pixiv.net/";
public static string UserId { get; private set; }
@@ -513,15 +559,27 @@ namespace Pixiview.Utils
}
}
- public static void SetCookie(string cookie)
+ public static void SetCookie(string cookie, bool save = false)
{
Cookie = cookie;
+ if (!save)
+ {
+ return;
+ }
+ if (cookie == null)
+ {
+ Preferences.Remove(CookieKey);
+ }
+ else
+ {
+ Preferences.Set(CookieKey, cookie);
+ }
}
#if __IOS__
- public static Task RequestCookieContainer(WebKit.WKHttpCookieStore cookieStore)
+ public static System.Threading.Tasks.Task RequestCookieContainer(WebKit.WKHttpCookieStore cookieStore)
{
- var task = new TaskCompletionSource();
+ var task = new System.Threading.Tasks.TaskCompletionSource();
cookieStore.GetAllCookies(cookies =>
{
var list = new List();
@@ -549,10 +607,10 @@ namespace Pixiview.Utils
});
return task.Task;
}
-#elif __ANDROID__
- task.SetResult(false);
#endif
+ public const string SuffixGlobal = " id=\"meta-global-data\" content='";
+ 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";