diff --git a/CHANGELOG.md b/CHANGELOG.md index f149e381e..30a69b7bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,126 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 2024-06-25 + +### Changes + +--- + +Packages with breaking changes: + + - There are no breaking changes in this release. + +Packages with other changes: + + - [`deriv_auth` - `v6.7.1`](#deriv_auth---v671) + - [`deriv_web_view` - `v0.2.2+3`](#deriv_web_view---v0223) + - [`deriv_ui` - `v0.0.7+9`](#deriv_ui---v0079) + - [`deriv_widgetbook` - `v0.0.2+9`](#deriv_widgetbook---v0029) + - [`deriv_passkeys` - `v0.0.2+3`](#deriv_passkeys---v0023) + - [`deriv_language_selector` - `v0.0.2+7`](#deriv_language_selector---v0027) + +Packages with dependency updates only: + +> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project. + + - `deriv_ui` - `v0.0.7+9` + - `deriv_widgetbook` - `v0.0.2+9` + - `deriv_passkeys` - `v0.0.2+3` + - `deriv_language_selector` - `v0.0.2+7` + +--- + +#### `deriv_auth` - `v6.7.1` + + - **FIX**(deriv_auth): Fix login provider null issue ([#641](https://github.com/regentmarkets/flutter-deriv-packages/issues/641)). ([e4181541](https://github.com/regentmarkets/flutter-deriv-packages/commit/e41815416eb76b3724481f8a0b980e943311ebeb)) + - **FIX**(deriv_web_view): update deriv ui version in deriv auth ([#639](https://github.com/regentmarkets/flutter-deriv-packages/issues/639)). ([11b46a9f](https://github.com/regentmarkets/flutter-deriv-packages/commit/11b46a9f7bd00482d3cac7820cf4cd5d61da0cad)) + +#### `deriv_web_view` - `v0.2.2+3` + + - **FIX**(deriv_web_view): update deriv web view readme file ([#637](https://github.com/regentmarkets/flutter-deriv-packages/issues/637)). ([b0b66dad](https://github.com/regentmarkets/flutter-deriv-packages/commit/b0b66dadb6cb1b30dc3ad759f2eee031673b6bbf)) + + +## 2024-06-25 + +### Changes + +--- + +Packages with breaking changes: + + - There are no breaking changes in this release. + +Packages with other changes: + + - [`deriv_auth` - `v6.7.0`](#deriv_auth---v670) + - [`deriv_web_view` - `v0.2.2+2`](#deriv_web_view---v0222) + - [`update_checker` - `v1.4.0`](#update_checker---v140) + - [`deriv_ui` - `v0.0.7+8`](#deriv_ui---v0078) + - [`deriv_widgetbook` - `v0.0.2+8`](#deriv_widgetbook---v0028) + - [`deriv_passkeys` - `v0.0.2+2`](#deriv_passkeys---v0022) + - [`deriv_language_selector` - `v0.0.2+6`](#deriv_language_selector---v0026) + +Packages with dependency updates only: + +> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project. + + - `deriv_ui` - `v0.0.7+8` + - `deriv_widgetbook` - `v0.0.2+8` + - `deriv_passkeys` - `v0.0.2+2` + - `deriv_language_selector` - `v0.0.2+6` + +--- + +#### `deriv_auth` - `v6.7.0` + + - **FIX**(deriv_web_view): update deriv ui version in deriv auth ([#639](https://github.com/regentmarkets/flutter-deriv-packages/issues/639)). ([11b46a9f](https://github.com/regentmarkets/flutter-deriv-packages/commit/11b46a9f7bd00482d3cac7820cf4cd5d61da0cad)) + - **FEAT**(deriv_auth): add log in user tracking events. ([#620](https://github.com/regentmarkets/flutter-deriv-packages/issues/620)). ([ae9556cf](https://github.com/regentmarkets/flutter-deriv-packages/commit/ae9556cf3af98196bb22e351d9a8eccbf534889c)) + +#### `deriv_web_view` - `v0.2.2+2` + + - **FIX**(deriv_web_view): update deriv web view readme file ([#637](https://github.com/regentmarkets/flutter-deriv-packages/issues/637)). ([b0b66dad](https://github.com/regentmarkets/flutter-deriv-packages/commit/b0b66dadb6cb1b30dc3ad759f2eee031673b6bbf)) + - **FIX**(deriv_webview): add language parameter to needed classes ([#600](https://github.com/regentmarkets/flutter-deriv-packages/issues/600)). ([9b857999](https://github.com/regentmarkets/flutter-deriv-packages/commit/9b857999f479486830671f8b8e8b7fc26dcd769b)) + +#### `update_checker` - `v1.4.0` + + - **FEAT**(update_checker): add the ability to change the key from the app side ([#628](https://github.com/regentmarkets/flutter-deriv-packages/issues/628)). ([b18609a0](https://github.com/regentmarkets/flutter-deriv-packages/commit/b18609a00533aaab6d6962eb89f323e2f560df8b)) + + +## 2024-06-24 + +### Changes + +--- + +Packages with breaking changes: + + - There are no breaking changes in this release. + +Packages with other changes: + + - [`deriv_ui` - `v0.0.7+7`](#deriv_ui---v0077) + - [`deriv_auth` - `v6.6.9`](#deriv_auth---v669) + - [`deriv_passkeys` - `v0.0.2+1`](#deriv_passkeys---v0021) + - [`deriv_widgetbook` - `v0.0.2+7`](#deriv_widgetbook---v0027) + - [`deriv_language_selector` - `v0.0.2+5`](#deriv_language_selector---v0025) + +Packages with dependency updates only: + +> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project. + + - `deriv_auth` - `v6.6.9` + - `deriv_passkeys` - `v0.0.2+1` + - `deriv_widgetbook` - `v0.0.2+7` + - `deriv_language_selector` - `v0.0.2+5` + +--- + +#### `deriv_ui` - `v0.0.7+7` + + - **REFACTOR**(deriv_ui): [DERG-3500] return inputted amount based on the formatter in numpad ([#624](https://github.com/regentmarkets/flutter-deriv-packages/issues/624)). ([fdf4df19](https://github.com/regentmarkets/flutter-deriv-packages/commit/fdf4df1979ddb8710dba8925ef779cca25d60615)) + + ## 2024-06-21 ### Changes diff --git a/README.md b/README.md index 28ded8060..d9e7ee691 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This repository contains private packages & plugins that are used by the company ## Using the packages -Each package has been released as git tag with convention as **packageName-vVersionNumber**`(Example: deriv_auth-v6.6.7)`. To use the package, add the following to your pubspec.yaml file: +Each package has been released as git tag with convention as **packageName-vVersionNumber**`(Example: deriv_auth-v6.7.1)`. To use the package, add the following to your pubspec.yaml file: ```yaml @@ -12,7 +12,7 @@ deriv_ui: git: url: git@github.com:regentmarkets/flutter-deriv-packages.git path: packages/deriv_ui - ref: deriv_ui-v0.0.7+6 #your prefered version + ref: deriv_ui-v0.0.7+9 #your prefered version ``` ## Packages @@ -20,7 +20,7 @@ deriv_ui: | Name | Description | Version | | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | | [analytics](./packages/analytics) | Used to collect and send analytical information to 'Firebase' and 'Segment'. | [v2.0.0](./packages/analytics/CHANGELOG.md) | -| [deriv_auth](./packages/deriv_auth) | A Dart package that provides Authentication logic for Deriv applications. | [v6.6.7 ](./packages/deriv_auth/CHANGELOG.md) | +| [deriv_auth](./packages/deriv_auth) | A Dart package that provides Authentication logic for Deriv applications. | [v6.7.1 ](./packages/deriv_auth/CHANGELOG.md) | | [deriv_banner](./packages/deriv_banner) | A widget to show banner in apps. | [v0.0.1+1](./packages/deriv_banner/CHANGELOG.md) | | [deriv_bloc_manager](./packages/deriv_bloc_manager) | Provides some tools to manage blocs. | [v0.0.1](./packages/deriv_bloc_manager/CHANGELOG.md) | | [deriv_datadog](./packages/deriv_datadog) | A package that helps you monitor the performance and user interactions of your Flutter app by sending data to Datadog. | [v0.0.1](./packages/deriv_datadog/CHANGELOG.md) | @@ -31,20 +31,20 @@ deriv_ui: | [deriv_http_client](./packages/deriv_http_client) | A package that provides a wrapper for http package. | [v2.0.0](./packages/deriv_http_client/CHANGELOG.md) | | [deriv_lint](./packages/deriv_lint) | A Dart package that provides lint rules for Dart and Flutter. | [v1.0.0](./packages/deriv_lint/CHANGELOG.md) | | [deriv_live_chat](./packages/deriv_live_chat) | A plugin for live chat SDK support to dart. | [v0.0.1+2](./packages/deriv_live_chat/CHANGELOG.md) | -| [deriv_language_selector](./packages/deriv_language_selector) | A package to handle language change of the app. | [v0.0.2+4](./packages/deriv_language_selector/CHANGELOG.md) | +| [deriv_language_selector](./packages/deriv_language_selector) | A package to handle language change of the app. | [v0.0.2+7](./packages/deriv_language_selector/CHANGELOG.md) | | [deriv_localizations](./packages/deriv_localizations) | A Package that contains the localization arb(coming from Crowdin) and dart generated files for flutter_deriv_packages. | [v1.1.1](./packages/deriv_localizations/CHANGELOG.md) | | [v1.4.4](./packages/deriv_localizations/CHANGELOG.md) | | [deriv_numpad](./packages/deriv_numpad) | Number Pad Widget for number input. | [v1.1.5](./packages/deriv_numpad/CHANGELOG.md) | | [deriv_rudderstack](./packages/deriv_rudderstack) | A plugin that add RudderStack SDK support to Flutter. | [v1.1.0](./packages/deriv_rudderstack/CHANGELOG.md) | | [deriv_store_launcher](./packages/deriv_store_launcher) | A plugin to launch app stores base on platform and manufacturer. | [v0.0.1+1](./packages/deriv_store_launcher/CHANGELOG.md) | | [deriv_technical_analysis](./packages/deriv_technical_analysis) | A Dart package for Technical Analysis. | [v0.0.1](./packages/deriv_technical_analysis/CHANGELOG.md) | | [deriv_theme](./packages/deriv_theme) | A package that contains the theme used by Deriv products. | [v2.4.0](./packages/deriv_theme/CHANGELOG.md) | -| [deriv_ui](./packages/deriv_ui) | A package that contains the UI components used by Deriv products. | [v0.0.7+6](./packages/deriv_ui/CHANGELOG.md) | +| [deriv_ui](./packages/deriv_ui) | A package that contains the UI components used by Deriv products. | [v0.0.7+9](./packages/deriv_ui/CHANGELOG.md) | | [deriv_utilities](./packages/deriv_utilities) | A package that contains the utilities including helper functions, mixins, and extensions. | [v1.0.0](./packages/deriv_utilities/CHANGELOG.md) | | [deriv_websocket](./packages/deriv_web_socket_client) | A package that provides a easy to use websocket client. | [v1.0.1](./packages/deriv_web_socket_client/CHANGELOG.md) | -| [deriv_web_view](./packages/deriv_web_view) | Deriv web view package. | [v0.2.2+1](./packages/deriv_web_view/CHANGELOG.md) | -| [deriv_widgetbook](./packages/deriv_widgetbook) |Storybook for Deriv UI Widgets and Components | [v0.0.2+6](./packages/deriv_widgetbook/CHANGELOG.md) | +| [deriv_web_view](./packages/deriv_web_view) | Deriv web view package. | [v0.2.2+3](./packages/deriv_web_view/CHANGELOG.md) | +| [deriv_widgetbook](./packages/deriv_widgetbook) |Storybook for Deriv UI Widgets and Components | [v0.0.2+9](./packages/deriv_widgetbook/CHANGELOG.md) | | [form_builder](./packages/form_builder) | A simpler and cleaner way to create, validate and submit forms. | [v1.0.0+1](./packages/form_builder/CHANGELOG.md) | -| [update_checker](./packages/update_checker) | Check and retrieve update information from the server for the given package. | [v1.3.0](./packages/update_checker/CHANGELOG.md) | +| [update_checker](./packages/update_checker) | Check and retrieve update information from the server for the given package. | [v1.4.0](./packages/update_checker/CHANGELOG.md) | | [deriv_feature_flag](./packages/deriv_feature_flag) | A package to provide feature flag functionality for apps. | [v0.1.1](./packages/deriv_feature_flag/CHANGELOG.md) | ## Environment Setup diff --git a/packages/deriv_auth/CHANGELOG.md b/packages/deriv_auth/CHANGELOG.md index f6108faa2..9c4cc3686 100644 --- a/packages/deriv_auth/CHANGELOG.md +++ b/packages/deriv_auth/CHANGELOG.md @@ -1,3 +1,17 @@ +## 6.7.1 + + - **FIX**(deriv_auth): Fix login provider null issue ([#641](https://github.com/regentmarkets/flutter-deriv-packages/issues/641)). ([e4181541](https://github.com/regentmarkets/flutter-deriv-packages/commit/e41815416eb76b3724481f8a0b980e943311ebeb)) + - **FIX**(deriv_web_view): update deriv ui version in deriv auth ([#639](https://github.com/regentmarkets/flutter-deriv-packages/issues/639)). ([11b46a9f](https://github.com/regentmarkets/flutter-deriv-packages/commit/11b46a9f7bd00482d3cac7820cf4cd5d61da0cad)) + +## 6.7.0 + + - **FIX**(deriv_web_view): update deriv ui version in deriv auth ([#639](https://github.com/regentmarkets/flutter-deriv-packages/issues/639)). ([11b46a9f](https://github.com/regentmarkets/flutter-deriv-packages/commit/11b46a9f7bd00482d3cac7820cf4cd5d61da0cad)) + - **FEAT**(deriv_auth): add log in user tracking events. ([#620](https://github.com/regentmarkets/flutter-deriv-packages/issues/620)). ([ae9556cf](https://github.com/regentmarkets/flutter-deriv-packages/commit/ae9556cf3af98196bb22e351d9a8eccbf534889c)) + +## 6.6.9 + + - Update a dependency to the latest release. + ## 6.6.8 - Update a dependency to the latest release. diff --git a/packages/deriv_auth/example/pubspec.yaml b/packages/deriv_auth/example/pubspec.yaml index bd7100588..ce0a6b59c 100644 --- a/packages/deriv_auth/example/pubspec.yaml +++ b/packages/deriv_auth/example/pubspec.yaml @@ -18,18 +18,6 @@ dependencies: flutter_bloc: ^8.1.3 http: ^0.13.6 device_preview: ^1.1.0 - deriv_http_client: - git: - url: git@github.com:regentmarkets/flutter-deriv-packages.git - path: packages/deriv_http_client - ref: deriv_http_client-v2.0.1 - -dependency_overrides: - deriv_ui: - git: - url: git@github.com:regentmarkets/flutter-deriv-packages.git - path: packages/deriv_ui - ref: deriv_ui-v0.0.7+5 dev_dependencies: flutter_test: diff --git a/packages/deriv_auth/lib/core/analytics/data/auth_tracking_data.dart b/packages/deriv_auth/lib/core/analytics/data/auth_tracking_data.dart new file mode 100644 index 000000000..9ce8e5491 --- /dev/null +++ b/packages/deriv_auth/lib/core/analytics/data/auth_tracking_data.dart @@ -0,0 +1,164 @@ +import 'package:deriv_auth/core/analytics/enums.dart'; + +/// Get user tracking data. +Map getUserTrackingData( + LoginAction action, + String appId, { + LoginProvider? provider, + String? errorMessage, +}) => + switch (action) { + LoginAction.openLoginForm => { + 'event': 'open', + 'properties': { + 'app_id': appId, + }, + }, + LoginAction.startLogin => _getLoginStartedTrackingData( + provider, + appId, + ), + LoginAction.finishLogin => _getLoginFinishedTrackingData( + provider, + appId, + ), + LoginAction.loginError => _getLoginErrorTrackingData( + provider, + appId, + errorMessage ?? (throw Exception('Error message is required.')), + ), + }; + +/// Get login started tracking data. +Map _getLoginStartedTrackingData( + LoginProvider? provider, String appId) => + switch (provider) { + LoginProvider.email => { + 'event': 'login_started', + 'properties': { + 'app_id': appId, + 'login_provider': 'email', + }, + }, + LoginProvider.passkey => { + 'event': 'login_started', + 'properties': { + 'app_id': appId, + 'login_provider': 'passkey', + }, + }, + LoginProvider.google => { + 'event': 'login_started', + 'properties': { + 'app_id': appId, + 'login_provider': 'google', + }, + }, + LoginProvider.facebook => { + 'event': 'login_started', + 'properties': { + 'app_id': appId, + 'login_provider': 'facebook', + }, + }, + LoginProvider.apple => { + 'event': 'login_started', + 'properties': { + 'app_id': appId, + 'login_provider': 'apple', + }, + }, + null => throw Exception('Null LoginProvider is being passed.'), + }; + +/// Get login finished tracking data. +Map _getLoginFinishedTrackingData( + LoginProvider? provider, String appId) => + switch (provider) { + LoginProvider.email => { + 'event': 'login_finished', + 'properties': { + 'app_id': appId, + 'login_provider': 'email', + }, + }, + LoginProvider.passkey => { + 'event': 'login_finished', + 'properties': { + 'app_id': appId, + 'login_provider': 'passkey', + }, + }, + LoginProvider.google => { + 'event': 'login_finished', + 'properties': { + 'app_id': appId, + 'login_provider': 'google', + }, + }, + LoginProvider.facebook => { + 'event': 'login_finished', + 'properties': { + 'app_id': appId, + 'login_provider': 'facebook', + }, + }, + LoginProvider.apple => { + 'event': 'login_finished', + 'properties': { + 'app_id': appId, + 'login_provider': 'apple', + }, + }, + null => throw Exception('Null LoginProvider is being passed.'), + }; + +/// Get login error tracking data. +Map _getLoginErrorTrackingData( + LoginProvider? provider, + String appId, + String errorMessage, +) => + switch (provider) { + LoginProvider.email => { + 'event': 'login_flow_error', + 'properties': { + 'app_id': appId, + 'login_provider': 'email', + 'error_message': errorMessage, + }, + }, + LoginProvider.passkey => { + 'event': 'login_flow_error', + 'properties': { + 'app_id': appId, + 'login_provider': 'passkey', + 'error_message': errorMessage, + }, + }, + LoginProvider.google => { + 'event': 'login_flow_error', + 'properties': { + 'app_id': appId, + 'login_provider': 'google', + 'error_message': errorMessage, + }, + }, + LoginProvider.facebook => { + 'event': 'login_flow_error', + 'properties': { + 'app_id': appId, + 'login_provider': 'facebook', + 'error_message': errorMessage, + }, + }, + LoginProvider.apple => { + 'event': 'login_flow_error', + 'properties': { + 'app_id': appId, + 'login_provider': 'apple', + 'error_message': errorMessage, + }, + }, + null => throw Exception('Null LoginProvider is being passed.'), + }; diff --git a/packages/deriv_auth/lib/core/analytics/data/auth_tracking_repository.dart b/packages/deriv_auth/lib/core/analytics/data/auth_tracking_repository.dart new file mode 100644 index 000000000..6e898f633 --- /dev/null +++ b/packages/deriv_auth/lib/core/analytics/data/auth_tracking_repository.dart @@ -0,0 +1,132 @@ +import 'package:analytics/sdk/rudderstack/sdk/deriv_rudderstack_sdk.dart'; +import 'package:deriv_auth/core/services/token/models/enums.dart'; +import 'package:deriv_auth/core/analytics/data/auth_tracking_data.dart'; +import 'package:deriv_auth/core/analytics/domain/auth_user_tracking_interface.dart'; +import 'package:deriv_auth/core/analytics/enums.dart'; + +/// Repository to track user events. +class AuthTrackingRepository implements AuthUserTrackingInterface { + /// Constructor for [AnalyticsRepository]. + AuthTrackingRepository._( + this._appId, + this._derivRudderstack, + ); + + static AuthTrackingRepository? _instance; + + /// Singleton instance of [AnalyticsRepository]. + static AuthTrackingRepository get instance => _instance ??= + throw Exception('AuthTrackingRepository is not initialized'); + + /// Instance of [DerivRudderstack]. + final DerivRudderstack _derivRudderstack; + + /// Initialize [AnalyticsRepository]. + static void init( + String appId, { + required DerivRudderstack derivRudderstack, + }) => + _instance = AuthTrackingRepository._( + appId, + derivRudderstack, + ); + + /// Deriv client app ID. + final String _appId; + + LoginProvider? _loginProvider; + + @override + void trackUserOpenedLoginForm() { + final Map data = getUserTrackingData( + LoginAction.openLoginForm, + _appId, + ); + + _derivRudderstack.track( + eventName: data['event'] as String, + properties: data['properties'] as Map, + ); + } + + @override + void trackError(String errorMessage) { + final Map data = getUserTrackingData( + LoginAction.loginError, + _appId, + provider: _loginProvider, + errorMessage: errorMessage, + ); + + _derivRudderstack.track( + eventName: data['event'] as String, + properties: data['properties'] as Map, + ); + } + + @override + void trackSystemLoginPressed() { + final Map data = getUserTrackingData( + LoginAction.startLogin, + _appId, + provider: LoginProvider.email, + ); + + _loginProvider = LoginProvider.email; + + _derivRudderstack.track( + eventName: data['event'] as String, + properties: data['properties'] as Map, + ); + } + + @override + void trackPasskeyLoginPressed() { + final Map data = getUserTrackingData( + LoginAction.startLogin, + _appId, + provider: LoginProvider.passkey, + ); + + _loginProvider = LoginProvider.passkey; + + _derivRudderstack.track( + eventName: data['event'] as String, + properties: data['properties'] as Map, + ); + } + + @override + void trackSocialLoginPressed(SocialAuthProvider type) { + _loginProvider = switch (type) { + SocialAuthProvider.google => LoginProvider.google, + SocialAuthProvider.facebook => LoginProvider.facebook, + SocialAuthProvider.apple => LoginProvider.apple, + }; + + final Map data = getUserTrackingData( + LoginAction.startLogin, + _appId, + provider: _loginProvider, + ); + + _derivRudderstack.track( + eventName: data['event'] as String, + properties: data['properties'] as Map, + ); + } + + @override + void trackLoginFinished() { + final Map data = getUserTrackingData( + LoginAction.finishLogin, + _appId, + provider: _loginProvider, + ); + + _derivRudderstack.track( + eventName: data['event'] as String, + properties: data['properties'] as Map, + ); + } +} diff --git a/packages/deriv_auth/lib/core/analytics/domain/auth_user_tracking_interface.dart b/packages/deriv_auth/lib/core/analytics/domain/auth_user_tracking_interface.dart new file mode 100644 index 000000000..3db7ab4f6 --- /dev/null +++ b/packages/deriv_auth/lib/core/analytics/domain/auth_user_tracking_interface.dart @@ -0,0 +1,24 @@ +import 'package:deriv_auth/deriv_auth.dart'; + +/// Interface to define the methods for tracking user events. +abstract interface class AuthUserTrackingInterface { + /// Track user opened login form. + void trackUserOpenedLoginForm(); + + /// Track user clicks log after entering email and password. + void trackSystemLoginPressed(); + + /// Track user clicks on Passkey login button. + void trackPasskeyLoginPressed(); + + /// Track user clicks on social login button. + void trackSocialLoginPressed( + SocialAuthProvider type, + ); + + /// Track login finished. + void trackLoginFinished(); + + /// Track login error. + void trackError(String errorMessage); +} diff --git a/packages/deriv_auth/lib/core/analytics/enums.dart b/packages/deriv_auth/lib/core/analytics/enums.dart new file mode 100644 index 000000000..7d0d6c118 --- /dev/null +++ b/packages/deriv_auth/lib/core/analytics/enums.dart @@ -0,0 +1,32 @@ +/// Enum for login actions +enum LoginAction { + /// Open login form. + openLoginForm, + + /// Start system login. + startLogin, + + /// Finish login. + finishLogin, + + /// Login error. + loginError, +} + +/// Enum for login provider. +enum LoginProvider { + /// Email login. + email, + + /// Passkey login. + passkey, + + /// Google login. + google, + + /// Facebook login. + facebook, + + /// Apple login. + apple, +} diff --git a/packages/deriv_auth/lib/core/analytics/service/auth_tracking_mixin.dart b/packages/deriv_auth/lib/core/analytics/service/auth_tracking_mixin.dart new file mode 100644 index 000000000..5c5c931de --- /dev/null +++ b/packages/deriv_auth/lib/core/analytics/service/auth_tracking_mixin.dart @@ -0,0 +1,36 @@ +import 'package:deriv_auth/deriv_auth.dart'; +import 'package:deriv_auth/core/analytics/data/auth_tracking_repository.dart'; + +/// Mixin for tracking user authentication actions. +mixin AuthTrackingMixin { + late final AuthTrackingRepository _repository = + AuthTrackingRepository.instance; + + /// Track user opened login form. + void trackUserOpenedLoginForm() => _repository.trackUserOpenedLoginForm(); + + /// Track login error. + void trackError(String errorMessage) => _repository.trackError(errorMessage); + + /// Track login started. + void trackLoginWithEmailAndPassword() => + _repository.trackSystemLoginPressed(); + + /// Track Passkey login started. + void trackLoginWithPasskey() => _repository.trackPasskeyLoginPressed(); + + /// Track Google login started. + void trackLoginWithGoogle() => + _repository.trackSocialLoginPressed(SocialAuthProvider.google); + + /// Track Facebook login started. + void trackLoginWithFacebook() => + _repository.trackSocialLoginPressed(SocialAuthProvider.facebook); + + /// Track Apple login started. + void trackLoginWithApple() => + _repository.trackSocialLoginPressed(SocialAuthProvider.apple); + + /// Track login finished. + void trackLoginFinished() => _repository.trackLoginFinished(); +} diff --git a/packages/deriv_auth/lib/features/auth/cubit/deriv_auth_cubit.dart b/packages/deriv_auth/lib/features/auth/cubit/deriv_auth_cubit.dart index 8d83d5a56..53eb7fb2a 100644 --- a/packages/deriv_auth/lib/features/auth/cubit/deriv_auth_cubit.dart +++ b/packages/deriv_auth/lib/features/auth/cubit/deriv_auth_cubit.dart @@ -1,4 +1,7 @@ +import 'package:analytics/sdk/rudderstack/sdk/deriv_rudderstack_sdk.dart'; import 'package:bloc/bloc.dart'; +import 'package:deriv_auth/core/analytics/data/auth_tracking_repository.dart'; +import 'package:deriv_auth/core/analytics/service/auth_tracking_mixin.dart'; import 'package:deriv_auth/core/exceptions/deriv_auth_exception.dart'; import 'package:deriv_auth/core/models/account_model.dart'; @@ -9,17 +12,27 @@ import 'package:deriv_auth/core/services/token/models/enums.dart'; import 'package:deriv_auth/core/services/token/models/login_request.dart'; import 'package:deriv_auth/features/auth/deriv_auth_io.dart'; import 'package:deriv_auth/features/auth/services/base_auth_service.dart'; +import 'package:deriv_auth/features/auth/services/deriv_auth_service.dart'; import 'package:deriv_auth/features/social_auth/models/social_auth_dto.dart'; part 'deriv_auth_state.dart'; /// This Cubit is the single source of truth for user login status, /// and it is responsible for all login functionality. -class DerivAuthCubit extends Cubit implements DerivAuthIO { +class DerivAuthCubit extends Cubit + with AuthTrackingMixin + implements DerivAuthIO { /// Initialize a [DerivAuthCubit]. DerivAuthCubit({ required this.authService, - }) : super(DerivAuthLoadingState()); + }) : super(DerivAuthLoadingState()) { + AuthTrackingRepository.init( + authService is DerivAuthService + ? (authService as DerivAuthService).connectionInfo.appId + : (throw Exception('Connection Info is not provided.')), + derivRudderstack: DerivRudderstack(), + ); + } /// [BaseAuthService] handles all login logic of cubit. final BaseAuthService authService; @@ -33,6 +46,8 @@ class DerivAuthCubit extends Cubit implements DerivAuthIO { String? otp, String? userAgent, }) async { + trackLoginWithEmailAndPassword(); + emit(DerivAuthLoadingState()); await _loginRequest( @@ -110,6 +125,9 @@ class DerivAuthCubit extends Cubit implements DerivAuthIO { final LandingCompanyEntity landingCompanyEntity = await authService.getLandingCompany(authorizeEntity.country); _isUserMigrated = _checkUserMigrated(authorizeEntity); + + trackLoginFinished(); + emit(DerivAuthLoggedInState( DerivAuthModel( authorizeEntity: authorizeEntity, @@ -136,6 +154,8 @@ class DerivAuthCubit extends Cubit implements DerivAuthIO { await authService.getLandingCompany(authorizeEntity.country); _isUserMigrated = _checkUserMigrated(authorizeEntity); + trackLoginFinished(); + emit( DerivAuthLoggedInState( DerivAuthModel( @@ -204,4 +224,15 @@ class DerivAuthCubit extends Cubit implements DerivAuthIO { @override Stream get output => stream; + + @override + void onChange(Change change) { + if (change.nextState is DerivAuthErrorState) { + trackError( + (change.nextState as DerivAuthErrorState).message, + ); + } + + super.onChange(change); + } } diff --git a/packages/deriv_auth/lib/features/auth/services/base_auth_service.dart b/packages/deriv_auth/lib/features/auth/services/base_auth_service.dart index f3df80e13..184acc869 100644 --- a/packages/deriv_auth/lib/features/auth/services/base_auth_service.dart +++ b/packages/deriv_auth/lib/features/auth/services/base_auth_service.dart @@ -5,6 +5,9 @@ import 'package:deriv_auth/core/services/token/models/login_request.dart'; /// Interface to define all authentication-related functionality. abstract class BaseAuthService { + /// Constructor for [BaseAuthService]. + BaseAuthService(); + /// Function before logging user in. Future onLoginRequest({ required GetTokensRequestModel request, diff --git a/packages/deriv_auth/lib/features/auth/services/deriv_auth_service.dart b/packages/deriv_auth/lib/features/auth/services/deriv_auth_service.dart index 573bb7567..1a0d6c697 100644 --- a/packages/deriv_auth/lib/features/auth/services/deriv_auth_service.dart +++ b/packages/deriv_auth/lib/features/auth/services/deriv_auth_service.dart @@ -1,6 +1,6 @@ import 'package:collection/collection.dart'; - import 'package:deriv_auth/core/connection_info.dart'; + import 'package:deriv_auth/core/constants/constants.dart'; import 'package:deriv_auth/core/exceptions/deriv_auth_exception.dart'; import 'package:deriv_auth/core/extensions/extensions.dart'; diff --git a/packages/deriv_auth/lib/features/get_started/presentation/layouts/deriv_get_started_layout.dart b/packages/deriv_auth/lib/features/get_started/presentation/layouts/deriv_get_started_layout.dart index 07cdabe9e..f9ec33a6d 100644 --- a/packages/deriv_auth/lib/features/get_started/presentation/layouts/deriv_get_started_layout.dart +++ b/packages/deriv_auth/lib/features/get_started/presentation/layouts/deriv_get_started_layout.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'dart:math' as math; +import 'package:deriv_auth/core/analytics/service/auth_tracking_mixin.dart'; import 'package:deriv_auth/core/extensions/context_extension.dart'; import 'package:deriv_auth/core/helpers/semantic_labels.dart'; import 'package:deriv_auth/features/get_started/models/deriv_get_started_slide_model.dart'; @@ -48,7 +49,8 @@ class DerivGetStartedLayout extends StatefulWidget { State createState() => _DerivGetStartedLayoutState(); } -class _DerivGetStartedLayoutState extends State { +class _DerivGetStartedLayoutState extends State + with AuthTrackingMixin { static const Duration _autoScrollInterval = Duration(seconds: 4); static const Duration _scrollAnimationDuration = Duration(seconds: 1); static const Alignment _slideImageAlignment = Alignment.center; @@ -172,7 +174,10 @@ class _DerivGetStartedLayoutState extends State { explicitChildNodes: true, label: SemanticsLabels.starterPageLoginButtonSemantic, child: SecondaryButton( - onPressed: widget.onLoginTapped, + onPressed: () { + trackUserOpenedLoginForm(); + widget.onLoginTapped(); + }, child: Center( child: Text( context.derivAuthLocalization.actionLogin, diff --git a/packages/deriv_auth/lib/features/login/presentation/layouts/deriv_login_layout.dart b/packages/deriv_auth/lib/features/login/presentation/layouts/deriv_login_layout.dart index 9bf31f9a6..4c14f4800 100644 --- a/packages/deriv_auth/lib/features/login/presentation/layouts/deriv_login_layout.dart +++ b/packages/deriv_auth/lib/features/login/presentation/layouts/deriv_login_layout.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:deriv_auth/core/analytics/service/auth_tracking_mixin.dart'; import 'package:deriv_auth/deriv_auth.dart'; import 'package:deriv_passkeys/deriv_passkeys.dart'; import 'package:deriv_theme/deriv_theme.dart'; @@ -100,7 +101,8 @@ class DerivLoginLayout extends StatefulWidget { State createState() => _DerivLoginLayoutState(); } -class _DerivLoginLayoutState extends State { +class _DerivLoginLayoutState extends State + with AuthTrackingMixin { final GlobalKey _formKey = GlobalKey(); final TextEditingController _emailController = TextEditingController(); @@ -131,7 +133,6 @@ class _DerivLoginLayoutState extends State { centerTitle: false, ), body: BlocConsumer( - bloc: authCubit, listener: _onAuthState, builder: (BuildContext context, DerivAuthState state) => Form( key: _formKey, @@ -162,7 +163,9 @@ class _DerivLoginLayoutState extends State { if (widget.isSocialAuthEnabled) const SizedBox(height: ThemeProvider.margin24), widget.isPasskeysEnabled - ? const ContinueWithPasskeyButton() + ? ContinueWithPasskeyButton( + onTap: trackLoginWithPasskey, + ) : const SizedBox.shrink(), DerivSocialAuthPanel( socialAuthStateHandler: widget.socialAuthStateHandler, diff --git a/packages/deriv_auth/lib/features/social_auth/presentation/widgets/deriv_social_auth_panel.dart b/packages/deriv_auth/lib/features/social_auth/presentation/widgets/deriv_social_auth_panel.dart index ea2241f4e..b8f4f32b6 100644 --- a/packages/deriv_auth/lib/features/social_auth/presentation/widgets/deriv_social_auth_panel.dart +++ b/packages/deriv_auth/lib/features/social_auth/presentation/widgets/deriv_social_auth_panel.dart @@ -1,3 +1,4 @@ +import 'package:deriv_auth/core/analytics/service/auth_tracking_mixin.dart'; import 'package:deriv_auth/deriv_auth.dart'; import 'package:deriv_theme/deriv_theme.dart'; import 'package:flutter/material.dart'; @@ -48,7 +49,8 @@ class DerivSocialAuthPanel extends StatefulWidget { State createState() => _DerivSocialAuthPanelState(); } -class _DerivSocialAuthPanelState extends State { +class _DerivSocialAuthPanelState extends State + with AuthTrackingMixin { late SocialAuthCubit _socialAuthCubit; @override @@ -121,6 +123,19 @@ class _DerivSocialAuthPanelState extends State { ), onTap: widget.isEnabled ? () async { + switch (socialAuthProvider) { + case SocialAuthProvider.google: + trackLoginWithGoogle(); + break; + case SocialAuthProvider.facebook: + trackLoginWithFacebook(); + break; + case SocialAuthProvider.apple: + trackLoginWithApple(); + break; + default: + break; + } final List? socialAuthProviders = await _socialAuthCubit.getSocialAuthProviders(); diff --git a/packages/deriv_auth/pubspec.yaml b/packages/deriv_auth/pubspec.yaml index 7d058b6b5..a63fa69f9 100644 --- a/packages/deriv_auth/pubspec.yaml +++ b/packages/deriv_auth/pubspec.yaml @@ -1,6 +1,6 @@ name: deriv_auth description: Provides deriv authentication functionalities for dart/flutter apps. -version: 6.6.8 +version: 6.7.1 environment: sdk: ">=3.0.0 <4.0.0" @@ -12,6 +12,12 @@ dependencies: flutter: sdk: flutter + analytics: + git: + url: git@github.com:regentmarkets/flutter-deriv-packages.git + path: packages/analytics + ref: analytics-v2.0.0 + deriv_theme: git: url: git@github.com:regentmarkets/flutter-deriv-packages.git @@ -22,7 +28,7 @@ dependencies: git: url: git@github.com:regentmarkets/flutter-deriv-packages.git path: packages/deriv_ui - ref: deriv_ui-v0.0.7+6 + ref: deriv_ui-v0.0.7+9 deriv_http_client: git: @@ -39,7 +45,7 @@ dependencies: git: url: git@github.com:regentmarkets/flutter-deriv-packages.git path: packages/deriv_web_view - ref: deriv_web_view-v0.2.2+1 + ref: deriv_web_view-v0.2.2+3 deriv_localizations: git: @@ -51,13 +57,13 @@ dependencies: git: url: git@github.com:regentmarkets/flutter-deriv-packages.git path: packages/deriv_passkeys - ref: deriv_passkeys-v0.0.2 + ref: deriv_passkeys-v0.0.2+3 deriv_language_selector: git: url: git@github.com:regentmarkets/flutter-deriv-packages.git path: packages/deriv_language_selector - ref: deriv_language_selector-v0.0.2+4 + ref: deriv_language_selector-v0.0.2+7 flutter_bloc: ^8.1.3 flutter_svg: ^2.0.7 @@ -73,7 +79,7 @@ dependency_overrides: git: url: git@github.com:regentmarkets/flutter-deriv-packages.git path: packages/deriv_ui - ref: deriv_ui-v0.0.7+6 + ref: deriv_ui-v0.0.7+9 dev_dependencies: mocktail: ^1.0.3 diff --git a/packages/deriv_auth/test/features/auth/cubit/deriv_auth_cubit_test.dart b/packages/deriv_auth/test/features/auth/cubit/deriv_auth_cubit_test.dart index 73829497f..cffb70907 100644 --- a/packages/deriv_auth/test/features/auth/cubit/deriv_auth_cubit_test.dart +++ b/packages/deriv_auth/test/features/auth/cubit/deriv_auth_cubit_test.dart @@ -1,4 +1,6 @@ +import 'package:analytics/sdk/rudderstack/sdk/deriv_rudderstack_sdk.dart'; import 'package:bloc_test/bloc_test.dart'; +import 'package:deriv_auth/core/analytics/data/auth_tracking_repository.dart'; import 'package:deriv_auth/core/exceptions/deriv_auth_exception.dart'; import 'package:deriv_auth/core/models/account_model.dart'; import 'package:deriv_auth/core/models/auth_error/auth_error.dart'; @@ -16,11 +18,28 @@ import '../mocked_data/mocked_auth_models.dart'; class MockAuthService extends Mock implements BaseAuthService {} +class MockDerivRudderStack extends Mock implements DerivRudderstack {} + void main() { + late final MockDerivRudderStack mockDerivRudderstack; + late final DerivAuthCubit authCubit; late final MockAuthService service; setUpAll(() async { + mockDerivRudderstack = MockDerivRudderStack(); + + AuthTrackingRepository.init( + 'test', + derivRudderstack: mockDerivRudderstack, + ); + + when(() => mockDerivRudderstack.track( + eventName: any(named: 'eventName'), + properties: any(named: 'properties'))).thenAnswer( + (_) => Future.value(true), + ); + service = MockAuthService(); authCubit = DerivAuthCubit(authService: service); }); diff --git a/packages/deriv_auth/test/features/get_started/presentation/layouts/deriv_get_started_layout_test.dart b/packages/deriv_auth/test/features/get_started/presentation/layouts/deriv_get_started_layout_test.dart index 23aa26b08..3e9271705 100644 --- a/packages/deriv_auth/test/features/get_started/presentation/layouts/deriv_get_started_layout_test.dart +++ b/packages/deriv_auth/test/features/get_started/presentation/layouts/deriv_get_started_layout_test.dart @@ -1,6 +1,8 @@ // ignore_for_file: always_specify_types +import 'package:analytics/sdk/rudderstack/sdk/deriv_rudderstack_sdk.dart'; import 'package:bloc_test/bloc_test.dart'; +import 'package:deriv_auth/core/analytics/data/auth_tracking_repository.dart'; import 'package:deriv_auth/features/get_started/models/deriv_get_started_slide_model.dart'; import 'package:deriv_auth/features/get_started/presentation/layouts/deriv_get_started_layout.dart'; import 'package:deriv_language_selector/deriv_language_selector.dart'; @@ -14,6 +16,8 @@ import 'package:patrol_finders/patrol_finders.dart'; import '../../../../pump_app.dart'; +class MockDerivRudderStack extends Mock implements DerivRudderstack {} + class MockDerivGetStartedSlideModel extends Mock implements DerivGetStartedSlideModel {} @@ -22,6 +26,8 @@ class MockLanguageCubit extends MockCubit void main() { group('DerivGetStartedLayout', () { + late final MockDerivRudderStack mockDerivRudderstack; + late MockDerivGetStartedSlideModel mockSlideModel; const String appLogoIconPath = 'assets/icons/ic_logo_extended.svg'; @@ -31,6 +37,23 @@ void main() { setUpAll(() { mockSlideModel = MockDerivGetStartedSlideModel(); + + mockDerivRudderstack = MockDerivRudderStack(); + + AuthTrackingRepository.init( + 'test', + derivRudderstack: mockDerivRudderstack, + ); + + when(() => mockDerivRudderstack.track( + eventName: any(named: 'eventName'), + properties: any(named: 'properties'))).thenAnswer( + (_) => Future.value(true), + ); + + when(() => mockSlideModel.imagePath) + .thenReturn('assets/images/charts.svg'); + when(() => mockSlideModel.supportingText).thenReturn('Supporting text'); when(() => mockSlideModel.imagePath) .thenReturn('assets/images/charts.svg'); when(() => mockSlideModel.supportingText).thenReturn('Supporting text'); diff --git a/packages/deriv_auth/test/features/login/presentation/layouts/deriv_login_layout_test.dart b/packages/deriv_auth/test/features/login/presentation/layouts/deriv_login_layout_test.dart index 9d8ddba69..d1bedacdb 100644 --- a/packages/deriv_auth/test/features/login/presentation/layouts/deriv_login_layout_test.dart +++ b/packages/deriv_auth/test/features/login/presentation/layouts/deriv_login_layout_test.dart @@ -1,4 +1,6 @@ +import 'package:analytics/sdk/rudderstack/sdk/deriv_rudderstack_sdk.dart'; import 'package:bloc_test/bloc_test.dart'; +import 'package:deriv_auth/core/analytics/data/auth_tracking_repository.dart'; import 'package:deriv_auth/core/models/landig_comany_model.dart'; import 'package:deriv_auth/deriv_auth.dart'; import 'package:deriv_passkeys/deriv_passkeys.dart'; @@ -18,8 +20,11 @@ class MockDerivPasskeysBloc extends MockBloc implements DerivPasskeysBloc {} +class MockDerivRudderStackService extends Mock implements DerivRudderstack {} + void main() { group('DerivLoginLayout', () { + late MockDerivRudderStackService mockDerivRudderstack; late MockAuthCubit authCubit; late MockSocialAuthCubit socialAuthCubit; late MockDerivPasskeysBloc derivPasskeysBloc; @@ -27,10 +32,23 @@ void main() { const String welcomeLabel = 'Welcome Back'; setUpAll(() { + mockDerivRudderstack = MockDerivRudderStackService(); authCubit = MockAuthCubit(); socialAuthCubit = MockSocialAuthCubit(); derivPasskeysBloc = MockDerivPasskeysBloc(); + AuthTrackingRepository.init( + 'test', + derivRudderstack: mockDerivRudderstack, + ); + + when(() => mockDerivRudderstack.track( + eventName: any(named: 'eventName'), + properties: any(named: 'properties'), + )).thenAnswer( + (_) => Future.value(true), + ); + when(() => derivPasskeysBloc.state).thenReturn( DerivPasskeysInitializedState(), ); diff --git a/packages/deriv_auth/test/features/signup/presentation/layouts/deriv_signup_layout_test.dart b/packages/deriv_auth/test/features/signup/presentation/layouts/deriv_signup_layout_test.dart index e48555b03..bcd5aec8a 100644 --- a/packages/deriv_auth/test/features/signup/presentation/layouts/deriv_signup_layout_test.dart +++ b/packages/deriv_auth/test/features/signup/presentation/layouts/deriv_signup_layout_test.dart @@ -1,3 +1,5 @@ +import 'package:analytics/sdk/rudderstack/sdk/deriv_rudderstack_sdk.dart'; +import 'package:deriv_auth/core/analytics/data/auth_tracking_repository.dart'; import 'package:deriv_auth/deriv_auth.dart'; import 'package:deriv_ui/deriv_ui.dart'; import 'package:flutter/material.dart'; @@ -11,8 +13,11 @@ import '../../../../mocks.dart'; import '../../../../pump_app.dart'; import '../../../social_auth/mocks/mock_social_provider_model.dart'; +class MockDerivRudderStack extends Mock implements DerivRudderstack {} + void main() { group('DerivSignupLayout', () { + late final MockDerivRudderStack mockDerivRudderstack; late MockSignupCubit signupCubit; late MockAuthCubit authCubit; late MockSocialAuthCubit socialAuthCubit; @@ -25,6 +30,19 @@ void main() { authCubit = MockAuthCubit(); socialAuthCubit = MockSocialAuthCubit(); + mockDerivRudderstack = MockDerivRudderStack(); + + AuthTrackingRepository.init( + 'test', + derivRudderstack: mockDerivRudderstack, + ); + + when(() => mockDerivRudderstack.track( + eventName: any(named: 'eventName'), + properties: any(named: 'properties'))).thenAnswer( + (_) => Future.value(true), + ); + registerFallbackValue(SocialAuthProvider.google); when(() => signupCubit.state) diff --git a/packages/deriv_language_selector/CHANGELOG.md b/packages/deriv_language_selector/CHANGELOG.md index 4eb2f1faf..042e415f2 100644 --- a/packages/deriv_language_selector/CHANGELOG.md +++ b/packages/deriv_language_selector/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.0.2+7 + + - Update a dependency to the latest release. + +## 0.0.2+6 + + - Update a dependency to the latest release. + +## 0.0.2+5 + + - Update a dependency to the latest release. + ## 0.0.2+4 - Update a dependency to the latest release. diff --git a/packages/deriv_language_selector/pubspec.yaml b/packages/deriv_language_selector/pubspec.yaml index 3b0c952eb..65dbe3b48 100644 --- a/packages/deriv_language_selector/pubspec.yaml +++ b/packages/deriv_language_selector/pubspec.yaml @@ -1,6 +1,6 @@ name: deriv_language_selector description: A package to select language for the app. It provides both UI and logic for language selection. -version: 0.0.2+4 +version: 0.0.2+7 publish_to: "none" environment: @@ -14,7 +14,7 @@ dependencies: git: url: git@github.com:regentmarkets/flutter-deriv-packages.git path: packages/deriv_ui - ref: deriv_ui-v0.0.7+6 + ref: deriv_ui-v0.0.7+9 shared_preferences: ^2.2.2 flutter_bloc: ^8.1.4 equatable: ^2.0.5 diff --git a/packages/deriv_passkeys/CHANGELOG.md b/packages/deriv_passkeys/CHANGELOG.md index 4a8a4e3b9..45d557892 100644 --- a/packages/deriv_passkeys/CHANGELOG.md +++ b/packages/deriv_passkeys/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.0.2+3 + + - Update a dependency to the latest release. + +## 0.0.2+2 + + - Update a dependency to the latest release. + +## 0.0.2+1 + + - Update a dependency to the latest release. + ## 0.0.2 - **REFACTOR**(deriv_passkeys): Removed deprecated linter rules ([#625](https://github.com/regentmarkets/flutter-deriv-packages/issues/625)). ([2fdc28f2](https://github.com/regentmarkets/flutter-deriv-packages/commit/2fdc28f20b8efe2ddc3a9a261c40b533307f25e3)) diff --git a/packages/deriv_passkeys/lib/src/presentation/widgets/passkey_created_call_to_action.dart b/packages/deriv_passkeys/lib/src/presentation/widgets/passkey_created_call_to_action.dart index 2555e0bf1..919aaaaa5 100644 --- a/packages/deriv_passkeys/lib/src/presentation/widgets/passkey_created_call_to_action.dart +++ b/packages/deriv_passkeys/lib/src/presentation/widgets/passkey_created_call_to_action.dart @@ -21,28 +21,25 @@ class PasskeysCreatedCallToAction extends StatelessWidget { @override Widget build(BuildContext context) => Padding( padding: const EdgeInsets.all(16), - child: Row( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Expanded( - child: SecondaryButton( - onPressed: () => addMorePasskeysNavigationCallback(context), - child: Text( - context.derivPasskeysLocalizations.addMorePasskeysButtonText, - style: TextStyle( - color: context.theme.colors.prominent, - ), + SecondaryButton( + onPressed: () => addMorePasskeysNavigationCallback(context), + child: Text( + context.derivPasskeysLocalizations.addMorePasskeysButtonText, + style: TextStyle( + color: context.theme.colors.prominent, ), ), ), const SizedBox(width: 16), - Expanded( - child: PrimaryButton( - onPressed: () => continueTradingNavigationCallback(context), - child: Text( - context.derivPasskeysLocalizations.continueTradingButtonText, - style: TextStyle( - color: context.theme.colors.prominent, - ), + PrimaryButton( + onPressed: () => continueTradingNavigationCallback(context), + child: Text( + context.derivPasskeysLocalizations.continueTradingButtonText, + style: TextStyle( + color: context.theme.colors.prominent, ), ), ), diff --git a/packages/deriv_passkeys/pubspec.yaml b/packages/deriv_passkeys/pubspec.yaml index f51b9c42d..d97350d14 100644 --- a/packages/deriv_passkeys/pubspec.yaml +++ b/packages/deriv_passkeys/pubspec.yaml @@ -1,6 +1,6 @@ name: deriv_passkeys description: Deriv Passkeys Flutter Plugin -version: 0.0.2 +version: 0.0.2+3 publish_to: "none" environment: @@ -32,7 +32,7 @@ dependencies: git: url: git@github.com:regentmarkets/flutter-deriv-packages.git path: packages/deriv_ui - ref: deriv_ui-v0.0.7+6 + ref: deriv_ui-v0.0.7+9 deriv_http_client: git: diff --git a/packages/deriv_ui/CHANGELOG.md b/packages/deriv_ui/CHANGELOG.md index 1441b306e..84203b2c2 100644 --- a/packages/deriv_ui/CHANGELOG.md +++ b/packages/deriv_ui/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.0.7+9 + + - Update a dependency to the latest release. + +## 0.0.7+8 + + - Update a dependency to the latest release. + +## 0.0.7+7 + + - **REFACTOR**(deriv_ui): [DERG-3500] return inputted amount based on the formatter in numpad ([#624](https://github.com/regentmarkets/flutter-deriv-packages/issues/624)). ([fdf4df19](https://github.com/regentmarkets/flutter-deriv-packages/commit/fdf4df1979ddb8710dba8925ef779cca25d60615)) + ## 0.0.7+6 - **REFACTOR**: update dependencies. ([af89e148](https://github.com/regentmarkets/flutter-deriv-packages/commit/af89e148dfecb6dbc8552b2b883cbad4102a56f8)) diff --git a/packages/deriv_ui/lib/components/numpad/core/exchange_notifier.dart b/packages/deriv_ui/lib/components/numpad/core/exchange_notifier.dart index e823e458b..29decb525 100644 --- a/packages/deriv_ui/lib/components/numpad/core/exchange_notifier.dart +++ b/packages/deriv_ui/lib/components/numpad/core/exchange_notifier.dart @@ -118,9 +118,9 @@ class ExchangeController extends ChangeNotifier { /// what user send by default in primaryCurrency when coming to numpad.) double finalAmount() { if (_exchangeRate.baseCurrency == primaryCurrency.currencyType) { - return primaryCurrency.amount; + return primaryCurrency.formattedAmount; } else { - return secondaryCurrency.amount; + return secondaryCurrency.formattedAmount; } } } diff --git a/packages/deriv_ui/lib/components/numpad/models/currency_detail.dart b/packages/deriv_ui/lib/components/numpad/models/currency_detail.dart index 1cb784034..15f388a0d 100644 --- a/packages/deriv_ui/lib/components/numpad/models/currency_detail.dart +++ b/packages/deriv_ui/lib/components/numpad/models/currency_detail.dart @@ -20,7 +20,7 @@ class CurrencyDetail { ]; /// Available stable coin currency that Deriv supports. - static List stableCurrencies = [ + static List stableCryptoCurrencies = [ 'USDC', 'USDT', 'TUSDT', @@ -37,8 +37,11 @@ class CurrencyDetail { bool get isFiat => fiatCurrencies.contains(currencyType); /// This will check if the currency is stable coin currency(USDC,tUSDT,eUSDT) or not. - bool get isStableCurrency => - stableCurrencies.contains(currencyType.toUpperCase()); + bool get isStableCryptoCurrency => + stableCryptoCurrencies.contains(currencyType.toUpperCase()); + + /// This will give the formatted amount to do processing based on type of currency it is like fiat or crypto currency. + double get formattedAmount => double.parse(formatter.format(amount)); /// Amount that is used to display for user. String get displayAmount { @@ -46,17 +49,17 @@ class CurrencyDetail { return ''; } - return isFiat || isStableCurrency + return isFiat || isStableCryptoCurrency ? amount.toStringAsFixed(2) : amount.toStringAsFixed(8); } /// This will give a specific currency formatter based on what type of currency it is like fiat or crypto currency. NumberFormat get formatter { - if (isFiat || isStableCurrency) { - return NumberFormat.decimalPattern()..maximumFractionDigits = 2; + if (isFiat || isStableCryptoCurrency) { + return NumberFormat('#0.##', 'en_US'); } else { - return NumberFormat.decimalPattern()..maximumFractionDigits = 8; + return NumberFormat('#0.########', 'en_US'); } } diff --git a/packages/deriv_ui/lib/components/numpad/widgets/number_pad.dart b/packages/deriv_ui/lib/components/numpad/widgets/number_pad.dart index 5bbd15020..24472b652 100644 --- a/packages/deriv_ui/lib/components/numpad/widgets/number_pad.dart +++ b/packages/deriv_ui/lib/components/numpad/widgets/number_pad.dart @@ -661,7 +661,7 @@ class _NumpadWithExchange extends NumberPad { NumberPadCloseCallback? onClose, }) : super( numberPadType: NumberPadWidgetType.singleInput, - formatter: NumberFormat.decimalPattern()..maximumFractionDigits = 8, + formatter: primaryCurrency.formatter, label: label, firstInputTitle: title, onClose: onClose, diff --git a/packages/deriv_ui/pubspec.yaml b/packages/deriv_ui/pubspec.yaml index f32c6ff6e..08fa0368b 100644 --- a/packages/deriv_ui/pubspec.yaml +++ b/packages/deriv_ui/pubspec.yaml @@ -1,6 +1,6 @@ name: deriv_ui description: A new Flutter package project. -version: 0.0.7+6 +version: 0.0.7+9 publish_to: none environment: @@ -23,7 +23,7 @@ dependencies: git: url: git@github.com:regentmarkets/flutter-deriv-packages.git path: packages/deriv_web_view - ref: deriv_web_view-v0.2.2+1 + ref: deriv_web_view-v0.2.2+3 flutter_svg: ^2.0.7 intl: ^0.18.0 diff --git a/packages/deriv_web_view/CHANGELOG.md b/packages/deriv_web_view/CHANGELOG.md index c90de8c2a..caf42b7ba 100644 --- a/packages/deriv_web_view/CHANGELOG.md +++ b/packages/deriv_web_view/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.2.2+3 + + - **FIX**(deriv_web_view): update deriv web view readme file ([#637](https://github.com/regentmarkets/flutter-deriv-packages/issues/637)). ([b0b66dad](https://github.com/regentmarkets/flutter-deriv-packages/commit/b0b66dadb6cb1b30dc3ad759f2eee031673b6bbf)) + +## 0.2.2+2 + + - **FIX**(deriv_web_view): update deriv web view readme file ([#637](https://github.com/regentmarkets/flutter-deriv-packages/issues/637)). ([b0b66dad](https://github.com/regentmarkets/flutter-deriv-packages/commit/b0b66dadb6cb1b30dc3ad759f2eee031673b6bbf)) + - **FIX**(deriv_webview): add language parameter to needed classes ([#600](https://github.com/regentmarkets/flutter-deriv-packages/issues/600)). ([9b857999](https://github.com/regentmarkets/flutter-deriv-packages/commit/9b857999f479486830671f8b8e8b7fc26dcd769b)) + ## 0.2.2+1 - **FIX**(deriv_web_view): update PTA model ([#557](https://github.com/regentmarkets/flutter-deriv-packages/issues/557)). ([49583f82](https://github.com/regentmarkets/flutter-deriv-packages/commit/49583f823fdac9c3ec3a85529fad9ab9f6784c67)) diff --git a/packages/deriv_web_view/lib/deriv_web_view.dart b/packages/deriv_web_view/lib/deriv_web_view.dart index 8580ac4e7..e8777a60a 100644 --- a/packages/deriv_web_view/lib/deriv_web_view.dart +++ b/packages/deriv_web_view/lib/deriv_web_view.dart @@ -154,6 +154,7 @@ Future openLoggedInWebPage({ required String appToken, required String userAgent, required String platform, + String? languageCode, HttpClientPredicate? getHttpClient, String destinationAppId = '16929', String? action, @@ -179,6 +180,7 @@ Future openLoggedInWebPage({ action: action, code: code, platform: platform, + languageCode: languageCode ); if (oneTimeToken == null) { @@ -219,6 +221,7 @@ Future openLoggedInWebPage({ action: action, code: code, platform: platform, + languageCode: languageCode, ); } @@ -252,6 +255,7 @@ Future _fetchOneTimeToken({ HttpClientPredicate? getHttpClient, String? action, String? code, + String? languageCode, }) async { loadingDialog(context); @@ -267,6 +271,7 @@ Future _fetchOneTimeToken({ code: code, getHttpClient: getHttpClient, platform: platform, + languageCode: languageCode, ); Navigator.of(context, rootNavigator: rootNavigator).pop(); @@ -287,6 +292,7 @@ Future _getOneTimeToken({ HttpClientPredicate? getHttpClient, String? action, String? code, + String? languageCode, }) async { try { final String? token = await performPassThroughAuthentication( @@ -301,6 +307,7 @@ Future _getOneTimeToken({ code: code, getHttpClient: getHttpClient, platform: platform, + languageCode: languageCode, ); return token; @@ -327,6 +334,7 @@ Future _validateCredentials({ HttpClientPredicate? getHttpClient, String? action, String? code, + String? languageCode, }) async { final String? oneTimeToken = await _fetchOneTimeToken( context: context, @@ -343,6 +351,7 @@ Future _validateCredentials({ action: action, code: code, platform: platform, + languageCode: languageCode, ); if (oneTimeToken == null) { diff --git a/packages/deriv_web_view/lib/helper.dart b/packages/deriv_web_view/lib/helper.dart index 37a4ed291..1860b7b61 100644 --- a/packages/deriv_web_view/lib/helper.dart +++ b/packages/deriv_web_view/lib/helper.dart @@ -26,6 +26,7 @@ Future performPassThroughAuthentication({ HttpClientPredicate? getHttpClient, String? action, String? code, + String? languageCode, }) async { final url = getPtaLoginUrl(host: endpoint); @@ -47,6 +48,7 @@ Future performPassThroughAuthentication({ platform: platform, action: action, code: code, + languageCode: languageCode, ), ).toJson(); diff --git a/packages/deriv_web_view/lib/models/pta_login_request_model.dart b/packages/deriv_web_view/lib/models/pta_login_request_model.dart index 4dfee0910..3edce537f 100644 --- a/packages/deriv_web_view/lib/models/pta_login_request_model.dart +++ b/packages/deriv_web_view/lib/models/pta_login_request_model.dart @@ -33,6 +33,7 @@ class UrlParamsModel { required this.platform, this.action, this.code, + this.languageCode, }); /// URL that user should be redirected to for example `/cashier`. @@ -50,6 +51,9 @@ class UrlParamsModel { /// Code. final String? code; + /// language code + final String? languageCode; + /// Converts a instance of this class to json. Map toJson() => { 'redirect_url': redirectUrl, @@ -57,5 +61,6 @@ class UrlParamsModel { if (action != null) 'action': action, if (code != null) 'code': code, 'platform': platform, + if (languageCode != null) 'lang': languageCode, }; } diff --git a/packages/deriv_web_view/pubspec.yaml b/packages/deriv_web_view/pubspec.yaml index b2198fe66..919b4f04a 100644 --- a/packages/deriv_web_view/pubspec.yaml +++ b/packages/deriv_web_view/pubspec.yaml @@ -1,7 +1,7 @@ name: deriv_web_view description: Deriv Web View package project. -version: 0.2.2+1 +version: 0.2.2+3 homepage: https://deriv.com/ publish_to: "none" diff --git a/packages/deriv_widgetbook/CHANGELOG.md b/packages/deriv_widgetbook/CHANGELOG.md index edd0b2854..5163095e0 100644 --- a/packages/deriv_widgetbook/CHANGELOG.md +++ b/packages/deriv_widgetbook/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.0.2+9 + + - Update a dependency to the latest release. + +## 0.0.2+8 + + - Update a dependency to the latest release. + +## 0.0.2+7 + + - Update a dependency to the latest release. + ## 0.0.2+6 - **REFACTOR**: update dependencies. ([af89e148](https://github.com/regentmarkets/flutter-deriv-packages/commit/af89e148dfecb6dbc8552b2b883cbad4102a56f8)) diff --git a/packages/deriv_widgetbook/pubspec.yaml b/packages/deriv_widgetbook/pubspec.yaml index 9ced126dc..79424c1a1 100644 --- a/packages/deriv_widgetbook/pubspec.yaml +++ b/packages/deriv_widgetbook/pubspec.yaml @@ -1,7 +1,7 @@ name: deriv_widgetbook description: Storybook for Deriv UI widgets and components. publish_to: "none" -version: 0.0.2+6 +version: 0.0.2+9 environment: sdk: ">=3.0.0 <4.0.0" @@ -16,7 +16,7 @@ dependencies: git: url: git@github.com:regentmarkets/flutter-deriv-packages.git path: packages/deriv_ui - ref: deriv_ui-v0.0.7+6 + ref: deriv_ui-v0.0.7+9 deriv_theme: git: url: git@github.com:regentmarkets/flutter-deriv-packages.git diff --git a/packages/update_checker/CHANGELOG.md b/packages/update_checker/CHANGELOG.md index 04eae25e0..caf0d3f95 100644 --- a/packages/update_checker/CHANGELOG.md +++ b/packages/update_checker/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.4.0 + + - **FEAT**(update_checker): add the ability to change the key from the app side ([#628](https://github.com/regentmarkets/flutter-deriv-packages/issues/628)). ([b18609a0](https://github.com/regentmarkets/flutter-deriv-packages/commit/b18609a00533aaab6d6962eb89f323e2f560df8b)) + ## 1.3.0 - **FEAT**(deriv_logger): add ability to print prettified logs in console and UI ([#608](https://github.com/regentmarkets/flutter-deriv-packages/issues/608)). ([5a91c24b](https://github.com/regentmarkets/flutter-deriv-packages/commit/5a91c24bde607ff37940edf18f8dfac67d3fc4fa)) diff --git a/packages/update_checker/lib/src/presentation/update_checker.dart b/packages/update_checker/lib/src/presentation/update_checker.dart index 88eeaa134..9f9514d6c 100644 --- a/packages/update_checker/lib/src/presentation/update_checker.dart +++ b/packages/update_checker/lib/src/presentation/update_checker.dart @@ -1,3 +1,4 @@ +import 'package:firebase_remote_config/firebase_remote_config.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:update_checker/src/repositories/base_firebase.dart'; @@ -43,6 +44,19 @@ class _UpdateCheckerState extends State { @override void initState() { super.initState(); + // Configure fetch settings + FirebaseRemoteConfig.instance.setConfigSettings(RemoteConfigSettings( + fetchTimeout: const Duration(seconds: 10), + // Default fetch timeout + + // As google set a limit of 5 call per hour for each device, + // we set the minimumFetchInterval to 15 minutes + // to avoid Throttling error, + // check: https://firebase.google.com/docs/remote-config/get-started?platform=ios#throttling + minimumFetchInterval: + const Duration(minutes: 15), // Minimum fetch interval set to 0 + )); + _updateBloc = UpdateBloc(firebaseRepository: widget.firebaseRepository); _updateBloc.add(UpdateFetchEvent()); } diff --git a/packages/update_checker/lib/src/repositories/firebase_remote_config.dart b/packages/update_checker/lib/src/repositories/firebase_remote_config.dart index 8fdd42e2d..58bbd165a 100644 --- a/packages/update_checker/lib/src/repositories/firebase_remote_config.dart +++ b/packages/update_checker/lib/src/repositories/firebase_remote_config.dart @@ -5,9 +5,11 @@ import 'package:update_checker/src/repositories/base_firebase.dart'; /// the firebase database. class FirebaseRemoteConfigRepository implements BaseFirebase { /// Initializes the Firebase Database repository - const FirebaseRemoteConfigRepository(); + FirebaseRemoteConfigRepository( + {String versionControlKey = 'app_version_control'}) + : _versionControlKey = versionControlKey; - static const String _versionControlKey = 'app_version_control'; + late final String _versionControlKey; /// Fetches the update information from the database. @override diff --git a/packages/update_checker/pubspec.yaml b/packages/update_checker/pubspec.yaml index ea68d1f23..5d50c0fc9 100644 --- a/packages/update_checker/pubspec.yaml +++ b/packages/update_checker/pubspec.yaml @@ -1,6 +1,6 @@ name: update_checker description: Check and retrieve update information from the server for the given package. -version: 1.3.0 +version: 1.4.0 homepage: https://deriv.com/ publish_to: "none"