diff --git a/mobile-app/lib/app/app.router.dart b/mobile-app/lib/app/app.router.dart index 66a9260cb..b02317648 100644 --- a/mobile-app/lib/app/app.router.dart +++ b/mobile-app/lib/app/app.router.dart @@ -277,8 +277,12 @@ class StackedRouter extends _i1.RouterBase { ); }, _i12.ChapterView: (data) { + final args = data.getArgs(nullOk: false); return _i21.MaterialPageRoute( - builder: (context) => const _i12.ChapterView(), + builder: (context) => _i12.ChapterView( + key: args.key, + superBlockDashedName: args.superBlockDashedName, + superBlockName: args.superBlockName), settings: data, ); }, @@ -596,6 +600,40 @@ class ChallengeTemplateViewArguments { } } +class ChapterViewArguments { + const ChapterViewArguments({ + this.key, + required this.superBlockDashedName, + required this.superBlockName, + }); + + final _i21.Key? key; + + final String superBlockDashedName; + + final String superBlockName; + + @override + String toString() { + return '{"key": "$key", "superBlockDashedName": "$superBlockDashedName", "superBlockName": "$superBlockName"}'; + } + + @override + bool operator ==(covariant ChapterViewArguments other) { + if (identical(this, other)) return true; + return other.key == key && + other.superBlockDashedName == superBlockDashedName && + other.superBlockName == superBlockName; + } + + @override + int get hashCode { + return key.hashCode ^ + superBlockDashedName.hashCode ^ + superBlockName.hashCode; + } +} + class ChapterBlockViewArguments { const ChapterBlockViewArguments({ this.key, @@ -883,14 +921,21 @@ extension NavigatorStateExtension on _i26.NavigationService { transition: transition); } - Future navigateToChapterView([ + Future navigateToChapterView({ + _i21.Key? key, + required String superBlockDashedName, + required String superBlockName, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { + }) async { return navigateTo(Routes.chapterView, + arguments: ChapterViewArguments( + key: key, + superBlockDashedName: superBlockDashedName, + superBlockName: superBlockName), id: routerId, preventDuplicates: preventDuplicates, parameters: parameters, @@ -1214,14 +1259,21 @@ extension NavigatorStateExtension on _i26.NavigationService { transition: transition); } - Future replaceWithChapterView([ + Future replaceWithChapterView({ + _i21.Key? key, + required String superBlockDashedName, + required String superBlockName, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { + }) async { return replaceWith(Routes.chapterView, + arguments: ChapterViewArguments( + key: key, + superBlockDashedName: superBlockDashedName, + superBlockName: superBlockName), id: routerId, preventDuplicates: preventDuplicates, parameters: parameters, diff --git a/mobile-app/lib/models/learn/curriculum_model.dart b/mobile-app/lib/models/learn/curriculum_model.dart index 3b1c2c663..3e5473048 100644 --- a/mobile-app/lib/models/learn/curriculum_model.dart +++ b/mobile-app/lib/models/learn/curriculum_model.dart @@ -1,4 +1,4 @@ -const chapterBasedSuperBlocks = ['full-stack-developer']; +import 'package:freecodecamp/ui/views/learn/utils/learn_globals.dart'; enum SuperBlocks { respWebDesignV9('responsive-web-design-v9'), @@ -320,7 +320,8 @@ class Chapter { enum ModuleType { review('review'), - exam('exam'); + exam('exam'), + certProject('cert-project'); static ModuleType fromValue(String value) { return ModuleType.values.firstWhere( diff --git a/mobile-app/lib/ui/views/learn/chapter/chapter_view.dart b/mobile-app/lib/ui/views/learn/chapter/chapter_view.dart index 4f256e442..7b56e68f9 100644 --- a/mobile-app/lib/ui/views/learn/chapter/chapter_view.dart +++ b/mobile-app/lib/ui/views/learn/chapter/chapter_view.dart @@ -5,18 +5,28 @@ import 'package:freecodecamp/ui/views/learn/chapter/chapter_viewmodel.dart'; import 'package:stacked/stacked.dart'; class ChapterView extends StatelessWidget { - const ChapterView({super.key}); + const ChapterView({ + super.key, + required this.superBlockDashedName, + required this.superBlockName, + }); + + final String superBlockDashedName; + final String superBlockName; @override Widget build(BuildContext context) { return ViewModelBuilder.reactive( viewModelBuilder: () => ChapterViewModel(), - onViewModelReady: (model) => model.init(), + onViewModelReady: (model) => model.init( + superBlockDashedName, + superBlockName, + ), builder: (context, model, child) { return Scaffold( backgroundColor: FccColors.gray90, appBar: AppBar( - title: Text('Chapters'), + title: Text(superBlockName), ), body: StreamBuilder( stream: model.auth.progress.stream, diff --git a/mobile-app/lib/ui/views/learn/chapter/chapter_viewmodel.dart b/mobile-app/lib/ui/views/learn/chapter/chapter_viewmodel.dart index 88fc39423..594c3c554 100644 --- a/mobile-app/lib/ui/views/learn/chapter/chapter_viewmodel.dart +++ b/mobile-app/lib/ui/views/learn/chapter/chapter_viewmodel.dart @@ -26,8 +26,8 @@ class ChapterViewModel extends BaseViewModel { notifyListeners(); } - void init() async { - superBlockFuture = requestChapters(); + void init(String superBlockDashedName, superBlockName) async { + superBlockFuture = requestChapters(superBlockDashedName, superBlockName); developmentMode(); } @@ -63,15 +63,18 @@ class ChapterViewModel extends BaseViewModel { return false; } - Future requestChapters() async { + Future requestChapters( + String superBlockDashedName, String superBlockName) async { String baseUrl = LearnService.baseUrl; - final Response res = await _dio.get('$baseUrl/full-stack-developer.json'); + final Response res = await _dio.get( + '$baseUrl/$superBlockDashedName.json', + ); if (res.statusCode == 200) { return SuperBlock.fromJson( res.data, - 'full-stack-developer', - 'Certified Full Stack Developer Curriculum', + superBlockDashedName, + superBlockName, ); } diff --git a/mobile-app/lib/ui/views/learn/landing/landing_viewmodel.dart b/mobile-app/lib/ui/views/learn/landing/landing_viewmodel.dart index 1ad0bcb8f..e8339612f 100644 --- a/mobile-app/lib/ui/views/learn/landing/landing_viewmodel.dart +++ b/mobile-app/lib/ui/views/learn/landing/landing_viewmodel.dart @@ -20,6 +20,7 @@ import 'package:freecodecamp/service/learn/daily_challenge_service.dart'; import 'package:freecodecamp/service/learn/learn_offline_service.dart'; import 'package:freecodecamp/service/learn/learn_service.dart'; import 'package:freecodecamp/ui/views/learn/landing/landing_view.dart'; +import 'package:freecodecamp/ui/views/learn/utils/learn_globals.dart'; import 'package:freecodecamp/ui/widgets/setup_dialog_ui.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:stacked/stacked.dart'; @@ -290,8 +291,14 @@ class LearnLandingViewModel extends BaseViewModel { } void routeToSuperBlock(String dashedName, String name) async { - if (dashedName == 'full-stack-developer') { - _navigationService.navigateTo(Routes.chapterView); + if (chapterBasedSuperBlocks.contains(dashedName)) { + _navigationService.navigateTo( + Routes.chapterView, + arguments: ChapterViewArguments( + superBlockDashedName: dashedName, + superBlockName: name, + ), + ); } else { _navigationService.navigateTo( Routes.superBlockView, diff --git a/mobile-app/lib/ui/views/learn/superblock/superblock_view.dart b/mobile-app/lib/ui/views/learn/superblock/superblock_view.dart index f74c3bdb9..4107569fe 100644 --- a/mobile-app/lib/ui/views/learn/superblock/superblock_view.dart +++ b/mobile-app/lib/ui/views/learn/superblock/superblock_view.dart @@ -100,7 +100,7 @@ class SuperBlockView extends StatelessWidget { } if (snapshot.hasError) { - return Text(context.t.error); + return Center(child: Text(context.t.error)); } return const Center( diff --git a/mobile-app/lib/ui/views/learn/utils/learn_globals.dart b/mobile-app/lib/ui/views/learn/utils/learn_globals.dart index b9faa8239..ea42d90fe 100644 --- a/mobile-app/lib/ui/views/learn/utils/learn_globals.dart +++ b/mobile-app/lib/ui/views/learn/utils/learn_globals.dart @@ -7,3 +7,9 @@ List hasDialogue = [ 'a2-english-for-developers', 'b1-english-for-developers', ]; + +const chapterBasedSuperBlocks = [ + 'responsive-web-design-v9', + 'javascript-v9', + 'python-v9' +];