mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-22 16:32:01 +03:00
Rename and add comments to utf8 utils.
This commit is contained in:
parent
f4838850e7
commit
38528c81ae
@ -10,7 +10,7 @@ import 'package:yubico_authenticator/app/logging.dart';
|
||||
import '../../app/message.dart';
|
||||
import '../../desktop/models.dart';
|
||||
import '../../widgets/responsive_dialog.dart';
|
||||
import '../../widgets/utf8_text_fields.dart';
|
||||
import '../../widgets/utf8_utils.dart';
|
||||
import '../state.dart';
|
||||
import '../../fido/models.dart';
|
||||
import '../../app/models.dart';
|
||||
@ -181,7 +181,7 @@ class _AddFingerprintDialogState extends ConsumerState<AddFingerprintDialog>
|
||||
focusNode: _nameFocus,
|
||||
maxLength: 15,
|
||||
inputFormatters: [limitBytesLength(15)],
|
||||
buildCounter: buildCountersFor(_label),
|
||||
buildCounter: buildByteCounterFor(_label),
|
||||
autofocus: true,
|
||||
decoration: InputDecoration(
|
||||
enabled: _fingerprint != null,
|
||||
|
@ -4,7 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../../app/message.dart';
|
||||
import '../../desktop/models.dart';
|
||||
import '../../widgets/responsive_dialog.dart';
|
||||
import '../../widgets/utf8_text_fields.dart';
|
||||
import '../../widgets/utf8_utils.dart';
|
||||
import '../models.dart';
|
||||
import '../state.dart';
|
||||
import '../../app/models.dart';
|
||||
@ -72,7 +72,7 @@ class _RenameAccountDialogState extends ConsumerState<RenameFingerprintDialog> {
|
||||
initialValue: _label,
|
||||
maxLength: 15,
|
||||
inputFormatters: [limitBytesLength(15)],
|
||||
buildCounter: buildCountersFor(_label),
|
||||
buildCounter: buildByteCounterFor(_label),
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Label',
|
||||
|
@ -13,7 +13,7 @@ import '../../app/state.dart';
|
||||
import '../../desktop/models.dart';
|
||||
import '../../widgets/file_drop_target.dart';
|
||||
import '../../widgets/responsive_dialog.dart';
|
||||
import '../../widgets/utf8_text_fields.dart';
|
||||
import '../../widgets/utf8_utils.dart';
|
||||
import '../models.dart';
|
||||
import '../state.dart';
|
||||
import 'utils.dart';
|
||||
@ -212,7 +212,7 @@ class _OathAddAccountPageState extends ConsumerState<OathAddAccountPage> {
|
||||
enabled: issuerRemaining > 0,
|
||||
maxLength: max(issuerRemaining, 1),
|
||||
inputFormatters: [limitBytesLength(issuerRemaining)],
|
||||
buildCounter: buildCountersFor(_issuerController.text),
|
||||
buildCounter: buildByteCounterFor(_issuerController.text),
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Issuer (optional)',
|
||||
@ -232,7 +232,7 @@ class _OathAddAccountPageState extends ConsumerState<OathAddAccountPage> {
|
||||
key: const Key('name'),
|
||||
controller: _accountController,
|
||||
maxLength: max(nameRemaining, 1),
|
||||
buildCounter: buildCountersFor(_accountController.text),
|
||||
buildCounter: buildByteCounterFor(_accountController.text),
|
||||
inputFormatters: [limitBytesLength(nameRemaining)],
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
|
@ -7,7 +7,7 @@ import '../../app/message.dart';
|
||||
import '../../app/models.dart';
|
||||
import '../../desktop/models.dart';
|
||||
import '../../widgets/responsive_dialog.dart';
|
||||
import '../../widgets/utf8_text_fields.dart';
|
||||
import '../../widgets/utf8_utils.dart';
|
||||
import '../models.dart';
|
||||
import '../state.dart';
|
||||
import 'utils.dart';
|
||||
@ -98,7 +98,7 @@ class _RenameAccountDialogState extends ConsumerState<RenameAccountDialog> {
|
||||
initialValue: _issuer,
|
||||
enabled: issuerRemaining > 0,
|
||||
maxLength: issuerRemaining > 0 ? issuerRemaining : null,
|
||||
buildCounter: buildCountersFor(_issuer),
|
||||
buildCounter: buildByteCounterFor(_issuer),
|
||||
inputFormatters: [limitBytesLength(issuerRemaining)],
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
@ -116,7 +116,7 @@ class _RenameAccountDialogState extends ConsumerState<RenameAccountDialog> {
|
||||
initialValue: _account,
|
||||
maxLength: nameRemaining,
|
||||
inputFormatters: [limitBytesLength(nameRemaining)],
|
||||
buildCounter: buildCountersFor(_account),
|
||||
buildCounter: buildByteCounterFor(_account),
|
||||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
labelText: 'Account name',
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
import '../../widgets/utf8_utils.dart';
|
||||
import '../models.dart';
|
||||
import '../../core/models.dart';
|
||||
|
||||
@ -19,7 +19,7 @@ Pair<int, int> getRemainingKeySpace(
|
||||
// Non-standard TOTP periods are stored as part of this data, as a "D/"- prefix.
|
||||
remaining -= '$period/'.length;
|
||||
}
|
||||
int issuerSpace = utf8.encode(issuer).length;
|
||||
int issuerSpace = byteLength(issuer);
|
||||
if (issuer.isNotEmpty) {
|
||||
// Issuer is separated from name with a ":", if present.
|
||||
issuerSpace += 1;
|
||||
@ -27,7 +27,7 @@ Pair<int, int> getRemainingKeySpace(
|
||||
|
||||
return Pair(
|
||||
// Always reserve at least one character for name
|
||||
remaining - 1 - max(utf8.encode(name).length, 1),
|
||||
remaining - 1 - max(byteLength(name), 1),
|
||||
remaining - issuerSpace,
|
||||
);
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
int _byteLength(String value) => utf8.encode(value).length;
|
||||
|
||||
InputCounterWidgetBuilder buildCountersFor(String currentValue) =>
|
||||
(context, {required currentLength, required isFocused, maxLength}) => Text(
|
||||
maxLength != null ? '${_byteLength(currentValue)}/$maxLength' : '',
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
);
|
||||
|
||||
TextInputFormatter limitBytesLength(int maxByteLength) =>
|
||||
TextInputFormatter.withFunction((oldValue, newValue) {
|
||||
final newLength = _byteLength(newValue.text);
|
||||
if (newLength <= maxByteLength) {
|
||||
return newValue;
|
||||
}
|
||||
return oldValue;
|
||||
});
|
29
lib/widgets/utf8_utils.dart
Executable file
29
lib/widgets/utf8_utils.dart
Executable file
@ -0,0 +1,29 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
/// Get the number of bytes used by a String when encoded to UTF-8.
|
||||
int byteLength(String value) => utf8.encode(value).length;
|
||||
|
||||
/// Builds a counter widget showing number of bytes used/available.
|
||||
///
|
||||
/// Set this as a [TextField.buildCounter] callback to show the number of bytes
|
||||
/// used rather than number of characters. [currentValue] should always match
|
||||
/// the input text value to measure.
|
||||
InputCounterWidgetBuilder buildByteCounterFor(String currentValue) =>
|
||||
(context, {required currentLength, required isFocused, maxLength}) => Text(
|
||||
maxLength != null ? '${byteLength(currentValue)}/$maxLength' : '',
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
);
|
||||
|
||||
/// Limits the input in length based on the byte length when encoded.
|
||||
/// This is generally used together with [buildByteCounterFor].
|
||||
TextInputFormatter limitBytesLength(int maxByteLength) =>
|
||||
TextInputFormatter.withFunction((oldValue, newValue) {
|
||||
final newLength = byteLength(newValue.text);
|
||||
if (newLength <= maxByteLength) {
|
||||
return newValue;
|
||||
}
|
||||
return oldValue;
|
||||
});
|
Loading…
Reference in New Issue
Block a user