diff --git a/iap/lib/src/data/models/iap_product.dart b/iap/lib/src/data/models/iap_product.dart index b075ff6..4ee2b24 100644 --- a/iap/lib/src/data/models/iap_product.dart +++ b/iap/lib/src/data/models/iap_product.dart @@ -9,15 +9,18 @@ enum IAPProductType { paidFeatures } class IAPProduct { final String storeId; final IAPProductStatus status; + final String price; const IAPProduct({ required this.storeId, this.status = IAPProductStatus.purchasable, + required this.price, }); IAPProduct copyWith({IAPProductStatus? status}) => IAPProduct( storeId: storeId, status: status ?? this.status, + price: price, ); } diff --git a/iap/lib/src/providers/iap_products_provider.dart b/iap/lib/src/providers/iap_products_provider.dart index 2c4ca5c..936f296 100644 --- a/iap/lib/src/providers/iap_products_provider.dart +++ b/iap/lib/src/providers/iap_products_provider.dart @@ -25,6 +25,7 @@ class IAPProductsProviderState extends State { IAPProduct( storeId: IAPProductType.paidFeatures.storeId, status: IAPProductStatus.purchased, + price: '0.0\$', ) ], child: widget.child, diff --git a/integration_test/mocks/iap_products_mock.dart b/integration_test/mocks/iap_products_mock.dart index 1a79bc2..9742c8a 100644 --- a/integration_test/mocks/iap_products_mock.dart +++ b/integration_test/mocks/iap_products_mock.dart @@ -27,6 +27,7 @@ class MockIAPProductsProviderState extends State { IAPProduct( storeId: IAPProductType.paidFeatures.storeId, status: _purchased ? IAPProductStatus.purchased : IAPProductStatus.purchasable, + price: '0.0\$', ), ]), child: widget.child, diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 0b973c9..0c3ad42 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -107,6 +107,15 @@ "unlockProFeatures": "Unlock Pro features", "unlockProFeaturesDescription": "Unlock professional features:\n \u2022 Equipment profiles containing filters for aperture, shutter speed, and more\n \u2022 List of films with compensation for what's known as reciprocity failure\n \u2022 Spot metering & Histogram\n \u2022 And more!\n\nBy unlocking Pro features you support the development and make it possible to add new features to the app.", "unlock": "Unlock", + "proFeaturesSupportText": "By purchasing you support the development and make it possible to add new features to the app.", + "unlockFor": "Unlock for {price}", + "@unlockFor": { + "price": { + "version": { + "type": "String" + } + } + }, "tooltipAdd": "Add", "tooltipClose": "Close", "tooltipExpand": "Expand", diff --git a/lib/runner.dart b/lib/runner.dart index 8eb31b2..96b6fba 100644 --- a/lib/runner.dart +++ b/lib/runner.dart @@ -25,7 +25,13 @@ Future runLightmeterApp(Environment env) async { runApp( env.buildType == BuildType.dev ? IAPProducts( - products: [IAPProduct(storeId: IAPProductType.paidFeatures.storeId)], + products: [ + IAPProduct( + storeId: IAPProductType.paidFeatures.storeId, + status: IAPProductStatus.purchasable, + price: '0.0\$', + ), + ], child: application, ) : IAPProductsProvider( diff --git a/lib/screens/shared/pro_features_dialog/widget_dialog_pro_features.dart b/lib/screens/shared/pro_features_dialog/widget_dialog_pro_features.dart index cdf76b0..5683301 100644 --- a/lib/screens/shared/pro_features_dialog/widget_dialog_pro_features.dart +++ b/lib/screens/shared/pro_features_dialog/widget_dialog_pro_features.dart @@ -52,7 +52,7 @@ class ProFeaturesDialog extends StatelessWidget { IAPProductsProvider.maybeOf(context)?.buy(IAPProductType.paidFeatures); }); }, - child: Text(S.of(context).unlock), + child: Text(S.of(context).unlockFor(IAPProducts.productOf(context, IAPProductType.paidFeatures)!.price)), ), ], ); diff --git a/test/application_mock.dart b/test/application_mock.dart index a1bffef..a7882cc 100644 --- a/test/application_mock.dart +++ b/test/application_mock.dart @@ -91,6 +91,7 @@ class _GoldenTestApplicationMockState extends State { IAPProduct( storeId: IAPProductType.paidFeatures.storeId, status: widget.productStatus, + price: '0.0\$', ), ], child: ApplicationWrapper( diff --git a/test/providers/equipment_profile_provider_test.dart b/test/providers/equipment_profile_provider_test.dart index fb329cd..15472dc 100644 --- a/test/providers/equipment_profile_provider_test.dart +++ b/test/providers/equipment_profile_provider_test.dart @@ -26,6 +26,7 @@ void main() { IAPProduct( storeId: IAPProductType.paidFeatures.storeId, status: productStatus, + price: '0.0\$', ), ], child: EquipmentProfileProvider( diff --git a/test/providers/films_provider_test.dart b/test/providers/films_provider_test.dart index 47c35c1..f898579 100644 --- a/test/providers/films_provider_test.dart +++ b/test/providers/films_provider_test.dart @@ -26,6 +26,7 @@ void main() { IAPProduct( storeId: IAPProductType.paidFeatures.storeId, status: productStatus, + price: '0.0\$', ), ], child: FilmsProvider( diff --git a/test/screens/metering/components/shared/readings_container/equipment_profile_picker_test.dart b/test/screens/metering/components/shared/readings_container/equipment_profile_picker_test.dart index 5eec978..8c7d96b 100644 --- a/test/screens/metering/components/shared/readings_container/equipment_profile_picker_test.dart +++ b/test/screens/metering/components/shared/readings_container/equipment_profile_picker_test.dart @@ -28,6 +28,7 @@ void main() { IAPProduct( storeId: IAPProductType.paidFeatures.storeId, status: IAPProductStatus.purchased, + price: '0.0\$', ), ], child: EquipmentProfileProvider( diff --git a/test/screens/metering/components/shared/readings_container/film_picker_test.dart b/test/screens/metering/components/shared/readings_container/film_picker_test.dart index 03f50ed..765ca51 100644 --- a/test/screens/metering/components/shared/readings_container/film_picker_test.dart +++ b/test/screens/metering/components/shared/readings_container/film_picker_test.dart @@ -27,6 +27,7 @@ void main() { IAPProduct( storeId: IAPProductType.paidFeatures.storeId, status: IAPProductStatus.purchased, + price: '0.0\$', ), ], child: FilmsProvider( diff --git a/test/screens/metering/utils/listener_equipment_profiles_test.dart b/test/screens/metering/utils/listener_equipment_profiles_test.dart index ae6cb87..38e2a14 100644 --- a/test/screens/metering/utils/listener_equipment_profiles_test.dart +++ b/test/screens/metering/utils/listener_equipment_profiles_test.dart @@ -28,6 +28,7 @@ void main() { IAPProduct( storeId: IAPProductType.paidFeatures.storeId, status: IAPProductStatus.purchased, + price: '0.0\$', ), ], child: EquipmentProfileProvider( diff --git a/test/screens/settings/components/widget_settings_section_lightmeter_pro_test.dart b/test/screens/settings/components/widget_settings_section_lightmeter_pro_test.dart index 1ae99f4..b4d2733 100644 --- a/test/screens/settings/components/widget_settings_section_lightmeter_pro_test.dart +++ b/test/screens/settings/components/widget_settings_section_lightmeter_pro_test.dart @@ -7,6 +7,8 @@ import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import '../../../application_mock.dart'; +const _price = '0.0\$'; + void main() { Future pumpApplication(WidgetTester tester) async { await tester.pumpWidget( @@ -14,6 +16,7 @@ void main() { products: [ IAPProduct( storeId: IAPProductType.paidFeatures.storeId, + price: _price, ), ], child: const WidgetTestApplicationMock( @@ -33,9 +36,9 @@ void main() { expect(find.byType(TransparentDialog), findsOneWidget); expect(find.text(S.current.proFeatures), findsNWidgets(2)); expect(find.text(S.current.cancel), findsOneWidget); - expect(find.text(S.current.unlock), findsOneWidget); + expect(find.text(S.current.unlockFor(_price)), findsOneWidget); - await tester.tap(find.text(S.current.unlock)); + await tester.tap(find.text(S.current.unlockFor(_price))); await tester.pumpAndSettle(); expect(find.byType(TransparentDialog), findsNothing); }, @@ -50,7 +53,7 @@ void main() { expect(find.byType(TransparentDialog), findsOneWidget); expect(find.text(S.current.proFeatures), findsNWidgets(2)); expect(find.text(S.current.cancel), findsOneWidget); - expect(find.text(S.current.unlock), findsOneWidget); + expect(find.text(S.current.unlockFor(_price)), findsOneWidget); await tester.tap(find.text(S.current.cancel)); await tester.pumpAndSettle();