Add support to new confirmation type (Purchase) and improve localization and snackbars

This commit is contained in:
achiez
2025-07-09 22:19:21 +03:00
parent 99982cacb6
commit 3abc12f4bc
16 changed files with 97 additions and 22 deletions
+22 -1
View File
@@ -9,9 +9,30 @@
<ResourceDictionary>
<converters:CoefficientConverter x:Key="CoefficientConverter" />
<converters:ReverseBooleanConverter x:Key="ReverseBooleanConverter" />
<converters:ProxyTextConverter x:Key="ProxyTextConverter" />
<converters:ProxyDataTextConverter x:Key="ProxyDataTextConverter" />
<converters:MultiCommandParameterConverter x:Key="MultiCommandParameterConverter" />
<converters:ColorToBrushConverter x:Key="ColorToBrushConverter" />
<converters:AnyMafilesToVisibilityConverter x:Key="AnyMafilesToVisibilityConverter" />
<converters:PortableMaClientStatusToColorConverter x:Key="PortableMaClientStatusToColorConverter" />
<converters:NullableToBooleanConverter x:Key="NullableToBooleanConverter" />
<!-- Background converters-->
<background:BackgroundImageVisibleConverter x:Key="BackgroundImageVisibleConverter" />
<background:BackgroundSourceConverter x:Key="BackgroundSourceConverter" />
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<materialDesign:NullableToVisibilityConverter x:Key="NullableToVisibilityConverter" />
<system:Boolean x:Key="True">True</system:Boolean>
<system:Boolean x:Key="False">False</system:Boolean>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Converters/Converters.xaml"/>
<ResourceDictionary Source="Theme/Themes/DefaultTheme.xaml" />
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesign3.Defaults.xaml" />
+1 -1
View File
@@ -44,7 +44,7 @@ public class SnackbarController
private static TimeSpan GetSnackbarTime(string str)
{
var duration = str.Length / 0.03;
var duration = str.Length / 0.022;
if (duration < MIN_SNACKBAR_TIME)
{
duration = MIN_SNACKBAR_TIME;
@@ -90,7 +90,8 @@ public partial class PortableMaClient : ObservableObject, IDisposable
var toConfirm = new List<Confirmation>();
if (AutoConfirmMarket)
{
var market = conf.Where(c => c.ConfType == ConfirmationType.MarketSellTransaction);
var market = conf.Where(c =>
c.ConfType is ConfirmationType.MarketSellTransaction or ConfirmationType.Purchase);
toConfirm.AddRange(market);
}
+1
View File
@@ -40,5 +40,6 @@ public static class Shell
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Logger.Fatal((Exception) e.ExceptionObject);
LogManager.Shutdown();
}
}
+1
View File
@@ -11,3 +11,4 @@
• Стабильность авто-подтверждений, возможность задать пользователю порог времени когда льются ошибки и только тогда выключать авто-подтверждение
• Безопасное сохранение мафайлов через .tmp / .bak
• Создание механизма накопления ошибок, чтобы исправить Patch Tuesday, условно аккаунт может игнорировать ошибки 1-2 часа (настриавемо)
@@ -207,4 +207,31 @@
</Button>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type confirmations:PurchaseConfirmation}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<materialDesign:PackIcon Width="20" Height="20" VerticalAlignment="Center" DockPanel.Dock="Left"
Kind="ShopComplete" Margin="0,0,10,0" />
<TextBlock VerticalAlignment="Center" Grid.Column="1" Text="{Tr MainWindow.ConfirmationTemplates.Purchase}" />
<TextBlock VerticalAlignment="Center" Grid.Column="2" HorizontalAlignment="Right"
Text="{Binding Time, StringFormat=t}" />
<Button Margin="5,0,0,0" VerticalAlignment="Center" Grid.Column="3"
Style="{StaticResource MaterialDesignIconButton}"
Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.(vm:MainVM.ConfirmCommand)}"
CommandParameter="{Binding }">
<materialDesign:PackIcon Kind="Check" />
</Button>
<Button Grid.Column="4" Style="{StaticResource MaterialDesignIconButton}"
Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.(vm:MainVM.CancelCommand)}"
CommandParameter="{Binding }">
<materialDesign:PackIcon Kind="Close" />
</Button>
</Grid>
</DataTemplate>
</ResourceDictionary>
+11 -6
View File
@@ -255,6 +255,11 @@
"en": "Market",
"ru": "Маркет",
"ua": "Маркет"
},
"Purchase": {
"en": "Purchase",
"ru": "Покупка",
"ua": "Покупка"
}
},
"CodeCopied": {
@@ -1098,14 +1103,14 @@
},
"ExceptionHandler": {
"SessionInvalidException": {
"ru": "Сессия истекла. Попробуйте обновить ее через меню или залогиниться заново",
"en": "Session expired. Try to refresh it through menu or login again",
"ua": "Сесія прострочена. Спробуйте оновити її через меню або залогінитися знову"
"ru": "Сессия истекла. Попробуйте обновить ее или залогиниться заново (Аккаунт → войти)",
"en": "Session expired. Try to refresh it or login again (Account → Login)",
"ua": "Сесія прострочена. Спробуйте оновити її через меню або залогінитися знову (Акаунт → Увійти)"
},
"SessionExpiredException": {
"ru": "Сессия полностью истекла. Нужно залогиниться заново",
"en": "Session fully expired. Need to login again",
"ua": "Сесія повніст'ю прострочена'. Потрібно залогінитися знову"
"ru": "Сессия полностью истекла. Нужно залогиниться заново (Аккаунт → Войти)",
"en": "Session fully expired. Need to login again (Account → Login)",
"ua": "Сесія повніст'ю прострочена'. Потрібно залогінитися знову (Акаунт → Увійти)"
},
"TaskCanceledException": {
"ru": "Произошла отмена операции",
@@ -2,7 +2,7 @@
public class AccountRecoveryConfirmation : Confirmation
{
public AccountRecoveryConfirmation(long id, ulong nonce, long creator, string typeName) : base(id, nonce, 6,
public AccountRecoveryConfirmation(long id, ulong nonce, ulong creator, string typeName) : base(id, nonce, 6,
creator, ConfirmationType.AccountRecovery, typeName)
{
}
@@ -12,7 +12,7 @@ public class Confirmation
/// <summary>
/// Represents either the Trade Offer ID or market transaction ID that caused this confirmation to be created.
/// </summary>
public long CreatorId { get; }
public ulong CreatorId { get; }
public string TypeName { get; init; }
public string HeadLine { get; init; } = string.Empty;
@@ -31,7 +31,7 @@ public class Confirmation
/// </summary>
public int IntType;
public Confirmation(long id, ulong nonce, int intType, long creatorId, ConfirmationType confType, string typeName)
public Confirmation(long id, ulong nonce, int intType, ulong creatorId, ConfirmationType confType, string typeName)
{
Id = id;
Nonce = nonce;
@@ -6,7 +6,7 @@ public class MarketConfirmation : Confirmation
public string ItemName { get; init; } = string.Empty;
public string PriceString { get; init; } = string.Empty;
public MarketConfirmation(long id, ulong key, long creator, string typeName) : base(id, key, 3, creator,
public MarketConfirmation(long id, ulong key, ulong creator, string typeName) : base(id, key, 3, creator,
ConfirmationType.MarketSellTransaction, typeName)
{
}
@@ -0,0 +1,8 @@
namespace SteamLib.SteamMobile.Confirmations;
public class PurchaseConfirmation : Confirmation
{
public PurchaseConfirmation(long id, ulong nonce, int intType, ulong creatorId, string typeName) : base(id, nonce, intType, creatorId, ConfirmationType.Purchase, typeName)
{
}
}
@@ -2,7 +2,7 @@
public class RegisterApiKeyConfirmation : Confirmation
{
public RegisterApiKeyConfirmation(long id, ulong nonce, long creatorId, string typeName) : base(id, nonce, 8,
public RegisterApiKeyConfirmation(long id, ulong nonce, ulong creatorId, string typeName) : base(id, nonce, 8,
creatorId, ConfirmationType.RegisterApiKey, typeName)
{
}
@@ -7,9 +7,9 @@ public class TradeConfirmation : Confirmation
public bool IsReceiveNothing { get; set; }
public override TradeConfirmationDetails? Details { get; }
public long TradeId => CreatorId;
public ulong TradeId => CreatorId;
public TradeConfirmation(long id, ulong nonce, long creator, string typeName) : base(id, nonce, 1, creator,
public TradeConfirmation(long id, ulong nonce, ulong creator, string typeName) : base(id, nonce, 1, creator,
ConfirmationType.Trade, typeName)
{
}
@@ -6,5 +6,6 @@ public enum ConfirmationType
Trade = 2,
MarketSellTransaction = 3,
AccountRecovery = 6,
RegisterApiKey = 9
RegisterApiKey = 9,
Purchase = 12
}
@@ -23,7 +23,7 @@ public class ConfirmationJson
[JsonProperty("type")] public ConfirmationType Type { get; set; }
[JsonProperty("type_name")] public string TypeName { get; set; } = string.Empty;
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("creator_id")] public long CreatorId { get; set; }
[JsonProperty("creator_id")] public ulong CreatorId { get; set; }
[JsonProperty("nonce")] public ulong Nonce { get; set; }
[JsonProperty("creation_time")] public UnixTimeStamp CreationTime { get; set; }
[JsonProperty("cancel")] public string Cancel { get; set; } = string.Empty;
@@ -77,6 +77,7 @@ public static class MobileConfirmationScrapper
ConfirmationType.AccountRecovery => GetAccountRecoveryConfirmation(json),
ConfirmationType.MarketSellTransaction => GetMarketConfirmation(json),
ConfirmationType.RegisterApiKey => GetRegisterApiKeyConfirmation(json),
ConfirmationType.Purchase => GetPurchaseConfirmation(json),
_ => new Confirmation(json.Id, json.Nonce, (int) json.Type, json.CreatorId, json.Type, json.TypeName)
{
Time = json.CreationTime.ToLocalDateTime()
@@ -166,4 +167,13 @@ public static class MobileConfirmationScrapper
PriceString = string.Empty //TODO:
};
}
private static PurchaseConfirmation GetPurchaseConfirmation(ConfirmationJson confirmation)
{
return new PurchaseConfirmation(confirmation.Id, confirmation.Nonce, (int) confirmation.Type,
confirmation.CreatorId, confirmation.TypeName)
{
Time = confirmation.CreationTime.ToLocalDateTime()
};
}
}