From c2ece8e0fad1ab98b112741486b6ab1b71099929 Mon Sep 17 00:00:00 2001 From: fatkhul jabal Date: Mon, 19 Feb 2024 13:44:16 +0700 Subject: [PATCH 1/4] update feature proof reading & create feature check version apps --- app/android/app/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/android/app/src/main/AndroidManifest.xml b/app/android/app/src/main/AndroidManifest.xml index a37c110c..1ae9acdb 100644 --- a/app/android/app/src/main/AndroidManifest.xml +++ b/app/android/app/src/main/AndroidManifest.xml @@ -6,7 +6,7 @@ Date: Mon, 19 Feb 2024 13:46:53 +0700 Subject: [PATCH 2/4] update feature proof reading & create feature check version apps --- app/Makefile | 5 +++ .../repositories/register_user_repo.dart | 29 ++++++++++++++ .../main/presentation/pages/home_page.dart | 9 ++++- .../onboarding/model/version_model.dart | 13 +++++++ .../bloc/user_initialization_bloc.dart | 23 ++++++++--- .../bloc/user_initialization_state.dart | 5 +++ .../onboarding/presentation/pages/_pages.dart | 2 + .../presentation/pages/splash_screen.dart | 14 ++++++- .../presentation/pages/update_dialog.dart | 39 +++++++++++++++++++ .../presentation/model/quiz_exercise.dart | 2 +- .../repositories/quiz_exercise.dart | 5 +-- .../presentation/pages/task_list_page.dart | 15 ++++++- .../Flutter/GeneratedPluginRegistrant.swift | 2 + app/pubspec.lock | 18 ++++++++- app/pubspec.yaml | 5 ++- 15 files changed, 170 insertions(+), 16 deletions(-) create mode 100644 app/lib/features/onboarding/model/version_model.dart create mode 100644 app/lib/features/onboarding/presentation/pages/update_dialog.dart diff --git a/app/Makefile b/app/Makefile index 5cd93d01..a7ec93f8 100644 --- a/app/Makefile +++ b/app/Makefile @@ -19,6 +19,11 @@ init: make build_runner @echo "╠ Initialize successed!" +release: + make init + @flutter pub run flutter_launcher_icons + @flutter build appbundle + dev: @flutter run lib/main.dart diff --git a/app/lib/features/authentication/register/repositories/register_user_repo.dart b/app/lib/features/authentication/register/repositories/register_user_repo.dart index 0ad9da6f..5dc5bac6 100644 --- a/app/lib/features/authentication/register/repositories/register_user_repo.dart +++ b/app/lib/features/authentication/register/repositories/register_user_repo.dart @@ -2,6 +2,7 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/foundation.dart'; import 'package:injectable/injectable.dart'; +import '../../../onboarding/model/version_model.dart'; import '../model/registered_user.dart'; @Injectable() @@ -111,4 +112,32 @@ class RegisterUserRepository { } return null; } + + Future getVersionApps(String version) async { + try { + final result = await FirebaseFirestore.instance + .collection('configuration') + .doc('version') + .get(); + + final allVersion = result.data()?['version'] as List; + + for (final element in allVersion) { + if (element == version) { + final storedVersion = element.toString(); + return VersionModel(version: storedVersion); + } + } + return null; + } on FirebaseException catch (e) { + if (kDebugMode) { + print("Failed with error '${e.code}': '${e.message}'"); + } + return null; + } catch (e) { + throw Exception(e.toString()); + } + } + + } diff --git a/app/lib/features/main/presentation/pages/home_page.dart b/app/lib/features/main/presentation/pages/home_page.dart index 3bd1ee7d..0e3a08fa 100644 --- a/app/lib/features/main/presentation/pages/home_page.dart +++ b/app/lib/features/main/presentation/pages/home_page.dart @@ -103,7 +103,7 @@ class _HomePageState extends State { text: 'Pengaturan', ), SizedBox( - height: MediaQuery.of(context).size.height - 620, + height: MediaQuery.of(context).size.height - 640, ), InkWell( onTap: () async { @@ -122,6 +122,13 @@ class _HomePageState extends State { ), ), ), + Center( + child: Text( + 'V 1.0.0', + textAlign: TextAlign.center, + style: FontTheme.greyNormal14(), + ), + ), ], ), ), diff --git a/app/lib/features/onboarding/model/version_model.dart b/app/lib/features/onboarding/model/version_model.dart new file mode 100644 index 00000000..f0fb2559 --- /dev/null +++ b/app/lib/features/onboarding/model/version_model.dart @@ -0,0 +1,13 @@ +class VersionModel { + final String version; + + VersionModel({ + required this.version, + }); + + factory VersionModel.fromJson(Map json) { + return VersionModel( + version: json['version'].toString(), + ); + } +} diff --git a/app/lib/features/onboarding/presentation/bloc/user_initialization_bloc.dart b/app/lib/features/onboarding/presentation/bloc/user_initialization_bloc.dart index dfe7e6a9..850ae603 100644 --- a/app/lib/features/onboarding/presentation/bloc/user_initialization_bloc.dart +++ b/app/lib/features/onboarding/presentation/bloc/user_initialization_bloc.dart @@ -4,6 +4,7 @@ import 'package:equatable/equatable.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:injectable/injectable.dart'; +import 'package:package_info_plus/package_info_plus.dart'; import '../../../authentication/register/repositories/register_user_repo.dart'; @@ -14,6 +15,7 @@ part 'user_initialization_state.dart'; @singleton class UserInitializationBloc extends Bloc { + final RegisterUserRepository registerUserRepository; // final GoogleSignIn _googleSignIn = GoogleSignIn(); @@ -21,7 +23,7 @@ class UserInitializationBloc : super(UserInitializationInitial()) { on(_auth); } - + FutureOr _auth( OnboardingAuthEvent state, Emitter emit, @@ -31,20 +33,31 @@ class UserInitializationBloc if (creds != null) { emit(UserAuthenticated()); final userId = creds.uid; + + final packageInfo = await PackageInfo.fromPlatform(); + + final checkVersionApps = await registerUserRepository.getVersionApps( + packageInfo.version + ); + + if (checkVersionApps == null) { + return emit(UpdateAvailable()); + } + try { final data = await registerUserRepository.getById(userId); print(data); if (data == null) { - emit(UserUnregistered()); + return emit(UserUnregistered()); } else { - emit(UserRegistered()); + return emit(UserRegistered()); } } catch (e) { - emit(UserError(e.toString())); + return emit(UserError(e.toString())); } } else { - emit(UserUnauthenticated()); + return emit(UserUnauthenticated()); } } } diff --git a/app/lib/features/onboarding/presentation/bloc/user_initialization_state.dart b/app/lib/features/onboarding/presentation/bloc/user_initialization_state.dart index 2e81ff1c..b1e02d94 100644 --- a/app/lib/features/onboarding/presentation/bloc/user_initialization_state.dart +++ b/app/lib/features/onboarding/presentation/bloc/user_initialization_state.dart @@ -40,6 +40,11 @@ class UserRegistered extends UserInitializationState { List get props => []; } +class UpdateAvailable extends UserInitializationState { + @override + List get props => []; +} + class UserGetDataLoading extends UserInitializationState { @override List get props => []; diff --git a/app/lib/features/onboarding/presentation/pages/_pages.dart b/app/lib/features/onboarding/presentation/pages/_pages.dart index aa116754..88dd56b7 100644 --- a/app/lib/features/onboarding/presentation/pages/_pages.dart +++ b/app/lib/features/onboarding/presentation/pages/_pages.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; +import 'package:url_launcher/url_launcher.dart'; import '../../../../core/constants/assets.dart'; import '../bloc/user_initialization_bloc.dart'; part 'splash_screen.dart'; part 'onboarding_page.dart'; +part 'update_dialog.dart'; diff --git a/app/lib/features/onboarding/presentation/pages/splash_screen.dart b/app/lib/features/onboarding/presentation/pages/splash_screen.dart index bc19b761..c2efea33 100644 --- a/app/lib/features/onboarding/presentation/pages/splash_screen.dart +++ b/app/lib/features/onboarding/presentation/pages/splash_screen.dart @@ -1,5 +1,6 @@ part of '_pages.dart'; + class SplashScreen extends StatelessWidget { const SplashScreen({super.key}); @@ -8,7 +9,9 @@ class SplashScreen extends StatelessWidget { final size = MediaQuery.of(context).size; return BlocListener( listener: (context, state) { - if (state is UserUnauthenticated) { + if (state is UpdateAvailable) { + showUpdateDialog(context); + } else if (state is UserUnauthenticated) { context.go('/onboarding'); } else if (state is UserUnregistered) { context.go('/register'); @@ -35,3 +38,12 @@ class SplashScreen extends StatelessWidget { ); } } + +void showUpdateDialog(BuildContext context) { + showDialog( + context: context, + builder: (BuildContext context) { + return const UpdateDialog(); + }, + ); +} diff --git a/app/lib/features/onboarding/presentation/pages/update_dialog.dart b/app/lib/features/onboarding/presentation/pages/update_dialog.dart new file mode 100644 index 00000000..a92daaae --- /dev/null +++ b/app/lib/features/onboarding/presentation/pages/update_dialog.dart @@ -0,0 +1,39 @@ +part of '_pages.dart'; + +class UpdateDialog extends StatelessWidget { + const UpdateDialog({super.key}); + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text('Versi Baru Tersedia'), + content: const SingleChildScrollView( + child: ListBody( + children: [ + Text('Sebuah versi baru dari aplikasi tersedia.'), + Text( + 'Silakan perbarui ke versi terbaru untuk ' + 'menikmati fitur dan perbaikan baru.' + ), + ], + ), + ), + actions: [ + Center( + child: TextButton( + child: const Text('Update Sekarang'), + onPressed: () async { + // Navigator.of(context).pop(); + final url = Uri.parse( + 'https://play.google.com/store/apps/details?id=com.toki.bebras_pandai&hl=en-US&ah=i6XiDj6PnW-iPzIlbXBXM-jTYjA', + ); + if (!await launchUrl(url)) { + throw Exception('Could not launch $url'); + } + }, + ), + ) + ], + ); + } +} diff --git a/app/lib/features/quiz_exercise/presentation/model/quiz_exercise.dart b/app/lib/features/quiz_exercise/presentation/model/quiz_exercise.dart index 3a9d22b7..799fd9ce 100644 --- a/app/lib/features/quiz_exercise/presentation/model/quiz_exercise.dart +++ b/app/lib/features/quiz_exercise/presentation/model/quiz_exercise.dart @@ -17,7 +17,7 @@ class QuizExerciseBase { factory QuizExerciseBase.fromJson(Map json) { return QuizExerciseBase( - id: json['id'] as String, + id: json['doc_id'] as String, challengeGroup: json['challenge_group'] as String, title: json['title'] as String, status: json['status'] as String?, diff --git a/app/lib/features/quiz_exercise/presentation/repositories/quiz_exercise.dart b/app/lib/features/quiz_exercise/presentation/repositories/quiz_exercise.dart index 14a8597e..00a49152 100644 --- a/app/lib/features/quiz_exercise/presentation/repositories/quiz_exercise.dart +++ b/app/lib/features/quiz_exercise/presentation/repositories/quiz_exercise.dart @@ -71,13 +71,10 @@ class QuizExerciseRepository { final globalResult = await db.collection('configuration').doc('global_variables').get(); - final taskSet = globalResult.get('task_set_doc_index') as List; + final taskSet = globalResult.get('task_set_doc_$group') as List; for (final element in taskSet) { - final challengeGroup = element['challenge_group'] as String; - if (challengeGroup == group) { quizExerciseBaseList .add(QuizExerciseBase.fromJson(element as Map)); - } } return quizExerciseBaseList; diff --git a/app/lib/features/task_list/presentation/pages/task_list_page.dart b/app/lib/features/task_list/presentation/pages/task_list_page.dart index 0d0c460a..41b6bb2c 100644 --- a/app/lib/features/task_list/presentation/pages/task_list_page.dart +++ b/app/lib/features/task_list/presentation/pages/task_list_page.dart @@ -80,11 +80,24 @@ class _TaskListPageState extends State { return GestureDetector( onTap: () { + String cleanedTaskId; + if (task.id.startsWith('penegak_')) { + cleanedTaskId = task.id.replaceFirst('penegak_', ''); + } else if (task.id.startsWith('sikecil_')) { + cleanedTaskId = task.id.replaceFirst('sikecil_', ''); + } else if (task.id.startsWith('penggalang_')) { + cleanedTaskId = task.id.replaceFirst('penggalang_', ''); + } else if (task.id.startsWith('siaga_')) { + cleanedTaskId = task.id.replaceFirst('siaga_', ''); + } else { + cleanedTaskId = task.id; + } + context.push( Uri( path: '/task_detail', queryParameters: { - 'task_id': task.id, + 'task_id': cleanedTaskId, }, ).toString(), ); diff --git a/app/macos/Flutter/GeneratedPluginRegistrant.swift b/app/macos/Flutter/GeneratedPluginRegistrant.swift index 1ad35f2a..97d31d81 100644 --- a/app/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/app/macos/Flutter/GeneratedPluginRegistrant.swift @@ -12,6 +12,7 @@ import firebase_messaging import firebase_storage import flutter_local_notifications import geolocator_apple +import package_info_plus import path_provider_foundation import printing import shared_preferences_foundation @@ -26,6 +27,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTFirebaseStoragePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseStoragePlugin")) FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) diff --git a/app/pubspec.lock b/app/pubspec.lock index 28904c97..a6879588 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -960,6 +960,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + package_info_plus: + dependency: "direct main" + description: + name: package_info_plus + sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79" + url: "https://pub.dev" + source: hosted + version: "5.0.1" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" + url: "https://pub.dev" + source: hosted + version: "2.0.1" path: dependency: transitive description: @@ -1558,5 +1574,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.2.0-194.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" flutter: ">=3.13.0" diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 1d842192..73f96b25 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -1,5 +1,5 @@ name: bebras_pandai -description: Bebras description +description: Aplikasi belajar Computational Thinking oleh bebras.org # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.0.0+1 +version: 1.0.0+13 environment: sdk: '>=3.0.5 <4.0.0' @@ -67,6 +67,7 @@ dependencies: firebase_messaging: ^14.7.3 cached_network_svg_image: ^0.0.7 flutter_html_svg: ^3.0.0-beta.2 + package_info_plus: ^5.0.1 dev_dependencies: build_runner: null From f95ebc06464df5cb98089244f3248b6ff19f4898 Mon Sep 17 00:00:00 2001 From: fatkhul jabal Date: Wed, 21 Feb 2024 12:19:18 +0700 Subject: [PATCH 3/4] update libraly version --- app/android/app/src/main/AndroidManifest.xml | 2 +- .../repositories/register_user_repo.dart | 1 + .../main/presentation/pages/_pages.dart | 2 ++ .../main/presentation/pages/home_page.dart | 20 ++++++++++++++++++- .../bloc/user_initialization_bloc.dart | 14 ++++++++----- app/lib/main.dart | 2 +- .../Flutter/GeneratedPluginRegistrant.swift | 2 -- app/pubspec.lock | 18 +---------------- app/pubspec.yaml | 2 +- 9 files changed, 35 insertions(+), 28 deletions(-) diff --git a/app/android/app/src/main/AndroidManifest.xml b/app/android/app/src/main/AndroidManifest.xml index 1ae9acdb..a37c110c 100644 --- a/app/android/app/src/main/AndroidManifest.xml +++ b/app/android/app/src/main/AndroidManifest.xml @@ -6,7 +6,7 @@ { + String version = ''; + @override void initState() { context.read().fetchUser(); + _loadVersion(); super.initState(); } + Future _loadVersion() async { + try { + final yamlMap = + loadYaml(await rootBundle.loadString('pubspec.yaml')); + final versionWithBuildNumber = + yamlMap['version'] as String; + final parts = versionWithBuildNumber.split('+'); + setState(() { + version = parts[0]; + }); + } catch (e) { + print('Error loading version: $e'); + } + } + @override Widget build(BuildContext context) { return BebrasScaffold( @@ -124,7 +142,7 @@ class _HomePageState extends State { ), Center( child: Text( - 'V 1.0.0', + 'V $version', textAlign: TextAlign.center, style: FontTheme.greyNormal14(), ), diff --git a/app/lib/features/onboarding/presentation/bloc/user_initialization_bloc.dart b/app/lib/features/onboarding/presentation/bloc/user_initialization_bloc.dart index 850ae603..ec491489 100644 --- a/app/lib/features/onboarding/presentation/bloc/user_initialization_bloc.dart +++ b/app/lib/features/onboarding/presentation/bloc/user_initialization_bloc.dart @@ -2,9 +2,10 @@ import 'dart:async'; import 'package:equatable/equatable.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:injectable/injectable.dart'; -import 'package:package_info_plus/package_info_plus.dart'; +import 'package:yaml/yaml.dart'; import '../../../authentication/register/repositories/register_user_repo.dart'; @@ -34,12 +35,15 @@ class UserInitializationBloc emit(UserAuthenticated()); final userId = creds.uid; - final packageInfo = await PackageInfo.fromPlatform(); - + final yamlMap = loadYaml(await rootBundle.loadString('pubspec.yaml')); + final versionWithBuildNumber = yamlMap['version'] as String; + final parts = versionWithBuildNumber.split('+'); + final version = parts[0]; + final checkVersionApps = await registerUserRepository.getVersionApps( - packageInfo.version + version ); - + if (checkVersionApps == null) { return emit(UpdateAvailable()); } diff --git a/app/lib/main.dart b/app/lib/main.dart index 48d775de..3a4ccfe0 100644 --- a/app/lib/main.dart +++ b/app/lib/main.dart @@ -13,6 +13,6 @@ Future main() async { configureDependencies(); await FirebaseService.initialize(); await FirebaseApi().initNotifications(); - await initializeDateFormatting('id_ID', null); + await initializeDateFormatting('id_ID'); runApp(const App()); } diff --git a/app/macos/Flutter/GeneratedPluginRegistrant.swift b/app/macos/Flutter/GeneratedPluginRegistrant.swift index 97d31d81..1ad35f2a 100644 --- a/app/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/app/macos/Flutter/GeneratedPluginRegistrant.swift @@ -12,7 +12,6 @@ import firebase_messaging import firebase_storage import flutter_local_notifications import geolocator_apple -import package_info_plus import path_provider_foundation import printing import shared_preferences_foundation @@ -27,7 +26,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTFirebaseStoragePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseStoragePlugin")) FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) - FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) diff --git a/app/pubspec.lock b/app/pubspec.lock index a6879588..28904c97 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -960,22 +960,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" - package_info_plus: - dependency: "direct main" - description: - name: package_info_plus - sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79" - url: "https://pub.dev" - source: hosted - version: "5.0.1" - package_info_plus_platform_interface: - dependency: transitive - description: - name: package_info_plus_platform_interface - sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" - url: "https://pub.dev" - source: hosted - version: "2.0.1" path: dependency: transitive description: @@ -1574,5 +1558,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.2.0 <4.0.0" + dart: ">=3.2.0-194.0.dev <4.0.0" flutter: ">=3.13.0" diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 73f96b25..a7f2329c 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -67,7 +67,6 @@ dependencies: firebase_messaging: ^14.7.3 cached_network_svg_image: ^0.0.7 flutter_html_svg: ^3.0.0-beta.2 - package_info_plus: ^5.0.1 dev_dependencies: build_runner: null @@ -101,6 +100,7 @@ flutter: - assets/images/ - assets/images/flags/ - .env + - pubspec.yaml # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware From 3fc5108c8e62b1f30930e3b6a791db3f21fd7412 Mon Sep 17 00:00:00 2001 From: fatkhul jabal Date: Thu, 22 Feb 2024 13:56:29 +0700 Subject: [PATCH 4/4] update popup version --- app/android/app/src/main/AndroidManifest.xml | 1 - app/ios/Runner.xcodeproj/project.pbxproj | 135 ++++++++++++++++-- .../presentation/pages/update_dialog.dart | 59 ++++---- app/macos/Runner.xcodeproj/project.pbxproj | 6 +- app/macos/Runner/Configs/AppInfo.xcconfig | 2 +- 5 files changed, 159 insertions(+), 44 deletions(-) diff --git a/app/android/app/src/main/AndroidManifest.xml b/app/android/app/src/main/AndroidManifest.xml index a37c110c..37ba9968 100644 --- a/app/android/app/src/main/AndroidManifest.xml +++ b/app/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ - /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 339E7C3ACD284CFEB4066CBE /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -257,6 +347,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + C55559B376FF4972972B6E34 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -364,13 +471,15 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 8NY9Z6P9SK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = bebrasPandai; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebrasPandai; + PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebras; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -380,14 +489,14 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AE0B7B92F70575B8D7E0D07E /* Pods-RunnerTests.debug.xcconfig */; + baseConfigurationReference = 76E6D5E674F0B996969AE18D /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebrasPandai.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebras.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -398,14 +507,14 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 89B67EB44CE7B6631473024E /* Pods-RunnerTests.release.xcconfig */; + baseConfigurationReference = 258C70F55133C40067AD15A9 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebrasPandai.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebras.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -414,14 +523,14 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 640959BDD8F10B91D80A66BE /* Pods-RunnerTests.profile.xcconfig */; + baseConfigurationReference = 54ED3700E7BFA509D831AE15 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebrasPandai.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebras.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -542,13 +651,15 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = ""; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = bebrasPandai; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebrasPandai; + PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebras; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -564,13 +675,15 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 8NY9Z6P9SK; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = bebrasPandai; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebrasPandai; + PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebras; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/app/lib/features/onboarding/presentation/pages/update_dialog.dart b/app/lib/features/onboarding/presentation/pages/update_dialog.dart index a92daaae..8cd66ace 100644 --- a/app/lib/features/onboarding/presentation/pages/update_dialog.dart +++ b/app/lib/features/onboarding/presentation/pages/update_dialog.dart @@ -5,35 +5,38 @@ class UpdateDialog extends StatelessWidget { @override Widget build(BuildContext context) { - return AlertDialog( - title: const Text('Versi Baru Tersedia'), - content: const SingleChildScrollView( - child: ListBody( - children: [ - Text('Sebuah versi baru dari aplikasi tersedia.'), - Text( - 'Silakan perbarui ke versi terbaru untuk ' - 'menikmati fitur dan perbaikan baru.' - ), - ], - ), - ), - actions: [ - Center( - child: TextButton( - child: const Text('Update Sekarang'), - onPressed: () async { - // Navigator.of(context).pop(); - final url = Uri.parse( - 'https://play.google.com/store/apps/details?id=com.toki.bebras_pandai&hl=en-US&ah=i6XiDj6PnW-iPzIlbXBXM-jTYjA', - ); - if (!await launchUrl(url)) { - throw Exception('Could not launch $url'); - } - }, + return WillPopScope( + onWillPop: () async => false, + child: AlertDialog( + title: const Text('Versi Baru Tersedia'), + content: const SingleChildScrollView( + child: ListBody( + children: [ + Text('Sebuah versi baru dari aplikasi tersedia.'), + Text( + 'Silakan perbarui ke versi terbaru untuk ' + 'menikmati fitur dan perbaikan baru.' + ), + ], ), - ) - ], + ), + actions: [ + Center( + child: TextButton( + child: const Text('Update Sekarang'), + onPressed: () async { + // Navigator.of(context).pop(); + final url = Uri.parse( + 'https://play.google.com/store/apps/details?id=com.toki.bebras_pandai&hl=en-US&ah=i6XiDj6PnW-iPzIlbXBXM-jTYjA', + ); + if (!await launchUrl(url)) { + throw Exception('Could not launch $url'); + } + }, + ), + ) + ], + ) ); } } diff --git a/app/macos/Runner.xcodeproj/project.pbxproj b/app/macos/Runner.xcodeproj/project.pbxproj index 3904f8e1..442144a8 100644 --- a/app/macos/Runner.xcodeproj/project.pbxproj +++ b/app/macos/Runner.xcodeproj/project.pbxproj @@ -384,7 +384,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebrasPandai.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebras.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/bebras_pandai.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/bebras_pandai"; @@ -398,7 +398,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebrasPandai.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebras.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/bebras_pandai.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/bebras_pandai"; @@ -412,7 +412,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebrasPandai.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebras.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/bebras_pandai.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/bebras_pandai"; diff --git a/app/macos/Runner/Configs/AppInfo.xcconfig b/app/macos/Runner/Configs/AppInfo.xcconfig index 037a1f72..e8011f9c 100644 --- a/app/macos/Runner/Configs/AppInfo.xcconfig +++ b/app/macos/Runner/Configs/AppInfo.xcconfig @@ -8,7 +8,7 @@ PRODUCT_NAME = bebras_pandai // The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebrasPandai +PRODUCT_BUNDLE_IDENTIFIER = com.toki.bebras // The copyright displayed in application information PRODUCT_COPYRIGHT = Copyright © 2023 com.toki. All rights reserved.