diff --git a/analysis_options.yaml b/analysis_options.yaml index 68e9714d..08b14c7a 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,9 +1,9 @@ include: package:flutter_lints/flutter.yaml analyzer: - strong-mode: - implicit-casts: false - implicit-dynamic: false + language: + strict-casts: true + strict-raw-types: true linter: rules: diff --git a/example/book_store/analysis_options.yaml b/example/book_store/analysis_options.yaml index ec5b55fc..1586dddc 100644 --- a/example/book_store/analysis_options.yaml +++ b/example/book_store/analysis_options.yaml @@ -1,9 +1,9 @@ include: package:flutter_lints/flutter.yaml analyzer: - strong-mode: - implicit-casts: false - implicit-dynamic: true + language: + strict-casts: true + strict-raw-types: true linter: rules: diff --git a/example/book_store/lib/main.dart b/example/book_store/lib/main.dart index 7673643a..0ccef872 100644 --- a/example/book_store/lib/main.dart +++ b/example/book_store/lib/main.dart @@ -36,7 +36,7 @@ RouteMap _buildRouteMap(BuildContext context) { body: Center( child: Text( "Couldn't find page '$path'", - style: Theme.of(context).textTheme.headline3, + style: Theme.of(context).textTheme.displaySmall, ), ), ), @@ -146,8 +146,7 @@ class BookStoreApp extends StatelessWidget { primaryColor: Color(0xFF131921), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( - primary: Color(0xfffebd68), - onPrimary: Color(0xff333333), + foregroundColor: Color(0xff333333), backgroundColor: Color(0xfffebd68), ), ), platform: TargetPlatform.macOS, diff --git a/example/book_store/lib/search_page.dart b/example/book_store/lib/search_page.dart index b3825f4b..5d0f0fb4 100644 --- a/example/book_store/lib/search_page.dart +++ b/example/book_store/lib/search_page.dart @@ -94,7 +94,7 @@ class SearchPage extends StatelessWidget { if (categoryMatches.isNotEmpty) ...[ Text( 'Categories', - style: Theme.of(context).textTheme.headline5, + style: Theme.of(context).textTheme.headlineSmall, ), for (final category in categoryMatches) ...[ Text(category.displayName), @@ -110,7 +110,7 @@ class SearchPage extends StatelessWidget { ], Text( 'Books', - style: Theme.of(context).textTheme.headline5, + style: Theme.of(context).textTheme.headlineSmall, ), if (books.isEmpty) Padding( diff --git a/example/book_store/lib/wishlist_page.dart b/example/book_store/lib/wishlist_page.dart index 3e867bff..f300773e 100644 --- a/example/book_store/lib/wishlist_page.dart +++ b/example/book_store/lib/wishlist_page.dart @@ -36,7 +36,7 @@ class WishlistHomePage extends StatelessWidget { children: [ Text( wishlist.title, - style: Theme.of(context).textTheme.headline6, + style: Theme.of(context).textTheme.titleLarge, ), Text('Share: ${wishlist.shareUrl}'), ], @@ -89,7 +89,7 @@ class WishlistPage extends StatelessWidget { children: [ Text( 'Wishlist ${wishList.title}', - style: Theme.of(context).textTheme.headline4, + style: Theme.of(context).textTheme.headlineMedium, ), Text('Share this wishlist! ${wishList.shareUrl}'), for (final bookId in wishList.bookIds) diff --git a/example/book_store/pubspec.yaml b/example/book_store/pubspec.yaml index 001f5763..8d734475 100644 --- a/example/book_store/pubspec.yaml +++ b/example/book_store/pubspec.yaml @@ -6,7 +6,7 @@ publish_to: "none" version: 1.0.0+1 environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=2.18.0 <4.0.0" dependencies: flutter: diff --git a/example/book_store/test/helpers.dart b/example/book_store/test/helpers.dart index 7fbb300a..b587507f 100644 --- a/example/book_store/test/helpers.dart +++ b/example/book_store/test/helpers.dart @@ -11,23 +11,32 @@ class SystemUrlTracker { /// Records changes in URL Future recordUrlChanges( - Future Function(SystemUrlTracker url) callback) async { + Future Function(SystemUrlTracker url) callback) async { try { final tracker = SystemUrlTracker(); final stackTraces = []; - SystemChannels.navigation.setMockMethodCallHandler((call) async { - if (call.method == 'routeInformationUpdated') { - final location = call.arguments['location'] as String; + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler( + SystemChannels.navigation, + (call) async { + if (call.method == 'routeInformationUpdated') { + final args = call.arguments as Map; + final location = args.containsKey('uri') + ? args['uri'] as String + : args['location'] as String; - tracker.current = location; - stackTraces.add(StackTrace.current); - } - }); + tracker.current = location; + stackTraces.add(StackTrace.current); + } + return null; + }, + ); await callback(tracker); } finally { - SystemChannels.navigation.setMockMethodCallHandler(null); + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(SystemChannels.navigation, null); } } diff --git a/example/deep_linking/lib/article_page.dart b/example/deep_linking/lib/article_page.dart index e3094baf..58b721d5 100644 --- a/example/deep_linking/lib/article_page.dart +++ b/example/deep_linking/lib/article_page.dart @@ -50,7 +50,7 @@ class _ArticlePageState extends State { children: [ Text( 'Article ${widget.id}', - style: Theme.of(context).textTheme.headline3, + style: Theme.of(context).textTheme.displaySmall, ), SizedBox(height: 20), Text('Hello this is article ${widget.id}'), diff --git a/example/deep_linking/lib/main.dart b/example/deep_linking/lib/main.dart index 888b9547..7a450f8f 100644 --- a/example/deep_linking/lib/main.dart +++ b/example/deep_linking/lib/main.dart @@ -142,7 +142,7 @@ class HomePage extends StatelessWidget { children: [ Text( 'Home page', - style: Theme.of(context).textTheme.headline3, + style: Theme.of(context).textTheme.displaySmall, ), SizedBox(height: 20), ElevatedButton( diff --git a/example/deep_linking/pubspec.yaml b/example/deep_linking/pubspec.yaml index dfabeca2..19d943b7 100644 --- a/example/deep_linking/pubspec.yaml +++ b/example/deep_linking/pubspec.yaml @@ -5,7 +5,7 @@ publish_to: "none" version: 1.0.0+1 environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=2.18.0 <4.0.0" dependencies: flutter: diff --git a/example/mobile_app/analysis_options.yaml b/example/mobile_app/analysis_options.yaml index cb51c35e..f8df21d0 100644 --- a/example/mobile_app/analysis_options.yaml +++ b/example/mobile_app/analysis_options.yaml @@ -1,9 +1,9 @@ include: package:flutter_lints/flutter.yaml analyzer: - strong-mode: - implicit-casts: false - implicit-dynamic: true + language: + strict-casts: true + strict-raw-types: true linter: rules: diff --git a/example/mobile_app/lib/main.dart b/example/mobile_app/lib/main.dart index 0009f1b5..06446d4e 100644 --- a/example/mobile_app/lib/main.dart +++ b/example/mobile_app/lib/main.dart @@ -23,7 +23,7 @@ void main() { /// This shows in a browser tab's title. class TitleObserver extends RoutemasterObserver { @override - void didChangeRoute(RouteData routeData, Page page) { + void didChangeRoute(RouteData routeData, Page page) { if (page.name != null) { SystemChrome.setApplicationSwitcherDescription( ApplicationSwitcherDescription( @@ -201,13 +201,13 @@ RouteMap _buildRouteMap(AppState appState) { } // For custom animations, just use the existing Flutter [Page] and [Route] objects -class FancyAnimationPage extends Page { +class FancyAnimationPage extends Page { final Widget child; FancyAnimationPage({required this.child}); @override - Route createRoute(BuildContext context) { + Route createRoute(BuildContext context) { return PageRouteBuilder( settings: this, pageBuilder: (context, animation, animation2) { diff --git a/example/mobile_app/lib/pages/bottom_sheet.dart b/example/mobile_app/lib/pages/bottom_sheet.dart index 20f8a80e..67f08fa8 100644 --- a/example/mobile_app/lib/pages/bottom_sheet.dart +++ b/example/mobile_app/lib/pages/bottom_sheet.dart @@ -20,7 +20,7 @@ class PageBasedMaterialWithModalsPageRoute required MaterialPage page, }) : super(page: page); - ModalBottomSheetRoute? _nextModalRoute; + ModalSheetRoute? _nextModalRoute; @override bool canTransitionTo(TransitionRoute nextRoute) { @@ -29,23 +29,18 @@ class PageBasedMaterialWithModalsPageRoute (nextRoute is CupertinoPageRoute && !nextRoute.fullscreenDialog) || (nextRoute is MaterialWithModalsPageRoute && !nextRoute.fullscreenDialog) || - (nextRoute is ModalBottomSheetRoute); + (nextRoute is ModalSheetRoute); } @override - void didChangeNext(Route? nextRoute) { - if (nextRoute is ModalBottomSheetRoute) { + void didChangeNext(Route? nextRoute) { + if (nextRoute is ModalSheetRoute) { _nextModalRoute = nextRoute; } super.didChangeNext(nextRoute); } - @override - void didPopNext(Route nextRoute) { - super.didPopNext(nextRoute); - } - @override bool didPop(T? result) { _nextModalRoute = null; diff --git a/example/mobile_app/pubspec.yaml b/example/mobile_app/pubspec.yaml index 29b4217c..c8a37028 100644 --- a/example/mobile_app/pubspec.yaml +++ b/example/mobile_app/pubspec.yaml @@ -4,7 +4,7 @@ publish_to: "none" version: 1.0.0+1 environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=2.18.0 <4.0.0" dependencies: flutter: @@ -13,7 +13,7 @@ dependencies: path: ../../ provider: ^5.0.0 cupertino_icons: ^1.0.0 - modal_bottom_sheet: ^2.0.1 + modal_bottom_sheet: ^3.0.0-pre dev_dependencies: flutter_test: diff --git a/example/mobile_app/test/bottom_navigation_test.dart b/example/mobile_app/test/bottom_navigation_test.dart index 427c77f8..bee846b8 100644 --- a/example/mobile_app/test/bottom_navigation_test.dart +++ b/example/mobile_app/test/bottom_navigation_test.dart @@ -6,7 +6,7 @@ import 'package:mobile_app/pages/home_page.dart'; import 'package:mobile_app/pages/notifications_page.dart'; import 'helpers.dart'; -Future pumpBottomNavigationPage(WidgetTester tester) async { +Future pumpBottomNavigationPage(WidgetTester tester) async { await tester.pumpWidget(MyApp()); await tester.tap(find.text('Log in')); await tester.pump(); diff --git a/example/mobile_app/test/feed_test.dart b/example/mobile_app/test/feed_test.dart index 88a93425..1ea809d7 100644 --- a/example/mobile_app/test/feed_test.dart +++ b/example/mobile_app/test/feed_test.dart @@ -5,7 +5,7 @@ import 'package:mobile_app/main.dart'; import 'package:mobile_app/pages/feed_page.dart'; import 'helpers.dart'; -Future pumpFeedPage(WidgetTester tester) async { +Future pumpFeedPage(WidgetTester tester) async { await tester.pumpWidget(MyApp()); await tester.tap(find.text('Log in')); await tester.pump(); diff --git a/example/mobile_app/test/helpers.dart b/example/mobile_app/test/helpers.dart index 25843d65..e6f51f4c 100644 --- a/example/mobile_app/test/helpers.dart +++ b/example/mobile_app/test/helpers.dart @@ -8,23 +8,29 @@ class SystemUrlTracker { /// Records changes in URL Future recordUrlChanges( - Future Function(SystemUrlTracker url) callback) async { + Future Function(SystemUrlTracker url) callback) async { try { final tracker = SystemUrlTracker(); final stackTraces = []; - SystemChannels.navigation.setMockMethodCallHandler((call) async { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(SystemChannels.navigation, (call) async { if (call.method == 'routeInformationUpdated') { - final location = call.arguments['location'] as String; + final args = call.arguments as Map; + final location = args.containsKey('uri') + ? args['uri'] as String + : args['location'] as String; tracker.current = location; stackTraces.add(StackTrace.current); } + return null; }); await callback(tracker); } finally { - SystemChannels.navigation.setMockMethodCallHandler(null); + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(SystemChannels.navigation, null); } } diff --git a/example/mobile_app/test/replace_test.dart b/example/mobile_app/test/replace_test.dart index 1d18cca1..c5e22147 100644 --- a/example/mobile_app/test/replace_test.dart +++ b/example/mobile_app/test/replace_test.dart @@ -4,7 +4,7 @@ import 'package:mobile_app/main.dart'; import 'package:mobile_app/pages/feed_page.dart'; import 'helpers.dart'; -Future pumpBottomNavigationPage(WidgetTester tester) async { +Future pumpBottomNavigationPage(WidgetTester tester) async { await tester.pumpWidget(MyApp()); await tester.tap(find.text('Log in')); await tester.pump(); diff --git a/example/navigation_bar/pubspec.yaml b/example/navigation_bar/pubspec.yaml index fe625317..9446c645 100644 --- a/example/navigation_bar/pubspec.yaml +++ b/example/navigation_bar/pubspec.yaml @@ -4,7 +4,7 @@ publish_to: "none" version: 1.0.0+1 environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=2.18.0 <4.0.0" dependencies: flutter: diff --git a/example/simple_example/analysis_options.yaml b/example/simple_example/analysis_options.yaml index ec5b55fc..1586dddc 100644 --- a/example/simple_example/analysis_options.yaml +++ b/example/simple_example/analysis_options.yaml @@ -1,9 +1,9 @@ include: package:flutter_lints/flutter.yaml analyzer: - strong-mode: - implicit-casts: false - implicit-dynamic: true + language: + strict-casts: true + strict-raw-types: true linter: rules: diff --git a/example/simple_example/pubspec.yaml b/example/simple_example/pubspec.yaml index a5eeff0b..720ee493 100644 --- a/example/simple_example/pubspec.yaml +++ b/example/simple_example/pubspec.yaml @@ -4,7 +4,7 @@ publish_to: "none" version: 1.0.0+1 environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=2.18.0 <4.0.0" dependencies: flutter: diff --git a/integration_test_app/analysis_options.yaml b/integration_test_app/analysis_options.yaml index 8b966164..0a0ff472 100644 --- a/integration_test_app/analysis_options.yaml +++ b/integration_test_app/analysis_options.yaml @@ -1,7 +1,7 @@ analyzer: - strong-mode: - implicit-casts: false - implicit-dynamic: true + language: + strict-casts: true + strict-raw-types: true linter: rules: diff --git a/integration_test_app/integration_test/navigation_hash_test.dart b/integration_test_app/integration_test/navigation_hash_test.dart index f12a10e0..96f438f7 100644 --- a/integration_test_app/integration_test/navigation_hash_test.dart +++ b/integration_test_app/integration_test/navigation_hash_test.dart @@ -7,7 +7,15 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); replaceTests( expectUrl: (expected) { - expect(window.location.hash, '#$expected'); + // Flutter after 3.10 has empty URLs for home route + final hashUrl = '#$expected'; + final allowEmpty = hashUrl == '#/'; + + expect( + window.location.hash == hashUrl || + (allowEmpty && window.location.hash.isEmpty), + isTrue, + ); }, ); } diff --git a/integration_test_app/macos/Podfile b/integration_test_app/macos/Podfile index dade8dfa..049abe29 100644 --- a/integration_test_app/macos/Podfile +++ b/integration_test_app/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.11' +platform :osx, '10.14' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/integration_test_app/macos/Podfile.lock b/integration_test_app/macos/Podfile.lock index dedef297..d4b359af 100644 --- a/integration_test_app/macos/Podfile.lock +++ b/integration_test_app/macos/Podfile.lock @@ -9,8 +9,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral SPEC CHECKSUMS: - FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424 + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 -PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c +PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 -COCOAPODS: 1.11.2 +COCOAPODS: 1.12.1 diff --git a/integration_test_app/macos/Runner.xcodeproj/project.pbxproj b/integration_test_app/macos/Runner.xcodeproj/project.pbxproj index 60079c12..43e87318 100644 --- a/integration_test_app/macos/Runner.xcodeproj/project.pbxproj +++ b/integration_test_app/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ @@ -202,7 +202,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 0930; + LastUpgradeCheck = 1300; ORGANIZATIONNAME = ""; TargetAttributes = { 33CC10EC2044A3C60003C045 = { @@ -255,6 +255,7 @@ /* Begin PBXShellScriptBuildPhase section */ 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -386,7 +387,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -465,7 +466,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -512,7 +513,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/integration_test_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/integration_test_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 9ff338a0..4763c866 100644 --- a/integration_test_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/integration_test_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ =2.12.0 <3.0.0' + sdk: ">=2.18.0 <4.0.0" dependencies: flutter: diff --git a/lib/routemaster.dart b/lib/routemaster.dart index 2cb0cf55..110bb59f 100644 --- a/lib/routemaster.dart +++ b/lib/routemaster.dart @@ -251,8 +251,8 @@ class NavigationResult { NavigationResult._(); /// Returns the top-most route that was created as a result of the navigation. - Future get route => _routeCompleter.future; - final Completer _routeCompleter = Completer(); + Future> get route => _routeCompleter.future; + final Completer> _routeCompleter = Completer>(); /// Used to get the return value from a route. /// @@ -262,8 +262,8 @@ class NavigationResult { /// Future get result async { final route = await _routeCompleter.future; - final result = await route.popped as T?; - return result; + final result = await route.popped; + return result as T?; } } @@ -277,7 +277,7 @@ class RoutemasterDelegate extends RouterDelegate /// This is only supplied to the top-level navigator, if you're using /// nested [PageStackNavigator] widgets you'll need to pass your custom /// [TransitionDelegate] to them individually. - final TransitionDelegate? transitionDelegate; + final TransitionDelegate? transitionDelegate; /// A function that returns a map of routes, to create pages from paths. final RouteMap Function(BuildContext context) routesBuilder; @@ -967,7 +967,7 @@ class RoutemasterDelegate extends RouterDelegate _PageResult _createPageContainer({ required _RouteRequest routeRequest, - required Page page, + required Page page, required RouteData routeData, required bool isLastRoute, }) { @@ -1087,7 +1087,7 @@ class RoutemasterDelegate extends RouterDelegate return redirects; } - void _didPush(Route route) { + void _didPush(Route route) { final page = route.settings; final current = _state.stack ._getCurrentPages() @@ -1102,7 +1102,7 @@ class RoutemasterDelegate extends RouterDelegate /// Attempts to find the current route data for the given [context]. /// /// Returns `null` if no route data is found. - RouteData? _maybeRouteDataFor(Page page) { + RouteData? _maybeRouteDataFor(Page page) { return _state.stack._getRouteData(page); } } @@ -1131,7 +1131,7 @@ class _PushObserver extends NavigatorObserver { _PushObserver(this.state); @override - void didPush(Route route, Route? previousRoute) { + void didPush(Route route, Route? previousRoute) { state.delegate._didPush(route); } } @@ -1228,13 +1228,11 @@ class RedirectLoopError extends Error { @override String toString() { - return 'Routemaster is stuck in an endless redirect loop:\n\n' + - redirects - .take(redirects.length - 1) - .mapIndexed((i, path1) => - " * '$path1' redirected to '${redirects[i + 1]}'") - .join('\n') + - '\n\nThis is an error in your routing map.'; + return '''Routemaster is stuck in an endless redirect loop: + +${redirects.take(redirects.length - 1).mapIndexed((i, path1) => " * '$path1' redirected to '${redirects[i + 1]}'").join('\n')} + +This is an error in your routing map.'''; } } @@ -1274,13 +1272,13 @@ class PageStackNavigator extends StatefulWidget { /// A delegate that decides how pages are animated when they're added or /// removed from the [Navigator]. - final TransitionDelegate transitionDelegate; + final TransitionDelegate transitionDelegate; /// A list of [NavigatorObserver] that will be passed to the [Navigator]. final List observers; /// A function that can filter or transform the list of pages from the stack. - final Iterable Function(List)? builder; + final Iterable> Function(List>)? builder; /// An optional key that's passed to the [Navigator] widget. /// diff --git a/lib/src/observers.dart b/lib/src/observers.dart index 36fba8db..046b2a42 100644 --- a/lib/src/observers.dart +++ b/lib/src/observers.dart @@ -10,7 +10,7 @@ abstract class RoutemasterObserver extends NavigatorObserver { RoutemasterObserver(); /// The router's current route changed. - void didChangeRoute(RouteData routeData, Page page) {} + void didChangeRoute(RouteData routeData, Page page) {} } /// Passes on navigation events to a list of [NavigatorObserver] objects. diff --git a/lib/src/pages/cupertino_tab_page.dart b/lib/src/pages/cupertino_tab_page.dart index 1b26be49..83c90392 100644 --- a/lib/src/pages/cupertino_tab_page.dart +++ b/lib/src/pages/cupertino_tab_page.dart @@ -32,7 +32,7 @@ class CupertinoTabPage extends StatefulPage with IndexedRouteMixIn { /// Optional function to customize the [Page] created for this route. /// If this is null, a [MaterialPage] is used. - final Page Function(Widget child) pageBuilder; + final Page Function(Widget child) pageBuilder; /// Specifies how tabs behave when used with the system back button. final TabBackBehavior backBehavior; @@ -107,7 +107,7 @@ class CupertinoTabPageState extends PageState } @override - Page createPage() { + Page createPage() { return page.pageBuilder( _CupertinoTabPageStateProvider( pageState: this, diff --git a/lib/src/pages/guard.dart b/lib/src/pages/guard.dart index 9c192c1a..571ba13a 100644 --- a/lib/src/pages/guard.dart +++ b/lib/src/pages/guard.dart @@ -22,7 +22,7 @@ import '../../routemaster.dart'; /// to the router's default path. class Guard extends Page { /// A function that returns a page to show if [canNavigate] returns true. - final Page Function() builder; + final Page Function() builder; /// Callback to check if the route is valid. If this returns false, /// [onNavigationFailed] is called. @@ -33,7 +33,8 @@ class Guard extends Page { /// Callback, called when the [canNavigate] returns false. /// /// By default this redirects to the default path. - final Page Function(RouteData info, BuildContext context)? onNavigationFailed; + final Page Function(RouteData info, BuildContext context)? + onNavigationFailed; /// Initializes a way to prevent loading of certain routes. /// @@ -46,7 +47,7 @@ class Guard extends Page { }); @override - Route createRoute(BuildContext context) { + Route createRoute(BuildContext context) { throw UnsupportedError('Guards must be unwrapped'); } } @@ -64,7 +65,7 @@ class NotFound extends Page { const NotFound(); @override - Route createRoute(BuildContext context) { + Route createRoute(BuildContext context) { throw UnsupportedError('createRoute must not be called on NotFound'); } } @@ -99,7 +100,7 @@ class Redirect extends Page { const Redirect(this.path, {this.queryParameters}); @override - Route createRoute(BuildContext context) { + Route createRoute(BuildContext context) { throw UnimplementedError('Redirect does not support building a route'); } } diff --git a/lib/src/pages/indexed_page.dart b/lib/src/pages/indexed_page.dart index 2348c452..4bbd125d 100644 --- a/lib/src/pages/indexed_page.dart +++ b/lib/src/pages/indexed_page.dart @@ -14,7 +14,7 @@ enum TabBackBehavior { history, } -Page _defaultPageBuilder(Widget child) { +Page _defaultPageBuilder(Widget child) { return MaterialPage(child: child); } @@ -37,7 +37,7 @@ class IndexedPage extends StatefulPage with IndexedRouteMixIn { /// Optional function to customize the [Page] created for this route. /// If this is null, a [MaterialPage] is used. - final Page Function(Widget child) pageBuilder; + final Page Function(Widget child) pageBuilder; /// Specifies how tabs behave when used with the system back button. final TabBackBehavior backBehavior; @@ -104,7 +104,7 @@ class IndexedPageState extends PageState } @override - Page createPage() { + Page createPage() { return page.pageBuilder( _IndexedPageStateProvider( pageState: this, @@ -217,18 +217,18 @@ mixin IndexedPageStateMixIn> /// /// Otherwise, returns null. int? _getIndexForPath(String path) { - String _getAbsoluteTabPath(String subpath) { + String getAbsoluteTabPath(String subpath) { return PathParser.getAbsolutePath( basePath: routeData.path, path: subpath, ).path; } - final requiredAbsolutePath = _getAbsoluteTabPath(path); + final requiredAbsolutePath = getAbsoluteTabPath(path); var i = 0; for (final initialPath in page.paths) { - final tabRootAbsolutePath = _getAbsoluteTabPath(initialPath); + final tabRootAbsolutePath = getAbsoluteTabPath(initialPath); if (pathContext.equals(tabRootAbsolutePath, requiredAbsolutePath) || pathContext.isWithin(tabRootAbsolutePath, requiredAbsolutePath)) { return i; @@ -252,7 +252,7 @@ mixin IndexedPageStateMixIn> } @override - RouteData? _getRouteData(Page page) { + RouteData? _getRouteData(Page page) { // It's likely the route data will be in the currently active page so // check that first final routeData = stacks[index]._getRouteData(page); diff --git a/lib/src/pages/page_stack.dart b/lib/src/pages/page_stack.dart index d27dde16..821c5fb2 100644 --- a/lib/src/pages/page_stack.dart +++ b/lib/src/pages/page_stack.dart @@ -20,7 +20,7 @@ class PageStack extends ChangeNotifier { /// A map so we can keep track of each page's route data. This can be used by /// users to get the current page's [RouteData] via `RouteData.of(context)`. - Map _routeMap = {}; + Map, RouteData> _routeMap = {}; /// Manages a stack of pages. PageStack({List routes = const []}) { @@ -28,10 +28,10 @@ class PageStack extends ChangeNotifier { } /// Generates a list of pages for the list of routes provided to this object. - List createPages() { + List> createPages() { assert(_pageContainers.isNotEmpty, "Can't generate pages with no routes"); - final newRouteMap = {}; + final newRouteMap = , RouteData>{}; final pages = _pageContainers.map( (pageState) { final page = pageState._getOrCreatePage(); @@ -74,7 +74,7 @@ class PageStack extends ChangeNotifier { } } - RouteData? _getRouteData(Page page) { + RouteData? _getRouteData(Page page) { var route = _routeMap[page]; if (route != null) { diff --git a/lib/src/pages/pages.dart b/lib/src/pages/pages.dart index 9bb9b853..66e73fbf 100644 --- a/lib/src/pages/pages.dart +++ b/lib/src/pages/pages.dart @@ -23,7 +23,7 @@ mixin PageContainer> { /// returned via popping the route. NavigationResult? _result; - Page _getOrCreatePage(); + Page _getOrCreatePage(); } /// A [PageContainer] for a regular [Page] that maintains no state. @@ -38,8 +38,8 @@ class StatelessPage> with PageContainer { _routeData = routeData; @override - Page _getOrCreatePage() => _page; - final Page _page; + Page _getOrCreatePage() => _page; + final Page _page; /// Route information for this page. @override @@ -86,12 +86,12 @@ abstract class PageState> /// Gets the actual Flutter [Page] object for passing to a [Navigator]. /// /// This will only be called once per [PageState], and the result cached. - Page createPage(); + Page createPage(); - Page? _createdChildPage; + Page? _createdChildPage; @override - Page _getOrCreatePage() { + Page _getOrCreatePage() { _createdChildPage ??= createPage(); return _createdChildPage!; } @@ -103,7 +103,7 @@ abstract class PageState> assert(_routeData != null); } - bool _debugTypesAreRight(Page page) => page is T; + bool _debugTypesAreRight(Page page) => page is T; } /// A stateful page that hosts other child pages. @@ -120,5 +120,5 @@ mixin MultiChildPageContainer> on PageState { /// a tab page could accept the pages and put them in one of its tab's stacks. bool maybeSetChildPages(Iterable pages); - RouteData? _getRouteData(Page page); + RouteData? _getRouteData(Page page); } diff --git a/lib/src/pages/stack_page.dart b/lib/src/pages/stack_page.dart index f6ed365f..be2d8a0f 100644 --- a/lib/src/pages/stack_page.dart +++ b/lib/src/pages/stack_page.dart @@ -35,7 +35,7 @@ class StackPage extends StatefulPage with RedirectingPage { /// Optional function to customize the [Page] created for this route. /// If this is null, a [MaterialPage] is used. - final Page Function(Widget child) pageBuilder; + final Page Function(Widget child) pageBuilder; /// Initializes the page with a list of child [paths]. const StackPage({ @@ -86,7 +86,7 @@ class StackPageState extends PageState final stack = PageStack(); @override - Page createPage() { + Page createPage() { return page.pageBuilder( _StackPageStateProvider( pageState: this, @@ -112,7 +112,7 @@ class StackPageState extends PageState } @override - RouteData? _getRouteData(Page page) { + RouteData? _getRouteData(Page page) { return stack._getRouteData(page); } } diff --git a/lib/src/pages/tab_page.dart b/lib/src/pages/tab_page.dart index 4df64cdd..1ce68c3f 100644 --- a/lib/src/pages/tab_page.dart +++ b/lib/src/pages/tab_page.dart @@ -11,7 +11,7 @@ class TabPage extends StatefulPage with IndexedRouteMixIn { /// Optional function to customize the [Page] created for this route. /// If this is null, a [MaterialPage] is used. - final Page Function(Widget child) pageBuilder; + final Page Function(Widget child) pageBuilder; /// Specifies how tabs behave when used with the system back button. final TabBackBehavior backBehavior; @@ -80,7 +80,7 @@ class TabPageState extends PageState } @override - Page createPage() { + Page createPage() { return page.pageBuilder( _TabControllerProvider( pageState: this, diff --git a/pubspec.yaml b/pubspec.yaml index 2bf87265..400ab3d7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,18 +4,18 @@ version: 1.0.1 homepage: https://github.com/tomgilder/routemaster environment: - sdk: ">=2.17.0 <3.0.0" - flutter: ">=1.17.0" + sdk: ">=2.18.0 <4.0.0" + flutter: ">=3.7.0" dependencies: flutter: sdk: flutter flutter_web_plugins: sdk: flutter - path: ^1.8.0 - collection: ^1.15.0 + path: ^1.8.2 + collection: ^1.17.0 dev_dependencies: - flutter_lints: ^1.0.4 + flutter_lints: ^2.0.2 flutter_test: sdk: flutter diff --git a/test/helpers.dart b/test/helpers.dart index 9bb7ec67..77d04448 100644 --- a/test/helpers.dart +++ b/test/helpers.dart @@ -33,16 +33,27 @@ Future recordUrlChanges( Future Function(SystemUrlTracker url) callback) async { try { final tracker = SystemUrlTracker(); - SystemChannels.navigation.setMockMethodCallHandler((call) async { - if (call.method == 'routeInformationUpdated') { - final location = call.arguments['location'] as String; - tracker.current = location; - } - }); + + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler( + SystemChannels.navigation, + (call) async { + if (call.method == 'routeInformationUpdated') { + final args = call.arguments as Map; + final location = args.containsKey('uri') + ? args['uri'] as String + : args['location'] as String; + + tracker.current = location; + } + return null; + }, + ); await callback(tracker); } finally { - SystemChannels.navigation.setMockMethodCallHandler(null); + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(SystemChannels.navigation, null); SystemNav.historyProvider = null; } } diff --git a/test/route_update_test.dart b/test/route_update_test.dart index 459759dd..9ab8176f 100644 --- a/test/route_update_test.dart +++ b/test/route_update_test.dart @@ -219,18 +219,26 @@ Future trackRoute( tracker.changeUpdateCount++; }); - SystemChannels.navigation.setMockMethodCallHandler( + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler( + SystemChannels.navigation, (call) async { if (call.method == 'routeInformationUpdated') { - final location = call.arguments['location'] as String; + final args = call.arguments as Map; + final location = args.containsKey('uri') + ? args['uri'] as String + : args['location'] as String; + tracker.systemUrl = location; } + return null; }, ); await callback(delegate, tracker); } finally { - SystemChannels.navigation.setMockMethodCallHandler(null); + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(SystemChannels.navigation, null); SystemNav.historyProvider = null; } } diff --git a/test/tab_test.dart b/test/tab_test.dart index d98132c1..ca845965 100644 --- a/test/tab_test.dart +++ b/test/tab_test.dart @@ -687,7 +687,7 @@ class StubRoutemaster implements Routemaster { class StubNavigationResult implements NavigationResult { @override - Future get route => throw UnimplementedError(); + Future> get route => throw UnimplementedError(); @override Future get result => throw UnimplementedError(); diff --git a/test/web_nav_hash_test.dart b/test/web_nav_hash_test.dart index 13838e98..13c7d6f3 100644 --- a/test/web_nav_hash_test.dart +++ b/test/web_nav_hash_test.dart @@ -10,8 +10,8 @@ void main() { expect( SystemNav.makePublicUrl( RouteData('/new-path', pathTemplate: '/new-path'), - ), - '#/new-path', + ).endsWith('#/new-path'), + isTrue, ); }); @@ -19,8 +19,8 @@ void main() { expect( SystemNav.makePublicUrl( RouteData('/new-path?', pathTemplate: '/new-path'), - ), - '#/new-path', + ).endsWith('#/new-path'), + isTrue, ); }); @@ -28,8 +28,8 @@ void main() { expect( SystemNav.makePublicUrl( RouteData('/new-path?query=param', pathTemplate: '/new-path'), - ), - '#/new-path?query=param', + ).endsWith('#/new-path?query=param'), + isTrue, ); });