mirror of
https://github.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies.git
synced 2026-07-25 06:14:31 +00:00
Refine UX, fix auth crash, and revert to .NET 8.0
- Reverted target framework to .NET 8.0 for stability. - Added autofocus to all dialog input fields (e.g. password dialogs). - Fixed crash when relogging into accounts without Steam Guard and added proper error message. - Unified and improved “Confirm Action” dialog design and text clarity. - Added setting to disable ripple effect animations for better performance. - Reduced minimum auto-confirmation timer interval from 10s to 5s. - App now auto-selects the most appropriate language on first launch. - Added trimming to proxy parse input - Fixed incorrect hint about maFile binding when using login-based mode. - Added ESC key behavior to remove focus from account search - Minor UI polish and cleanup across dialogs.
This commit is contained in:
@@ -361,3 +361,5 @@ MigrationBackup/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
todo/
|
||||
@@ -76,7 +76,7 @@
|
||||
<a href="https://t.me/nebulaauth">t.me/nebulaauth</a>
|
||||
</b>
|
||||
</li>
|
||||
<li><b>FIX:</b> Resolved issue where a "Confirmation Error" notification appeared despite the confirmation being successful.</li>
|
||||
<li><b>FIX:</b> Resolved issue where a "Confirmation Error" notification appeared despite the confirmation being successful.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
FontFamily="{md:MaterialDesignFont}"
|
||||
TextElement.Foreground="{DynamicResource BaseContentBrush}"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance viewModel:MainVM}">
|
||||
d:DataContext="{d:DesignInstance viewModel:MainVM}"
|
||||
md:RippleAssist.IsDisabled="{Binding Settings.RippleDisabled}">
|
||||
<b:Interaction.Behaviors>
|
||||
<windowStyle:WindowChromeRenderedBehavior />
|
||||
</b:Interaction.Behaviors>
|
||||
@@ -63,6 +64,7 @@
|
||||
<TextBlock FontWeight="Bold" Foreground="#9a65b8" Text="{Tr MainWindow.Global.DragNDropHint}" />
|
||||
<md:PackIcon Foreground="#9a65b8" HorizontalAlignment="Center" Width="36" Height="36"
|
||||
Kind="FileReplaceOutline" />
|
||||
|
||||
</StackPanel>
|
||||
<ToolBarTray>
|
||||
<ToolBar ClipToBounds="True" HorizontalContentAlignment="Stretch"
|
||||
@@ -146,6 +148,7 @@
|
||||
<KeyBinding Key="Delete" Command="{Binding RemoveProxyCommand}" />
|
||||
</UIElement.InputBindings>
|
||||
</ComboBox>
|
||||
|
||||
<md:PackIcon Kind="StopAlert" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
Foreground="{DynamicResource ErrorBrush}" Margin="3"
|
||||
ToolTipService.InitialShowDelay="300">
|
||||
@@ -173,6 +176,7 @@
|
||||
ToolTip="{Tr MainWindow.AppBar.Proxy.ProxyAlert.DefaultInUse}"
|
||||
ToolTipService.InitialShowDelay="300"
|
||||
Visibility="{Binding IsDefaultProxy, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||
<Separator />
|
||||
<ToggleButton ToolTip="{Tr MainWindow.AppBar.MarketTimerHint}"
|
||||
IsEnabled="{Binding IsMafileSelected}" Margin="2"
|
||||
Style="{StaticResource MaterialDesignFlatToggleButton}"
|
||||
@@ -346,7 +350,9 @@
|
||||
md:TextFieldAssist.HasClearButton="True" w:FontScaleWindow.Scale="0.7"
|
||||
w:FontScaleWindow.ResizeFont="True" Grid.Row="1" Margin="10,5,10,10"
|
||||
md:HintAssist.Hint="{Tr MainWindow.LeftPart.SearchBoxHint}"
|
||||
Text="{Binding SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{Binding SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
x:Name="SearchField"
|
||||
KeyDown="SearchField_OnKeyDown" />
|
||||
</Grid>
|
||||
|
||||
</Border>
|
||||
@@ -382,7 +388,6 @@
|
||||
Grid.Row="1" Height="4" Style="{StaticResource MaterialDesignLinearProgressBar}"
|
||||
MaxTime="30" TimeRemaining="{Binding CodeProgress, Mode=OneWay}" />
|
||||
</Grid>
|
||||
|
||||
<Button IsEnabled="{Binding IsMafileSelected}" w:FontScaleWindow.Scale="0.7"
|
||||
w:FontScaleWindow.ResizeFont="True" Grid.Row="1"
|
||||
Style="{StaticResource MaterialDesignOutlinedButton}" Margin="0,10,0,10"
|
||||
|
||||
@@ -51,6 +51,12 @@ public partial class MainWindow
|
||||
}
|
||||
}
|
||||
|
||||
private void SearchField_OnKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key != Key.Escape || !SearchField.IsFocused) return;
|
||||
Keyboard.ClearFocus();
|
||||
}
|
||||
|
||||
#region Dran'n'Drop
|
||||
|
||||
private void UIElement_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
|
||||
|
||||
@@ -99,8 +99,8 @@ public static class MaClient
|
||||
}
|
||||
|
||||
return await SteamMobileConfirmationsApi.SendConfirmation(Client, confirmation, mafile.SessionData!.SteamId,
|
||||
mafile,
|
||||
confirm);
|
||||
mafile,
|
||||
confirm);
|
||||
}
|
||||
|
||||
public static async Task<bool> SendMultipleConfirmation(Mafile mafile, IEnumerable<Confirmation> confirmations,
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.IO;
|
||||
using System.Windows.Media;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using NebulaAuth.Core;
|
||||
using NebulaAuth.Utility;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace NebulaAuth.Model;
|
||||
@@ -28,6 +29,7 @@ public partial class Settings : ObservableObject
|
||||
{
|
||||
Instance = new Settings();
|
||||
Instance.PropertyChanged += SettingsOnPropertyChanged;
|
||||
Instance.Language = LanguageUtility.DetectPreferredLanguage();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -70,6 +72,7 @@ public partial class Settings : ObservableObject
|
||||
Instance.LeftOpacity = 0.4;
|
||||
Instance.RightOpacity = 0.8;
|
||||
Instance.ApplyBlurBackground = true;
|
||||
Instance.RippleDisabled = false;
|
||||
Save();
|
||||
}
|
||||
|
||||
@@ -99,6 +102,7 @@ public partial class Settings : ObservableObject
|
||||
[ObservableProperty] private double _backgroundGamma;
|
||||
[ObservableProperty] private bool _applyBlurBackground = true;
|
||||
[ObservableProperty] private ThemeType _themeType = ThemeType.Default;
|
||||
[ObservableProperty] private bool _rippleDisabled;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net9.0-windows7.0</TargetFramework>
|
||||
<TargetFramework>net8.0-windows7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
• Сейчас, при наличии новой версии, отображается стандартное окно обновлений из библиотеки. Планируется сделать кастомный дизайн, для соответствия общему стилю.
|
||||
• В приложении реализованы "совмещённые" подтверждения для торговой площадки. Т.е. при наличии более одного предмета, ожидающего подтверждение, можно либо отменить, либо подтвердить все. В планах добавить расширенный функционал, с возможностью точечного управления.
|
||||
• Добавить кнопку "открыть мафайл" в меню "Файл" по аналогии с открытием папки
|
||||
• Добавить полное шифрование мафайлов по аналогии с SDA
|
||||
• Сделать автоматический билд и загрузку обновления на Github при изменении в мастер ветке
|
||||
• Антик-окно как в MarketApp, возможность сразу открыть браузер напр. на CefSharp с залогиненым аккаунтом
|
||||
• Стабильность авто-подтверждений, возможность задать пользователю порог времени когда льются ошибки и только тогда выключать авто-подтверждение
|
||||
• Безопасное сохранение мафайлов через .tmp / .bak
|
||||
• Создание механизма накопления ошибок, чтобы исправить Patch Tuesday, условно аккаунт может игнорировать ошибки 1-2 часа (настриавемо)
|
||||
|
||||
• Исправить "Перенос гуарда". Иногда не хочет принимать код / подтверждение
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using NebulaAuth.Core;
|
||||
@@ -6,6 +7,7 @@ using NebulaAuth.Model;
|
||||
using SteamLib.Exceptions;
|
||||
using SteamLib.Exceptions.Authorization;
|
||||
using SteamLib.Exceptions.General;
|
||||
using SteamLib.ProtoCore.Enums;
|
||||
using SteamLibForked.Exceptions.Authorization;
|
||||
|
||||
namespace NebulaAuth.Utility;
|
||||
@@ -94,6 +96,18 @@ public static class ExceptionHandler
|
||||
return "LoginException".GetCodeBehindLocalization() + ": " +
|
||||
ErrorTranslatorHelper.TranslateLoginError(e.Error);
|
||||
}
|
||||
case UnsupportedAuthTypeException e:
|
||||
{
|
||||
var requestedType = e.AllowedGuardTypes.First();
|
||||
var msgType = requestedType switch
|
||||
{
|
||||
EAuthSessionGuardType.DeviceCode or EAuthSessionGuardType.DeviceConfirmation => "Guard",
|
||||
EAuthSessionGuardType.EmailCode => "Mail",
|
||||
_ => "Unknown"
|
||||
};
|
||||
|
||||
return GetCodeBehindLocalization("UnsupportedAuthTypeException", msgType);
|
||||
}
|
||||
case not null when handleAllExceptions:
|
||||
{
|
||||
return "UnknownException".GetCodeBehindLocalization() + exception.Message;
|
||||
@@ -112,4 +126,11 @@ public static class ExceptionHandler
|
||||
{
|
||||
return LocManager.GetCodeBehindOrDefault(key, EXCEPTION_HANDLER_LOC_PATH, key);
|
||||
}
|
||||
|
||||
private static string GetCodeBehindLocalization(params string[] path)
|
||||
{
|
||||
var def = path.Length == 0 ? "" : path.Last();
|
||||
var newArr = path.Prepend(EXCEPTION_HANDLER_LOC_PATH).ToArray();
|
||||
return LocManager.GetCodeBehindOrDefault(def, newArr);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using NebulaAuth.Core;
|
||||
|
||||
namespace NebulaAuth.Utility;
|
||||
|
||||
public static class LanguageUtility
|
||||
{
|
||||
public static LocalizationLanguage DetectPreferredLanguage()
|
||||
{
|
||||
var userCulture = CultureInfo.CurrentUICulture;
|
||||
var userLang = userCulture.TwoLetterISOLanguageName;
|
||||
var userRegion = userCulture.Name;
|
||||
|
||||
switch (userLang)
|
||||
{
|
||||
case "ru": return LocalizationLanguage.Russian;
|
||||
case "uk": return LocalizationLanguage.Ukrainian;
|
||||
case "en": return LocalizationLanguage.English;
|
||||
}
|
||||
|
||||
if (userRegion.EndsWith("UA", StringComparison.OrdinalIgnoreCase))
|
||||
return LocalizationLanguage.Ukrainian;
|
||||
|
||||
string[] cisRegions =
|
||||
[
|
||||
"RU", "BY", "KZ", "KG", "TJ", "TM", "UZ", "AM", "AZ", "GE", "MD"
|
||||
];
|
||||
|
||||
if (cisRegions.Any(r => userRegion.EndsWith(r, StringComparison.OrdinalIgnoreCase)))
|
||||
return LocalizationLanguage.Russian;
|
||||
|
||||
return LocalizationLanguage.English;
|
||||
}
|
||||
}
|
||||
@@ -4,42 +4,88 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:theme="clr-namespace:NebulaAuth.Theme"
|
||||
mc:Ignorable="d"
|
||||
Height="Auto" Width="Auto" MaxWidth="500"
|
||||
Background="{DynamicResource WindowBackground}">
|
||||
<Grid Margin="15">
|
||||
<Grid MinHeight="140" MinWidth="350">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock theme:FontScaleWindow.Scale="0.8"
|
||||
theme:FontScaleWindow.ResizeFont="True"
|
||||
HorizontalAlignment="Center" Margin="10,10,10,15"
|
||||
Text="Подтвердите действие"
|
||||
x:Name="ConfirmTextBlock"
|
||||
TextWrapping="WrapWithOverflow" />
|
||||
<Grid Grid.Row="1" Margin="10,0,10,5">
|
||||
<Grid Margin="10,10,10,5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button DockPanel.Dock="Left"
|
||||
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
|
||||
CommandParameter="{StaticResource True}"
|
||||
FontSize="{Binding ElementName=ConfirmTextBlock, Path=FontSize,
|
||||
Converter={StaticResource CoefficientConverter},
|
||||
ConverterParameter=0.85}">
|
||||
ОК
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<!--<materialDesign:PackIcon Kind="WarningCircleOutline" Width="20" Height="20" Margin="0,0,5,0"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{DynamicResource PrimaryContentBrush}" />-->
|
||||
<TextBlock FontStyle="Normal" Foreground="{DynamicResource BaseContentBrush}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center" FontSize="18" Text="{Tr ConfirmCancelDialog.Title}" />
|
||||
</StackPanel>
|
||||
<Button Grid.Column="1" Width="30" Height="30" Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||
HorizontalAlignment="Right" CommandParameter="{StaticResource False}"
|
||||
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}">
|
||||
<materialDesign:PackIcon Kind="Close" Width="24" Height="24" Foreground="IndianRed" />
|
||||
|
||||
</Button>
|
||||
<Button Grid.Column="1" DockPanel.Dock="Right"
|
||||
</Grid>
|
||||
<Separator Grid.Row="1" Opacity="0.7" />
|
||||
<Grid Grid.Row="2" Margin="12">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Border Visibility="{Binding Tip, Converter={StaticResource NullableToVisibilityConverter}}"
|
||||
Margin="10"
|
||||
Padding="5"
|
||||
BorderThickness="1"
|
||||
CornerRadius="12">
|
||||
<Border.BorderBrush>
|
||||
<SolidColorBrush Color="{DynamicResource BaseShadowColor}" Opacity="0.5" />
|
||||
</Border.BorderBrush>
|
||||
<Border.Background>
|
||||
<SolidColorBrush Color="{DynamicResource Base300Color}" Opacity="0.2" />
|
||||
</Border.Background>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon Kind="QuestionMarkCircleOutline" Foreground="{DynamicResource InfoBrush}"
|
||||
Height="22"
|
||||
Width="22" VerticalAlignment="Center" Margin="5,0,0,0" />
|
||||
<TextBlock x:Name="ConfirmTextBlock" VerticalAlignment="Center"
|
||||
MaxWidth="420" FontSize="14"
|
||||
TextWrapping="WrapWithOverflow"
|
||||
Margin="10,10,10,10" Text="Confirm?" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Grid Grid.Row="1" Margin="10,0,10,5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button
|
||||
Width="130"
|
||||
HorizontalAlignment="Left"
|
||||
|
||||
Margin="2,0,4,0"
|
||||
Style="{StaticResource MaterialDesignRaisedButton}"
|
||||
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
|
||||
CommandParameter="{StaticResource False}"
|
||||
FontSize="{Binding ElementName=ConfirmTextBlock, Path=FontSize,
|
||||
Converter={StaticResource CoefficientConverter},
|
||||
ConverterParameter=0.85}">
|
||||
Отмена
|
||||
</Button>
|
||||
CommandParameter="{StaticResource True}">
|
||||
ОК
|
||||
</Button>
|
||||
<Button Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
Width="130"
|
||||
Margin="0,0,2,0"
|
||||
Style="{StaticResource MaterialDesignOutlinedButton}"
|
||||
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
|
||||
CommandParameter="{StaticResource False}">
|
||||
Отмена
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -45,7 +45,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBox Text="{Binding Password, UpdateSourceTrigger=PropertyChanged}"
|
||||
<TextBox TabIndex="0" Text="{Binding Password, UpdateSourceTrigger=PropertyChanged}"
|
||||
|
||||
materialDesign:TextFieldAssist.HasClearButton="True"
|
||||
Padding="10"
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBox Text="{Binding Password, UpdateSourceTrigger=PropertyChanged}"
|
||||
<TextBox TabIndex="0" Text="{Binding Password, UpdateSourceTrigger=PropertyChanged}"
|
||||
|
||||
materialDesign:TextFieldAssist.HasClearButton="True"
|
||||
Padding="10"
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<TextBlock Grid.Row="2" IsHitTestVisible="False" TextWrapping="Wrap" FontWeight="Normal"
|
||||
Text="{Tr SetEncryptedPasswordDialog.DialogText}" theme:FontScaleWindow.Scale="0.8"
|
||||
theme:FontScaleWindow.ResizeFont="True" Margin="10" HorizontalAlignment="Left" />
|
||||
<PasswordBox FontSize="16"
|
||||
<PasswordBox TabIndex="0" FontSize="16" x:Name="PasswordBox"
|
||||
materialDesign:PasswordBoxAssist.Password="{Binding Password, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="10" Grid.Row="3" Style="{StaticResource MaterialDesignFloatingHintRevealPasswordBox}"
|
||||
materialDesign:HintAssist.Hint="{Tr SetEncryptedPasswordDialog.Password}" />
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Image x:Name="CaptchaImage" Stretch="Uniform" />
|
||||
<TextBox Grid.Row="1" Style="{StaticResource MaterialDesignFloatingHintTextBox}" x:Name="CaptchaTB" />
|
||||
<TextBox TabIndex="0" Grid.Row="1" Style="{StaticResource MaterialDesignFloatingHintTextBox}"
|
||||
x:Name="CaptchaTB" />
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<TextBlock Margin="5,0,0,0" Text="{Tr LinkerDialog.Authorization}" />
|
||||
</StackPanel>
|
||||
<TextBox
|
||||
TabIndex="0"
|
||||
Padding="8"
|
||||
FontSize="14"
|
||||
Style="{StaticResource MaterialDesignOutlinedTextBox}"
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
</StackPanel>
|
||||
|
||||
<TextBox
|
||||
TabIndex="0"
|
||||
Padding="8"
|
||||
FontSize="14"
|
||||
Style="{StaticResource MaterialDesignOutlinedTextBox}"
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
MinHeight="500"
|
||||
MinWidth="400"
|
||||
MaxHeight="550"
|
||||
MaxWidth="500"
|
||||
d:DataContext="{d:DesignInstance other:ProxyManagerVM}"
|
||||
Background="Transparent">
|
||||
<Grid>
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="650"
|
||||
FontFamily="{materialDesign:MaterialDesignFont}"
|
||||
MinHeight="600"
|
||||
MinHeight="400"
|
||||
MaxHeight="600"
|
||||
MinWidth="400"
|
||||
MaxWidth="400"
|
||||
d:DataContext="{d:DesignInstance other:SettingsVM}"
|
||||
@@ -46,7 +47,7 @@
|
||||
<TabControl materialDesign:ColorZoneAssist.Background="{DynamicResource Base100Brush}"
|
||||
Style="{StaticResource MaterialDesignUniformTabControl}" Grid.Row="2">
|
||||
<TabItem Header="{Tr SettingsDialog.MainSettings}">
|
||||
<StackPanel Width="340" Margin="10,30,10,10" Orientation="Vertical" HorizontalAlignment="Center">
|
||||
<StackPanel Width="340" Margin="10,20,10,40" Orientation="Vertical" HorizontalAlignment="Center">
|
||||
<ComboBox Style="{StaticResource MaterialDesignFloatingHintComboBox}" Margin="0,15,0,0"
|
||||
FontSize="16"
|
||||
ItemsSource="{Binding Languages}" DisplayMemberPath="Value" SelectedValuePath="Key"
|
||||
@@ -92,7 +93,15 @@
|
||||
|
||||
</TabItem>
|
||||
<TabItem IsEnabled="True" Header="{Tr SettingsDialog.ThemeSettings}">
|
||||
<StackPanel Width="340" Margin="10,30,10,10" Orientation="Vertical" HorizontalAlignment="Center">
|
||||
<StackPanel Width="340" Margin="10,20,10,10" Orientation="Vertical" HorizontalAlignment="Center">
|
||||
<ComboBox Style="{StaticResource MaterialDesignOutlinedComboBox}"
|
||||
Padding="8"
|
||||
Margin="0,15,0,0"
|
||||
FontSize="16"
|
||||
ItemsSource="{Binding ThemeTypes}" DisplayMemberPath="Value" SelectedValuePath="Key"
|
||||
SelectedValue="{Binding ThemeType}"
|
||||
materialDesign:HintAssist.Hint="{Tr SettingsDialog.Theme.CurrentTheme}" />
|
||||
|
||||
<ComboBox Style="{StaticResource MaterialDesignOutlinedComboBox}"
|
||||
Padding="8"
|
||||
Margin="0,15,0,0"
|
||||
@@ -102,15 +111,6 @@
|
||||
SelectedValue="{Binding BackgroundMode}"
|
||||
materialDesign:HintAssist.Hint="{Tr SettingsDialog.BackgroundHint}" />
|
||||
|
||||
<!-- Theme input -->
|
||||
<ComboBox Style="{StaticResource MaterialDesignOutlinedComboBox}"
|
||||
Padding="8"
|
||||
Margin="0,15,0,0"
|
||||
FontSize="16"
|
||||
ItemsSource="{Binding ThemeTypes}" DisplayMemberPath="Value" SelectedValuePath="Key"
|
||||
SelectedValue="{Binding ThemeType}"
|
||||
materialDesign:HintAssist.Hint="{Tr SettingsDialog.Theme.CurrentTheme}" />
|
||||
|
||||
<TextBlock Text="{Tr SettingsDialog.Theme.BackgroundBlur}" Margin="0,15,0,0" />
|
||||
<Slider materialDesign:SliderAssist.HideActiveTrack="True"
|
||||
TickFrequency="5"
|
||||
@@ -156,14 +156,16 @@
|
||||
|
||||
|
||||
<CheckBox Margin="0,15,0,0" Content="{Tr SettingsDialog.Theme.DialogBlur}"
|
||||
IsChecked="{Binding ApplyBlurBackground}" />
|
||||
IsChecked="{Binding ApplyBlurBackground}"
|
||||
FontSize="15" />
|
||||
<CheckBox Margin="0,15,0,0" Content="{Tr SettingsDialog.Theme.RippleDisabled}"
|
||||
FontSize="15"
|
||||
IsChecked="{Binding RippleDisabled}" />
|
||||
<Button Margin="0,15,0,0" Command="{Binding ResetThemeDefaultsCommand}"
|
||||
Content="{Tr SettingsDialog.Theme.Reset}" />
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -227,7 +227,7 @@ public partial class LinkAccountVM : ObservableObject, ISmsCodeProvider, IPhoneN
|
||||
|
||||
Storage.SaveMafile(mafile);
|
||||
File.Delete(Path.Combine("mafiles_backup", mafile.AccountName + ".mafile"));
|
||||
await Done(mafile.RevocationCode ?? string.Empty, mafile.SteamId.Steam64.ToString());
|
||||
await Done(mafile.RevocationCode ?? string.Empty, mafile.SteamId.Steam64.ToString(), login);
|
||||
}
|
||||
|
||||
#region Step 3: Phone Number
|
||||
@@ -280,9 +280,10 @@ public partial class LinkAccountVM : ObservableObject, ISmsCodeProvider, IPhoneN
|
||||
|
||||
#region Step 7: Done
|
||||
|
||||
public async Task Done(string rCode, string steamId)
|
||||
public async Task Done(string rCode, string steamId, string login)
|
||||
{
|
||||
var step = new LinkAccountDoneStepVM(rCode, steamId);
|
||||
var filename = Settings.Instance.UseAccountNameAsMafileName ? login : steamId;
|
||||
var step = new LinkAccountDoneStepVM(rCode, filename);
|
||||
SetCurrentStep(step);
|
||||
await step.GetResultAsync();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using NebulaAuth.Core;
|
||||
using NebulaAuth.Model;
|
||||
using NebulaAuth.Utility;
|
||||
|
||||
namespace NebulaAuth.ViewModel.Linker;
|
||||
|
||||
@@ -13,10 +11,10 @@ public partial class LinkAccountDoneStepVM : LinkAccountStepVM
|
||||
private readonly TaskCompletionSource _doneTcs = new();
|
||||
private readonly string _rCode;
|
||||
|
||||
public LinkAccountDoneStepVM(string rCode, string steamId)
|
||||
public LinkAccountDoneStepVM(string rCode, string fileName)
|
||||
{
|
||||
var tipStr = LocManager.GetCodeBehindOrDefault("MafileLinked", LinkAccountVM.LOCALIZATION_KEY, "MafileLinked");
|
||||
InnerTip = string.Format(tipStr, rCode, steamId);
|
||||
InnerTip = string.Format(tipStr, rCode, fileName);
|
||||
_rCode = rCode;
|
||||
}
|
||||
|
||||
@@ -44,13 +42,6 @@ public partial class LinkAccountDoneStepVM : LinkAccountStepVM
|
||||
[RelayCommand]
|
||||
private void CopyCode()
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(_rCode);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Shell.Logger.Error(ex, "Error whily copying RCode");
|
||||
}
|
||||
ClipboardHelper.Set(_rCode);
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,6 @@ public partial class MainVM : ObservableObject
|
||||
[RelayCommand]
|
||||
public async Task Debug()
|
||||
{
|
||||
Shell.Logger.Info("test");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -86,12 +86,12 @@ public partial class MainVM //MAAC
|
||||
{
|
||||
var timerCheckSeconds = Settings.TimerSeconds;
|
||||
if (timerCheckSeconds == value) return;
|
||||
if (timerCheckSeconds < 10)
|
||||
if (timerCheckSeconds < 5)
|
||||
{
|
||||
timerCheckSeconds = 10; //Guard
|
||||
timerCheckSeconds = 5; //Guard
|
||||
}
|
||||
|
||||
if (value < 10)
|
||||
if (value < 5)
|
||||
{
|
||||
value = timerCheckSeconds;
|
||||
SnackbarController.SendSnackbar(GetLocalization("TimerTooFast"));
|
||||
|
||||
@@ -42,6 +42,7 @@ public partial class ProxyManagerVM : ObservableObject
|
||||
var split = input
|
||||
.Split(Environment.NewLine)
|
||||
.Where(s => string.IsNullOrWhiteSpace(s) == false)
|
||||
.Select(x => x.Trim())
|
||||
.ToArray();
|
||||
|
||||
if (split.Length == 0) return;
|
||||
|
||||
@@ -169,5 +169,11 @@ public partial class SettingsVM : ObservableObject
|
||||
set => Settings.ThemeType = value;
|
||||
}
|
||||
|
||||
public bool RippleDisabled
|
||||
{
|
||||
get => Settings.RippleDisabled;
|
||||
set => Settings.RippleDisabled = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -166,8 +166,8 @@
|
||||
},
|
||||
"MafileProxyInUse": {
|
||||
"en": "Mafile proxy is in use",
|
||||
"ru": "Используется прокси из mafile",
|
||||
"ua": "Використовується проксі з mafile"
|
||||
"ru": "Используется прокси из мафайла",
|
||||
"ua": "Використовується проксі з мафайла"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -366,6 +366,11 @@
|
||||
"ru": "Размытие при открытии диалог. окна",
|
||||
"ua": "Розмиття при відкритті діалог. вікна"
|
||||
},
|
||||
"RippleDisabled": {
|
||||
"en": "Disable ripple animations",
|
||||
"ru": "Отключить анимации «ripple»",
|
||||
"ua": "Вимкнути анімації «ripple»"
|
||||
},
|
||||
"Reset": {
|
||||
"en": "Reset",
|
||||
"ru": "Сбросить",
|
||||
@@ -680,6 +685,13 @@
|
||||
"ua": "Steam Guard перенесено"
|
||||
}
|
||||
},
|
||||
"ConfirmCancelDialog": {
|
||||
"Title": {
|
||||
"ru": "Подтвердите действие",
|
||||
"en": "Confirm action",
|
||||
"ua": "Підтвердіть дію"
|
||||
}
|
||||
},
|
||||
"CodeBehind": {
|
||||
"MainVM": {
|
||||
"SuccessfulLogin": {
|
||||
@@ -698,9 +710,13 @@
|
||||
"ua": "Відсутній RCode"
|
||||
},
|
||||
"ConfirmRemovingAuthenticator": {
|
||||
"ru": "Вы точно уверены что хотите удалить аутентификатор?",
|
||||
"en": "Are you sure you want to remove authenticator?",
|
||||
"ua": "Ви точно впевнені що хочете видалити аутентифікатор?"
|
||||
"ru":
|
||||
"Вы точно уверены, что хотите удалить аутентификатор?\r\nПосле этого вы не сможете обмениваться, использовать торговую площадку 15 дней. Мафайл будет удалён навсегда",
|
||||
"en":
|
||||
"Are you sure you want to remove the authenticator?\r\nAfter that, you will not be able to trade or use the marketplace for 15 days. Mafile will be deleted permanently",
|
||||
"ua":
|
||||
"Ви точно впевнені, що хочете видалити автентифікатор?\r\nПісля цього ви не зможете обмінюватися, використовувати торгову площадку 15 днів. Мафайл буде видалено назавжди"
|
||||
|
||||
},
|
||||
"AuthenticatorRemoved": {
|
||||
"ru": "Аутентификатор удален",
|
||||
@@ -733,12 +749,12 @@
|
||||
"ua": "Помилка підтвердження"
|
||||
},
|
||||
"ConfirmMafileOverwrite": {
|
||||
"ru": "Внимание, мафайл уже присутствует в папке mafiles.\r\nПерезаписать мафайлы, которые конфликтуют?",
|
||||
"en": "Attention, mafile already exists in mafiles folder.\r\nOverwrite conflicting mafiles?",
|
||||
"ua": "Увага, мафайл вже присутній у папці mafiles.\r\nПерезаписати мафайли, які конфліктують?"
|
||||
"ru": "Внимание, мафайл(-ы) уже присутствует в папке mafiles.\r\nПерезаписать мафайлы, которые конфликтуют?",
|
||||
"en": "Attention, mafile(-s) already exists in mafiles folder.\r\nOverwrite conflicting mafiles?",
|
||||
"ua": "Увага, мафайл(-и) вже присутній у папці mafiles.\r\nПерезаписати мафайли, які конфліктують?"
|
||||
},
|
||||
"MafileImportError": {
|
||||
"ru": "Ошибка импорта мафайла",
|
||||
"ru": "Ошибка при импорте мафайла",
|
||||
"en": "Mafile import error",
|
||||
"ua": "Помилка імпорту мафайла"
|
||||
},
|
||||
@@ -769,16 +785,16 @@
|
||||
},
|
||||
"RemoveMafileConfirmation": {
|
||||
"ru":
|
||||
"Удалить мафайл? Мафайл будет перемещен в папку 'mafiles_removed' (Это действие не удаляет Steam Guard с аккаунта)",
|
||||
"Удалить mafile?\r\nМафайл будет перемещен в папку 'mafiles_removed'\r\nЭто действие НЕ удаляет Steam Guard с аккаунта",
|
||||
"en":
|
||||
"Remove mafile? Mafile will be moved to 'mafiles_removed' directory (This action does not remove the Steam Guard from the account)",
|
||||
"Remove mafile?\r\nMafile will be moved to 'mafiles_removed' directory\r\nThis action will NOT remove the Steam Guard from the account",
|
||||
"ua":
|
||||
"Видалити мафайл? Мафайл буде переміщено у каталог 'mafiles_removed' (Ця дія не видаляє автентифікатор з облікового запису)"
|
||||
"Видалити mafile?\r\nМафайл буде переміщено у каталог 'mafiles_removed'\r\nЦя дія НЕ видаляє автентифікатор з облікового запису"
|
||||
},
|
||||
"CantRemoveAlreadyExist": {
|
||||
"ru": "Не удалось переместить мафайл, возможно в папке уже существует мафайл с таким именем.",
|
||||
"ru": "Не удалось переместить mafile, возможно в папке уже существует мафайл с таким именем.",
|
||||
"en": "Can't move mafile, maybe mafile with same name already exists in mafiles_removed folder.",
|
||||
"ua": "Не вдалося перемістити мафайл, можливо в папці вже існує мафайл з таким іменем."
|
||||
"ua": "Не вдалося перемістити mafile, можливо в папці вже існує мафайл з таким іменем."
|
||||
},
|
||||
"CantRemoveMafile": {
|
||||
"ru": "Не удалось удалить (переместить) мафайл:",
|
||||
@@ -1132,6 +1148,24 @@
|
||||
"en": "Login error: ",
|
||||
"ua": "Помилка входу: "
|
||||
},
|
||||
"UnsupportedAuthTypeException": {
|
||||
"Mail": {
|
||||
"ru": "Ошибка: Был запрошен код с почты. Steam Guard не активирован",
|
||||
"en": "Error: Email code was requested. Steam Guard is not activated",
|
||||
"ua": "Помилка: Був запрошений код з пошти. Steam Guard не активовано"
|
||||
},
|
||||
"Guard": {
|
||||
"ru": "Ошибка: Был запрошен вход с помощью Steam Guard. На аккаунте уже активирован мобильный аутентификатор",
|
||||
"en": "Error: Login with Steam Guard was requested. Mobile authenticator is already activated on the account",
|
||||
"ua":
|
||||
"Помилка: Був запрошений вхід за допомогою Steam Guard. На акаунті вже активовано мобільний автентифікатор"
|
||||
},
|
||||
"Unknown": {
|
||||
"ru": "Ошибка: Неизвестный тип аутентификации",
|
||||
"en": "Error: Unknown authentication type",
|
||||
"ua": "Помилка: Невідомий тип автентифікації"
|
||||
}
|
||||
},
|
||||
"UnknownException": {
|
||||
"ru": "Неизвестная ошибка: ",
|
||||
"en": "Unknown error: ",
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AchiesUtilities.Newtonsoft.JSON" Version="1.3.3" />
|
||||
<PackageReference Include="AchiesUtilities.Web" Version="1.3.2" />
|
||||
<PackageReference Include="AchiesUtilities.Newtonsoft.JSON" Version="1.3.8" />
|
||||
<PackageReference Include="AchiesUtilities.Web" Version="1.3.8" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.12.1" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2025.2.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="protobuf-net" Version="3.2.52" />
|
||||
|
||||
@@ -6,13 +6,13 @@ namespace SteamLib.Utility;
|
||||
public static partial class SteamIdParser
|
||||
{
|
||||
[GeneratedRegex("^7656119([0-9]{10})$", RegexOptions.Compiled)]
|
||||
public static partial Regex Steam64Regex { get; }
|
||||
public static partial Regex Steam64Regex();
|
||||
|
||||
[GeneratedRegex(@"STEAM_(?<universe>[0-9]):(?<lowestBit>[0-9]):(?<highestBits>[0-9]{1,10})", RegexOptions.Compiled)]
|
||||
public static partial Regex Steam2Regex { get; }
|
||||
public static partial Regex Steam2Regex();
|
||||
|
||||
[GeneratedRegex(@"^\[?(?<type>[a-zA-Z]):1:(?<id>[0-9]{1,10})\]$", RegexOptions.Compiled)]
|
||||
public static partial Regex Steam3Regex { get; }
|
||||
public static partial Regex Steam3Regex();
|
||||
|
||||
|
||||
#region TryParse
|
||||
@@ -46,7 +46,7 @@ public static partial class SteamIdParser
|
||||
{
|
||||
result = default;
|
||||
if (input == null) return false;
|
||||
var match64 = Steam64Regex.Match(input);
|
||||
var match64 = Steam64Regex().Match(input);
|
||||
if (match64.Success)
|
||||
{
|
||||
return TryParse64(long.Parse(match64.Value), out result);
|
||||
@@ -69,7 +69,7 @@ public static partial class SteamIdParser
|
||||
|
||||
public static bool TryParse2(string input, out SteamId2 result)
|
||||
{
|
||||
var match2 = Steam2Regex.Match(input);
|
||||
var match2 = Steam2Regex().Match(input);
|
||||
if (match2.Success)
|
||||
{
|
||||
var universe = byte.Parse(match2.Groups["universe"].Value);
|
||||
@@ -85,7 +85,7 @@ public static partial class SteamIdParser
|
||||
|
||||
public static bool TryParse3(string input, out SteamId3 result)
|
||||
{
|
||||
var match3 = Steam3Regex.Match(input);
|
||||
var match3 = Steam3Regex().Match(input);
|
||||
if (match3.Success)
|
||||
{
|
||||
var type = match3.Groups["type"].Value[0];
|
||||
@@ -137,7 +137,7 @@ public static partial class SteamIdParser
|
||||
|
||||
public static SteamId2 Parse2(string input)
|
||||
{
|
||||
var match2 = Steam2Regex.Match(input);
|
||||
var match2 = Steam2Regex().Match(input);
|
||||
if (match2.Success)
|
||||
{
|
||||
var universe = byte.Parse(match2.Groups["universe"].Value);
|
||||
@@ -151,7 +151,7 @@ public static partial class SteamIdParser
|
||||
|
||||
public static SteamId3 Parse3(string input)
|
||||
{
|
||||
var match3 = Steam3Regex.Match(input);
|
||||
var match3 = Steam3Regex().Match(input);
|
||||
if (match3.Success)
|
||||
{
|
||||
var type = match3.Groups["type"].Value[0];
|
||||
|
||||
Reference in New Issue
Block a user