From 81587b93992adf0cae23ff81d60397cc07c4bc3b Mon Sep 17 00:00:00 2001 From: hydromoll Date: Thu, 17 Sep 2026 14:21:20 +0300 Subject: [PATCH] =?UTF-8?q?fix(=F0=9F=8D=8F):=20diff=20ClusteredYamap=20pr?= =?UTF-8?q?ops=20instead=20of=20async=20full=20re-apply?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/ClusteredYamapLiteView.mm | 153 ++++++++++++++++++++++++---------- 1 file changed, 107 insertions(+), 46 deletions(-) diff --git a/ios/ClusteredYamapLiteView.mm b/ios/ClusteredYamapLiteView.mm index 328a725..97a209a 100644 --- a/ios/ClusteredYamapLiteView.mm +++ b/ios/ClusteredYamapLiteView.mm @@ -1,5 +1,4 @@ #import "ClusteredYamapLiteView.h" -#include #include "ReactCodegen/react/renderer/components/YamapLiteViewSpec/EventEmitters.h" #include "YamapLiteCircleView.h" #include "YamapLiteMarkerView.h" @@ -7,6 +6,7 @@ #include "YamapLitePolylineView.h" #include #include +#include #import #import @@ -17,6 +17,7 @@ #import #import "RCTFabricComponentsPlugins.h" +#import "Utils/PointsEqual.h" #if __has_include("YamapLite/YamapLite-Swift.h") #import "YamapLite/YamapLite-Swift.h" #else @@ -60,62 +61,122 @@ - (void)updateProps:(Props::Shared const &)props *std::static_pointer_cast(_props); const auto &newViewProps = *std::static_pointer_cast(props); - // Ensure all map property updates happen on the main thread - // React Native Fabric can call updateProps from a background thread - dispatch_async(dispatch_get_main_queue(), ^{ - // Always update properties from newViewProps to ensure applyProperties() - // uses correct values - NSString *sampleRate = - RCTNSStringFromStringNilIfEmpty(toString(newViewProps.mapType)); - self->_view.mapType = sampleRate; - self->_view.nightMode = newViewProps.nightMode; - self->_view.zoomGesturesEnabled = newViewProps.zoomGesturesEnabled; - self->_view.scrollGesturesEnabled = newViewProps.scrollGesturesEnabled; - self->_view.rotateGesturesEnabled = newViewProps.rotateGesturesEnabled; - self->_view.tiltGesturesEnabled = newViewProps.tiltGesturesEnabled; - self->_view.fastTapEnabled = newViewProps.fastTapEnabled; - self->_view.userLocationAccuracyFillColor = + + if (oldViewProps.mapType != newViewProps.mapType) { + _view.mapType = RCTNSStringFromString(toString(newViewProps.mapType)); + } + if (oldViewProps.nightMode != newViewProps.nightMode) { + _view.nightMode = newViewProps.nightMode; + } + if (oldViewProps.zoomGesturesEnabled != newViewProps.zoomGesturesEnabled) { + _view.zoomGesturesEnabled = newViewProps.zoomGesturesEnabled; + } + if (oldViewProps.scrollGesturesEnabled != + newViewProps.scrollGesturesEnabled) { + _view.scrollGesturesEnabled = newViewProps.scrollGesturesEnabled; + } + if (oldViewProps.rotateGesturesEnabled != + newViewProps.rotateGesturesEnabled) { + _view.rotateGesturesEnabled = newViewProps.rotateGesturesEnabled; + } + if (oldViewProps.tiltGesturesEnabled != newViewProps.tiltGesturesEnabled) { + _view.tiltGesturesEnabled = newViewProps.tiltGesturesEnabled; + } + if (oldViewProps.fastTapEnabled != newViewProps.fastTapEnabled) { + _view.fastTapEnabled = newViewProps.fastTapEnabled; + } + if (oldViewProps.maxFps != newViewProps.maxFps) { + _view.maxFps = newViewProps.maxFps; + } + + if (oldViewProps.initialRegion.lat != newViewProps.initialRegion.lat || + oldViewProps.initialRegion.lon != newViewProps.initialRegion.lon || + oldViewProps.initialRegion.zoom != newViewProps.initialRegion.zoom || + oldViewProps.initialRegion.azimuth != + newViewProps.initialRegion.azimuth || + oldViewProps.initialRegion.tilt != newViewProps.initialRegion.tilt) { + [_view move:newViewProps.initialRegion.lat + :newViewProps.initialRegion.lon + :newViewProps.initialRegion.zoom + :newViewProps.initialRegion.azimuth + :newViewProps.initialRegion.tilt]; + } + + if (oldViewProps.userLocationAccuracyFillColor != + newViewProps.userLocationAccuracyFillColor) { + UIColor *color = [self hexStringToColor:RCTNSStringFromString( newViewProps.userLocationAccuracyFillColor)]; - self->_view.userLocationAccuracyStrokeColor = [self + if (color) { + _view.userLocationAccuracyFillColor = color; + } + } + if (oldViewProps.userLocationAccuracyStrokeColor != + newViewProps.userLocationAccuracyStrokeColor) { + UIColor *color = [self hexStringToColor:RCTNSStringFromString( newViewProps.userLocationAccuracyStrokeColor)]; - self->_view.userLocationAccuracyStrokeWidth = + if (color) { + _view.userLocationAccuracyStrokeColor = color; + } + } + if (oldViewProps.userLocationAccuracyStrokeWidth != + newViewProps.userLocationAccuracyStrokeWidth) { + _view.userLocationAccuracyStrokeWidth = newViewProps.userLocationAccuracyStrokeWidth; - self->_view.showUserPosition = newViewProps.showUserPosition; - self->_view.userLocationIconScale = newViewProps.userLocationIconScale; - self->_view.clusterColor = [self - hexStringToColor:RCTNSStringFromString(newViewProps.clusterColor)]; + } + if (oldViewProps.showUserPosition != newViewProps.showUserPosition) { + [_view setShowUserPositionState:newViewProps.showUserPosition]; + } + if (oldViewProps.userLocationIcon != newViewProps.userLocationIcon) { + [_view setUserLocationIconWithPath:RCTNSStringFromString( + newViewProps.userLocationIcon)]; + } + if (oldViewProps.userLocationIconScale != + newViewProps.userLocationIconScale) { + _view.userLocationIconScale = newViewProps.userLocationIconScale; + } + if (oldViewProps.followUser != newViewProps.followUser) { + [_view setFollowUser:newViewProps.followUser]; + } + + if (oldViewProps.logoPosition.horizontal != + newViewProps.logoPosition.horizontal || + oldViewProps.logoPosition.vertical != + newViewProps.logoPosition.vertical) { + [_view setLogoPositionWithPosition:@{ + @"horizontal" : + RCTNSStringFromString(toString(newViewProps.logoPosition.horizontal)), + @"vertical" : + RCTNSStringFromString(toString(newViewProps.logoPosition.vertical)) + }]; + } + if (oldViewProps.logoPadding.vertical != newViewProps.logoPadding.vertical || + oldViewProps.logoPadding.horizontal != + newViewProps.logoPadding.horizontal) { + [_view setLogoPaddingWithVertical:newViewProps.logoPadding.vertical + horizontal:newViewProps.logoPadding.horizontal]; + } + if (oldViewProps.clusterColor != newViewProps.clusterColor) { + UIColor *color = [self + hexStringToColor:RCTNSStringFromString(newViewProps.clusterColor)]; + if (color) { + _view.clusterColor = color; + } + } + if (!yamaplite::pointsEqual(oldViewProps.clusteredMarkers, + newViewProps.clusteredMarkers)) { NSMutableArray *markersArr = [NSMutableArray arrayWithCapacity:newViewProps.clusteredMarkers.size()]; - for (const auto &marker : newViewProps.clusteredMarkers) { - YMKPoint *point = [YMKPoint pointWithLatitude:marker.lat - longitude:marker.lon]; - [markersArr addObject:point]; + [markersArr addObject:[YMKPoint pointWithLatitude:marker.lat + longitude:marker.lon]]; } + [_view setupClusteredMarkersWithMarkers:markersArr]; + } - [self->_view setupClusteredMarkersWithMarkers:markersArr]; - NSDictionary *logoPositionDict = @{ - @"horizontal" : - RCTNSStringFromString(toString(newViewProps.logoPosition.horizontal)), - @"vertical" : - RCTNSStringFromString(toString(newViewProps.logoPosition.vertical)) - }; - [self->_view setShowUserPositionState:newViewProps.showUserPosition]; - [self->_view updateUserIcon]; - [self->_view - setUserLocationIconWithPath:RCTNSStringFromString( - newViewProps.userLocationIcon)]; - [self->_view move:newViewProps.initialRegion.lat :newViewProps.initialRegion.lon :newViewProps.initialRegion.zoom :newViewProps.initialRegion.azimuth :newViewProps.initialRegion.tilt]; - [self->_view setLogoPositionWithPosition:logoPositionDict]; - [self->_view - setLogoPaddingWithVertical:newViewProps.logoPadding.vertical - horizontal:newViewProps.logoPadding.horizontal]; - self->_view.maxFps = newViewProps.maxFps; - [self->_view applyProperties]; - }); + [_view applyProperties]; [super updateProps:props oldProps:oldProps]; }