Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ class InlineInAppMessageViewManager :
view?.elementId = value
}

@ReactProp(name = "showScrollIndicators", defaultBoolean = true)
override fun setShowScrollIndicators(view: ReactInlineInAppMessageView?, value: Boolean) {
view?.showScrollIndicators = value
}

companion object {
internal const val NAME = "InlineMessageNative"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package io.customer.reactnative.sdk.messaginginapp

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import androidx.annotation.AttrRes
import androidx.annotation.StyleRes
import io.customer.messaginginapp.type.InAppMessage
Expand Down Expand Up @@ -29,6 +31,26 @@ class ReactInlineInAppMessageView @JvmOverloads constructor(
setActionListener(this)
}

var showScrollIndicators: Boolean = true
set(value) {
if (field == value) return
field = value
applyScrollIndicators(this)
}

override fun onViewAdded(child: View) {
super.onViewAdded(child)
applyScrollIndicators(child)
}

private fun applyScrollIndicators(view: View) {
view.isVerticalScrollBarEnabled = showScrollIndicators
view.isHorizontalScrollBarEnabled = showScrollIndicators
if (view is ViewGroup) {
for (i in 0 until view.childCount) applyScrollIndicators(view.getChildAt(i))
}
}

override fun onActionClick(message: InAppMessage, actionValue: String, actionName: String) {
val payload = mapOf(
"message" to mapOf(
Expand Down
4 changes: 3 additions & 1 deletion api-extractor-output/customerio-reactnative.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { TurboModule } from 'react-native';
import type { UnsafeObject } from 'react-native/Libraries/Types/CodegenTypes';
import type { ViewProps } from 'react-native';
import { ViewStyle } from 'react-native';
import type { WithDefault } from 'react-native/Libraries/Types/CodegenTypes';

// @public
export type CioConfig = {
Expand Down Expand Up @@ -204,13 +205,14 @@ export const InlineInAppMessageView: React_2.FC<InlineInAppMessageViewProps>;
// Warning: (ae-forgotten-export) The symbol "NativeProps" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
export interface InlineInAppMessageViewProps extends Omit<NativeProps, 'onSizeChange' | 'onStateChange' | 'onActionClick'> {
export interface InlineInAppMessageViewProps extends Omit<NativeProps, 'onSizeChange' | 'onStateChange' | 'onActionClick' | 'showScrollIndicators'> {
loadingComponent?: React_2.ReactNode;
loadingContainerStyle?: ViewStyle;
loadingIndicatorProps?: ActivityIndicatorProps & {
minimumHeight?: number;
};
onActionClick?: (message: InAppMessage, actionValue: string, actionName: string) => void;
showScrollIndicators?: boolean;
}

// @public
Expand Down
7 changes: 7 additions & 0 deletions ios/wrappers/inapp/inline/RCTInlineMessageNative.mm
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
// On updates, diff against the parameter rather than _props so we never rely on
// the ivar's runtime type.
BOOL elementIdChanged = YES;
BOOL showScrollIndicatorsChanged = YES;
if (oldProps) {
const auto &oldViewProps = *std::static_pointer_cast<InlineMessageNativeProps const>(oldProps);
elementIdChanged = oldViewProps.elementId != newViewProps.elementId;
showScrollIndicatorsChanged = oldViewProps.showScrollIndicators != newViewProps.showScrollIndicators;
}

if (elementIdChanged) {
Expand All @@ -62,6 +64,11 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
[self.bridge setElementId:elementId];
}

if (showScrollIndicatorsChanged) {
[self assertBridgeAvailable:@"updating showScrollIndicators prop"];
[self.bridge setShowScrollIndicators:newViewProps.showScrollIndicators];
}

[super updateProps:props oldProps:oldProps];
}

Expand Down
3 changes: 3 additions & 0 deletions ios/wrappers/inapp/inline/ReactInlineMessageView.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ NS_ASSUME_NONNULL_BEGIN
/// Sets the element ID for the inline message
- (void)setElementId:(NSString *)elementId;

/// Sets container scroll indicators visibility
- (void)setShowScrollIndicators:(BOOL)showScrollIndicators;

/// Prepares the view for reuse in React Native lifecycle
- (void)setupForReuse;

Expand Down
19 changes: 19 additions & 0 deletions ios/wrappers/inapp/inline/ReactInlineMessageView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import CioMessagingInApp
import Foundation
import UIKit
import WebKit

/// React Native wrapper for inline message display with content view lifecycle management.
///
Expand Down Expand Up @@ -29,6 +30,14 @@ class ReactInlineMessageView: NSObject {
contentView.elementId = elementId
}

private var showScrollIndicators: Bool = true

@objc
func setShowScrollIndicators(_ showScrollIndicators: Bool) {
self.showScrollIndicators = showScrollIndicators
applyScrollIndicators(in: contentView)
}
Comment thread
xavi-999 marked this conversation as resolved.

@objc
func setupForReuse() {
contentView.onViewAttached()
Expand Down Expand Up @@ -106,6 +115,7 @@ extension ReactInlineMessageView: InlineMessageBridgeViewDelegate {
}

func onMessageSizeChanged(width: CGFloat, height: CGFloat) {
applyScrollIndicators(in: contentView)
sendOnSizeChangeEvent(width: width, height: height)
}

Expand All @@ -114,11 +124,20 @@ extension ReactInlineMessageView: InlineMessageBridgeViewDelegate {
}

func onStartLoading(onComplete: @escaping () -> Void) {
applyScrollIndicators(in: contentView)
sendOnStateChangeEvent(state: .loadingStarted)
onComplete()
}

func onFinishLoading() {
sendOnStateChangeEvent(state: .loadingFinished)
}

private func applyScrollIndicators(in view: UIView) {
if let webView = view as? WKWebView {
webView.scrollView.showsVerticalScrollIndicator = showScrollIndicators
webView.scrollView.showsHorizontalScrollIndicator = showScrollIndicators
}
view.subviews.forEach { applyScrollIndicators(in: $0) }
}
}
4 changes: 3 additions & 1 deletion src/components/InlineInAppMessageView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type { InAppMessage } from '../types';
/** @public */
export interface InlineInAppMessageViewProps extends Omit<
NativeProps,
'onSizeChange' | 'onStateChange' | 'onActionClick'
'onSizeChange' | 'onStateChange' | 'onActionClick' | 'showScrollIndicators'
> {
/** Custom loading component to display while message is loading */
loadingComponent?: React.ReactNode;
Expand All @@ -33,6 +33,8 @@ export interface InlineInAppMessageViewProps extends Omit<
};
/** Custom styles for the loading container */
loadingContainerStyle?: ViewStyle;
/** Controls whether the inline message's scroll indicators are visible. (default: true) */
showScrollIndicators?: boolean;
/** Callback triggered when a user clicks an action button in the inline message */
onActionClick?: (
message: InAppMessage,
Expand Down
2 changes: 2 additions & 0 deletions src/specs/components/InlineMessageNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { HostComponent, ViewProps } from 'react-native';
import type {
DirectEventHandler,
Double,
WithDefault,
} from 'react-native/Libraries/Types/CodegenTypes';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';

Expand Down Expand Up @@ -46,6 +47,7 @@ export interface ActionClickEvent {
export interface NativeProps extends ViewProps {
/** Required element ID for retrieving inline message content. */
elementId: string;
showScrollIndicators?: WithDefault<boolean, true>;
onSizeChange: DirectEventHandler<SizeChangeEvent>;
onStateChange?: DirectEventHandler<StateChangeEvent>;
onActionClick?: DirectEventHandler<ActionClickEvent>;
Expand Down