Files
hash-wallet/lib/new-ui/widgets/digit_input.dart
T
5b2a8f6755 Cw 1379 add monero support to trezor rebase dev (#3273)
* refactor: migrate hardware wallet resources to `new-ui`, add Trezor model support, and streamline hardware wallet handling across services

* refactor: migrate hardware wallet resources to `new-ui`, add Trezor model support, and streamline hardware wallet handling across services

* fix: correctly check for Ledger hardware wallet type in `isHardwareWallet` logic

* refactor: unify `isConnected` method for hardware wallets, add Trezor-specific support, and update Monero sync logic

* refactor: add Trezor transaction signing support, streamline hardware wallet handling, and update Monero dependency

* refactor: improve Trezor transaction handling, adjust hardware wallet state logic, and update Monero dependency references

* fix: non-hww tx commit() in xmr
fix: prod monero_c
fix: keyImage import workaround for Trezor/Cupcake
chore: add kotlin's .salive to .gitignore

* fix: universal_ble builds on iOS
chore: remove prints
fix: proper CI prebuilt for linux

* new trezor connection ui

* fix page title

* typo

* fix page title anim

* refactor: enhance Trezor pairing flow, update state management, and simplify UI logic in hardware wallet integration

* fix: correct widget indentation in Trezor pairing failure state UI

* fix: extract Trezor pairing failure state UI to `_errorBox` widget and update Trezor dependency reference

* refactor: simplify hardware wallet pairing error UI, optimize `_errorBox` layout, and streamline widget logic

* Update cw_monero/lib/pending_monero_transaction.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* Update lib/buy/robinhood/robinhood_buy_provider.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* feat: add USB intent filters, device filter for hardware wallets, and update Trezor dependency reference

* Update cw_monero/pubspec.yaml [skip ci]

* Update cw_wownero/pubspec.yaml [skip ci]

* Update cw_zano/pubspec.yaml [skip ci]

* fix: use CryptoCurrency.title instead of amount-refactor-only .symbol getter

new_wallet_type_page used curr.symbol, which only exists on the
amount-refactor branch (String get symbol => title). On dev the
equivalent is curr.title. Adapts the Trezor feature to dev's API
without pulling in amount-refactor.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fix wallet list screen not scrollable
minor fixes

---------

Co-authored-by: Konstantin Ullrich <konstantinullrich12@gmail.com>
Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
Co-authored-by: Robert Malikowski <malikowskirobert@gmail.com>
Co-authored-by: Konstantin Ullrich <konstantin@cakewallet.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 02:33:17 +02:00

183 lines
4.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class DigitInputController {
String _text = "";
String get text => _text;
set text(String newText) {
_text = newText;
for (final listener in _listeners) {
listener.call();
}
}
final List<void Function()> _listeners = [];
void addListener(void Function() listener) => _listeners.add(listener);
}
class DigitInputPill extends StatelessWidget {
const DigitInputPill({super.key, this.digit, required this.highlighted});
final String? digit;
final bool highlighted;
@override
Widget build(BuildContext context) {
return Container(
width: 51,
height: 84,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceContainerHigh,
borderRadius: BorderRadius.circular(16),
border:
highlighted ? Border.all(color: Theme.of(context).colorScheme.primary, width: 2) : null,
),
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Text(digit ?? " ", style: TextStyle(fontSize: 40)),
),
),
);
}
}
class DigitInput extends StatefulWidget {
const DigitInput({
super.key,
required this.controller,
required this.desiredLength,
this.breakAt = 3,
});
final DigitInputController controller;
final int desiredLength;
final int breakAt;
@override
State<DigitInput> createState() => _DigitInputState();
}
class _DigitInputState extends State<DigitInput> implements TextInputClient {
TextInputConnection? _textInputConnection;
@override
void initState() {
super.initState();
_openVirtualKeyboard();
}
void _openVirtualKeyboard() {
if (_textInputConnection == null || !_textInputConnection!.attached) {
_textInputConnection = TextInput.attach(
this,
const TextInputConfiguration(
inputType: TextInputType.numberWithOptions(
signed: false,
decimal: false,
),
inputAction: TextInputAction.none,
),
);
}
_textInputConnection!.setEditingState(
TextEditingValue(
text: widget.controller.text,
selection: TextSelection.collapsed(offset: widget.controller.text.length),
),
);
_textInputConnection!.show();
}
void _closeVirtualKeyboard() => _textInputConnection?.close();
@override
void dispose() {
_closeVirtualKeyboard();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _openVirtualKeyboard,
child: SizedBox(
height: 84,
child: ListView.separated(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) => DigitInputPill(
digit: widget.controller.text.length > index ? widget.controller.text[index] : null,
highlighted: widget.controller.text.length == index,
),
separatorBuilder: (context, index) =>
SizedBox(width: (index + 1) % widget.breakAt == 0 ? 16 : 4),
itemCount: widget.desiredLength,
),
),
);
}
@override
void updateEditingValue(TextEditingValue value) {
final RegExp numberRegExp = RegExp(r'^\d{0,6}$');
if (numberRegExp.hasMatch(value.text)) {
setState(() => widget.controller.text = value.text);
} else {
// flutter keeps the text editing state regardless of whether you actually used it or not.
// so, if validation fails, we gotta set it back to what it was explicitly
_textInputConnection?.setEditingState(
TextEditingValue(
text: widget.controller.text,
selection: TextSelection.collapsed(offset: widget.controller.text.length),
),
);
}
}
@override
void performAction(TextInputAction action) {}
@override
TextEditingValue? get currentTextEditingValue => TextEditingValue(text: widget.controller.text);
@override
void connectionClosed() => _textInputConnection = null;
@override
AutofillScope? get currentAutofillScope => null;
@override
void performPrivateCommand(String action, Map<String, dynamic> data) {}
@override
void showAutocorrectionPromptRect(int start, int end) {}
@override
void updateFloatingCursor(RawFloatingCursorPoint point) {}
@override
void insertTextPlaceholder(Size size) {}
@override
void removeTextPlaceholder() {}
@override
void showToolbar() {}
@override
void performSelector(String selectorName) {}
@override
void didChangeInputControl(TextInputControl? oldControl, TextInputControl? newControl) {}
@override
void insertContent(KeyboardInsertedContent content) {}
}