mirror of
https://github.com/BeyondDimension/SteamTools.git
synced 2026-10-26 03:59:34 +08:00
save
This commit is contained in:
+1
-1
Submodule references/AvaloniaGif updated: 16c810dce2...0356f4bad0
@@ -1,7 +1,7 @@
|
||||
using Android.Content;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Android.OS;
|
||||
using AndroidApplication = Android.App.Application;
|
||||
//using Android.OS;
|
||||
//using AndroidApplication = Android.App.Application;
|
||||
|
||||
namespace System.Application
|
||||
{
|
||||
@@ -38,16 +38,16 @@ namespace System.Application
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
static bool IsDarkMode(Context context)
|
||||
public static bool IsDarkMode(Context context)
|
||||
{
|
||||
var isNight = IsNight(context);
|
||||
return isNight.HasValue && isNight.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否正在安卓Q中使用深色主题(Dark)
|
||||
/// </summary>
|
||||
public static bool IsDarkModeQ
|
||||
=> Build.VERSION.SdkInt >= BuildVersionCodes.Q && IsDarkMode(AndroidApplication.Context);
|
||||
///// <summary>
|
||||
///// 是否正在安卓Q中使用深色主题(Dark)
|
||||
///// </summary>
|
||||
//public static bool IsDarkModeQ
|
||||
// => Build.VERSION.SdkInt >= BuildVersionCodes.Q && IsDarkMode(AndroidApplication.Context);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using AndroidX.AppCompat.App;
|
||||
using AndroidX.AppCompat.App;
|
||||
using AndroidX.AppCompat.Widget;
|
||||
using System.Application.UI.Internals;
|
||||
using System.Common;
|
||||
|
||||
@@ -4,6 +4,8 @@ namespace System.Application.UI.ViewModels
|
||||
{
|
||||
public abstract class IdTitleIconViewModel<TId, TIcon> : ReactiveObject
|
||||
{
|
||||
protected virtual bool IgnoreIcon { get; }
|
||||
|
||||
protected TId? id;
|
||||
/// <summary>
|
||||
/// 唯一键
|
||||
@@ -15,7 +17,7 @@ namespace System.Application.UI.ViewModels
|
||||
{
|
||||
if (this.RaiseAndSetIfChanged2(ref id, value)) return;
|
||||
Title = GetTitleById(value);
|
||||
Icon = GetIconById(value);
|
||||
if (!IgnoreIcon) Icon = GetIconById(value);
|
||||
OnIdChanged(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ navigator.__proto__ = newProto;
|
||||
return theme switch
|
||||
{
|
||||
AppTheme.FollowingSystem => GetThemeStringByFollowingSystem(),
|
||||
_ => theme.ToString(),
|
||||
_ => theme.ToString2(),
|
||||
};
|
||||
static string GetThemeStringByFollowingSystem()
|
||||
{
|
||||
@@ -267,8 +267,8 @@ navigator.__proto__ = newProto;
|
||||
{
|
||||
goto dark;
|
||||
}
|
||||
return "auto";
|
||||
dark: return AppTheme.Dark.ToString();
|
||||
return AppTheme.FollowingSystem.ToString2();
|
||||
dark: return AppTheme.Dark.ToString2();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ namespace System.Application.UI.Views.Pages
|
||||
|
||||
webView = this.FindControl<WebView3>(nameof(webView));
|
||||
webView.Url = string.Format(
|
||||
"https://steampp.net/changelogbox?theme={0}&language={1}",
|
||||
UrlConstants.OfficialWebsite_Box_Changelog_,
|
||||
CefNetApp.GetTheme(),
|
||||
R.Language);
|
||||
}
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ namespace System.Application.UI.Views.Pages
|
||||
InitializeComponent();
|
||||
webViewQA = this.FindControl<WebView3>("webViewQA");
|
||||
webViewQA.Url = string.Format(
|
||||
"https://steampp.net/faqbox?theme={0}&language={1}",
|
||||
UrlConstants.OfficialWebsite_Box_Faq_,
|
||||
CefNetApp.GetTheme(),
|
||||
R.Language);
|
||||
}
|
||||
|
||||
+10
-10
@@ -20,7 +20,7 @@
|
||||
x:DataType="vm:ShareManageViewModel"
|
||||
x:CompileBindings="True">
|
||||
<Panel>
|
||||
<controls:TitleBar></controls:TitleBar>
|
||||
<controls:TitleBar></controls:TitleBar>
|
||||
<Menu
|
||||
Margin="0 0 145 0" Height="30"
|
||||
HorizontalAlignment="Right"
|
||||
@@ -104,16 +104,16 @@
|
||||
</ia:DataTriggerBehavior>
|
||||
</i:Interaction.Behaviors>
|
||||
</Ellipse>
|
||||
<controls:ScrollingTextBlock x:Name="nickname"
|
||||
Text="{Binding SteamNickName}"
|
||||
FontSize="20"
|
||||
Foreground="{DynamicResource HighlightForegroundBrushKey}"
|
||||
Cursor="Hand"
|
||||
<controls:ScrollingTextBlock x:Name="nickname"
|
||||
Text="{Binding SteamNickName}"
|
||||
FontSize="20"
|
||||
Foreground="{DynamicResource HighlightForegroundBrushKey}"
|
||||
Cursor="Hand"
|
||||
ToolTip.Tip="{ReflectionBinding Path=Res.UserChange_BtnTootlip,Mode=OneWay,Source={x:Static resx:R.Current}}">
|
||||
<i:Interaction.Behaviors>
|
||||
<ia:EventTriggerBehavior EventName="Tapped"
|
||||
<ia:EventTriggerBehavior EventName="Tapped"
|
||||
SourceObject="{ReflectionBinding #nickname}">
|
||||
<ia:InvokeCommandAction Command="{ReflectionBinding #u.DataContext.SteamId_Click}"
|
||||
<ia:InvokeCommandAction Command="{ReflectionBinding #u.DataContext.SteamId_Click}"
|
||||
CommandParameter="{Binding}"/>
|
||||
</ia:EventTriggerBehavior>
|
||||
</i:Interaction.Behaviors>
|
||||
@@ -226,6 +226,6 @@
|
||||
</ItemsRepeater.ItemTemplate>
|
||||
</ItemsRepeater>
|
||||
</ScrollViewer>
|
||||
|
||||
</Panel>
|
||||
|
||||
</Panel>
|
||||
</Window>
|
||||
|
||||
@@ -238,7 +238,7 @@ namespace System.Application.UI.Views.Windows
|
||||
}
|
||||
else if (IsHttpUrl(x))
|
||||
{
|
||||
if (x.StartsWith("https://steampp.net", StringComparison.OrdinalIgnoreCase))
|
||||
if (x.StartsWith(UrlConstants.OfficialWebsite, StringComparison.OrdinalIgnoreCase))
|
||||
x = string.Format(
|
||||
x + "?theme={0}&language={1}",
|
||||
CefNetApp.GetTheme(),
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace System.Application.Models
|
||||
using System.Application.Models;
|
||||
|
||||
namespace System.Application.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用程序主题
|
||||
@@ -23,6 +25,23 @@
|
||||
/// <summary>
|
||||
/// 自定义主题
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
Custom,
|
||||
}
|
||||
}
|
||||
|
||||
namespace System
|
||||
{
|
||||
public static partial class AppThemeEnumExtensions
|
||||
{
|
||||
public static string ToString2(this AppTheme value)
|
||||
{
|
||||
return value switch
|
||||
{
|
||||
AppTheme.FollowingSystem => "auto",
|
||||
AppTheme.Light => "light",
|
||||
_ => "dark",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ namespace System.Application.Services
|
||||
#endif
|
||||
}
|
||||
|
||||
public async void DelAccount()
|
||||
public async Task DelAccountAsync()
|
||||
{
|
||||
if (!IsAuthenticated) return;
|
||||
var msg = AppResources.Success_.Format(AppResources.DelAccount);
|
||||
|
||||
@@ -440,6 +440,15 @@ namespace System.Application.UI.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Bug 反馈 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string BugFeedback {
|
||||
get {
|
||||
return ResourceManager.GetString("BugFeedback", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 取消 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2520,6 +2529,15 @@ namespace System.Application.UI.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 产品官网 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string ProductOfficialWebsite {
|
||||
get {
|
||||
return ResourceManager.GetString("ProductOfficialWebsite", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 恢复代码 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -2988,6 +3006,15 @@ namespace System.Application.UI.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 源码仓库 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string SourceRepository {
|
||||
get {
|
||||
return ResourceManager.GetString("SourceRepository", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 开始更新 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -245,6 +245,9 @@
|
||||
<data name="Btn_Text_Continue" xml:space="preserve">
|
||||
<value>继续</value>
|
||||
</data>
|
||||
<data name="BugFeedback" xml:space="preserve">
|
||||
<value>Bug 反馈</value>
|
||||
</data>
|
||||
<data name="Cancel" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
@@ -942,6 +945,9 @@
|
||||
<data name="PleaseSelect" xml:space="preserve">
|
||||
<value>请选择</value>
|
||||
</data>
|
||||
<data name="ProductOfficialWebsite" xml:space="preserve">
|
||||
<value>产品官网</value>
|
||||
</data>
|
||||
<data name="RecoveryCode" xml:space="preserve">
|
||||
<value>恢复代码</value>
|
||||
</data>
|
||||
@@ -1099,6 +1105,9 @@
|
||||
<data name="SMSCode" xml:space="preserve">
|
||||
<value>短信验证代码</value>
|
||||
</data>
|
||||
<data name="SourceRepository" xml:space="preserve">
|
||||
<value>源码仓库</value>
|
||||
</data>
|
||||
<data name="StartUpdate" xml:space="preserve">
|
||||
<value>开始更新</value>
|
||||
</data>
|
||||
|
||||
@@ -1,114 +1,39 @@
|
||||
using ReactiveUI;
|
||||
using System.Application.Services;
|
||||
using System.Application.UI.Resx;
|
||||
using System.Properties;
|
||||
using System.Reactive;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using static System.Application.Services.CloudService.Constants;
|
||||
|
||||
namespace System.Application.UI.ViewModels
|
||||
{
|
||||
public class AboutPageViewModel : TabItemViewModel
|
||||
partial class AboutPageViewModel : TabItemViewModel
|
||||
{
|
||||
public static AboutPageViewModel Instance { get; } = new();
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get => AppResources.About;
|
||||
protected set { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public AboutPageViewModel()
|
||||
{
|
||||
IconKey = nameof(AboutPageViewModel).Replace("ViewModel", "Svg");
|
||||
|
||||
OpenBrowserCommand = ReactiveCommand.Create<string>(BrowserOpen);
|
||||
|
||||
CopyLinkCommand = ReactiveCommand.Create<string>(IDesktopAppService.Instance.SetClipboardText);
|
||||
|
||||
CheckUpdateCommand = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await IAppUpdateService.Instance.CheckUpdateAsync(showIsExistUpdateFalse: true);
|
||||
});
|
||||
|
||||
DelAccountCommand = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
if (!UserService.Current.IsAuthenticated) return;
|
||||
var r = await MessageBoxCompat.ShowAsync(AppResources.DelAccountTips, ThisAssembly.AssemblyTrademark, MessageBoxButtonCompat.OKCancel);
|
||||
if (r == MessageBoxResultCompat.OK)
|
||||
{
|
||||
UserService.Current.DelAccount();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> CheckUpdateCommand { get; }
|
||||
|
||||
public ReactiveCommand<string, Unit> OpenBrowserCommand { get; }
|
||||
|
||||
public ReactiveCommand<string, Unit> CopyLinkCommand { get; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> DelAccountCommand { get; }
|
||||
|
||||
static string GetOS() => DI.Platform switch
|
||||
{
|
||||
Platform.Windows => "Windows",
|
||||
Platform.Linux => "Linux",
|
||||
Platform.Android => "Android",
|
||||
Platform.Apple => DI.DeviceIdiom switch
|
||||
{
|
||||
DeviceIdiom.Phone => "iOS",
|
||||
DeviceIdiom.Tablet => "iPadOS",
|
||||
DeviceIdiom.Desktop => "macOS",
|
||||
DeviceIdiom.TV => "tvOS",
|
||||
DeviceIdiom.Watch => "watchOS",
|
||||
_ => string.Empty,
|
||||
},
|
||||
Platform.UWP => "UWP",
|
||||
_ => string.Empty,
|
||||
};
|
||||
|
||||
public string VersionDisplay => $"{ThisAssembly.VersionDisplay} for {GetOS()} ({RuntimeInformation.ProcessArchitecture})";
|
||||
|
||||
public string LabelVersionDisplay => ThisAssembly.IsBetaRelease ? "Beta Version:" : "Current Version:";
|
||||
|
||||
public string Copyright
|
||||
{
|
||||
get
|
||||
{
|
||||
// https://www.w3cschool.cn/html/html-copyright.html
|
||||
int startYear = 2020, thisYear = 2021;
|
||||
var nowYear = DateTime.Now.Year;
|
||||
if (nowYear < thisYear) nowYear = thisYear;
|
||||
return $"© {startYear}{(nowYear == startYear ? startYear : "-" + nowYear)} {ThisAssembly.AssemblyCompany}. All Rights Reserved.";
|
||||
}
|
||||
get => TitleName;
|
||||
protected set { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
public static string RmbadminSteamLink => SteamApiUrls.MY_PROFILE_URL;
|
||||
|
||||
public static string RmbadminLink => "https://github.com/rmbadmin";
|
||||
public static string RmbadminLink => UrlConstants.GitHub_User_Rmbadmin;
|
||||
|
||||
public static string AigioLLink => "https://github.com/AigioL";
|
||||
public static string AigioLLink => UrlConstants.GitHub_User_AigioL;
|
||||
|
||||
public static string MossimosLink => "https://github.com/Mossimos";
|
||||
public static string MossimosLink => UrlConstants.GitHub_User_Mossimos;
|
||||
|
||||
public static string CliencerLink => "https://space.bilibili.com/30031316";
|
||||
public static string CliencerLink => UrlConstants.BILI_User_Cliencer;
|
||||
|
||||
public static string PrivacyLink => "https://steampp.net/privacy";
|
||||
public static string PrivacyLink => UrlConstants.OfficialWebsite_Privacy;
|
||||
|
||||
public static string AgreementLink => "https://steampp.net/agreement";
|
||||
public static string AgreementLink => UrlConstants.OfficialWebsite_Agreement;
|
||||
|
||||
public static string OfficialLink => "https://steampp.net";
|
||||
public static string OfficialLink => UrlConstants.OfficialWebsite;
|
||||
|
||||
public static string SourceCodeLink => "https://github.com/rmbadmin/SteamTools";
|
||||
public static string SourceCodeLink => UrlConstants.GitHub_Repository;
|
||||
|
||||
public static string UserSupportLink => "https://steampp.net/contact";
|
||||
public static string UserSupportLink => UrlConstants.OfficialWebsite_Contact;
|
||||
|
||||
public static string BugReportLink => "https://github.com/rmbadmin/SteamTools/issues";
|
||||
public static string BugReportLink => UrlConstants.GitHub_Issues;
|
||||
|
||||
public static string FAQLink => "https://steampp.net/faq";
|
||||
public static string FAQLink => UrlConstants.OfficialWebsite_Faq;
|
||||
|
||||
public static string LicenseLink => "https://github.com/rmbadmin/SteamTools/blob/develop/LICENSE";
|
||||
public static string LicenseLink => UrlConstants.License_GPLv3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
using ReactiveUI;
|
||||
using System.Application.Services;
|
||||
using System.Application.UI.Resx;
|
||||
using System.Linq;
|
||||
using System.Properties;
|
||||
using System.Reactive;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
//#if __MOBILE__
|
||||
//using Xamarin.Essentials;
|
||||
//#endif
|
||||
using static System.Application.Services.CloudService.Constants;
|
||||
|
||||
namespace System.Application.UI.ViewModels
|
||||
{
|
||||
public partial class AboutPageViewModel
|
||||
{
|
||||
static string TitleName => AppResources.About;
|
||||
|
||||
public AboutPageViewModel()
|
||||
{
|
||||
#if !__MOBILE__
|
||||
IconKey = nameof(AboutPageViewModel).Replace("ViewModel", "Svg");
|
||||
#endif
|
||||
|
||||
OpenBrowserCommand = ReactiveCommand.Create<string>(BrowserOpen);
|
||||
|
||||
//#if !__MOBILE__
|
||||
// CopyLinkCommand =
|
||||
//#if __MOBILE__
|
||||
// ReactiveCommand.CreateFromTask<string>(Clipboard.SetTextAsync);
|
||||
//#else
|
||||
// ReactiveCommand.Create<string>(IDesktopAppService.Instance.SetClipboardText);
|
||||
//#endif
|
||||
//#endif
|
||||
|
||||
CheckUpdateCommand = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await IAppUpdateService.Instance.CheckUpdateAsync(showIsExistUpdateFalse: true);
|
||||
});
|
||||
|
||||
DelAccountCommand = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
if (!UserService.Current.IsAuthenticated) return;
|
||||
#if !__MOBILE__
|
||||
var r = await MessageBoxCompat.ShowAsync(AppResources.DelAccountTips, ThisAssembly.AssemblyTrademark, MessageBoxButtonCompat.OKCancel);
|
||||
if (r == MessageBoxResultCompat.OK)
|
||||
{
|
||||
await UserService.Current.DelAccountAsync();
|
||||
}
|
||||
#else
|
||||
throw new NotImplementedException();
|
||||
#endif
|
||||
});
|
||||
|
||||
#if __MOBILE__
|
||||
preferenceButtons = new()
|
||||
{
|
||||
PreferenceButtonViewModel.Create(PreferenceButton.检查更新, this),
|
||||
PreferenceButtonViewModel.Create(PreferenceButton.更新日志, this),
|
||||
PreferenceButtonViewModel.Create(PreferenceButton.常见问题疑难解答, this),
|
||||
PreferenceButtonViewModel.Create(PreferenceButton.开放源代码许可, this),
|
||||
PreferenceButtonViewModel.Create(PreferenceButton.源码仓库, this),
|
||||
PreferenceButtonViewModel.Create(PreferenceButton.产品官网, this),
|
||||
PreferenceButtonViewModel.Create(PreferenceButton.联系我们, this),
|
||||
PreferenceButtonViewModel.Create(PreferenceButton.Bug反馈, this),
|
||||
};
|
||||
|
||||
UserService.Current.WhenAnyValue(x => x.User).Subscribe(value =>
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
PreferenceButtonViewModel.RemoveAuthorized(preferenceButtons, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
var delAccount = preferenceButtons.FirstOrDefault(x => x.Id == PreferenceButton.账号注销);
|
||||
if (delAccount == null)
|
||||
{
|
||||
delAccount = PreferenceButtonViewModel.Create(PreferenceButton.账号注销, this);
|
||||
preferenceButtons.Add(delAccount);
|
||||
}
|
||||
}
|
||||
}).AddTo(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> CheckUpdateCommand { get; }
|
||||
|
||||
public ReactiveCommand<string, Unit> OpenBrowserCommand { get; }
|
||||
|
||||
//#if !__MOBILE__
|
||||
// public ReactiveCommand<string, Unit> CopyLinkCommand { get; }
|
||||
//#endif
|
||||
|
||||
public ReactiveCommand<Unit, Unit> DelAccountCommand { get; }
|
||||
|
||||
static string GetOS() => DI.Platform switch
|
||||
{
|
||||
Platform.Windows => "Windows",
|
||||
Platform.Linux => "Linux",
|
||||
Platform.Android => "Android",
|
||||
Platform.Apple => DI.DeviceIdiom switch
|
||||
{
|
||||
DeviceIdiom.Phone => "iOS",
|
||||
DeviceIdiom.Tablet => "iPadOS",
|
||||
DeviceIdiom.Desktop => "macOS",
|
||||
DeviceIdiom.TV => "tvOS",
|
||||
DeviceIdiom.Watch => "watchOS",
|
||||
_ => string.Empty,
|
||||
},
|
||||
Platform.UWP => "UWP",
|
||||
_ => string.Empty,
|
||||
};
|
||||
|
||||
public string VersionDisplay => $"{ThisAssembly.VersionDisplay} for {GetOS()} ({RuntimeInformation.ProcessArchitecture})";
|
||||
|
||||
public string LabelVersionDisplay => ThisAssembly.IsBetaRelease ? "Beta Version:" : "Current Version:";
|
||||
|
||||
public string Copyright
|
||||
{
|
||||
get
|
||||
{
|
||||
// https://www.w3cschool.cn/html/html-copyright.html
|
||||
int startYear = 2020, thisYear = 2021;
|
||||
var nowYear = DateTime.Now.Year;
|
||||
if (nowYear < thisYear) nowYear = thisYear;
|
||||
return $"© {startYear}{(nowYear == startYear ? startYear : "-" + nowYear)} {ThisAssembly.AssemblyCompany}. All Rights Reserved.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -223,10 +223,10 @@ namespace System.Application.UI.ViewModels
|
||||
switch (parameter)
|
||||
{
|
||||
case Agreement:
|
||||
parameter = "https://steampp.net/AgreementBox";
|
||||
parameter = UrlConstants.OfficialWebsite_Box_Agreement;
|
||||
break;
|
||||
case Privacy:
|
||||
parameter = "https://steampp.net/PrivacyBox";
|
||||
parameter = UrlConstants.OfficialWebsite_Box_Privacy;
|
||||
break;
|
||||
}
|
||||
#if __MOBILE__
|
||||
|
||||
@@ -9,11 +9,10 @@
|
||||
|
||||
<include layout="@layout/shared_toolbar" />
|
||||
|
||||
<ScrollView
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/grey_window_background"
|
||||
android:fillViewport="true">
|
||||
android:background="@color/grey_window_background">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -55,6 +54,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/preference_buttons_space_min"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textColorLink="@color/text_link"
|
||||
android:textSize="14sp"
|
||||
tools:text="Developers: @软妹币玩家 - @AigioL - @Mossimos"
|
||||
xamarin:managedType="AndroidX.AppCompat.Widget.AppCompatTextView" />
|
||||
@@ -65,6 +65,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/preference_buttons_space_min"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textColorLink="@color/text_link"
|
||||
android:textSize="14sp"
|
||||
tools:text="Business Cooperation Contact: @Cliencer克总"
|
||||
xamarin:managedType="AndroidX.AppCompat.Widget.AppCompatTextView" />
|
||||
@@ -75,6 +76,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/preference_buttons_space_min"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textColorLink="@color/text_link"
|
||||
android:textSize="14sp"
|
||||
tools:text="This open source software is licensed with GPLv3 License"
|
||||
xamarin:managedType="AndroidX.AppCompat.Widget.AppCompatTextView" />
|
||||
@@ -87,52 +89,29 @@
|
||||
android:paddingTop="@dimen/preference_buttons_space_min"
|
||||
android:paddingBottom="@dimen/preference_buttons_space_min"
|
||||
tools:itemCount="9"
|
||||
tools:listitem="@layout/layout_preference_large_button"
|
||||
tools:listitem="@layout/layout_preference_small_button"
|
||||
xamarin:managedType="AndroidX.RecyclerView.Widget.RecyclerView" />
|
||||
|
||||
<!--检查更新-->
|
||||
<!--更新日志-->
|
||||
<!--常见问题疑难解答-->
|
||||
<!--开放源代码许可-->
|
||||
<!--源码仓库-->
|
||||
<!--产品官网-->
|
||||
<!--联系我们-->
|
||||
<!--Bug反馈-->
|
||||
<!--账号注销-->
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvAgreementAndPrivacy"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textColorLink="@color/text_link"
|
||||
android:textSize="14sp"
|
||||
tools:text="用户协议 | 隐私政策"
|
||||
xamarin:managedType="AndroidX.AppCompat.Widget.AppCompatTextView" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvAgreementAndPrivacy"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textSize="14sp"
|
||||
tools:text="用户协议 | 隐私政策"
|
||||
xamarin:managedType="AndroidX.AppCompat.Widget.AppCompatTextView" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvCopyright"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/preference_buttons_space_min"
|
||||
android:layout_marginBottom="@dimen/preference_buttons_space_min"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textSize="12sp"
|
||||
tools:text="© 2020-2021 长沙次元超越科技有限公司. All Rights Reserved."
|
||||
xamarin:managedType="AndroidX.AppCompat.Widget.AppCompatTextView" />
|
||||
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvCopyright"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/preference_buttons_space_min"
|
||||
android:layout_marginBottom="@dimen/preference_buttons_space_min"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textSize="12sp"
|
||||
tools:text="© 2020-2021 长沙次元超越科技有限公司. All Rights Reserved."
|
||||
xamarin:managedType="AndroidX.AppCompat.Widget.AppCompatTextView" />
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
||||
|
||||
+2
-2
@@ -20,8 +20,8 @@
|
||||
android:id="@+id/ivIcon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginEnd="@dimen/activity_horizontal_margin"
|
||||
app:tint="@color/icon_background"
|
||||
tools:src="@drawable/baseline_account_box_black_24"
|
||||
xamarin:managedType="AndroidX.AppCompat.Widget.AppCompatImageView" />
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:xamarin="http://schemas.xamarin.com/android/xamarin/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:background="?android:windowBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:paddingStart="@dimen/activity_horizontal_margin"
|
||||
android:paddingEnd="@dimen/activity_horizontal_margin">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textSize="17sp"
|
||||
tools:text="检查更新"
|
||||
xamarin:managedType="AndroidX.AppCompat.Widget.AppCompatTextView" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -82,6 +82,7 @@
|
||||
<Compile Remove="UI\Views.Controls\**" />
|
||||
<EmbeddedResource Remove="UI\Views.Controls\**" />
|
||||
<None Remove="UI\Views.Controls\**" />
|
||||
<Compile Include="..\Common.ClientLib.Droid\Application\DarkModeUtil.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)'=='Debug'">
|
||||
@@ -337,6 +338,9 @@
|
||||
<AndroidResource Include="..\ST.Client.Mobile.Droid.Design\ui\src\main\res\drawable-xxxhdpi\baseline_verified_user_black_24.png">
|
||||
<Link>Resources\drawable-xxxhdpi\baseline_verified_user_black_24.png</Link>
|
||||
</AndroidResource>
|
||||
<AndroidBoundLayout Include="..\ST.Client.Mobile.Droid.Design\ui\src\main\res\layout\activity_about.xml">
|
||||
<Link>Resources\layout\activity_about.xml</Link>
|
||||
</AndroidBoundLayout>
|
||||
<AndroidBoundLayout Include="..\ST.Client.Mobile.Droid.Design\ui\src\main\res\layout\activity_login_or_register.xml">
|
||||
<Link>Resources\layout\activity_login_or_register.xml</Link>
|
||||
</AndroidBoundLayout>
|
||||
@@ -373,6 +377,9 @@
|
||||
<AndroidBoundLayout Include="..\ST.Client.Mobile.Droid.Design\ui\src\main\res\layout\layout_preference_large_button.xml">
|
||||
<Link>Resources\layout\layout_preference_large_button.xml</Link>
|
||||
</AndroidBoundLayout>
|
||||
<AndroidBoundLayout Include="..\ST.Client.Mobile.Droid.Design\ui\src\main\res\layout\layout_preference_small_button.xml">
|
||||
<Link>Resources\layout\layout_preference_small_button.xml</Link>
|
||||
</AndroidBoundLayout>
|
||||
<AndroidBoundLayout Include="..\ST.Client.Mobile.Droid.Design\ui\src\main\res\layout\shared_loading.xml">
|
||||
<Link>Resources\layout\shared_loading.xml</Link>
|
||||
</AndroidBoundLayout>
|
||||
@@ -474,3 +481,4 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,207 @@
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.Graphics;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Text;
|
||||
using Android.Text.Style;
|
||||
using AndroidX.RecyclerView.Widget;
|
||||
using Binding;
|
||||
using Google.Android.Material.Dialog;
|
||||
using ReactiveUI;
|
||||
using System.Application.UI.Adapters;
|
||||
using System.Application.UI.Resx;
|
||||
using System.Application.UI.ViewModels;
|
||||
using System.Text;
|
||||
using Xamarin.Essentials;
|
||||
using static System.Application.Services.CloudService.Constants;
|
||||
using static System.Application.UI.ViewModels.AboutPageViewModel;
|
||||
|
||||
namespace System.Application.UI.Activities
|
||||
{
|
||||
[Register(JavaPackageConstants.Activities + nameof(AboutActivity))]
|
||||
[Activity(Theme = ManifestConstants.MainTheme,
|
||||
[Activity(Theme = ManifestConstants.MainTheme_NoActionBar,
|
||||
LaunchMode = LaunchMode.SingleTask,
|
||||
ConfigurationChanges = ManifestConstants.ConfigurationChanges)]
|
||||
internal sealed class AboutActivity : BaseActivity
|
||||
internal sealed class AboutActivity : BaseActivity<activity_about, AboutPageViewModel>
|
||||
{
|
||||
protected override int? LayoutResource => throw new NotImplementedException();
|
||||
protected override int? LayoutResource => Resource.Layout.activity_about;
|
||||
|
||||
protected override void OnCreate(Bundle? savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
|
||||
this.SetSupportActionBarWithNavigationClick(binding!.toolbar);
|
||||
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
|
||||
|
||||
ViewModel = new();
|
||||
ViewModel.AddTo(this);
|
||||
|
||||
binding!.tvDevelopers.SetLinkMovementMethod();
|
||||
binding!.tvBusinessCooperationContact.SetLinkMovementMethod();
|
||||
binding!.tvOpenSourceLicensed.SetLinkMovementMethod();
|
||||
binding!.tvAgreementAndPrivacy.SetLinkMovementMethod();
|
||||
|
||||
binding!.tvTitle.TextFormatted = CreateTitle();
|
||||
binding!.tvVersion.Text = $"{ViewModel.LabelVersionDisplay} {ViewModel.VersionDisplay}";
|
||||
binding!.tvDevelopers.TextFormatted = CreateDevelopers();
|
||||
binding!.tvBusinessCooperationContact.TextFormatted = CreateBusinessCooperationContact();
|
||||
binding!.tvOpenSourceLicensed.TextFormatted = CreateOpenSourceLicensed();
|
||||
binding!.tvCopyright.Text = ViewModel.Copyright;
|
||||
|
||||
R.Current.WhenAnyValue(x => x.Res).Subscribe(_ =>
|
||||
{
|
||||
Title = ViewModel.Title;
|
||||
binding!.tvAgreementAndPrivacy.TextFormatted = CreateAgreementAndPrivacy();
|
||||
}).AddTo(this);
|
||||
|
||||
static void BrowserOpenByDialogClick(DialogClickEventArgs e, Func<string, string?> func)
|
||||
{
|
||||
if (e.Which >= 0 && e.Which < SourceRepositories.Length)
|
||||
{
|
||||
var value = func(SourceRepositories[e.Which]);
|
||||
if (value != default) BrowserOpen(value);
|
||||
}
|
||||
}
|
||||
|
||||
var adapter = new SmallPreferenceButtonAdapter<PreferenceButtonViewModel, PreferenceButton>(ViewModel!.PreferenceButtons);
|
||||
adapter.ItemClick += (_, e) =>
|
||||
{
|
||||
switch (e.Current.Id)
|
||||
{
|
||||
case PreferenceButton.检查更新:
|
||||
ViewModel!.CheckUpdateCommand.Invoke();
|
||||
break;
|
||||
case PreferenceButton.更新日志:
|
||||
BrowserOpen(string.Format(
|
||||
UrlConstants.OfficialWebsite_Box_Changelog_,
|
||||
MainApplication.GetTheme(),
|
||||
R.Language));
|
||||
break;
|
||||
case PreferenceButton.常见问题疑难解答:
|
||||
BrowserOpen(string.Format(
|
||||
UrlConstants.OfficialWebsite_Box_Faq_,
|
||||
MainApplication.GetTheme(),
|
||||
R.Language));
|
||||
break;
|
||||
case PreferenceButton.开放源代码许可:
|
||||
throw new NotImplementedException();
|
||||
break;
|
||||
case PreferenceButton.源码仓库:
|
||||
new MaterialAlertDialogBuilder(this).SetItems(SourceRepositories, (_, e) => BrowserOpenByDialogClick(e, value => value switch
|
||||
{
|
||||
GitHub => UrlConstants.GitHub_Repository,
|
||||
Gitee => UrlConstants.Gitee_Repository,
|
||||
_ => default,
|
||||
})).Show();
|
||||
break;
|
||||
case PreferenceButton.产品官网:
|
||||
BrowserOpen(UrlConstants.OfficialWebsite);
|
||||
break;
|
||||
case PreferenceButton.联系我们:
|
||||
BrowserOpen(UrlConstants.OfficialWebsite_Contact);
|
||||
break;
|
||||
case PreferenceButton.Bug反馈:
|
||||
new MaterialAlertDialogBuilder(this).SetItems(SourceRepositories, (_, e) => BrowserOpenByDialogClick(e, value => value switch
|
||||
{
|
||||
GitHub => UrlConstants.GitHub_Issues,
|
||||
Gitee => UrlConstants.Gitee_Issues,
|
||||
_ => default,
|
||||
})).Show();
|
||||
break;
|
||||
case PreferenceButton.账号注销:
|
||||
ViewModel!.DelAccountCommand.Invoke();
|
||||
break;
|
||||
}
|
||||
};
|
||||
var layout = new LinearLayoutManager(this, LinearLayoutManager.Vertical, false);
|
||||
binding.rvPreferenceButtons.SetLayoutManager(layout);
|
||||
binding.rvPreferenceButtons.SetAdapter(adapter);
|
||||
}
|
||||
|
||||
static SpannableString CreateTitle()
|
||||
{
|
||||
SpannableString spannable = new(Title_0 + Title_1);
|
||||
ForegroundColorSpan fcs = new(ThemeAccentBrushKey.ToPlatformColor());
|
||||
int start = Title_0.Length, end = Title_0.Length + Title_1.Length;
|
||||
spannable.SetSpan(fcs, start, end, SpanTypes.ExclusiveExclusive);
|
||||
StyleSpan ss = new(TypefaceStyle.Bold);
|
||||
spannable.SetSpan(ss, start, end, SpanTypes.ExclusiveExclusive);
|
||||
return spannable;
|
||||
}
|
||||
|
||||
static SpannableString CreateDevelopers() => MainApplication.CreateSpannableString(list =>
|
||||
{
|
||||
int length;
|
||||
StringBuilder str = new(Developers_0);
|
||||
length = str.Length;
|
||||
str.Append(At_Rmbadmin);
|
||||
list.Add((new HyperlinkClickableSpan(_ =>
|
||||
{
|
||||
BrowserOpen(UrlConstants.GitHub_User_Rmbadmin);
|
||||
}), length, str.Length, SpanTypes.ExclusiveExclusive));
|
||||
str.Append(Separator);
|
||||
length = str.Length;
|
||||
str.Append(At_AigioL);
|
||||
list.Add((new HyperlinkClickableSpan(_ =>
|
||||
{
|
||||
BrowserOpen(UrlConstants.GitHub_User_AigioL);
|
||||
}), length, str.Length, SpanTypes.ExclusiveExclusive));
|
||||
str.Append(Separator);
|
||||
length = str.Length;
|
||||
str.Append(At_Mossimos);
|
||||
list.Add((new HyperlinkClickableSpan(_ =>
|
||||
{
|
||||
BrowserOpen(UrlConstants.GitHub_User_Mossimos);
|
||||
}), length, str.Length, SpanTypes.ExclusiveExclusive));
|
||||
return str;
|
||||
});
|
||||
|
||||
static SpannableString CreateBusinessCooperationContact() => MainApplication.CreateSpannableString(list =>
|
||||
{
|
||||
int length;
|
||||
StringBuilder str = new(BusinessCooperationContact_0);
|
||||
length = str.Length;
|
||||
str.Append(At_Cliencer);
|
||||
list.Add((new HyperlinkClickableSpan(_ =>
|
||||
{
|
||||
BrowserOpen(UrlConstants.BILI_User_Cliencer);
|
||||
}), length, str.Length, SpanTypes.ExclusiveExclusive));
|
||||
return str;
|
||||
});
|
||||
|
||||
static SpannableString CreateAgreementAndPrivacy() => MainApplication.CreateSpannableString(list =>
|
||||
{
|
||||
int length;
|
||||
StringBuilder str = new();
|
||||
length = str.Length;
|
||||
str.Append(AppResources.User_Agreement);
|
||||
list.Add((new HyperlinkClickableSpan(_ =>
|
||||
{
|
||||
BrowserOpen(UrlConstants.OfficialWebsite_Box_Agreement);
|
||||
}), length, str.Length, SpanTypes.ExclusiveExclusive));
|
||||
str.Append(Separator2);
|
||||
length = str.Length;
|
||||
str.Append(AppResources.User_Privacy);
|
||||
list.Add((new HyperlinkClickableSpan(_ =>
|
||||
{
|
||||
BrowserOpen(UrlConstants.OfficialWebsite_Box_Privacy);
|
||||
}), length, str.Length, SpanTypes.ExclusiveExclusive));
|
||||
return str;
|
||||
});
|
||||
|
||||
static SpannableString CreateOpenSourceLicensed() => MainApplication.CreateSpannableString(list =>
|
||||
{
|
||||
int length;
|
||||
StringBuilder str = new(OpenSourceLicensed_0);
|
||||
length = str.Length;
|
||||
str.Append(OpenSourceLicensed_1);
|
||||
list.Add((new HyperlinkClickableSpan(_ =>
|
||||
{
|
||||
BrowserOpen(UrlConstants.License_GPLv3);
|
||||
}), length, str.Length, SpanTypes.ExclusiveExclusive));
|
||||
return str;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -10,13 +10,10 @@ using AndroidX.Navigation.UI;
|
||||
using Binding;
|
||||
using Microsoft.Identity.Client;
|
||||
using ReactiveUI;
|
||||
using System.Application.Mvvm;
|
||||
using System.Application.UI.Resx;
|
||||
using System.Application.UI.ViewModels;
|
||||
using System.Collections.Generic;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Text;
|
||||
using JObject = Java.Lang.Object;
|
||||
|
||||
namespace System.Application.UI.Activities
|
||||
{
|
||||
@@ -24,11 +21,8 @@ namespace System.Application.UI.Activities
|
||||
[Activity(Theme = ManifestConstants.MainTheme_NoActionBar,
|
||||
LaunchMode = LaunchMode.SingleTask,
|
||||
ConfigurationChanges = ManifestConstants.ConfigurationChanges)]
|
||||
internal sealed class LoginOrRegisterActivity : BaseActivity<activity_login_or_register, LoginOrRegisterPageViewModel>, IDisposableHolder
|
||||
internal sealed class LoginOrRegisterActivity : BaseActivity<activity_login_or_register, LoginOrRegisterPageViewModel>
|
||||
{
|
||||
readonly CompositeDisposable disposables = new();
|
||||
ICollection<IDisposable> IDisposableHolder.CompositeDisposable => disposables;
|
||||
|
||||
protected override int? LayoutResource => Resource.Layout.activity_login_or_register;
|
||||
|
||||
static readonly Dictionary<int, Func<string>> title_strings = new()
|
||||
@@ -73,15 +67,14 @@ namespace System.Application.UI.Activities
|
||||
AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
public static SpannableString CreateAgreementAndPrivacy(LoginOrRegisterPageViewModel viewModel)
|
||||
public static SpannableString CreateAgreementAndPrivacy(LoginOrRegisterPageViewModel viewModel) => MainApplication.CreateSpannableString(list =>
|
||||
{
|
||||
int length;
|
||||
var linkTextIndexs = new List<(JObject what, int start, int end, SpanTypes flags)>();
|
||||
StringBuilder str = new(AppResources.User_RegisterAgreed);
|
||||
str.Append(" ");
|
||||
length = str.Length;
|
||||
str.Append(AppResources.User_Agreement);
|
||||
linkTextIndexs.Add((new HyperlinkClickableSpan(_ =>
|
||||
list.Add((new HyperlinkClickableSpan(_ =>
|
||||
{
|
||||
viewModel.OpenHyperlink.Invoke(LoginOrRegisterPageViewModel.Agreement);
|
||||
}), length, str.Length, SpanTypes.ExclusiveExclusive));
|
||||
@@ -90,17 +83,11 @@ namespace System.Application.UI.Activities
|
||||
str.Append(" ");
|
||||
length = str.Length;
|
||||
str.Append(AppResources.User_Privacy);
|
||||
linkTextIndexs.Add((new HyperlinkClickableSpan(_ =>
|
||||
list.Add((new HyperlinkClickableSpan(_ =>
|
||||
{
|
||||
viewModel.OpenHyperlink.Invoke(LoginOrRegisterPageViewModel.Privacy);
|
||||
}), length, str.Length, SpanTypes.ExclusiveExclusive));
|
||||
|
||||
SpannableString spannable = new(str.ToString());
|
||||
foreach (var (what, start, end, flags) in linkTextIndexs)
|
||||
{
|
||||
spannable.SetSpan(what, start, end, flags);
|
||||
}
|
||||
return spannable;
|
||||
}
|
||||
return str;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,7 @@ using AndroidX.Navigation.UI;
|
||||
using Binding;
|
||||
using Java.Lang;
|
||||
using ReactiveUI;
|
||||
using System.Application.Mvvm;
|
||||
using System.Application.UI.ViewModels;
|
||||
using System.Collections.Generic;
|
||||
using System.Reactive.Disposables;
|
||||
|
||||
namespace System.Application.UI.Activities
|
||||
{
|
||||
@@ -18,11 +15,8 @@ namespace System.Application.UI.Activities
|
||||
[Activity(Theme = ManifestConstants.MainTheme_NoActionBar,
|
||||
LaunchMode = LaunchMode.SingleTask,
|
||||
ConfigurationChanges = ManifestConstants.ConfigurationChanges)]
|
||||
internal sealed class MainActivity : BaseActivity<activity_main>, IDisposableHolder, IReadOnlyViewFor<MyPageViewModel>
|
||||
internal sealed class MainActivity : BaseActivity<activity_main>, IReadOnlyViewFor<MyPageViewModel>
|
||||
{
|
||||
readonly CompositeDisposable disposables = new();
|
||||
ICollection<IDisposable> IDisposableHolder.CompositeDisposable => disposables;
|
||||
|
||||
protected override int? LayoutResource => Resource.Layout.activity_main;
|
||||
|
||||
protected override bool BackToHome => true;
|
||||
@@ -75,7 +69,6 @@ namespace System.Application.UI.Activities
|
||||
{
|
||||
base.OnDestroy();
|
||||
navController = null;
|
||||
disposables.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-6
@@ -2,14 +2,18 @@ using Android.Views;
|
||||
using Binding;
|
||||
using ReactiveUI;
|
||||
using System.Application.UI.ViewModels;
|
||||
using TViewHolder = System.Application.UI.Adapters.MyPreferenceButtonViewHolder;
|
||||
using TViewModel = System.Application.UI.ViewModels.MyPageViewModel.PreferenceButtonViewModel;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace System.Application.UI.Adapters
|
||||
{
|
||||
internal sealed class MyPreferenceButtonAdapter : BaseReactiveRecycleViewAdapter<TViewHolder, TViewModel>
|
||||
internal sealed class LargePreferenceButtonAdapter<TViewModel, TId> : BaseReactiveRecycleViewAdapter<LargePreferenceButtonViewHolder<TViewModel, TId>, TViewModel>
|
||||
where TViewModel : RIdTitleIconViewModel<TId, ResIcon>
|
||||
{
|
||||
public MyPreferenceButtonAdapter(MyPageViewModel viewModel) : base(viewModel.PreferenceButtons)
|
||||
public LargePreferenceButtonAdapter(ObservableCollection<TViewModel> collection) : base(collection)
|
||||
{
|
||||
}
|
||||
|
||||
public LargePreferenceButtonAdapter(ReadOnlyObservableCollection<TViewModel> collection) : base(collection)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -19,11 +23,12 @@ namespace System.Application.UI.Adapters
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class MyPreferenceButtonViewHolder : BaseReactiveViewHolder<TViewModel>
|
||||
internal sealed class LargePreferenceButtonViewHolder<TViewModel, TId> : BaseReactiveViewHolder<TViewModel>
|
||||
where TViewModel : RIdTitleIconViewModel<TId, ResIcon>
|
||||
{
|
||||
readonly layout_preference_large_button binding;
|
||||
|
||||
public MyPreferenceButtonViewHolder(View itemView) : base(itemView)
|
||||
public LargePreferenceButtonViewHolder(View itemView) : base(itemView)
|
||||
{
|
||||
binding = new(itemView);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Android.Views;
|
||||
using Binding;
|
||||
using ReactiveUI;
|
||||
using System.Application.UI.ViewModels;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace System.Application.UI.Adapters
|
||||
{
|
||||
internal sealed class SmallPreferenceButtonAdapter<TViewModel, TId> : BaseReactiveRecycleViewAdapter<SmallPreferenceButtonViewHolder<TViewModel, TId>, TViewModel>
|
||||
where TViewModel : RIdTitleViewModel<TId>
|
||||
{
|
||||
public SmallPreferenceButtonAdapter(ObservableCollection<TViewModel> collection) : base(collection)
|
||||
{
|
||||
}
|
||||
|
||||
public SmallPreferenceButtonAdapter(ReadOnlyObservableCollection<TViewModel> collection) : base(collection)
|
||||
{
|
||||
}
|
||||
|
||||
public override int? GetLayoutResource(int viewType)
|
||||
{
|
||||
return Resource.Layout.layout_preference_small_button;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class SmallPreferenceButtonViewHolder<TViewModel, TId> : BaseReactiveViewHolder<TViewModel>
|
||||
where TViewModel : RIdTitleViewModel<TId>
|
||||
{
|
||||
readonly layout_preference_small_button binding;
|
||||
|
||||
public SmallPreferenceButtonViewHolder(View itemView) : base(itemView)
|
||||
{
|
||||
binding = new(itemView);
|
||||
}
|
||||
|
||||
public override void OnBind()
|
||||
{
|
||||
base.OnBind();
|
||||
|
||||
ViewModel!.WhenAnyValue(x => x.Title).Subscribe(value =>
|
||||
{
|
||||
binding.tvTitle.Text = value;
|
||||
}).AddTo(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,10 @@ using Android.Views;
|
||||
using AndroidX.AppCompat.App;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.AndroidX;
|
||||
using System.Application.Mvvm;
|
||||
using System.Application.UI.ViewModels;
|
||||
using System.Collections.Generic;
|
||||
using System.Reactive.Disposables;
|
||||
using XEPlatform = Xamarin.Essentials.Platform;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
@@ -54,8 +57,12 @@ namespace System.Application.UI.Activities
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="BaseActivity"/>
|
||||
public abstract partial class BaseActivity<TViewBinding> : BaseActivity where TViewBinding : class
|
||||
public abstract partial class BaseActivity<TViewBinding> : BaseActivity, IDisposableHolder
|
||||
where TViewBinding : class
|
||||
{
|
||||
readonly CompositeDisposable disposables = new();
|
||||
ICollection<IDisposable> IDisposableHolder.CompositeDisposable => disposables;
|
||||
|
||||
protected override void OnCreate(Bundle? savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
@@ -65,6 +72,7 @@ namespace System.Application.UI.Activities
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
disposables.Dispose();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
@@ -81,9 +89,13 @@ namespace System.Application.UI.Activities
|
||||
/// </summary>
|
||||
/// <typeparam name="TViewBinding"></typeparam>
|
||||
/// <typeparam name="TViewModel"></typeparam>
|
||||
public abstract partial class BaseActivity<TViewBinding, TViewModel> : ReactiveAppCompatActivity<TViewModel>, IReadOnlyViewFor<TViewModel> where TViewBinding : class
|
||||
public abstract partial class BaseActivity<TViewBinding, TViewModel> : ReactiveAppCompatActivity<TViewModel>, IReadOnlyViewFor<TViewModel>, IDisposableHolder
|
||||
where TViewBinding : class
|
||||
where TViewModel : ViewModelBase
|
||||
{
|
||||
readonly CompositeDisposable disposables = new();
|
||||
ICollection<IDisposable> IDisposableHolder.CompositeDisposable => disposables;
|
||||
|
||||
protected override void OnCreate(Bundle? savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
@@ -113,6 +125,7 @@ namespace System.Application.UI.Activities
|
||||
ClearOnClickListener();
|
||||
if (navController != null) navController = null;
|
||||
base.OnDestroy();
|
||||
disposables.Dispose();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using Android.OS;
|
||||
using Android.Views;
|
||||
using ReactiveUI.AndroidX;
|
||||
using System.Application;
|
||||
using System.Application.Mvvm;
|
||||
using System.Application.UI.ViewModels;
|
||||
using System.Collections.Generic;
|
||||
using System.Reactive.Disposables;
|
||||
using Fragment = AndroidX.Fragment.App.Fragment;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
@@ -37,7 +38,7 @@ namespace System.Application.UI.Fragments
|
||||
public override void OnDestroyView()
|
||||
{
|
||||
ClearOnClickListener();
|
||||
base.OnDestroy();
|
||||
base.OnDestroyView();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,10 +65,13 @@ namespace System.Application.UI.Fragments
|
||||
/// </summary>
|
||||
/// <typeparam name="TViewBinding"></typeparam>
|
||||
/// <typeparam name="TViewModel"></typeparam>
|
||||
public abstract partial class BaseFragment<TViewBinding, TViewModel> : ReactiveFragment<TViewModel>, ReactiveUI.IReadOnlyViewFor<TViewModel>
|
||||
public abstract partial class BaseFragment<TViewBinding, TViewModel> : ReactiveFragment<TViewModel>, ReactiveUI.IReadOnlyViewFor<TViewModel>, IDisposableHolder
|
||||
where TViewBinding : class
|
||||
where TViewModel : ViewModelBase
|
||||
{
|
||||
readonly CompositeDisposable disposables = new();
|
||||
ICollection<IDisposable> IDisposableHolder.CompositeDisposable => disposables;
|
||||
|
||||
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||
{
|
||||
var view = BaseFragment.CreateView(LayoutResource, inflater, container);
|
||||
@@ -81,7 +85,8 @@ namespace System.Application.UI.Fragments
|
||||
public override void OnDestroyView()
|
||||
{
|
||||
ClearOnClickListener();
|
||||
base.OnDestroy();
|
||||
base.OnDestroyView();
|
||||
disposables.Dispose();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,19 @@
|
||||
using Android.Runtime;
|
||||
using Android.Text.Method;
|
||||
using Android.Views;
|
||||
using AndroidX.RecyclerView.Widget;
|
||||
using Binding;
|
||||
using ReactiveUI;
|
||||
using System.Application.Mvvm;
|
||||
using System.Application.UI.Activities;
|
||||
using System.Application.UI.Adapters;
|
||||
using System.Application.UI.Resx;
|
||||
using System.Application.UI.ViewModels;
|
||||
using System.Collections.Generic;
|
||||
using System.Reactive.Disposables;
|
||||
using static System.Application.UI.ViewModels.LoginOrRegisterPageViewModel;
|
||||
|
||||
namespace System.Application.UI.Fragments
|
||||
{
|
||||
[Register(JavaPackageConstants.Fragments + nameof(FastLoginOrRegisterFragment))]
|
||||
internal sealed class FastLoginOrRegisterFragment : BaseFragment<fragment_login_and_register_by_fast, LoginOrRegisterPageViewModel>, IDisposableHolder
|
||||
internal sealed class FastLoginOrRegisterFragment : BaseFragment<fragment_login_and_register_by_fast, LoginOrRegisterPageViewModel>
|
||||
{
|
||||
readonly CompositeDisposable disposables = new();
|
||||
ICollection<IDisposable> IDisposableHolder.CompositeDisposable => disposables;
|
||||
|
||||
protected override int? LayoutResource => Resource.Layout.fragment_login_and_register_by_fast;
|
||||
|
||||
public override void OnCreateView(View view)
|
||||
|
||||
@@ -3,23 +3,17 @@ using Android.Views;
|
||||
using AndroidX.RecyclerView.Widget;
|
||||
using Binding;
|
||||
using ReactiveUI;
|
||||
using System.Application.Mvvm;
|
||||
using System.Application.Services;
|
||||
using System.Application.UI.Activities;
|
||||
using System.Application.UI.Adapters;
|
||||
using System.Application.UI.ViewModels;
|
||||
using System.Collections.Generic;
|
||||
using System.Reactive.Disposables;
|
||||
using static System.Application.UI.ViewModels.MyPageViewModel;
|
||||
|
||||
namespace System.Application.UI.Fragments
|
||||
{
|
||||
[Register(JavaPackageConstants.Fragments + nameof(MyFragment))]
|
||||
internal sealed class MyFragment : BaseFragment<fragment_my, MyPageViewModel>, IDisposableHolder
|
||||
internal sealed class MyFragment : BaseFragment<fragment_my, MyPageViewModel>
|
||||
{
|
||||
readonly CompositeDisposable disposables = new();
|
||||
ICollection<IDisposable> IDisposableHolder.CompositeDisposable => disposables;
|
||||
|
||||
protected override int? LayoutResource => Resource.Layout.fragment_my;
|
||||
|
||||
public override void OnCreateView(View view)
|
||||
@@ -34,7 +28,7 @@ namespace System.Application.UI.Fragments
|
||||
|
||||
SetOnClickListener(binding!.layoutUser);
|
||||
|
||||
var adapter = new MyPreferenceButtonAdapter(ViewModel!);
|
||||
var adapter = new LargePreferenceButtonAdapter<PreferenceButtonViewModel, PreferenceButton>(ViewModel!.PreferenceButtons);
|
||||
adapter.ItemClick += (_, e) =>
|
||||
{
|
||||
if (e.Current.Authentication && !UserService.Current.IsAuthenticated)
|
||||
@@ -60,12 +54,6 @@ namespace System.Application.UI.Fragments
|
||||
binding.rvPreferenceButtons.SetAdapter(adapter);
|
||||
}
|
||||
|
||||
public override void OnDestroyView()
|
||||
{
|
||||
base.OnDestroyView();
|
||||
disposables.Dispose();
|
||||
}
|
||||
|
||||
protected override bool OnClick(View view)
|
||||
{
|
||||
if (view.Id == Resource.Id.layoutUser)
|
||||
|
||||
@@ -5,22 +5,16 @@ using Android.Views.InputMethods;
|
||||
using Android.Widget;
|
||||
using Binding;
|
||||
using ReactiveUI;
|
||||
using System.Application.Mvvm;
|
||||
using System.Application.Services;
|
||||
using System.Application.UI.Activities;
|
||||
using System.Application.UI.Resx;
|
||||
using System.Application.UI.ViewModels;
|
||||
using System.Collections.Generic;
|
||||
using System.Reactive.Disposables;
|
||||
|
||||
namespace System.Application.UI.Fragments
|
||||
{
|
||||
[Register(JavaPackageConstants.Fragments + nameof(PhoneNumberLoginOrRegisterFragment))]
|
||||
internal sealed class PhoneNumberLoginOrRegisterFragment : BaseFragment<fragment_login_and_register_by_phone_number, LoginOrRegisterPageViewModel>, IDisposableHolder, TextView.IOnEditorActionListener
|
||||
internal sealed class PhoneNumberLoginOrRegisterFragment : BaseFragment<fragment_login_and_register_by_phone_number, LoginOrRegisterPageViewModel>, TextView.IOnEditorActionListener
|
||||
{
|
||||
readonly CompositeDisposable disposables = new();
|
||||
ICollection<IDisposable> IDisposableHolder.CompositeDisposable => disposables;
|
||||
|
||||
protected override int? LayoutResource => Resource.Layout.fragment_login_and_register_by_phone_number;
|
||||
|
||||
public override void OnCreateView(View view)
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
using Android.App;
|
||||
using Android.Runtime;
|
||||
using Android.Text;
|
||||
using System.Application.Security;
|
||||
using System.Application.UI.ViewModels;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Xamarin.Essentials;
|
||||
using _ThisAssembly = System.Properties.ThisAssembly;
|
||||
using AndroidApplication = Android.App.Application;
|
||||
using AppTheme = System.Application.Models.AppTheme;
|
||||
using JObject = Java.Lang.Object;
|
||||
using XEFileProvider = Xamarin.Essentials.FileProvider;
|
||||
using XEPlatform = Xamarin.Essentials.Platform;
|
||||
using XEVersionTracking = Xamarin.Essentials.VersionTracking;
|
||||
@@ -71,5 +76,27 @@ namespace System.Application.UI
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string GetTheme()
|
||||
{
|
||||
if (DarkModeUtil.IsDarkMode(Context))
|
||||
{
|
||||
return AppTheme.Dark.ToString2();
|
||||
}
|
||||
return AppTheme.Light.ToString2();
|
||||
}
|
||||
|
||||
public static SpannableString CreateSpannableString(Func<List<(JObject what, int start, int end, SpanTypes flags)>, StringBuilder> func)
|
||||
{
|
||||
var linkTextIndexs = new List<(JObject what, int start, int end, SpanTypes flags)>();
|
||||
var sb = func(linkTextIndexs);
|
||||
var str = sb.ToString();
|
||||
SpannableString spannable = new(str);
|
||||
foreach (var (what, start, end, flags) in linkTextIndexs)
|
||||
{
|
||||
spannable.SetSpan(what, start, end, flags);
|
||||
}
|
||||
return spannable;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,12 @@
|
||||
<LinkBase>Services\Implementation</LinkBase>
|
||||
</Compile>
|
||||
<Compile Include="..\ST.Client.Desktop\ServiceCollectionExtensions.TryAddFontManager.cs"/>
|
||||
<Compile Include="..\ST.Client.Desktop\UI\ViewModels\Pages\About\AboutPageViewModel.shared.cs">
|
||||
<Link>UI\ViewModels\AboutPageViewModel.shared.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ST.Client.Desktop\Models\Enum\AppTheme.cs">
|
||||
<LinkBase>Models\Enum</LinkBase>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
using ReactiveUI;
|
||||
using System.Application.Mvvm;
|
||||
using System.Application.UI.Resx;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using Xamarin.Essentials;
|
||||
|
||||
namespace System.Application.UI.ViewModels
|
||||
{
|
||||
partial class AboutPageViewModel : ViewModelBase
|
||||
{
|
||||
public string Title => TitleName;
|
||||
|
||||
ObservableCollection<PreferenceButtonViewModel> preferenceButtons;
|
||||
public ObservableCollection<PreferenceButtonViewModel> PreferenceButtons
|
||||
{
|
||||
get => preferenceButtons;
|
||||
set => this.RaiseAndSetIfChanged(ref preferenceButtons, value);
|
||||
}
|
||||
|
||||
public enum PreferenceButton
|
||||
{
|
||||
检查更新 = 1,
|
||||
更新日志,
|
||||
常见问题疑难解答,
|
||||
开放源代码许可,
|
||||
源码仓库,
|
||||
产品官网,
|
||||
联系我们,
|
||||
Bug反馈,
|
||||
账号注销,
|
||||
}
|
||||
|
||||
public sealed class PreferenceButtonViewModel : RIdTitleViewModel<PreferenceButton>
|
||||
{
|
||||
PreferenceButtonViewModel()
|
||||
{
|
||||
}
|
||||
|
||||
protected override string GetTitleById(PreferenceButton id)
|
||||
{
|
||||
var title = id switch
|
||||
{
|
||||
PreferenceButton.检查更新 => AppResources.CheckUpdate,
|
||||
PreferenceButton.更新日志 => AppResources.About_UpdateLog,
|
||||
PreferenceButton.常见问题疑难解答 => AppResources.About_FAQ,
|
||||
PreferenceButton.开放源代码许可 => AppResources.About_OpenSource,
|
||||
PreferenceButton.源码仓库 => AppResources.SourceRepository,
|
||||
PreferenceButton.产品官网 => AppResources.ProductOfficialWebsite,
|
||||
PreferenceButton.联系我们 => AppResources.About_Contactus,
|
||||
PreferenceButton.Bug反馈 => AppResources.BugFeedback,
|
||||
PreferenceButton.账号注销 => AppResources.DelAccount,
|
||||
_ => string.Empty,
|
||||
};
|
||||
return title;
|
||||
}
|
||||
|
||||
public static void RemoveAuthorized(ICollection<PreferenceButtonViewModel> collection, IDisposableHolder vm)
|
||||
{
|
||||
var removeArray = collection.Where(x => x.Id == PreferenceButton.账号注销).ToArray();
|
||||
Array.ForEach(removeArray, x =>
|
||||
{
|
||||
collection.Remove(x);
|
||||
x.OnUnbind(vm);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建实例
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="vm"></param>
|
||||
/// <returns></returns>
|
||||
public static PreferenceButtonViewModel Create(PreferenceButton id, IDisposableHolder vm)
|
||||
{
|
||||
PreferenceButtonViewModel r = new() { Id = id, };
|
||||
r.OnBind(vm);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
public const string GitHub = "GitHub";
|
||||
public const string Gitee = "Gitee";
|
||||
public static readonly string[] SourceRepositories = new[] { GitHub, Gitee };
|
||||
public const string Title_0 = "Steam++ Tools ";
|
||||
public const string Title_1 = "2.0";
|
||||
public const string Developers_0 = "Developers: ";
|
||||
public const string Separator = " - ";
|
||||
public const string Separator2 = " | ";
|
||||
public const string At_Rmbadmin = "@软妹币玩家";
|
||||
public const string At_AigioL = "@AigioL";
|
||||
public const string At_Mossimos = "@Mossimos";
|
||||
public const string At_Cliencer = "@Cliencer克总";
|
||||
public const string BusinessCooperationContact_0 = "Business Cooperation Contact: ";
|
||||
public const string OpenSourceLicensed_0 = "This open source software is licensed with ";
|
||||
public const string OpenSourceLicensed_1 = "GPLv3 License";
|
||||
const string _ThemeAccentBrushKey = "#FF0078D7";
|
||||
public static readonly Color ThemeAccentBrushKey = ColorConverters.FromHex(_ThemeAccentBrushKey);
|
||||
}
|
||||
}
|
||||
@@ -61,4 +61,11 @@ namespace System.Application.UI.ViewModels
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class RIdTitleViewModel<TId> : RIdTitleIconViewModel<TId, byte>
|
||||
{
|
||||
protected sealed override bool IgnoreIcon => true;
|
||||
|
||||
protected sealed override byte GetIconById(TId? id) => default;
|
||||
}
|
||||
}
|
||||
@@ -600,7 +600,7 @@ namespace System.Application.Services.Implementation
|
||||
/// <summary>
|
||||
/// 在应用商店中打开
|
||||
/// </summary>
|
||||
protected virtual void OpenInAppStore() => BrowserOpen("https://steampp.net/");
|
||||
protected virtual void OpenInAppStore() => BrowserOpen(UrlConstants.OfficialWebsite);
|
||||
|
||||
void StartUpdate()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
namespace System.Application
|
||||
{
|
||||
public static class UrlConstants
|
||||
{
|
||||
public const string GitHub_User_Rmbadmin = "https://github.com/rmbadmin";
|
||||
public const string GitHub_User_AigioL = "https://github.com/AigioL";
|
||||
public const string GitHub_User_Mossimos = "https://github.com/Mossimos";
|
||||
|
||||
public const string BILI_User_Cliencer = "https://space.bilibili.com/30031316";
|
||||
|
||||
public const string OfficialWebsite = "https://steampp.net";
|
||||
public const string OfficialWebsite_Privacy = "https://steampp.net/privacy";
|
||||
public const string OfficialWebsite_Agreement = "https://steampp.net/agreement";
|
||||
public const string OfficialWebsite_Contact = "https://steampp.net/contact";
|
||||
public const string OfficialWebsite_Faq = "https://steampp.net/faq";
|
||||
public const string OfficialWebsite_Box_Changelog_ = "https://steampp.net/changelogbox?theme={0}&language={1}";
|
||||
public const string OfficialWebsite_Box_Faq_ = "https://steampp.net/faqbox?theme={0}&language={1}";
|
||||
public const string OfficialWebsite_Box_Privacy = "https://steampp.net/PrivacyBox";
|
||||
public const string OfficialWebsite_Box_Agreement = "https://steampp.net/AgreementBox";
|
||||
|
||||
public const string GitHub_Repository = "https://github.com/SteamTools-Team/SteamTools";
|
||||
public const string Gitee_Repository = "https://gitee.com/rmbgame/SteamTools";
|
||||
|
||||
public const string GitHub_Issues = "https://github.com/SteamTools-Team/SteamTools";
|
||||
public const string Gitee_Issues = "https://gitee.com/rmbgame/SteamTools";
|
||||
|
||||
public const string License_GPLv3 = "https://www.gnu.org/licenses/gpl-3.0.html";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user