#1008 opening app from launcher shows home page only when exited by back button
This commit is contained in:
parent
1578d2d944
commit
27cf1bf4aa
4 changed files with 108 additions and 81 deletions
|
@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- opening app from launcher shows home page only when exited by back button
|
||||||
- Screen saver: black background, consistent with slideshow
|
- Screen saver: black background, consistent with slideshow
|
||||||
- upgraded Flutter to stable v3.22.2
|
- upgraded Flutter to stable v3.22.2
|
||||||
|
|
||||||
|
|
|
@ -285,10 +285,10 @@ open class MainActivity : FlutterFragmentActivity() {
|
||||||
open fun extractIntentData(intent: Intent?): FieldMap {
|
open fun extractIntentData(intent: Intent?): FieldMap {
|
||||||
when (val action = intent?.action) {
|
when (val action = intent?.action) {
|
||||||
Intent.ACTION_MAIN -> {
|
Intent.ACTION_MAIN -> {
|
||||||
val fields = hashMapOf<String, Any?>(
|
val fields = HashMap<String, Any?>()
|
||||||
INTENT_DATA_KEY_LAUNCHER to intent.hasCategory(Intent.CATEGORY_LAUNCHER),
|
if (intent.getBooleanExtra(EXTRA_KEY_SAFE_MODE, false)) {
|
||||||
INTENT_DATA_KEY_SAFE_MODE to intent.getBooleanExtra(EXTRA_KEY_SAFE_MODE, false),
|
fields[INTENT_DATA_KEY_SAFE_MODE] = true
|
||||||
)
|
}
|
||||||
intent.getStringExtra(EXTRA_KEY_PAGE)?.let { page ->
|
intent.getStringExtra(EXTRA_KEY_PAGE)?.let { page ->
|
||||||
val filters = extractFiltersFromIntent(intent)
|
val filters = extractFiltersFromIntent(intent)
|
||||||
fields[INTENT_DATA_KEY_PAGE] = page
|
fields[INTENT_DATA_KEY_PAGE] = page
|
||||||
|
@ -497,7 +497,6 @@ open class MainActivity : FlutterFragmentActivity() {
|
||||||
const val INTENT_DATA_KEY_ACTION = "action"
|
const val INTENT_DATA_KEY_ACTION = "action"
|
||||||
const val INTENT_DATA_KEY_ALLOW_MULTIPLE = "allowMultiple"
|
const val INTENT_DATA_KEY_ALLOW_MULTIPLE = "allowMultiple"
|
||||||
const val INTENT_DATA_KEY_FILTERS = "filters"
|
const val INTENT_DATA_KEY_FILTERS = "filters"
|
||||||
const val INTENT_DATA_KEY_LAUNCHER = "launcher"
|
|
||||||
const val INTENT_DATA_KEY_MIME_TYPE = "mimeType"
|
const val INTENT_DATA_KEY_MIME_TYPE = "mimeType"
|
||||||
const val INTENT_DATA_KEY_PAGE = "page"
|
const val INTENT_DATA_KEY_PAGE = "page"
|
||||||
const val INTENT_DATA_KEY_QUERY = "query"
|
const val INTENT_DATA_KEY_QUERY = "query"
|
||||||
|
|
|
@ -26,6 +26,7 @@ import 'package:aves/theme/themes.dart';
|
||||||
import 'package:aves/widgets/collection/collection_grid.dart';
|
import 'package:aves/widgets/collection/collection_grid.dart';
|
||||||
import 'package:aves/widgets/collection/collection_page.dart';
|
import 'package:aves/widgets/collection/collection_page.dart';
|
||||||
import 'package:aves/widgets/common/basic/scaffold.dart';
|
import 'package:aves/widgets/common/basic/scaffold.dart';
|
||||||
|
import 'package:aves/widgets/common/behaviour/pop/scope.dart';
|
||||||
import 'package:aves/widgets/common/behaviour/route_tracker.dart';
|
import 'package:aves/widgets/common/behaviour/route_tracker.dart';
|
||||||
import 'package:aves/widgets/common/behaviour/routes.dart';
|
import 'package:aves/widgets/common/behaviour/routes.dart';
|
||||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
|
@ -178,6 +179,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
static const defaultPageTransitionsBuilder = FadeUpwardsPageTransitionsBuilder();
|
static const defaultPageTransitionsBuilder = FadeUpwardsPageTransitionsBuilder();
|
||||||
static final GlobalKey<NavigatorState> _navigatorKey = GlobalKey(debugLabel: 'app-navigator');
|
static final GlobalKey<NavigatorState> _navigatorKey = GlobalKey(debugLabel: 'app-navigator');
|
||||||
static ScreenBrightness? _screenBrightness;
|
static ScreenBrightness? _screenBrightness;
|
||||||
|
static bool _exitedMainByPop = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
@ -224,83 +226,91 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
DurationsProvider(),
|
DurationsProvider(),
|
||||||
HighlightInfoProvider(),
|
HighlightInfoProvider(),
|
||||||
],
|
],
|
||||||
child: OverlaySupport(
|
child: NotificationListener<PopExitNotification>(
|
||||||
child: FutureBuilder<void>(
|
onNotification: (notification) {
|
||||||
future: _appSetup,
|
if (_appModeNotifier.value == AppMode.main) {
|
||||||
builder: (context, snapshot) {
|
_exitedMainByPop = true;
|
||||||
final initialized = !snapshot.hasError && snapshot.connectionState == ConnectionState.done;
|
}
|
||||||
if (initialized) {
|
return true;
|
||||||
AvesApp.showSystemUI();
|
},
|
||||||
}
|
child: OverlaySupport(
|
||||||
final home = initialized
|
child: FutureBuilder<void>(
|
||||||
? _getFirstPage(intentData: widget.debugIntentData)
|
future: _appSetup,
|
||||||
: AvesScaffold(
|
builder: (context, snapshot) {
|
||||||
body: snapshot.hasError ? _buildError(snapshot.error!) : const SizedBox(),
|
final initialized = !snapshot.hasError && snapshot.connectionState == ConnectionState.done;
|
||||||
);
|
if (initialized) {
|
||||||
return Selector<Settings, (Locale?, AvesThemeBrightness, bool)>(
|
AvesApp.showSystemUI();
|
||||||
selector: (context, s) => (
|
}
|
||||||
s.locale,
|
final home = initialized
|
||||||
s.initialized ? s.themeBrightness : SettingsDefaults.themeBrightness,
|
? _getFirstPage(intentData: widget.debugIntentData)
|
||||||
s.initialized ? s.enableDynamicColor : SettingsDefaults.enableDynamicColor,
|
: AvesScaffold(
|
||||||
),
|
body: snapshot.hasError ? _buildError(snapshot.error!) : const SizedBox(),
|
||||||
builder: (context, s, child) {
|
|
||||||
final (settingsLocale, themeBrightness, enableDynamicColor) = s;
|
|
||||||
return DynamicColorBuilder(
|
|
||||||
builder: (lightScheme, darkScheme) {
|
|
||||||
const defaultAccent = AvesColorsData.defaultAccent;
|
|
||||||
Color lightAccent = defaultAccent, darkAccent = defaultAccent;
|
|
||||||
if (enableDynamicColor) {
|
|
||||||
lightAccent = lightScheme?.primary ?? lightAccent;
|
|
||||||
darkAccent = darkScheme?.primary ?? darkAccent;
|
|
||||||
}
|
|
||||||
final lightTheme = Themes.lightTheme(lightAccent, initialized);
|
|
||||||
final darkTheme = themeBrightness == AvesThemeBrightness.black ? Themes.blackTheme(darkAccent, initialized) : Themes.darkTheme(darkAccent, initialized);
|
|
||||||
return Shortcuts(
|
|
||||||
shortcuts: {
|
|
||||||
// handle Android TV remote `select` button (KEYCODE_DPAD_CENTER)
|
|
||||||
// the following keys are already handled by default:
|
|
||||||
// KEYCODE_ENTER, KEYCODE_BUTTON_A, KEYCODE_NUMPAD_ENTER
|
|
||||||
LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
|
|
||||||
},
|
|
||||||
child: Builder(
|
|
||||||
builder: (context) {
|
|
||||||
return MediaQuery(
|
|
||||||
data: MediaQuery.of(context).copyWith(
|
|
||||||
// disable accessible navigation, as it impacts snack bar action timer
|
|
||||||
// for all users of apps registered as accessibility services,
|
|
||||||
// even though they are not for accessibility purposes (like TalkBack is)
|
|
||||||
accessibleNavigation: false,
|
|
||||||
),
|
|
||||||
child: MaterialApp(
|
|
||||||
navigatorKey: _navigatorKey,
|
|
||||||
home: home,
|
|
||||||
navigatorObservers: _navigatorObservers,
|
|
||||||
builder: (context, child) => _decorateAppChild(
|
|
||||||
context: context,
|
|
||||||
initialized: initialized,
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
onGenerateTitle: (context) => context.l10n.appName,
|
|
||||||
theme: lightTheme,
|
|
||||||
darkTheme: darkTheme,
|
|
||||||
themeMode: themeBrightness.appThemeMode,
|
|
||||||
locale: settingsLocale,
|
|
||||||
localizationsDelegates: const [
|
|
||||||
...AppLocalizations.localizationsDelegates,
|
|
||||||
...LocalizationsNn.delegates,
|
|
||||||
],
|
|
||||||
supportedLocales: AvesApp.supportedLocales,
|
|
||||||
scrollBehavior: AvesScrollBehavior(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
return Selector<Settings, (Locale?, AvesThemeBrightness, bool)>(
|
||||||
);
|
selector: (context, s) => (
|
||||||
},
|
s.locale,
|
||||||
);
|
s.initialized ? s.themeBrightness : SettingsDefaults.themeBrightness,
|
||||||
},
|
s.initialized ? s.enableDynamicColor : SettingsDefaults.enableDynamicColor,
|
||||||
|
),
|
||||||
|
builder: (context, s, child) {
|
||||||
|
final (settingsLocale, themeBrightness, enableDynamicColor) = s;
|
||||||
|
return DynamicColorBuilder(
|
||||||
|
builder: (lightScheme, darkScheme) {
|
||||||
|
const defaultAccent = AvesColorsData.defaultAccent;
|
||||||
|
Color lightAccent = defaultAccent, darkAccent = defaultAccent;
|
||||||
|
if (enableDynamicColor) {
|
||||||
|
lightAccent = lightScheme?.primary ?? lightAccent;
|
||||||
|
darkAccent = darkScheme?.primary ?? darkAccent;
|
||||||
|
}
|
||||||
|
final lightTheme = Themes.lightTheme(lightAccent, initialized);
|
||||||
|
final darkTheme = themeBrightness == AvesThemeBrightness.black ? Themes.blackTheme(darkAccent, initialized) : Themes.darkTheme(darkAccent, initialized);
|
||||||
|
return Shortcuts(
|
||||||
|
shortcuts: {
|
||||||
|
// handle Android TV remote `select` button (KEYCODE_DPAD_CENTER)
|
||||||
|
// the following keys are already handled by default:
|
||||||
|
// KEYCODE_ENTER, KEYCODE_BUTTON_A, KEYCODE_NUMPAD_ENTER
|
||||||
|
LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
|
||||||
|
},
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
return MediaQuery(
|
||||||
|
data: MediaQuery.of(context).copyWith(
|
||||||
|
// disable accessible navigation, as it impacts snack bar action timer
|
||||||
|
// for all users of apps registered as accessibility services,
|
||||||
|
// even though they are not for accessibility purposes (like TalkBack is)
|
||||||
|
accessibleNavigation: false,
|
||||||
|
),
|
||||||
|
child: MaterialApp(
|
||||||
|
navigatorKey: _navigatorKey,
|
||||||
|
home: home,
|
||||||
|
navigatorObservers: _navigatorObservers,
|
||||||
|
builder: (context, child) => _decorateAppChild(
|
||||||
|
context: context,
|
||||||
|
initialized: initialized,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
onGenerateTitle: (context) => context.l10n.appName,
|
||||||
|
theme: lightTheme,
|
||||||
|
darkTheme: darkTheme,
|
||||||
|
themeMode: themeBrightness.appThemeMode,
|
||||||
|
locale: settingsLocale,
|
||||||
|
localizationsDelegates: const [
|
||||||
|
...AppLocalizations.localizationsDelegates,
|
||||||
|
...LocalizationsNn.delegates,
|
||||||
|
],
|
||||||
|
supportedLocales: AvesApp.supportedLocales,
|
||||||
|
scrollBehavior: AvesScrollBehavior(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -615,6 +625,18 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
|
|
||||||
void _onNewIntent(Map? intentData) {
|
void _onNewIntent(Map? intentData) {
|
||||||
reportService.log('New intent data=$intentData');
|
reportService.log('New intent data=$intentData');
|
||||||
|
|
||||||
|
if (_appModeNotifier.value == AppMode.main) {
|
||||||
|
// do not reset when relaunching the app, except when exiting by pop
|
||||||
|
final shouldReset = _exitedMainByPop;
|
||||||
|
_exitedMainByPop = false;
|
||||||
|
|
||||||
|
if (!shouldReset && (intentData ?? {}).isEmpty) {
|
||||||
|
reportService.log('Relaunch');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_navigatorKey.currentState!.pushReplacement(DirectMaterialPageRoute(
|
_navigatorKey.currentState!.pushReplacement(DirectMaterialPageRoute(
|
||||||
settings: const RouteSettings(name: HomePage.routeName),
|
settings: const RouteSettings(name: HomePage.routeName),
|
||||||
builder: (_) => _getFirstPage(intentData: intentData),
|
builder: (_) => _getFirstPage(intentData: intentData),
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
|
import 'package:aves/widgets/aves_app.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ class AvesPopScope extends StatelessWidget {
|
||||||
} else {
|
} else {
|
||||||
// exit
|
// exit
|
||||||
reportService.log('Exit by pop');
|
reportService.log('Exit by pop');
|
||||||
|
PopExitNotification().dispatch(context);
|
||||||
SystemNavigator.pop();
|
SystemNavigator.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,3 +38,6 @@ class AvesPopScope extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class PopExitNotification extends Notification {}
|
||||||
|
|
Loading…
Reference in a new issue