60
60
import android .widget .TextView ;
61
61
import android .widget .Toast ;
62
62
63
+ import androidx .activity .BackEventCompat ;
63
64
import androidx .activity .ComponentActivity ;
65
+ import androidx .activity .OnBackPressedCallback ;
64
66
import androidx .annotation .DrawableRes ;
65
67
import androidx .annotation .NonNull ;
66
68
import androidx .annotation .Nullable ;
85
87
import org .thunderdog .challegram .data .TGReaction ;
86
88
import org .thunderdog .challegram .mediaview .MediaViewController ;
87
89
import org .thunderdog .challegram .navigation .ActivityResultHandler ;
90
+ import org .thunderdog .challegram .navigation .BackPressMode ;
88
91
import org .thunderdog .challegram .navigation .DrawerController ;
89
92
import org .thunderdog .challegram .navigation .HeaderView ;
90
93
import org .thunderdog .challegram .navigation .InterceptLayout ;
91
94
import org .thunderdog .challegram .navigation .MenuMoreWrap ;
92
95
import org .thunderdog .challegram .navigation .NavigationController ;
93
96
import org .thunderdog .challegram .navigation .NavigationGestureController ;
97
+ import org .thunderdog .challegram .navigation .NavigationStack ;
94
98
import org .thunderdog .challegram .navigation .OptionsLayout ;
95
99
import org .thunderdog .challegram .navigation .OverlayView ;
96
100
import org .thunderdog .challegram .navigation .ReactionsOverlayView ;
97
101
import org .thunderdog .challegram .navigation .RootDrawable ;
102
+ import org .thunderdog .challegram .navigation .SystemBackEventListener ;
98
103
import org .thunderdog .challegram .navigation .TooltipOverlayView ;
99
104
import org .thunderdog .challegram .navigation .ViewController ;
100
105
import org .thunderdog .challegram .player .RecordAudioVideoController ;
@@ -242,7 +247,11 @@ public ClickBait getSettingsClickBait () {
242
247
}
243
248
244
249
public boolean isAnimating (boolean intercept ) {
245
- return (navigation != null && (intercept ? navigation .isAnimatingWithEffect () : navigation .isAnimating ())) || (drawer != null && drawer .isAnimating ()) || isProgressShowing || (cameraAnimator != null && cameraAnimator .isAnimating ());
250
+ return
251
+ (navigation != null && (intercept ? navigation .isAnimatingWithEffect () : navigation .isAnimating ())) ||
252
+ (drawer != null && drawer .isAnimating ()) ||
253
+ isProgressShowing ||
254
+ (cameraAnimator != null && cameraAnimator .isAnimating ());
246
255
}
247
256
248
257
public boolean processTouchEvent (MotionEvent event ) {
@@ -485,7 +494,6 @@ public void onCreate (Bundle savedInstanceState) {
485
494
if (Config .USE_CUSTOM_NAVIGATION_COLOR ) {
486
495
this .isWindowLight = !Theme .isDark ();
487
496
}
488
- this .isGestureNavigationEnabled = Screen .isGesturalNavigationEnabled (getResources ());
489
497
// UI.resetSizes();
490
498
setActivityState (UI .State .RESUMED );
491
499
TdlibManager .instance ().watchDog ().onActivityCreate (this );
@@ -500,6 +508,7 @@ public void onCreate (Bundle savedInstanceState) {
500
508
501
509
Screen .checkDensity ();
502
510
511
+ this .isGestureNavigationEnabled = Screen .isGesturalNavigationEnabled (getResources ());
503
512
mHasSoftwareKeys = hasSoftwareKeys ();
504
513
505
514
currentOrientation = UI .getOrientation ();
@@ -569,9 +578,9 @@ public void onCreate (Bundle savedInstanceState) {
569
578
570
579
Lang .addLanguageListener (this );
571
580
572
- /*if (BuildConfig.DEBUG) {
573
- addRemoveRtlSwitch( );
574
- }*/
581
+ navigation . getStack (). addChangeListener ( navigationStackChangeListener );
582
+ backPressedCallback . setEnabled ( isBackPressActionAvailable ( handleOnBackPress ( false , false )) );
583
+ getOnBackPressedDispatcher (). addCallback ( backPressedCallback );
575
584
}
576
585
577
586
private View rtlSwitchView ;
@@ -1197,6 +1206,7 @@ public void onDestroy () {
1197
1206
}
1198
1207
setOrientationLockFlags (0 );
1199
1208
if (navigation != null ) {
1209
+ navigation .getStack ().removeChangeListener (navigationStackChangeListener );
1200
1210
navigation .destroy ();
1201
1211
}
1202
1212
Lang .removeLanguageListener (this );
@@ -1342,57 +1352,140 @@ public void onConfigurationChanged (@NonNull Configuration newConfig) {
1342
1352
}
1343
1353
}
1344
1354
1345
- @ Override
1346
- @ SuppressWarnings ("deprecation" )
1347
- public void onBackPressed () {
1348
- if (isPasscodeShowing ) {
1349
- super .onBackPressed ();
1350
- } else {
1351
- onBackPressed (false );
1355
+ private final NavigationStack .ChangeListener navigationStackChangeListener = stack -> {
1356
+ notifyBackPressAvailabilityChanged ();
1357
+ };
1358
+
1359
+ private final OnBackPressedCallback backPressedCallback = new OnBackPressedCallback (false ) {
1360
+ @ Override
1361
+ public void handleOnBackPressed () {
1362
+ boolean handled = false ;
1363
+ if (backPressTarget != null ) {
1364
+ handled = backPressTarget .onSystemBackPressed ();
1365
+ backPressTarget = null ;
1366
+ }
1367
+ if (!handled ) {
1368
+ performBackPress (false );
1369
+ }
1370
+ }
1371
+
1372
+ private SystemBackEventListener backPressTarget ;
1373
+
1374
+ @ Override
1375
+ public void handleOnBackStarted (@ NonNull BackEventCompat backEvent ) {
1376
+ @ BackPressMode int mode = backPressMode ;
1377
+ SystemBackEventListener target ;
1378
+ switch (mode ) {
1379
+ case BackPressMode .NAVIGATE_BACK_IN_STACK :
1380
+ target = navigation ;
1381
+ break ;
1382
+ case BackPressMode .CLOSE_NAVIGATION_DRAWER :
1383
+ target = drawer ;
1384
+ break ;
1385
+ case BackPressMode .CUSTOM_ACTION_PERFORMED :
1386
+ case BackPressMode .SYSTEM_ACTION_REQUIRED :
1387
+ target = null ;
1388
+ break ;
1389
+ default :
1390
+ throw new AssertionError (Integer .toString (mode ));
1391
+ }
1392
+ if (target != null && target .onSystemBackStarted (backEvent )) {
1393
+ backPressTarget = target ;
1394
+ } else {
1395
+ backPressTarget = null ;
1396
+ }
1397
+ }
1398
+
1399
+ @ Override
1400
+ public void handleOnBackCancelled () {
1401
+ if (backPressTarget != null ) {
1402
+ backPressTarget .onSystemBackCancelled ();
1403
+ backPressTarget = null ;
1404
+ }
1405
+ }
1406
+
1407
+ @ Override
1408
+ public void handleOnBackProgressed (@ NonNull BackEventCompat backEvent ) {
1409
+ if (backPressTarget != null ) {
1410
+ backPressTarget .onSystemBackProgressed (backEvent );
1411
+ }
1412
+ }
1413
+ };
1414
+
1415
+ private static boolean isBackPressActionAvailable (@ BackPressMode int backPressMode ) {
1416
+ return backPressMode != BackPressMode .SYSTEM_ACTION_REQUIRED ;
1417
+ }
1418
+
1419
+ private @ BackPressMode int backPressMode = BackPressMode .SYSTEM_ACTION_REQUIRED ;
1420
+
1421
+ public void notifyBackPressAvailabilityChanged () {
1422
+ @ BackPressMode int backPressMode = handleOnBackPress (false , false );
1423
+ this .backPressMode = backPressMode ;
1424
+ boolean isEnabled = isBackPressActionAvailable (backPressMode );
1425
+ if (backPressedCallback .isEnabled () != isEnabled ) {
1426
+ backPressedCallback .setEnabled (isEnabled );
1352
1427
}
1353
1428
}
1354
1429
1355
- @ SuppressWarnings ("deprecation" )
1356
- public void onBackPressed (boolean fromTop ) {
1430
+ public void performBackPress (boolean fromTop ) {
1431
+ if (handleOnBackPress (fromTop , true ) == BackPressMode .SYSTEM_ACTION_REQUIRED ) {
1432
+ backPressedCallback .setEnabled (false );
1433
+ getOnBackPressedDispatcher ().onBackPressed ();
1434
+ }
1435
+ }
1436
+
1437
+ public @ BackPressMode int handleOnBackPress (boolean fromTop , boolean commit ) {
1438
+ if (isPasscodeShowing ) {
1439
+ return BackPressMode .SYSTEM_ACTION_REQUIRED ;
1440
+ }
1357
1441
if (isProgressShowing ) {
1358
- if (progressListener != null ) {
1442
+ if (progressListener != null && commit ) {
1359
1443
hideProgress (true );
1360
1444
}
1361
- return ;
1445
+ return BackPressMode . CUSTOM_ACTION_PERFORMED ;
1362
1446
}
1363
- if (tooltipOverlayView != null && tooltipOverlayView .onBackPressed ( )) {
1364
- return ;
1447
+ if (tooltipOverlayView != null && tooltipOverlayView .handleOnBackPress ( commit )) {
1448
+ return BackPressMode . CUSTOM_ACTION_PERFORMED ;
1365
1449
}
1366
- if (dismissLastOpenWindow (false , true , fromTop )) {
1367
- return ;
1450
+ if (dismissLastOpenWindow (false , true , fromTop , commit )) {
1451
+ return BackPressMode . CUSTOM_ACTION_PERFORMED ;
1368
1452
}
1369
1453
if (isCameraOpen ) {
1370
- closeCameraByBackPress ();
1371
- return ;
1454
+ if (commit ) {
1455
+ closeCameraByBackPress ();
1456
+ }
1457
+ return BackPressMode .CUSTOM_ACTION_PERFORMED ;
1372
1458
}
1373
1459
if (recordAudioVideoController .isOpen ()) {
1374
- recordAudioVideoController .onBackPressed ();
1375
- return ;
1376
- }
1377
- if (!isAnimating (false )) {
1378
- if (navigation .passBackPressToActivity (fromTop )) {
1379
- super .onBackPressed ();
1380
- return ;
1381
- }
1382
- if (navigation .onBackPressed (fromTop )) {
1383
- return ;
1460
+ if (commit ) {
1461
+ recordAudioVideoController .onBackPressed ();
1384
1462
}
1385
- if (drawer != null && drawer .isVisible ()) {
1463
+ return BackPressMode .CUSTOM_ACTION_PERFORMED ;
1464
+ }
1465
+ if (isAnimating (false )) {
1466
+ return BackPressMode .CUSTOM_ACTION_PERFORMED ;
1467
+ }
1468
+ if (navigation .passBackPressToActivity (fromTop )) {
1469
+ return BackPressMode .SYSTEM_ACTION_REQUIRED ;
1470
+ }
1471
+ @ BackPressMode int navigationBackPress = navigation .performOnBackPressed (fromTop , commit );
1472
+ if (navigationBackPress != BackPressMode .SYSTEM_ACTION_REQUIRED ) {
1473
+ return navigationBackPress ;
1474
+ }
1475
+ if (drawer != null && drawer .isVisible ()) {
1476
+ if (commit ) {
1386
1477
drawer .close (0f , null );
1478
+ }
1479
+ return BackPressMode .CLOSE_NAVIGATION_DRAWER ;
1480
+ } else {
1481
+ ViewController <?> c = navigation .getCurrentStackItem ();
1482
+ if (c != null && (c .inSelectMode () || c .inSearchMode () || c .inCustomMode ())) {
1483
+ navigationBackPress = navigation .performOnBackPressed (fromTop , commit );
1484
+ return navigationBackPress != BackPressMode .SYSTEM_ACTION_REQUIRED ?
1485
+ navigationBackPress :
1486
+ BackPressMode .CUSTOM_ACTION_PERFORMED ;
1387
1487
} else {
1388
- ViewController <?> c = navigation .getCurrentStackItem ();
1389
- if (c == null ) {
1390
- super .onBackPressed ();
1391
- } else if (c .inSelectMode () || c .inSearchMode () || c .inCustomMode ()) {
1392
- navigation .onBackPressed (fromTop );
1393
- } else {
1394
- super .onBackPressed ();
1395
- }
1488
+ return BackPressMode .SYSTEM_ACTION_REQUIRED ;
1396
1489
}
1397
1490
}
1398
1491
}
@@ -1595,6 +1688,7 @@ public void removePasscodeListener (PasscodeListener listener) {
1595
1688
private void setIsPasscodeShowing (boolean isShowing ) {
1596
1689
if (this .isPasscodeShowing != isShowing ) {
1597
1690
this .isPasscodeShowing = isShowing ;
1691
+ notifyBackPressAvailabilityChanged ();
1598
1692
if (isShowing ) {
1599
1693
removeAllWindows ();
1600
1694
} else {
@@ -1777,6 +1871,7 @@ public void showProgress (String message, ProgressPopupListener listener) {
1777
1871
return ;
1778
1872
}
1779
1873
isProgressShowing = true ;
1874
+ notifyBackPressAvailabilityChanged ();
1780
1875
final boolean firstTime ;
1781
1876
if (progressWrap == null ) {
1782
1877
progressWrap = new ProgressWrap (this );
@@ -1853,6 +1948,7 @@ public void hideProgress (boolean forced) {
1853
1948
1854
1949
isProgressShowing = false ;
1855
1950
isProgressAnimating = true ;
1951
+ notifyBackPressAvailabilityChanged ();
1856
1952
1857
1953
ValueAnimator obj ;
1858
1954
obj = AnimatorUtils .simpleValueAnimator ();
@@ -2361,6 +2457,7 @@ public void showPopupWindow (PopupLayout window) {
2361
2457
windows .add (window );
2362
2458
checkDisallowScreenshots ();
2363
2459
window .showBoundWindow (rootView );
2460
+ notifyBackPressAvailabilityChanged ();
2364
2461
}
2365
2462
2366
2463
public boolean hasAnimatingWindow () {
@@ -2385,6 +2482,7 @@ public void removeWindowFromList (PopupLayout window) {
2385
2482
if (!windows .remove (window )) {
2386
2483
completelyForgetThisWindow (window );
2387
2484
}
2485
+ notifyBackPressAvailabilityChanged ();
2388
2486
checkDisallowScreenshots ();
2389
2487
}
2390
2488
@@ -2393,18 +2491,20 @@ public void removeWindowFromList (PopupLayout window) {
2393
2491
return popupLayout != null ? popupLayout .getBoundController () : null ;
2394
2492
}
2395
2493
2396
- public boolean dismissLastOpenWindow (boolean byKeyPress , boolean byBackPress , boolean byHeaderBackPress ) {
2494
+ public boolean dismissLastOpenWindow (boolean byKeyPress , boolean byBackPress , boolean byHeaderBackPress , boolean commit ) {
2397
2495
final int size = windows .size ();
2398
2496
for (int i = size - 1 ; i >= 0 ; i --) {
2399
2497
PopupLayout window = windows .get (i );
2400
2498
if (window .isBoundWindowShowing ()) {
2401
2499
if (byKeyPress && window .canHideKeyboard ()) {
2402
- return window .hideSoftwareKeyboard ();
2500
+ return commit || window .hideSoftwareKeyboard ();
2403
2501
}
2404
- if (byBackPress && window .onBackPressed (byHeaderBackPress )) {
2502
+ if (byBackPress && window .performOnBackPressed (byHeaderBackPress , commit )) {
2405
2503
return true ;
2406
2504
}
2407
- window .hideWindow (true );
2505
+ if (commit ) {
2506
+ window .hideWindow (true );
2507
+ }
2408
2508
return true ;
2409
2509
}
2410
2510
}
@@ -2422,6 +2522,7 @@ public void pretendYouDontKnowThisWindow (PopupLayout window) {
2422
2522
}
2423
2523
forgottenWindows .put (i , window );
2424
2524
}
2525
+ notifyBackPressAvailabilityChanged ();
2425
2526
}
2426
2527
2427
2528
private int indexOfForgottenWindow (PopupLayout window ) {
@@ -2446,6 +2547,7 @@ public void letsRememberAboutThisWindow (PopupLayout window) {
2446
2547
}
2447
2548
forgottenWindows .remove (oldIndex );
2448
2549
checkDisallowScreenshots ();
2550
+ notifyBackPressAvailabilityChanged ();
2449
2551
}
2450
2552
}
2451
2553
@@ -2789,6 +2891,7 @@ public void onFactorChangeFinished (int id, float finalFactor, FactorAnimator ca
2789
2891
switch (id ) {
2790
2892
case ANIMATOR_ID_CAMERA : {
2791
2893
processCameraAnimationFinish (finalFactor );
2894
+ notifyBackPressAvailabilityChanged ();
2792
2895
break ;
2793
2896
}
2794
2897
}
@@ -3038,6 +3141,7 @@ private void checkCameraOrientationBlocked () {
3038
3141
private void setCameraOpen (ViewController .CameraOpenOptions options , boolean isOpen , boolean byDrag ) {
3039
3142
if (this .isCameraOpen != isOpen ) {
3040
3143
this .isCameraOpen = isOpen ;
3144
+ notifyBackPressAvailabilityChanged ();
3041
3145
if (isOpen ) {
3042
3146
this .cameraOptions = options ;
3043
3147
}
@@ -3111,6 +3215,7 @@ private void processCameraAnimationFinish (final float toFactor) {
3111
3215
} else if (toFactor == 0f && !isCameraOpen ) {
3112
3216
onCameraCompletelyClosed ();
3113
3217
}
3218
+ notifyBackPressAvailabilityChanged ();
3114
3219
});
3115
3220
}
3116
3221
0 commit comments