diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6202b8df..e9e2e707 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -101,7 +101,6 @@ dependencies { ksp(libs.androidx.room.compiler) implementation(libs.compose.charts) - implementation(libs.play.services.ads) implementation(project(":compose-cardstack")) diff --git a/app/src/main/java/com/pwhs/quickmem/App.kt b/app/src/main/java/com/pwhs/quickmem/App.kt index 947f4841..0ef74e71 100644 --- a/app/src/main/java/com/pwhs/quickmem/App.kt +++ b/app/src/main/java/com/pwhs/quickmem/App.kt @@ -6,7 +6,7 @@ import com.onesignal.OneSignal import com.onesignal.debug.LogLevel as OneSignalLogLevel import com.pwhs.quickmem.core.datastore.AppManager import com.pwhs.quickmem.core.datastore.TokenManager -import com.pwhs.quickmem.data.dto.notification.TokenRequestDto +import com.pwhs.quickmem.data.dto.notification.DeviceTokenRequestDto import com.pwhs.quickmem.data.remote.ApiService import com.revenuecat.purchases.LogLevel as RevenueCatLogLevel import com.revenuecat.purchases.Purchases @@ -78,7 +78,7 @@ class App : Application() { val accessToken = tokenManager.accessToken.firstOrNull() ?: "" val userId = appManager.userId.firstOrNull() ?: "" try { - apiService.sendDeviceToken(accessToken, TokenRequestDto(userId, token)) + apiService.sendDeviceToken(accessToken, DeviceTokenRequestDto(userId, token)) Timber.d("Token sent to server successfully.") } catch (e: Exception) { Timber.e(e, "Error sending token to server") diff --git a/app/src/main/java/com/pwhs/quickmem/core/data/enums/NotificationType.kt b/app/src/main/java/com/pwhs/quickmem/core/data/enums/NotificationType.kt new file mode 100644 index 00000000..3d51ab61 --- /dev/null +++ b/app/src/main/java/com/pwhs/quickmem/core/data/enums/NotificationType.kt @@ -0,0 +1,6 @@ +package com.pwhs.quickmem.core.data.enums + +enum class NotificationType(val type: String) { + INVITE_USER_JOIN_CLASS("INVITE_USER_JOIN_CLASS"), + NONE("NONE"), +} \ No newline at end of file diff --git a/app/src/main/java/com/pwhs/quickmem/core/service/AppFirebaseMessagingService.kt b/app/src/main/java/com/pwhs/quickmem/core/service/AppFirebaseMessagingService.kt index a00ab904..b7a2d68b 100644 --- a/app/src/main/java/com/pwhs/quickmem/core/service/AppFirebaseMessagingService.kt +++ b/app/src/main/java/com/pwhs/quickmem/core/service/AppFirebaseMessagingService.kt @@ -7,13 +7,14 @@ import android.content.Intent import android.os.Build.VERSION.SDK_INT import android.os.Build.VERSION_CODES import androidx.core.app.NotificationCompat +import androidx.core.net.toUri import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import com.pwhs.quickmem.MainActivity import com.pwhs.quickmem.R import com.pwhs.quickmem.core.datastore.AppManager import com.pwhs.quickmem.core.datastore.TokenManager -import com.pwhs.quickmem.data.dto.notification.TokenRequestDto +import com.pwhs.quickmem.data.dto.notification.DeviceTokenRequestDto import com.pwhs.quickmem.data.remote.ApiService import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -42,7 +43,7 @@ class AppFirebaseMessagingService : FirebaseMessagingService() { val accessToken = tokenManager.accessToken.firstOrNull() ?: "" val userId = appManager.userId.firstOrNull() ?: "" try { - apiService.sendDeviceToken(accessToken, TokenRequestDto(userId, token)) + apiService.sendDeviceToken(accessToken, DeviceTokenRequestDto(userId, token)) Timber.d("Token sent to server successfully.") } catch (e: Exception) { Timber.e(e, "Error sending token to server") @@ -54,23 +55,38 @@ class AppFirebaseMessagingService : FirebaseMessagingService() { override fun onMessageReceived(remoteMessage: RemoteMessage) { Timber.d("From: ${remoteMessage.from}") + remoteMessage.notification?.title?.let { Timber.d("Notification Title: $it") } + remoteMessage.notification?.body?.let { Timber.d("Notification Body: $it") } + remoteMessage.data.isNotEmpty() + .let { Timber.d("Message data payload: ${remoteMessage.data}") } CoroutineScope(Dispatchers.IO).launch { val isPushNotificationsEnabled = appManager.pushNotifications.firstOrNull() ?: false if (isPushNotificationsEnabled) { remoteMessage.notification?.let { - showNotification(it.title, it.body) + showNotification(it.title, it.body, remoteMessage.data) } } } } - private fun showNotification(title: String?, body: String?) { + private fun showNotification(title: String?, body: String?, data: Map) { val channelId = "QuickMem Channel" val notificationId = 0 - val intent = Intent(this, MainActivity::class.java).apply { - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + val notificationType = data["notificationType"] + val classCode = data["code"] + + val intent = if (notificationType == "INVITE_USER_JOIN_CLASS" && classCode != null) { + Intent( + Intent.ACTION_VIEW, + "quickmem://join/class?code=$classCode".toUri() + ) + } else { + Intent(this, MainActivity::class.java).apply { + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + } } + val pendingIntent = PendingIntent.getActivity( this, 0, diff --git a/app/src/main/java/com/pwhs/quickmem/data/dto/notification/TokenRequestDto.kt b/app/src/main/java/com/pwhs/quickmem/data/dto/notification/DeviceTokenRequestDto.kt similarity index 86% rename from app/src/main/java/com/pwhs/quickmem/data/dto/notification/TokenRequestDto.kt rename to app/src/main/java/com/pwhs/quickmem/data/dto/notification/DeviceTokenRequestDto.kt index 8a925029..8519d576 100644 --- a/app/src/main/java/com/pwhs/quickmem/data/dto/notification/TokenRequestDto.kt +++ b/app/src/main/java/com/pwhs/quickmem/data/dto/notification/DeviceTokenRequestDto.kt @@ -2,7 +2,7 @@ package com.pwhs.quickmem.data.dto.notification import com.google.gson.annotations.SerializedName -data class TokenRequestDto( +data class DeviceTokenRequestDto( @SerializedName("userId") val userId: String, @SerializedName("deviceToken") diff --git a/app/src/main/java/com/pwhs/quickmem/data/dto/notification/GetNotificationResponseDto.kt b/app/src/main/java/com/pwhs/quickmem/data/dto/notification/GetNotificationResponseDto.kt index c585b67a..8e4c7b1f 100644 --- a/app/src/main/java/com/pwhs/quickmem/data/dto/notification/GetNotificationResponseDto.kt +++ b/app/src/main/java/com/pwhs/quickmem/data/dto/notification/GetNotificationResponseDto.kt @@ -1,6 +1,7 @@ package com.pwhs.quickmem.data.dto.notification import com.google.gson.annotations.SerializedName +import com.pwhs.quickmem.core.data.enums.NotificationType data class GetNotificationResponseDto( @SerializedName("id") @@ -13,6 +14,10 @@ data class GetNotificationResponseDto( val userId: String, @SerializedName("isRead") val isRead: Boolean, + @SerializedName("notificationType") + val notificationType: NotificationType? = NotificationType.NONE, + @SerializedName("data") + val data: NotificationDataDto? = null, @SerializedName("createdAt") val createdAt: String, @SerializedName("updatedAt") diff --git a/app/src/main/java/com/pwhs/quickmem/data/dto/notification/NotificationDataDto.kt b/app/src/main/java/com/pwhs/quickmem/data/dto/notification/NotificationDataDto.kt new file mode 100644 index 00000000..e0db1034 --- /dev/null +++ b/app/src/main/java/com/pwhs/quickmem/data/dto/notification/NotificationDataDto.kt @@ -0,0 +1,10 @@ +package com.pwhs.quickmem.data.dto.notification + +import com.google.gson.annotations.SerializedName + +data class NotificationDataDto( + @SerializedName("id") + val id: String? = null, + @SerializedName("code") + val code: String? = null, +) diff --git a/app/src/main/java/com/pwhs/quickmem/data/mapper/notification/GetNotificationResponseMapper.kt b/app/src/main/java/com/pwhs/quickmem/data/mapper/notification/GetNotificationResponseMapper.kt index d3b7b88e..553769b9 100644 --- a/app/src/main/java/com/pwhs/quickmem/data/mapper/notification/GetNotificationResponseMapper.kt +++ b/app/src/main/java/com/pwhs/quickmem/data/mapper/notification/GetNotificationResponseMapper.kt @@ -10,7 +10,9 @@ fun GetNotificationResponseDto.toModel() = GetNotificationResponseModel( userId = userId, isRead = isRead, createdAt = createdAt, - updatedAt = updatedAt + updatedAt = updatedAt, + notificationType = notificationType, + data = data?.toModel() ) fun GetNotificationResponseModel.toDto() = GetNotificationResponseDto( @@ -20,5 +22,7 @@ fun GetNotificationResponseModel.toDto() = GetNotificationResponseDto( userId = userId, isRead = isRead, createdAt = createdAt, - updatedAt = updatedAt + updatedAt = updatedAt, + notificationType = notificationType, + data = data?.toDto() ) diff --git a/app/src/main/java/com/pwhs/quickmem/data/mapper/notification/NotificationDataMapper.kt b/app/src/main/java/com/pwhs/quickmem/data/mapper/notification/NotificationDataMapper.kt new file mode 100644 index 00000000..5a5903a5 --- /dev/null +++ b/app/src/main/java/com/pwhs/quickmem/data/mapper/notification/NotificationDataMapper.kt @@ -0,0 +1,14 @@ +package com.pwhs.quickmem.data.mapper.notification + +import com.pwhs.quickmem.data.dto.notification.NotificationDataDto +import com.pwhs.quickmem.domain.model.notification.NotificationDataModel + +fun NotificationDataDto.toModel() = NotificationDataModel( + id = id, + code = code +) + +fun NotificationDataModel.toDto() = NotificationDataDto( + id = id, + code = code +) \ No newline at end of file diff --git a/app/src/main/java/com/pwhs/quickmem/data/remote/ApiService.kt b/app/src/main/java/com/pwhs/quickmem/data/remote/ApiService.kt index a7b66786..cd27dad4 100644 --- a/app/src/main/java/com/pwhs/quickmem/data/remote/ApiService.kt +++ b/app/src/main/java/com/pwhs/quickmem/data/remote/ApiService.kt @@ -57,7 +57,7 @@ import com.pwhs.quickmem.data.dto.folder.UpdateFolderRequestDto import com.pwhs.quickmem.data.dto.folder.UpdateFolderResponseDto import com.pwhs.quickmem.data.dto.notification.GetNotificationResponseDto import com.pwhs.quickmem.data.dto.notification.MarkNotificationReadRequestDto -import com.pwhs.quickmem.data.dto.notification.TokenRequestDto +import com.pwhs.quickmem.data.dto.notification.DeviceTokenRequestDto import com.pwhs.quickmem.data.dto.flashcard.WriteStatusFlashCardDto import com.pwhs.quickmem.data.dto.streak.GetStreakDto import com.pwhs.quickmem.data.dto.streak.GetTopStreakResponseDto @@ -564,7 +564,7 @@ interface ApiService { @POST("notifications/register") suspend fun sendDeviceToken( @Header("Authorization") authorization: String, - @Body tokenRequest: TokenRequestDto + @Body tokenRequest: DeviceTokenRequestDto ): Response @GET("notifications/user/{id}") diff --git a/app/src/main/java/com/pwhs/quickmem/domain/model/notification/GetNotificationResponseModel.kt b/app/src/main/java/com/pwhs/quickmem/domain/model/notification/GetNotificationResponseModel.kt index 57412118..fc807eb6 100644 --- a/app/src/main/java/com/pwhs/quickmem/domain/model/notification/GetNotificationResponseModel.kt +++ b/app/src/main/java/com/pwhs/quickmem/domain/model/notification/GetNotificationResponseModel.kt @@ -1,10 +1,14 @@ package com.pwhs.quickmem.domain.model.notification +import com.pwhs.quickmem.core.data.enums.NotificationType + data class GetNotificationResponseModel( val id: String, val title: String, val message: String, val userId: String, + val notificationType: NotificationType? = NotificationType.NONE, + val data: NotificationDataModel? = null, val isRead: Boolean, val createdAt: String, val updatedAt: String diff --git a/app/src/main/java/com/pwhs/quickmem/domain/model/notification/NotificationDataModel.kt b/app/src/main/java/com/pwhs/quickmem/domain/model/notification/NotificationDataModel.kt new file mode 100644 index 00000000..eefc9933 --- /dev/null +++ b/app/src/main/java/com/pwhs/quickmem/domain/model/notification/NotificationDataModel.kt @@ -0,0 +1,6 @@ +package com.pwhs.quickmem.domain.model.notification + +data class NotificationDataModel( + val id: String? = null, + val code: String? = null, +) \ No newline at end of file diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/DeepLinkScreen.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/DeepLinkScreen.kt index 748d9f1b..159e1d42 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/DeepLinkScreen.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/DeepLinkScreen.kt @@ -2,7 +2,6 @@ package com.pwhs.quickmem.presentation.app.deeplink import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.ui.Modifier import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootGraph import com.ramcosta.composedestinations.annotation.parameters.DeepLink @@ -11,10 +10,7 @@ import com.ramcosta.composedestinations.generated.destinations.JoinClassScreenDe import com.ramcosta.composedestinations.generated.destinations.LoadFolderScreenDestination import com.ramcosta.composedestinations.generated.destinations.LoadStudySetScreenDestination import com.ramcosta.composedestinations.navigation.DestinationsNavigator -import timber.log.Timber -//Deeplink for receiving code from class, folder, study set -//TODO: Implement this screen @Destination( deepLinks = [ DeepLink(uriPattern = "quickmem://join/class?code={classCode}"), @@ -24,20 +20,18 @@ import timber.log.Timber ) @Composable fun DeepLinkScreen( - modifier: Modifier = Modifier, studySetCode: String? = null, folderCode: String? = null, classCode: String? = null, navigator: DestinationsNavigator, ) { - Timber.d("DeepLinkScreen: studySetCode: $studySetCode, folderCode: $folderCode, classCode: $classCode") LaunchedEffect(key1 = true) { when { classCode != null -> { navigator.navigate( JoinClassScreenDestination( code = classCode, - type = "class" + isFromDeepLink = true ) ) { popUpTo(NavGraphs.root) { @@ -51,7 +45,6 @@ fun DeepLinkScreen( folderCode != null -> { navigator.navigate( LoadFolderScreenDestination( - type = "folder", folderCode = folderCode ) ) { @@ -66,7 +59,6 @@ fun DeepLinkScreen( studySetCode != null -> { navigator.navigate( LoadStudySetScreenDestination( - type = "studySet", studySetCode = studySetCode ) ) { diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassArgs.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassArgs.kt index a189acab..22d5fab5 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassArgs.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassArgs.kt @@ -1,6 +1,7 @@ package com.pwhs.quickmem.presentation.app.deeplink.classes + data class JoinClassArgs( val code: String, - val type: String + val isFromDeepLink: Boolean ) \ No newline at end of file diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassScreen.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassScreen.kt index 09703f19..8372b9cf 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassScreen.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassScreen.kt @@ -9,7 +9,7 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Home +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material3.Button import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material3.ExperimentalMaterial3Api @@ -69,6 +69,9 @@ fun JoinClassScreen( viewModel.uiEvent.collect { event -> when (event) { is JoinClassUiEvent.JoinedClass -> { + if (!uiState.isFromDeepLink) { + navigator.navigateUp() + } navigator.navigate( ClassDetailScreenDestination( id = event.id, @@ -76,11 +79,13 @@ fun JoinClassScreen( description = event.description ) ) { - popUpTo(NavGraphs.root) { - saveState = false + if (uiState.isFromDeepLink) { + popUpTo(NavGraphs.root) { + saveState = false + } + launchSingleTop = true + restoreState = false } - launchSingleTop = true - restoreState = false } } @@ -156,7 +161,7 @@ fun JoinClass( onClick = onBackHome ) { Icon( - imageVector = Icons.Default.Home, + imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back", tint = Color.Gray.copy(alpha = 0.6f) ) diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassUiState.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassUiState.kt index d5cbde04..7687b5e2 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassUiState.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassUiState.kt @@ -8,6 +8,6 @@ data class JoinClassUiState( val classId: String? = null, val isUnAuthorized: Boolean = false, val code: String? = null, - val type: String? = null, + val isFromDeepLink: Boolean = false, val classDetailResponseModel: GetClassDetailResponseModel? = null ) \ No newline at end of file diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassViewModel.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassViewModel.kt index ab746cf3..2f18b178 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassViewModel.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/classes/JoinClassViewModel.kt @@ -34,15 +34,12 @@ class JoinClassViewModel @Inject constructor( val uiEvent = _uiEvent.receiveAsFlow() init { - val code = savedStateHandle.get("code") - val type = savedStateHandle.get("type") - - Timber.d("JoinClassViewModel: code: $code, type: $type") - + val code = savedStateHandle.get("code") ?: "" + val isFromDeepLink = savedStateHandle.get("isFromDeepLink") ?: false _uiState.update { it.copy( code = code, - type = type + isFromDeepLink = isFromDeepLink ) } @@ -85,6 +82,14 @@ class JoinClassViewModel @Inject constructor( is Resources.Success -> { if (resource.data?.owner?.id == userId || resource.data?.isJoined == true) { + _uiState.update { + it.copy( + classDetailResponseModel = resource.data, + isLoading = false, + userId = userId, + classId = resource.data.id + ) + } _uiEvent.send( JoinClassUiEvent.JoinedClass( id = resource.data.id, diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/folder/LoadFolderArgs.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/folder/LoadFolderArgs.kt index 6b738cff..a8b214c6 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/folder/LoadFolderArgs.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/folder/LoadFolderArgs.kt @@ -1,6 +1,6 @@ package com.pwhs.quickmem.presentation.app.deeplink.folder + data class LoadFolderArgs( val folderCode: String, - val type: String ) \ No newline at end of file diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/folder/LoadFolderUiState.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/folder/LoadFolderUiState.kt index 29ac10b3..138eb39e 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/folder/LoadFolderUiState.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/folder/LoadFolderUiState.kt @@ -2,7 +2,6 @@ package com.pwhs.quickmem.presentation.app.deeplink.folder data class LoadFolderUiState( val folderCode: String = "", - val type: String = "", val isLoading: Boolean = true, val folderId: String? = null ) \ No newline at end of file diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/folder/LoadFolderViewModel.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/folder/LoadFolderViewModel.kt index 5ffd6f0c..88902336 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/folder/LoadFolderViewModel.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/folder/LoadFolderViewModel.kt @@ -30,12 +30,10 @@ class LoadFolderViewModel @Inject constructor( init { val folderCode = saveStateHandle.get("folderCode") ?: "" - val type = saveStateHandle.get("type") ?: "" _uiState.update { it.copy( folderCode = folderCode, - type = type ) } loadFolder() @@ -44,10 +42,9 @@ class LoadFolderViewModel @Inject constructor( private fun loadFolder() { viewModelScope.launch { val folderCode = uiState.value.folderCode - val type = uiState.value.type val token = tokenManager.accessToken.firstOrNull() - if (folderCode.isEmpty() || type.isEmpty() || token == null) { + if (folderCode.isEmpty() || token == null) { _uiEvent.send(LoadFolderUiEvent.UnAuthorized) return@launch } diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/study_set/LoadStudySetArgs.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/study_set/LoadStudySetArgs.kt index 0da55621..fcabd1e6 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/study_set/LoadStudySetArgs.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/study_set/LoadStudySetArgs.kt @@ -2,5 +2,4 @@ package com.pwhs.quickmem.presentation.app.deeplink.study_set data class LoadStudySetArgs( val studySetCode: String, - val type: String ) \ No newline at end of file diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/study_set/LoadStudySetUiState.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/study_set/LoadStudySetUiState.kt index 1f60703f..c75654d4 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/study_set/LoadStudySetUiState.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/study_set/LoadStudySetUiState.kt @@ -2,7 +2,6 @@ package com.pwhs.quickmem.presentation.app.deeplink.study_set data class LoadStudySetUiState( val studySetCode: String = "", - val type: String = "", val isLoading: Boolean = true, val studySetId: String? = null ) \ No newline at end of file diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/study_set/LoadStudySetViewModel.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/study_set/LoadStudySetViewModel.kt index 4108faac..98e148ca 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/study_set/LoadStudySetViewModel.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/deeplink/study_set/LoadStudySetViewModel.kt @@ -3,7 +3,6 @@ package com.pwhs.quickmem.presentation.app.deeplink.study_set import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.pwhs.quickmem.core.datastore.AppManager import com.pwhs.quickmem.core.datastore.TokenManager import com.pwhs.quickmem.core.utils.Resources import com.pwhs.quickmem.domain.repository.StudySetRepository @@ -31,12 +30,10 @@ class LoadStudySetViewModel @Inject constructor( init { val studySetCode = savedStateHandle.get("studySetCode") ?: "" - val type = savedStateHandle.get("type") ?: "" _uiState.update { it.copy( studySetCode = studySetCode, - type = type ) } loadStudySet() @@ -45,10 +42,9 @@ class LoadStudySetViewModel @Inject constructor( private fun loadStudySet() { viewModelScope.launch { val studySetCode = uiState.value.studySetCode - val type = uiState.value.type val token = tokenManager.accessToken.firstOrNull() - if (studySetCode.isEmpty() || type.isEmpty() || token == null) { + if (studySetCode.isEmpty() || token == null) { _uiEvent.send(LoadStudySetUiEvent.UnAuthorized) return@launch } diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/home/HomeScreen.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/home/HomeScreen.kt index e2547f13..2b0a1f56 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/home/HomeScreen.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/home/HomeScreen.kt @@ -71,6 +71,7 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.isGranted import com.google.accompanist.permissions.rememberPermissionState import com.pwhs.quickmem.R +import com.pwhs.quickmem.core.data.enums.NotificationType import com.pwhs.quickmem.domain.model.classes.GetClassByOwnerResponseModel import com.pwhs.quickmem.domain.model.folder.GetFolderResponseModel import com.pwhs.quickmem.domain.model.notification.GetNotificationResponseModel @@ -94,6 +95,7 @@ import com.ramcosta.composedestinations.annotation.RootGraph import com.ramcosta.composedestinations.generated.destinations.ClassDetailScreenDestination import com.ramcosta.composedestinations.generated.destinations.CreateStudySetScreenDestination import com.ramcosta.composedestinations.generated.destinations.FolderDetailScreenDestination +import com.ramcosta.composedestinations.generated.destinations.JoinClassScreenDestination import com.ramcosta.composedestinations.generated.destinations.SearchScreenDestination import com.ramcosta.composedestinations.generated.destinations.SearchStudySetBySubjectScreenDestination import com.ramcosta.composedestinations.generated.destinations.StudySetDetailScreenDestination @@ -162,9 +164,19 @@ fun HomeScreen( viewModel.onEvent(HomeUiAction.OnChangeCustomerInfo(customerInfo)) }, notifications = uiState.notifications, - onNotificationClicked = { notificationId -> + onMarkAsRead = { notificationId -> viewModel.onEvent(HomeUiAction.MarkAsRead(notificationId)) }, + onNotificationClick = { notification -> + if (notification.data?.id?.isNotEmpty() == true && notification.data.code?.isNotEmpty() == true && notification.notificationType == NotificationType.INVITE_USER_JOIN_CLASS) { + navigator.navigate( + JoinClassScreenDestination( + code = notification.data.code, + isFromDeepLink = false + ) + ) + } + }, onSearchStudySetBySubject = { subject -> navigator.navigate( SearchStudySetBySubjectScreenDestination( @@ -206,7 +218,8 @@ private fun Home( onClickToCreateStudySet: () -> Unit = {}, customer: CustomerInfo? = null, onCustomerInfoChanged: (CustomerInfo) -> Unit = {}, - onNotificationClicked: (String) -> Unit = {}, + onMarkAsRead: (String) -> Unit = {}, + onNotificationClick: (GetNotificationResponseModel) -> Unit = {}, notifications: List = emptyList(), onSearchStudySetBySubject: (SubjectModel) -> Unit = {}, ) { @@ -338,20 +351,7 @@ private fun Home( modifier = Modifier .align(Alignment.TopEnd) .size(16.dp), - ) { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Text( - text = "$notificationCount", - style = typography.bodySmall.copy( - fontSize = 10.sp, - fontWeight = FontWeight.Bold, - ) - ) - } - } + ) } } } @@ -626,7 +626,8 @@ private fun Home( NotificationListBottomSheet( onDismissRequest = { showNotificationBottomSheet = false }, notifications = notifications, - onNotificationClicked = onNotificationClicked, + onMarkAsRead = onMarkAsRead, + onNotificationClicked = onNotificationClick, sheetState = modalBottomSheetState ) } diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/home/components/NotificationItem.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/home/components/NotificationItem.kt index cd258819..69976e08 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/home/components/NotificationItem.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/home/components/NotificationItem.kt @@ -1,7 +1,6 @@ package com.pwhs.quickmem.presentation.app.home.components import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth @@ -30,6 +29,7 @@ import com.pwhs.quickmem.util.calculateTimeAgo fun NotificationItem( notification: GetNotificationResponseModel, onMarkAsRead: (String) -> Unit, + onNotificationClicked: (GetNotificationResponseModel) -> Unit ) { val backgroundColor = if (notification.isRead) { @@ -53,6 +53,7 @@ fun NotificationItem( if (!notification.isRead) { onMarkAsRead(notification.id) } + onNotificationClicked(notification) }, colors = CardDefaults.cardColors( containerColor = backgroundColor @@ -62,8 +63,7 @@ fun NotificationItem( Row( modifier = Modifier .fillMaxWidth() - .background(backgroundColor) - .clickable { onMarkAsRead(notification.id) }, + .background(backgroundColor), verticalAlignment = Alignment.CenterVertically ) { Column( diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/home/components/NotificationListBottomSheet.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/home/components/NotificationListBottomSheet.kt index ee8772ef..b7cb5725 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/home/components/NotificationListBottomSheet.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/home/components/NotificationListBottomSheet.kt @@ -36,7 +36,8 @@ fun NotificationListBottomSheet( onDismissRequest: () -> Unit, sheetState: SheetState, notifications: List, - onNotificationClicked: (String) -> Unit, + onMarkAsRead: (String) -> Unit, + onNotificationClicked: (GetNotificationResponseModel) -> Unit ) { ModalBottomSheet( @@ -91,8 +92,9 @@ fun NotificationListBottomSheet( NotificationItem( notification = notification, onMarkAsRead = { - onNotificationClicked(notification.id) - } + onMarkAsRead(it) + }, + onNotificationClicked = onNotificationClicked ) HorizontalDivider( modifier = Modifier.padding(horizontal = 10.dp), diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/search/SearchScreen.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/search/SearchScreen.kt index 8e771376..11da5c26 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/search/SearchScreen.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/search/SearchScreen.kt @@ -139,8 +139,7 @@ private fun Search( errorMessage = errorMessage, placeholder = stringResource(R.string.txt_study_sets_folder_classes), onSearch = onSearch, - - ) + ) }, expandedHeight = 160.dp, actions = {