mirror of
https://github.com/BeyondDimension/SteamTools.git
synced 2026-10-26 03:59:34 +08:00
Compare commits
23
Commits
3.0.0-rc.5
...
3.0.0-rc.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a78f387cf | ||
|
|
8a091cee0c | ||
|
|
28f9dde2a4 | ||
|
|
aa88832d09 | ||
|
|
3da18b39ac | ||
|
|
01e8478ce0 | ||
|
|
0de026257a | ||
|
|
5ff097d7d6 | ||
|
|
59effc34a3 | ||
|
|
afd21a3285 | ||
|
|
c7ffeb6046 | ||
|
|
e659e3d502 | ||
|
|
077a333d49 | ||
|
|
056a73e3f0 | ||
|
|
db5095c205 | ||
|
|
a1789cec16 | ||
|
|
9a234ae84f | ||
|
|
8692eaef7c | ||
|
|
cb6516ce53 | ||
|
|
d8362ce9ea | ||
|
|
0cfdff80cd | ||
|
|
15c67bcd52 | ||
|
|
3ebe7de3d7 |
@@ -212,6 +212,15 @@
|
||||
"Summary": "菜单排序",
|
||||
"IsRegionOrEndregion": null,
|
||||
"IsValueType": null
|
||||
},
|
||||
{
|
||||
"TypeName": "string",
|
||||
"PropertyName": "StartDefaultPageName",
|
||||
"DefaultValue": "null",
|
||||
"DefaultValueIsConst": true,
|
||||
"Summary": "程序启动时默认页",
|
||||
"IsRegionOrEndregion": null,
|
||||
"IsValueType": null
|
||||
}
|
||||
],
|
||||
"Usings": ""
|
||||
|
||||
@@ -21,7 +21,7 @@ public static partial class AssemblyInfo
|
||||
/// <summary>
|
||||
/// RC 版本号,范围 0~9,只增不减
|
||||
/// </summary>
|
||||
const string ver_for_rc = "5";
|
||||
const string ver_for_rc = "7";
|
||||
|
||||
public const string FileVersion = $"{Version2}.{ver_for_rc}0{ver_for_preview}.0";
|
||||
|
||||
|
||||
@@ -2,11 +2,18 @@ namespace BD.WTTS.UI;
|
||||
|
||||
public static class ControlExtensions
|
||||
{
|
||||
public static void SetViewModel<T>(this Control c) where T : ViewModelBase, new()
|
||||
public static void SetViewModel<T>(this Control c, bool useCache = false) where T : ViewModelBase, new()
|
||||
{
|
||||
if (c.DataContext == null || c.DataContext.GetType() != typeof(T))
|
||||
{
|
||||
c.DataContext = new T();
|
||||
T cx;
|
||||
|
||||
if (useCache)
|
||||
cx = IViewModelManager.Instance.Get<T>();
|
||||
else
|
||||
cx = new T();
|
||||
|
||||
c.DataContext = cx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -113,7 +113,6 @@ public sealed class AvaloniaWindowManagerImpl : IWindowManagerImpl
|
||||
|
||||
if (viewModel != null)
|
||||
{
|
||||
|
||||
if (viewModel is IWindowViewModel window)
|
||||
{
|
||||
window.Close = b => td?.Hide(b ? TaskDialogStandardResult.OK : TaskDialogStandardResult.Close);
|
||||
|
||||
@@ -7,7 +7,7 @@ public partial class HomePage : ReactiveUserControl<HomePageViewModel>
|
||||
public HomePage()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.SetViewModel<HomePageViewModel>();
|
||||
this.SetViewModel<HomePageViewModel>(useCache: true);
|
||||
|
||||
//ShopsScrollViewer.PointerWheelChanged += ShopsScrollViewer_PointerWheelChanged;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,26 @@
|
||||
Text="{Binding Path=Res.Settings_UI, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
|
||||
Theme="{StaticResource SubtitleTextBlockStyle}" />
|
||||
|
||||
<Border IsEnabled="{Binding Path=User, Mode=OneWay, Source={x:Static s:UserService.Current}, Converter={StaticResource IsNullConverter}, ConverterParameter=invert}">
|
||||
<ui:SettingsExpander
|
||||
Description="{Binding Path=Res.Advertisement_NoShow_Tip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
|
||||
Header="{Binding Path=Res.Settings_UI_StartDefaultPage, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
|
||||
IsEnabled="{Binding Path=User.UserType, Mode=OneWay, Source={x:Static s:UserService.Current}, Converter={StaticResource EnumEqualValueConverter}, ConverterParameter={x:Static enum:UserType.Sponsor}}">
|
||||
<ui:SettingsExpander.IconSource>
|
||||
<ui:FontIconSource FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="{StaticResource HeartBroken}" />
|
||||
</ui:SettingsExpander.IconSource>
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ComboBox ItemsSource="{Binding Path=MainWindow2.TabItems, Mode=OneWay, Source={x:Static s:IViewModelManager.Instance}}" SelectedItem="{Binding SelectDefaultPage, Mode=TwoWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate DataType="spp:TabItemViewModel">
|
||||
<TextBlock Text="{Binding Name}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
</Border>
|
||||
|
||||
<Border IsEnabled="{Binding Path=User, Mode=OneWay, Source={x:Static s:UserService.Current}, Converter={StaticResource IsNullConverter}, ConverterParameter=invert}">
|
||||
<ui:SettingsExpander
|
||||
Description="{Binding Path=Res.Advertisement_NoShow_Tip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
|
||||
|
||||
@@ -37,7 +37,36 @@ public sealed partial class MainWindow : ReactiveAppWindow<MainWindowViewModel>
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnOpened(EventArgs e)
|
||||
DateTime lastOpenedTime;
|
||||
|
||||
internal bool SetStartDefaultPageName()
|
||||
{
|
||||
if (NavigationService.Instance.CurrnetPage != null)
|
||||
return false;
|
||||
|
||||
var mw2 = IViewModelManager.Instance.MainWindow2;
|
||||
if (mw2 == null)
|
||||
return false;
|
||||
|
||||
Type? pageType = null;
|
||||
if (!string.IsNullOrEmpty(UISettings.StartDefaultPageName.Value))
|
||||
{
|
||||
var tabItems = mw2?.TabItems;
|
||||
if (tabItems == null)
|
||||
return false;
|
||||
|
||||
var page = tabItems.OfType<MenuTabItemViewModel>()
|
||||
.FirstOrDefault(s => s.Id == UISettings.StartDefaultPageName.Value);
|
||||
if (page != null)
|
||||
{
|
||||
pageType = page.PageType;
|
||||
}
|
||||
}
|
||||
INavigationService.Instance.Navigate(pageType ?? typeof(HomePage));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override async void OnOpened(EventArgs e)
|
||||
{
|
||||
base.OnOpened(e);
|
||||
if (Steamworks.SteamClient.IsValid)
|
||||
@@ -46,24 +75,23 @@ public sealed partial class MainWindow : ReactiveAppWindow<MainWindowViewModel>
|
||||
}
|
||||
if (AppSplashScreen.IsInitialized)
|
||||
{
|
||||
if (NavigationService.Instance.CurrnetPage == null)
|
||||
{
|
||||
INavigationService.Instance.Navigate(typeof(HomePage));
|
||||
}
|
||||
Task2.InBackground(async () =>
|
||||
{
|
||||
IViewModelManager.Instance.Get<HomePageViewModel>().GetServerContent();
|
||||
await AdvertiseService.Current.RefrshAdvertiseAsync();
|
||||
NoticeService.Current.GetNewsAsync();
|
||||
});
|
||||
try // 在主窗口显示时调用此函数检查是否需要显示新版本通知窗口
|
||||
{
|
||||
Ioc.Get_Nullable<IAppUpdateService>()?.OnMainOpenTryShowNewVersionWindow();
|
||||
}
|
||||
catch
|
||||
{
|
||||
SetStartDefaultPageName();
|
||||
}
|
||||
if (lastOpenedTime == default ||
|
||||
(DateTime.Now - lastOpenedTime) > TimeSpan.FromMinutes(30))
|
||||
{
|
||||
lastOpenedTime = DateTime.Now;
|
||||
await IViewModelManager.Instance.Get<HomePageViewModel>().GetServerContent();
|
||||
await AdvertiseService.Current.RefrshAdvertiseAsync();
|
||||
await NoticeService.Current.GetNewsAsync();
|
||||
}
|
||||
try // 在主窗口显示时调用此函数检查是否需要显示新版本通知窗口
|
||||
{
|
||||
Ioc.Get_Nullable<IAppUpdateService>()?.OnMainOpenTryShowNewVersionWindow();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,7 +100,7 @@ public sealed class AppSplashScreen : IApplicationSplashScreen
|
||||
{
|
||||
public static bool IsInitialized = false;
|
||||
|
||||
public WindowViewModel? ViewModel { get; }
|
||||
//public WindowViewModel? ViewModel { get; }
|
||||
|
||||
public string? AppName { get; }
|
||||
|
||||
@@ -162,7 +190,7 @@ public sealed class AppSplashScreen : IApplicationSplashScreen
|
||||
});
|
||||
|
||||
AdvertiseService.Current.InitAdvertise();
|
||||
NoticeService.Current.GetNewsAsync();
|
||||
await NoticeService.Current.GetNewsAsync();
|
||||
|
||||
var mainWindow = App.Instance.MainWindow;
|
||||
mainWindow.ThrowIsNull();
|
||||
@@ -205,8 +233,10 @@ public sealed class AppSplashScreen : IApplicationSplashScreen
|
||||
{
|
||||
mainWindow.DataContext = IViewModelManager.Instance.MainWindow;
|
||||
s.InitSettingSubscribe();
|
||||
|
||||
INavigationService.Instance.Navigate(typeof(HomePage));
|
||||
if (mainWindow is MainWindow mainWindow1)
|
||||
{
|
||||
mainWindow1.SetStartDefaultPageName();
|
||||
}
|
||||
});
|
||||
#if STARTUP_WATCH_TRACE || DEBUG
|
||||
WatchTrace.Record("InitMainWindowViewModel");
|
||||
|
||||
@@ -151,7 +151,7 @@ public sealed class Plugin : PluginBase<Plugin>, IPlugin
|
||||
|
||||
//if (ResourceService.IsChineseSimplified)
|
||||
//{
|
||||
await ProxyService.Current.InitializeAsync();
|
||||
await MainThread2.InvokeOnMainThreadAsync(ProxyService.Current.InitializeAsync);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ public sealed partial class GameAcceleratorService
|
||||
: ReactiveObject
|
||||
#endif
|
||||
{
|
||||
static GameAcceleratorService? mCurrent;
|
||||
static readonly Lazy<GameAcceleratorService> mCurrent = new(() => new(), LazyThreadSafetyMode.ExecutionAndPublication);
|
||||
|
||||
public static GameAcceleratorService Current => mCurrent ??= new();
|
||||
public static GameAcceleratorService Current => mCurrent.Value;
|
||||
|
||||
public SourceCache<XunYouGameViewModel, int> Games { get; }
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ public sealed partial class ProxyService
|
||||
: ReactiveObject, IProxyService
|
||||
#endif
|
||||
{
|
||||
static ProxyService? mCurrent;
|
||||
static readonly Lazy<ProxyService> mCurrent = new(() => new(), LazyThreadSafetyMode.ExecutionAndPublication);
|
||||
|
||||
public static ProxyService Current => mCurrent ??= new();
|
||||
public static ProxyService Current => mCurrent.Value;
|
||||
|
||||
readonly IReverseProxyService reverseProxyService = IReverseProxyService.Constants.Instance;
|
||||
readonly IScriptManager scriptManager = IScriptManager.Instance;
|
||||
@@ -62,6 +62,7 @@ public sealed partial class ProxyService
|
||||
});
|
||||
|
||||
this.WhenAnyValue(v => v.ProxyDomainsList)
|
||||
.ObserveOn(RxApp.MainThreadScheduler)
|
||||
.Subscribe(domain => domain?
|
||||
.ToObservableChangeSet()
|
||||
.AutoRefresh(x => x.ObservableItems)
|
||||
@@ -75,6 +76,7 @@ public sealed partial class ProxyService
|
||||
}));
|
||||
|
||||
this.WhenAnyValue(v => v.ProxyScripts)
|
||||
.ObserveOn(RxApp.MainThreadScheduler)
|
||||
.Subscribe(script => script?
|
||||
.Connect()
|
||||
.AutoRefresh(x => x.Disable)
|
||||
@@ -117,7 +119,7 @@ public sealed partial class ProxyService
|
||||
return null;
|
||||
var data = ProxyDomains.Items
|
||||
.Where(x => x.Items != null)
|
||||
.SelectMany(s => s.Items!.Where(w => w.Checked));
|
||||
.SelectMany(s => s.Items!.Where(w => w.ThreeStateEnable != false));
|
||||
//return data.Concat(data.SelectMany(s => GetProxyDomainsItems(s)));
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -197,6 +197,12 @@ public sealed partial class ProxySettings_ : IProxySettings, ISettings, ISetting
|
||||
[MPKey(22), MP2Key(22), JsonPropertyOrder(22)]
|
||||
public string? CustomDohAddres { get; set; } = IProxySettings.DefaultCustomDohAddres;
|
||||
|
||||
/// <summary>
|
||||
/// 加速页面 Tab 选项卡选中下标
|
||||
/// </summary>
|
||||
[MPKey(23), MP2Key(23), JsonPropertyOrder(23)]
|
||||
public int AcceleratorTabsSelectedIndex { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public static partial class ProxySettings
|
||||
@@ -359,4 +365,9 @@ public static partial class ProxySettings
|
||||
public static SettingsProperty<string, ProxySettings_> CustomDohAddres { get; }
|
||||
= new(DefaultCustomDohAddres);
|
||||
|
||||
/// <summary>
|
||||
/// 加速页面 Tab 选项卡选中下标
|
||||
/// </summary>
|
||||
public static SettingsStructProperty<int, ProxySettings_> AcceleratorTabsSelectedIndex { get; }
|
||||
= new();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@ public partial class AcceleratorPage : PageBase<AcceleratorPageViewModel>
|
||||
public AcceleratorPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.SetViewModel<AcceleratorPageViewModel>();
|
||||
this.SetViewModel<AcceleratorPageViewModel>(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,10 +353,10 @@
|
||||
VerticalAlignment="Top"
|
||||
ItemContainerTheme="{StaticResource TabItemStyle}"
|
||||
Theme="{StaticResource TabStripStyle}">
|
||||
<TabStripItem Name="GameAccTab" Content="游戏加速" />
|
||||
<TabStripItem Content="平台加速 (免费)" IsVisible="{Binding Source={x:Static s:ProxyService.Current}, Path=!ProxyStatus, Mode=OneWay}" />
|
||||
<TabStripItem Content="{x:Static spp:Strings.CommunityFix_FlowStatistics}" IsVisible="{Binding Source={x:Static s:ProxyService.Current}, Path=ProxyStatus, Mode=OneWay}" />
|
||||
<TabStripItem Content="{x:Static spp:Strings.CommunityFix_Services}" IsVisible="{Binding Source={x:Static s:ProxyService.Current}, Path=ProxyStatus, Mode=OneWay}" />
|
||||
<TabStripItem Name="GameAccTab" Content="游戏加速" />
|
||||
</TabStrip>
|
||||
<Carousel
|
||||
Grid.Row="1"
|
||||
@@ -364,66 +364,6 @@
|
||||
Classes="AnimeSlide"
|
||||
SelectedIndex="{Binding #AcceleratorTabs.SelectedIndex}">
|
||||
|
||||
<!-- 游戏加速 -->
|
||||
<Panel x:DataType="spp:GameAcceleratorPageViewModel">
|
||||
<Panel.DataContext>
|
||||
<spp:GameAcceleratorPageViewModel />
|
||||
</Panel.DataContext>
|
||||
<spp:ContentLoader
|
||||
IsLoading="{Binding Source={x:Static s:GameAcceleratorService.Current}, Path=IsLoadingGames, Mode=OneWay}"
|
||||
IsShowNoResultText="{Binding !!!Games.Count}"
|
||||
IsVisible="{Binding Source={x:Static s:GameAcceleratorService.Current}, Path=!CurrentAcceleratorGame.IsAccelerated}"
|
||||
NoResultMessage="{x:Static spp:Strings.GameAccelerator_GamesEmptyTip}}">
|
||||
<ScrollViewer
|
||||
Name="GameScrollViewer"
|
||||
Padding="0,0,10,0"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
IsVisible="{Binding !!Games.Count}"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<ItemsRepeater ItemsSource="{Binding Games}" VerticalCacheLength="50">
|
||||
<ItemsRepeater.Layout>
|
||||
<UniformGridLayout
|
||||
ItemsJustification="Start"
|
||||
ItemsStretch="Uniform"
|
||||
MinColumnSpacing="10"
|
||||
MinItemHeight="180"
|
||||
MinItemWidth="200"
|
||||
MinRowSpacing="10" />
|
||||
</ItemsRepeater.Layout>
|
||||
<ItemsRepeater.ItemTemplate>
|
||||
<DataTemplate DataType="spp:XunYouGameViewModel">
|
||||
<spp:GameAppItem ButtonCommand="{Binding GameAcceleratorCommand, Source={x:Static s:GameAcceleratorService.Current}}" />
|
||||
</DataTemplate>
|
||||
</ItemsRepeater.ItemTemplate>
|
||||
</ItemsRepeater>
|
||||
|
||||
<StackPanel
|
||||
Margin="0,30"
|
||||
HorizontalAlignment="Center"
|
||||
Spacing="10">
|
||||
<spp:Image2
|
||||
Width="100"
|
||||
Height="100"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
RenderOptions.BitmapInterpolationMode="HighQuality"
|
||||
Source="avares://BD.WTTS.Client.Avalonia/UI/Assets/Icons/empty.png"
|
||||
Stretch="UniformToFill" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="已经到底啦! 没有找到想加速的游戏的话可以搜索添加哦~" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</spp:ContentLoader>
|
||||
<spp:GameDetail
|
||||
Margin="0,0,10,0"
|
||||
Content="{Binding Source={x:Static s:GameAcceleratorService.Current}, Path=CurrentAcceleratorGame}"
|
||||
IsVisible="{Binding Source={x:Static s:GameAcceleratorService.Current}, Path=CurrentAcceleratorGame.IsAccelerated}" />
|
||||
</Panel>
|
||||
|
||||
<!-- 平台加速 -->
|
||||
<ScrollViewer
|
||||
Padding="0,0,10,0"
|
||||
@@ -544,6 +484,67 @@
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
|
||||
<!-- 游戏加速 -->
|
||||
<Panel x:DataType="spp:GameAcceleratorPageViewModel">
|
||||
<Panel.DataContext>
|
||||
<spp:GameAcceleratorPageViewModel />
|
||||
</Panel.DataContext>
|
||||
<spp:ContentLoader
|
||||
IsLoading="{Binding Source={x:Static s:GameAcceleratorService.Current}, Path=IsLoadingGames, Mode=OneWay}"
|
||||
IsShowNoResultText="{Binding !!!Games.Count}"
|
||||
IsVisible="{Binding Source={x:Static s:GameAcceleratorService.Current}, Path=!CurrentAcceleratorGame.IsAccelerated}"
|
||||
NoResultMessage="{x:Static spp:Strings.GameAccelerator_GamesEmptyTip}}">
|
||||
<ScrollViewer
|
||||
Name="GameScrollViewer"
|
||||
Padding="0,0,10,0"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
IsVisible="{Binding !!Games.Count}"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<ItemsRepeater ItemsSource="{Binding Games}" VerticalCacheLength="50">
|
||||
<ItemsRepeater.Layout>
|
||||
<UniformGridLayout
|
||||
ItemsJustification="Start"
|
||||
ItemsStretch="Uniform"
|
||||
MinColumnSpacing="10"
|
||||
MinItemHeight="180"
|
||||
MinItemWidth="200"
|
||||
MinRowSpacing="10" />
|
||||
</ItemsRepeater.Layout>
|
||||
<ItemsRepeater.ItemTemplate>
|
||||
<DataTemplate DataType="spp:XunYouGameViewModel">
|
||||
<spp:GameAppItem ButtonCommand="{Binding GameAcceleratorCommand, Source={x:Static s:GameAcceleratorService.Current}}" />
|
||||
</DataTemplate>
|
||||
</ItemsRepeater.ItemTemplate>
|
||||
</ItemsRepeater>
|
||||
|
||||
<StackPanel
|
||||
Margin="0,30"
|
||||
HorizontalAlignment="Center"
|
||||
Spacing="10">
|
||||
<spp:Image2
|
||||
Width="100"
|
||||
Height="100"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
RenderOptions.BitmapInterpolationMode="HighQuality"
|
||||
Source="avares://BD.WTTS.Client.Avalonia/UI/Assets/Icons/empty.png"
|
||||
Stretch="UniformToFill" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="已经到底啦! 没有找到想加速的游戏的话可以搜索添加哦~" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</spp:ContentLoader>
|
||||
<spp:GameDetail
|
||||
Margin="0,0,10,0"
|
||||
Content="{Binding Source={x:Static s:GameAcceleratorService.Current}, Path=CurrentAcceleratorGame}"
|
||||
IsVisible="{Binding Source={x:Static s:GameAcceleratorService.Current}, Path=CurrentAcceleratorGame.IsAccelerated}" />
|
||||
</Panel>
|
||||
|
||||
<!--<TabItem Header="加速日志">
|
||||
|
||||
</TabItem>-->
|
||||
@@ -600,12 +601,21 @@
|
||||
</AutoCompleteBox.ItemTemplate>
|
||||
</AutoCompleteBox>
|
||||
|
||||
<!--<StackPanel
|
||||
<StackPanel
|
||||
Grid.ColumnSpan="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsVisible="{Binding Source={x:Static s:ProxyService.Current}, Path=ProxyStatus, Mode=OneWay}"
|
||||
Spacing="8">
|
||||
<StackPanel.IsVisible>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.And}">
|
||||
<CompiledBinding
|
||||
Mode="OneWay"
|
||||
Path="ProxyStatus"
|
||||
Source="{x:Static s:ProxyService.Current}" />
|
||||
<Binding Path="!#GameAccTab.IsSelected" />
|
||||
</MultiBinding>
|
||||
</StackPanel.IsVisible>
|
||||
<StackPanel.Styles>
|
||||
<Style Selector="TextBlock">
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
@@ -620,7 +630,7 @@
|
||||
<Run Text="{x:Static spp:Strings.CommunityFix_EnableScriptService}" />
|
||||
<Run Text="{Binding Source={x:Static s:ProxyService.Current}, Path=IsEnableScript, Converter={StaticResource StringFormatConverter}}" />
|
||||
</TextBlock>
|
||||
</StackPanel>-->
|
||||
</StackPanel>
|
||||
|
||||
<spp:AdControl
|
||||
Grid.Row="1"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Interactivity;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace BD.WTTS.UI.Views.Pages;
|
||||
@@ -12,6 +13,8 @@ public partial class AcceleratorPage2 : PageBase<AcceleratorPageViewModel>
|
||||
{
|
||||
readonly Dictionary<string, string[]> dictPinYinArray = new();
|
||||
|
||||
List<int> acceleratorTabsSelectedIndexs = new();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AcceleratorPage2"/> class.
|
||||
/// </summary>
|
||||
@@ -21,7 +24,27 @@ public partial class AcceleratorPage2 : PageBase<AcceleratorPageViewModel>
|
||||
var mode = ProxySettings.ProxyMode.Value;
|
||||
|
||||
InitializeComponent();
|
||||
this.SetViewModel<AcceleratorPageViewModel>();
|
||||
this.SetViewModel<AcceleratorPageViewModel>(true);
|
||||
|
||||
for (int i = 0; i < AcceleratorTabs.Items.Count; i++)
|
||||
{
|
||||
var item = AcceleratorTabs.Items[i];
|
||||
if (item is Visual visual && visual.IsVisible)
|
||||
{
|
||||
acceleratorTabsSelectedIndexs.Add(i);
|
||||
}
|
||||
}
|
||||
var itemCount = AcceleratorTabs.ItemCount;
|
||||
var acceleratorTabsSelectedIndex = ProxySettings.AcceleratorTabsSelectedIndex.Value;
|
||||
if (acceleratorTabsSelectedIndex >= 0 && acceleratorTabsSelectedIndex < itemCount)
|
||||
{
|
||||
if (acceleratorTabsSelectedIndexs.Contains(acceleratorTabsSelectedIndex))
|
||||
{
|
||||
AcceleratorTabs.SelectedIndex = acceleratorTabsSelectedIndex;
|
||||
}
|
||||
}
|
||||
|
||||
AcceleratorTabs.SelectionChanged += AcceleratorTabs_SelectionChanged;
|
||||
|
||||
//重置回保存的值
|
||||
ProxySettings.ProxyMode.Value = mode;
|
||||
@@ -31,7 +54,7 @@ public partial class AcceleratorPage2 : PageBase<AcceleratorPageViewModel>
|
||||
ProxyService.Current.WhenValueChanged(x => x.ProxyStatus, false)
|
||||
.Subscribe(x =>
|
||||
{
|
||||
AcceleratorTabs.SelectedIndex = x ? 2 : 1;
|
||||
AcceleratorTabs.SelectedIndex = x ? 1 : 0;
|
||||
}));
|
||||
|
||||
if (XunYouSDK.IsSupported)
|
||||
@@ -48,15 +71,31 @@ public partial class AcceleratorPage2 : PageBase<AcceleratorPageViewModel>
|
||||
else
|
||||
{
|
||||
GameAccTab.IsVisible = false;
|
||||
AcceleratorTabs.SelectedIndex = 1;
|
||||
AcceleratorTabs.SelectedIndex = 0;
|
||||
}
|
||||
});
|
||||
|
||||
SearchGameBox.DropDownClosed += SearchGameBox_DropDownClosed;
|
||||
SearchGameBox.TextSelector = (_, _) => null;
|
||||
SearchGameBox.TextSelector = (_, _) => null!;
|
||||
SearchGameBox.TextFilter = GameContains;
|
||||
}
|
||||
|
||||
void AcceleratorTabs_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
var value = AcceleratorTabs.SelectedIndex;
|
||||
if (acceleratorTabsSelectedIndexs.Contains(value))
|
||||
{
|
||||
ProxySettings.AcceleratorTabsSelectedIndex.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnLoaded(RoutedEventArgs e)
|
||||
{
|
||||
base.OnLoaded(e);
|
||||
if (AcceleratorTabs.SelectedIndex == default && ProxyService.Current.ProxyStatus)
|
||||
AcceleratorTabs.SelectedIndex = 1;
|
||||
}
|
||||
|
||||
private void SearchGameBox_DropDownClosed(object? sender, EventArgs e)
|
||||
{
|
||||
if (SearchGameBox.SelectedItem is XunYouGame xunYouGame && xunYouGame is not null)
|
||||
@@ -98,17 +137,17 @@ public partial class AcceleratorPage2 : PageBase<AcceleratorPageViewModel>
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnDetachedFromVisualTree(e);
|
||||
//protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
//{
|
||||
// base.OnDetachedFromVisualTree(e);
|
||||
|
||||
//try
|
||||
//{
|
||||
// ISettingsLoadService.Current.ForceSave<GameAcceleratorSettingsModel>();
|
||||
//}
|
||||
//catch (Exception ex)
|
||||
//{
|
||||
// Log.Error(nameof(AcceleratorPage), ex, "ForceSave fail.");
|
||||
//}
|
||||
}
|
||||
// //try
|
||||
// //{
|
||||
// // ISettingsLoadService.Current.ForceSave<GameAcceleratorSettingsModel>();
|
||||
// //}
|
||||
// //catch (Exception ex)
|
||||
// //{
|
||||
// // Log.Error(nameof(AcceleratorPage), ex, "ForceSave fail.");
|
||||
// //}
|
||||
//}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@ namespace BD.WTTS.Services;
|
||||
|
||||
public sealed class ASFService : ReactiveObject
|
||||
{
|
||||
static ASFService? mCurrent;
|
||||
static readonly Lazy<ASFService> mCurrent = new(() => new(), LazyThreadSafetyMode.ExecutionAndPublication);
|
||||
|
||||
public static ASFService Current => mCurrent ??= new();
|
||||
public static ASFService Current => mCurrent.Value;
|
||||
|
||||
readonly IArchiSteamFarmService archiSteamFarmService = IArchiSteamFarmService.Instance;
|
||||
|
||||
|
||||
+50
-16
@@ -13,7 +13,7 @@ public sealed class BasicPlatformSwitcher : IPlatformSwitcher
|
||||
this.platformService = platformService;
|
||||
}
|
||||
|
||||
bool BasicCopyInAccount(string accId, PlatformAccount platform)
|
||||
async ValueTask<bool> BasicCopyInAccount(string accId, PlatformAccount platform)
|
||||
{
|
||||
var allIds = JTokenHelper.ReadDict(platform.IdsJsonPath);
|
||||
var accName = allIds[accId];
|
||||
@@ -63,10 +63,17 @@ public sealed class BasicPlatformSwitcher : IPlatformSwitcher
|
||||
|
||||
var regValue = regJson[accFile] ?? "";
|
||||
|
||||
if (!Registry2.SetRegistryKey(accFile[4..], regValue)) // Remove "REG:" and read data
|
||||
if (DesktopBridge.IsRunningAsUwp)
|
||||
{
|
||||
Toast.Show(ToastIcon.Error, AppResources.Error_WriteRegistryFailed);
|
||||
return false;
|
||||
await SetEpicCurrentUserAsync(regValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Registry2.SetRegistryKey(accFile[4..], regValue)) // Remove "REG:" and read data
|
||||
{
|
||||
Toast.Show(ToastIcon.Error, AppResources.Error_WriteRegistryFailed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -131,7 +138,7 @@ public sealed class BasicPlatformSwitcher : IPlatformSwitcher
|
||||
// Copy saved files in
|
||||
if (!string.IsNullOrEmpty(account?.AccountId))
|
||||
{
|
||||
if (!BasicCopyInAccount(account.AccountId, platform)) return;
|
||||
if (!await BasicCopyInAccount(account.AccountId, platform)) return;
|
||||
//Globals.AddTrayUser(platform.SafeName, $"+{platform.PrimaryId}:" + accId, accName, BasicSettings.TrayAccNumber); // Add to Tray list, using first Identifier
|
||||
}
|
||||
|
||||
@@ -156,17 +163,21 @@ public sealed class BasicPlatformSwitcher : IPlatformSwitcher
|
||||
//}
|
||||
}
|
||||
|
||||
public ValueTask<bool> ClearCurrentLoginUser(PlatformAccount platform)
|
||||
public async ValueTask<bool> ClearCurrentLoginUser(PlatformAccount platform)
|
||||
{
|
||||
var result = ClearCurrentLoginUserCore(platform);
|
||||
return ValueTask.FromResult(result);
|
||||
var result = await ClearCurrentLoginUserCore(platform);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ClearCurrentLoginUserCore(PlatformAccount platform)
|
||||
async ValueTask<bool> ClearCurrentLoginUserCore(PlatformAccount platform)
|
||||
{
|
||||
// Foreach file/folder/reg in Platform.PathListToClear
|
||||
if (platform.ClearPaths.Any_Nullable(accFile => !DeleteFileOrFolder(accFile, platform)))
|
||||
return false;
|
||||
|
||||
foreach (var accFile in platform.ClearPaths!)
|
||||
{
|
||||
if (!await DeleteFileOrFolder(accFile, platform))
|
||||
return false;
|
||||
}
|
||||
|
||||
var uniqueIdFile = IOPath.ExpandEnvironmentVariables(platform.UniqueIdPath, platform.FolderPath);
|
||||
|
||||
@@ -185,7 +196,22 @@ public sealed class BasicPlatformSwitcher : IPlatformSwitcher
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeleteFileOrFolder(string accFile, PlatformAccount platform)
|
||||
async ValueTask SetEpicCurrentUserAsync(string userName)
|
||||
{
|
||||
#if WINDOWS
|
||||
string contents =
|
||||
$"""
|
||||
Windows Registry Editor Version 5.00
|
||||
; {AssemblyInfo.Trademark} BD.WTTS.Services.Implementation.BasicPlatformSwitcher.SetEpicCurrentUserAsync
|
||||
[HKEY_CURRENT_USER\Software\Epic Games\Unreal Engine\Identifiers]
|
||||
"AccountId"="{userName}"
|
||||
""";
|
||||
var regpath = IOPath.GetCacheFilePath(WindowsPlatformServiceImpl.CacheTempDirName, "SwitchEpicUser", FileEx.Reg);
|
||||
await WindowsPlatformServiceImpl.StartProcessRegeditAsync(regpath, contents);
|
||||
#endif
|
||||
}
|
||||
|
||||
async ValueTask<bool> DeleteFileOrFolder(string accFile, PlatformAccount platform)
|
||||
{
|
||||
// The "file" is a registry key
|
||||
#if WINDOWS
|
||||
@@ -198,7 +224,14 @@ public sealed class BasicPlatformSwitcher : IPlatformSwitcher
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Registry2.SetRegistryKey(accFile[4..])) return true;
|
||||
if (DesktopBridge.IsRunningAsUwp)
|
||||
{
|
||||
await SetEpicCurrentUserAsync(string.Empty);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (Registry2.SetRegistryKey(accFile[4..])) return true;
|
||||
|
||||
}
|
||||
Toast.Show(ToastIcon.Error, AppResources.Error_WriteRegistryFailed);
|
||||
return false;
|
||||
@@ -210,9 +243,10 @@ public sealed class BasicPlatformSwitcher : IPlatformSwitcher
|
||||
{
|
||||
if (accFile.StartsWith("JSON_SELECT"))
|
||||
{
|
||||
var path = accFile.Split("::")[1];
|
||||
var path = IOPath.ExpandEnvironmentVariables(accFile.Split("::")[1]);
|
||||
var selector = accFile.Split("::")[2];
|
||||
JTokenHelper.ReplaceVarInJsonFile(path, selector, "");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,7 +513,7 @@ public sealed class BasicPlatformSwitcher : IPlatformSwitcher
|
||||
// Handle special args in username
|
||||
//var hadSpecialProperties = ProcessSpecialAccName(specialString, accName, uniqueId);
|
||||
|
||||
var regJson = platform.UniqueIdPath.StartsWith("REG:") ? JTokenHelper.ReadRegJson(platform.RegJsonPath(name)) : new Dictionary<string, string>();
|
||||
var regJson = platform.UniqueIdPath.StartsWith("REG:") ? JTokenHelper.ReadDict(platform.RegJsonPath(name)) : new Dictionary<string, string>();
|
||||
|
||||
foreach (var (accFile, savedFile) in platform.LoginFiles)
|
||||
{
|
||||
@@ -532,7 +566,7 @@ public sealed class BasicPlatformSwitcher : IPlatformSwitcher
|
||||
var originalValueString = (string)originalValue;
|
||||
originalValueString = IOPath.CleanPathIlegalCharacter(firstResult ? originalValueString.Split(delimiter).First() : originalValueString.Split(delimiter).Last());
|
||||
|
||||
if (!Directory.Exists(localCachePath)) Directory.CreateDirectory(localCachePath);
|
||||
IOPath.DirCreateByNotExists(localCachePath);
|
||||
JTokenHelper.SaveJsonFile(Path.Combine(localCachePath, savedFile), originalValueString);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -217,6 +217,13 @@
|
||||
MoreFlyout="{StaticResource SharedMenuFlyout}"
|
||||
Status="{Binding Path=Res.UserChange_RecentLogin, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
|
||||
Tags="{Binding AliasName}">
|
||||
<ToolTip.Tip>
|
||||
<TextBlock>
|
||||
<Run FontSize="16" Text="{Binding DisplayName}" />
|
||||
<LineBreak />
|
||||
<Run Text="{Binding AliasName}" />
|
||||
</TextBlock>
|
||||
</ToolTip.Tip>
|
||||
<spp:AppItem.Status>
|
||||
<Border Classes="Status" IsVisible="{Binding MostRecent}">
|
||||
<TextBlock Text="{Binding Path=Res.UserChange_RecentLogin, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
|
||||
|
||||
@@ -11,7 +11,7 @@ public partial class GameAccountPage : PageBase<GameAccountPageViewModel>
|
||||
public GameAccountPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.SetViewModel<GameAccountPageViewModel>();
|
||||
this.SetViewModel<GameAccountPageViewModel>(true);
|
||||
//DataContext ??= new GameAccountPageViewModel();
|
||||
|
||||
//this.WhenActivated(disposable =>
|
||||
|
||||
@@ -18,7 +18,7 @@ public sealed class IdleAppsPageViewModel : ViewModelBase
|
||||
|
||||
public IdleAppsPageViewModel()
|
||||
{
|
||||
CompositeDisposable.Add(GameLibrarySettings.AFKAppList.Subscribe(_ => Refresh_Click()));
|
||||
CompositeDisposable.Add(GameLibrarySettings.AFKAppList.Subscribe(_ => Refresh_Click(), false));
|
||||
|
||||
RunStopBtnCommand = ReactiveCommand.Create<SteamApp>(RunStopBtn_Click);
|
||||
DeleteButtonCommand = ReactiveCommand.Create<SteamApp>(DeleteButton_Click);
|
||||
@@ -206,12 +206,18 @@ public sealed class IdleAppsPageViewModel : ViewModelBase
|
||||
}
|
||||
}
|
||||
|
||||
public void Refresh_Click()
|
||||
public async void Refresh_Click()
|
||||
{
|
||||
var list = new ObservableCollection<SteamApp>();
|
||||
if (GameLibrarySettings.AFKAppList.Any_Nullable())
|
||||
{
|
||||
int runOtherAppCount = 0;
|
||||
|
||||
while (SteamConnectService.Current.IsLoadingGameList)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
foreach (var item in GameLibrarySettings.AFKAppList.Value!)
|
||||
{
|
||||
var appInfo = SteamConnectService.Current.SteamApps.Items.FirstOrDefault(x => x.AppId == item.Key);
|
||||
@@ -224,7 +230,7 @@ public sealed class IdleAppsPageViewModel : ViewModelBase
|
||||
if (!runState.Process.HasExited)
|
||||
{
|
||||
appInfo.Process = runState.Process;
|
||||
appInfo.Process.Exited += (object? _, EventArgs _) =>
|
||||
appInfo.Process.Exited += (_, _) =>
|
||||
{
|
||||
SteamConnectService.Current.RuningSteamApps.TryRemove(appInfo.AppId, out runState);
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "run --rids win-x64 --hsm-sign --stm-upload",
|
||||
"commandLineArgs_release": "run --rids win-x64 --hsm-sign --stm-upload",
|
||||
"commandLineArgs_nsis": "nsis --rids win-x64 --hsm-sign --t 240306_1151276715468",
|
||||
"commandLineArgs_nsis": "nsis --rids win-x64 --hsm-sign --t 240314_1523131679333",
|
||||
"commandLineArgs_debug": "run --rids win-x64 --hsm-sign --stm-upload --debug",
|
||||
"commandLineArgs_GenerateBridgeContentXml": "csproj --rids win-x64"
|
||||
}
|
||||
|
||||
@@ -6486,6 +6486,15 @@ namespace BD.WTTS.Client.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 启动时默认打开页面 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string Settings_UI_StartDefaultPage {
|
||||
get {
|
||||
return ResourceManager.GetString("Settings_UI_StartDefaultPage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 跟随系统 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -2927,5 +2927,8 @@
|
||||
</data>
|
||||
<data name="GameAccelerator_ChangeArea" xml:space="preserve">
|
||||
<value>切换加速区服</value>
|
||||
</data>
|
||||
<data name="Settings_UI_StartDefaultPage" xml:space="preserve">
|
||||
<value>启动时默认打开页面</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -6,9 +6,9 @@ namespace BD.WTTS.Services;
|
||||
/// </summary>
|
||||
public sealed class AdvertiseService : ReactiveObject
|
||||
{
|
||||
static AdvertiseService? mCurrent;
|
||||
static readonly Lazy<AdvertiseService> mCurrent = new(() => new(), LazyThreadSafetyMode.ExecutionAndPublication);
|
||||
|
||||
public static AdvertiseService Current => mCurrent ??= new();
|
||||
public static AdvertiseService Current => mCurrent.Value;
|
||||
|
||||
[Reactive]
|
||||
public ObservableCollection<AdvertisementDTO>? HorizontalBannerAdvertisements { get; set; }
|
||||
|
||||
@@ -6,9 +6,9 @@ namespace BD.WTTS.Services;
|
||||
|
||||
public sealed class UserService : ReactiveObject
|
||||
{
|
||||
static UserService? mCurrent;
|
||||
static readonly Lazy<UserService> mCurrent = new(() => new(), LazyThreadSafetyMode.ExecutionAndPublication);
|
||||
|
||||
public static UserService Current => mCurrent ??= new();
|
||||
public static UserService Current => mCurrent.Value;
|
||||
|
||||
readonly IUserManager userManager = IUserManager.Instance;
|
||||
readonly IMicroServiceClient csc = IMicroServiceClient.Instance;
|
||||
@@ -179,6 +179,12 @@ public sealed class UserService : ReactiveObject
|
||||
|
||||
public async Task RefreshUserAsync(IdentityUserInfoDTO? user, bool refreshCurrentUser = true)
|
||||
{
|
||||
#if DEBUG
|
||||
if (user != null)
|
||||
{
|
||||
user.UserType = UserType.Sponsor;
|
||||
}
|
||||
#endif
|
||||
User = user;
|
||||
this.RaisePropertyChanged(nameof(IsAuthenticated));
|
||||
|
||||
@@ -231,7 +237,7 @@ public sealed class UserService : ReactiveObject
|
||||
}
|
||||
else
|
||||
{
|
||||
Browser2.Open(string.Format(Constants.Urls.OfficialWebsite_Fast_Login_, token.AccessToken, HttpUtility.UrlEncode(token.ExpiresIn.ToString()), HttpUtility.UrlEncode(url)));
|
||||
Browser2.Open(string.Format(Constants.Urls.OfficialWebsite_Fast_Login_, token.AccessToken, HttpUtility.UrlEncode(token.ExpiresIn.ToString("R")), HttpUtility.UrlEncode(url)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@ namespace BD.WTTS.Services;
|
||||
|
||||
public sealed class NoticeService : ReactiveObject
|
||||
{
|
||||
static NoticeService? mCurrent;
|
||||
static readonly Lazy<NoticeService> mCurrent = new(() => new(), LazyThreadSafetyMode.ExecutionAndPublication);
|
||||
|
||||
public static NoticeService Current => mCurrent ??= new();
|
||||
public static NoticeService Current => mCurrent.Value;
|
||||
|
||||
//readonly INotificationRepository notificationRepo = Ioc.Get<INotificationRepository>();
|
||||
|
||||
@@ -30,7 +30,7 @@ public sealed class NoticeService : ReactiveObject
|
||||
//NoticeTypes = new();
|
||||
}
|
||||
|
||||
public async void GetNewsAsync()
|
||||
public async Task GetNewsAsync()
|
||||
{
|
||||
var client = Instance.Message;
|
||||
var result = await client.GetMessage(IApplication.ClientPlatform, OfficialMessageType.News);
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace BD.WTTS.Services;
|
||||
|
||||
public sealed class ResourceService : ReactiveObject
|
||||
{
|
||||
static ResourceService? mCurrent;
|
||||
static readonly Lazy<ResourceService> mCurrent = new(() => new(), LazyThreadSafetyMode.ExecutionAndPublication);
|
||||
|
||||
public static ResourceService Current => mCurrent ??= new();
|
||||
public static ResourceService Current => mCurrent.Value;
|
||||
|
||||
public static readonly IReadOnlyDictionary<string, string> Languages;
|
||||
public static readonly IReadOnlyDictionary<string, string> SteamLanguages;
|
||||
|
||||
@@ -17,7 +17,9 @@ public sealed class SteamConnectService
|
||||
|
||||
public const int SteamAFKMaxCount = 32;
|
||||
|
||||
public static SteamConnectService Current { get; } = new();
|
||||
static readonly Lazy<SteamConnectService> mCurrent = new(() => new(), LazyThreadSafetyMode.ExecutionAndPublication);
|
||||
|
||||
public static SteamConnectService Current => mCurrent.Value;
|
||||
|
||||
readonly ISteamworksLocalApiService swLocalService = ISteamworksLocalApiService.Instance;
|
||||
readonly ISteamService stmService = ISteamService.Instance;
|
||||
@@ -516,6 +518,7 @@ public sealed class SteamConnectService
|
||||
{
|
||||
return;
|
||||
}
|
||||
SteamUsers.Clear();
|
||||
SteamUsers.AddOrUpdate(list);
|
||||
|
||||
#region 加载备注信息和 JumpList
|
||||
|
||||
@@ -4,8 +4,8 @@ namespace BD.WTTS.Services.Implementation;
|
||||
internal sealed class ViewModelManager : ReactiveObject, IViewModelManager
|
||||
{
|
||||
bool disposedValue;
|
||||
Dictionary<Type, byte[]> viewModelDataCaches = new();
|
||||
Dictionary<Type, ViewModelBase> viewModelCaches = new();
|
||||
ConcurrentDictionary<Type, byte[]> viewModelDataCaches = new();
|
||||
ConcurrentDictionary<Type, ViewModelBase> viewModelCaches = new();
|
||||
|
||||
/// <summary>
|
||||
/// 获取为当前主窗口提供的数据
|
||||
@@ -69,7 +69,8 @@ internal sealed class ViewModelManager : ReactiveObject, IViewModelManager
|
||||
var vmType = viewModel.GetType();
|
||||
var value = Serializable.SMP2(vmType, viewModel);
|
||||
viewModelDataCaches[vmType] = value;
|
||||
viewModelCaches.Remove(vmType);
|
||||
viewModelDataCaches[vmType] = value;
|
||||
viewModelCaches.TryRemove(vmType, out var _);
|
||||
}
|
||||
|
||||
void Dispose(bool disposing)
|
||||
|
||||
@@ -7,9 +7,9 @@ namespace BD.WTTS.Services;
|
||||
[Obsolete("不再使用常驻通知")]
|
||||
public sealed class ToastService : ReactiveObject
|
||||
{
|
||||
static ToastService? mCurrent;
|
||||
static readonly Lazy<ToastService> mCurrent = new(() => new(), LazyThreadSafetyMode.ExecutionAndPublication);
|
||||
|
||||
public static ToastService Current => mCurrent ??= new();
|
||||
public static ToastService Current => mCurrent.Value;
|
||||
|
||||
static readonly Lazy<bool> mIsSupported = new(() => Ioc.Get<IToast>() is ToastImpl);
|
||||
|
||||
|
||||
@@ -118,6 +118,11 @@ public partial interface IUISettings
|
||||
/// </summary>
|
||||
HashSet<string>? SortMenuTabs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 程序启动时默认页
|
||||
/// </summary>
|
||||
string? StartDefaultPageName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主题的默认值
|
||||
/// </summary>
|
||||
@@ -208,4 +213,9 @@ public partial interface IUISettings
|
||||
/// </summary>
|
||||
const HashSet<string>? DefaultSortMenuTabs = null;
|
||||
|
||||
/// <summary>
|
||||
/// 程序启动时默认页的默认值
|
||||
/// </summary>
|
||||
const string? DefaultStartDefaultPageName = null;
|
||||
|
||||
}
|
||||
|
||||
@@ -159,6 +159,12 @@ public sealed partial class UISettings_ : IUISettings, ISettings, ISettings<UISe
|
||||
[MPKey(17), MP2Key(17), JsonPropertyOrder(17)]
|
||||
public HashSet<string>? SortMenuTabs { get; set; } = IUISettings.DefaultSortMenuTabs;
|
||||
|
||||
/// <summary>
|
||||
/// 程序启动时默认页
|
||||
/// </summary>
|
||||
[MPKey(18), MP2Key(18), JsonPropertyOrder(18)]
|
||||
public string? StartDefaultPageName { get; set; } = IUISettings.DefaultStartDefaultPageName;
|
||||
|
||||
}
|
||||
|
||||
public static partial class UISettings
|
||||
@@ -279,4 +285,10 @@ public static partial class UISettings
|
||||
public static SettingsProperty<string, HashSet<string>, UISettings_> SortMenuTabs { get; }
|
||||
= new(DefaultSortMenuTabs);
|
||||
|
||||
/// <summary>
|
||||
/// 程序启动时默认页
|
||||
/// </summary>
|
||||
public static SettingsProperty<string, UISettings_> StartDefaultPageName { get; }
|
||||
= new(DefaultStartDefaultPageName);
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ public interface IWindowViewModel : IPageViewModel
|
||||
/// <summary>
|
||||
/// 关闭当前 ViewModel 绑定的窗口
|
||||
/// </summary>
|
||||
Action<bool> Close { get; set; }
|
||||
Action<bool>? Close { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 显示当前 ViewModel 绑定的窗口
|
||||
|
||||
@@ -41,13 +41,13 @@ public sealed class HomePageViewModel : TabItemViewModel
|
||||
//GetServerContent();
|
||||
}
|
||||
|
||||
public override void Activation()
|
||||
{
|
||||
base.Activation();
|
||||
GetServerContent();
|
||||
}
|
||||
//public override void Activation()
|
||||
//{
|
||||
// base.Activation();
|
||||
// GetServerContent();
|
||||
//}
|
||||
|
||||
public async void GetServerContent()
|
||||
public async Task GetServerContent()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -33,6 +33,31 @@ public sealed partial class SettingsPageViewModel : TabItemViewModel
|
||||
set => this.RaiseAndSetIfChanged(ref _SelectFont, value);
|
||||
}
|
||||
|
||||
MenuTabItemViewModel _SelectDefaultPage =
|
||||
IViewModelManager.Instance.MainWindow2.TabItems.OfType<MenuTabItemViewModel>().FirstOrDefault(
|
||||
s =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(UISettings.StartDefaultPageName.Value))
|
||||
{
|
||||
return s.Id == "Welcome";
|
||||
}
|
||||
return s.Id == UISettings.StartDefaultPageName.Value;
|
||||
});
|
||||
|
||||
[IgnoreDataMember, MPIgnore, MP2Ignore, N_JsonIgnore, S_JsonIgnore]
|
||||
public MenuTabItemViewModel SelectDefaultPage
|
||||
{
|
||||
get => _SelectDefaultPage;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _SelectDefaultPage, value);
|
||||
if (!string.IsNullOrEmpty(value?.Id))
|
||||
{
|
||||
UISettings.StartDefaultPageName.Value = value.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember, MPIgnore, MP2Ignore, N_JsonIgnore, S_JsonIgnore]
|
||||
public ICommand? SelectImage_Click { get; }
|
||||
|
||||
|
||||
@@ -15,6 +15,13 @@ static partial class VisualStudioAppCenterSDK
|
||||
{
|
||||
internal static void Init()
|
||||
{
|
||||
if (DateTime.UtcNow >= new DateTime(2025, 3, 31, default, default, default, DateTimeKind.Utc))
|
||||
{
|
||||
// Visual Studio App Center is scheduled for retirement on March 31, 2025.
|
||||
// https://learn.microsoft.com/en-us/appcenter/retirement
|
||||
return;
|
||||
}
|
||||
|
||||
var appSecret = AppSecret;
|
||||
if (string.IsNullOrWhiteSpace(appSecret))
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user