Compare commits

...
27 Commits
Author SHA1 Message Date
Aigio Liu 686171f73c android fast login ui 2021-06-12 17:20:34 +08:00
mossimo d597f992e4 Merge branch 'develop' of https://github.com/SteamTools-Team/SteamTools into develop 2021-06-12 05:04:00 +08:00
mossimo 174ec43551 fix macos install cer 2021-06-12 05:03:34 +08:00
Aigio Liu 90f1aae4bd Android Native UI 2021-06-11 22:30:29 +08:00
Aigio Liu 99270e730e fix 2021-06-11 16:07:25 +08:00
Aigio Liu 080ed55860 fix 2021-06-11 16:07:24 +08:00
Aigio Liu ea0cd59763 AttachDevTools2 2021-06-11 15:40:17 +08:00
Aigio Liu a8780568d6 AttachDevTools2 2021-06-11 15:40:13 +08:00
rmbgame 9b9de32f3c 调整深色和浅色模式的视觉效果
添加asf功能 50%
2021-06-11 05:20:24 +08:00
rmbgame 288f947730 重写webview3 2021-06-10 21:01:39 +08:00
rmbgame 3c65d716b1 save 2021-06-10 21:01:39 +08:00
Aigio Liu ebef7ede81 fix 2021-06-10 18:48:43 +08:00
mossimo be5bb78773 Merge branch 'develop' of https://github.com/SteamTools-Team/SteamTools into develop 2021-06-10 18:34:52 +08:00
Aigio Liu db636e894f fix 2021-06-10 18:33:32 +08:00
mossimo 808f0c1b9d host edit 2021-06-10 18:09:04 +08:00
Aigio Liu 20af863f4e macOS AppLogo 2021-06-10 00:58:49 +08:00
Aigio Liu 15ddeddf0d fix 2021-06-10 00:46:30 +08:00
Aigio Liu 3eff9a45c6 IHttpService.GetImageAsync use Polly & AppLogo Update SVG & Mobile UI MyPage 2021-06-10 00:42:53 +08:00
Aigio Liu c3fbeb3c4a fix 2021-06-08 17:08:41 +08:00
Mossimo efc3cf6797 NoSandBox fix macos 2021-06-08 17:02:39 +08:00
Aigio Liu b78ac16667 增量更新 v2 2021-06-08 14:10:31 +08:00
mossimo a492968401 1 2021-06-06 18:16:50 +08:00
mossimo b4f220e683 NoSteamRunTips 2021-06-06 18:16:06 +08:00
Aigio Liu b356d80c3e fix 2021-06-06 12:11:12 +08:00
Aigio Liu 049072ea5d v2.4.1 2021-06-06 10:33:05 +08:00
rmbgame 9c13426781 fix more screen 2021-06-06 01:48:44 +08:00
rmbgame 67ec02af0c fix taskbar high dpi error 2021-06-06 01:42:11 +08:00
196 changed files with 2512 additions and 394 deletions
+14 -13
View File
@@ -10,22 +10,23 @@
10. 改进 缓存获取加速项目数据,避免失败时无数据
11. 修复 手动检查更新时有概率出现两个新版本窗口
12. 改进 未使用社区加速时退出程序不再清理 hosts 文件
13. 修复 托盘位置因 DPI 缩放导致位置不正确
| File | Checksum (SHA256) |
| ---- | ---- |
| Steam++_win_x64_v2.4.0.7z | SHA256 |
| Steam++_win_x64_v2.4.0.exe | SHA256 |
| Steam++_win_x64_v2.4.0.msix | SHA256 |
| Steam++_win_arm64_v2.4.0.7z | SHA256 |
| Steam++_win_arm64_v2.4.0.exe | SHA256 |
| Steam++_win_arm64_v2.4.0.msix | SHA256 |
| Steam++_linux_x64_v2.4.0.7z | SHA256 |
| Steam++_linux_x64_v2.4.0.deb | SHA256 |
| Steam++_macos_x64_v2.4.0.dmg | SHA256 |
| Steam++_macos_arm64_v2.4.0.dmg | SHA256 |
| Steam++_android_v2.4.0.apk | SHA256 |
| Steam++_android_arm64_v2.4.0.apk | SHA256 |
| Steam++_android_arm_v2.4.0.apk | SHA256 |
| Steam++_win_x64_v2.4.1.7z | SHA256 |
| Steam++_win_x64_v2.4.1.exe | SHA256 |
| Steam++_win_x64_v2.4.1.msix | SHA256 |
| Steam++_win_arm64_v2.4.1.7z | SHA256 |
| Steam++_win_arm64_v2.4.1.exe | SHA256 |
| Steam++_win_arm64_v2.4.1.msix | SHA256 |
| Steam++_linux_x64_v2.4.1.7z | SHA256 |
| Steam++_linux_x64_v2.4.1.deb | SHA256 |
| Steam++_macos_x64_v2.4.1.dmg | SHA256 |
| Steam++_macos_arm64_v2.4.1.dmg | SHA256 |
| Steam++_android_v2.4.1.apk | SHA256 |
| Steam++_android_arm64_v2.4.1.apk | SHA256 |
| Steam++_android_arm_v2.4.1.apk | SHA256 |
***
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

+5
View File
@@ -0,0 +1,5 @@
<svg id="abee0869-1b5a-43b0-ad2d-68b9c06591d9" data-name="steampp" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 151.22 160.98"><defs><style>.bee71911-c304-409c-b1a3-5c617b033d97{fill:#fff;}.e33bb62c-3cd8-43d8-b337-a8f898048f78{fill:url(#fe73b66f-3888-4385-9976-c891a0dc3db5);}.f52f40e5-9b40-42f3-ad92-92d8d45039d2{fill:url(#f2f22e4f-2cb9-40ee-9151-f69f4c5c4c7f);}</style><linearGradient id="fe73b66f-3888-4385-9976-c891a0dc3db5" x1="53.34" y1="148.33" x2="142.57" y2="59.1" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#1890de"/><stop offset="0.07" stop-color="#2195e1"/><stop offset="0.31" stop-color="#3ea3ea"/><stop offset="0.54" stop-color="#53adf1"/><stop offset="0.78" stop-color="#60b3f5"/><stop offset="1" stop-color="#64b5f6"/></linearGradient><linearGradient id="f2f22e4f-2cb9-40ee-9151-f69f4c5c4c7f" x1="162.65" y1="122.92" x2="85.29" y2="45.56" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#81c784"/><stop offset="0.1" stop-color="#6cb46f"/><stop offset="0.21" stop-color="#5ba55f"/><stop offset="0.34" stop-color="#519c55"/><stop offset="0.5" stop-color="#4e9952"/><stop offset="0.66" stop-color="#519c55"/><stop offset="0.79" stop-color="#5ba55f"/><stop offset="0.9" stop-color="#6cb46f"/><stop offset="1" stop-color="#81c784"/></linearGradient></defs>
<path class="e33bb62c-3cd8-43d8-b337-a8f898048f78" d="M121.28,180.51c-3.4,0-6.79,0-10.19,0a6.18,6.18,0,0,1-5.51-4.24c-1.45-5.21-2.87-10.43-4.4-15.61a2.41,2.41,0,0,0-1.43-1.38,77.05,77.05,0,0,1-15.07-6.87,20.55,20.55,0,0,1-2.74-1.69c-1-.8-1.7-.51-2.51.14-3.13,2.47-6.33,4.85-9.36,7.42A5,5,0,0,1,63,158c-2.76-2.7-5.35-5.57-8-8.39-3.37-3.56-6.74-7.12-10.07-10.72a5.91,5.91,0,0,1-.54-7.46c2.48-3.46,4.71-7.09,7.09-10.63a1.41,1.41,0,0,0,0-1.73,83.14,83.14,0,0,1-8.36-18.84,1.73,1.73,0,0,0-1-1q-6.65-1.92-13.33-3.71A5.63,5.63,0,0,1,24.42,90q0-10.2,0-20.4c0-2.64,1.36-4.09,4-4.2,4-.18,8.06-.3,12.1-.41a1.39,1.39,0,0,0,1.56-1.21,44.26,44.26,0,0,1,5.85-12.88,1.57,1.57,0,0,0-.08-2.12c-2.36-3.15-4.66-6.35-7-9.55a3.3,3.3,0,0,1,.77-4.92c4.07-2.86,8.21-5.65,12.23-8.59a4.94,4.94,0,0,1,5.68.09c3,2.3,6.11,4.49,9.08,6.84a2.64,2.64,0,0,0,2.74.5,47.44,47.44,0,0,1,12.43-2.3c.65,0,.94-.25,1-.89.08-.87.26-1.73.34-2.6.18-1.95.3-3.9.5-5.85a2.12,2.12,0,0,1,2.51-1.85,53.28,53.28,0,0,1,5.29.94c3.74.77,7.48,1.57,11.23,2.35a6.31,6.31,0,0,1,5.06,4.53c.84,2.57,1.74,5.13,2.77,7.63a4.14,4.14,0,0,0,1.72,1.64c1,.58,2.11.94,3.15,1.43a3.09,3.09,0,0,1,.67.59,2.63,2.63,0,0,1-.87.09,43.19,43.19,0,0,0-12-1.43c-8.59.2-16.54,2.49-23.3,8A34.77,34.77,0,0,0,71.26,60.66c-2.73,7.4-2.92,15-2,22.67a54.81,54.81,0,0,0,5.41,17.74c1.55,3.14,3.42,6.12,5.13,9.18.45.81.78.92,1.44.13,1.2-1.44,2.51-2.79,3.79-4.16a3.05,3.05,0,0,0,.89-2.37c-.3-6.14-.32-12.31-.94-18.43a6,6,0,0,1,1.88-5.23c4.11-4.46,8.16-9,12.2-13.48a3.3,3.3,0,0,1,2.57-1.18c5.19-.19,10.37-.49,15.56-.71,1.54-.07,2.25.33,2.46,1.69a3.24,3.24,0,0,1-.65,2.35c-4,4.49-8,8.9-12,13.31a1.39,1.39,0,0,0-.33,1.79c1.46,3.18,2.83,6.4,4.28,9.59a1.75,1.75,0,0,0,.88.84c3.38,1.18,6.79,2.31,10.18,3.47.75.26,1.18-.11,1.63-.62q5.73-6.36,11.48-12.68c.3-.32.55-.79.92-.92a4.94,4.94,0,0,1,2.31-.47,2,2,0,0,1,1.58,2.15c.17,3.23.31,6.46.49,9.69.12,2.11.33,4.22.38,6.33a2.87,2.87,0,0,1-.63,1.82q-7,7.84-14.14,15.58a2.57,2.57,0,0,1-1.21.64,7.13,7.13,0,0,1-1.54.17c-6.5.32-13,.63-19.5,1a2.29,2.29,0,0,0-1.43.66c-1.81,1.9-3.55,3.87-5.34,5.8-.7.75-.56,1.24.24,1.83a66.14,66.14,0,0,0,18.27,9.79,50.54,50.54,0,0,0,16.8,2.79c8.41-.07,16.16-2.26,22.88-7.5a34.86,34.86,0,0,0,11-15.07c.24-.6.56-1.15.85-1.72a8.81,8.81,0,0,1,.12,2c-.46,2.87-1,5.71-1.48,8.58a2,2,0,0,0,.37,1.4c2.55,3.37,5.12,6.73,7.74,10,1.93,2.45,2.53,4.88.8,7.78-2.64,4.4-5.06,8.94-7.63,13.38-1.26,2.17-3.18,2.53-5.25,1q-4.09-3-8.11-6.13c-3.2-2.49-3.16-2.49-6.44-.16a39.15,39.15,0,0,1-10.69,5.22,1.43,1.43,0,0,0-1.19,1.7c.14,4.67.12,9.35.37,14a4.3,4.3,0,0,1-4.55,4.62C127.85,180.37,124.56,180.51,121.28,180.51Z" transform="translate(-24.41 -19.59)"/>
<path class="f52f40e5-9b40-42f3-ad92-92d8d45039d2" d="M105.9,39.94a52.29,52.29,0,0,1,18.17,3.85,64.5,64.5,0,0,1,17.47,10.47,67.77,67.77,0,0,1,11,11.42,64.77,64.77,0,0,1,10.06,18.26,68.43,68.43,0,0,1,2.78,9.75,47.72,47.72,0,0,1,.23,16.69,35.77,35.77,0,0,1-7.11,16.37A30.1,30.1,0,0,1,143.14,137a42.13,42.13,0,0,1-12.28,1.72c-.16,0-.32,0-.47,0a1.78,1.78,0,0,1,.45-.28c1.95-.66,3.94-1.23,5.87-2A25.79,25.79,0,0,0,149.25,126a31.24,31.24,0,0,0,4.45-11.76,39.49,39.49,0,0,0,.29-11.78,49.28,49.28,0,0,0-3.15-12.35A58.94,58.94,0,0,0,140.6,72.89a61.58,61.58,0,0,0-14-12.39,53,53,0,0,0-15.64-6.79c-9-2.18-17.72-1.64-25.83,3.11a26.22,26.22,0,0,0-11.19,13C73.09,71.84,72.6,74,72,76c0,.17-.14.34-.2.51a1.55,1.55,0,0,1-.23-.6c.07-1.92.07-3.85.28-5.75A36.07,36.07,0,0,1,77,55a29.6,29.6,0,0,1,9.92-9.86A30.76,30.76,0,0,1,98.22,40.9C100.76,40.5,103.34,40.26,105.9,39.94Z" transform="translate(-24.41 -19.59)"/></svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

@@ -2,7 +2,7 @@ namespace System.Properties
{
static partial class ThisAssembly
{
public const string Version = "2.4.0";
public const string Version = "2.4.1";
public const string InfoVersion = Version /*+ "-beta"*/;
}
@@ -1,4 +1,4 @@
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Configuration;
@@ -39,6 +39,12 @@ namespace System.Application.UI
static IEnumerable<Process> GetCurrentAllProcess()
{
var current = Process.GetCurrentProcess();
#if DEBUG
if (string.Equals("dotnet", Path.GetFileNameWithoutExtension(current.MainModule?.FileName), StringComparison.OrdinalIgnoreCase))
{
return Array.Empty<Process>();
}
#endif
var currentMainModule = current.TryGetMainModule();
var query = from p in Process.GetProcessesByName(current.ProcessName)
let pMainModule = p.TryGetMainModule()
@@ -29,7 +29,8 @@ namespace System.Application.UI
// https://docs.microsoft.com/zh-cn/archive/msdn-magazine/2019/march/net-parse-the-command-line-with-system-commandline
var rootCommand = new RootCommand("命令行工具(Command Line Tools/CLT)");
void MainHandler()
void MainHandler() => MainHandler_(null);
void MainHandler_(Action? onInitStartuped)
{
#if StartupTrace
StartupTrace.Restart("ProcessCheck");
@@ -38,6 +39,7 @@ namespace System.Application.UI
#if StartupTrace
StartupTrace.Restart("Startup.Init");
#endif
onInitStartuped?.Invoke();
if (IsMainProcess)
{
var isInitAppInstanceReset = false;
@@ -91,11 +93,12 @@ namespace System.Application.UI
StartupTrace.Restart("InitAvaloniaApp");
#endif
}
void MainHandlerByCLT()
void MainHandlerByCLT() => MainHandlerByCLT_(null);
void MainHandlerByCLT_(Action? onInitStartuped)
{
IsMainProcess = true;
IsCLTProcess = false;
MainHandler();
MainHandler_(onInitStartuped);
}
#if DEBUG
@@ -122,8 +125,10 @@ namespace System.Application.UI
devtools.Handler = CommandHandler.Create(() =>
{
AppHelper.EnableDevtools = true;
AppHelper.LoggerMinLevel = LogLevel.Debug;
MainHandlerByCLT();
MainHandlerByCLT_(onInitStartuped: () =>
{
AppHelper.LoggerMinLevel = LogLevel.Debug;
});
});
rootCommand.AddCommand(devtools);
@@ -13,7 +13,7 @@ namespace System.Application.UI.Views
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
#if StartupTrace
StartupTrace.Restart("MainWindow.ctor");
Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 B

After

Width:  |  Height:  |  Size: 946 B

@@ -154,6 +154,7 @@ navigator.__proto__ = newProto;
AcceptLanguageList = CultureInfo.CurrentUICulture.GetAcceptLanguage(),
MultiThreadedMessageLoop = !externalMessagePump,
ExternalMessagePump = externalMessagePump,
NoSandbox = true,
WindowlessRenderingEnabled = true,
// https://magpcss.org/ceforum/viewtopic.php?t=14648#p32857
LogSeverity = ThisAssembly.Debuggable ? CefLogSeverity.Error : CefLogSeverity.Disable,
@@ -172,6 +173,7 @@ navigator.__proto__ = newProto;
return;
}
settings.ResourcesDirPath = resourcesDirPath;
settings.NoSandbox = true;
}
else
{
@@ -181,7 +183,7 @@ navigator.__proto__ = newProto;
AppHelper.Initialized += () =>
{
if (PlatformInfo.IsMacOS || Environment.GetCommandLineArgs().Contains("--external-message-pump"))
if (Instance.UsesExternalMessageLoop)
{
messagePump = new Timer(_ => Dispatcher.UIThread.Post(CefApi.DoMessageLoopWork), null, messagePumpDelay, messagePumpDelay);
}
@@ -2,9 +2,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard">
<Style.Resources>
<Color x:Key="ThemeColorKey">#FF222222</Color>
<Color x:Key="ThemeColorKey">#66000000</Color>
<SolidColorBrush x:Key="ThemeBrushKey"
Color="#FF222222" />
Color="#66000000" />
<Color x:Key="BackgroundColorKey">#FF000000</Color>
<SolidColorBrush x:Key="BackgroundBrushKey"
@@ -1,121 +1,121 @@
<Style xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard">
<Style.Resources>
<Color x:Key="ThemeColorKey">#FFFCFCFC</Color>
<SolidColorBrush x:Key="ThemeBrushKey"
Color="#FFFCFCFC" />
<Style.Resources>
<Color x:Key="ThemeColorKey">#88FCFCFC</Color>
<SolidColorBrush x:Key="ThemeBrushKey"
Color="#88FCFCFC" />
<Color x:Key="BackgroundColorKey">#FFD7D7DC</Color>
<SolidColorBrush x:Key="BackgroundBrushKey"
Color="#FFD7D7DC" />
<Color x:Key="BackgroundColorKey">#FFD7D7DC</Color>
<SolidColorBrush x:Key="BackgroundBrushKey"
Color="#FFD7D7DC" />
<Color x:Key="BorderColorKey">#FFB9B9C0</Color>
<SolidColorBrush x:Key="BorderBrushKey"
Color="#FFB9B9C0" />
<Color x:Key="BorderColorKey">#FFB9B9C0</Color>
<SolidColorBrush x:Key="BorderBrushKey"
Color="#FFB9B9C0" />
<Color x:Key="ForegroundColorKey">#FF363636</Color>
<SolidColorBrush x:Key="ForegroundBrushKey"
Color="#FF363636" />
<Color x:Key="ForegroundColorKey">#FF363636</Color>
<SolidColorBrush x:Key="ForegroundBrushKey"
Color="#FF363636" />
<Color x:Key="SemiactiveBackgroundColorKey">#FFF5F5F8</Color>
<SolidColorBrush x:Key="SemiactiveBackgroundBrushKey"
Color="#FFF5F5F8" />
<Color x:Key="SemiactiveBackgroundColorKey">#FFF5F5F8</Color>
<SolidColorBrush x:Key="SemiactiveBackgroundBrushKey"
Color="#FFF5F5F8" />
<Color x:Key="SemiactiveBorderColorKey">#FFB9B9C0</Color>
<SolidColorBrush x:Key="SemiactiveBorderBrushKey"
Color="#FFB9B9C0" />
<Color x:Key="SemiactiveBorderColorKey">#FFB9B9C0</Color>
<SolidColorBrush x:Key="SemiactiveBorderBrushKey"
Color="#FFB9B9C0" />
<Color x:Key="SemiActiveForegroundColorKey">#FF101010</Color>
<SolidColorBrush x:Key="SemiActiveForegroundBrushKey"
Color="#FF101010" />
<Color x:Key="SemiActiveForegroundColorKey">#FF101010</Color>
<SolidColorBrush x:Key="SemiActiveForegroundBrushKey"
Color="#FF101010" />
<Color x:Key="ActiveBackgroundColorKey">#FFFFFFFF</Color>
<SolidColorBrush x:Key="ActiveBackgroundBrushKey"
Color="#FFFFFFFF" />
<Color x:Key="ActiveBackgroundColorKey">#FFFFFFFF</Color>
<SolidColorBrush x:Key="ActiveBackgroundBrushKey"
Color="#FFFFFFFF" />
<Color x:Key="ActiveBorderColorKey">#FFB9B9C0</Color>
<SolidColorBrush x:Key="ActiveBorderBrushKey"
Color="#FFB9B9C0" />
<Color x:Key="ActiveBorderColorKey">#FFB9B9C0</Color>
<SolidColorBrush x:Key="ActiveBorderBrushKey"
Color="#FFB9B9C0" />
<Color x:Key="ActiveForegroundColorKey">#FF000000</Color>
<SolidColorBrush x:Key="ActiveForegroundBrushKey"
Color="#FF000000" />
<Color x:Key="ActiveForegroundColorKey">#FF000000</Color>
<SolidColorBrush x:Key="ActiveForegroundBrushKey"
Color="#FF000000" />
<Color x:Key="InactiveBackgroundColorKey">#FFEFEFF2</Color>
<SolidColorBrush x:Key="InactiveBackgroundBrushKey"
Color="#FFEFEFF2" />
<Color x:Key="InactiveBackgroundColorKey">#FFEFEFF2</Color>
<SolidColorBrush x:Key="InactiveBackgroundBrushKey"
Color="#FFEFEFF2" />
<Color x:Key="InactiveBorderColorKey">#FFD7D7DE</Color>
<SolidColorBrush x:Key="InactiveBorderBrushKey"
Color="#FFD7D7DE" />
<Color x:Key="InactiveBorderColorKey">#FFD7D7DE</Color>
<SolidColorBrush x:Key="InactiveBorderBrushKey"
Color="#FFD7D7DE" />
<Color x:Key="InactiveForegroundColorKey">#FF808080</Color>
<SolidColorBrush x:Key="InactiveForegroundBrushKey"
Color="#FF666666" />
<Color x:Key="InactiveForegroundColorKey">#FF808080</Color>
<SolidColorBrush x:Key="InactiveForegroundBrushKey"
Color="#FF666666" />
<Color x:Key="HighlightBackgroundColorKey">#FFA5A5AC</Color>
<SolidColorBrush x:Key="HighlightBackgroundBrushKey"
Color="#FFA5A5AC" />
<Color x:Key="HighlightBackgroundColorKey">#FFA5A5AC</Color>
<SolidColorBrush x:Key="HighlightBackgroundBrushKey"
Color="#FFA5A5AC" />
<Color x:Key="HighlightBorderColorKey">#FFA5A5AC</Color>
<SolidColorBrush x:Key="HighlightBorderBrushKey"
Color="#FFA5A5AC" />
<Color x:Key="HighlightBorderColorKey">#FFA5A5AC</Color>
<SolidColorBrush x:Key="HighlightBorderBrushKey"
Color="#FFA5A5AC" />
<Color x:Key="HighlightForegroundColorKey">#FF000000</Color>
<SolidColorBrush x:Key="HighlightForegroundBrushKey"
Color="#FF000000" />
<Color x:Key="HighlightForegroundColorKey">#FF000000</Color>
<SolidColorBrush x:Key="HighlightForegroundBrushKey"
Color="#FF000000" />
<Color x:Key="Highlight2BackgroundColorKey">#FF696970</Color>
<SolidColorBrush x:Key="Highlight2BackgroundBrushKey"
Color="#FF696970" />
<Color x:Key="Highlight2BackgroundColorKey">#FF696970</Color>
<SolidColorBrush x:Key="Highlight2BackgroundBrushKey"
Color="#FF696970" />
<Color x:Key="Highlight2BorderColorKey">#FF696970</Color>
<SolidColorBrush x:Key="Highlight2BorderBrushKey"
Color="#FF696970" />
<Color x:Key="Highlight2BorderColorKey">#FF696970</Color>
<SolidColorBrush x:Key="Highlight2BorderBrushKey"
Color="#FF696970" />
<Color x:Key="Highlight2ForegroundColorKey">#FFFFFFFF</Color>
<SolidColorBrush x:Key="Highlight2ForegroundBrushKey"
Color="#FFFFFFFF" />
<Color x:Key="Highlight2ForegroundColorKey">#FFFFFFFF</Color>
<SolidColorBrush x:Key="Highlight2ForegroundBrushKey"
Color="#FFFFFFFF" />
<Color x:Key="Highlight3BackgroundColorKey">#FF4B4B52</Color>
<SolidColorBrush x:Key="Highlight3BackgroundBrushKey"
Color="#FF4B4B52" />
<Color x:Key="Highlight3BackgroundColorKey">#FF4B4B52</Color>
<SolidColorBrush x:Key="Highlight3BackgroundBrushKey"
Color="#FF4B4B52" />
<Color x:Key="Highlight3BorderColorKey">#FF4B4B52</Color>
<SolidColorBrush x:Key="Highlight3BorderBrushKey"
Color="#FF4B4B52" />
<Color x:Key="Highlight3BorderColorKey">#FF4B4B52</Color>
<SolidColorBrush x:Key="Highlight3BorderBrushKey"
Color="#FF4B4B52" />
<Color x:Key="Highlight3ForegroundColorKey">#FFFFFFFF</Color>
<SolidColorBrush x:Key="Highlight3ForegroundBrushKey"
Color="#FFFFFFFF" />
<Color x:Key="Highlight3ForegroundColorKey">#FFFFFFFF</Color>
<SolidColorBrush x:Key="Highlight3ForegroundBrushKey"
Color="#FFFFFFFF" />
<Color x:Key="LinkForegroundColorKey">#FF0000C8</Color>
<SolidColorBrush x:Key="LinkForegroundBrushKey"
Color="#FF0000C8" />
<Color x:Key="LinkForegroundColorKey">#FF0000C8</Color>
<SolidColorBrush x:Key="LinkForegroundBrushKey"
Color="#FF0000C8" />
<Color x:Key="ActiveLinkForegroundColorKey">#FF007ACC</Color>
<SolidColorBrush x:Key="ActiveLinkForegroundBrushKey"
Color="#FF007ACC" />
<Color x:Key="ActiveLinkForegroundColorKey">#FF007ACC</Color>
<SolidColorBrush x:Key="ActiveLinkForegroundBrushKey"
Color="#FF007ACC" />
<Color x:Key="ValidationErrorColorKey">#FFC80000</Color>
<SolidColorBrush x:Key="ValidationErrorBrushKey"
Color="#FFC80000" />
</Style.Resources>
<Color x:Key="ValidationErrorColorKey">#FFC80000</Color>
<SolidColorBrush x:Key="ValidationErrorBrushKey"
Color="#FFC80000" />
</Style.Resources>
</Style>
@@ -0,0 +1,18 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:controls="clr-namespace:System.Application.UI.Views.Controls"
x:Class="System.Application.UI.Views.Controls.WebView3">
<Panel HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<controls:WebViewBase x:Name="Browser"
Background="Transparent"/>
<controls:ProgressRing x:Name="webViewLoading"
IsIndeterminate="True"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="100" Width="100" />
</Panel>
</UserControl>
@@ -0,0 +1,106 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.LogicalTree;
using Avalonia.Markup.Xaml;
using CefNet;
using System.Application.UI.Resx;
using System.Application.UI.ViewModels;
namespace System.Application.UI.Views.Controls
{
public partial class WebView3 : UserControl, IDisposable
{
readonly ProgressRing webViewLoading;
bool disposedValue;
public WebViewBase Browser { get; }
/// <summary>
/// webview url <see cref="TextGap"/> property.
/// </summary>
public static readonly StyledProperty<string> UrlProperty =
AvaloniaProperty.Register<ScrollingTextBlock, string>(nameof(Url), WebView3WindowViewModel.AboutBlank);
public string Url
{
get { return GetValue(UrlProperty); }
set { SetValue(UrlProperty, value); }
}
public WebView3()
{
InitializeComponent();
webViewLoading = this.FindControl<ProgressRing>(nameof(webViewLoading));
Browser = this.FindControl<WebViewBase>(nameof(Browser));
Browser.Opacity = 0;
Browser.LoadingStateChange += WebView_LoadingStateChange;
this.GetObservable(UrlProperty)
.Subscribe(x =>
{
Navigate(Url);
});
}
public void Navigate(string url)
{
if (Browser.BrowserObject == null)
{
Browser.InitialUrl = url;
}
else
{
Browser.Navigate(url);
}
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
private void WebView_LoadingStateChange(object? sender, LoadingStateChangeEventArgs e)
{
if (!e.Busy)
{
if (Browser.Opacity != 1) Browser.Opacity = 1;
if (webViewLoading.IsVisible) webViewLoading.IsVisible = false;
}
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnDetachedFromLogicalTree(e);
Dispose();
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: 释放托管状态(托管对象)
if (Browser != null)
{
Browser.LoadingStateChange -= WebView_LoadingStateChange;
((IDisposable)Browser).Dispose();
}
}
// TODO: 释放未托管的资源(未托管的对象)并替代终结器
// TODO: 将大型字段设置为 null
disposedValue = true;
}
}
public void Dispose()
{
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}
@@ -16,7 +16,7 @@ using static System.Application.Services.CloudService.Constants;
// ReSharper disable once CheckNamespace
namespace System.Application.UI.Views.Controls
{
public sealed class WebView3 : WebView
public class WebViewBase : WebView
{
public static readonly RoutedEvent<FullscreenModeChangeEventArgs> FullscreenEvent = RoutedEvent.Register<WebView, FullscreenModeChangeEventArgs>("Fullscreen", RoutingStrategies.Bubble);
@@ -26,11 +26,11 @@ namespace System.Application.UI.Views.Controls
remove { RemoveHandler(FullscreenEvent, value); }
}
public WebView3()
public WebViewBase()
{
}
public WebView3(WebView opener) : base(opener)
public WebViewBase(WebView opener) : base(opener)
{
}
@@ -87,7 +87,7 @@ namespace System.Application.UI.Views.Controls
public class FullscreenModeChangeEventArgs : RoutedEventArgs
{
public FullscreenModeChangeEventArgs(IInteractive source, bool fullscreen) : base(WebView3.FullscreenEvent, source)
public FullscreenModeChangeEventArgs(IInteractive source, bool fullscreen) : base(WebViewBase.FullscreenEvent, source)
{
Fullscreen = fullscreen;
}
@@ -100,14 +100,14 @@ namespace System.Application.UI.Views.Controls
const int SHOW_DEV_TOOLS = (int)CefMenuId.UserFirst + 0;
//const int INSPECT_ELEMENT = (int)CefMenuId.UserFirst + 1;
readonly WebView3 webView;
readonly WebViewBase webView;
public WebView3Glue(WebView3 view) : base(view)
public WebView3Glue(WebViewBase view) : base(view)
{
webView = view;
}
private new WebView3 WebView => (WebView3)base.WebView;
private new WebViewBase WebView => (WebViewBase)base.WebView;
protected override bool OnSetFocus(CefBrowser browser, CefFocusSource source)
{
@@ -332,11 +332,11 @@ namespace System.Application.UI.Views.Controls
/// </summary>
unsafe class StreamResponseFilter : CefResponseFilter
{
readonly WebView3 webView;
readonly WebViewBase webView;
readonly bool rspIsCiphertext;
MemoryStream? memoryStream;
public StreamResponseFilter(WebView3 webView, bool rspIsCiphertext)
public StreamResponseFilter(WebViewBase webView, bool rspIsCiphertext)
{
this.webView = webView;
this.rspIsCiphertext = rspIsCiphertext;
@@ -188,6 +188,9 @@
<DataTemplate DataType="vm:GameRelatedPageViewModel">
<pages:GameRelatedPage/>
</DataTemplate>
<DataTemplate DataType="vm:ArchiSteamFarmPlusPageViewModel">
<pages:ArchiSteamFarmPlusPage/>
</DataTemplate>
</TabControl.DataTemplates>
<TabControl.ItemTemplate>
<DataTemplate>
@@ -6,7 +6,6 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="System.Application.UI.Views.Pages.About_ChangeLog">
<Panel>
<controls:WebView3 x:Name="webViewQA" Background="Transparent" />
<controls:ProgressRing x:Name="webViewQALoading" IsIndeterminate="True" HorizontalAlignment="Stretch" Height="100" Width="100" />
<controls:WebView3 x:Name="webView" Background="Transparent" />
</Panel>
</UserControl>
@@ -8,71 +8,25 @@ using System.Application.UI.Views.Controls;
namespace System.Application.UI.Views.Pages
{
public class About_ChangeLog : UserControl, IDisposable
public class About_ChangeLog : UserControl
{
readonly WebView3 webViewQA;
readonly ProgressRing webViewQALoading;
bool disposedValue;
readonly WebView3 webView;
public About_ChangeLog()
{
InitializeComponent();
webViewQALoading = this.FindControl<ProgressRing>(nameof(webViewQALoading));
webViewQA = this.FindControl<WebView3>(nameof(webViewQA));
webViewQA.Opacity = 0;
webViewQA.LoadingStateChange += WebView_LoadingStateChange;
webViewQA.InitialUrl = string.Format(
webView = this.FindControl<WebView3>(nameof(webView));
webView.Url = string.Format(
"https://steampp.net/changelogbox?theme={0}&language={1}",
CefNetApp.GetTheme(),
R.Language);
}
private void WebView_LoadingStateChange(object? sender, LoadingStateChangeEventArgs e)
{
if (!e.Busy)
{
if (webViewQA.Opacity != 1) webViewQA.Opacity = 1;
if (webViewQALoading.IsVisible) webViewQALoading.IsVisible = false;
}
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnDetachedFromLogicalTree(e);
Dispose();
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: 释放托管状态(托管对象)
if (webViewQA != null)
{
webViewQA.LoadingStateChange -= WebView_LoadingStateChange;
((IDisposable)webViewQA).Dispose();
}
}
// TODO: 释放未托管的资源(未托管的对象)并替代终结器
// TODO: 将大型字段设置为 null
disposedValue = true;
}
}
public void Dispose()
{
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}
@@ -7,6 +7,5 @@
x:Class="System.Application.UI.Views.Pages.About_FAQPage">
<Panel>
<controls:WebView3 x:Name="webViewQA" Background="Transparent" />
<controls:ProgressRing x:Name="webViewQALoading" IsIndeterminate="True" HorizontalAlignment="Stretch" Height="100" Width="100" />
</Panel>
</UserControl>
@@ -8,71 +8,24 @@ using System.Application.UI.Views.Controls;
namespace System.Application.UI.Views.Pages
{
public class About_FAQPage : UserControl, IDisposable
public class About_FAQPage : UserControl
{
readonly WebView3 webViewQA;
readonly ProgressRing webViewQALoading;
bool disposedValue;
WebView3 webViewQA;
public About_FAQPage()
{
InitializeComponent();
webViewQALoading = this.FindControl<ProgressRing>(nameof(webViewQALoading));
webViewQA = this.FindControl<WebView3>(nameof(webViewQA));
webViewQA.Opacity = 0;
webViewQA.LoadingStateChange += WebView_LoadingStateChange;
webViewQA.InitialUrl = string.Format(
webViewQA = this.FindControl<WebView3>("webViewQA");
webViewQA.Url = string.Format(
"https://steampp.net/faqbox?theme={0}&language={1}",
CefNetApp.GetTheme(),
R.Language);
}
private void WebView_LoadingStateChange(object? sender, LoadingStateChangeEventArgs e)
{
if (!e.Busy)
{
if (webViewQA.Opacity != 1) webViewQA.Opacity = 1;
if (webViewQALoading.IsVisible) webViewQALoading.IsVisible = false;
}
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnDetachedFromLogicalTree(e);
Dispose();
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: 释放托管状态(托管对象)
if (webViewQA != null)
{
webViewQA.LoadingStateChange -= WebView_LoadingStateChange;
((IDisposable)webViewQA).Dispose();
}
}
// TODO: 释放未托管的资源(未托管的对象)并替代终结器
// TODO: 将大型字段设置为 null
disposedValue = true;
}
}
public void Dispose()
{
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}
@@ -0,0 +1,64 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:System.Application.UI.ViewModels;assembly=System.Application.SteamTools.Client.Desktop"
xmlns:controls="clr-namespace:System.Application.UI.Views.Controls"
xmlns:resx="clr-namespace:System.Application.UI.Resx;assembly=System.Application.SteamTools.Client.Desktop"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pages="clr-namespace:System.Application.UI.Views.Pages"
mc:Ignorable="d"
d:DesignWidth="800" d:DesignHeight="450"
x:DataType="vm:ArchiSteamFarmPlusPageViewModel"
x:CompileBindings="True"
x:Class="System.Application.UI.Views.Pages.ArchiSteamFarmPlusPage">
<TabControl TabStripPlacement="Left">
<TabItem Header="ASF控制台">
<TextBox AcceptsReturn="True"/>
</TabItem>
<TabItem Header="ASF Web UI">
<controls:WebView3 Url="{Binding WebUrl}"/>
</TabItem>
<TabItem Header="Bot配置">
</TabItem>
<TabItem Header="ASF配置">
<StackPanel Spacing="20">
<StackPanel.Styles>
<Style Selector="TextBlock">
<Setter Property="FontSize" Value="{StaticResource FontSizeH7}"/>
<Setter Property="Foreground" Value="{DynamicResource HighlightForegroundBrushKey}" />
</Style>
<Style Selector="DockPanel > TextBlock">
<Setter Property="Margin" Value="0 0 20 0" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="(DockPanel.Dock)" Value="Left" />
</Style>
<Style Selector="DockPanel > ToggleSwitch">
<Setter Property="Margin" Value="0 0 -12 0" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="OnContent" Value="{x:Null}" />
<Setter Property="OffContent" Value="{x:Null}" />
</Style>
</StackPanel.Styles>
<DockPanel>
<TextBlock Text="ASF路径"/>
<Button Content="选择路径"></Button>
</DockPanel>
<DockPanel>
<TextBlock Text="启用IPC"/>
<ToggleSwitch />
</DockPanel>
<StackPanel Orientation="Vertical" Spacing="8">
<TextBlock Text="IPC密码"/>
<TextBox Watermark="IPC密码"></TextBox>
</StackPanel>
</StackPanel>
</TabItem>
</TabControl>
</UserControl>
@@ -0,0 +1,19 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using System.Application.UI.ViewModels;
namespace System.Application.UI.Views.Pages
{
public class ArchiSteamFarmPlusPage : UserControl
{
public ArchiSteamFarmPlusPage()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}
@@ -9,7 +9,7 @@ namespace System.Application.UI.Views.Pages
{
public class DebugWebViewPage : UserControl, IDisposable
{
readonly WebView webView;
readonly WebView3 webView;
readonly TextBox urlTextBox;
public DebugWebViewPage()
@@ -17,14 +17,14 @@ namespace System.Application.UI.Views.Pages
InitializeComponent();
webView = this.FindControl<WebView3>("webView");
webView.InitialUrl = "chrome://version";
webView.Url = "chrome://version";
//webView.BrowserCreated += WebView_BrowserCreated;
urlTextBox = this.FindControl<TextBox>("urlTextBox");
urlTextBox.KeyUp += UrlTextBox_KeyUp;
}
private void UrlTextBox_KeyUp(object sender, Avalonia.Input.KeyEventArgs e)
private void UrlTextBox_KeyUp(object? sender, Avalonia.Input.KeyEventArgs e)
{
if (e.Key == Avalonia.Input.Key.Enter)
{
@@ -62,21 +62,21 @@ namespace System.Application.UI.Views.Pages
{
if (disposing)
{
// TODO: 释放托管状态(托管对象)
// TODO: 释放托管状态(托管对象)
if (webView != null)
{
((IDisposable)webView).Dispose();
}
}
// TODO: 释放未托管的资源(未托管的对象)并替代终结器
// TODO: 将大型字段设置为 null
// TODO: 释放未托管的资源(未托管的对象)并替代终结器
// TODO: 将大型字段设置为 null
disposedValue = true;
}
}
public void Dispose()
{
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
Dispose(disposing: true);
//GC.SuppressFinalize(this);
}
@@ -79,7 +79,7 @@
</TextBlock>
<ListBox Items="{Binding WindowList,Mode=OneWay}"
Height="200" Margin="0,5"
Height="200" Margin="0,5" Background="{DynamicResource ThemeBrushKey}"
SelectedItem="{Binding SelectWindow}">
<ListBox.ItemTemplate>
<DataTemplate>
@@ -34,7 +34,7 @@ namespace System.Application.UI.Views.Windows
}
};
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -46,7 +46,7 @@ namespace System.Application.UI.Views.Windows
TbPhoneNumber.KeyUp += Submit;
TbSmsCodeNew.KeyUp += Submit;
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -114,7 +114,7 @@ namespace Avalonia.Controls
else if (DI.Platform == System.Platform.Apple)
{
ExtendClientAreaChromeHints =
ExtendClientAreaChromeHints.SystemChrome;
ExtendClientAreaChromeHints.OSXThickTitleBar;
}
else
{
@@ -225,7 +225,7 @@ namespace Avalonia.Controls
else if (DI.Platform == System.Platform.Apple)
{
ExtendClientAreaChromeHints =
ExtendClientAreaChromeHints.SystemChrome;
ExtendClientAreaChromeHints.OSXThickTitleBar;
}
else
{
@@ -11,7 +11,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -11,7 +11,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -11,7 +11,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -11,7 +11,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -15,7 +15,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -11,7 +11,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -11,7 +11,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -15,7 +15,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -12,7 +12,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -11,7 +11,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -38,7 +38,7 @@ namespace System.Application.UI.Views.Windows
}
};
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -22,7 +22,7 @@ namespace System.Application.UI.Views.Windows
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -12,7 +12,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
BtnCancel = this.FindControl<Button>(nameof(BtnCancel));
BtnCancel.Click += (_, _) => Close();
@@ -11,7 +11,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -3,7 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
Width="180" Height="400"
Width="180"
x:Class="System.Application.UI.Views.Windows.TaskBarWindow"
xmlns:resx="clr-namespace:System.Application.UI.Resx;assembly=System.Application.SteamTools.Client.Desktop"
xmlns:service="clr-namespace:System.Application.Services;assembly=System.Application.SteamTools.Client.Desktop"
@@ -25,7 +25,7 @@ namespace System.Application.UI.Views.Windows
this.Opened += Window_Opened;
this.LostFocus += Window_LostFocus;
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -49,17 +49,24 @@ namespace System.Application.UI.Views.Windows
//{
// this.Position = new PixelPoint(vm.SizePosition.X, vm.SizePosition.Y - (int)this.Height);
//}
var workingAreaWidth = this.Screens.Primary.WorkingArea.Width;
vm.WhenAnyValue(x => x.SizePosition.X, x => x.SizePosition.Y)
.Subscribe(x =>
{
if ((x.Item1 + (int)this.Width + 30) > workingAreaWidth)
var screen = this.Screens.ScreenFromPoint(new PixelPoint(x.Item1, x.Item2));
var heightPoint = x.Item2 - (int)(this.Height * screen.PixelDensity);
if (heightPoint < 0)
{
this.Position = new PixelPoint(x.Item1 - (int)this.Width, x.Item2 - (int)this.Height);
this.Position = new PixelPoint(x.Item1, x.Item2);
}
else if ((x.Item1 + (int)this.Width + 30) > screen.WorkingArea.Width)
{
this.Position = new PixelPoint(x.Item1 - (int)(this.Width * screen.PixelDensity), heightPoint);
}
else
{
this.Position = new PixelPoint(x.Item1, x.Item2 - (int)this.Height);
this.Position = new PixelPoint(x.Item1, heightPoint);
}
});
}
@@ -14,7 +14,7 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
}
@@ -31,9 +31,9 @@
MaterialOpacity="{ReflectionBinding Value,Source={x:Static ms:UISettings.AcrylicOpacity},Mode=OneWay}" TintOpacity="1"/>
</ExperimentalAcrylicBorder.Material>
</ExperimentalAcrylicBorder>
<controls:WebView3 x:Name="webView"/>
<controls:ProgressRing IsIndeterminate="True" HorizontalAlignment="Stretch" Height="100" Width="100" IsVisible="{Binding IsLoading}" />
<controls:WebView3 x:Name="webView" Url="{Binding Url}"/>
<!--Toast-->
<controls:ToastMessage />
</Panel>
@@ -26,14 +26,13 @@ namespace System.Application.UI.Views.Windows
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools2();
#endif
webView = this.FindControl<WebView3>(nameof(webView));
webView.InitialUrl = WebView3WindowViewModel.AboutBlank;
webView.Opacity = 0;
webView.DocumentTitleChanged += WebView_DocumentTitleChanged;
webView.LoadingStateChange += WebView_LoadingStateChange;
webView.BrowserCreated += WebView_BrowserCreated;
webView.Browser.InitialUrl = WebView3WindowViewModel.AboutBlank;
webView.Browser.DocumentTitleChanged += WebView_DocumentTitleChanged;
webView.Browser.LoadingStateChange += WebView_LoadingStateChange;
webView.Browser.BrowserCreated += WebView_BrowserCreated;
}
CancellationTokenSource? cts;
@@ -58,7 +57,7 @@ namespace System.Application.UI.Views.Windows
}
if (isDelayed && vm.IsLoading)
{
webView.Stop();
webView.Browser.Stop();
await WebViewLoadingTimeoutAsync(vm);
}
}
@@ -106,7 +105,7 @@ namespace System.Application.UI.Views.Windows
}
if (!e.Busy)
{
var mainFrame = webView.GetMainFrame();
var mainFrame = webView.Browser.GetMainFrame();
if (mainFrame != null)
{
var mainFrameSource = await mainFrame.GetSourceAsync(default);
@@ -115,7 +114,6 @@ namespace System.Application.UI.Views.Windows
await WebViewLoadingTimeoutAsync(vm);
return;
}
if (webView.Opacity != 1) webView.Opacity = 1;
if (vm.IsLoading)
{
vm.IsLoading = false;
@@ -128,7 +126,7 @@ namespace System.Application.UI.Views.Windows
string? initialUrl;
private void WebView_BrowserCreated(object? sender, EventArgs e)
{
if (initialUrl != null && webView.BrowserObject != null)
if (initialUrl != null && webView.Browser.BrowserObject != null)
{
webView.Navigate(initialUrl);
}
@@ -136,7 +134,7 @@ namespace System.Application.UI.Views.Windows
void Navigate(string url)
{
if (webView.BrowserObject == null)
if (webView.Browser.BrowserObject == null)
{
initialUrl = url;
}
@@ -203,9 +201,9 @@ namespace System.Application.UI.Views.Windows
{
await LoginUsingSteamClientCookiesAsync();
if (loginUsingSteamClientState == LoginUsingSteamClientState.Success
&& webView.BrowserObject != null)
&& webView.Browser.BrowserObject != null)
{
webView.Reload();
webView.Browser.Reload();
}
}
@@ -218,7 +216,7 @@ namespace System.Application.UI.Views.Windows
vm.Close += Close;
if (!string.IsNullOrWhiteSpace(vm.Title))
{
webView.DocumentTitleChanged -= WebView_DocumentTitleChanged;
webView.Browser.DocumentTitleChanged -= WebView_DocumentTitleChanged;
}
if (vm.UseLoginUsingSteamClient)
{
@@ -249,10 +247,10 @@ namespace System.Application.UI.Views.Windows
Navigate(x);
}
}).AddTo(vm);
vm.WhenAnyValue(x => x.StreamResponseFilterUrls).Subscribe(x => webView.StreamResponseFilterUrls = x).AddTo(vm);
vm.WhenAnyValue(x => x.FixedSinglePage).Subscribe(x => webView.FixedSinglePage = x).AddTo(vm);
vm.WhenAnyValue(x => x.IsSecurity).Subscribe(x => webView.IsSecurity = x).AddTo(vm);
webView.OnStreamResponseFilterResourceLoadComplete += vm.OnStreamResponseFilterResourceLoadComplete;
vm.WhenAnyValue(x => x.StreamResponseFilterUrls).Subscribe(x => webView.Browser.StreamResponseFilterUrls = x).AddTo(vm);
vm.WhenAnyValue(x => x.FixedSinglePage).Subscribe(x => webView.Browser.FixedSinglePage = x).AddTo(vm);
vm.WhenAnyValue(x => x.IsSecurity).Subscribe(x => webView.Browser.IsSecurity = x).AddTo(vm);
webView.Browser.OnStreamResponseFilterResourceLoadComplete += vm.OnStreamResponseFilterResourceLoadComplete;
}
}
@@ -302,11 +300,11 @@ namespace System.Application.UI.Views.Windows
if (webView != null)
{
cts?.Cancel();
webView.DocumentTitleChanged -= WebView_DocumentTitleChanged;
webView.LoadingStateChange -= WebView_LoadingStateChange;
webView.Browser.DocumentTitleChanged -= WebView_DocumentTitleChanged;
webView.Browser.LoadingStateChange -= WebView_LoadingStateChange;
if (DataContext is WebView3WindowViewModel vm)
{
webView.OnStreamResponseFilterResourceLoadComplete -= vm.OnStreamResponseFilterResourceLoadComplete;
webView.Browser.OnStreamResponseFilterResourceLoadComplete -= vm.OnStreamResponseFilterResourceLoadComplete;
}
((IDisposable)webView).Dispose();
}
@@ -1,7 +1,7 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using System.Application.Services;
using System.Net;
// ReSharper disable once CheckNamespace
namespace System
@@ -21,5 +21,13 @@ namespace System
}
return false;
}
#if DEBUG
public static void AttachDevTools2(this TopLevel root)
{
if (DI.Platform == Platform.Apple && DI.DeviceIdiom == DeviceIdiom.Desktop) return;
root.AttachDevTools();
}
#endif
}
}
@@ -56,4 +56,5 @@
<ItemGroup Condition="'$(Configuration)'=='Debug'">
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.999-cibuild0014488-beta" />
</ItemGroup>
</Project>
@@ -119,7 +119,7 @@ namespace System.Application.Services.Implementation
td.Settings.StopIfGoingOnBatteries = false;
td.Settings.DisallowStartIfOnBatteries = false;
td.Triggers.Add(new LogonTrigger());
td.Actions.Add(new ExecAction(AppHelper.ProgramName, "-clt c -silence", Path.GetDirectoryName(Assembly.GetCallingAssembly().Location)));
td.Actions.Add(new ExecAction(AppHelper.ProgramName, "-clt c -silence", IOPath.BaseDirectory));
if (IsAdministrator)
td.Principal.RunLevel = TaskRunLevel.Highest;
TaskService.Instance.RootFolder.RegisterTaskDefinition(name, td);
@@ -55,7 +55,7 @@ namespace System.Application.UI
JumpList jumpList1 = JumpList.GetJumpList(AvaloniaApplication.Current);
if (jumpList1 != null)
{
var tk = jumpList1.JumpItems.FirstOrDefault(s => s is JumpTask t && t.Arguments == task.Arguments);
var tk = jumpList1.JumpItems.FirstOrDefault(s => s is JumpTask t && t.ApplicationPath == task.ApplicationPath && t.Arguments == task.Arguments);
if (tk != null)
{
jumpList1.JumpItems.Remove(tk);
@@ -0,0 +1,21 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace System.Application.Models
{
public class ASFGlobalConfig
{
[JsonProperty(Required = Required.DisallowNull)]
public bool IPC { get; set; }
[JsonProperty]
public string? IPCPassword { get; set; }
[JsonProperty(Required = Required.DisallowNull)]
public ulong SteamOwnerID { get; set; }
}
}
@@ -110,5 +110,16 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddSingleton<IWindowService, WindowServiceImpl>();
return services;
}
/// <summary>
/// 添加 asf 功能
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddArchiSteamFarmService(this IServiceCollection services)
{
services.AddSingleton<IArchiSteamFarmService, ArchiSteamFarmServiceImpl>();
return services;
}
}
}
@@ -0,0 +1,32 @@
using ReactiveUI;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace System.Application.Services.Implementation
{
public interface IArchiSteamFarmService
{
public static IArchiSteamFarmService Instance => DI.Get<IArchiSteamFarmService>();
public string? ArchiSteamFarmExePath { get; }
public string? ArchiSteamFarmConfigPath { get; }
public StringBuilder ArchiSteamFarmOutText { get; }
public Process? Process { get; }
public bool IsArchiSteamFarmExists { get; }
public bool IsArchiSteamFarmRuning { get; }
void SetArchiSteamFarmExePath(string path);
string GetArchiSteamFarmIPCUrl();
bool RunArchiSteamFarm();
void SetArchiSteamFarmConfig();
void AddBot();
}
}
@@ -0,0 +1,105 @@
using ReactiveUI;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace System.Application.Services.Implementation
{
internal sealed class ArchiSteamFarmServiceImpl : ReactiveObject, IArchiSteamFarmService
{
readonly IDesktopPlatformService platformService;
public string? ArchiSteamFarmExePath { get; private set; }
public string? ArchiSteamFarmConfigPath => string.IsNullOrEmpty(ArchiSteamFarmExePath) ? Path.GetDirectoryName(ArchiSteamFarmExePath) : null;
public StringBuilder ArchiSteamFarmOutText { get; private set; } = new StringBuilder();
public Process? Process { get; private set; }
public bool IsArchiSteamFarmExists => File.Exists(ArchiSteamFarmExePath);
public bool IsArchiSteamFarmRuning => !Process?.HasExited ?? false;
public ArchiSteamFarmServiceImpl(IDesktopPlatformService platform)
{
platformService = platform;
var temp = Path.Combine(IOPath.BaseDirectory, "ASF", "ArchiSteamFarm.exe");
SetArchiSteamFarmExePath(temp);
}
public void SetArchiSteamFarmExePath(string path)
{
if (File.Exists(path) && Path.GetExtension(path) == "exe")
{
ArchiSteamFarmExePath = path;
}
}
public bool RunArchiSteamFarm()
{
try
{
if (IsArchiSteamFarmExists)
{
Task.Run(() =>
{
Process = new Process();
Process.StartInfo.FileName = ArchiSteamFarmExePath;//要执行的程序名称
Process.StartInfo.UseShellExecute = true;
Process.StartInfo.StandardOutputEncoding = Encoding.Default;
Process.StartInfo.RedirectStandardInput = true;
Process.StartInfo.RedirectStandardOutput = true;
Process.StartInfo.RedirectStandardError = true;
Process.StartInfo.CreateNoWindow = true;//不显示程序窗口
Process.Start();//启动程序
Process.StandardInput.AutoFlush = true;
//Process.StartInfo.Verb = "runas";
//Process.StandardInput.WriteLine();
StreamReader standardOutput = Process.StandardOutput;
while (!standardOutput.EndOfStream)
{
string? text = standardOutput.ReadLine();
ArchiSteamFarmOutText.Append(text + Environment.NewLine);
}
Process.Close();
standardOutput.Close();
}).Forget();
}
}
catch (Exception ex)
{
Log.Error(nameof(IArchiSteamFarmService), ex, nameof(RunArchiSteamFarm));
}
return IsArchiSteamFarmRuning;
}
public string GetArchiSteamFarmIPCUrl()
{
return "http://0.0.0.0:1242";
}
public void SetArchiSteamFarmConfig()
{
}
public void AddBot()
{
}
public void GetAllBots()
{
}
public void SaveBotConfig()
{
}
}
}
@@ -212,13 +212,15 @@ namespace System.Application.Services
return (IPAddress.Loopback.ToString(), host);
});
}).Where(w => !string.IsNullOrEmpty(w.Item1));
var r = IHostsFileService.Instance.UpdateHosts(hosts);
if (r.ResultType != OperationResultType.Success)
if (DI.Platform == Platform.Windows)
{
Toast.Show(SR.OperationHostsError_.Format(r.Message));
httpProxyService.StopProxy();
return;
var r = IHostsFileService.Instance.UpdateHosts(hosts);
if (r.ResultType != OperationResultType.Success)
{
Toast.Show(SR.OperationHostsError_.Format(r.Message));
httpProxyService.StopProxy();
return;
}
}
}
}
@@ -254,7 +254,7 @@ namespace System.Application.Services
user.MicrosoftAccountEmail = null;
break;
case FastLoginChannel.QQ:
user.QQAccountNumber = null;
user.QQNickName = null;
break;
case FastLoginChannel.Apple:
user.AppleAccountEmail = null;
@@ -285,7 +285,7 @@ namespace System.Application.Services
user.MicrosoftAccountEmail = rsp.User?.MicrosoftAccountEmail;
break;
case FastLoginChannel.QQ:
user.QQAccountNumber = rsp.User?.QQAccountNumber;
user.QQNickName = rsp.User?.QQNickName;
break;
case FastLoginChannel.Apple:
user.AppleAccountEmail = rsp.User?.AppleAccountEmail;
+31 -9
View File
@@ -1,13 +1,9 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NLog;
using NLog.Extensions.Logging;
using System.Application.Models;
using System.Application.Security;
using System.Application.Services;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Properties;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
using NInternalLogger = NLog.Common.InternalLogger;
@@ -69,7 +65,7 @@ namespace System.Application.UI
const LogLevel DefaultLoggerMinLevel = ThisAssembly.Debuggable ? LogLevel.Debug : LogLevel.Error;
public static NLogLevel DefaultNLoggerMinLevel = ConvertLogLevel(DefaultLoggerMinLevel);
public static readonly NLogLevel DefaultNLoggerMinLevel = ConvertLogLevel(DefaultLoggerMinLevel);
/// <summary>
/// Convert log level to NLog variant.
@@ -101,7 +97,8 @@ namespace System.Application.UI
{
try
{
LoggerFilterOptions.MinLevel = logLevel;
var o = LoggerFilterOptions;
if (o != null) o.MinLevel = logLevel;
}
catch
{
@@ -109,10 +106,22 @@ namespace System.Application.UI
SetNLoggerMinLevel(ConvertLogLevel(logLevel));
}
static LoggerFilterOptions? _LoggerFilterOptions;
/// <summary>
/// 日志过滤选项
/// </summary>
static LoggerFilterOptions LoggerFilterOptions => DI.Get<IOptions<LoggerFilterOptions>>().Value;
static LoggerFilterOptions? LoggerFilterOptions
{
get
{
if (_LoggerFilterOptions != null) return _LoggerFilterOptions;
return DI.Get_Nullable<IOptions<LoggerFilterOptions>>()?.Value;
}
set
{
_LoggerFilterOptions = value;
}
}
internal static (LogLevel minLevel, Action<ILoggingBuilder> cfg) Configure()
{
@@ -138,10 +147,23 @@ namespace System.Application.UI
/// </summary>
public static LogLevel LoggerMinLevel
{
get => LoggerFilterOptions.MinLevel;
get
{
var o = LoggerFilterOptions;
if (o == null)
{
o = new();
LoggerFilterOptions = o;
}
return o.MinLevel;
}
set
{
LoggerFilterOptions.MinLevel = value;
var o = LoggerFilterOptions;
if (o != null)
{
o.MinLevel = value;
}
SetNLoggerMinLevel(value);
}
}
@@ -75,8 +75,8 @@ namespace System.Application.UI.ViewModels
AddTabItem<SteamAccountPageViewModel>();
AddTabItem<GameListPageViewModel>();
AddTabItem<LocalAuthPageViewModel>();
AddTabItem<ArchiSteamFarmPlusPageViewModel>();
//AddTabItem<SteamIdlePageViewModel>();
//AddTabItem<ArchiSteamFarmPlusPageViewModel>();
if (DI.Platform == Platform.Windows)
AddTabItem<GameRelatedPageViewModel>();
//AddTabItem<OtherPlatformPageViewModel>();
@@ -21,7 +21,7 @@ namespace System.Application.UI.ViewModels
public AboutPageViewModel()
{
IconKey = nameof(AboutPageViewModel).Replace("ViewModel", "Svg");
OpenBrowserCommand = ReactiveCommand.Create<string>(BrowserOpen);
CopyLinkCommand = ReactiveCommand.Create<string>(IDesktopAppService.Instance.SetClipboardText);
@@ -50,7 +50,7 @@ namespace System.Application.UI.ViewModels
public ReactiveCommand<Unit, Unit> DelAccountCommand { get; }
public string VersionDisplay => ThisAssembly.VersionDisplay;
public string VersionDisplay => ThisAssembly.VersionDisplay + (Environment.Is64BitProcess ? " (x64)" : " (x32)");
public string LabelVersionDisplay => ThisAssembly.IsBetaRelease ? "Beta Version:" : "Current Version:";
@@ -1,4 +1,6 @@
using System.Application.UI.Resx;
using ReactiveUI;
using System.Application.Services.Implementation;
using System.Application.UI.Resx;
namespace System.Application.UI.ViewModels
{
@@ -13,6 +15,17 @@ namespace System.Application.UI.ViewModels
public ArchiSteamFarmPlusPageViewModel()
{
IconKey = nameof(ArchiSteamFarmPlusPageViewModel).Replace("ViewModel", "Svg");
WebUrl = IArchiSteamFarmService.Instance.GetArchiSteamFarmIPCUrl();
}
private string? _WebUrl;
public string? WebUrl
{
get => _WebUrl;
set => this.RaiseAndSetIfChanged(ref _WebUrl, value);
}
}
}
@@ -20,6 +20,7 @@ namespace System.Application.UI.ViewModels
public class IdleAppWindowViewModel : WindowViewModel
{
private bool init=false;
private readonly ISteamService SteamTool = ISteamService.Instance;
public IdleAppWindowViewModel() : base()
{
Title = ThisAssembly.AssemblyTrademark + " | " + AppResources.GameList_IdleGamesManger;
@@ -154,64 +155,72 @@ namespace System.Application.UI.ViewModels
}
public void RunOrStopAllButton_Click()
{
if (!RunLoaingState)
if (SteamTool.IsRunningSteamProcess)
{
RunLoaingState = true;
RunState = !RunState;
if (RunState)
if (!RunLoaingState)
{
foreach (var item in IdleGameList)
RunLoaingState = true;
RunState = !RunState;
if (RunState)
{
var runState = SteamConnectService.Current.RuningSteamApps.FirstOrDefault(x => x.AppId == item.AppId);
if (runState == null)
foreach (var item in IdleGameList)
{
item.StartSteamAppProcess();
SteamConnectService.Current.RuningSteamApps.Add(item);
}
else
{
if (runState.Process == null || !runState.Process.HasExited)
var runState = SteamConnectService.Current.RuningSteamApps.FirstOrDefault(x => x.AppId == item.AppId);
if (runState == null)
{
runState.StartSteamAppProcess();
item.StartSteamAppProcess();
SteamConnectService.Current.RuningSteamApps.Add(item);
}
else
{
item.Process = runState.Process;
if (runState.Process == null || !runState.Process.HasExited)
{
runState.StartSteamAppProcess();
}
else
{
item.Process = runState.Process;
}
}
}
}
ChangeRunTxt();
ChangeRunTxt();
}
else
{
foreach (var item in IdleGameList)
{
var runState = SteamConnectService.Current.RuningSteamApps.FirstOrDefault(x => x.AppId == item.AppId);
if (runState != null)
{
runState.Process?.Kill();
SteamConnectService.Current.RuningSteamApps.Remove(runState);
item.Process = null;
}
else
{
item.Process = null;
SteamConnectService.Current.RuningSteamApps.Add(item);
}
}
}
RunLoaingState = false;
Toast.Show(AppResources.GameList_OperationSuccess);
}
else
{
foreach (var item in IdleGameList)
{
var runState = SteamConnectService.Current.RuningSteamApps.FirstOrDefault(x => x.AppId == item.AppId);
if (runState != null)
{
runState.Process?.Kill();
SteamConnectService.Current.RuningSteamApps.Remove(runState);
item.Process = null;
}
else
{
item.Process = null;
SteamConnectService.Current.RuningSteamApps.Add(item);
}
}
Toast.Show(AppResources.GameList_LoaingTips);
}
RunLoaingState = false;
Toast.Show(AppResources.GameList_OperationSuccess);
}
else
{
Toast.Show(AppResources.GameList_LoaingTips);
else {
var result = MessageBoxCompat.ShowAsync(@AppResources.GameList_SteamNotRuning, ThisAssembly.AssemblyTrademark, MessageBoxButtonCompat.OK);
}
}
public void RunStopBtn_Click(SteamApp app)
{
var runInfoState = SteamConnectService.Current.RuningSteamApps.FirstOrDefault(x => x.AppId == app.AppId);
if (SteamTool.IsRunningSteamProcess)
{
var runInfoState = SteamConnectService.Current.RuningSteamApps.FirstOrDefault(x => x.AppId == app.AppId);
if (runInfoState == null)
{
RunOrStop(app);
@@ -225,6 +234,11 @@ namespace System.Application.UI.ViewModels
ChangeRunTxt();
Toast.Show(AppResources.GameList_OperationSuccess);
}
else
{
var result = MessageBoxCompat.ShowAsync(@AppResources.GameList_SteamNotRuning, ThisAssembly.AssemblyTrademark, MessageBoxButtonCompat.OK);
}
}
public void RunOrStop(SteamApp app)
{
@@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
@@ -0,0 +1 @@
/build
@@ -0,0 +1,45 @@
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
defaultConfig {
applicationId "net.steampp.app.design"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation 'de.hdodenhof:circleimageview:3.1.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
implementation 'androidx.navigation:navigation-fragment:2.3.0'
implementation 'androidx.navigation:navigation-ui:2.3.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -0,0 +1,26 @@
package net.steampp.app.design;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("net.steampp.app.design", appContext.getPackageName());
}
}
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.steampp.app.design">
<application
android:name=".ui.MainApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/MainTheme">
<activity
android:name=".ui.activities.MainActivity"
android:configChanges="screenSize|orientation|keyboard|keyboardHidden|screenLayout|smallestScreenSize"
android:label="@string/app_name" />
<activity
android:name=".ui.activities.SplashActivity"
android:configChanges="screenSize|orientation|keyboard|keyboardHidden|screenLayout|smallestScreenSize"
android:label="@string/app_name"
android:noHistory="true"
android:theme="@style/MainTheme.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

@@ -0,0 +1,18 @@
package net.steampp.app.design.ui;
import android.app.Application;
import android.content.Context;
public class MainApplication extends Application {
static Context _context;
public static Context getContext() {
return _context;
}
@Override
public void onCreate() {
super.onCreate();
_context = this;
}
}
@@ -0,0 +1,47 @@
package net.steampp.app.design.ui.activities;
import android.os.Bundle;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import net.steampp.app.design.R;
import net.steampp.app.design.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// 底部导航(https://material.io/components/bottom-navigation)
// - 需要从应用程序中的任何地方访问的顶级目的地
// - 三到五个目的地
// - 仅限移动或平板电脑
// 导航抽屉(https://material.io/components/navigation-drawer)
// - 具有五个或更多顶级目的地的应用
// - 具有两个或两个以上级别的导航等级的应用程序
// - 不相关的目的地之间的快速导航
BottomNavigationView navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_local_auth, R.id.navigation_community_fix, R.id.navigation_game_list, R.id.navigation_my)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(binding.navView, navController);
}
}
@@ -0,0 +1,23 @@
package net.steampp.app.design.ui.activities;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class SplashActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
@Override
public void onBackPressed() {
}
}
@@ -0,0 +1,46 @@
package net.steampp.app.design.ui.fragments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import net.steampp.app.design.databinding.FragmentCommunityFixBinding;
import net.steampp.app.design.ui.viewmodels.CommunityFixViewModel;
public class CommunityFixFragment extends Fragment {
private CommunityFixViewModel viewModel;
private FragmentCommunityFixBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
viewModel =
new ViewModelProvider(this).get(CommunityFixViewModel.class);
binding = FragmentCommunityFixBinding.inflate(inflater, container, false);
View root = binding.getRoot();
final TextView textView = binding.textView;
viewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
textView.setText(s);
}
});
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
@@ -0,0 +1,46 @@
package net.steampp.app.design.ui.fragments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import net.steampp.app.design.databinding.FragmentGameListBinding;
import net.steampp.app.design.ui.viewmodels.GameListViewModel;
public class GameListFragment extends Fragment {
private GameListViewModel viewModel;
private FragmentGameListBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
viewModel =
new ViewModelProvider(this).get(GameListViewModel.class);
binding = FragmentGameListBinding.inflate(inflater, container, false);
View root = binding.getRoot();
final TextView textView = binding.textView;
viewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
textView.setText(s);
}
});
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
@@ -0,0 +1,46 @@
package net.steampp.app.design.ui.fragments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import net.steampp.app.design.databinding.FragmentLocalAuthBinding;
import net.steampp.app.design.ui.viewmodels.LocalAuthViewModel;
public class LocalAuthFragment extends Fragment {
private LocalAuthViewModel viewModel;
private FragmentLocalAuthBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
viewModel =
new ViewModelProvider(this).get(LocalAuthViewModel.class);
binding = FragmentLocalAuthBinding.inflate(inflater, container, false);
View root = binding.getRoot();
final TextView textView = binding.textView;
viewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
textView.setText(s);
}
});
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
@@ -0,0 +1,46 @@
package net.steampp.app.design.ui.fragments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import net.steampp.app.design.databinding.FragmentMyBinding;
import net.steampp.app.design.ui.viewmodels.MyViewModel;
public class MyFragment extends Fragment {
private MyViewModel viewModel;
private FragmentMyBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
viewModel =
new ViewModelProvider(this).get(MyViewModel.class);
binding = FragmentMyBinding.inflate(inflater, container, false);
View root = binding.getRoot();
// final TextView textView = binding.textView;
// viewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
// @Override
// public void onChanged(@Nullable String s) {
// textView.setText(s);
// }
// });
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
@@ -0,0 +1,26 @@
package net.steampp.app.design.ui.viewmodels;
import android.app.Application;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import net.steampp.app.design.R;
import net.steampp.app.design.ui.MainApplication;
import java.util.Arrays;
public class CommunityFixViewModel extends ViewModel {
private MutableLiveData<String> mText;
public CommunityFixViewModel() {
mText = new MutableLiveData<>();
mText.setValue(Arrays.stream(this.getClass().getName().split("\\.")).reduce((first, second) -> second).orElse("").replace("ViewModel","") + "\n" + MainApplication.getContext().getString(R.string.under_construction));
}
public LiveData<String> getText() {
return mText;
}
}
@@ -0,0 +1,24 @@
package net.steampp.app.design.ui.viewmodels;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import net.steampp.app.design.R;
import net.steampp.app.design.ui.MainApplication;
import java.util.Arrays;
public class GameListViewModel extends ViewModel {
private MutableLiveData<String> mText;
public GameListViewModel() {
mText = new MutableLiveData<>();
mText.setValue(Arrays.stream(this.getClass().getName().split("\\.")).reduce((first, second) -> second).orElse("").replace("ViewModel","") + "\n" + MainApplication.getContext().getString(R.string.under_construction));
}
public LiveData<String> getText() {
return mText;
}
}
@@ -0,0 +1,24 @@
package net.steampp.app.design.ui.viewmodels;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import net.steampp.app.design.R;
import net.steampp.app.design.ui.MainApplication;
import java.util.Arrays;
public class LocalAuthViewModel extends ViewModel {
private MutableLiveData<String> mText;
public LocalAuthViewModel() {
mText = new MutableLiveData<>();
mText.setValue(Arrays.stream(this.getClass().getName().split("\\.")).reduce((first, second) -> second).orElse("").replace("ViewModel","") + "\n" + MainApplication.getContext().getString(R.string.under_construction));
}
public LiveData<String> getText() {
return mText;
}
}
@@ -0,0 +1,24 @@
package net.steampp.app.design.ui.viewmodels;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import net.steampp.app.design.R;
import net.steampp.app.design.ui.MainApplication;
import java.util.Arrays;
public class MyViewModel extends ViewModel {
private MutableLiveData<String> mText;
public MyViewModel() {
mText = new MutableLiveData<>();
mText.setValue(Arrays.stream(this.getClass().getName().split("\\.")).reduce((first, second) -> second).orElse("").replace("ViewModel","") + "\n" + MainApplication.getContext().getString(R.string.under_construction));
}
public LiveData<String> getText() {
return mText;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Some files were not shown because too many files have changed in this diff Show More