diff --git a/app/src/main/java/com/github/nullptroma/wallenc/app/MainActivity.kt b/app/src/main/java/com/github/nullptroma/wallenc/app/MainActivity.kt index 5c5b7de..328b18c 100644 --- a/app/src/main/java/com/github/nullptroma/wallenc/app/MainActivity.kt +++ b/app/src/main/java/com/github/nullptroma/wallenc/app/MainActivity.kt @@ -2,11 +2,13 @@ package com.github.nullptroma.wallenc.app import android.Manifest import android.content.pm.PackageManager +import android.content.Intent import android.os.Build import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge +import androidx.compose.runtime.mutableIntStateOf import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import com.github.nullptroma.wallenc.app.auth.YandexSignInService @@ -22,6 +24,8 @@ class MainActivity : ComponentActivity() { @Inject lateinit var yandexSignInService: YandexSignInService + private val openTaskPipelineFromNotification = mutableIntStateOf(0) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) yandexSignInService.registerWith(this) @@ -30,11 +34,27 @@ class MainActivity : ComponentActivity() { Timber.plant(Timber.DebugTree()) + consumeOpenTaskPipelineIntent(intent) + setContent { - WallencUi() + WallencUi( + taskPipelineOpenRequestCount = openTaskPipelineFromNotification.intValue, + ) } } + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + consumeOpenTaskPipelineIntent(intent) + } + + private fun consumeOpenTaskPipelineIntent(intent: Intent?) { + if (intent?.getBooleanExtra(EXTRA_OPEN_TASK_PIPELINE, false) != true) return + intent.removeExtra(EXTRA_OPEN_TASK_PIPELINE) + openTaskPipelineFromNotification.intValue += 1 + } + override fun onDestroy() { yandexSignInService.unregister(this) super.onDestroy() @@ -55,6 +75,9 @@ class MainActivity : ComponentActivity() { } companion object { + const val EXTRA_OPEN_TASK_PIPELINE = + "com.github.nullptroma.wallenc.app.EXTRA_OPEN_TASK_PIPELINE" + private const val NOTIFICATION_PERMISSION_REQUEST_CODE = 100 } } diff --git a/app/src/main/java/com/github/nullptroma/wallenc/app/tasks/TaskPipelineForegroundService.kt b/app/src/main/java/com/github/nullptroma/wallenc/app/tasks/TaskPipelineForegroundService.kt index 912c0ec..51fa12c 100644 --- a/app/src/main/java/com/github/nullptroma/wallenc/app/tasks/TaskPipelineForegroundService.kt +++ b/app/src/main/java/com/github/nullptroma/wallenc/app/tasks/TaskPipelineForegroundService.kt @@ -11,6 +11,7 @@ import android.os.IBinder import android.view.View import android.widget.RemoteViews import androidx.core.app.NotificationCompat +import com.github.nullptroma.wallenc.app.MainActivity import com.github.nullptroma.wallenc.app.R import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator import com.github.nullptroma.wallenc.domain.tasks.TaskForegroundItem @@ -142,6 +143,7 @@ class TaskPipelineForegroundService : Service() { .setSmallIcon(android.R.drawable.stat_sys_download) .setOngoing(true) .setOnlyAlertOnce(true) + .setContentIntent(openTaskPipelinePendingIntent()) .addAction( 0, getString(R.string.task_notification_cancel), @@ -175,6 +177,7 @@ class TaskPipelineForegroundService : Service() { .setSmallIcon(android.R.drawable.stat_sys_download) .setOngoing(true) .setOnlyAlertOnce(true) + .setContentIntent(openTaskPipelinePendingIntent()) .setStyle(NotificationCompat.DecoratedCustomViewStyle()) .setCustomBigContentView(big) .addAction( @@ -185,6 +188,17 @@ class TaskPipelineForegroundService : Service() { .build() } + private fun openTaskPipelinePendingIntent(): PendingIntent = + PendingIntent.getActivity( + this, + REQUEST_CODE_OPEN_TASK_PIPELINE, + Intent(this, MainActivity::class.java).apply { + putExtra(MainActivity.EXTRA_OPEN_TASK_PIPELINE, true) + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP + }, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, + ) + private fun cancelAllTasksPendingIntent(): PendingIntent = PendingIntent.getService( this, @@ -323,6 +337,8 @@ class TaskPipelineForegroundService : Service() { private const val ACTION_CANCEL_ALL_TASKS = "com.github.nullptroma.wallenc.action.CANCEL_ALL_TASKS" + private const val REQUEST_CODE_OPEN_TASK_PIPELINE = 2 + private const val CHANNEL_ID = "wallenc_task_pipeline" private const val FOREGROUND_NOTIFICATION_ID = 1001 diff --git a/ui/src/main/java/com/github/nullptroma/wallenc/ui/WallencUi.kt b/ui/src/main/java/com/github/nullptroma/wallenc/ui/WallencUi.kt index 1612efd..97a0d49 100644 --- a/ui/src/main/java/com/github/nullptroma/wallenc/ui/WallencUi.kt +++ b/ui/src/main/java/com/github/nullptroma/wallenc/ui/WallencUi.kt @@ -17,6 +17,7 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier @@ -39,17 +40,20 @@ import com.github.nullptroma.wallenc.ui.theme.WallencTheme @Composable -fun WallencUi() { +fun WallencUi(taskPipelineOpenRequestCount: Int = 0) { WallencTheme { Surface { - WallencNavRoot() + WallencNavRoot(taskPipelineOpenRequestCount = taskPipelineOpenRequestCount) } } } @OptIn(ExperimentalMaterial3Api::class) @Composable -fun WallencNavRoot(viewModel: WallencViewModel = hiltViewModel()) { +fun WallencNavRoot( + viewModel: WallencViewModel = hiltViewModel(), + taskPipelineOpenRequestCount: Int = 0, +) { val navState = rememberNavigationState() val mainNavState = rememberNavigationState() @@ -58,6 +62,12 @@ fun WallencNavRoot(viewModel: WallencViewModel = hiltViewModel()) { val topLevelRoutes = viewModel.routes + LaunchedEffect(taskPipelineOpenRequestCount) { + if (taskPipelineOpenRequestCount <= 0) return@LaunchedEffect + val route = topLevelRoutes[TaskPipelineRoute::class.qualifiedName!!] ?: return@LaunchedEffect + navState.changeTop(route) + } + val topLevelNavBarItems = remember { mapOf( MainRoute::class.qualifiedName!! to NavBarItemData(