diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogInput.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogInput.kt index a240addce8ffb9da7637e5d27a8f8f47eec8bad2..be9f8a3b4eba5890accb8170c64864718b2d16fc 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogInput.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogInput.kt @@ -87,6 +87,7 @@ fun BlogInput( item = selectedBlogPost, onItemRepeat = null, onAuthorClicked = null, + onLinkClicked = null, ) } IconButton( diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogPostView.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogPostView.kt index 1c5a54705278d6afeab32800d9c221a16a3daf25..755c06d12907822fbca79a08ddc82fdead961f2e 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogPostView.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogPostView.kt @@ -86,7 +86,7 @@ fun main() = preview { text = "This is a normal blog post.\n\nIt has one author and no comments.", time = System.currentTimeMillis() - 999_000 ) - BlogPostView(post, {}, {}) + BlogPostView(post, {}, {}, {}) val htmlPost = getRandomBlogPostItem( text = """ <h1>Headline</h1> @@ -119,13 +119,13 @@ fun main() = preview { """.trimIndent(), time = System.currentTimeMillis() - 750_000 ) - BlogPostView(htmlPost, {}, {}) + BlogPostView(htmlPost, {}, {}, {}) val commentPost = getRandomBlogCommentItem( parent = post, comment = "This is a comment on that first blog post.\n\nIt has two lines as well.", time = System.currentTimeMillis() - 500_000 ) - BlogPostView(commentPost, {}, {}) + BlogPostView(commentPost, {}, {}, {}) BlogPostView( getRandomBlogCommentItem( parent = commentPost, @@ -134,8 +134,9 @@ fun main() = preview { ), null, null, + null, ) - BlogPostView(getRandomBlogPost(getRandomString(1337), 1337), null, null) + BlogPostView(getRandomBlogPost(getRandomString(1337), 1337), null, null, null) } } @@ -145,6 +146,7 @@ fun BlogPostView( item: BlogPost, onItemRepeat: ((BlogPost) -> Unit)?, onAuthorClicked: ((GroupId) -> Unit)?, + onLinkClicked: ((String) -> Unit)?, modifier: Modifier = Modifier, ) = Card(modifier = modifier) { Row(modifier = Modifier.height(IntrinsicSize.Min)) { @@ -160,9 +162,7 @@ fun BlogPostView( maxLines = if (onItemRepeat == null) 5 else Int.MAX_VALUE, overflow = TextOverflow.Ellipsis, ) { link -> - // TODO: handle link clicks. Display dialog warning the user about opening an external app - // with the implication that it can be used to identify the user. Also, make this actually - // clickable which it is not in the SelectionContainer at the moment. + onLinkClicked?.invoke(link) } } Spacer(Modifier.height(8.dp)) diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogScreen.kt index 90b493351cb6f2c9391e79fb78a370f8b25949ca..1596138b3d8e3f8c9ac5da27ca9314b3543f35fa 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogScreen.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/BlogScreen.kt @@ -54,12 +54,22 @@ import org.briarproject.briar.desktop.threadedgroup.sharing.ThreadedGroupSharing import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE import org.briarproject.briar.desktop.ui.HorizontalDivider import org.briarproject.briar.desktop.ui.getInfoDrawerHandler +import org.briarproject.briar.desktop.utils.DesktopUtils.browseLinkIfSupported import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nF import org.briarproject.briar.desktop.viewmodel.viewModel @Composable fun BlogScreen(viewModel: FeedViewModel = viewModel()) { + LinkClickedDialog( + link = viewModel.clickedLink.value, + visible = viewModel.openLinkWarningDialogVisible.value, + onDismissed = { viewModel.dismissOpenLinkWarningDialog() }, + onConfirmed = { + viewModel.dismissOpenLinkWarningDialog() + browseLinkIfSupported(viewModel.clickedLink.value) + }, + ) Scaffold( topBar = { // only show header if some blog is selected @@ -93,6 +103,7 @@ fun BlogScreen(viewModel: FeedViewModel = viewModel()) { onItemSelected = viewModel::selectPost, onBlogSelected = if (viewModel.selectedBlog.value == null) viewModel::selectBlog else null, onBlogPostsVisible = viewModel::onPostsVisible, + onLinkClicked = viewModel::showOpenLinkWarningDialog, modifier = Modifier.padding(padding) ) } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/FeedScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/FeedScreen.kt index 049d725120a70e3699564fd7830e46671e8eaf5a..3f31754e601f49a9adc436ebf03efeabdb6ba221 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/FeedScreen.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/FeedScreen.kt @@ -66,6 +66,7 @@ fun main() = preview( }, onItemSelected = {}, onBlogSelected = {}, + onLinkClicked = {}, onBlogPostsVisible = {}, ) } @@ -77,6 +78,7 @@ fun FeedScreen( onItemSelected: (BlogPost) -> Unit, onBlogSelected: ((GroupId) -> Unit)?, onBlogPostsVisible: (List<MessageId>) -> Unit, + onLinkClicked: ((String) -> Unit)?, modifier: Modifier = Modifier, ) { val scrollState = rememberLazyListState() @@ -98,6 +100,7 @@ fun FeedScreen( item = item, onItemRepeat = onItemSelected, onAuthorClicked = onBlogSelected, + onLinkClicked = onLinkClicked, modifier = Modifier .heightIn(min = HEADER_SIZE) .fillMaxWidth() diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/FeedViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/FeedViewModel.kt index 14c720ec5e26efbab66b2062c9b3fbb25654b8d2..e7107d74a8dc5a4c58bae1b5243db43bf740d7fc 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/FeedViewModel.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/FeedViewModel.kt @@ -79,6 +79,12 @@ class FeedViewModel @Inject constructor( private val _selectedBlog = mutableStateOf<GroupId?>(null) val selectedBlog = _selectedBlog.asState() + private val _openLinkWarningDialogVisible = mutableStateOf(false) + val openLinkWarningDialogVisible = _openLinkWarningDialogVisible.asState() + + private val _clickedLink = mutableStateOf("") + val clickedLink = _clickedLink.asState() + init { runOnDbThreadWithTransaction(true, this::loadAllBlogPosts) } @@ -263,4 +269,13 @@ class FeedViewModel @Inject constructor( } return UnreadPostInfo(firstUnread, num) } + + fun showOpenLinkWarningDialog(link: String) { + _clickedLink.value = link + _openLinkWarningDialogVisible.value = true + } + + fun dismissOpenLinkWarningDialog() { + _openLinkWarningDialogVisible.value = false + } } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/LinkClickedDialog.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/LinkClickedDialog.kt index 26c05c74cd8783dce23d72d23f3789ad5336fc3b..e516440c40ae66fa70f68933e2f313151d44f5d2 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/LinkClickedDialog.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/blog/LinkClickedDialog.kt @@ -47,12 +47,9 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import org.briarproject.briar.desktop.theme.codeBackground import org.briarproject.briar.desktop.ui.Tooltip +import org.briarproject.briar.desktop.utils.DesktopUtils.browseLinkIfSupported import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n import org.briarproject.briar.desktop.utils.PreviewUtils.preview -import java.awt.Desktop -import java.awt.Desktop.getDesktop -import java.awt.Desktop.isDesktopSupported -import java.net.URI @Suppress("HardCodedStringLiteral") fun main() = preview("visible" to true) { @@ -65,9 +62,7 @@ fun main() = preview("visible" to true) { }, onConfirmed = { setBooleanParameter("visible", false) - if (isDesktopSupported() && getDesktop().isSupported(Desktop.Action.BROWSE)) { - getDesktop().browse(URI(link)) - } + browseLinkIfSupported(link) } ) } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/DesktopUtils.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/DesktopUtils.kt new file mode 100644 index 0000000000000000000000000000000000000000..a3da319bd95675eb7cb46fe89e3922e644bc3b50 --- /dev/null +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/DesktopUtils.kt @@ -0,0 +1,32 @@ +/* + * Briar Desktop + * Copyright (C) 2021-2022 The Briar Project + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package org.briarproject.briar.desktop.utils + +import java.awt.Desktop +import java.awt.Desktop.getDesktop +import java.awt.Desktop.isDesktopSupported +import java.net.URI + +object DesktopUtils { + fun browseLinkIfSupported(link: String) { + if (isDesktopSupported() && getDesktop().isSupported(Desktop.Action.BROWSE)) { + getDesktop().browse(URI(link)) + } + } +}