Skip to content

Commit

Permalink
XF Pages
Browse files Browse the repository at this point in the history
  • Loading branch information
AigioL committed Nov 3, 2021
1 parent ad16ec3 commit 776f333
Show file tree
Hide file tree
Showing 37 changed files with 907 additions and 61 deletions.
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
<PackageVersion Include="System.Diagnostics.Tracing" Version="4.3.0" />
<PackageVersion Include="TinyPinyin.Net" Version="1.0.2" />
<PackageVersion Include="JustArchiNET.Madness" Version="1.4.0" />
<PackageVersion Include="Xam.Plugins.Forms.ImageCircle" Version="3.1.1.1-beta" />
</ItemGroup>
<ItemGroup Condition=" $(DefineConstants.Contains('_HAVE_XF_')) ">
<PackageVersion Include="Xamarin.AndroidX.AppCompat" Version="1.3.1.3" />
Expand Down
1 change: 1 addition & 0 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ Read what we [milestones](https://github.com/SteamTools-Team/SteamTools/mileston
* [Ant Design](https://github.com/ant-design/ant-design)
* [Ant Design Blazor](https://github.com/ant-design-blazor/ant-design-blazor)
* [Toast messages for Xamarin.iOS](https://github.com/andrius-k/Toast)
* [ImageCirclePlugin](https://github.com/jamesmontemagno/ImageCirclePlugin)
* [Visual Studio App Center SDK for .NET](https://github.com/microsoft/appcenter-sdk-dotnet)
* [AppCenter-XMac](https://github.com/nor0x/AppCenter-XMac)
* [MSBuild.Sdk.Extras](https://github.com/novotnyllc/MSBuildSdkExtras)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ OS | Version | Architectures |
* [Ant Design](https://github.com/ant-design/ant-design)
* [Ant Design Blazor](https://github.com/ant-design-blazor/ant-design-blazor)
* [Toast messages for Xamarin.iOS](https://github.com/andrius-k/Toast)
* [ImageCirclePlugin](https://github.com/jamesmontemagno/ImageCirclePlugin)
* [Visual Studio App Center SDK for .NET](https://github.com/microsoft/appcenter-sdk-dotnet)
* [AppCenter-XMac](https://github.com/nor0x/AppCenter-XMac)
* [MSBuild.Sdk.Extras](https://github.com/novotnyllc/MSBuildSdkExtras)
Expand Down
15 changes: 10 additions & 5 deletions src/Common.CoreLib/Serializable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using static System.Serializable;
using SJsonSerializer = System.Text.Json.JsonSerializer;
using SJsonSerializerOptions = System.Text.Json.JsonSerializerOptions;
using SJsonIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition;

namespace System
{
Expand Down Expand Up @@ -110,8 +111,12 @@ public static string SJSON(JsonImplType implType, object? value, Type? inputType
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = writeIndented,
IgnoreNullValues = ignoreNullValues
//IgnoreNullValues = ignoreNullValues
};
if (ignoreNullValues)
{
options.DefaultIgnoreCondition = SJsonIgnoreCondition.WhenWritingNull;
}
return SJsonSerializer.Serialize(value, inputType ?? value?.GetType() ?? typeof(object), options);
default:
#if NOT_NJSON
Expand Down Expand Up @@ -313,9 +318,9 @@ public static T DMPB64U<T>(string? value, CancellationToken cancellationToken =
/// <param name="obj"></param>
/// <returns></returns>
[return: NotNullIfNotNull("obj")]
public static T? Clone<T>(T? obj)
public static T? Clone<T>(T? obj) where T : notnull
{
if (EqualityComparer<T>.Default.Equals(obj, default)) return default;
if (EqualityComparer<T?>.Default.Equals(obj, default)) return default;
#if NOT_MP
var jsonStr = SJSON(obj);
return DJSON<T>(jsonStr);
Expand Down Expand Up @@ -345,7 +350,7 @@ public static T DMPB64U<T>(string? value, CancellationToken cancellationToken =
/// <param name="value"></param>
/// <returns></returns>
public static string SJSON_Original(object? value)
=> SerializeObject(value, Formatting.Indented, Serializable.IgnoreJsonPropertyContractResolverWithStringEnumConverterSettings);
=> SerializeObject(value, Formatting.Indented, IgnoreJsonPropertyContractResolverWithStringEnumConverterSettings);

/// <summary>
/// 反序列化 JSON 模型,使用原键名
Expand All @@ -355,7 +360,7 @@ public static string SJSON_Original(object? value)
/// <returns></returns>
[return: MaybeNull]
public static T DJSON_Original<T>(string value)
=> DeserializeObject<T>(value, Serializable.IgnoreJsonPropertyContractResolverWithStringEnumConverterSettings);
=> DeserializeObject<T>(value, IgnoreJsonPropertyContractResolverWithStringEnumConverterSettings);
#endif
}

Expand Down
40 changes: 33 additions & 7 deletions src/ST.Client.Android/UI/MainApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#if DEBUG
using Square.LeakCanary;
#endif
using ImageCircle.Forms.Plugin.Droid;
using XFApplication = Xamarin.Forms.Application;
using XEAppTheme = Xamarin.Essentials.AppTheme;

namespace System.Application.UI
{
Expand Down Expand Up @@ -169,6 +172,7 @@ bool GetIsMainProcess()

Forms.Init(this, null);
FormsMaterial.Init(this, null);
ImageCircleRenderer.Init();

stopwatch.Stop();
startTrace.AppendFormatLine("init XF {0}ms", stopwatch.ElapsedMilliseconds);
Expand Down Expand Up @@ -202,6 +206,8 @@ bool GetIsMainProcess()
const AppTheme _DefaultActualTheme = AppTheme.Light;
AppTheme IApplication.DefaultActualTheme => _DefaultActualTheme;

public bool IsRuntimeSwitchXFAppTheme { get; set; } = true;

public new AppTheme Theme
{
get => AppCompatDelegate.DefaultNightMode switch
Expand All @@ -212,14 +218,34 @@ bool GetIsMainProcess()
};
set
{
var defaultNightMode = value switch
int defaultNightMode;
OSAppTheme theme;
switch (value)
{
case AppTheme.Light:
defaultNightMode = AppCompatDelegate.ModeNightNo;
theme = OSAppTheme.Light;
break;
case AppTheme.Dark:
defaultNightMode = AppCompatDelegate.ModeNightYes;
theme = OSAppTheme.Dark;
break;
case AppTheme.FollowingSystem:
defaultNightMode = AppCompatDelegate.ModeNightFollowSystem;
theme = AppInfo.RequestedTheme switch
{
XEAppTheme.Light => OSAppTheme.Light,
XEAppTheme.Dark => OSAppTheme.Dark,
_ => OSAppTheme.Unspecified,
};
break;
default:
return;
}
if (IsRuntimeSwitchXFAppTheme && XFApplication.Current is App app)
{
AppTheme.FollowingSystem => AppCompatDelegate.ModeNightFollowSystem,
AppTheme.Light => AppCompatDelegate.ModeNightNo,
AppTheme.Dark => AppCompatDelegate.ModeNightYes,
_ => int.MinValue,
};
if (defaultNightMode == int.MinValue) return;
app.AppTheme = theme;
}
AppCompatDelegate.DefaultNightMode = defaultNightMode;
}
}
Expand Down
14 changes: 10 additions & 4 deletions src/ST.Client.Android/UI/Renderers/FragmentPageRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@
using AndroidX.Fragment.App;
using System.Application.UI.Fragments;
using System.Application.UI.Renderers;
using System.Application.UI.Views;
using System.Collections.Generic;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using n = System.Application.UI.Views.Native;

[assembly: ExportRenderer(typeof(LocalAuthPage), typeof(FragmentPageRenderer<LocalAuthFragment>))]
[assembly: ExportRenderer(typeof(ArchiSteamFarmPlusPage), typeof(FragmentPageRenderer<ASFPlusFragment>))]
[assembly: ExportRenderer(typeof(MyPage), typeof(FragmentPageRenderer<MyFragment>))]
[assembly: ExportRenderer(
typeof(n.LocalAuthPage),
typeof(FragmentPageRenderer<LocalAuthFragment>))]
[assembly: ExportRenderer(
typeof(n.ArchiSteamFarmPlusPage),
typeof(FragmentPageRenderer<ASFPlusFragment>))]
[assembly: ExportRenderer(
typeof(n.MyPage),
typeof(FragmentPageRenderer<MyFragment>))]

namespace System.Application.UI.Renderers
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Globalization;
#if !__MOBILE__
using Avalonia.Data.Converters;
#else
using Xamarin.Forms;
#endif

namespace System.Application.Converters
{
public class LoginOrRegisterChannelBackgroundColorConverter : IValueConverter
{
static Color ColorFromHex(string hex)
{
return Color.FromHex(hex);
}

public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
var valueStr = value?.ToString();
return valueStr switch
{
nameof(FastLoginChannel.Steam) => ColorFromHex("#145c8f"),
nameof(FastLoginChannel.Xbox) or nameof(FastLoginChannel.Microsoft) => ColorFromHex("#027d00"),
nameof(FastLoginChannel.Apple) => ColorFromHex("#000000"),
nameof(FastLoginChannel.QQ) => ColorFromHex("#12B7F5"),
"Phone" or "PhoneNumber" => ColorFromHex("#2196F3"),
_ => Binding.DoNothing,
};
}

public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) => throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
#if !__MOBILE__
using Avalonia.Data.Converters;
#else
using Xamarin.Forms;
#endif

namespace System.Application.Converters
{
public class LoginOrRegisterChannelTextConverter : IMultiValueConverter
{
public object? Convert(IList<object?>? values, Type? targetType, object? parameter, CultureInfo? culture)
{
if (values != null && values.Count >= 3)
{
var stringValues = values.Select(x => (x is not string str) ? x?.ToString() ?? string.Empty : str).ToArray();
var args = stringValues.Skip(1).FirstOrDefault();
switch (args)
{
case "Xbox":
args = "Xbox Live";
break;
case "Phone" or "PhoneNumber":
return stringValues[2];
}
var format = stringValues.FirstOrDefault() ?? string.Empty;
return format.Format(args);
}
return Binding.DoNothing;
}

public object? Convert(object?[]? values, Type? targetType, object? parameter, CultureInfo? culture)
{
IList<object?>? values_ = values;
return Convert(values_, targetType, parameter, culture);
}

public object? ConvertBack(object? value, Type? targetType, object? parameter, CultureInfo? culture) => throw new NotImplementedException();

public object[]? ConvertBack(object? value, Type[]? targetTypes, object? parameter, CultureInfo? culture) => throw new NotImplementedException();
}
}
36 changes: 36 additions & 0 deletions src/ST.Client.XamarinForms/Converters/PathGeometryConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Globalization;
using Xamarin.Forms;
using XFSPathGeometryConverter = Xamarin.Forms.Shapes.PathGeometryConverter;

namespace System.Application.Converters
{
public class PathGeometryConverter : XFSPathGeometryConverter, IValueConverter
{
internal static object? GetGeometryByPathString(XFSPathGeometryConverter converter, string pathStr)
{
try
{
// https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/shapes/path-markup-syntax
var pathData = converter.ConvertFromInvariantString(pathStr);
return pathData;
}
catch
{
}
return Binding.DoNothing;
}

public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
var valueStr = value?.ToString();
if (!string.IsNullOrWhiteSpace(valueStr))
{
var r = GetGeometryByPathString(this, valueStr);
return r;
}
return Binding.DoNothing;
}

public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) => throw new NotImplementedException();
}
}
28 changes: 28 additions & 0 deletions src/ST.Client.XamarinForms/Converters/PathIconConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Globalization;
using Xamarin.Forms;
using static System.Application.Converters.PathGeometryConverter;
using static System.Application.Converters.ResourceKeyConverter;
using XFSPathGeometryConverter = Xamarin.Forms.Shapes.PathGeometryConverter;

namespace System.Application.Converters
{
public class PathIconConverter : XFSPathGeometryConverter, IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
var valueStr = value?.ToString();
if (!string.IsNullOrWhiteSpace(valueStr))
{
var pathStr = GetResourceByKey(valueStr)?.ToString();
if (!string.IsNullOrWhiteSpace(pathStr))
{
var r = GetGeometryByPathString(this, pathStr);
return r;
}
}
return Binding.DoNothing;
}

public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) => throw new NotImplementedException();
}
}
50 changes: 50 additions & 0 deletions src/ST.Client.XamarinForms/Converters/ResourceKeyConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Globalization;
using Xamarin.Forms;
using XFApplication = Xamarin.Forms.Application;

namespace System.Application.Converters
{
public class ResourceKeyConverter : IValueConverter
{
const string DrawingSvg = "DrawingSvg";

internal static object? GetResourceByKey(string key)
{
var res = XFApplication.Current.Resources;
if (res.ContainsKey(DrawingSvg))
{
var svgRes = res[DrawingSvg];
if (svgRes is ResourceDictionary drawingSvg)
{
switch (key)
{
case "Steam":
key = "SteamDrawing";
break;
case "PhoneNumber":
key = "Phone";
break;
}
if (drawingSvg.ContainsKey(key))
{
return drawingSvg[key];
}
}
}
return null;
}

public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
var valueStr = value?.ToString();
if (!string.IsNullOrWhiteSpace(valueStr))
{
var r = GetResourceByKey(valueStr);
return r;
}
return Binding.DoNothing;
}

public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) => throw new NotImplementedException();
}
}
Loading

0 comments on commit 776f333

Please sign in to comment.