Skip to content

Commit

Permalink
Resolve some TODO's (clean up along the way)
Browse files Browse the repository at this point in the history
  • Loading branch information
25huizengek1 committed Sep 22, 2024
1 parent 4923af2 commit b88f30c
Show file tree
Hide file tree
Showing 30 changed files with 774 additions and 525 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.ksp)
}

Expand Down
136 changes: 63 additions & 73 deletions app/src/main/kotlin/app/vitune/android/MainApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,15 @@ import com.kieronquinn.monetcompat.core.MonetCompat
import com.kieronquinn.monetcompat.interfaces.MonetColorsChangedListener
import com.valentinilk.shimmer.LocalShimmerTheme
import dev.kdrag0n.monet.theme.ColorScheme
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

private const val TAG = "MainActivity"
private val coroutineScope = CoroutineScope(Dispatchers.IO)

// Viewmodel in order to avoid recreating the entire Player state (WORKAROUND)
class MainViewModel : ViewModel() {
Expand Down Expand Up @@ -287,15 +289,7 @@ class MainActivity : ComponentActivity(), MonetColorsChangedListener {
val isDownloading by downloadState.collectAsState()

Box {
HomeScreen(
onPlaylistUrl = { url ->
runCatching {
handleUrl(url.toUri())
}.onFailure {
toast(getString(R.string.error_url, url))
}
}
)
HomeScreen()
}

AnimatedVisibility(
Expand Down Expand Up @@ -374,7 +368,7 @@ class MainActivity : ComponentActivity(), MonetColorsChangedListener {
intent.data = null
extras?.text = null

handleUrl(uri)
handleUrl(uri, vm.awaitBinder())
}

MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH -> {
Expand All @@ -398,68 +392,6 @@ class MainActivity : ComponentActivity(), MonetColorsChangedListener {
}
}

private fun handleUrl(uri: Uri) {
val path = uri.pathSegments.firstOrNull()
Log.d(TAG, "Opening url: $uri ($path)")

lifecycleScope.launch(Dispatchers.IO) {
when (path) {
"search" -> uri.getQueryParameter("q")?.let { query ->
searchResultRoute.ensureGlobal(query)
}

"playlist" -> uri.getQueryParameter("list")?.let { playlistId ->
val browseId = "VL$playlistId"

if (playlistId.startsWith("OLAK5uy_")) Innertube.playlistPage(
body = BrowseBody(browseId = browseId)
)
?.getOrNull()
?.let { page ->
page.songsPage?.items?.firstOrNull()?.album?.endpoint?.browseId
?.let { albumRoute.ensureGlobal(it) }
} ?: withContext(Dispatchers.Main) {
toast(
getString(
R.string.error_url,
uri
)
)
}
else playlistRoute.ensureGlobal(
p0 = browseId,
p1 = uri.getQueryParameter("params"),
p2 = null,
p3 = playlistId.startsWith("RDCLAK5uy_")
)
}

"channel", "c" -> uri.lastPathSegment?.let { channelId ->
artistRoute.ensureGlobal(channelId)
}

else -> when {
path == "watch" -> uri.getQueryParameter("v")
uri.host == "youtu.be" -> path
else -> {
withContext(Dispatchers.Main) {
toast(getString(R.string.error_url, uri))
}
null
}
}?.let { videoId ->
Innertube.song(videoId)?.getOrNull()?.let { song ->
val binder = vm.awaitBinder()

withContext(Dispatchers.Main) {
binder.player.forcePlay(song.asMediaItem)
}
}
}
}
}
}

override fun onDestroy() {
super.onDestroy()
monet.removeMonetColorsChangedListener(this)
Expand Down Expand Up @@ -488,6 +420,65 @@ class MainActivity : ComponentActivity(), MonetColorsChangedListener {
}
}

context(Context)
fun handleUrl(
uri: Uri,
binder: PlayerService.Binder?
) {
val path = uri.pathSegments.firstOrNull()
Log.d(TAG, "Opening url: $uri ($path)")

coroutineScope.launch {
when (path) {
"search" -> uri.getQueryParameter("q")?.let { query ->
searchResultRoute.ensureGlobal(query)
}

"playlist" -> uri.getQueryParameter("list")?.let { playlistId ->
val browseId = "VL$playlistId"

if (playlistId.startsWith("OLAK5uy_")) Innertube.playlistPage(
body = BrowseBody(browseId = browseId)
)
?.getOrNull()
?.let { page ->
page.songsPage?.items?.firstOrNull()?.album?.endpoint?.browseId
?.let { albumRoute.ensureGlobal(it) }
} ?: withContext(Dispatchers.Main) {
toast(getString(R.string.error_url, uri))
}
else playlistRoute.ensureGlobal(
p0 = browseId,
p1 = uri.getQueryParameter("params"),
p2 = null,
p3 = playlistId.startsWith("RDCLAK5uy_")
)
}

"channel", "c" -> uri.lastPathSegment?.let { channelId ->
artistRoute.ensureGlobal(channelId)
}

else -> when {
path == "watch" -> uri.getQueryParameter("v")
uri.host == "youtu.be" -> path
else -> {
withContext(Dispatchers.Main) {
toast(getString(R.string.error_url, uri))
}
null
}
}?.let { videoId ->
Innertube.song(videoId)?.getOrNull()?.let { song ->
withContext(Dispatchers.Main) {
binder?.player?.forcePlay(song.asMediaItem)
}
}
}
}
}
}

val LocalPlayerServiceBinder = staticCompositionLocalOf<PlayerService.Binder?> { null }
val LocalPlayerAwareWindowInsets =
compositionLocalOf<WindowInsets> { error("No player insets provided") }
Expand All @@ -497,7 +488,6 @@ class MainApplication : Application(), ImageLoaderFactory, Configuration.Provide
override fun onCreate() {
StrictMode.setVmPolicy(
VmPolicy.Builder()
// TODO: check all intent launchers for 'unsafe' intents (new rules like 'all intents should have an action')
.let {
if (isAtLeastAndroid12) it.detectUnsafeIntentLaunch()
else it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,31 +84,31 @@ object PlayerPreferences : GlobalPreferencesHolder() {
) {
None(
preset = PresetReverb.PRESET_NONE,
displayName = { stringResource(R.string.thumbnail_roundness_none) } // TODO: rename
displayName = { stringResource(R.string.none) }
),
SmallRoom(
preset = PresetReverb.PRESET_SMALLROOM,
displayName = { "Small room" }
displayName = { stringResource(R.string.reverb_small_room) }
),
MediumRoom(
preset = PresetReverb.PRESET_MEDIUMROOM,
displayName = { "Medium room" }
displayName = { stringResource(R.string.reverb_medium_room) }
),
LargeRoom(
preset = PresetReverb.PRESET_LARGEROOM,
displayName = { "Large room" }
displayName = { stringResource(R.string.reverb_large_room) }
),
MediumHall(
preset = PresetReverb.PRESET_MEDIUMHALL,
displayName = { "Medium hall" }
displayName = { stringResource(R.string.reverb_medium_hall) }
),
LargeHall(
preset = PresetReverb.PRESET_LARGEHALL,
displayName = { "Large hall" }
displayName = { stringResource(R.string.reverb_large_hall) }
),
Plate(
preset = PresetReverb.PRESET_PLATE,
displayName = { "Plate" }
displayName = { stringResource(R.string.reverb_plate) }
)
}
}
Loading

0 comments on commit b88f30c

Please sign in to comment.