Commit 09ddf787 by Aleksandr Tamakov

Request notification permission

parent d88818dd
......@@ -7,6 +7,7 @@
android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
......
package com.isidroid.c23.domain.use_case
import android.content.Context
import androidx.core.app.ActivityCompat
import com.isidroid.c23.ext.hasNotificationPermission
import com.isidroid.spot.model.RichSpot
import com.isidroid.spot.repository.ActiveSpotRepository
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.flow
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class ContentUseCase @Inject constructor(private val activeSpotRepository: ActiveSpotRepository) {
class ContentUseCase @Inject constructor(
@ApplicationContext private val context: Context,
private val activeSpotRepository: ActiveSpotRepository
) {
fun create() = flow {
val spot = activeSpotRepository.getDefaultSpot()
emit(spot)
val hasNotificationPermission = context.hasNotificationPermission.takeIf { spot != null }
emit(Pair(spot, hasNotificationPermission))
}
}
\ No newline at end of file
package com.isidroid.c23.ext
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.compose.ui.graphics.Color
import androidx.core.content.ContextCompat
import com.isidroid.c23.BuildConfig
import com.isidroid.c23.constant.AppBuildType
import com.isidroid.c23.data.source.settings.Settings
......@@ -20,4 +25,10 @@ fun randomColor(): Color {
blue = random.nextFloat(),
alpha = 1.0f
)
}
\ No newline at end of file
}
val Context.hasNotificationPermission: Boolean
get() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) return true
return ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
}
\ No newline at end of file
......@@ -30,7 +30,7 @@ internal fun TopAppBarComponent(
) {
CenterAlignedTopAppBar(
actions = actions,
modifier = modifier.height(64.dp),
modifier = modifier,
title = {
Text(
text = text,
......
......@@ -11,24 +11,26 @@ class ContentContract {
data class PickContent(val photo: Boolean = false, val documents: Boolean = false, val word: Boolean = false) : Event
data class MultipleContents(val uris: List<Uri>) : Event
data class OpenMap(val lat: Double? = null, val lng: Double? = null, val spotCode: String? = null) : Event
data object GoBack: Event
data object ToPrintJobList: Event
data object GoBack : Event
data object ToPrintJobList : Event
data object CheckNotificationPermission : Event
}
sealed interface Effect : ViewSideEffect {
sealed interface Navigation : Effect {
data class ToRenderPreview(val uris: String) : Navigation
data class ToMap(val lat: Double? = null, val lng: Double? = null, val spotId: String? = null) : Navigation
data object ToBack: Navigation
data object ToPrintJobList: Navigation
data object ToBack : Navigation
data object ToPrintJobList : Navigation
}
}
data class State(
val hasNotificationPermission: Boolean? = null,
val galleryHash: String? = null,
val documentHash: String? = null,
val wordHash: String? = null,
val richSpot: RichSpot? = null
val richSpot: RichSpot? = null,
) : ViewState
) : ViewState
}
\ No newline at end of file
package com.isidroid.c23.ui.screen.content
import android.Manifest
import android.os.Build
import androidx.activity.compose.BackHandler
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image
......@@ -43,6 +46,7 @@ import com.isidroid.c23.ui._component.ShortOfficeInfoComponent
import com.isidroid.c23.ui._component.TopAppBarComponent
import com.isidroid.core.vm.SIDE_EFFECTS_KEY
import kotlinx.coroutines.flow.Flow
import timber.log.Timber
@OptIn(ExperimentalMaterial3Api::class)
@Composable
......@@ -57,6 +61,10 @@ fun ContentScreen(
onEventSent(ContentContract.Event.MultipleContents(uris))
}
val notificationLauncher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {
onEventSent(ContentContract.Event.CheckNotificationPermission)
}
BackHandler {
onEventSent(ContentContract.Event.GoBack)
}
......@@ -64,6 +72,7 @@ fun ContentScreen(
LaunchedEffect(state.value.galleryHash) { if (state.value.galleryHash != null) launcher.launch("image/*") }
LaunchedEffect(state.value.documentHash) { if (state.value.documentHash != null) launcher.launch("application/pdf") }
LaunchedEffect(state.value.wordHash) { if (state.value.wordHash != null) launcher.launch("application/msword") }
LaunchedEffect("not_perm_${state.value.hasNotificationPermission}") { if (state.value.hasNotificationPermission == false) notificationLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) }
LaunchedEffect(SIDE_EFFECTS_KEY) {
......
......@@ -37,6 +37,7 @@ class ContentViewModel @Inject constructor(
is ContentContract.Event.OpenMap -> setEffect { ContentContract.Effect.Navigation.ToMap(event.lat, event.lng, event.spotCode) }
ContentContract.Event.GoBack -> setEffect { ContentContract.Effect.Navigation.ToBack }
ContentContract.Event.ToPrintJobList -> setEffect { ContentContract.Effect.Navigation.ToPrintJobList }
ContentContract.Event.CheckNotificationPermission -> setState { copy(hasNotificationPermission = null) }
}
}
......@@ -49,11 +50,13 @@ class ContentViewModel @Inject constructor(
}
private suspend fun create() {
useCase.create().flowOn(Dispatchers.IO).collect { data ->
useCase.create().flowOn(Dispatchers.IO).collect {
val (data, hasPermission) = it
if (data == null)
setEffect { ContentContract.Effect.Navigation.ToMap() }
else
setState { copy(richSpot = data) }
setState { copy(richSpot = data, hasNotificationPermission = hasPermission) }
}
}
}
\ No newline at end of file
......@@ -12,6 +12,7 @@ import com.isidroid.job_sender.ext.createRenderItems
import com.isidroid.job_sender.ext.decreaseCounter
import com.isidroid.rendering.repository.RenderRepository
import com.isidroid.spot.repository.SpotRepository
import kotlinx.coroutines.delay
import timber.log.Timber
internal class JobSendRepositoryImpl(
......@@ -57,6 +58,8 @@ internal class JobSendRepositoryImpl(
for ((index, item) in items.withIndex()) {
eventCollector.updateProgress(index, total)
delay(10_000)
try {
val uploadResult = sendJobNetworkSource.uploadPage(jobId = item.printJobId, token = item.accessToken, filePath = item.sourceFile)
if (!uploadResult)
......@@ -80,7 +83,6 @@ internal class JobSendRepositoryImpl(
printJobRepository.updateJobStatus(status = JobStatus.UPLOAD_ERROR, *failedJobIds.toTypedArray())
val successJobs = printJobRepository.readLocalList(ids = successJobIds.toList())
println("failedJobIds=$failedJobIds")
val failedJobs = printJobRepository.readLocalList(ids = failedJobIds.toList())
// notify event emitters
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment