fix: camera button (📷) intercepted by kiosk native btnSettings overlay

- Kiosk (Android): btnSettings was positioned top|end with alpha=0.12,
  sitting invisibly on top of the HTML scan button in the webapp header.
  Moved to bottom|end (marginBottom=80dp, alpha=0.28) so it never
  overlaps the header. Kiosk versionCode 15→16, versionName 1.7.15.
- Web (Android Chrome/Brave): pointerleave fired before pointerup when
  finger drifted, cancelling the long-press timer and letting a synthetic
  click bubble to an unintended handler. Fixed with setPointerCapture +
  preventDefault + replaced pointerleave with pointercancel. Added
  touch-action:manipulation to .header-scan-btn CSS.
This commit is contained in:
dadaloop82
2026-05-16 18:02:36 +00:00
parent d28055a512
commit 0f567c4ba0
5 changed files with 15 additions and 7 deletions
+2
View File
@@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **`pz`/`conf` unit labels translated** — "pz" now shows as "pcs" in English and "Stk" in German; "conf" shows as "pkg" / "Pkg". All `unitLabels` objects in JS now use `t('units.pz')` / `t('units.conf')`.
### Fixed
- **Camera button (📷) opened kiosk SettingsActivity on Android** — The native `btnSettings` ImageButton in the kiosk layout was positioned `top|end` with `alpha=0.12` (nearly invisible), sitting directly on top of the HTML scan button in the webapp header. Every tap on the 📷 button was intercepted by the native View and opened `SettingsActivity`. Fixed: moved `btnSettings` to `bottom|end` (above the bottom nav bar, `marginBottom=80dp`) and increased `alpha` to `0.28` so it is clearly separate from the header. Kiosk versionCode bumped to 16.
- **Camera button (📷) opened settings on Android Chrome/Brave** — `pointerleave` fired before `pointerup` when finger drifted slightly, cancelling the long-press timer and leaving the browser to dispatch a synthetic `click` that bubbled to an unintended handler. Fixed: added `setPointerCapture` (prevents `pointerleave` during touch) and `preventDefault` (blocks synthetic click); replaced `pointerleave` with `pointercancel` handler. Added `touch-action: manipulation` to `.header-scan-btn` CSS.
- **Logo white background on splash screen** — Re-processed both `logo.png` and `logo_icon.png` with fuzz 35% alpha extraction, removing the white background that was visible against the dark splash background (`#0f172a`).
- **Recipe button label** — Shortened to "Ricetta" / "Recipe" / "Rezept" for compact display in the inventory quick-action modal.
- **Quantity decimal precision** — `qtyNum` in recipe/cooking ingredient buttons and `conf` fallback display in inventory cards now limited to 1 decimal place (was showing 7+ decimal places from raw AI output, e.g. `0.25353223 conf`).
+1
View File
@@ -279,6 +279,7 @@ body {
height: 48px;
box-shadow: 0 2px 8px rgba(0,0,0,0.18);
animation: pulse-scan 2s ease-in-out infinite;
touch-action: manipulation; /* prevent 300ms delay and double-tap zoom on mobile */
}
.header-scan-btn:active {
background: rgba(255,255,255,0.45);
+5 -1
View File
@@ -14276,6 +14276,8 @@ function initSpesaMode() {
if (!btn) return;
btn.addEventListener('pointerdown', (e) => {
e.preventDefault(); // prevent browser-generated synthetic click + 300ms delay
btn.setPointerCapture(e.pointerId); // ensure pointerup always fires on this element even if finger drifts
_longPressTimer = setTimeout(() => {
_longPressTimer = null;
startSpesaMode();
@@ -14289,12 +14291,14 @@ function initSpesaMode() {
showPage('scan');
}
});
btn.addEventListener('pointerleave', () => {
btn.addEventListener('pointercancel', () => {
// OS cancelled gesture (e.g. home swipe) — discard timer, do nothing
if (_longPressTimer) {
clearTimeout(_longPressTimer);
_longPressTimer = null;
}
});
// Note: no pointerleave handler needed — setPointerCapture prevents it from firing during touch
}
function startSpesaMode() {
+2 -2
View File
@@ -11,8 +11,8 @@ android {
applicationId = "it.dadaloop.evershelf.kiosk"
minSdk = 24
targetSdk = 34
versionCode = 15
versionName = "1.7.14"
versionCode = 16
versionName = "1.7.15"
}
signingConfigs {
@@ -43,17 +43,18 @@
android:layout_height="match_parent"
android:visibility="gone" />
<!-- Settings gear (shown after setup, over WebView) — top-right corner to avoid overlapping modals -->
<!-- Settings gear (shown after setup, over WebView) — bottom-right corner so it never
overlaps the webapp header buttons (e.g. the 📷 scan button at top-right) -->
<ImageButton
android:id="@+id/btnSettings"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_gravity="top|end"
android:layout_marginTop="8dp"
android:layout_gravity="bottom|end"
android:layout_marginBottom="80dp"
android:layout_marginEnd="8dp"
android:background="@android:color/transparent"
android:src="@android:drawable/ic_menu_manage"
android:alpha="0.12"
android:alpha="0.28"
android:contentDescription="Settings"
android:scaleType="centerInside"
android:visibility="gone" />