@@ -69,6 +69,10 @@ public class PortalActivity extends AppCompatActivity {
6969
7070 private GestureWebView webView ;
7171 private org .iiab .controller .redesign .FqrController fqr ; // ADFA-4879: FQR maps (only on /maps/)
72+ private static final long AUTO_HIDE_MS = 4000L ; // ADFA-4887: nav-bar auto-hide after inactivity
73+ private boolean fullscreenOn = false ; // ADFA-4887: Home button toggles fullscreen
74+ private Handler hideHandler ; // ADFA-4887: nav-bar auto-hide (cleared in onDestroy)
75+ private Runnable hideRunnable ;
7276 // pdf.js builds advertised by /pdfjs/manifest.json (loaded off the main thread).
7377 // Empty until loaded / when the box serves none -> PDFs fall back to download.
7478 private volatile List <PdfViewerBuild > pdfViewerBuilds = Collections .emptyList ();
@@ -100,26 +104,30 @@ protected void onCreate(Bundle savedInstanceState) {
100104 Button btnExit = findViewById (R .id .btnExit );
101105 Button btnForward = findViewById (R .id .btnForward );
102106
103- // --- PERSISTENT BAR ---
104- // Keep the nav bar (with Exit) visible so a non-technical user always has an
105- // obvious way out . The handle is only used after a manual hide (btnHideNav) .
107+ // --- NAV BAR (auto-hide after inactivity) ---
108+ // Visible on entry; hides after AUTO_HIDE_MS with no interaction, measured from the LAST
109+ // touch . The handle (⌃) brings it back; btnHideNav hides it manually .
106110 bottomNav .post (() -> {
107111 bottomNav .setTranslationY (0 );
108112 bottomNav .setVisibility (View .VISIBLE );
109113 });
110114 btnHandle .setVisibility (View .GONE );
111115
112- // --- AUTO-HIDE TIMER ---
113- Handler hideHandler = new Handler (Looper .getMainLooper ());
116+ hideHandler = new Handler (Looper .getMainLooper ());
114117
115- Runnable hideRunnable = () -> {
118+ hideRunnable = () -> {
116119 bottomNav .animate ().translationY (bottomNav .getHeight ()).setDuration (250 );
117120 btnHandle .setVisibility (View .VISIBLE );
118121 btnHandle .animate ().alpha (1f ).setDuration (150 );
119122 };
120123
121- // Persistent bar: never auto-hide. Cancel any pending hide; only btnHideNav hides.
122- Runnable resetTimer = () -> hideHandler .removeCallbacks (hideRunnable );
124+ // Reschedule the hide on every interaction -> auto-hide from the LAST touch, not the first.
125+ Runnable resetTimer = () -> {
126+ hideHandler .removeCallbacks (hideRunnable );
127+ hideHandler .postDelayed (hideRunnable , AUTO_HIDE_MS );
128+ };
129+ webView .setOnUserInteraction (resetTimer ); // content touches count as interaction too
130+ resetTimer .run (); // start the initial countdown
123131
124132 // --- HANDLE LOGIC (Show Bar) ---
125133 btnHandle .setOnClickListener (v -> {
@@ -141,8 +149,23 @@ protected void onCreate(Bundle savedInstanceState) {
141149 // Resolve the target URL once (domain), surviving rotation via the ViewModel.
142150 final String finalTargetUrl = vm .targetUrl (getIntent ().getStringExtra ("TARGET_URL" ));
143151
152+ // ADFA-4887: there is no in-WebView home page anymore, so Home is a Fullscreen toggle.
153+ // Enters full immersive (system bars hidden) and hides our bar too — but the bar stays
154+ // recoverable via the handle. Press again to exit.
144155 btnHome .setOnClickListener (v -> {
145- webView .loadUrl (finalTargetUrl );
156+ fullscreenOn = !fullscreenOn ;
157+ androidx .core .view .WindowInsetsControllerCompat wic =
158+ androidx .core .view .WindowCompat .getInsetsController (getWindow (), getWindow ().getDecorView ());
159+ if (fullscreenOn ) {
160+ wic .setSystemBarsBehavior (
161+ androidx .core .view .WindowInsetsControllerCompat .BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE );
162+ wic .hide (androidx .core .view .WindowInsetsCompat .Type .systemBars ());
163+ hideRunnable .run (); // hide our bar too (still recoverable via the handle)
164+ } else {
165+ wic .show (androidx .core .view .WindowInsetsCompat .Type .systemBars ());
166+ btnHandle .animate ().alpha (0f ).setDuration (150 ).withEndAction (() -> btnHandle .setVisibility (View .GONE ));
167+ bottomNav .animate ().translationY (0 ).setDuration (250 );
168+ }
146169 resetTimer .run ();
147170 });
148171
@@ -387,6 +410,7 @@ protected void onDestroy() {
387410 // ADFA-4879: stop FQR polling + drop its overlay/dialog so we don't leak the activity.
388411 // The durable server job (if any) keeps running and shows up on the next /maps/ reload.
389412 if (fqr != null ) fqr .detach ();
413+ if (hideHandler != null && hideRunnable != null ) hideHandler .removeCallbacks (hideRunnable ); // ADFA-4887
390414 super .onDestroy ();
391415 }
392416
0 commit comments