1.2.4: pull-to-refresh only at the top of the chat
Some checks failed
build / apk (push) Has been cancelled

The swipe gesture no longer reloads the page while a presentation, the
canvas, a dialog or any other scrolled list is on screen: the web app
reports a single pull-allowed flag (overlays + every scroller), the shell
starts from 'forbidden' until the page says otherwise and the WebView
drops its overscroll glow.
This commit is contained in:
Niko Marmeladkov 2026-10-19 08:19:09 +03:00
parent 3ad6e6cf7c
commit 6e02c22b4f
3 changed files with 17 additions and 8 deletions

View file

@ -15,7 +15,9 @@ resources.
leaves the app.
- TLS errors are never bypassed, no cleartext traffic, no backup.
- Day/night theme follows the system; the page keeps its own theme setting.
- Back gesture navigates the chat history, pull-to-refresh reloads.
- Back gesture navigates the chat history; pull-to-refresh reloads only at
the very top of the chat — never inside a presentation, a dialog or another
list.
## Install
@ -23,7 +25,7 @@ Download the APK from the releases page:
**https://git.n1ko.dev/Niko/nikogpt_android/releases**
Latest build:
https://git.n1ko.dev/Niko/nikogpt_android/releases/download/v1.2.3/nikogpt-android-1.2.3.apk
https://git.n1ko.dev/Niko/nikogpt_android/releases/download/v1.2.4/nikogpt-android-1.2.4.apk
Open the APK on the phone (allow installing apps from this source when Android
asks). The APKs are signed with the project's release key; Android may still

View file

@ -22,8 +22,8 @@ android {
applicationId = "dev.n1ko.nikogpt"
minSdk = 29 // Android 10
targetSdk = 35
versionCode = 9
versionName = "1.2.3"
versionCode = 10
versionName = "1.2.4"
}
signingConfigs {

View file

@ -80,10 +80,14 @@ class MainActivity : AppCompatActivity() {
// Shared text ("Share to NikoGPT") waiting for the page to load.
private var pendingShare: String? = null
// Whether the chat's inner scroll container is at the top; pull-to-refresh
// only fires there (the WebView itself never scrolls).
// Whether the web app currently allows a pull-to-refresh gesture. It
// reports this on every scroll and whenever an overlay opens or closes
// (window.NikoGPTAndroid.setAtTop), because the WebView itself never
// scrolls — the messages list, a presentation viewer, dialogs … all scroll
// inside the page. Starts false: until the page explicitly says "at the
// top of the chat", a pull must not reload anything.
@Volatile
private var webAtTop = true
private var webAtTop = false
// Where the camera writes the picture before it reaches the web app.
private var pendingCameraUri: Uri? = null
@ -291,8 +295,11 @@ class MainActivity : AppCompatActivity() {
refresh.setOnRefreshListener { webView.reload() }
// Pull-to-refresh only when the chat list is really at the top; a
// bigger trigger distance keeps normal scrolling from reloading.
refresh.setOnChildScrollUpCallback { _, _ -> !webAtTop }
refresh.setOnChildScrollUpCallback { _, _ -> !webAtTop || webView.canScrollVertically(-1) }
refresh.setDistanceToTriggerSync((80 * resources.displayMetrics.density).toInt())
// No native overscroll glow/bounce on the WebView either: the page
// owns every scroller.
webView.overScrollMode = View.OVER_SCROLL_NEVER
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {