From 4b547e19c478c516c5d879c5130e943e1b0e5dab Mon Sep 17 00:00:00 2001 From: bohdanbtw <127321482+bohdanbtw@users.noreply.github.com> Date: Thu, 12 Mar 2026 15:27:03 +0000 Subject: [PATCH] feat(confirmations): reveal items in grouped market sell confirmations (#18) Grouped market sell confirmations previously appeared as a single row showing only the item count (e.g. "Sell 4 pcs"). This made it difficult to verify which items were being confirmed or their prices. Add an expandable grouped confirmation that reveals individual items with their icon, name and price. Also allow confirming or canceling items individually while keeping confirm-all and cancel-all actions. Includes a scrollable list for large batches and minor UI/code cleanup. Co-authored-by: bohdanbtw [bohdanbtw@DESKTOP-ANGF2KJ](mailto:bohdanbtw@DESKTOP-ANGF2KJ) --- src/NebulaAuth/Core/DialogsController.cs | 4 +- src/NebulaAuth/Model/Mafiles/Storage.cs | 6 +- .../View/ConfirmationTemplates.xaml | 123 +++++++++++++----- .../ViewModel/MainVM_Confirmations.cs | 69 ++++++++-- src/NebulaAuth/ViewModel/MainVM_File.cs | 2 +- src/NebulaAuth/localization.loc.json | 28 ++++ 6 files changed, 182 insertions(+), 50 deletions(-) diff --git a/src/NebulaAuth/Core/DialogsController.cs b/src/NebulaAuth/Core/DialogsController.cs index 9ee4da4..7459707 100644 --- a/src/NebulaAuth/Core/DialogsController.cs +++ b/src/NebulaAuth/Core/DialogsController.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading.Tasks; using MaterialDesignThemes.Wpf; using NebulaAuth.Model; @@ -130,7 +130,7 @@ public static class DialogsController var content = msg == null ? new ConfirmCancelDialog() : new ConfirmCancelDialog(msg); var result = await DialogHost.Show(content); - return result != null && (bool) result; + return result != null && (bool)result; } public static async Task ShowTextFieldDialog(string? title = null, string? msg = null) diff --git a/src/NebulaAuth/Model/Mafiles/Storage.cs b/src/NebulaAuth/Model/Mafiles/Storage.cs index 77c66dd..e116832 100644 --- a/src/NebulaAuth/Model/Mafiles/Storage.cs +++ b/src/NebulaAuth/Model/Mafiles/Storage.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -51,7 +51,7 @@ public static class Storage await Task.Run(() => { return Parallel.ForEachAsync(files, - new ParallelOptions {CancellationToken = token, MaxDegreeOfParallelism = threadCount}, + new ParallelOptions { CancellationToken = token, MaxDegreeOfParallelism = threadCount }, async (file, ct) => { try @@ -218,7 +218,7 @@ public static class Storage if (counter % 5 == 0) { - progress?.Report(counter / (double) files.Count); + progress?.Report(counter / (double)files.Count); await Task.Delay(10); } } diff --git a/src/NebulaAuth/View/ConfirmationTemplates.xaml b/src/NebulaAuth/View/ConfirmationTemplates.xaml index 26542d2..eea568e 100644 --- a/src/NebulaAuth/View/ConfirmationTemplates.xaml +++ b/src/NebulaAuth/View/ConfirmationTemplates.xaml @@ -1,4 +1,4 @@ - - @@ -175,36 +174,96 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -227,7 +286,7 @@ diff --git a/src/NebulaAuth/ViewModel/MainVM_Confirmations.cs b/src/NebulaAuth/ViewModel/MainVM_Confirmations.cs index 872da27..b06d998 100644 --- a/src/NebulaAuth/ViewModel/MainVM_Confirmations.cs +++ b/src/NebulaAuth/ViewModel/MainVM_Confirmations.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; @@ -76,18 +76,27 @@ public partial class MainVM //Confirmations return SendConfirmation(SelectedMafile, confirmation, false); } + + private async Task SendConfirmation(Mafile mafile, Confirmation confirmation, bool confirm) { bool result; + try { - if (confirmation is MarketMultiConfirmation multi) + switch (confirmation) { - result = await MaClient.SendMultipleConfirmation(mafile, multi.Confirmations, confirm); - } - else - { - result = await MaClient.SendConfirmation(mafile, confirmation, confirm); + case MarketMultiConfirmation multi: + result = await MaClient.SendMultipleConfirmation(mafile, multi.Confirmations, confirm); + break; + + case MarketConfirmation market: + result = await MaClient.SendConfirmation(mafile, market, confirm); + break; + + default: + result = await MaClient.SendConfirmation(mafile, confirmation, confirm); + break; } } catch (Exception ex) @@ -96,13 +105,49 @@ public partial class MainVM //Confirmations return; } - if (result) - { - Confirmations.Remove(confirmation); - } - else + if (!result) { SnackbarController.SendSnackbar(GetLocalization("ConfirmationError")); + return; } + + UpdateConfirmationState(confirmation); + } + + private void UpdateConfirmationState(Confirmation confirmation) + { + if (confirmation is MarketConfirmation item) + { + var parent = Confirmations + .OfType() + .FirstOrDefault(p => p.Confirmations.Contains(item)); + + if (parent == null) + { + Confirmations.Remove(item); + return; + } + + parent.Confirmations.Remove(item); + + if (parent.Confirmations.Count == 0) + { + Confirmations.Remove(parent); + return; + } + + if (parent.Confirmations.Count == 1) + { + var remaining = parent.Confirmations[0]; + var idx = Confirmations.IndexOf(parent); + Confirmations[idx] = remaining; + return; + } + + parent.Time = parent.Confirmations.FirstOrDefault()?.Time ?? parent.Time; + return; + } + + Confirmations.Remove(confirmation); } } \ No newline at end of file diff --git a/src/NebulaAuth/ViewModel/MainVM_File.cs b/src/NebulaAuth/ViewModel/MainVM_File.cs index 1341adc..bbe365d 100644 --- a/src/NebulaAuth/ViewModel/MainVM_File.cs +++ b/src/NebulaAuth/ViewModel/MainVM_File.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Specialized; using System.Diagnostics; using System.IO; diff --git a/src/NebulaAuth/localization.loc.json b/src/NebulaAuth/localization.loc.json index 08c7d47..0bf795e 100644 --- a/src/NebulaAuth/localization.loc.json +++ b/src/NebulaAuth/localization.loc.json @@ -410,6 +410,34 @@ "zh": "购买", "ua": "Покупка", "fr": "Acheter" + }, + "ConfirmAll": { + "en": "Confirm all", + "ru": "Подтвердить все", + "zh": "全部确认", + "ua": "Підтвердити все", + "fr": "Tout confirmer" + }, + "CancelAll": { + "en": "Cancel all", + "ru": "Отклонить все", + "zh": "全部取消", + "ua": "Відхилити все", + "fr": "Tout annuler" + }, + "ConfirmOne": { + "en": "Confirm this item", + "ru": "Подтвердить этот предмет", + "zh": "确认此物品", + "ua": "Підтвердити цей предмет", + "fr": "Confirmer cet objet" + }, + "CancelOne": { + "en": "Cancel this item", + "ru": "Отклонить этот предмет", + "zh": "取消此物品", + "ua": "Відхилити цей предмет", + "fr": "Annuler cet objet" } }, "CodeCopied": {