Release v1.0.3: Enhanced NDEF reading and UX improvements
Major Improvements: - Implement exclusive card access with retry logic and exponential backoff - Fix Type 4 NDEF length parsing (now correctly reads NTAG424 and similar chips) - Add enhanced card type detection (Type 2 vs Type 4) - Implement chunked reading for large NDEF messages - Add proper TLV parsing for Type 2 tags Bug Fixes: - Fix WPF window lifecycle issue (visual tree error on reopen) - Fix NDEF length parsing incorrectly detecting extended format - Correct data offset for Type 4 tag reading New Features: - Multi-line log selection and copy to clipboard - Context menu with Copy Selected Lines, Copy All, Select All - Runtime version roll-forward support (.NET 8.0.x compatibility) Technical Details: - Type 4 tags now use correct 2-byte NLEN field per NFC Forum spec - Removed incorrect 3-byte extended length detection - Window now hides instead of closing for proper tray app behavior - Connection attempts exclusive access first, falls back to shared mode - Status timeout increased from 0ms to 1000ms for better card detection
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
using System.ComponentModel;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using NfcActions.Services;
|
||||
using NfcActions.ViewModels;
|
||||
|
||||
namespace NfcActions;
|
||||
@@ -39,4 +43,84 @@ public partial class MainWindow : Window
|
||||
// Silently fail if browser can't be opened
|
||||
}
|
||||
}
|
||||
|
||||
private void CopySelectedLogs_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var selectedItems = LogListBox.SelectedItems.Cast<LogEntry>().ToList();
|
||||
if (selectedItems.Count == 0)
|
||||
{
|
||||
MessageBox.Show("No log entries selected. Please select one or more lines first.",
|
||||
"No Selection",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
var logText = new StringBuilder();
|
||||
foreach (var entry in selectedItems)
|
||||
{
|
||||
logText.AppendLine(entry.FormattedMessage);
|
||||
}
|
||||
|
||||
Clipboard.SetText(logText.ToString());
|
||||
|
||||
MessageBox.Show($"Copied {selectedItems.Count} log {(selectedItems.Count == 1 ? "entry" : "entries")} to clipboard.",
|
||||
"Copied",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Failed to copy to clipboard: {ex.Message}",
|
||||
"Error",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyAllLogs_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DataContext is MainViewModel viewModel)
|
||||
{
|
||||
var allEntries = viewModel.LogEntries.ToList();
|
||||
if (allEntries.Count == 0)
|
||||
{
|
||||
MessageBox.Show("No log entries available.",
|
||||
"Empty Log",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
var logText = new StringBuilder();
|
||||
foreach (var entry in allEntries)
|
||||
{
|
||||
logText.AppendLine(entry.FormattedMessage);
|
||||
}
|
||||
|
||||
Clipboard.SetText(logText.ToString());
|
||||
|
||||
MessageBox.Show($"Copied all {allEntries.Count} log entries to clipboard.",
|
||||
"Copied",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Information);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Failed to copy to clipboard: {ex.Message}",
|
||||
"Error",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectAllLogs_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
LogListBox.SelectAll();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user