Skip to content

Commit

Permalink
Bettering torrent support. (#1612)
Browse files Browse the repository at this point in the history
* Bettering torrent support.

- Fixes URI validation to include magnet link schemes.
- When creating a post, can automatically copy the torrent title from
  the link.
- Adds a torrent helper for magnet links.
- Fixes magnet link clicks.
- Fixes #1609

* Addressing PR comments.

* Fixing tests.

* Cleaning up.
  • Loading branch information
dessalines authored Aug 6, 2024
1 parent ed68524 commit ce99dfb
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 10 deletions.
2 changes: 2 additions & 0 deletions app/src/main/java/com/jerboa/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ const val MAX_POST_TITLE_LENGTH = 200
*/
const val SHOW_UPVOTE_PCT_THRESHOLD = 0.9F
const val VIEW_VOTES_LIMIT = 40L

val ALLOWED_SCHEMES = listOf("http", "https", "magnet")
5 changes: 2 additions & 3 deletions app/src/main/java/com/jerboa/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.core.os.LocaleListCompat
import androidx.core.util.PatternsCompat
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.CreationExtras
Expand Down Expand Up @@ -251,7 +250,7 @@ fun parseUrl(
baseUrl: String,
url: String,
): Pair<Boolean, String>? {
if (url.startsWith("https://") || url.startsWith("http://")) {
if (ALLOWED_SCHEMES.any { url.startsWith(it) }) {
return Pair(false, url)
} else if (url.startsWith("/c/")) {
if (url.count { c -> c == '@' } == 1) {
Expand Down Expand Up @@ -648,7 +647,7 @@ fun validateUrl(
url: String,
label: String = ctx.getString(R.string.url),
): InputField =
if (url.isNotEmpty() && !PatternsCompat.WEB_URL.matcher(url).matches()) {
if (url.isNotEmpty() && !ALLOWED_SCHEMES.any { url.startsWith(it) }) {
InputField(
label = ctx.getString(R.string.url_invalid),
hasError = true,
Expand Down
28 changes: 27 additions & 1 deletion app/src/main/java/com/jerboa/ui/components/post/PostListing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ import com.jerboa.ui.components.community.CommunityLink
import com.jerboa.ui.components.community.CommunityName
import com.jerboa.ui.components.person.PersonProfileLink
import com.jerboa.ui.components.post.composables.PostOptionsDropdown
import com.jerboa.ui.components.settings.about.TORRENT_HELP_LINK
import com.jerboa.ui.theme.ACTION_BAR_ICON_SIZE
import com.jerboa.ui.theme.CARD_COLORS
import com.jerboa.ui.theme.LARGER_ICON_THUMBNAIL_SIZE
Expand Down Expand Up @@ -483,6 +484,10 @@ fun PostBody(
// The metadata card
if (fullBody && showPostLinkPreview) {
MetadataCard(post = post)

if (post.url?.startsWith("magnet") == true) {
TorrentHelpInfo()
}
}

// Check to make sure body isn't empty string
Expand Down Expand Up @@ -1762,7 +1767,7 @@ fun MetadataCard(post: Post) {
shape = MaterialTheme.shapes.medium,
modifier =
Modifier
.padding(vertical = MEDIUM_PADDING, horizontal = MEDIUM_PADDING)
.padding(MEDIUM_PADDING)
.fillMaxWidth(),
content = {
Column(
Expand All @@ -1789,3 +1794,24 @@ fun MetadataCard(post: Post) {
)
}
}

@Composable
fun TorrentHelpInfo() {
OutlinedCard(
shape = MaterialTheme.shapes.medium,
modifier =
Modifier
.padding(MEDIUM_PADDING)
.fillMaxWidth(),
content = {
Column(
modifier = Modifier.padding(MEDIUM_PADDING),
) {
MyMarkdownText(
markdown = stringResource(R.string.torrent_help, TORRENT_HELP_LINK),
onClick = {},
)
}
},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,25 @@ fun CreatePostScreen(
}

val (suggestedTitle, suggestedTitleLoading) =
when (val res = createPostViewModel.siteMetadataRes) {
ApiState.Empty -> MetaDataRes(null, false)
ApiState.Loading -> MetaDataRes(null, true)
is ApiState.Success ->
MetaDataRes(res.data.metadata.title, false)
else -> MetaDataRes(null, false)
// If its a torrent magnet link, use the dn param to extract the torrent title
if (url.startsWith("magnet")) {
val query = Uri.parse(url).query
// Unfortunately you have to use a fake http uri, otherwise getQueryParameter throws a non-hierarchical error.
val torrentDownloadName = Uri.parse("http://test.com?$query").getQueryParameter("dn")

if (torrentDownloadName !== null) {
MetaDataRes(torrentDownloadName, false)
} else {
MetaDataRes(null, false)
}
} else {
when (val res = createPostViewModel.siteMetadataRes) {
ApiState.Empty -> MetaDataRes(null, false)
ApiState.Loading -> MetaDataRes(null, true)
is ApiState.Success ->
MetaDataRes(res.data.metadata.title, false)
else -> MetaDataRes(null, false)
}
}
Surface(color = MaterialTheme.colorScheme.background) {
Scaffold(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const val JERBOA_MATRIX_CHAT = "https://matrix.to/#/#jerboa-dev:matrix.org"
const val DONATE_LINK = "https://join-lemmy.org/donate"
const val JERBOA_LEMMY_ML_LINK = "https://lemmy.ml/c/jerboa"
const val MASTODON_LINK = "https://mastodon.social/@LemmyDev"
const val TORRENT_HELP_LINK = "https://join-lemmy.org/docs/users/02-media.html#torrents"

@OptIn(ExperimentalMaterial3Api::class)
@Composable
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -493,4 +493,5 @@
<string name="you_have_no_blocked_users">You have no blocked users</string>
<string name="you_have_no_blocked_communities">You have no blocked communities</string>
<string name="you_have_no_blocked_instances">You have no blocked instances</string>
<string name="torrent_help">Lemmy can use a technology called BitTorrent to view or stream media. [Click here](%1$s) to learn how.</string>
</resources>

0 comments on commit ce99dfb

Please sign in to comment.