diff --git a/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleItem.kt b/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleItem.kt index 2aabd2ba2..1bb04bdf5 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleItem.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleItem.kt @@ -24,6 +24,7 @@ import androidx.compose.material.icons.rounded.ArrowDownward import androidx.compose.material.icons.rounded.ArrowUpward import androidx.compose.material.icons.rounded.CheckCircleOutline import androidx.compose.material.icons.rounded.FiberManualRecord +import androidx.compose.material.icons.rounded.OpenInBrowser import androidx.compose.material.icons.rounded.Share import androidx.compose.material.icons.rounded.Star import androidx.compose.material3.DropdownMenuItem @@ -320,6 +321,7 @@ fun SwipeableArticleItem( onMarkAboveAsRead: ((ArticleWithFeed) -> Unit)? = null, onMarkBelowAsRead: ((ArticleWithFeed) -> Unit)? = null, onShare: ((ArticleWithFeed) -> Unit)? = null, + onOpenInBrowser: ((ArticleWithFeed) -> Unit)? = null, ) { var isMenuExpanded by remember { mutableStateOf(false) } @@ -381,6 +383,7 @@ fun SwipeableArticleItem( onMarkAboveAsRead = onMarkAboveAsRead, onMarkBelowAsRead = onMarkBelowAsRead, onShare = onShare, + onOpenInBrowser = onOpenInBrowser ) { isMenuExpanded = false } @@ -571,6 +574,7 @@ fun ArticleItemMenuContent( onMarkAboveAsRead: ((ArticleWithFeed) -> Unit)? = null, onMarkBelowAsRead: ((ArticleWithFeed) -> Unit)? = null, onShare: ((ArticleWithFeed) -> Unit)? = null, + onOpenInBrowser: ((ArticleWithFeed) -> Unit)? = null, onItemClick: (() -> Unit)? = null, ) { val starImageVector = @@ -667,6 +671,22 @@ fun ArticleItemMenuContent( }, ) } + onOpenInBrowser?.let { + DropdownMenuItem( + text = { Text(text = stringResource(id = R.string.open_in_browser)) }, + onClick = { + onOpenInBrowser(articleWithFeed) + onItemClick?.invoke() + }, + leadingIcon = { + Icon( + imageVector = Icons.Rounded.OpenInBrowser, + contentDescription = null, + modifier = Modifier.size(iconSize) + ) + }, + ) + } } @Preview @@ -680,6 +700,7 @@ fun MenuContentPreview() { onMarkBelowAsRead = {}, onMarkAboveAsRead = {}, onShare = {}, + onOpenInBrowser = {} ) } } diff --git a/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleList.kt b/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleList.kt index 723454074..850f19b13 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleList.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleList.kt @@ -29,6 +29,7 @@ fun LazyListScope.ArticleList( onMarkAboveAsRead: ((ArticleWithFeed) -> Unit)? = null, onMarkBelowAsRead: ((ArticleWithFeed) -> Unit)? = null, onShare: ((ArticleWithFeed) -> Unit)? = null, + onOpenInBrowser: ((ArticleWithFeed) -> Unit)? = null, ) { // https://issuetracker.google.com/issues/193785330 // FIXME: Using sticky header with paging-compose need to iterate through the entire list @@ -57,6 +58,7 @@ fun LazyListScope.ArticleList( onMarkBelowAsRead = if (index == pagingItems.itemCount - 1) null else onMarkBelowAsRead, onShare = onShare, + onOpenInBrowser = onOpenInBrowser, ) } @@ -91,6 +93,7 @@ fun LazyListScope.ArticleList( onMarkBelowAsRead = if (index == pagingItems.itemCount - 1) null else onMarkBelowAsRead, onShare = onShare, + onOpenInBrowser = onOpenInBrowser ) } } diff --git a/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt b/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt index 602def14a..ca11537cd 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt @@ -59,6 +59,7 @@ import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow @@ -131,6 +132,7 @@ fun FlowPage( val filterBarPadding = LocalFlowFilterBarPadding.current val filterBarTonalElevation = LocalFlowFilterBarTonalElevation.current val sharedContent = LocalSharedContent.current + val uriHandler = LocalUriHandler.current val markAsReadOnScroll = LocalMarkAsReadOnScroll.current.value val context = LocalContext.current @@ -219,6 +221,12 @@ fun FlowPage( } } + val onOpenInBrowser: ((ArticleWithFeed) -> Unit)? = remember { + { articleWithFeed -> + with(articleWithFeed.article) { uriHandler.openUri(link) } + } + } + LaunchedEffect(onSearch) { if (!onSearch) { keyboardController?.hide() @@ -692,6 +700,7 @@ fun FlowPage( onMarkAboveAsRead = onMarkAboveAsRead, onMarkBelowAsRead = onMarkBelowAsRead, onShare = onShare, + onOpenInBrowser = onOpenInBrowser, ) item { Spacer(modifier = Modifier.height(128.dp)) diff --git a/app/src/main/java/me/ash/reader/ui/page/home/reading/TopBar.kt b/app/src/main/java/me/ash/reader/ui/page/home/reading/TopBar.kt index fdcb0dcd0..9c512e8fa 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/reading/TopBar.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/reading/TopBar.kt @@ -20,6 +20,7 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBars import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.rounded.MenuOpen +import androidx.compose.material.icons.outlined.OpenInBrowser import androidx.compose.material.icons.outlined.Palette import androidx.compose.material.icons.outlined.Share import androidx.compose.material.icons.rounded.Close @@ -38,6 +39,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp @@ -65,6 +67,7 @@ fun TopBar( ) { val context = LocalContext.current val sharedContent = LocalSharedContent.current + val uriHandler = LocalUriHandler.current val isOutlined = LocalReadingPageTonalElevation.current == ReadingPageTonalElevationPreference.Outlined @@ -138,6 +141,14 @@ fun TopBar( ) { sharedContent.share(context, title, link) } + FeedbackIconButton( + modifier = Modifier.size(22.dp), + imageVector = Icons.Outlined.OpenInBrowser, + contentDescription = stringResource(R.string.open_in_browser), + tint = MaterialTheme.colorScheme.onSurface + ) { + uriHandler.openUri(link!!) + } }, colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent), )