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 notifications unviewed api #3

Merged
merged 1 commit into from
Mar 15, 2024
Merged
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
@@ -0,0 +1,49 @@
package com.keyvalue.siren.androidsdk.data.managers

import com.keyvalue.siren.androidsdk.data.model.UnViewedNotificationResponseData
import com.keyvalue.siren.androidsdk.data.networkcallbacks.NetworkCallback
import com.keyvalue.siren.androidsdk.data.repository.NotificationRepository
import com.keyvalue.siren.androidsdk.data.repository.NotificationRepositoryImplementation
import com.keyvalue.siren.androidsdk.data.state.NotificationUnViewedState
import kotlinx.coroutines.flow.MutableStateFlow
import org.json.JSONObject

class NotificationManager(baseURL: String) {
private var service: NotificationRepository =
NotificationRepositoryImplementation(baseURL)
var notificationUnViewedState: MutableStateFlow<NotificationUnViewedState?> =
MutableStateFlow(null)

suspend fun fetchUnViewedNotificationsCount(
userToken: String,
recipientId: String,
) {
service.fetchUnViewedNotificationsCount(
userToken,
recipientId,
object : NetworkCallback {
override suspend fun onResult(classObject: Any) {
val notificationUnViewedState =
NotificationUnViewedState(
notificationUnViewedResponse = classObject as UnViewedNotificationResponseData,
errorResponse = null,
)
[email protected](
notificationUnViewedState,
)
}

override suspend fun onError(errorObject: JSONObject) {
val notificationUnViewedState =
NotificationUnViewedState(
notificationUnViewedResponse = null,
errorResponse = errorObject,
)
[email protected](
notificationUnViewedState,
)
}
},
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.keyvalue.siren.androidsdk.data.model

import com.google.gson.annotations.SerializedName

data class UnViewedNotificationResponse(
@SerializedName("data")
val unViewedNotificationResponse: UnViewedNotificationResponseData?,
@SerializedName("error")
val error: ErrorResponse?,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.keyvalue.siren.androidsdk.data.model

data class UnViewedNotificationResponseData(
val id: String,
val createdAt: String,
val updatedAt: String,
val deletedAt: String?,
val createdBy: String,
val updatedBy: String,
val deletedBy: String?,
val projectEnvironmentId: String,
val referenceId: String,
val providerIntegrationId: String,
val lastOpenedAt: String?,
val totalUnviewed: Long,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.keyvalue.siren.androidsdk.data.repository

import com.keyvalue.siren.androidsdk.data.networkcallbacks.NetworkCallback

interface NotificationRepository {
suspend fun fetchUnViewedNotificationsCount(
userToken: String,
recipientId: String,
networkCallback: NetworkCallback,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.keyvalue.siren.androidsdk.data.repository

import com.google.gson.Gson
import com.keyvalue.siren.androidsdk.data.model.UnViewedNotificationResponse
import com.keyvalue.siren.androidsdk.data.networkcallbacks.NetworkCallback
import com.keyvalue.siren.androidsdk.data.retrofit.RetrofitClient
import com.keyvalue.siren.androidsdk.data.service.NotificationApiService
import com.keyvalue.siren.androidsdk.utils.constants.CODE_GENERIC_API_ERROR
import com.keyvalue.siren.androidsdk.utils.constants.CODE_TIMED_OUT
import com.keyvalue.siren.androidsdk.utils.constants.ERROR_MESSAGE_SERVICE_NOT_AVAILABLE
import com.keyvalue.siren.androidsdk.utils.constants.ERROR_MESSAGE_TIMED_OUT
import com.keyvalue.siren.androidsdk.utils.constants.SirenErrorTypes
import org.json.JSONObject
import java.net.SocketTimeoutException

class NotificationRepositoryImplementation(baseURL: String) : NotificationRepository {
private var notificationsApiService: NotificationApiService? = null

init {
notificationsApiService =
RetrofitClient.getRetrofitInstance(baseURL)?.create(
NotificationApiService::class.java,
)
}

override suspend fun fetchUnViewedNotificationsCount(
userToken: String,
recipientId: String,
networkCallback: NetworkCallback,
) {
try {
val parentResponse =
notificationsApiService?.fetchUnViewedNotificationsCount(recipientId, userToken)
val response = parentResponse?.body()
if (response?.unViewedNotificationResponse != null) {
response.unViewedNotificationResponse.let {
networkCallback.onResult(it)
}
} else {
val errorBody = parentResponse?.errorBody()?.string()
if (errorBody != null) {
val errors =
Gson().fromJson<UnViewedNotificationResponse>(
errorBody,
UnViewedNotificationResponse::class.java,
)
networkCallback.onError(
JSONObject().put("type", SirenErrorTypes.ERROR)
.put("code", errors.error?.errorCode ?: CODE_GENERIC_API_ERROR).put(
"message",
errors.error?.message
?: "HTTP error! status: ${parentResponse.raw().code} ${parentResponse.raw().message}",
),
)
}
}
} catch (e: SocketTimeoutException) {
networkCallback.onError(
JSONObject().put("code", CODE_TIMED_OUT).put("message", ERROR_MESSAGE_TIMED_OUT),
)
} catch (e: Exception) {
networkCallback.onError(
JSONObject().put("code", CODE_GENERIC_API_ERROR)
.put("message", ERROR_MESSAGE_SERVICE_NOT_AVAILABLE),
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.keyvalue.siren.androidsdk.data.service

import com.keyvalue.siren.androidsdk.data.model.UnViewedNotificationResponse
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Path

interface NotificationApiService {
@GET("api/v2/in-app/recipients/{inAppRecipientId}")
suspend fun fetchUnViewedNotificationsCount(
@Path("inAppRecipientId") id: String,
@Header("Authorization") token: String,
): Response<UnViewedNotificationResponse>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.keyvalue.siren.androidsdk.data.state

import com.keyvalue.siren.androidsdk.data.model.UnViewedNotificationResponseData
import org.json.JSONObject

class NotificationUnViewedState(
var errorResponse: JSONObject? = null,
var notificationUnViewedResponse: UnViewedNotificationResponseData? = null,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.keyvalue.siren.androidsdk.presenter

import com.keyvalue.siren.androidsdk.data.managers.NotificationManager
import com.keyvalue.siren.androidsdk.data.model.UnViewedNotificationResponseData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.json.JSONObject

class NotificationPresenter(
private var userToken: String,
private var recipientId: String,
) : BasePresenter() {
private var notificationManager: NotificationManager? = null

init {
notificationManager = NotificationManager(baseURL)
}

fun fetchUnViewedNotificationsCount(callback: (UnViewedNotificationResponseData?, JSONObject?, Boolean) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
notificationManager?.fetchUnViewedNotificationsCount(userToken, recipientId)
notificationManager?.notificationUnViewedState?.collect { notificationUnViewedState ->
if (notificationUnViewedState?.errorResponse == null) {
notificationUnViewedState?.notificationUnViewedResponse?.let { response ->
callback(
response,
null,
false,
)
}
} else {
callback(
null,
notificationUnViewedState.errorResponse,
true,
)
}
}
}
}
}