* feat(app): dismiss the chat keyboard on a fast upward flick Scrolling the history to read earlier messages left the keyboard up, so the visible transcript stayed cramped and the keyboard had to be closed by hand first — two steps for what should be one. React Native's keyboardDismissMode cannot express the wanted behaviour: "on-drag" fires on the first pixel and kills the keyboard on any peek-scroll, and "interactive" is broken on inverted lists. So the gesture is measured here: samples are taken from the scroll events and, at release, the speed over the drag's final stretch decides. Measuring at release rather than averaging the whole drag is what keeps a fast but controlled read-scroll from counting as a flick, since such a gesture decelerates before the finger lifts. Timestamps and offsets come from the events, never from a clock: with a busy JS thread the callbacks arrive in a burst long after the gesture, and wall-clock spacing then reads a calm scroll as a flick. The release offset comes from the end-drag event for the same reason — the last onScroll can be stale by the time a short flick lands. Android needs both the blur and the dismiss. Dismissing alone leaves the input focused and the keyboard inset applied, so the layout stays shifted with an empty gap where the keyboard was; blurring alone releases focus but leaves the IME on screen. Verified on an Android device with a Release build: a slow drag and a 0.6 dp/ms scroll keep the keyboard, a 2.9 dp/ms flick dismisses it and the composer settles back with no leftover gap. iOS was exercised by hand on device only, without automated coverage of the gesture itself. * refactor(app): isolate keyboard flick dismissal * fix(app): isolate keyboard shift context --------- Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
Welcome to your Expo app 👋
This is an Expo project created with create-expo-app.
Get started
-
Install dependencies
npm install -
Start the app
npx expo start
In the output, you'll find options to open the app in a
- development build
- Android emulator
- iOS simulator
- Expo Go, a limited sandbox for trying out app development with Expo
You can start developing by editing the files inside the app directory. This project uses file-based routing.
Get a fresh project
When you're ready, run:
npm run reset-project
This command will move the starter code to the app-example directory and create a blank app directory where you can start developing.
Learn more
To learn more about developing your project with Expo, look at the following resources:
- Expo documentation: Learn fundamentals, or go into advanced topics with our guides.
- Learn Expo tutorial: Follow a step-by-step tutorial where you'll create a project that runs on Android, iOS, and the web.
Join the community
Join our community of developers creating universal apps.
- Expo on GitHub: View our open source platform and contribute.
- Discord community: Chat with Expo users and ask questions.
Dictation debugging
Set EXPO_PUBLIC_ENABLE_AUDIO_DEBUG=1 before running npx expo start to render the in-app audio debug card. Pair it with the server-side STT_DEBUG_AUDIO_DIR flag so every dictation includes a copyable path to the saved raw audio file.