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
20 changes: 17 additions & 3 deletions android/src/main/java/com/exponea/ExponeaModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -520,9 +520,23 @@ class ExponeaModule(private val reactContext: ReactApplicationContext) :

override fun markAppInboxAsRead(message: ReadableMap, promise: Promise) = requireInitialized(promise) {
catchAndReject(promise) {
val messageItem = message.toMessageItem()
Exponea.markAppInboxAsRead(messageItem) { success ->
promise.resolve(success)
val messageData = message.toHashMapRecursively().toMessageItem()
if (messageData == null) {
promise.reject("ExponeaDataException", "AppInbox message data are invalid. See logs", null)
return@catchAndReject
}
Exponea.fetchAppInboxItem(messageId = messageData.id) { nativeMessage ->
if (nativeMessage == null) {
promise.reject("ExponeaDataException", "AppInbox message not found. See logs", null)
return@fetchAppInboxItem
}
Exponea.markAppInboxAsRead(nativeMessage) { success ->
if (success) {
promise.resolve(true)
} else {
promise.reject("ExponeaError", "Failed to mark AppInbox message as read", null)
}
}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion android/src/main/java/com/exponea/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,8 @@ internal fun Map<String, Any?>.toMessageItem(): MessageItem? {

internal fun Map<String, Any?>.toMessageItemAction(): MessageItemAction? {
val source = this
val sourceType = MessageItemAction.Type.find(source.getNullSafely("type")) ?: return null
val typeKey = source.getNullSafely("type", String::class) ?: source.getNullSafely("action", String::class)
val sourceType = MessageItemAction.Type.find(typeKey) ?: return null
return MessageItemAction().apply {
type = sourceType
title = source.getNullSafely("title")
Expand Down
64 changes: 49 additions & 15 deletions ios/Exponea.mm
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,26 @@ + (NSString *)moduleName
return @"Exponea";
}

- (NSDictionary *)appInboxMessageToDictionary:(const JS::NativeExponea::AppInboxMessage &)message
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[@"id"] = message.id_();
dict[@"type"] = message.type();
if (message.is_read().has_value()) { dict[@"is_read"] = @(message.is_read().value()); }
if (message.create_time().has_value()) { dict[@"create_time"] = @(message.create_time().value()); }
if (message.content()) { dict[@"content"] = message.content(); }
return dict;
}

- (NSDictionary *)appInboxActionToDictionary:(const JS::NativeExponea::AppInboxAction &)action
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
if (action.action()) { dict[@"action"] = action.action(); }
if (action.title()) { dict[@"title"] = action.title(); }
if (action.url()) { dict[@"url"] = action.url(); }
return dict;
}

- (NSNumber *)isConfigured
{
return @([_exponeaBridge isConfigured]);
Expand Down Expand Up @@ -587,45 +607,59 @@ - (void)fetchAppInboxItem:(NSString *)messageId
}];
}

- (void)markAppInboxAsRead:(NSDictionary *)message
- (void)markAppInboxAsRead:(JS::NativeExponea::AppInboxMessage &)message
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject
{
BOOL success = [_exponeaBridge markAppInboxAsRead:message];
resolve(@(success));
NSString *messageId = message.id_();
if (messageId == nil || messageId.length == 0) {
reject(@"ExponeaError", @"App inbox message ID is missing", nil);
return;
}

[_exponeaBridge markAppInboxAsRead:messageId
success:^(BOOL marked) {
if (marked) {
resolve(@(YES));
} else {
reject(@"ExponeaError", [NSString stringWithFormat:@"Failed to mark app inbox message %@ as read", messageId], nil);
}
} failure:^(NSError *error) {
reject(@"ExponeaError", error.localizedDescription, error);
}];
}

- (void)trackAppInboxOpened:(NSDictionary *)message
- (void)trackAppInboxOpened:(JS::NativeExponea::AppInboxMessage &)message
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject
{
BOOL success = [_exponeaBridge trackAppInboxOpened:message considerConsent:YES];
BOOL success = [_exponeaBridge trackAppInboxOpened:[self appInboxMessageToDictionary:message] considerConsent:YES];
if (success) {
resolve([NSNull null]);
} else {
reject(@"ExponeaError", @"Failed to track app inbox opened", nil);
}
}

- (void)trackAppInboxOpenedWithoutTrackingConsent:(NSDictionary *)message
- (void)trackAppInboxOpenedWithoutTrackingConsent:(JS::NativeExponea::AppInboxMessage &)message
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject
{
BOOL success = [_exponeaBridge trackAppInboxOpened:message considerConsent:NO];
BOOL success = [_exponeaBridge trackAppInboxOpened:[self appInboxMessageToDictionary:message] considerConsent:NO];
if (success) {
resolve([NSNull null]);
} else {
reject(@"ExponeaError", @"Failed to track app inbox opened without consent", nil);
}
}

- (void)trackAppInboxClick:(NSDictionary *)action
message:(NSDictionary *)message
- (void)trackAppInboxClick:(JS::NativeExponea::AppInboxAction &)action
message:(JS::NativeExponea::AppInboxMessage &)message
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject
{
BOOL success = [_exponeaBridge trackAppInboxClick:action
message:message
BOOL success = [_exponeaBridge trackAppInboxClick:[self appInboxActionToDictionary:action]
message:[self appInboxMessageToDictionary:message]
considerConsent:YES];
if (success) {
resolve([NSNull null]);
Expand All @@ -634,13 +668,13 @@ - (void)trackAppInboxClick:(NSDictionary *)action
}
}

- (void)trackAppInboxClickWithoutTrackingConsent:(NSDictionary *)action
message:(NSDictionary *)message
- (void)trackAppInboxClickWithoutTrackingConsent:(JS::NativeExponea::AppInboxAction &)action
message:(JS::NativeExponea::AppInboxMessage &)message
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject
{
BOOL success = [_exponeaBridge trackAppInboxClick:action
message:message
BOOL success = [_exponeaBridge trackAppInboxClick:[self appInboxActionToDictionary:action]
message:[self appInboxMessageToDictionary:message]
considerConsent:NO];
if (success) {
resolve([NSNull null]);
Expand Down
29 changes: 19 additions & 10 deletions ios/ExponeaBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -585,21 +585,30 @@ public class ExponeaRNVersion: NSObject, ExponeaVersionProvider {
}
}

public func markAppInboxAsRead(_ messageDict: [AnyHashable: Any]) -> Bool {
public func markAppInboxAsRead(
_ messageId: String,
success: @escaping (Bool) -> Void,
failure: @escaping (Error) -> Void
) {
guard ExponeaBridge.exponeaInstance.isConfigured else {
print("ExponeaBridge: SDK not configured")
return false
failure(ExponeaError.notConfigured)
return
}

do {
let message = try TypeConverters.parseAppInboxMessage(from: messageDict as NSDictionary)
ExponeaSDK.Exponea.shared.markAppInboxAsRead(message) { marked in
print("ExponeaBridge: Message marked as read: \(marked)")
print("ExponeaBridge: Fetching native AppInbox message before marking as read: \(messageId)")
ExponeaSDK.Exponea.shared.fetchAppInboxItem(messageId) { result in
switch result {
case .success(let message):
print("ExponeaBridge: Marking native AppInbox message as read: \(messageId)")
ExponeaSDK.Exponea.shared.markAppInboxAsRead(message) { marked in
print("ExponeaBridge: AppInbox message \(messageId) marked as read: \(marked)")
success(marked)
}
case .failure(let error):
print("ExponeaBridge: Failed to fetch native AppInbox message \(messageId) before marking as read: \(error)")
failure(error)
}
return true
} catch {
print("ExponeaBridge: Failed to parse app inbox message: \(error)")
return false
}
}

Expand Down