diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ad303fa..302c0e5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -86,6 +86,20 @@ jobs: - name: Build Android apk For Production run: melos run build-apk + # Install Firebase CLI + - name: Install Firebase CLI + run: curl -sL https://firebase.tools | bash + + # Distribute APK to Firebase App Distribution + - name: Distribute APK + run: | + firebase appdistribution:distribute apps/app_core/build/app/outputs/flutter-apk/app-prod-release.apk \ + --app "${{ secrets.FIREBASE_APP_ID }}" \ + --groups "7Span-Internal" \ + --release-notes "${{ github.event.head_commit.message }}" + env: + FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} + - name: Upload the build Artifact uses: actions/upload-artifact@v4 with: diff --git a/apps/app_core/ios/Runner.xcodeproj/project.pbxproj b/apps/app_core/ios/Runner.xcodeproj/project.pbxproj index 33c28cb..b374ea5 100644 --- a/apps/app_core/ios/Runner.xcodeproj/project.pbxproj +++ b/apps/app_core/ios/Runner.xcodeproj/project.pbxproj @@ -510,7 +510,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = "com.flutter.boilerplate.app\n"; + PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.demo.app; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -535,7 +535,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.app; + PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.demo.app; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -650,7 +650,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.flutter.boilerplate.app\n"; + PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.demo.app; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -701,7 +701,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = "com.flutter.boilerplate.app\n"; + PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.demo.app; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; @@ -728,7 +728,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.app; + PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.demo.app; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -759,7 +759,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.app; + PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.demo.app; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -847,7 +847,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.app; + PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.demo.app; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -951,7 +951,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.app; + PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.demo.app; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -1050,7 +1050,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.app; + PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.demo.app; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -1154,7 +1154,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.app; + PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.demo.app; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -1258,7 +1258,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.app; + PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.demo.app; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -1357,7 +1357,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.app; + PRODUCT_BUNDLE_IDENTIFIER = com.flutter.boilerplate.demo.app; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png index 3b89f3e..38fb302 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png index 323d229..2a7740b 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png index 03f71d1..025368c 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png index 35223cc..64a990d 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png index 26669cc..e2c8fd6 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png index c61eae3..48bef24 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png index 64bf10b..062ed27 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png index 03f71d1..025368c 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png index 81eeb2c..81e7ca0 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png index af24bf3..4005ce5 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png index 54620a9..6f876f2 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png index a5dfd31..e726e1c 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png index 520b746..baa46e2 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png index 184a170..a07e391 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png index af24bf3..4005ce5 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png index f0ae0a2..e05da37 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png index f307247..e431015 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png index 9be0f22..5f441dd 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png index 55e2a1e..ff4049d 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png index 78b9229..f4b152f 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png index 1000019..62e2472 100644 Binary files a/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/apps/app_core/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/apps/app_core/ios/Runner/info.plist b/apps/app_core/ios/Runner/info.plist index 6df563e..ecc38cd 100644 --- a/apps/app_core/ios/Runner/info.plist +++ b/apps/app_core/ios/Runner/info.plist @@ -35,14 +35,14 @@ 971758003871-288i8740a8i9re9hiki2p84uvbd8busq.apps.googleusercontent.com LSRequiresIPhoneOS + NSUserNotificationUsageDescription + We need notification permissions to keep you updated. UIApplicationSupportsIndirectInputEvents UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main - NSUserNotificationUsageDescription - We need notification permissions to keep you updated. UISupportedInterfaceOrientations UIInterfaceOrientationPortrait @@ -57,4 +57,4 @@ UIInterfaceOrientationLandscapeRight - \ No newline at end of file + diff --git a/apps/app_core/lib/modules/home/bloc/home_bloc.dart b/apps/app_core/lib/modules/home/bloc/home_bloc.dart index a45307e..b2918f7 100644 --- a/apps/app_core/lib/modules/home/bloc/home_bloc.dart +++ b/apps/app_core/lib/modules/home/bloc/home_bloc.dart @@ -12,41 +12,43 @@ part 'home_state.dart'; class HomeBloc extends Bloc { HomeBloc({required this.repository}) : super(const HomeState()) { on(_fetchPosts); - on(_onLoadMorePosts, transformer: droppable()); + on( + _onLoadMorePosts, + transformer: droppable(), + ); } final HomeRepository repository; - int _page = 1; - final int _limit = 5; - Future _fetchPosts( FetchPostsEvent event, Emitter emit, ) async { - _page = 1; - emit(const HomeState(apiStatus: ApiStatus.loading)); - final response = - await repository.fetchPostData(page: _page, limit: _limit).run(); + final response = await repository.fetchPostData().run(); - response.fold((error) => emit(state.copyWith(apiStatus: ApiStatus.error)), ( - response, - ) { - if (response.isEmpty) { - emit(const HomeState(apiStatus: ApiStatus.empty, hasReachedMax: true)); - } else { - emit( - state.copyWith( - postList: response, - apiStatus: ApiStatus.loaded, - hasReachedMax: response.length < _limit, - ), - ); - _page++; - } - }); + response.fold( + (error) => emit(state.copyWith(apiStatus: ApiStatus.error)), + (response) { + if (response.isEmpty) { + emit( + const HomeState( + apiStatus: ApiStatus.empty, + hasReachedMax: true, + ), + ); + } else { + emit( + state.copyWith( + postList: response, + apiStatus: ApiStatus.loaded, + hasReachedMax: response.length < ApiConstant.pageSize, + ), + ); + } + }, + ); } Future _onLoadMorePosts( @@ -56,19 +58,19 @@ class HomeBloc extends Bloc { if (state.hasReachedMax) return; final response = - await repository.fetchPostData(page: _page, limit: _limit).run(); + await repository.fetchPostData(page: state.nextPage).run(); - response.fold((error) => emit(state.copyWith(apiStatus: ApiStatus.error)), ( - response, - ) { - emit( - state.copyWith( - postList: List.of(state.postList)..addAll(response), - apiStatus: ApiStatus.loaded, - hasReachedMax: response.length < _limit, - ), - ); - _page++; - }); + response.fold( + (error) => emit(state.copyWith(apiStatus: ApiStatus.error)), + (response) { + emit( + state.copyWith( + postList: List.of(state.postList)..addAll(response), + apiStatus: ApiStatus.loaded, + hasReachedMax: response.length < ApiConstant.pageSize, + ), + ); + }, + ); } } diff --git a/apps/app_core/lib/modules/home/bloc/home_state.dart b/apps/app_core/lib/modules/home/bloc/home_state.dart index f33cf01..91faad1 100644 --- a/apps/app_core/lib/modules/home/bloc/home_state.dart +++ b/apps/app_core/lib/modules/home/bloc/home_state.dart @@ -8,9 +8,23 @@ class HomeState extends Equatable { }); final ApiStatus apiStatus; - final List postList; // The currently loaded users + final List + postList; // The currently loaded users final bool hasReachedMax; // Whether all pages are loaded + /// if API pagination starts with 1: + /// ```dart + /// int get nextPage => + /// (list.length / pageSize).floor() + 1; + ///``` + /// + /// if API pagination starts with 0: + /// ```dart + /// int get nextPage => + /// (list.length / pageSize).ceil(); + /// ``` + int get nextPage => (postList.length / ApiConstant.pageSize).floor() + 1; + /// Copy the state with new values. @override diff --git a/apps/app_core/lib/modules/home/repository/home_repository.dart b/apps/app_core/lib/modules/home/repository/home_repository.dart index b79c68f..776433b 100644 --- a/apps/app_core/lib/modules/home/repository/home_repository.dart +++ b/apps/app_core/lib/modules/home/repository/home_repository.dart @@ -10,8 +10,7 @@ import 'package:fpdart/fpdart.dart'; abstract interface class IHomeRepository { TaskEither> fetchPostData({ - required int page, - required int limit, + int page = 1, }); TaskEither setPlayerId(String playerId); @@ -20,10 +19,9 @@ abstract interface class IHomeRepository { class HomeRepository implements IHomeRepository { @override TaskEither> fetchPostData({ - required int page, - required int limit, + int page = 1, }) { - return makefetchPostsRequest(page, limit) + return makeFetchPostsRequest(page) .chainEither(RepositoryUtils.checkStatusCode) .chainEither( (response) => RepositoryUtils.mapToModel(() { @@ -31,7 +29,9 @@ class HomeRepository implements IHomeRepository { var postList = []; for (final postModel in response.data as List) { postList.add( - PostResponseModel.fromJson(postModel as Map), + PostResponseModel.fromJson( + postModel as Map, + ), ); } return postList; @@ -39,10 +39,13 @@ class HomeRepository implements IHomeRepository { ); } - TaskEither makefetchPostsRequest(int page, int limit) { + TaskEither makeFetchPostsRequest(int page) { return baseApiClient.request( path: ApiEndpoints.posts, - queryParameters: {'_page': page, '_limit': limit}, + queryParameters: { + '_page': page, + '_limit': ApiConstant.pageSize, + }, ); } @@ -50,10 +53,14 @@ class HomeRepository implements IHomeRepository { TaskEither setPlayerId(String playerID) => getIt() .setPlayerId(playerID) - .flatMap((r) => _sendPlayerIdToServer(playerID).map((r) => true)); + .flatMap( + (r) => _sendPlayerIdToServer(playerID).map((r) => true), + ); /// Make API call to send the player ID to the server - TaskEither _sendPlayerIdToServer(String playerID) { + TaskEither _sendPlayerIdToServer( + String playerID, + ) { return userApiClient.request( path: 'Endpoint', queryParameters: {'playerId': playerID}, diff --git a/packages/api_client/lib/api_client.dart b/packages/api_client/lib/api_client.dart index 6100a7e..cfe8ae0 100644 --- a/packages/api_client/lib/api_client.dart +++ b/packages/api_client/lib/api_client.dart @@ -5,3 +5,4 @@ export 'src/api_failure.dart'; export 'src/rest_api_client.dart'; export 'src/hive.api.service.dart' hide UserTokenSaveService; export 'src/repository_utils.dart'; +export 'src/api_constant.dart'; diff --git a/packages/api_client/lib/src/api_constant.dart b/packages/api_client/lib/src/api_constant.dart new file mode 100644 index 0000000..42c91e1 --- /dev/null +++ b/packages/api_client/lib/src/api_constant.dart @@ -0,0 +1,3 @@ +final class ApiConstant { + static const pageSize = 5; +} diff --git a/scripts/firebase_app_distribution.sh b/scripts/firebase_app_distribution.sh new file mode 100644 index 0000000..57fd022 --- /dev/null +++ b/scripts/firebase_app_distribution.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +set -e + +# Path to firebase_options.dart +FIREBASE_OPTIONS_PATH="apps/app_core/lib/firebase_options.dart" + +# Check if the file exists +if [[ ! -f "$FIREBASE_OPTIONS_PATH" ]]; then + echo ":x: firebase_options.dart not found at $FIREBASE_OPTIONS_PATH" + exit 1 +fi + +# === Config === +APP_ID=$(awk ' + $0 ~ /static const FirebaseOptions android = FirebaseOptions\(/ { in_android=1 } + in_android && $0 ~ /appId:/ { + gsub(/.*appId:[[:space:]]+'\''/, "", $0) + gsub(/'\''.*,?/, "", $0) + print $0 + exit + } +' "$FIREBASE_OPTIONS_PATH") +APK_PATH="./apps/app_core/build/app/outputs/flutter-apk/app-prod-release.apk" + +# === Ask for Group Name === +echo ":group: Enter the Firebase tester group name you want to distribute to:" +read GROUP_NAME + +if [[ -z "$GROUP_NAME" ]]; then + echo ":x: Group name cannot be empty!" + exit 1 +fi + +# === Ask for Release Notes === +echo ":memo: Enter the release notes (press Enter to skip):" +read RELEASE_NOTES + +if [[ -z "$RELEASE_NOTES" ]]; then + RELEASE_NOTES="No release notes provided" +fi + +# === Build APK === +echo ":tools: Building APK..." +melos run build-apk + +# === Upload to Firebase App Distribution === +echo ":rocket: Uploading APK to Firebase App Distribution..." +firebase appdistribution:distribute "$APK_PATH" \ + --app "$APP_ID" \ + --groups "$GROUP_NAME" \ + --release-notes "$RELEASE_NOTES" + +# === Done === +echo ":white_check_mark: Upload complete!"