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:
@@ -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')`.
|
- **`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
|
### 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`).
|
- **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.
|
- **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`).
|
- **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`).
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ body {
|
|||||||
height: 48px;
|
height: 48px;
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.18);
|
box-shadow: 0 2px 8px rgba(0,0,0,0.18);
|
||||||
animation: pulse-scan 2s ease-in-out infinite;
|
animation: pulse-scan 2s ease-in-out infinite;
|
||||||
|
touch-action: manipulation; /* prevent 300ms delay and double-tap zoom on mobile */
|
||||||
}
|
}
|
||||||
.header-scan-btn:active {
|
.header-scan-btn:active {
|
||||||
background: rgba(255,255,255,0.45);
|
background: rgba(255,255,255,0.45);
|
||||||
|
|||||||
+5
-1
@@ -14276,6 +14276,8 @@ function initSpesaMode() {
|
|||||||
if (!btn) return;
|
if (!btn) return;
|
||||||
|
|
||||||
btn.addEventListener('pointerdown', (e) => {
|
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 = setTimeout(() => {
|
||||||
_longPressTimer = null;
|
_longPressTimer = null;
|
||||||
startSpesaMode();
|
startSpesaMode();
|
||||||
@@ -14289,12 +14291,14 @@ function initSpesaMode() {
|
|||||||
showPage('scan');
|
showPage('scan');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
btn.addEventListener('pointerleave', () => {
|
btn.addEventListener('pointercancel', () => {
|
||||||
|
// OS cancelled gesture (e.g. home swipe) — discard timer, do nothing
|
||||||
if (_longPressTimer) {
|
if (_longPressTimer) {
|
||||||
clearTimeout(_longPressTimer);
|
clearTimeout(_longPressTimer);
|
||||||
_longPressTimer = null;
|
_longPressTimer = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// Note: no pointerleave handler needed — setPointerCapture prevents it from firing during touch
|
||||||
}
|
}
|
||||||
|
|
||||||
function startSpesaMode() {
|
function startSpesaMode() {
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ android {
|
|||||||
applicationId = "it.dadaloop.evershelf.kiosk"
|
applicationId = "it.dadaloop.evershelf.kiosk"
|
||||||
minSdk = 24
|
minSdk = 24
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 15
|
versionCode = 16
|
||||||
versionName = "1.7.14"
|
versionName = "1.7.15"
|
||||||
}
|
}
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
|
|||||||
@@ -43,17 +43,18 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:visibility="gone" />
|
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
|
<ImageButton
|
||||||
android:id="@+id/btnSettings"
|
android:id="@+id/btnSettings"
|
||||||
android:layout_width="44dp"
|
android:layout_width="44dp"
|
||||||
android:layout_height="44dp"
|
android:layout_height="44dp"
|
||||||
android:layout_gravity="top|end"
|
android:layout_gravity="bottom|end"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginBottom="80dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:src="@android:drawable/ic_menu_manage"
|
android:src="@android:drawable/ic_menu_manage"
|
||||||
android:alpha="0.12"
|
android:alpha="0.28"
|
||||||
android:contentDescription="Settings"
|
android:contentDescription="Settings"
|
||||||
android:scaleType="centerInside"
|
android:scaleType="centerInside"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|||||||
Reference in New Issue
Block a user