feat(ui): URL-shaped keyboard + lowercase enforcement for server host
The server-host TextField on the connect form accepts a hostname or
hostname:port pair (e.g. kr.teamspeak.app:9987). Two improvements:
1. keyboardType: TextInputType.url surfaces '.', '/', ':' on the
primary on-screen keyboard plane so the user does not have to
switch to the symbols pane mid-address. Matches iOS Safari's
URL bar.
2. textCapitalization.none + autocorrect/enableSuggestions=false
prevents iOS from auto-capitalising the first letter or
'correcting' 'kr.teamspeak.app' to something else.
3. inputFormatters belt-and-braces:
* deny whitespace (handles tab-indented paste)
* lowercase pipeline (handles uppercase paste)
4. Visual affordances: prefix dns icon + 'host[:port]' hint.
Nickname field intentionally unchanged \u2014 may contain unicode,
mixed case, spaces.
flutter build ios --release --no-codesign: 30.7 s, Runner.app
30.0 MB. flutter analyze clean (6 pre-existing deprecation
warnings on Radio.groupValue/onChanged).
This commit is contained in:
@@ -1294,11 +1294,42 @@ class _ConnectFormState extends State<_ConnectForm> {
|
||||
controller: widget.hostCtl,
|
||||
focusNode: _hostFocus,
|
||||
onTap: () => _hostFocus.requestFocus(),
|
||||
// Server addresses are URL-shaped: hostname or
|
||||
// hostname:port, all-lowercase ASCII, never user-
|
||||
// friendly prose. Configure the on-screen keyboard
|
||||
// accordingly:
|
||||
// * keyboardType: .url \u2014 surfaces ".", "/",
|
||||
// ":" on the primary keyboard plane so the user
|
||||
// doesn't have to switch to the symbols pane to
|
||||
// type kr.teamspeak.app:9987.
|
||||
// * textInputAction: .next \u2014 return key advances
|
||||
// to the nickname field.
|
||||
// * autocorrect / enableSuggestions: false \u2014 iOS
|
||||
// should not autocorrect 'kr.teamspeak.app' to
|
||||
// 'kr.teamspeak.lap' or suggest 'KR' in caps.
|
||||
// * textCapitalization: .none \u2014 don't capitalise the
|
||||
// first letter the way iOS does for sentences.
|
||||
// * inputFormatters: deny whitespace and uppercase\u2014
|
||||
// belt-and-braces in case the user pastes from a
|
||||
// formatted source (e.g. tab-indented copy).
|
||||
keyboardType: TextInputType.url,
|
||||
textCapitalization: TextCapitalization.none,
|
||||
textInputAction: TextInputAction.next,
|
||||
autocorrect: false,
|
||||
enableSuggestions: false,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.deny(RegExp(r'\s')),
|
||||
TextInputFormatter.withFunction(
|
||||
(oldValue, newValue) => newValue.copyWith(
|
||||
text: newValue.text.toLowerCase(),
|
||||
selection: newValue.selection,
|
||||
),
|
||||
),
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.fieldServerHost,
|
||||
hintText: 'host[:port]',
|
||||
prefixIcon: const Icon(Icons.dns_outlined),
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user