Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/add_support_for_fabric_native_components_in_nativeadview #424

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

alhiwatan
Copy link
Collaborator

@alhiwatan alhiwatan commented Feb 28, 2025

Add support for Fabric Native Components in NativeAdView.

Description by Korbit AI

What change is being made?

Add support for Fabric Native Components in NativeAdView across Android and iOS platforms to optimize and enhance the integration of native ads within the React Native framework.

Why are these changes being made?

The adoption of Fabric Native Components leverages the new React Native architecture, which aims to improve performance by directly connecting native views and JavaScript. This change facilitates better event handling and component updates, aligning with modern programming approaches and ensuring better ad rendering performance within the AppLovin ecosystem. Additionally, the update transitions from using existing structures to the new architecture with minimal redundancy while maintaining backward compatibility where necessary.

Is this description stale? Ask me to generate a new description by commenting /korbit-generate-pr-description

Copy link

@korbit-ai korbit-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review by Korbit AI

Korbit automatically attempts to detect when you fix issues in new commits.
Category Issue Fix Detected
Readability Duplicated Complex Parameter Parsing Logic ▹ view
Functionality Unsafe Non-null Assertion in renderNativeAd Command ▹ view
Performance Unnecessary Style Flattening ▹ view
Functionality Incorrect Image Source Logic ▹ view
Readability Unnecessary empty constructor ▹ view
Readability Repetitive Ref Declarations ▹ view
Readability Suboptimal parameter type for view tag ▹ view
Files scanned
File Path Reviewed
src/nativeAd/NativeAdViewProvider.tsx
android/src/main/java/com/applovin/reactnative/AppLovinMAXNativeAdViewManagerImpl.java
android/src/oldarch/com/applovin/reactnative/AppLovinMAXNativeAdViewManager.java
android/src/newarch/com/applovin/reactnative/AppLovinMAXNativeAdViewManager.java
src/nativeAd/NativeAdViewComponents.tsx
src/nativeAd/NativeAdView.tsx
android/src/main/java/com/applovin/reactnative/AppLovinMAXNativeAdView.java

Explore our documentation to understand the languages and file types we support and the files we ignore.

Need a new review? Comment /korbit-review on this PR and I'll review your latest changes.

Korbit Guide: Usage and Customization

Interacting with Korbit

  • You can manually ask Korbit to review your PR using the /korbit-review command in a comment at the root of your PR.
  • You can ask Korbit to generate a new PR description using the /korbit-generate-pr-description command in any comment on your PR.
  • Too many Korbit comments? I can resolve all my comment threads if you use the /korbit-resolve command in any comment on your PR.
  • Chat with Korbit on issues we post by tagging @korbit-ai in your reply.
  • Help train Korbit to improve your reviews by giving a 👍 or 👎 on the comments Korbit posts.

Customizing Korbit

  • Check out our docs on how you can make Korbit work best for you and your team.
  • Customize Korbit for your organization through the Korbit Console.

Feedback and Support

Comment on lines 57 to 58
const imageSource =
(nativeAd?.url && { uri: nativeAd.url }) || (nativeAd.image ? defaultIcon : nativeAd.imageSource ? { uri: `data:image/jpeg;base64,${nativeAd.imageSource}` } : defaultIcon);

This comment was marked as resolved.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated using a simple if-else statement.

Comment on lines 125 to 133
for ( int i = 0; i < readableArray.size(); i++ )
{
extraParameters = readableMap.toHashMap();
ReadableMap map = readableArray.getMap( i );

String key = map.getString( "key" );

if ( !AppLovinSdkUtils.isValidString( key ) ) continue;

if ( map.hasKey( "value" ) )

This comment was marked as resolved.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd take the recommendation from Korbit actually. The code can probably be abstracted and consolidated.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great to see you're considering the suggestion, @thomasmso! Implementing the helper method will indeed improve the readability and maintainability of the code. The suggested solution looks solid. Let us know if you encounter any issues while integrating this!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a helper function to support both extraParameters and localExtraParameters.

},
[onAdLoadFailed]
);
Commands.renderNativeAd(nativeAdViewRef.current!);

This comment was marked as resolved.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As suggested, check null first.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for taking the time to incorporate the changes. Before merging, I see in this diff that you still have a non-null assertion operator with nativeAdViewRef.current in the onAdLoadedEvent callback. To prevent potential crashes, please consider adding a null check before implicitly asserting that nativeAdViewRef.current is not null. Apart from this, everything appears to be okay.

}

@Override
public void updateAssetView(final AppLovinMAXNativeAdView view, final double assetViewTag, final String assetViewName)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suboptimal parameter type for view tag category Readability

Tell me more
What is the issue?

Using double type for what appears to be an integer view tag, requiring an explicit Math.round conversion

Why this matters

The unnecessary use of double for an ID/tag creates potential for precision loss and requires extra conversion code, making the API less intuitive.

Suggested change ∙ Feature Preview

Change the parameter type to int:

updateAssetView(final AppLovinMAXNativeAdView view, final int assetViewTag, final String assetViewName)

Report a problem with this comment

💬 Chat with Korbit by mentioning @korbit-ai.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has to be double since the signature of this function is defined by codegen.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification @alhiwatan. Agreed, the types need to be aligned with the codegen signature to avoid potential issues. In this case, using double makes sense. If there's room for optimisation in the future, we could consider investigating if codegen could be more adaptable for cases like this.

Comment on lines 40 to 46
const titleRef = useRef<React.ElementRef<typeof Text> | null>(null);
const advertiserRef = useRef<React.ElementRef<typeof Text> | null>(null);
const bodyRef = useRef<React.ElementRef<typeof Text> | null>(null);
const callToActionRef = useRef<React.ElementRef<typeof Text> | null>(null);
const imageRef = useRef<React.ElementRef<typeof Image> | null>(null);
const optionViewRef = useRef<React.ElementRef<typeof View> | null>(null);
const mediaViewRef = useRef<React.ElementRef<typeof View> | null>(null);

This comment was marked as resolved.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update as suggested.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, I see you've updated the ref declarations as suggested. This indeed improves code readability. Also, I encourage you to consider maintaining this approach for future updates. Please proceed with the merging process.

Comment on lines 13 to 16
public class AppLovinMAXNativeAdViewManager
extends ViewGroupManager<AppLovinMAXNativeAdView>
{
public AppLovinMAXNativeAdViewManager() { }

This comment was marked as resolved.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update. The code looks cleaner without the unnecessary empty constructor. Good job!

const starColor = StyleSheet.flatten((style as StyleProp<TextStyle>) || {}).color ?? '#ffe234';
const starSize = StyleSheet.flatten((style as StyleProp<TextStyle>) || {}).fontSize ?? 10;

const starTextStyle = StyleSheet.flatten(style) as TextStyle;

This comment was marked as resolved.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated as suggested.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making the update. The Memoization has been properly implemented to help optimize the style computations. This is good programming practice especially for functions with expensive operations. Everything looks good here, so this issue can be marked as resolved. If there are any other concerns or changes please let me know.


Map<String, Object> extraParametersMap = new HashMap<>();

for ( int i = 0; i < readableArray.size(); i++ )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is used in the other PR for native adviews - so is this something we can consolidate the logic for? Like in Utils class?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a helper function to support both AdView and NativeAdView.

@@ -108,19 +116,84 @@ public void setCustomData(@Nullable final String value)
customData = value;
}

public void setExtraParameters(@Nullable final ReadableMap readableMap)
public void setExtraParameters(@Nullable final ReadableArray readableArray)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should name parameters to describe what it is, not its type. So I'd name it extraParameters.

}
else if ( type == ReadableType.Null )
{
extraParametersMap.put( key, null );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If null - should remove? When is this going to be the case?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can null be used to reset the value of the key?

Comment on lines 125 to 133
for ( int i = 0; i < readableArray.size(); i++ )
{
extraParameters = readableMap.toHashMap();
ReadableMap map = readableArray.getMap( i );

String key = map.getString( "key" );

if ( !AppLovinSdkUtils.isValidString( key ) ) continue;

if ( map.hasKey( "value" ) )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd take the recommendation from Korbit actually. The code can probably be abstracted and consolidated.

@@ -170,6 +243,45 @@ public void loadAd()
}
}

public void updateAssetView(final int assetViewTag, final String assetViewName)
{
if ( assetViewName.equals( "TitleView" ) )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: in Java, to avoid NPEs, we operate on the string first. So "TitleView".equals( assetViewName ).

@alhiwatan
Copy link
Collaborator Author

Please review again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants