Add "Copy QR Code" button with clipboard support
Implemented a copy-to-clipboard button for QR codes, including Blazor logic for feedback and disabled states. Injected IJSRuntime for JS interop and added supporting JS functions for image copying and fallback download. Reduced QR code image size for better compatibility. Added responsive and accessible CSS for the new button. Cleaned up timers and feedback state on component disposal.
This commit is contained in:
+74
-3
@@ -2,6 +2,7 @@
|
||||
@using QRCoder
|
||||
@using SixLabors.ImageSharp.Formats
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
@inject IJSRuntime JSRuntime
|
||||
<PageTitle>QRPay - QR Payment Generator</PageTitle>
|
||||
|
||||
<div class="qrpay-container">
|
||||
@@ -72,7 +73,24 @@
|
||||
</div>
|
||||
|
||||
<div class="qrcode-display">
|
||||
<img src="@QRCodeStr" alt="Payment QR Code" />
|
||||
<img id="qrcode-image" src="@QRCodeStr" alt="Payment QR Code" />
|
||||
|
||||
<!-- Copy Button -->
|
||||
<button class="btn-copy @(_isCopying ? "copying" : "")" @onclick="@CopyQRCodeToClipboard" disabled="@_isCopying">
|
||||
@if (_isCopying)
|
||||
{
|
||||
<span class="copy-spinner"></span>
|
||||
<span>Copying...</span>
|
||||
}
|
||||
else if (_copySuccess)
|
||||
{
|
||||
<span>✓ Copied!</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>📋 Copy QR Code</span>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="payment-details">
|
||||
@@ -105,6 +123,9 @@
|
||||
private string QRCodeStr = string.Empty;
|
||||
private bool _showQRCode = false;
|
||||
private bool _isGenerating = false;
|
||||
private bool _isCopying = false;
|
||||
private bool _copySuccess = false;
|
||||
private System.Threading.Timer? _copySuccessTimer;
|
||||
|
||||
public class PaymentModel
|
||||
{
|
||||
@@ -154,10 +175,11 @@
|
||||
var payBySquare = new PayBySquareTextGenerator.PayBySquareOverkill(payment);
|
||||
var stringData = payBySquare.GeneratePayBySquareOverkillString();
|
||||
|
||||
// Generate QR code data
|
||||
// Generate QR code data - smaller size for better clipboard handling
|
||||
using var qrCodeData = QRCodeGenerator.GenerateQrCode(stringData, QRCodeGenerator.ECCLevel.Q);
|
||||
using var qrCode = new PngByteQRCode(qrCodeData);
|
||||
byte[] qrCodeImage = qrCode.GetGraphic(20);
|
||||
// Reduced from 20 to 10 for smaller clipboard image
|
||||
byte[] qrCodeImage = qrCode.GetGraphic(10);
|
||||
|
||||
QRCodeStr = $"data:image/png;base64,{Convert.ToBase64String(qrCodeImage)}";
|
||||
}
|
||||
@@ -172,11 +194,60 @@
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CopyQRCodeToClipboard()
|
||||
{
|
||||
try
|
||||
{
|
||||
_isCopying = true;
|
||||
_copySuccess = false;
|
||||
StateHasChanged();
|
||||
|
||||
// Use JavaScript to copy the QR code image to clipboard with smaller size
|
||||
var success = await JSRuntime.InvokeAsync<bool>("copyImageToClipboardSmall", "qrcode-image");
|
||||
|
||||
_isCopying = false;
|
||||
|
||||
if (success)
|
||||
{
|
||||
_copySuccess = true;
|
||||
StateHasChanged();
|
||||
|
||||
// Reset the success state after 3 seconds
|
||||
_copySuccessTimer?.Dispose();
|
||||
_copySuccessTimer = new System.Threading.Timer(_ =>
|
||||
{
|
||||
InvokeAsync(() =>
|
||||
{
|
||||
_copySuccess = false;
|
||||
StateHasChanged();
|
||||
});
|
||||
}, null, TimeSpan.FromSeconds(3), Timeout.InfiniteTimeSpan);
|
||||
}
|
||||
else
|
||||
{
|
||||
StateHasChanged();
|
||||
// Could show an error message here if needed
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_isCopying = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void GoBack()
|
||||
{
|
||||
_showQRCode = false;
|
||||
QRCodeStr = string.Empty;
|
||||
paymentModel = new PaymentModel(); // Reset the form
|
||||
_copySuccess = false;
|
||||
_copySuccessTimer?.Dispose();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_copySuccessTimer?.Dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user