Many improvemtns and fixes related to decoupling of svelte and rust on android.
🏗️ Build and Test JellyTau / Run Tests (push) Failing after 18s
🏗️ Build and Test JellyTau / Build Android APK (push) Has been skipped
Traceability Validation / Check Requirement Traces (push) Failing after 2s

This commit is contained in:
2026-02-28 19:50:47 +01:00
parent 07f3bf04ca
commit e8e37649fa
53 changed files with 2309 additions and 792 deletions
+58
View File
@@ -0,0 +1,58 @@
/**
* Composable for preventing accidental taps/clicks during and shortly after scrolling.
*
* On Android WebView, touch-to-click cancellation during scroll gestures can be unreliable,
* causing accidental taps on interactive elements (like library cards) while the user is scrolling.
*
* This composable tracks scroll activity and provides a guard function that should wrap
* click handlers to prevent them from firing during/shortly after scroll.
*
* @param cooldownMs - Time in ms after scroll stops before clicks are re-enabled (default: 200ms)
* @returns Object with onScroll handler and guarded click wrapper
*
* @example
* ```svelte
* <script>
* const { onScroll, guardedClick, isScrollActive } = useScrollGuard();
* </script>
*
* <div onscroll={onScroll}>
* <button onclick={guardedClick(() => handleClick())}>Click me</button>
* </div>
* ```
*/
export function useScrollGuard(cooldownMs: number = 200) {
let isScrolling = false;
let scrollTimeout: ReturnType<typeof setTimeout> | null = null;
function onScroll() {
isScrolling = true;
if (scrollTimeout) clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(() => {
isScrolling = false;
}, cooldownMs);
}
/**
* Returns true if the user is currently scrolling or just finished scrolling.
*/
function isScrollActive(): boolean {
return isScrolling;
}
/**
* Wraps a no-arg click handler to only fire if the user is not currently scrolling.
*/
function guardedClick(handler: () => void): () => void {
return () => {
if (isScrolling) return;
handler();
};
}
function cleanup() {
if (scrollTimeout) clearTimeout(scrollTimeout);
}
return { onScroll, guardedClick, isScrollActive, cleanup };
}