diff --git a/Pixiview.iOS/Pixiview.iOS.csproj b/Pixiview.iOS/Pixiview.iOS.csproj index b23c6e3..d6b1fef 100644 --- a/Pixiview.iOS/Pixiview.iOS.csproj +++ b/Pixiview.iOS/Pixiview.iOS.csproj @@ -81,6 +81,7 @@ + diff --git a/Pixiview.iOS/Renderers/OptionEntryRenderer.cs b/Pixiview.iOS/Renderers/OptionEntryRenderer.cs new file mode 100644 index 0000000..7a5a601 --- /dev/null +++ b/Pixiview.iOS/Renderers/OptionEntryRenderer.cs @@ -0,0 +1,23 @@ +using System; +using Pixiview.iOS.Renderers; +using Pixiview.UI; +using Xamarin.Forms; +using Xamarin.Forms.Platform.iOS; + +[assembly: ExportRenderer(typeof(OptionEntry), typeof(OptionEntryRenderer))] +namespace Pixiview.iOS.Renderers +{ + public class OptionEntryRenderer : EntryRenderer + { + protected override void OnElementChanged(ElementChangedEventArgs e) + { + base.OnElementChanged(e); + + var control = Control; + if (control != null) + { + control.BorderStyle = UIKit.UITextBorderStyle.None; + } + } + } +} diff --git a/Pixiview/App.cs b/Pixiview/App.cs index c414be8..f3f8b33 100644 --- a/Pixiview/App.cs +++ b/Pixiview/App.cs @@ -36,6 +36,29 @@ namespace Pixiview SetTheme(theme, true); } + private void InitPreferences() + { + var isProxied = Preferences.Get(Configs.IsProxiedKey, false); + if (isProxied) + { + var host = Preferences.Get(Configs.HostKey, string.Empty); + int port = Preferences.Get(Configs.PortKey, 0); + if (!string.IsNullOrEmpty(host) && port > 0) + { + Configs.Proxy = new System.Net.WebProxy(host, port); + DebugPrint($"load proxy: {host}:{port}"); + } + else + { + Configs.Proxy = null; + } + } + else + { + Configs.Proxy = null; + } + } + private void InitLanguage(IEnvironmentService service) { var ci = service.GetCurrentCultureInfo(); @@ -76,6 +99,7 @@ namespace Pixiview MainPage = new AppShell(); InitResources(service); + InitPreferences(); } protected override void OnSleep() diff --git a/Pixiview/OptionPage.xaml b/Pixiview/OptionPage.xaml index 2bf334a..16fe1bc 100644 --- a/Pixiview/OptionPage.xaml +++ b/Pixiview/OptionPage.xaml @@ -4,9 +4,22 @@ xmlns:u="clr-namespace:Pixiview.UI" xmlns:r="clr-namespace:Pixiview.Resources" x:Class="Pixiview.OptionPage" - BackgroundColor="{DynamicResource WindowColor}" Title="{r:Text Option}"> - - + + + + + + + + + + + diff --git a/Pixiview/OptionPage.xaml.cs b/Pixiview/OptionPage.xaml.cs index 8e947f5..fdad41c 100644 --- a/Pixiview/OptionPage.xaml.cs +++ b/Pixiview/OptionPage.xaml.cs @@ -1,12 +1,79 @@ using Pixiview.UI; +using Pixiview.Utils; +using Xamarin.Essentials; +using Xamarin.Forms; namespace Pixiview { public partial class OptionPage : AdaptedPage { + public static readonly BindableProperty IsProxiedProperty = BindableProperty.Create( + nameof(IsProxied), typeof(bool), typeof(OptionPage)); + public static readonly BindableProperty HostProperty = BindableProperty.Create( + nameof(Host), typeof(string), typeof(OptionPage)); + public static readonly BindableProperty PortProperty = BindableProperty.Create( + nameof(Port), typeof(string), typeof(OptionPage)); + + public bool IsProxied + { + get => (bool)GetValue(IsProxiedProperty); + set => SetValue(IsProxiedProperty, value); + } + public string Host + { + get => (string)GetValue(HostProperty); + set => SetValue(HostProperty, value); + } + public string Port + { + get => (string)GetValue(PortProperty); + set => SetValue(PortProperty, value); + } + public OptionPage() { + BindingContext = this; InitializeComponent(); } + + protected override void OnAppearing() + { + base.OnAppearing(); + + IsProxied = Preferences.Get(Configs.IsProxiedKey, false); + Host = Preferences.Get(Configs.HostKey, string.Empty); + int pt = Preferences.Get(Configs.PortKey, 0); + if (pt > 0) + { + Port = pt.ToString(); + } + } + + protected override void OnDisappearing() + { + base.OnDisappearing(); + + var proxied = IsProxied; + var h = Host?.Trim(); + + Preferences.Set(Configs.IsProxiedKey, proxied); + Preferences.Set(Configs.HostKey, h); + var p = Port; + if (int.TryParse(p, out int pt) && pt > 0) + { + Preferences.Set(Configs.PortKey, pt); + } + + if (proxied && !string.IsNullOrEmpty(h) && pt > 0) + { + Configs.Proxy = new System.Net.WebProxy(h, pt); + App.DebugPrint($"set proxy to: {h}:{pt}"); + } + else + { + Configs.Proxy = null; + App.DebugPrint($"clear proxy"); + } + } } } diff --git a/Pixiview/Resources/Languages/zh-CN.xml b/Pixiview/Resources/Languages/zh-CN.xml index a45cc3f..1d3b665 100644 --- a/Pixiview/Resources/Languages/zh-CN.xml +++ b/Pixiview/Resources/Languages/zh-CN.xml @@ -5,6 +5,11 @@ 取消 + 代理 + 详细 + 启用 + 主机 + 端口 R-18 已关注 推荐 diff --git a/Pixiview/UI/OptionCell.cs b/Pixiview/UI/OptionCell.cs new file mode 100644 index 0000000..a8bf09a --- /dev/null +++ b/Pixiview/UI/OptionCell.cs @@ -0,0 +1,106 @@ +using Pixiview.UI.Theme; +using Pixiview.Utils; +using Xamarin.Forms; + +namespace Pixiview.UI +{ + public class OptionEntry : Entry { } + + public abstract class OptionCell : ViewCell + { + public static readonly BindableProperty TitleProperty = BindableProperty.Create( + nameof(Title), typeof(string), typeof(OptionCell)); + + public string Title + { + get => (string)GetValue(TitleProperty); + set => SetValue(TitleProperty, value); + } + + protected abstract View Content { get; } + + public OptionCell() + { + View = new Grid + { + BindingContext = this, + Padding = new Thickness(20, 0), + ColumnDefinitions = + { + new ColumnDefinition { Width = new GridLength(.2, GridUnitType.Star) }, + new ColumnDefinition { Width = new GridLength(.8, GridUnitType.Star) } + }, + Children = + { + new Label + { + LineBreakMode = LineBreakMode.TailTruncation, + VerticalOptions = LayoutOptions.Center + } + .Binding(Label.TextProperty, nameof(Title)) + .DynamicResource(Label.TextColorProperty, ThemeBase.TextColor), + + Content.GridColumn(1) + } + } + .DynamicResource(VisualElement.BackgroundColorProperty, ThemeBase.OptionTintColor); + } + } + + public class OptionSwitchCell : OptionCell + { + public static readonly BindableProperty IsToggledProperty = BindableProperty.Create( + nameof(IsToggled), typeof(bool), typeof(OptionSwitchCell)); + + public bool IsToggled + { + get => (bool)GetValue(IsToggledProperty); + set => SetValue(IsToggledProperty, value); + } + + protected override View Content => new Switch + { + HorizontalOptions = LayoutOptions.End, + VerticalOptions = LayoutOptions.Center + }.Binding(Switch.IsToggledProperty, nameof(IsToggled), BindingMode.TwoWay); + } + + public class OptionEntryCell : OptionCell + { + public static readonly BindableProperty TextProperty = BindableProperty.Create( + nameof(Text), typeof(string), typeof(OptionSwitchCell)); + public static readonly BindableProperty KeyboardProperty = BindableProperty.Create( + nameof(Keyboard), typeof(Keyboard), typeof(OptionSwitchCell)); + public static readonly BindableProperty PlaceholderProperty = BindableProperty.Create( + nameof(Placeholder), typeof(string), typeof(OptionSwitchCell)); + + public string Text + { + get => (string)GetValue(TextProperty); + set => SetValue(TextProperty, value); + } + public Keyboard Keyboard + { + get => (Keyboard)GetValue(KeyboardProperty); + set => SetValue(KeyboardProperty, value); + } + public string Placeholder + { + get => (string)GetValue(PlaceholderProperty); + set => SetValue(PlaceholderProperty, value); + } + + protected override View Content => new OptionEntry + { + HorizontalOptions = LayoutOptions.Fill, + HorizontalTextAlignment = TextAlignment.End, + VerticalOptions = LayoutOptions.Center, + ReturnType = ReturnType.Next + } + .Binding(Entry.TextProperty, nameof(Text), BindingMode.TwoWay) + .Binding(InputView.KeyboardProperty, nameof(Keyboard)) + .Binding(Entry.PlaceholderProperty, nameof(Placeholder)) + .DynamicResource(Entry.TextColorProperty, ThemeBase.TextColor) + .DynamicResource(VisualElement.BackgroundColorProperty, ThemeBase.OptionTintColor); + } +} diff --git a/Pixiview/UI/Theme/DarkTheme.cs b/Pixiview/UI/Theme/DarkTheme.cs index 2b7daa2..8443564 100644 --- a/Pixiview/UI/Theme/DarkTheme.cs +++ b/Pixiview/UI/Theme/DarkTheme.cs @@ -36,6 +36,7 @@ namespace Pixiview.UI.Theme Add(MaskColor, Color.FromRgba(0xff, 0xff, 0xff, 0x50)); Add(NavColor, Color.Black); Add(NavSelectedColor, Color.FromRgb(0x22, 0x22, 0x22)); + Add(OptionTintColor, Color.FromRgb(0x11, 0x11, 0x11)); } } } diff --git a/Pixiview/UI/Theme/LightTheme.cs b/Pixiview/UI/Theme/LightTheme.cs index 54ada22..ca1b227 100644 --- a/Pixiview/UI/Theme/LightTheme.cs +++ b/Pixiview/UI/Theme/LightTheme.cs @@ -36,6 +36,7 @@ namespace Pixiview.UI.Theme Add(MaskColor, Color.FromRgba(0, 0, 0, 0x50)); Add(NavColor, Color.FromRgb(0xf0, 0xf0, 0xf0)); Add(NavSelectedColor, Color.LightGray); + Add(OptionTintColor, Color.White); } } } diff --git a/Pixiview/UI/Theme/ThemeBase.cs b/Pixiview/UI/Theme/ThemeBase.cs index 56f757a..b344d0c 100644 --- a/Pixiview/UI/Theme/ThemeBase.cs +++ b/Pixiview/UI/Theme/ThemeBase.cs @@ -23,6 +23,7 @@ namespace Pixiview.UI.Theme public const string MaskColor = nameof(MaskColor); public const string NavColor = nameof(NavColor); public const string NavSelectedColor = nameof(NavSelectedColor); + public const string OptionTintColor = nameof(OptionTintColor); public const string IconLightFontFamily = nameof(IconLightFontFamily); public const string IconRegularFontFamily = nameof(IconRegularFontFamily); diff --git a/Pixiview/Utils/Extensions.cs b/Pixiview/Utils/Extensions.cs index b43e021..cacc70b 100644 --- a/Pixiview/Utils/Extensions.cs +++ b/Pixiview/Utils/Extensions.cs @@ -4,15 +4,15 @@ namespace Pixiview.Utils { public static class Extensions { - public static T Binding(this T view, BindableProperty property, string name) where T : BindableObject + public static T Binding(this T view, BindableProperty property, string name, BindingMode mode = BindingMode.Default) where T : BindableObject { if (name == null) { - view.SetValue(property, default(T)); + view.SetValue(property, property.DefaultValue); } else { - view.SetBinding(property, name); + view.SetBinding(property, name, mode); } return view; } @@ -28,6 +28,12 @@ namespace Pixiview.Utils Grid.SetRow(view, row); return view; } + + public static T GridColumn(this T view, int column) where T : BindableObject + { + Grid.SetColumn(view, column); + return view; + } } public static class Screen diff --git a/Pixiview/Utils/Stores.cs b/Pixiview/Utils/Stores.cs index 24ffeac..5f584e9 100644 --- a/Pixiview/Utils/Stores.cs +++ b/Pixiview/Utils/Stores.cs @@ -439,12 +439,16 @@ namespace Pixiview.Utils { App.DebugPrint($"GET: {url}"); var uri = new Uri(url); + var proxy = Configs.Proxy; var handler = new HttpClientHandler { - Proxy = Configs.Proxy, - UseProxy = true, AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }; + if (proxy != null) + { + handler.Proxy = proxy; + handler.UseProxy = true; + } var client = new HttpClient(handler) { BaseAddress = new Uri($"{uri.Scheme}://{uri.Host}") @@ -468,7 +472,11 @@ namespace Pixiview.Utils public static class Configs { - public static readonly WebProxy Proxy = new WebProxy("router.tsanie.us", 8088); + public const string IsProxiedKey = "isProxied"; + public const string HostKey = "host"; + public const string PortKey = "port"; + + public static WebProxy Proxy; public const int MaxThreads = 3; public const string Referer = "https://www.pixiv.net/";