Files
chanora/apps
EdisonJwa 7c0e5caa92 fix(ui,ios): first-tap on TextField now opens the keyboard
User report: 'every first time to tap to input box nothing
happened'. Symptom is iPhone-specific: the very first tap on any
of the Host / Nickname / Password text boxes in the connect form
fails to focus + open the keyboard. The second tap on the same
field works.

Two distinct causes, both addressed:

  apps/chanora_flutter/lib/main.dart
    The connect form lives inside a SingleChildScrollView. Flutter
    on iOS has a long-standing issue (flutter#19027) where the
    enclosing Scrollable's gesture-arena participant absorbs the
    first tap as a possible scroll-intent, leaving the TextField
    unfocused; the second tap reaches the field because the
    scrollable has already declined to handle a drag.

    Fix: _ConnectForm converted from StatelessWidget to
    StatefulWidget so it can own FocusNodes for the three text
    fields. Each TextField gains:
      * focusNode: <its own FocusNode>
      * onTap: () => focusNode.requestFocus()
        — forces focus on tap-down regardless of arena outcome
      * textInputAction: TextInputAction.next (host, nick) /
        TextInputAction.done (password) for return-key flow
      * autocorrect: false, enableSuggestions: false
        — these are server-host / nickname / password fields, the
        iOS auto-correct + suggestion bar is wrong for all three.

    Also set keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior
    .onDrag on the SingleChildScrollView so the keyboard hides
    when the user starts scrolling the bookmark list below.

  apps/chanora_flutter/ios/Runner/AppDelegate.swift
    AVAudioSession.sharedInstance().requestRecordPermission was
    fired synchronously from didFinishLaunchingWithOptions. The
    permission alert can race with iOS's text-input subsystem
    initialisation: if the alert appears before the keyboard
    layer finishes wiring up, subsequent text-field focus
    requests are dropped silently.

    Fix: DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) to
    defer the permission request until ~1 s after the app shell
    is on screen. Long enough for iOS's text-input layer to fully
    initialise; short enough that the user reads the prompt
    before tapping a field.

flutter analyze: clean (6 pre-existing Radio.groupValue infos).
flutter build ios --release --no-codesign: 26.8 s clean
(Runner.app 29.8 MB).
2026-05-16 15:50:27 +08:00
..