diff --git a/feature/alert/build.gradle.kts b/feature/alert/build.gradle.kts index f4b79165a3..e53fcc2e66 100644 --- a/feature/alert/build.gradle.kts +++ b/feature/alert/build.gradle.kts @@ -9,4 +9,5 @@ android { dependencies { implementation(project(":infra:events")) + implementation(project(":infra:auth-store")) } diff --git a/feature/alert/src/main/java/com/simprints/feature/alert/screen/AlertFragment.kt b/feature/alert/src/main/java/com/simprints/feature/alert/screen/AlertFragment.kt index 4a7312aa74..917015bb7d 100644 --- a/feature/alert/src/main/java/com/simprints/feature/alert/screen/AlertFragment.kt +++ b/feature/alert/src/main/java/com/simprints/feature/alert/screen/AlertFragment.kt @@ -3,6 +3,7 @@ package com.simprints.feature.alert.screen import android.os.Bundle import android.view.View import android.widget.TextView +import android.widget.Toast import androidx.activity.addCallback import androidx.core.content.res.ResourcesCompat import androidx.core.view.isVisible @@ -20,6 +21,7 @@ import com.simprints.feature.alert.databinding.FragmentAlertBinding import com.simprints.infra.logging.LoggingConstants.CrashReportTag.ALERT import com.simprints.infra.logging.Simber import com.simprints.infra.uibase.navigation.setResult +import com.simprints.infra.uibase.system.Clipboard import com.simprints.infra.uibase.view.setTextWithFallbacks import com.simprints.infra.uibase.viewbinding.viewBinding import dagger.hilt.android.AndroidEntryPoint @@ -61,6 +63,7 @@ internal class AlertFragment : Fragment(R.layout.fragment_alert) { binding.alertRightButton.setupButton(config.rightButton, config.appErrorReason) } + requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) { Simber.tag(ALERT.name).i("Alert back button clicked") setPressedButtonResult(AlertContract.ALERT_BUTTON_PRESSED_BACK, config.appErrorReason) @@ -68,6 +71,11 @@ internal class AlertFragment : Fragment(R.layout.fragment_alert) { } config.eventType?.let { vm.saveAlertEvent(it) } + binding.alertExportButton.setOnClickListener { + Clipboard.copyToClipboard(requireContext(), vm.collectExportData()) + Toast.makeText(requireContext(), IDR.string.alert_export_copied, Toast.LENGTH_SHORT).show() + } + Simber.tag(ALERT.name).i("${binding.alertTitle.text}") } diff --git a/feature/alert/src/main/java/com/simprints/feature/alert/screen/AlertViewModel.kt b/feature/alert/src/main/java/com/simprints/feature/alert/screen/AlertViewModel.kt index 0a2455a4b1..fd30e0b84a 100644 --- a/feature/alert/src/main/java/com/simprints/feature/alert/screen/AlertViewModel.kt +++ b/feature/alert/src/main/java/com/simprints/feature/alert/screen/AlertViewModel.kt @@ -1,25 +1,49 @@ package com.simprints.feature.alert.screen import androidx.lifecycle.ViewModel +import com.simprints.core.DeviceID import com.simprints.core.ExternalScope import com.simprints.core.tools.time.TimeHelper +import com.simprints.infra.authstore.AuthStore import com.simprints.infra.events.SessionEventRepository import com.simprints.infra.events.event.domain.models.AlertScreenEvent import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import javax.inject.Inject @HiltViewModel internal class AlertViewModel @Inject constructor( + @DeviceID private val deviceId: String, private val timeHelper: TimeHelper, private val eventRepository: SessionEventRepository, - @ExternalScope private val ioScope: CoroutineScope, + private val authStore: AuthStore, + @ExternalScope private val externalScope: CoroutineScope, ) : ViewModel() { + private lateinit var cachedAlertEvent: AlertScreenEvent + fun saveAlertEvent(type: AlertScreenEvent.AlertScreenPayload.AlertScreenEventType) { - ioScope.launch { - eventRepository.addOrUpdateEvent(AlertScreenEvent(timeHelper.now(), type)) + externalScope.launch { + val event = AlertScreenEvent(timeHelper.now(), type) + eventRepository.addOrUpdateEvent(event) + // Preserving the alert event to be able to export its data if requested by user + cachedAlertEvent = event } } + + fun collectExportData(): String = runBlocking { + val sessionId = eventRepository.getCurrentSessionScope().id + + """ + Event ID: ${cachedAlertEvent.id} + Timestamp: ${cachedAlertEvent.payload.createdAt.ms} + Project ID: ${authStore.signedInProjectId} + User ID: ${authStore.signedInUserId?.value} + Device ID: $deviceId + Session ID: $sessionId + Alert type: ${cachedAlertEvent.payload.alertType} + """.trimIndent() + } } diff --git a/feature/alert/src/main/res/layout/fragment_alert.xml b/feature/alert/src/main/res/layout/fragment_alert.xml index db5477df44..bc303cf315 100644 --- a/feature/alert/src/main/res/layout/fragment_alert.xml +++ b/feature/alert/src/main/res/layout/fragment_alert.xml @@ -6,6 +6,26 @@ android:layout_height="match_parent" android:background="@color/simprints_blue"> + + + + diff --git a/infra/resources/src/main/res/values/strings.xml b/infra/resources/src/main/res/values/strings.xml index 9962aa2a50..495f955cd1 100644 --- a/infra/resources/src/main/res/values/strings.xml +++ b/infra/resources/src/main/res/values/strings.xml @@ -4,6 +4,8 @@ Alert Close + Copy details + Copied data to clipboard General Consent