fix: improve paste support for PIN code input fields

- Add support for pasting multi-digit verification codes
- Filter pasted content to alphanumeric characters only
- Always start filling from the first field when pasting
- Optimize performance by updating all fields at once
- Support both numeric and alphanumeric codes (e.g., 123456, A1B2C3)

Fixes the issue where pasting a 6-digit code like '123456' would only
show the last digit '6' in the first field. Now all digits are correctly
distributed across all input fields.

This improvement benefits both SignInSMSView and SignIn2FAView since they
share the same PinCodeTextField component.
This commit is contained in:
Shuhari 2025-11-12 15:28:03 +08:00
parent 1a0d3353b9
commit a2628edceb

View file

@ -149,6 +149,34 @@ class PinCodeTextView: NSControl, NSTextFieldDelegate {
let newFieldText = field.stringValue
// Handle pasting multiple characters (e.g., pasting "123456" from clipboard)
if newFieldText.count > 1 {
// Filter to alphanumeric characters only
let validCharacters = newFieldText.filter { $0.isLetter || $0.isNumber }
// Always start from the first field and clear previous content
var newCode = Array(repeating: Character?.none, count: numberOfDigits)
for (offset, character) in validCharacters.enumerated() {
if offset < numberOfDigits {
newCode[offset] = character
}
}
// Update all fields at once to avoid triggering didSet multiple times
code = newCode
// Move focus to next empty field or the last field if all are filled
let nextEmptyIndex = code.firstIndex(where: { $0 == nil }) ?? numberOfDigits - 1
if nextEmptyIndex < characterViews.count {
window?.makeFirstResponder(characterViews[nextEmptyIndex])
} else {
resignFirstResponder()
}
return
}
// Handle single character input
let lastCharacter: Character?
if newFieldText.isEmpty {
lastCharacter = nil