From 1f069136ba6d891392ba4787f1bf4a1fef5686a5 Mon Sep 17 00:00:00 2001 From: Michelle Dayangco Date: Wed, 11 Mar 2026 15:50:02 +0800 Subject: [PATCH 1/5] Enhancement changes on VritusizeWidget implementation --- lib/src/widgets/virtusize_widget.dart | 82 +++++++++++++-------- lib/src/widgets/virtusize_widget_event.dart | 21 +++--- 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/lib/src/widgets/virtusize_widget.dart b/lib/src/widgets/virtusize_widget.dart index ab17530..714f1ed 100644 --- a/lib/src/widgets/virtusize_widget.dart +++ b/lib/src/widgets/virtusize_widget.dart @@ -8,21 +8,21 @@ import '../main.dart'; import '../models/product_data_check.dart'; import '../models/recommendation.dart'; -class VirtusizeWidget extends StatefulWidget { +class VirtusizeWidgetBuilder extends StatefulWidget { final VirtusizeClientProduct product; - final Container child; - final ValueChanged onVirtusizeEventChanged; - VirtusizeWidget({ + + final Widget Function(BuildContext context, VirtusizeWidgetState) builder; + + VirtusizeWidgetBuilder({ required this.product, - required this.child, - required this.onVirtusizeEventChanged, + required this.builder, }) : super(key: ValueKey('button_${product.externalProductId}')); @override - State createState() => _VirtusizeWidgetState(); + State createState() => _VirtusizeWidgetBuilderState(); } -class _VirtusizeWidgetState extends State { +class _VirtusizeWidgetBuilderState extends State { late final StreamSubscription _pdcSubscription; late final StreamSubscription _errorSubscription; late final StreamSubscription _recSubscription; @@ -31,6 +31,8 @@ class _VirtusizeWidgetState extends State { bool _isAllowedForStore = false; Timer? _productDataCheckTimeout; + VirtusizeWidgetState _eventState = VirtusizeWidgetLoading(); + @override void initState() { super.initState(); @@ -44,11 +46,15 @@ class _VirtusizeWidgetState extends State { _productDataCheckTimeout?.cancel(); setState(() { - _isValidProduct = productDataCheck.isValidProduct; + _eventState = VirtusizeWidgetLoading(); + + _isValidProduct = productDataCheck.isValidProduct; _isAllowedForStore = productDataCheck.isAllowedForStore(); - }); - widget.onVirtusizeEventChanged(LoadingChanged(true)); + if(!_isValidProduct) { + _eventState = VirtusizeWidgetError(error: 'Invalid product: ${productDataCheck.externalProductId}'); + } + }); }); _recSubscription = IVirtusizeSDK.instance.recStream.listen(( @@ -58,8 +64,7 @@ class _VirtusizeWidgetState extends State { recommendation.externalProductID) { return; } - widget.onVirtusizeEventChanged(LoadingChanged(false)); - getRecommendedSize(recommendation.text); + onVirtusizeWidgetCompleted(recommendation.text); }); _errorSubscription = IVirtusizeSDK.instance.productErrorStream.listen(( @@ -68,9 +73,10 @@ class _VirtusizeWidgetState extends State { if (widget.product.externalProductId != externalProductId) { return; } - widget.onVirtusizeEventChanged(LoadingChanged(false)); - widget.onVirtusizeEventChanged(ErrorOccurred()); + setState(() { + _eventState = VirtusizeWidgetError(error: 'Product error: $externalProductId'); + }); }); // Start timeout timer for product data check @@ -82,14 +88,16 @@ class _VirtusizeWidgetState extends State { _productDataCheckTimeout = Timer(Duration(seconds: 10), () { if (!mounted) return; - if (!_isValidProduct) { - setState(() {}); + if (_eventState is VirtusizeWidgetLoading) { + setState(() { + _eventState = VirtusizeWidgetError(error: 'Product data check timed out'); + }); } }); } @override - void didUpdateWidget(VirtusizeWidget oldWidget) { + void didUpdateWidget(VirtusizeWidgetBuilder oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.product.externalProductId != widget.product.externalProductId) { setState(() { @@ -110,23 +118,35 @@ class _VirtusizeWidgetState extends State { @override Widget build(BuildContext context) { - // Show the view only when the product is confirmed valid - if (_isValidProduct && _isAllowedForStore) { - return GestureDetector( - onTap: _openVirtusizeWebview, - child: widget.child, - ); + + switch(_eventState){ + case VirtusizeWidgetCompleted():{ + //Return empty container if store is not allowed to use this widget class + if(!_isAllowedForStore){ + return Container(); + } + + return GestureDetector( + onTap: _openVirtusizeWebview, + child: widget.builder(context, _eventState), + ); + } + default: + return widget.builder(context, _eventState); } - return Container(); } - void getRecommendedSize(String recText) { + void onVirtusizeWidgetCompleted(String recText) { List recTextArray = recText.split("
"); - if (recTextArray.length == 2) { - widget.onVirtusizeEventChanged(RecommendedSizeChanged(recTextArray.first, recTextArray.last)); - } else { - widget.onVirtusizeEventChanged(RecommendedSizeChanged(recText, "")); - } + setState(() { + if (recTextArray.length == 2) { + _eventState = VirtusizeWidgetCompleted( + recommendedText: recTextArray.first, recommendedSize: recTextArray.last); + } else { + _eventState = VirtusizeWidgetCompleted( + recommendedText: recText, recommendedSize: ''); + } + }); } Future _openVirtusizeWebview() async { diff --git a/lib/src/widgets/virtusize_widget_event.dart b/lib/src/widgets/virtusize_widget_event.dart index 3c4c586..0c0cc74 100644 --- a/lib/src/widgets/virtusize_widget_event.dart +++ b/lib/src/widgets/virtusize_widget_event.dart @@ -1,18 +1,17 @@ -sealed class VirtusizeWidgetEvent {} +sealed class VirtusizeWidgetState {} -class RecommendedSizeChanged extends VirtusizeWidgetEvent { - final String size; - final String text; +class VirtusizeWidgetCompleted extends VirtusizeWidgetState { + final String recommendedText; + final String recommendedSize; - RecommendedSizeChanged(this.text, this.size); + VirtusizeWidgetCompleted({required this.recommendedText,required this.recommendedSize}); } -class LoadingChanged extends VirtusizeWidgetEvent { - final bool isLoading; - - LoadingChanged(this.isLoading); +class VirtusizeWidgetLoading extends VirtusizeWidgetState { + VirtusizeWidgetLoading(); } -class ErrorOccurred extends VirtusizeWidgetEvent { - ErrorOccurred(); +class VirtusizeWidgetError extends VirtusizeWidgetState { + final Object error; + VirtusizeWidgetError({required this.error}); } \ No newline at end of file From f6c736599b676e75bd067f4459122cb8d1cfeb14 Mon Sep 17 00:00:00 2001 From: Michelle Dayangco Date: Fri, 13 Mar 2026 09:37:10 +0800 Subject: [PATCH 2/5] Update virtusize_flutter_sdk.podspec --- ios/virtusize_flutter_sdk.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/virtusize_flutter_sdk.podspec b/ios/virtusize_flutter_sdk.podspec index 8474190..02791a6 100644 --- a/ios/virtusize_flutter_sdk.podspec +++ b/ios/virtusize_flutter_sdk.podspec @@ -17,7 +17,7 @@ This SDK helps clients to integrate Virtusize’s size and fit service into thei s.resources = 'Resources/**/*.json' s.resource_bundle = { 'virtusize_flutter_sdk' => ['Resources/**/*.json'] } s.dependency 'Flutter' - s.dependency 'Virtusize', '~> 2.12.25' + s.dependency 'Virtusize', '~> 2.12.26' s.static_framework = true s.platform = :ios, '14.0' From 685406c1aa402218b6f87d7a22d75719adf6da7c Mon Sep 17 00:00:00 2001 From: OleS Date: Fri, 13 Mar 2026 12:19:37 +0200 Subject: [PATCH 3/5] Fix willFit parameter on iOS native --- ios/Classes/SwiftVirtusizeFlutterPlugin.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ios/Classes/SwiftVirtusizeFlutterPlugin.swift b/ios/Classes/SwiftVirtusizeFlutterPlugin.swift index f5b1989..41609bf 100644 --- a/ios/Classes/SwiftVirtusizeFlutterPlugin.swift +++ b/ios/Classes/SwiftVirtusizeFlutterPlugin.swift @@ -184,7 +184,8 @@ extension SwiftVirtusizeFlutterPlugin: VirtusizeFlutterProductEventHandler { storeProduct: VirtusizeServerProduct, bestUserProduct: VirtusizeServerProduct?, recommendationText: String, - willFit: Bool?) { + willFit: Bool + ) { DispatchQueue.main.async { [self] in self.flutterChannel?.invokeMethod( VirtusizeFlutterMethod.onProduct, From 2339b29e1fb894b3803c34a5aa3fb01b98c15607 Mon Sep 17 00:00:00 2001 From: OleS Date: Fri, 13 Mar 2026 12:53:37 +0200 Subject: [PATCH 4/5] Fix android pull_request_checks yml --- .github/workflows/pull_request_checks.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pull_request_checks.yml b/.github/workflows/pull_request_checks.yml index e196ea9..5fe4757 100644 --- a/.github/workflows/pull_request_checks.yml +++ b/.github/workflows/pull_request_checks.yml @@ -48,12 +48,14 @@ jobs: cache: true - name: Install dependencies - run: flutter pub get - + run: | + flutter pub get + cd example && flutter pub get + - name: Clean Gradle cache working-directory: ./example/android run: rm -rf ~/.gradle/caches/ - + - name: Run Android tests working-directory: ./example/android run: ./gradlew testDebugUnitTest -x :url_launcher_android:testDebugUnitTest From 726e6952d492d74115821f59ee945a95022feabe Mon Sep 17 00:00:00 2001 From: OleS Date: Fri, 13 Mar 2026 13:15:34 +0200 Subject: [PATCH 5/5] gradle settings fix --- example/android/settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/android/settings.gradle.kts b/example/android/settings.gradle.kts index f515db5..43394ed 100644 --- a/example/android/settings.gradle.kts +++ b/example/android/settings.gradle.kts @@ -19,7 +19,7 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" id("com.android.application") version "8.9.1" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app")