8000 Add podcast support by jocmp · Pull Request #1305 · jocmp/capyreader · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add podcast support #1305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ dependencies {
implementation(libs.androidx.material.icons.extended)
implementation(libs.androidx.material3)
implementation(libs.androidx.material3.window.size)
implementation(libs.androidx.media3.datasource.okhttp)
implementation(libs.androidx.navigation.compose)
implementation(libs.androidx.paging.compose)
implementation(libs.androidx.paging.runtime.ktx)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package com.capyreader.app.ui.articles.audio

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Pause
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage
import com.capyreader.app.ui.theme.CapyTheme
import com.jocmp.capy.Enclosure
import com.jocmp.capy.articles.Podcast
import java.net.URL

@Composable
fun AudioEmbedView(podcast: Podcast) {
var isPlaying by remember { mutableStateOf(false) }

Surface(
color = colorScheme.surfaceContainer,
modifier = Modifier
.height(84.dp)
.padding(vertical = 8.dp, horizontal = 16.dp)
.clip(RoundedCornerShape(8.dp))
) {
Row(
verticalAlignment = CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
) {
podcast.enclosure.itunesImage?.let {
AsyncImage(
model = it,
contentDescription = null,
contentScale = ContentScale.Crop,
modifier =
Modifier
.aspectRatio(1f)
.background(colorScheme.surfaceContainer)
)
}

Column(
Modifier.weight(0.1f),
) {
Text(
podcast.feedName,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.labelSmall,
)
Text(
podcast.title,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
fontSize = 14.sp,
)
}

IconButton(
isPlaying = !isPlaying },
) {
Icon(
imageVector = if (isPlaying) Icons.Default.Pause else Icons.Default.PlayArrow,
contentDescription = if (isPlaying) "Pause" else "Play"
)
}
}
}
}

@Preview
@Composable
fun AudioEmbedViewPreview() {
CapyTheme {
Box(
Modifier.padding(16.dp)
) {
AudioEmbedView(
podcast = Podcast(
articleID = "123",
title = "The movie and TV tech we actually want to use",
feedName = "The Vergecast",
enclosure = Enclosure(
url = URL("https://example.com"),
type = "audio/mpeg",
itunesDurationSeconds = 3601,
itunesImage = null,
)
)
)
}
}
}
29 changes: 22 additions & 7 deletions app/src/main/java/com/capyreader/app/ui/articles/detail/ArticleView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ import com.capyreader.app.preferences.ArticleVerticalSwipe.NEXT_ARTICLE
import com.capyreader.app.preferences.ArticleVerticalSwipe.OPEN_ARTICLE_IN_BROWSER
import com.capyreader.app.preferences.ArticleVerticalSwipe.PREVIOUS_ARTICLE
import com.capyreader.app.ui.articles.LocalFullContent
import com.capyreader.app.ui.articles.audio.AudioEmbedView
import com.capyreader.app.ui.components.WebViewState
import com.capyreader.app.ui.components.pullrefresh.SwipeRefresh
import com.jocmp.capy.Article
import com.jocmp.capy.articles.podcast
import org.koin.compose.koinInject

@OptIn(ExperimentalMaterial3Api::class)
Expand Down Expand Up @@ -97,6 +99,11 @@ fun ArticleView(
bottomScrollBehavior = bottomScrollBehavior,
enableBottomBar = enableBottomBar,
topToolbarPreference = topToolbarPreference,
audioPlayer = {
article.podcast()?.let {
AudioEmbedView(podcast = it)
}
},
topBar = {
ArticleTopBar(
scrollBehavior = topToolbarPreference.scrollBehavior,
Expand Down Expand Up @@ -169,11 +176,13 @@ fun ArticleView(
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun ArticleViewScaffold(
topBar: @Composable () -> Unit,
enableBottomBar: Boolean,
bottomBar: @Composable () -> Unit,
audioPlayer: @Composable () -> Unit,
reader: @Composable () -> Unit,
bottomScrollBehavior: BottomAppBarScrollBehavior,
topToolbarPreference: ToolbarPreferences,
Expand Down Expand Up @@ -206,13 +215,19 @@ private fun ArticleViewScaffold(
topBar()
}

if (enableBottomBar) {
Box(
Modifier
.align(Alignment.BottomStart)
.fillMaxWidth()
) {
bottomBar()
Column(
Modifier
.align(Alignment.BottomStart)
) {
audioPlayer()

if (enableBottomBar) {
Box(
Modifier
.fillMaxWidth()
) {
bottomBar()
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.jocmp.capy.articles

import com.jocmp.capy.Article

fun Article.podcast(): Podcast? {
val enclosure = enclosures.firstOrNull { it.type.startsWith("audio/") } ?: return null

return Podcast(articleID = id, title = title, feedName = feedName, enclosure = enclosure)
}
10 changes: 10 additions & 0 deletions capy/src/main/java/com/jocmp/capy/articles/Podcast.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.jocmp.capy.articles
< 9E88 br>
import com.jocmp.capy.Enclosure

data class Podcast(
val articleID: String,
val title: String,
val feedName: String,
val enclosure: Enclosure
)
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ kotlin = "2.1.0"
ksp = "2.1.0-1.0.29"
androidx-lifecycle-runtime = "2.9.1"
androidx-adaptive = "1.1.0"
media3 = "1.7.1"
mockk = "1.14.2"
navigation-compose = "2.9.0"
okhttp = "4.12.0"
Expand All @@ -33,6 +34,7 @@ androidx-material = { module = "com.google.android.material:material", version =
androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended" }
androidx-material3 = { module = "androidx.compose.material3:material3", version = "1.3.2" }
androidx-material3-window-size = { module = "androidx.compose.material3:material3-window-size-class-android", version = "1.3.2" }
androidx-media3-datasource-okhttp = { module = "androidx.media3:media3-datasource-okhttp", version.ref = "media3" }
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigation-compose" }
androidx-paging-compose = { module = "androidx.paging:paging-compose", version.ref = "paging-compose" }
androidx-paging-runtime-ktx = { module = "androidx.paging:paging-runtime-ktx", version.ref = "androidx-paging" }
Expand Down
0