diff --git a/app/src/main/java/com/readrops/app/item/ItemImageDialog.kt b/app/src/main/java/com/readrops/app/item/ItemImageDialog.kt index cc47f80c..d7c2c6ef 100644 --- a/app/src/main/java/com/readrops/app/item/ItemImageDialog.kt +++ b/app/src/main/java/com/readrops/app/item/ItemImageDialog.kt @@ -8,10 +8,10 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp import com.readrops.app.R +import com.readrops.app.util.DefaultPreview +import com.readrops.app.util.components.SelectableIconText import com.readrops.app.util.components.dialog.BaseDialog -import com.readrops.app.util.components.SelectableImageText import com.readrops.app.util.theme.spacing enum class ItemImageChoice { @@ -30,25 +30,32 @@ fun ItemImageDialog( onDismiss = onDismiss ) { Column { - SelectableImageText( - image = rememberVectorPainter(image = Icons.Default.Share), + SelectableIconText( + icon = rememberVectorPainter(image = Icons.Default.Share), text = stringResource(id = R.string.share_image), style = MaterialTheme.typography.titleMedium, - spacing = MaterialTheme.spacing.shortSpacing, + spacing = MaterialTheme.spacing.mediumSpacing, padding = MaterialTheme.spacing.shortSpacing, - imageSize = 16.dp, onClick = { onChoice(ItemImageChoice.SHARE) } ) - SelectableImageText( - image = painterResource(id = R.drawable.ic_download), + SelectableIconText( + icon = painterResource(id = R.drawable.ic_download), text = stringResource(id = R.string.download_image), style = MaterialTheme.typography.titleMedium, - spacing = MaterialTheme.spacing.shortSpacing, + spacing = MaterialTheme.spacing.mediumSpacing, padding = MaterialTheme.spacing.shortSpacing, - imageSize = 16.dp, onClick = { onChoice(ItemImageChoice.DOWNLOAD) } ) } } +} + +@DefaultPreview +@Composable +private fun ItemImageDialogPreview() { + ItemImageDialog( + onChoice = {}, + onDismiss = {} + ) } \ No newline at end of file diff --git a/app/src/main/java/com/readrops/app/item/ItemScreen.kt b/app/src/main/java/com/readrops/app/item/ItemScreen.kt index e96b40f4..7f2a325f 100644 --- a/app/src/main/java/com/readrops/app/item/ItemScreen.kt +++ b/app/src/main/java/com/readrops/app/item/ItemScreen.kt @@ -13,9 +13,13 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost @@ -51,12 +55,15 @@ import androidx.core.net.toUri import androidx.core.view.children import androidx.lifecycle.compose.collectAsStateWithLifecycle import cafe.adriel.voyager.koin.getScreenModel +import cafe.adriel.voyager.navigator.LocalNavigator +import cafe.adriel.voyager.navigator.currentOrThrow import coil.compose.AsyncImage import com.readrops.app.R import com.readrops.app.item.view.ItemNestedScrollView import com.readrops.app.item.view.ItemWebView import com.readrops.app.util.components.AndroidScreen import com.readrops.app.util.components.CenteredProgressIndicator +import com.readrops.app.util.components.FeedIcon import com.readrops.app.util.components.IconText import com.readrops.app.util.theme.MediumSpacer import com.readrops.app.util.theme.ShortSpacer @@ -74,6 +81,7 @@ class ItemScreen( override fun Content() { val context = LocalContext.current val density = LocalDensity.current + val navigator = LocalNavigator.currentOrThrow val screenModel = getScreenModel(parameters = { parametersOf(itemId) }) @@ -122,7 +130,7 @@ class ItemScreen( LaunchedEffect(state.fileDownloadedEvent) { if (state.fileDownloadedEvent) { - snackbarHostState.showSnackbar("Downloaded file!") + snackbarHostState.showSnackbar(context.getString(R.string.downloaded_file)) } } @@ -136,6 +144,12 @@ class ItemScreen( primaryColor } + val colorScheme = when (state.theme) { + "light" -> CustomTabsIntent.COLOR_SCHEME_LIGHT + "dark" -> CustomTabsIntent.COLOR_SCHEME_DARK + else -> CustomTabsIntent.COLOR_SCHEME_SYSTEM + } + fun openUrl(url: String) { if (state.openInExternalBrowser) { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) @@ -150,14 +164,14 @@ class ItemScreen( ) .setShareState(CustomTabsIntent.SHARE_STATE_ON) .setUrlBarHidingEnabled(true) + .setColorScheme(colorScheme) .build() .launchUrl(context, url.toUri()) } } Scaffold( - modifier = Modifier - .nestedScroll(nestedScrollConnection), + modifier = Modifier.nestedScroll(nestedScrollConnection), snackbarHost = { SnackbarHost(snackbarHostState) }, bottomBar = { ItemScreenBottomBar( @@ -194,6 +208,7 @@ class ItemScreen( factory = { context -> ItemNestedScrollView( context = context, + useBackgroundTitle = item.imageLink != null, onGlobalLayoutListener = { viewHeight, contentHeight -> isScrollable = viewHeight - contentHeight < 0 }, @@ -203,19 +218,27 @@ class ItemScreen( if (item.imageLink != null) { BackgroundTitle(itemWithFeed = itemWithFeed) } else { - val tintColor = if (itemWithFeed.color != 0) { - Color(itemWithFeed.color) - } else { - MaterialTheme.colorScheme.onBackground - } + Box { + IconButton( + onClick = { navigator.pop() }, + modifier = Modifier + .statusBarsPadding() + .align(Alignment.TopStart) + ) { + Icon( + imageVector = Icons.AutoMirrored.Default.ArrowBack, + contentDescription = null, + ) + } - SimpleTitle( - itemWithFeed = itemWithFeed, - titleColor = tintColor, - accentColor = tintColor, - baseColor = MaterialTheme.colorScheme.onBackground, - bottomPadding = true - ) + SimpleTitle( + itemWithFeed = itemWithFeed, + titleColor = accentColor, + accentColor = accentColor, + baseColor = MaterialTheme.colorScheme.onBackground, + bottomPadding = true + ) + } } } }, @@ -248,6 +271,8 @@ class ItemScreen( fun BackgroundTitle( itemWithFeed: ItemWithFeed, ) { + val navigator = LocalNavigator.currentOrThrow + val onScrimColor = Color.White.copy(alpha = 0.85f) val accentColor = if (itemWithFeed.color != 0) { Color(itemWithFeed.color) @@ -276,13 +301,28 @@ fun BackgroundTitle( modifier = Modifier .fillMaxSize() ) { - SimpleTitle( - itemWithFeed = itemWithFeed, - titleColor = onScrimColor, - accentColor = accentColor, - baseColor = onScrimColor, - bottomPadding = true - ) + Box { + IconButton( + onClick = { navigator.pop() }, + modifier = Modifier + .statusBarsPadding() + .align(Alignment.TopStart) + ) { + Icon( + imageVector = Icons.AutoMirrored.Default.ArrowBack, + contentDescription = null, + tint = Color.White + ) + } + + SimpleTitle( + itemWithFeed = itemWithFeed, + titleColor = onScrimColor, + accentColor = accentColor, + baseColor = onScrimColor, + bottomPadding = true + ) + } } } @@ -309,14 +349,11 @@ fun SimpleTitle( bottom = if (bottomPadding) spacing else 0.dp ) ) { - AsyncImage( - model = itemWithFeed.feedIconUrl, - contentDescription = itemWithFeed.feedName, - placeholder = painterResource(id = R.drawable.ic_rss_feed_grey), - error = painterResource(id = R.drawable.ic_rss_feed_grey), - modifier = Modifier - .size(48.dp) - .clip(CircleShape) + FeedIcon( + iconUrl = itemWithFeed.feedIconUrl, + name = itemWithFeed.feedName, + size = 48.dp, + modifier = Modifier.clip(CircleShape) ) ShortSpacer() diff --git a/app/src/main/java/com/readrops/app/item/ItemScreenModel.kt b/app/src/main/java/com/readrops/app/item/ItemScreenModel.kt index fe3b087b..19699e0e 100644 --- a/app/src/main/java/com/readrops/app/item/ItemScreenModel.kt +++ b/app/src/main/java/com/readrops/app/item/ItemScreenModel.kt @@ -24,6 +24,7 @@ import com.readrops.db.queries.ItemSelectionQueryBuilder import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @@ -81,17 +82,22 @@ class ItemScreenModel( } screenModelScope.launch(dispatcher) { - preferences.openLinksWith.flow - .collect { value -> - mutableState.update { - it.copy( - openInExternalBrowser = when (value) { - "external_navigator" -> true - else -> false - } - ) - } + combine( + preferences.openLinksWith.flow, + preferences.theme.flow + ) { openLinksWith, theme -> + openLinksWith to theme + }.collect { (openLinksWith, theme) -> + mutableState.update { + it.copy( + openInExternalBrowser = when (openLinksWith) { + "external_navigator" -> true + else -> false + }, + theme = theme + ) } + } } } @@ -186,5 +192,6 @@ data class ItemState( val bottomBarState: BottomBarState = BottomBarState(), val imageDialogUrl: String? = null, val fileDownloadedEvent: Boolean = false, - val openInExternalBrowser: Boolean = false + val openInExternalBrowser: Boolean = false, + val theme: String? = "" ) \ No newline at end of file diff --git a/app/src/main/java/com/readrops/app/item/view/ItemNestedScrollView.kt b/app/src/main/java/com/readrops/app/item/view/ItemNestedScrollView.kt index 82d3d710..f3755adf 100644 --- a/app/src/main/java/com/readrops/app/item/view/ItemNestedScrollView.kt +++ b/app/src/main/java/com/readrops/app/item/view/ItemNestedScrollView.kt @@ -11,6 +11,7 @@ import androidx.core.widget.NestedScrollView @SuppressLint("ResourceType", "ViewConstructor") class ItemNestedScrollView( context: Context, + useBackgroundTitle: Boolean, onGlobalLayoutListener: (viewHeight: Int, contentHeight: Int) -> Unit, onUrlClick: (String) -> Unit, onImageLongPress: (String) -> Unit, @@ -54,6 +55,12 @@ class ItemNestedScrollView( webViewParams.addRule(RelativeLayout.BELOW, composeView.id) webView.layoutParams = webViewParams + if (useBackgroundTitle) { + val density = resources.displayMetrics.density + val dpAsPixels = (8 * density + 0.5f).toInt() + composeView.setPadding(0, 0, 0, dpAsPixels) + } + addView(composeView) addView(webView) } diff --git a/app/src/main/java/com/readrops/app/util/components/FeedIcon.kt b/app/src/main/java/com/readrops/app/util/components/FeedIcon.kt index 53fee57c..df5fba44 100644 --- a/app/src/main/java/com/readrops/app/util/components/FeedIcon.kt +++ b/app/src/main/java/com/readrops/app/util/components/FeedIcon.kt @@ -14,6 +14,7 @@ import com.readrops.app.util.FeedKey fun FeedIcon( iconUrl: String?, name: String, + modifier: Modifier = Modifier, size: Dp = 24.dp ) { AsyncImage( @@ -22,6 +23,6 @@ fun FeedIcon( placeholder = painterResource(R.drawable.ic_rss_feed_grey), fallback = painterResource(id = R.drawable.ic_rss_feed_grey), contentDescription = name, - modifier = Modifier.size(size) + modifier = modifier.size(size) ) } \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 66c37cc6..f8615989 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -217,4 +217,5 @@ Litecoin (copier l\'adresse) "Si vous considérez que mon travail vous est utile et si vous souhaitez me soutenir, vous pouvez me faire une donation. " Ajouter un flux + Fichier téléchargé ! \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 93f50cec..3a76ebb5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -230,4 +230,5 @@ Litecoin (copy address) I you find my work useful and you would like to support me, you can consider making me a donation. Add feed + Downloaded file! \ No newline at end of file