Skip to content

Commit

Permalink
add platform media control
Browse files Browse the repository at this point in the history
  • Loading branch information
Tlaster committed Jan 10, 2025
1 parent 25ff2ea commit 93169c4
Show file tree
Hide file tree
Showing 29 changed files with 1,786 additions and 479 deletions.
2 changes: 0 additions & 2 deletions app/src/main/java/dev/dimension/flare/di/AndroidModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package dev.dimension.flare.di
import androidx.media3.common.util.UnstableApi
import dev.dimension.flare.common.ComposeInAppNotification
import dev.dimension.flare.common.InAppNotification
import dev.dimension.flare.common.PlayerPoll
import dev.dimension.flare.data.repository.SettingsRepository
import dev.dimension.flare.ui.component.VideoPlayerPool
import org.koin.core.module.dsl.singleOf
Expand All @@ -14,7 +13,6 @@ import org.koin.dsl.module
val androidModule =
module {
singleOf(::SettingsRepository)
singleOf(::PlayerPoll)
singleOf(::VideoPlayerPool)
singleOf(::ComposeInAppNotification) binds arrayOf(InAppNotification::class, ComposeInAppNotification::class)
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import compose.icons.fontawesomeicons.solid.CircleQuestion
import compose.icons.fontawesomeicons.solid.MagnifyingGlass
import compose.icons.fontawesomeicons.solid.Xmark
import dev.dimension.flare.R
import dev.dimension.flare.common.AppDeepLink
import dev.dimension.flare.common.onEmpty
import dev.dimension.flare.common.onLoading
import dev.dimension.flare.common.onSuccess
Expand Down Expand Up @@ -92,6 +93,9 @@ import moe.tlaster.precompose.molecule.producePresenter
DeepLink(
uriPattern = "flare://$FULL_ROUTE_PLACEHOLDER",
),
DeepLink(
uriPattern = AppDeepLink.LOGIN,
),
],
)
fun ServiceSelectRoute(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import io.ktor.http.encodeURLQueryComponent
public const val APPSCHEMA: String = "flare"

public object AppDeepLink {
public const val LOGIN: String = "$APPSCHEMA://Login"

public object Callback {
public const val MASTODON: String = "$APPSCHEMA://Callback/SignIn/Mastodon"
public const val MISSKEY: String = "$APPSCHEMA://Callback/SignIn/Misskey"
Expand Down
3 changes: 3 additions & 0 deletions shared/ui/component/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ kotlin {
implementation(libs.ksoup)
implementation(libs.kotlinx.immutable)
implementation(libs.precompose.molecule)
implementation(compose("org.jetbrains.compose.material3:material3-window-size-class"))
}
}
val commonTest by getting {
Expand All @@ -43,6 +44,8 @@ kotlin {
dependencies {
implementation(libs.compose.placeholder.material3)
implementation(compose.material3)
implementation(libs.bundles.media3)
implementation(libs.bundles.koin)
}
}
val jvmMain by getting {
Expand Down
8 changes: 8 additions & 0 deletions shared/ui/component/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application>

</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -1,53 +1,42 @@
package dev.dimension.flare.common
package dev.dimension.flare.ui.component

import android.content.Context
import androidx.annotation.OptIn
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.core.util.lruCache
import androidx.compose.ui.platform.LocalContext
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import kotlinx.coroutines.delay
import kotlin.time.Duration.Companion.seconds

@OptIn(UnstableApi::class)
class PlayerPoll(
private val context: Context,
) {
private val players =
lruCache<String, Player>(
10,
create = { uri ->
ExoPlayer
.Builder(context)
.build()
.apply {
setMediaItem(MediaItem.fromUri(uri))
}
},
onEntryRemoved = { _, _, oldValue, _ ->
oldValue.release()
},
)

fun get(uri: String): Player = players[uri]

fun remove(uri: String) {
players.remove(uri)
@Composable
internal actual fun rememberPlayerState(uri: String): PlayerState {
val context = LocalContext.current
val player =
remember {
ExoPlayer
.Builder(context)
.build()
.apply {
setMediaItem(MediaItem.fromUri(uri))
}
}
DisposableEffect(player) {
onDispose {
player.release()
}
}
return player.observeState()
}

@Composable
fun Player.observeState(): PlayerState {
private fun Player.observeState(): PlayerState {
var playing by remember(this) { mutableStateOf(false) }
var loading by remember(this) { mutableStateOf(false) }
var position by remember(this) { mutableLongStateOf(0L) }
Expand Down Expand Up @@ -82,26 +71,27 @@ fun Player.observeState(): PlayerState {
removeListener(listener)
}
}
return PlayerState(
playing = playing,
loading = loading,
position = position,
duration = maxDuration,
)
}
return object : PlayerState {
override val playing: Boolean
get() = playing
override val loading: Boolean
get() = loading
override val duration: Long
get() = maxDuration
override val progress: Float
get() = position.toFloat() / maxDuration.toFloat()

@Immutable
data class PlayerState(
val playing: Boolean,
val loading: Boolean,
val position: Long,
val duration: Long,
) {
val progress: Float
get() =
if (duration > 0) {
position.toFloat() / duration
} else {
0f
}
override fun play() {
this@observeState.prepare()
this@observeState.play()
}

override fun pause() {
this@observeState.pause()
}

override fun seekTo(position: Long) {
this@observeState.seekTo(position)
}
}
}
Loading

0 comments on commit 93169c4

Please sign in to comment.