Compare commits

...
Author SHA1 Message Date
Mossimo ce222da8ef fix 2022-04-02 12:35:19 +08:00
Mossimo 5388425f1d 2022-04-01 16:48 2022-04-01 16:48:06 +08:00
Mossimo 56687596c6 2022-04-01 16:36 2022-04-01 16:39:10 +08:00
Mossimo edf5acc455 封面图更新,点击打开 详情 2022-04-01 16:33:43 +08:00
Mossimo 517a259e4e move to debug 2022-03-23 17:11:29 +08:00
Mossimo f15d005771 按钮 , 文本多语言 2022-03-23 17:10:02 +08:00
Mossimo 9f9478f0e5 修改Tab名 2022-03-23 16:52:40 +08:00
Mossimo 3822a646de hb dev 2022-03-23 16:35:13 +08:00
Mossimo 35d4bc83e6 账户历史记录窗口 2022-03-23 16:30:06 +08:00
Mossimo c5eae6a980 鼠标移动到头像上遮罩层 2022-03-02 18:42:18 +08:00
Mossimo 8e50c843f0 完善个人中心 2022-03-01 22:53:04 +08:00
Aigio Liu 8a4fcaa539 fix ChangeLanguageCore 2022-03-01 22:53:04 +08:00
RMBGAME 15fc32dd46 proxy UA edit 2022-03-01 22:53:04 +08:00
RMBGAME fb9cb68957 fix UI error 2022-03-01 22:53:04 +08:00
Aigio Liu 91152a55fc linux archive format changed from 7z to tar.zst 2022-03-01 22:53:04 +08:00
Aigio Liu 8aebbe2b0a Update nuget Packages & Add AccelerateProjectDTO.UserAgent & fix Android AutoRun 2022-03-01 22:53:03 +08:00
Aigio Liu ecf085c7c4 Desktop ASF Config Page UI 2022-03-01 22:53:03 +08:00
RMBGAME 13d6b6213f New Desktop About UI Style 2022-03-01 22:53:03 +08:00
Aigio Liu 9c49c82db9 fix Android FilePicker2 PermissionException & new Android ASF Config UI & #1025 2022-03-01 22:53:03 +08:00
Aigio Liu 428b841712 Android DonateActivity 2022-03-01 22:53:03 +08:00
Aigio Liu 716210b089 Android DonateActivity & ASF Update v5.2.2.5 2022-03-01 22:53:03 +08:00
dependabot[bot] 2b2ccdd3b1 Bump Z.EntityFramework.Plus.EFCore from 6.13.9 to 6.13.10
Bumps [Z.EntityFramework.Plus.EFCore](https://github.com/zzzprojects/EntityFramework-Plus) from 6.13.9 to 6.13.10.
- [Release notes](https://github.com/zzzprojects/EntityFramework-Plus/releases)
- [Commits](https://github.com/zzzprojects/EntityFramework-Plus/commits)

---
updated-dependencies:
- dependency-name: Z.EntityFramework.Plus.EFCore
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-01 22:53:02 +08:00
dependabot[bot] 8d0e857df5 Bump Microsoft.NET.Test.Sdk from 17.0.0 to 17.1.0
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.0.0 to 17.1.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.0.0...v17.1.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-01 22:53:01 +08:00
RMBGAME 978f0d8f51 Update .Net SDK 6.0.200 2022-03-01 22:53:01 +08:00
RMBGAME b4b0303426 修复部分UI错误 2022-03-01 22:53:01 +08:00
RMBGAME f4c928c46c 改进移除令牌提示 2022-03-01 22:53:01 +08:00
Aigio Liu 34a25ceabe Android Donate Page UI 2022-03-01 22:53:01 +08:00
Aigio Liu 90a5f30802 Android UserBasicInfoFragment UID Copy 2022-03-01 22:53:00 +08:00
Mossimo 3f113c96aa change color 2022-03-01 22:53:00 +08:00
Aigio Liu 7ce53f11aa Add AccelerateProjectDTO.UserAgent 2022-02-24 13:56:28 +08:00
Aigio Liu 90c0513493 Add UserAgent 2022-02-24 12:36:28 +08:00
Mossimo 2a42ce2caf a 2022-02-22 18:07:04 +08:00
Mossimo c1f6781fa9 AccountPage TryAdd 2022-02-19 15:08:04 +08:00
Mossimo 467c0f4975 update 2022-02-14 21:27:42 +08:00
Mossimo e7d8e636d2 Accountpage 2022-02-06 12:41:34 +08:00
Mossimo 3855291c68 save 2022-01-11 18:08:36 +08:00
Mossimo d0d1baac29 通知公告(OK) 样式待微调 2021-12-30 23:28:34 +08:00
Mossimo 1c50fdf4af save 2021-12-27 23:50:41 +08:00
Mossimo c1b889f887 mvvm 2021-12-27 23:23:36 +08:00
Mossimo fa84523799 尝试修复GM刷新排序 2021-12-21 15:53:18 +08:00
Mossimo 160f3d53bb 跳过 cloudflare 浏览器检测 实现操作太复杂放弃,cookie 跨域无法解决,用户自己填写Cookie 操作麻烦 2021-12-16 16:56:39 +08:00
Mossimo ed77ad8d2d add window 2021-12-14 20:39:39 +08:00
38 changed files with 1166 additions and 29 deletions
+2 -2
View File
@@ -152,7 +152,7 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: '[${{ matrix.configuration }}]${{ env.ProjectName }}_linux_x64_${{ env.GITHUB_SHA_SHORT }}'
path: src\ST.Client.Desktop.Avalonia.App\bin\${{ matrix.configuration }}\Publish\${{ env.ProjectName }}_linux_x64_${{ env.GITHUB_SHA_SHORT }}.7z
path: src\ST.Client.Desktop.Avalonia.App\bin\${{ matrix.configuration }}\Publish\${{ env.ProjectName }}_linux_x64_${{ env.GITHUB_SHA_SHORT }}.tar.zst
- name: Upload linux-arm64 App ${{ matrix.configuration }}
continue-on-error: true
@@ -160,4 +160,4 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: '[${{ matrix.configuration }}]${{ env.ProjectName }}_linux_arm64_${{ env.GITHUB_SHA_SHORT }}'
path: src\ST.Client.Desktop.Avalonia.App\bin\${{ matrix.configuration }}\Publish\${{ env.ProjectName }}_linux_arm64_${{ env.GITHUB_SHA_SHORT }}.7z
path: src\ST.Client.Desktop.Avalonia.App\bin\${{ matrix.configuration }}\Publish\${{ env.ProjectName }}_linux_arm64_${{ env.GITHUB_SHA_SHORT }}.tar.zst
@@ -134,11 +134,13 @@
Foreground="{DynamicResource HighlightForegroundBrushKey}"
FontSize="14"
VerticalAlignment="Center"/>
<controls:ScrollingTextBlock Text="{ReflectionBinding Path=User.NickName,Mode=OneWay,Source={x:Static service:UserService.Current}}"
IsVisible="{ReflectionBinding Path=User,Mode=OneWay,Source={x:Static service:UserService.Current},Converter={StaticResource IsNullConverter},ConverterParameter=invert}"
Foreground="{DynamicResource HighlightForegroundBrushKey}"
FontSize="14"
VerticalAlignment="Center"/>
<StackPanel IsVisible="{ReflectionBinding Path=User,Mode=OneWay,Source={x:Static service:UserService.Current},Converter={StaticResource IsNullConverter},ConverterParameter=invert}">
<controls:ScrollingTextBlock Text="{ReflectionBinding Path=User.NickName,Mode=OneWay,Source={x:Static service:UserService.Current}}"
Foreground="{DynamicResource HighlightForegroundBrushKey}"
FontSize="14"
VerticalAlignment="Center"/>
<Label Content="{ReflectionBinding Path=User.LevelStr,Mode=OneWay,Source={x:Static service:UserService.Current}}" Foreground="{DynamicResource HighlightForegroundBrushKey}" VerticalContentAlignment="Center" FontSize="12"/>
</StackPanel>
<!--<TextBlock Text="{ReflectionBinding Path=PhoneNumber,Mode=OneWay,Source={x:Static service:UserService.Current}}"
IsVisible="{ReflectionBinding Path=User.HasPhoneNumber,Mode=OneWay,Source={x:Static service:UserService.Current}}"
Foreground="{DynamicResource InactiveForegroundBrushKey}"
@@ -154,6 +156,9 @@
<ui:MenuFlyoutItem Text="{ReflectionBinding Path=Res.UserProfile,Mode=OneWay,Source={x:Static resx:R.Current}}"
Command="{ReflectionBinding Path=ShowWindow,Source={x:Static service:UserService.Current}}"
CommandParameter="UserProfile"/>
<ui:MenuFlyoutItem Text="{ReflectionBinding Path=Res.NotificationChannelType_Name_Announcement,Mode=OneWay,Source={x:Static resx:R.Current}}"
Command="{ReflectionBinding Path=ShowWindow,Source={x:Static service:UserService.Current}}"
CommandParameter="Notice"/>
<ui:MenuFlyoutItem Text="{ReflectionBinding Path=Res.User_ChangePhoneNum,Mode=OneWay,Source={x:Static resx:R.Current}}"
IsVisible="{ReflectionBinding Path=HasPhoneNumber,Source={x:Static service:UserService.Current}}}"
Command="{ReflectionBinding Path=ShowWindow,Source={x:Static service:UserService.Current}}"
@@ -40,6 +40,7 @@ namespace System.Application.UI.Views
//{ typeof(GameRelated_BorderlessPageViewModel), typeof(GameRelated_BorderlessPage) },
#if DEBUG
{ typeof(DebugPageViewModel), typeof(DebugPage) },
{ typeof(AccountPageViewModel), typeof(AccountPage) },
#endif
};
}
@@ -0,0 +1,239 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:System.Application.UI.ViewModels"
xmlns:resx="using:System.Application.UI.Resx"
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"
xmlns:service="using:System.Application.Services"
xmlns:models="using:System.Application.Models"
xmlns:ms="using:System.Application.Settings"
xmlns:i="using:Avalonia.Xaml.Interactivity"
xmlns:ia="using:Avalonia.Xaml.Interactions.Core"
x:DataType="vm:AccountPageViewModel"
xmlns:gif="using:AvaloniaGif"
x:CompileBindings="True"
x:Class="System.Application.UI.Views.Pages.AccountPage">
<StackPanel HorizontalAlignment="Stretch" Margin="{StaticResource PageMargin}" Background="Transparent" Spacing="20">
<StackPanel Spacing="8" DockPanel.Dock="Right">
<Border
Classes="paper"
Background="{DynamicResource ThemeBrushKey}"
Padding="10"
Margin="10 20 10 10">
<Panel >
<DockPanel>
<DockPanel>
<i:Interaction.Behaviors>
<ia:EventTriggerBehavior EventName="Tapped" SourceObject="{ReflectionBinding #avatar}">
<ia:InvokeCommandAction Command="{ReflectionBinding OpenUserProfile}"/>
</ia:EventTriggerBehavior>
<ia:EventTriggerBehavior EventName="PointerEnter" SourceObject="{ReflectionBinding #avatar}">
<ia:ChangePropertyAction
PropertyName="IsVisible"
TargetObject="{ReflectionBinding #avatarMask}"
Value="True" />
</ia:EventTriggerBehavior>
<ia:EventTriggerBehavior EventName="PointerLeave" SourceObject="{ReflectionBinding #avatar}">
<ia:ChangePropertyAction
PropertyName="IsVisible"
TargetObject="{ReflectionBinding #avatarMask}"
Value="False" />
</ia:EventTriggerBehavior>
</i:Interaction.Behaviors>
<Canvas x:Name="DrawCanvas"
VerticalAlignment="Center"
Margin="10 0"
Height="64"
Width="64"
Background="Transparent">
<gif:Image2 x:Name="avatar"
Source="{ReflectionBinding Path=AvatarPath, Source={x:Static service:UserService.Current},Mode=OneWay,Converter={StaticResource BitmapAssetValueConverter}}"
Stretch="Uniform"
VerticalAlignment="Center"
HorizontalAlignment="Center"
DecodeWidth="64"
Height="64"
Width="64"
Cursor="Hand"
FallbackSource="avares://System.Application.SteamTools.Client.Avalonia/Application/UI/Assets/AppResources/avatar.jpg"
ToolTip.Tip="{ReflectionBinding Path=Res.UserProfile,
Mode=OneWay,
Source={x:Static resx:R.Current}}">
<gif:Image2.Clip>
<EllipseGeometry Rect="0,0,64,64" />
</gif:Image2.Clip>
</gif:Image2>
<Rectangle x:Name="avatarMask"
IsVisible="false"
IsHitTestVisible="False"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Width="64"
Height="64"
Fill="#99000000">
<Rectangle.Clip>
<EllipseGeometry Rect="0,0,64,64" />
</Rectangle.Clip>
</Rectangle>
</Canvas>
</DockPanel>
<StackPanel Spacing="5" Margin="10" IsVisible="{ReflectionBinding Path=User,Mode=OneWay,Source={x:Static service:UserService.Current},Converter={StaticResource IsNullConverter},ConverterParameter=invert}">
<DockPanel>
<TextBlock Text="{ReflectionBinding Path=Res.User_UnLogin,Mode=OneWay,Source={x:Static resx:R.Current}}"
IsVisible="{ReflectionBinding Path=User,Mode=OneWay,Source={x:Static service:UserService.Current},Converter={StaticResource IsNullConverter}}"
Foreground="{DynamicResource HighlightForegroundBrushKey}"
FontSize="14"
VerticalAlignment="Center"/>
<TextBlock IsVisible="{Binding IsSponsor}" Margin="0 0 10 0" Text="{ReflectionBinding Path=Res.User_Sponsor,Mode=OneWay,Source={x:Static resx:R.Current}}" FontSize="12"></TextBlock>
<controls:ScrollingTextBlock Text="{ReflectionBinding Path=User.NickName,Mode=OneWay,Source={x:Static service:UserService.Current}}"
Foreground="{DynamicResource HighlightForegroundBrushKey}"
FontSize="14"
VerticalAlignment="Center"/>
<Label Margin="15 0 0 0" Content="{ReflectionBinding Path=User.LevelStr,Mode=OneWay,Source={x:Static service:UserService.Current}}" Foreground="{DynamicResource HighlightForegroundBrushKey}" VerticalContentAlignment="Center" FontSize="12"/>
<Border CornerRadius="2" Height="5" Width="25" Background="#ffffff" Opacity="0.2" Margin="0 5 5 0">
<Border Width="10" HorizontalAlignment="Left" CornerRadius="10">
<Border.Background>
<LinearGradientBrush StartPoint="0.1,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#b00dff"/>
<GradientStop Offset="1" Color="#580083"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Border>
<WrapPanel HorizontalAlignment="Right">
<Button Background="Transparent" Cursor="Hand"
Margin="10 0 10 0"
Command="{ReflectionBinding SignIn}"
ToolTip.Tip="{ReflectionBinding Path=Res.Refresh,Mode=OneWay,Source={x:Static resx:R.Current}}">
<PathIcon Width="16" Data="{StaticResource RefreshDrawing}" />
</Button>
<Button Background="Transparent" Cursor="Hand"
Command="{ReflectionBinding RefreshScriptButton}"
ToolTip.Tip="{ReflectionBinding Path=Res.SignOut,Mode=OneWay,Source={x:Static resx:R.Current}}">
<PathIcon Width="16" Data="{StaticResource SearchDrawing}" />
</Button>
</WrapPanel>
</DockPanel>
<Separator Classes="Separator"></Separator>
<DockPanel>
<DockPanel>
<Label Content="{ReflectionBinding Path=Res.User_EngineOil,Mode=OneWay,Source={x:Static resx:R.Current}}"></Label>
<Label Content=":"></Label>
<Button Background="Transparent" Cursor="Hand"
Padding="0"
Command="{ReflectionBinding OpenEngineOilLogs}"
ToolTip.Tip="{ReflectionBinding Path=Res.User_EngineOil,Mode=OneWay,Source={x:Static resx:R.Current}}">
<Label Content="{ReflectionBinding Path=User.EngineOil,Mode=OneWay,Source={x:Static service:UserService.Current}}">
</Label>
</Button>
</DockPanel>
<DockPanel>
<Label Content="{ReflectionBinding Path=Res.User_Balance,Mode=OneWay,Source={x:Static resx:R.Current}}"></Label>
<Label Content=":"></Label>
<Button Background="Transparent" Cursor="Hand"
Padding="0"
Command="{ReflectionBinding OpenEngineOilLogs}"
ToolTip.Tip="{ReflectionBinding Path=Res.User_Balance,Mode=OneWay,Source={x:Static resx:R.Current}}">
<Label Content="{ReflectionBinding Path=User.Balance,Mode=OneWay,Source={x:Static service:UserService.Current}}">
</Label>
</Button>
</DockPanel>
</DockPanel>
</StackPanel>
</DockPanel>
</Panel>
</Border>
<Separator Classes="Separator"></Separator>
<Grid ColumnDefinitions="Auto,*"
RowDefinitions="Auto,*">
<Border Grid.Column="0"
Margin="10 0 10 10"
MinWidth="300"
Grid.Row="0" Classes="paper" Background="{DynamicResource ThemeBrushKey}" Padding="10">
<DockPanel>
<ScrollViewer HorizontalScrollBarVisibility="Disabled"
Padding="0 0 0 10">
<ItemsControl
x:Name="item"
Items="{ReflectionBinding SelectGroup.Items.DataSource,Source={x:Static service:NotificationService.Current}}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="models:NoticeDTO">
<DockPanel>
<StackPanel Spacing="8" DockPanel.Dock="Right">
<DockPanel>
<controls:ScrollingTextBlock
Width="{Binding $parent.Width}"
Text="{Binding Title,Mode=OneWay}"
FontSize="16"
VerticalAlignment="Center"
Foreground="{DynamicResource HighlightForegroundBrushKey}"/>
<WrapPanel HorizontalAlignment="Right" VerticalAlignment="Center">
<TextBlock
Text="{Binding Author}"
FontSize="14"
VerticalAlignment="Center"
Foreground="{DynamicResource HighlightForegroundBrushKey}"/>
<TextBlock Text=" / " FontSize="14"></TextBlock>
<TextBlock
Text="{Binding CreationTime}"
FontSize="14"
VerticalAlignment="Center"
Foreground="{DynamicResource HighlightForegroundBrushKey}"/>
</WrapPanel>
</DockPanel>
<Separator Classes="Separator" Margin="0 0 0 5"></Separator>
<TextBlock
Width="{Binding $parent.Width}"
TextWrapping="WrapWithOverflow"
Text="{Binding Introduction}"
FontSize="12"
Foreground="{DynamicResource HighlightForegroundBrushKey}"/>
</StackPanel>
</DockPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
</Border>
<Border Grid.Column="1" Grid.Row="0" Classes="paper" Margin="0 0 10 10" Background="{DynamicResource ThemeBrushKey}" Padding="10">
<DockPanel >
<TextBlock Text="这里部分常见内容 官网Json获取 手动编辑" FontSize="14"></TextBlock>
</DockPanel>
</Border>
</Grid>
<Grid ColumnDefinitions="Auto,*"
RowDefinitions="Auto,*">
<Border Grid.Column="0"
Grid.Row="0" Classes="paper" Background="{DynamicResource ThemeBrushKey}">
<DockPanel>
</DockPanel>
</Border>
<Border Grid.Column="1"
Grid.Row="0" Classes="paper" Background="{DynamicResource ThemeBrushKey}">
<DockPanel >
</DockPanel>
</Border>
</Grid>
</StackPanel>
</StackPanel>
</UserControl>
@@ -0,0 +1,20 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using System.Application.UI.ViewModels;
namespace System.Application.UI.Views.Pages
{
public class AccountPage : ReactiveUserControl<AccountPageViewModel>
{
public AccountPage()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}
@@ -0,0 +1,24 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:System.Application.UI.ViewModels"
xmlns:resx="using:System.Application.UI.Resx"
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"
xmlns:service="using:System.Application.Services"
xmlns:models="using:System.Application.Models"
xmlns:ms="using:System.Application.Settings"
xmlns:i="using:Avalonia.Xaml.Interactivity"
xmlns:ia="using:Avalonia.Xaml.Interactions.Core"
x:DataType="vm:Account_BalanceLogsPageViewModel"
xmlns:gif="using:AvaloniaGif"
x:CompileBindings="True"
x:Class="System.Application.UI.Views.Pages.Account_BalanceLogsPage">
<StackPanel HorizontalAlignment="Stretch" Margin="{StaticResource PageMargin}" Background="Transparent" Spacing="20">
<StackPanel Spacing="8" DockPanel.Dock="Right">
</StackPanel>
</StackPanel>
</UserControl>
@@ -0,0 +1,20 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using System.Application.UI.ViewModels;
namespace System.Application.UI.Views.Pages
{
public class Account_BalanceLogsPage : ReactiveUserControl<Account_BalanceLogsPageViewModel>
{
public Account_BalanceLogsPage()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}
@@ -0,0 +1,24 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:System.Application.UI.ViewModels"
xmlns:resx="using:System.Application.UI.Resx"
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"
xmlns:service="using:System.Application.Services"
xmlns:models="using:System.Application.Models"
xmlns:ms="using:System.Application.Settings"
xmlns:i="using:Avalonia.Xaml.Interactivity"
xmlns:ia="using:Avalonia.Xaml.Interactions.Core"
x:DataType="vm:Account_EngineOilLogsPageViewModel"
xmlns:gif="using:AvaloniaGif"
x:CompileBindings="True"
x:Class="System.Application.UI.Views.Pages.Account_EngineOilLogsPage">
<StackPanel HorizontalAlignment="Stretch" Margin="{StaticResource PageMargin}" Background="Transparent" Spacing="20">
<StackPanel Spacing="8" DockPanel.Dock="Right">
</StackPanel>
</StackPanel>
</UserControl>
@@ -0,0 +1,20 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using System.Application.UI.ViewModels;
namespace System.Application.UI.Views.Pages
{
public class Account_EngineOilLogsPage : ReactiveUserControl<Account_EngineOilLogsPageViewModel>
{
public Account_EngineOilLogsPage()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}
@@ -0,0 +1,144 @@
<Window 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="600"
Width="800" Height="600"
x:Name="u"
xmlns:gif="using:AvaloniaGif"
xmlns:i="using:Avalonia.Xaml.Interactivity"
xmlns:ia="using:Avalonia.Xaml.Interactions.Core"
x:Class="System.Application.UI.Views.Windows.NoticeWindow"
xmlns:service="using:System.Application.Services"
xmlns:resx="using:System.Application.UI.Resx"
xmlns:vm="using:System.Application.UI.ViewModels"
xmlns:controls="clr-namespace:System.Application.UI.Views.Controls"
xmlns:ms="using:System.Application.Settings"
xmlns:models="using:System.Application.Models"
FontFamily="{Binding Source={x:Static ms:UISettings.FontName},Path=Value, Mode=OneWay,Converter={StaticResource NameToFontFamilyConverter}}"
Background="Transparent"
ExtendClientAreaTitleBarHeightHint="30"
Title="{Binding Title}"
x:DataType="vm:NoticeWindowViewModel"
x:CompileBindings="True">
<Panel HorizontalAlignment="Stretch">
<controls:TitleBar></controls:TitleBar>
<DockPanel>
<Border DockPanel.Dock="Top"
Padding="10"
Margin="10 40 10 10">
<DockPanel>
<TabControl
Classes="flat"
x:Name="items"
Items="{ReflectionBinding ObservableItems,Source={x:Static service:NotificationService.Current}}"
SelectedItem="{ReflectionBinding Source={x:Static service:NotificationService.Current},Path=SelectGroup,Mode=TwoWay}"
Background="Transparent">
<TabControl.ItemTemplate>
<DataTemplate x:DataType="models:NoticeTypeDTO">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<Panel>
<StackPanel IsVisible="{ReflectionBinding Source={x:Static service:NotificationService.Current},Path=IsLoading,Mode=OneWay}"
HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="10">
<ProgressBar
Width="100"
Height="100"
Classes="Circle"
IsIndeterminate="True"
Orientation="Vertical" />
<TextBlock Text="{ReflectionBinding Path=Res.Loading,Mode=OneWay,Source={x:Static resx:R.Current}}"></TextBlock>
</StackPanel>
<StackPanel IsVisible="{ReflectionBinding Source={x:Static service:NotificationService.Current},Path=IsEmpty,Mode=OneWay}"
HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="10">
<TextBlock Text="{ReflectionBinding Path=Res.NoticeEmpty,Mode=OneWay,Source={x:Static resx:R.Current}}"></TextBlock>
</StackPanel>
<ScrollViewer HorizontalScrollBarVisibility="Disabled"
Padding="0 0 0 10">
<ItemsControl
x:Name="item"
Items="{ReflectionBinding SelectGroup.Items.DataSource,Source={x:Static service:NotificationService.Current}}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="models:NoticeDTO">
<Border Classes="paper"
Margin="0 10"
Background="{DynamicResource ThemeBrushKey}"
Padding="20 10">
<DockPanel>
<StackPanel Spacing="8" DockPanel.Dock="Right">
<DockPanel >
<i:Interaction.Behaviors>
<ia:EventTriggerBehavior EventName="Tapped" SourceObject="{ReflectionBinding #title}">
<ia:InvokeCommandAction Command="{ReflectionBinding #u.DataContext.OpenNoticeWeb}" CommandParameter="{Binding}"/>
</ia:EventTriggerBehavior>
</i:Interaction.Behaviors>
<controls:ScrollingTextBlock
x:Name="title"
Width="{Binding $parent.Width}"
Text="{Binding Title,Mode=OneWay}"
FontSize="16"
VerticalAlignment="Center"
Foreground="{DynamicResource HighlightForegroundBrushKey}"
/>
<WrapPanel HorizontalAlignment="Right" VerticalAlignment="Center">
<TextBlock
Text="{Binding Author}"
FontSize="14"
VerticalAlignment="Center"
Foreground="{DynamicResource HighlightForegroundBrushKey}"/>
<TextBlock Text=" / " FontSize="14"></TextBlock>
<TextBlock
Text="{Binding CreationTime}"
FontSize="14"
VerticalAlignment="Center"
Foreground="{DynamicResource HighlightForegroundBrushKey}"/>
</WrapPanel>
</DockPanel>
<Separator Classes="Separator" Margin="0 0 0 5"></Separator>
<Grid ColumnDefinitions="Auto,*">
<Border ClipToBounds="True">
<Panel
x:Name="avatar"
Cursor="Hand" >
<gif:Image2
Width="150"
DecodeWidth="150"
AutoStart="true"
Source="{Binding PictureStream^}"
FallbackSource="avares://System.Application.SteamTools.Client.Avalonia/Application/UI/Assets/AppResources/avatar.jpg"
Stretch="Uniform" />
</Panel>
</Border>
<Panel Grid.Column="1" Margin="10,0,0,0">
<TextBlock
Width="{Binding $parent.Width}"
TextWrapping="WrapWithOverflow"
Text="{Binding Introduction}"
FontSize="12"
Foreground="{DynamicResource HighlightForegroundBrushKey}"/>
</Panel>
</Grid>
</StackPanel>
</DockPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Panel>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</DockPanel>
</Border>
</DockPanel>
</Panel>
</Window>
@@ -0,0 +1,23 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using System.Application.UI.ViewModels;
namespace System.Application.UI.Views.Windows
{
public class NoticeWindow : FluentWindow<NoticeWindowViewModel>
{
public NoticeWindow() : base()
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}
@@ -0,0 +1,34 @@
<Window 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="600"
Width="800" Height="600"
x:Name="u"
x:Class="System.Application.UI.Views.Windows.SignWindow"
xmlns:resx="using:System.Application.UI.Resx"
xmlns:vm="using:System.Application.UI.ViewModels"
xmlns:controls="clr-namespace:System.Application.UI.Views.Controls"
xmlns:ms="using:System.Application.Settings"
FontFamily="{Binding Source={x:Static ms:UISettings.FontName},Path=Value, Mode=OneWay,Converter={StaticResource NameToFontFamilyConverter}}"
Background="Transparent"
ExtendClientAreaTitleBarHeightHint="30"
Title="{Binding Title}"
x:DataType="vm:SignWindowViewModel"
x:CompileBindings="True">
<Panel HorizontalAlignment="Stretch">
<controls:TitleBar></controls:TitleBar>
<DockPanel>
<Border DockPanel.Dock="Top"
Classes="paper"
Background="{DynamicResource ThemeBrushKey}"
Padding="10"
Margin="10 40 10 10">
<DockPanel>
</DockPanel>
</Border>
</DockPanel>
</Panel>
</Window>
@@ -0,0 +1,23 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using System.Application.UI.ViewModels;
namespace System.Application.UI.Views.Windows
{
public class SignWindow : FluentWindow<SignWindowViewModel>
{
public SignWindow() : base()
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}
+1
View File
@@ -32,5 +32,6 @@ namespace System.Application
ASF_AddBot,
SteamShutdown,
ProxySettings,
Notice,
}
}
+5 -1
View File
@@ -1,4 +1,4 @@
using System.Application;
using System.Application;
using System.Application.Services;
using System.IO;
using System.Threading;
@@ -45,6 +45,10 @@ namespace System.Application
/// 验证码图片
/// </summary>
CodeImage,
/// <summary>
/// 通知公告封面图
/// </summary>
NoticePicture
}
}
@@ -0,0 +1,115 @@
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using System.Application.Models;
using System.Application.Properties;
using System.Application.Settings;
using System.Application.UI.Resx;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Properties;
using System.Reactive.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Models;
namespace System.Application.Services
{
public sealed class NotificationService : ReactiveObject
{
static NotificationService? mCurrent;
public static NotificationService Current => mCurrent ?? new();
readonly IHttpService httpService = DI.Get<IHttpService>();
public SourceList<NoticeTypeDTO> NoticeTypes { get; }
private ReadOnlyObservableCollection<NoticeTypeDTO>? _ObservableItems;
public ReadOnlyObservableCollection<NoticeTypeDTO>? ObservableItems
{
get => _ObservableItems;
set => this.RaiseAndSetIfChanged(ref _ObservableItems, value);
}
bool _IsLoading;
public bool IsLoading
{
get => _IsLoading;
set => this.RaiseAndSetIfChanged(ref _IsLoading, value);
}
bool _IsEmpty;
public bool IsEmpty
{
get => _IsEmpty;
set => this.RaiseAndSetIfChanged(ref _IsEmpty, value);
}
private NoticeTypeDTO? _SelectGroup;
public NoticeTypeDTO? SelectGroup
{
get => _SelectGroup;
set => this.RaiseAndSetIfChanged(ref _SelectGroup, value);
}
public async Task InitializeNotice()
{
IsLoading = true;
var client = ICloudServiceClient.Instance.Notice;
var result = await client.Types();
if (result.IsSuccess)
{
NoticeTypes.Clear();
NoticeTypes.AddRange(result.Content!.OrderBy(x => x.Index));
}
}
public async Task GetTable(NoticeTypeDTO selectGroup)
{
if (selectGroup != null)
{
var client = ICloudServiceClient.Instance.Notice;
var result = await client.Table(selectGroup.Id, selectGroup.Index);
if (result.IsSuccess)
{
foreach (var item in result.Content!.DataSource)
{
if (!string.IsNullOrWhiteSpace(item.Picture))
item.PictureStream = httpService.GetImageAsync(item.Picture, ImageChannelType.NoticePicture);
}
SelectGroup!.Items = result.Content!;
}
IsEmpty = SelectGroup!.Items == null || SelectGroup.Items?.DataSource.Count == 0;
}
}
public NotificationService()
{
mCurrent = this;
NoticeTypes = new SourceList<NoticeTypeDTO>();
this.WhenAnyValue(x => x.SelectGroup)
.Subscribe(async x =>
{
if (x != null)
{
IsLoading = true;
await GetTable(x);
IsLoading = false;
}
});
NoticeTypes
.Connect()
.ObserveOn(RxApp.MainThreadScheduler)
.Sort(SortExpressionComparer<NoticeTypeDTO>.Ascending(x => x.Order).ThenBy(x => x.Name))
.Bind(out _ObservableItems)
.Subscribe(_ =>
{
SelectGroup = NoticeTypes.Items.FirstOrDefault();
});
}
}
}
+8 -1
View File
@@ -34,6 +34,10 @@ namespace System.Application.Services
{
isDialog = false;
}
else if (windowName == CustomWindow.Notice)
{
isDialog = true;
}
else if (windowName == CustomWindow.ChangeBindPhoneNumber)
{
var cUser = await userManager.GetCurrentUserAsync();
@@ -71,7 +75,10 @@ namespace System.Application.Services
await SignOutAsync(csc.Manage.SignOut);
}
}
public async Task<IApiResponse<ClockInResponse>> SignIn()
{
return await csc.AccountClockIn();
}
public async Task DelAccountAsync()
{
if (!IsAuthenticated) return;
+36
View File
@@ -225,6 +225,15 @@ namespace System.Application.UI.Resx {
}
}
/// <summary>
/// 查找类似 签到成功 的本地化字符串。
/// </summary>
public static string Account_SignIn_Ok {
get {
return ResourceManager.GetString("Account_SignIn_Ok", resourceCulture);
}
}
/// <summary>
/// 查找类似 修改的数据生效需要重启 Steam 是否需要重启 Steam。 的本地化字符串。
/// </summary>
@@ -5403,6 +5412,15 @@ namespace System.Application.UI.Resx {
}
}
/// <summary>
/// 查找类似 余额 的本地化字符串。
/// </summary>
public static string User_Balance {
get {
return ResourceManager.GetString("User_Balance", resourceCulture);
}
}
/// <summary>
/// 查找类似 基本资料 的本地化字符串。
/// </summary>
@@ -5439,6 +5457,15 @@ namespace System.Application.UI.Resx {
}
}
/// <summary>
/// 查找类似 积分 的本地化字符串。
/// </summary>
public static string User_EngineOil {
get {
return ResourceManager.GetString("User_EngineOil", resourceCulture);
}
}
/// <summary>
/// 查找类似 快速登录 的本地化字符串。
/// </summary>
@@ -5664,6 +5691,15 @@ namespace System.Application.UI.Resx {
}
}
/// <summary>
/// 查找类似 捐助用户 的本地化字符串。
/// </summary>
public static string User_Sponsor {
get {
return ResourceManager.GetString("User_Sponsor", resourceCulture);
}
}
/// <summary>
/// 查找类似 点击头像快速登录 的本地化字符串。
/// </summary>
+12
View File
@@ -2094,6 +2094,18 @@ AAAAA-BBBBB-CCCC3</value>
<data name="NewVersionUpdateNotifyText_" xml:space="preserve">
<value>检测到新版本 v{0}</value>
</data>
<data name="User_Balance" xml:space="preserve">
<value>余额</value>
</data>
<data name="User_EngineOil" xml:space="preserve">
<value>积分</value>
</data>
<data name="User_Sponsor" xml:space="preserve">
<value>捐助用户</value>
</data>
<data name="Account_SignIn_Ok" xml:space="preserve">
<value>签到成功</value>
</data>
<data name="Save" xml:space="preserve">
<value>保存</value>
</data>
@@ -147,6 +147,15 @@ namespace System.Application.UI.ViewModels
}
}
partial class AccountPageViewModel : TabItemViewModel
{
public static string DisplayName => AppResources.UserProfile;
public override string Name
{
get => DisplayName;
}
}
#if DEBUG
partial class DebugPageViewModel : TabItemViewModel
{
@@ -60,6 +60,7 @@ namespace System.Application.UI.ViewModels
public GameRelatedPageViewModel GameRelatedPage => GetTabItemVM<GameRelatedPageViewModel>();
public OtherPlatformPageViewModel OtherPlatformPage => GetTabItemVM<OtherPlatformPageViewModel>();
public AccountPageViewModel AccountPage => GetTabItemVM<AccountPageViewModel>();
protected static readonly IPlatformService platformService = IPlatformService.Instance;
public MainWindowViewModel()
@@ -82,7 +83,7 @@ namespace System.Application.UI.ViewModels
{
IsOpenUserMenu = UserService.Current.IsAuthenticated;
if (!IsOpenUserMenu)
{
{
UserService.Current.ShowWindow(CustomWindow.LoginOrRegister);
}
});
@@ -0,0 +1,59 @@
using ReactiveUI;
using System;
using System.Application.Services;
using System.Application.UI.Resx;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reactive;
using System.Application.Models;
// ReSharper disable once CheckNamespace
namespace System.Application.UI.ViewModels
{
public partial class AccountPageViewModel
{
public ReactiveCommand<Unit, Unit>? OpenUserProfile { get; }
public ReactiveCommand<Unit, Unit>? OpenEngineOilLogs { get; }
public ReactiveCommand<Unit, Unit>? OpenBalanceLogs { get; }
public ReactiveCommand<Unit, Unit>? SignIn { get; }
public AccountPageViewModel()
{
OpenUserProfile = ReactiveCommand.Create(() =>
{
UserService.Current.ShowWindow(CustomWindow.UserProfile);
});
OpenEngineOilLogs = ReactiveCommand.Create(() =>
{
});
OpenBalanceLogs = ReactiveCommand.Create(() =>
{
});
SignIn = ReactiveCommand.CreateFromTask(async () =>
{
var state = await UserService.Current.SignIn();
if (state.IsSuccess)
{
UserService.Current.User!.Experience = state.Content!.Experience;
Toast.Show(AppResources.Account_SignIn_Ok);
}
else
{
Toast.Show(state.Message);
}
});
}
public override async void Activation()
{
if (IsFirstActivation && NotificationService.Current.NoticeTypes.Count == 0)
await NotificationService.Current.InitializeNotice();
var defaultNotice = NotificationService.Current?.NoticeTypes.Items.FirstOrDefault();
if (defaultNotice != null && NotificationService.Current?.SelectGroup?.Id != defaultNotice.Id)
await NotificationService.Current!.GetTable(defaultNotice!);
base.Activation();
}
public bool IsSponsor => UserService.Current.User?.UserType.HasFlag(UserType.Sponsor) ?? false;
}
}
@@ -0,0 +1,21 @@
using ReactiveUI;
using System;
using System.Application.Services;
using System.Application.UI.Resx;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reactive;
// ReSharper disable once CheckNamespace
namespace System.Application.UI.ViewModels
{
public partial class Account_BalanceLogsPageViewModel
{
public Account_BalanceLogsPageViewModel()
{
}
}
}
@@ -0,0 +1,21 @@
using ReactiveUI;
using System;
using System.Application.Services;
using System.Application.UI.Resx;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reactive;
// ReSharper disable once CheckNamespace
namespace System.Application.UI.ViewModels
{
public partial class Account_EngineOilLogsPageViewModel
{
public Account_EngineOilLogsPageViewModel()
{
}
}
}
@@ -0,0 +1,36 @@
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using System.Application.Models;
using System.Application.Services;
using System.Application.UI.Resx;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
namespace System.Application.UI.ViewModels
{
public class NoticeWindowViewModel : WindowViewModel
{
public static string DisplayName => AppResources.NotificationChannelType_Name_Announcement;
public ReactiveCommand<string, Unit>? OpenNotice { get; }
public NoticeWindowViewModel()
{
Title = GetTitleByDisplayName(DisplayName);
OpenNotice = ReactiveCommand.CreateFromTask<string>(Browser2.OpenAsync);
}
public void OpenNoticeWeb(NoticeDTO item)
{
if (item.IsOpenBrowser)
Browser2.Open(string.Format(UrlConstants.OfficialWebsite_Notice, item.Id));
}
public override async void Activation()
{
if (IsFirstActivation && NotificationService.Current.NoticeTypes.Count == 0)
await NotificationService.Current.InitializeNotice();
base.Activation();
}
}
}
@@ -0,0 +1,23 @@
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using System.Application.Models;
using System.Application.Services;
using System.Application.UI.Resx;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
namespace System.Application.UI.ViewModels
{
public class SignWindowViewModel : WindowViewModel
{
public static string DisplayName => AppResources.ScriptStore;
public SignWindowViewModel()
{
Title = GetTitleByDisplayName(DisplayName);
}
}
}
+1
View File
@@ -22,6 +22,7 @@ namespace System.Application
public const string OfficialWebsite_UnixHostAccess_ = "https://steampp.net/unixhostaccess?prot={0}";
public const string OfficialWebsite_UnixHostAccess = "https://steampp.net/unixhostaccess";
public const string OfficialWebsite_ApplicationUpdateFailCode_ = "https://steampp.net?appUpdFailCode={0}";
public const string OfficialWebsite_Notice = "https://steampp.net/notice?id={0}";
public const string GitHub_Repository = "https://github.com/BeyondDimension/SteamTools";
public const string Gitee_Repository = "https://gitee.com/rmbgame/SteamTools";
@@ -0,0 +1,34 @@
#if MVVM_VM
using ReactiveUI;
using System.Collections.Generic;
using MPIgnore = MessagePack.IgnoreMemberAttribute;
using N_JsonIgnore = Newtonsoft.Json.JsonIgnoreAttribute;
using S_JsonIgnore = System.Text.Json.Serialization.JsonIgnoreAttribute;
#endif
using MPKey = MessagePack.KeyAttribute;
using MPObj = MessagePack.MessagePackObjectAttribute;
using N_JsonProperty = Newtonsoft.Json.JsonPropertyAttribute;
using S_JsonProperty = System.Text.Json.Serialization.JsonPropertyNameAttribute;
namespace System.Application.Models
{
[MPObj]
public class AdvertisementDTO
{
[MPKey(0)]
[N_JsonProperty("0")]
[S_JsonProperty("0")]
public Guid Id { get; set; }
/// <summary>
/// 排序
/// </summary>
[MPKey(1)]
[N_JsonProperty("1")]
[S_JsonProperty("1")]
public int Order { get; set; }
}
}
@@ -1,12 +1,24 @@
#if MVVM_VM
using ReactiveUI;
using System.Collections.Generic;
using MPIgnore = MessagePack.IgnoreMemberAttribute;
using N_JsonIgnore = Newtonsoft.Json.JsonIgnoreAttribute;
using S_JsonIgnore = System.Text.Json.Serialization.JsonIgnoreAttribute;
#endif
using MPKey = MessagePack.KeyAttribute;
using MPObj = MessagePack.MessagePackObjectAttribute;
using N_JsonProperty = Newtonsoft.Json.JsonPropertyAttribute;
using S_JsonProperty = System.Text.Json.Serialization.JsonPropertyNameAttribute;
using System.Threading.Tasks;
namespace System.Application.Models
{
[MPObj]
public class NoticeDTO
#if MVVM_VM
:ReactiveObject
#endif
{
[MPKey(0)]
[N_JsonProperty("0")]
@@ -25,6 +37,18 @@ namespace System.Application.Models
[N_JsonProperty("2")]
[S_JsonProperty("2")]
public string Picture { get; set; } = string.Empty;
#if MVVM_VM
Task<string?>? _PictureStream;
[MPIgnore]
[N_JsonIgnore]
[S_JsonIgnore]
public Task<string?>? PictureStream
{
get => _PictureStream;
set => this.RaiseAndSetIfChanged(ref _PictureStream, value);
}
#endif
/// <summary>
/// 标题
/// </summary>
@@ -55,7 +79,7 @@ namespace System.Application.Models
[MPKey(6)]
[N_JsonProperty("6")]
[S_JsonProperty("6")]
public DateTimeOffset CreationTime { get; set; } = DateTimeOffset.Now;
public DateTimeOffset CreationTime { get; set; }
/// <summary>
/// 消息启用时间(预约添加)
@@ -63,7 +87,7 @@ namespace System.Application.Models
[MPKey(7)]
[N_JsonProperty("7")]
[S_JsonProperty("7")]
public DateTimeOffset EnableTime { get; set; } = DateTimeOffset.Now;
public DateTimeOffset EnableTime { get; set; }
/// <summary>
/// 是否浏览器打开
@@ -72,5 +96,22 @@ namespace System.Application.Models
[N_JsonProperty("8")]
[S_JsonProperty("8")]
public bool IsOpenBrowser { get; set; }
/// <summary>
/// 提醒过期时间 (默认3天)
/// </summary>
[MPKey(9)]
[N_JsonProperty("9")]
[S_JsonProperty("9")]
public DateTimeOffset OverdueTime { get; set; }
#if MVVM_VM
/// <summary>
/// 当前组中所有的加速项目集合
/// </summary>
[MPIgnore]
[N_JsonIgnore]
[S_JsonIgnore]
public bool Overdue => DateTimeOffset.Now > OverdueTime;
#endif
}
}
@@ -1,3 +1,11 @@
#if MVVM_VM
using ReactiveUI;
using System.Collections.Generic;
using MPIgnore = MessagePack.IgnoreMemberAttribute;
using N_JsonIgnore = Newtonsoft.Json.JsonIgnoreAttribute;
using S_JsonIgnore = System.Text.Json.Serialization.JsonIgnoreAttribute;
#endif
using MPKey = MessagePack.KeyAttribute;
using MPObj = MessagePack.MessagePackObjectAttribute;
using N_JsonProperty = Newtonsoft.Json.JsonPropertyAttribute;
@@ -7,6 +15,9 @@ namespace System.Application.Models
{
[MPObj]
public class NoticeTypeDTO
#if MVVM_VM
: ReactiveObject
#endif
{
[MPKey(0)]
[N_JsonProperty("0")]
@@ -28,5 +39,33 @@ namespace System.Application.Models
[N_JsonProperty("2")]
[S_JsonProperty("2")]
public int Order { get; set; }
#if MVVM_VM
/// <summary>
/// 当前组中所有的加速项目集合
/// </summary>
[MPIgnore]
[N_JsonIgnore]
[S_JsonIgnore]
public int Index
{
get => _Index;
set => this.RaiseAndSetIfChanged(ref _Index, value);
}
int _Index = 1;
/// <summary>
/// 当前组中所有的加速项目集合
/// </summary>
[MPIgnore]
[N_JsonIgnore]
[S_JsonIgnore]
public PagedModel<NoticeDTO>? Items
{
get => mItems;
set => this.RaiseAndSetIfChanged(ref mItems, value);
}
PagedModel<NoticeDTO>? mItems;
#endif
}
}
@@ -88,7 +88,18 @@ namespace System.Application.Models
[N_JsonProperty("7")]
[S_JsonProperty("7")]
public byte Level { get; set; }
#if MVVM_VM
[MPIgnore]
[N_JsonIgnore]
[S_JsonIgnore]
public string LevelStr
{
get
{
return $"Lv.{Level}";
}
}
#endif
[MPKey(8)]
[N_JsonProperty("8")]
[S_JsonProperty("8")]
@@ -1,4 +1,5 @@
using System.Application.Models;
using System.Application.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace System.Application.Services.CloudService.Clients.Abstractions
@@ -14,5 +15,17 @@ namespace System.Application.Services.CloudService.Clients.Abstractions
var refresh_token = jWT.RefreshToken;
return RefreshToken(refresh_token.ThrowIsNull(nameof(refresh_token)));
}
/// <summary>
/// 签到
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
Task<IApiResponse<ClockInResponse>> ClockIn(ClockInRequest request);
/// <summary>
/// 获取签到历史记录
/// </summary>
/// <param name="time">时间 服务器会自动取该时间本月的所有签到记录</param>
/// <returns></returns>
Task<IApiResponse<IEnumerable<DateTimeOffset>>> ClockInLogs(DateTimeOffset? time);
}
}
@@ -7,7 +7,7 @@ namespace System.Application.Services.CloudService.Clients.Abstractions
public interface INoticeClient
{
Task<IApiResponse<NoticeTypeDTO[]>> Types();
Task<IApiResponse<PagedModel<NoticeDTO>>> Table(Guid typeId, int index, int size);
Task<IApiResponse<PagedModel<NoticeDTO>>> Table(Guid typeId, int index, int? size = null);
Task<IApiResponse<NoticeDTO[]>> NewMsg(Guid typeId, DateTimeOffset? time);
}
}
@@ -1,5 +1,6 @@
using System.Application.Models;
using System.Application.Models;
using System.Application.Services.CloudService.Clients.Abstractions;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
@@ -10,17 +11,42 @@ namespace System.Application.Services.CloudService.Clients
public AccountClient(IApiConnection conn) : base(conn)
{
}
public Task<IApiResponse<LoginOrRegisterResponse>> LoginOrRegister(LoginOrRegisterRequest request)
=> conn.SendAsync<LoginOrRegisterRequest, LoginOrRegisterResponse>(
isAnonymous: true,
=> conn.SendAsync<LoginOrRegisterRequest, LoginOrRegisterResponse>(
isAnonymous: true,
isSecurity: true,
method: HttpMethod.Post,
requestUri: "api/Account/LoginOrRegister",
request: request,
cancellationToken: default,
responseContentMaybeNull: false);
/// <summary>
/// 签到
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public Task<IApiResponse<ClockInResponse>> ClockIn(ClockInRequest request)
=> conn.SendAsync<ClockInRequest, ClockInResponse>(
isAnonymous: false,
isSecurity: true,
method: HttpMethod.Post,
requestUri: "api/Account/LoginOrRegister",
requestUri: "api/Manage/ClockIn",
request: request,
cancellationToken: default,
responseContentMaybeNull: false);
/// <summary>
/// 获取签到历史记录
/// </summary>
/// <param name="time">时间 服务器会自动取该时间本月的所有签到记录</param>
/// <returns></returns>
public Task<IApiResponse<IEnumerable<DateTimeOffset>>> ClockInLogs(DateTimeOffset? time)
=> conn.SendAsync<IEnumerable<DateTimeOffset>>(
isAnonymous: true,
isSecurity: true,
method: HttpMethod.Get,
requestUri: $"api/Manage/ClockInLogs?time={(time.HasValue ? time : DateTimeOffset.Now)}",
cancellationToken: default,
responseContentMaybeNull: false);
public Task<IApiResponse<JWTEntity>> RefreshToken(string refresh_token)
=> conn.SendAsync<JWTEntity>(
isAnonymous: true, // 刷新Token必须匿名身份,否则将递归死循环
@@ -15,25 +15,26 @@ namespace System.Application.Services.CloudService.Clients
=> conn.SendAsync<NoticeTypeDTO[]>(
isPolly: true,
isAnonymous: true,
isSecurity: false,
isSecurity: true,
method: HttpMethod.Get,
requestUri: "api/Notice/Types",
cancellationToken: default);
public Task<IApiResponse<PagedModel<NoticeDTO>>> Table(Guid typeId, int index, int size)
public Task<IApiResponse<PagedModel<NoticeDTO>>> Table(Guid typeId, int index, int? size = null)
=> conn.SendAsync<PagedModel<NoticeDTO>>(
isPolly: true,
isAnonymous: true,
isSecurity: false,
isSecurity: true,
method: HttpMethod.Post,
requestUri: $"api/Notice/Table/{typeId}?index={index}&size={size}",
requestUri: $"api/Notice/List/{typeId}?index={index}{(size.HasValue ? $"&size={size}" : "")}",
cancellationToken: default);
public Task<IApiResponse<NoticeDTO[]>> NewMsg(Guid typeId,DateTimeOffset? time)
=> conn.SendAsync<NoticeDTO[]>(
isPolly: true,
isAnonymous: true,
isSecurity: false,
isSecurity: true,
method: HttpMethod.Get,
requestUri: $"api/Notice/NewMsg/{typeId}{(time.HasValue?$"?time={time}":"")}",
cancellationToken: default);
@@ -25,6 +25,7 @@ namespace System.Application.Services.CloudService
public IAuthMessageClient AuthMessage { get; }
public IVersionClient Version { get; }
public IActiveUserClient ActiveUser { get; }
public INoticeClient Notice { get; }
public IAccelerateClient Accelerate { get; }
public IDonateRankingClient DonateRanking { get; }
@@ -83,7 +84,7 @@ namespace System.Application.Services.CloudService
Accelerate = new AccelerateClient(connection);
Script = new ScriptClient(connection);
DonateRanking = new DonateRankingClient(connection);
Notice = new NoticeClient(connection);
#endregion
}
@@ -92,6 +93,7 @@ namespace System.Application.Services.CloudService
IAuthHelper IApiConnectionPlatformHelper.Auth => authHelper;
public abstract Task SaveAuthTokenAsync(JWTEntity authToken);
public abstract Task OnLoginedAsync(IReadOnlyPhoneNumber? phoneNumber, ILoginResponse response);
@@ -120,6 +122,11 @@ namespace System.Application.Services.CloudService
//return connection.SendAsync(request, completionOption, cancellationToken);
}
Task<IApiResponse<ClockInResponse>> ICloudServiceClient.AccountClockIn()
{
return Account.ClockIn(new ClockInRequest { CreationTime=DateTimeOffset.Now});
}
async Task<string> ICloudServiceClient.Info()
{
var api = await connection.GetHtml(default, "/info");
@@ -10,7 +10,7 @@ using System.Threading.Tasks;
namespace System.Application.Services.CloudService
{
public sealed partial class MockCloudServiceClient : ICloudServiceClient, IAccountClient, IManageClient, IAuthMessageClient, IVersionClient, IActiveUserClient, IAccelerateClient, IScriptClient, IDonateRankingClient
public sealed partial class MockCloudServiceClient : ICloudServiceClient, IAccountClient, IManageClient, IAuthMessageClient, IVersionClient, IActiveUserClient, IAccelerateClient, IScriptClient, IDonateRankingClient, INoticeClient
{
readonly IToast toast;
readonly IModelValidator validator;
@@ -33,6 +33,8 @@ namespace System.Application.Services.CloudService
public IAccelerateClient Accelerate => this;
public IDonateRankingClient DonateRanking => this;
public INoticeClient Notice => this;
#region ModelValidator
IApiResponse? ModelValidator<TRequestModel>(TRequestModel requestModel) => ModelValidator<TRequestModel, object>(requestModel);
@@ -249,6 +251,41 @@ namespace System.Application.Services.CloudService
await Task.Delay(1500);
return ApiResponse.Ok(new PagedModel<RankingResponse> { });
}
public async Task<IApiResponse<NoticeTypeDTO[]>> Types()
{
await Task.Delay(1500);
return ApiResponse.Ok(new NoticeTypeDTO[] { });
}
public async Task<IApiResponse<NoticeDTO[]>> NewMsg(Guid typeId, DateTimeOffset? time)
{
await Task.Delay(1500);
return ApiResponse.Ok(new NoticeDTO[] { });
}
public async Task<IApiResponse<PagedModel<NoticeDTO>>> Table(Guid typeId, int index, int? size = null)
{
await Task.Delay(1500);
return ApiResponse.Ok(new PagedModel<NoticeDTO> { });
}
public async Task<IApiResponse<ClockInResponse>> ClockIn(ClockInRequest request)
{
await Task.Delay(1500);
return ApiResponse.Ok(new ClockInResponse { });
}
public async Task<IApiResponse<IEnumerable<DateTimeOffset>>> ClockInLogs(DateTimeOffset? time)
{
await Task.Delay(1500);
return ApiResponse.Ok(new List<DateTimeOffset> { });
}
public Task<IApiResponse<ClockInResponse>> AccountClockIn()
{
throw new NotImplementedException();
}
}
}
#endif
@@ -17,11 +17,16 @@ namespace System.Application.Services
IVersionClient Version { get; }
IActiveUserClient ActiveUser { get; }
IAccelerateClient Accelerate { get; }
INoticeClient Notice { get; }
IDonateRankingClient DonateRanking { get; }
/// <inheritdoc cref="IApiConnection.DownloadAsync(bool, CancellationToken, string, string, IProgress{float})"/>
Task<IApiResponse> Download(bool isAnonymous, string requestUri, string cacheFilePath, IProgress<float>? progress, CancellationToken cancellationToken = default);
/// <summary>
/// 签到
/// </summary>
/// <returns></returns>
Task<IApiResponse<ClockInResponse>> AccountClockIn();
/// <summary>
/// 请求代理
/// </summary>