fix(ux): address critic review on mobile landscape, dual hud fade and clipboard feedback
- Optimize short/landscape screen (< 520px height) viewports with compact padding, shrinkable containers and zero-overflow layout - Synchronize dual-HUD immersive fading for both Header and Controls with 3s stillness and global wake-up interactions - Enhance PasteModal with user-friendly error alerts and auto-focusing textarea on clipboard denial Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
44
src/App.tsx
44
src/App.tsx
@@ -215,7 +215,7 @@ export default function App() {
|
||||
}
|
||||
};
|
||||
|
||||
// Mouse activity detection for HUD fading
|
||||
// Mouse/touch/key activity detection for HUD fading
|
||||
const resetInactivity = useCallback(() => {
|
||||
setIsUserActive(true);
|
||||
if (inactivityTimerRef.current) {
|
||||
@@ -224,7 +224,7 @@ export default function App() {
|
||||
if (isPlaying && settings.autoHideControls) {
|
||||
inactivityTimerRef.current = window.setTimeout(() => {
|
||||
setIsUserActive(false);
|
||||
}, 2200);
|
||||
}, 3000);
|
||||
}
|
||||
}, [isPlaying, settings.autoHideControls]);
|
||||
|
||||
@@ -235,11 +235,28 @@ export default function App() {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const handleInteraction = () => {
|
||||
resetInactivity();
|
||||
};
|
||||
|
||||
window.addEventListener('mousemove', handleInteraction);
|
||||
window.addEventListener('keydown', handleInteraction);
|
||||
window.addEventListener('touchstart', handleInteraction);
|
||||
window.addEventListener('pointerdown', handleInteraction);
|
||||
|
||||
const timer = window.setTimeout(() => {
|
||||
setIsUserActive(false);
|
||||
}, 2200);
|
||||
return () => window.clearTimeout(timer);
|
||||
}, [isPlaying, settings.autoHideControls]);
|
||||
}, 3000);
|
||||
|
||||
return () => {
|
||||
window.clearTimeout(timer);
|
||||
window.removeEventListener('mousemove', handleInteraction);
|
||||
window.removeEventListener('keydown', handleInteraction);
|
||||
window.removeEventListener('touchstart', handleInteraction);
|
||||
window.removeEventListener('pointerdown', handleInteraction);
|
||||
};
|
||||
}, [isPlaying, settings.autoHideControls, resetInactivity]);
|
||||
|
||||
// Keyboard shortcuts
|
||||
const anyModalOpen =
|
||||
@@ -278,6 +295,9 @@ export default function App() {
|
||||
|
||||
const themeClass = `theme-${settings.theme}`;
|
||||
const isHudDimmed = isPlaying && !isUserActive && settings.autoHideControls;
|
||||
const hudClasses = isHudDimmed
|
||||
? 'opacity-0 pointer-events-none transition-opacity duration-500'
|
||||
: 'opacity-100 pointer-events-auto transition-opacity duration-300';
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -286,11 +306,7 @@ export default function App() {
|
||||
className={`relative w-full h-full flex flex-col justify-between overflow-hidden transition-colors duration-300 font-sans ${themeClass}`}
|
||||
>
|
||||
{/* Top Header HUD */}
|
||||
<div
|
||||
className={`w-full z-20 transition-opacity duration-500 ${
|
||||
isHudDimmed ? 'opacity-0 hover:opacity-100' : 'opacity-100'
|
||||
}`}
|
||||
>
|
||||
<div className={`w-full z-20 shrink-0 ${hudClasses}`}>
|
||||
<Header
|
||||
book={activeBook}
|
||||
currentChapter={currentChapter}
|
||||
@@ -307,7 +323,7 @@ export default function App() {
|
||||
</div>
|
||||
|
||||
{/* Main RSVP Focus Arena */}
|
||||
<main className="flex-1 flex flex-col items-center justify-center px-4 z-10 w-full my-auto">
|
||||
<main className="flex-1 min-h-0 flex flex-col items-center justify-center px-2 sm:px-4 z-10 w-full overflow-hidden my-auto">
|
||||
{isLoading ? (
|
||||
<div className="flex flex-col items-center space-y-3 text-neutral-400">
|
||||
<div className="w-8 h-8 rounded-full border-2 border-rose-500 border-t-transparent animate-spin" />
|
||||
@@ -330,11 +346,7 @@ export default function App() {
|
||||
</main>
|
||||
|
||||
{/* Bottom Controls HUD */}
|
||||
<div
|
||||
className={`w-full pb-6 z-20 transition-opacity duration-500 ${
|
||||
isHudDimmed ? 'opacity-10 hover:opacity-100' : 'opacity-100'
|
||||
}`}
|
||||
>
|
||||
<div className={`w-full pb-2 sm:pb-6 short:pb-1 z-20 shrink-0 ${hudClasses}`}>
|
||||
<Controls
|
||||
currentIndex={currentIndex}
|
||||
totalTokens={totalTokens}
|
||||
|
||||
Reference in New Issue
Block a user