From b4b500d5dd10c1a1290cc229ce0041382f658c92 Mon Sep 17 00:00:00 2001 From: Barnabas Balogh Date: Tue, 3 Mar 2026 14:15:50 +0100 Subject: [PATCH] fix: request POST_NOTIFICATIONS permission before episode downloads EpisodeScreen called viewModel.onDownloadClick() directly without first requesting the POST_NOTIFICATIONS runtime permission. On Android 13+ (API 33+), foreground service notifications are suppressed without this permission, so downloads ran silently with no notification shown. Mirrors the existing permission pattern from MovieScreen: on Android 13+ the system dialog is shown before the first download; on denial the download still proceeds (notification is nice-to-have). --- .../app/content/episode/EpisodeScreen.kt | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/hu/bbara/purefin/app/content/episode/EpisodeScreen.kt b/app/src/main/java/hu/bbara/purefin/app/content/episode/EpisodeScreen.kt index 5662076..8bc8022 100644 --- a/app/src/main/java/hu/bbara/purefin/app/content/episode/EpisodeScreen.kt +++ b/app/src/main/java/hu/bbara/purefin/app/content/episode/EpisodeScreen.kt @@ -1,5 +1,9 @@ package hu.bbara.purefin.app.content.episode +import android.Manifest +import android.os.Build +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -39,6 +43,23 @@ fun EpisodeScreen( val episode = viewModel.episode.collectAsState() val downloadState = viewModel.downloadState.collectAsState() + val notificationPermissionLauncher = rememberLauncherForActivityResult( + ActivityResultContracts.RequestPermission() + ) { _ -> + // Proceed with download regardless — notification is nice-to-have + viewModel.onDownloadClick() + } + + val onDownloadClick = { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + && downloadState.value is DownloadState.NotDownloaded + ) { + notificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) + } else { + viewModel.onDownloadClick() + } + } + if (episode.value == null) { PurefinWaitingScreen() return @@ -48,7 +69,7 @@ fun EpisodeScreen( episode = episode.value!!, downloadState = downloadState.value, onBack = viewModel::onBack, - onDownloadClick = viewModel::onDownloadClick, + onDownloadClick = onDownloadClick, modifier = modifier ) }