Skip to content

Commit

Permalink
Various fixes (including now playing & lyrics performance)
Browse files Browse the repository at this point in the history
  • Loading branch information
toasterofbread committed Nov 5, 2022
1 parent 3ac4343 commit cf752f2
Show file tree
Hide file tree
Showing 18 changed files with 382 additions and 484 deletions.
6 changes: 4 additions & 2 deletions app/src/main/java/com/spectre7/spmp/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class MainActivity : ComponentActivity() {
Python.start(AndroidPlatform(this))
}

PlayerHost(this)
PlayerHost()

window.setFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
Expand All @@ -45,7 +45,9 @@ class MainActivity : ComponentActivity() {
theme = Theme.default()

Surface(modifier = Modifier.fillMaxSize()) {
PlayerView()
if (PlayerHost.service_connected) {
PlayerView()
}
}
}
}
Expand Down
49 changes: 25 additions & 24 deletions app/src/main/java/com/spectre7/spmp/PlayerHost.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import android.os.Binder
import android.os.IBinder
import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaSessionCompat
import android.util.Log
import android.view.KeyEvent
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.media.session.MediaButtonReceiver
Expand All @@ -24,46 +26,42 @@ import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
import com.google.android.exoplayer2.ui.PlayerNotificationManager
import com.spectre7.spmp.api.DataApi
import com.spectre7.spmp.model.Song
import com.spectre7.spmp.ui.layout.PlayerStatus
import com.spectre7.utils.sendToast
import kotlin.concurrent.thread

enum class SERVICE_INTENT_ACTIONS { STOP, BUTTON_VOLUME }

class PlayerHost(private var context: Context) {
class PlayerHost {

private lateinit var service: PlayerService
private var service_connected by mutableStateOf(false)

private var service: PlayerService? = null
private var service_bound: Boolean = false
private var service_connection: ServiceConnection? = null
private var service_intent: Intent? = null
private val context: Context
get() = MainActivity.context

init {
PlayerHost.instance = this
instance = this
getService()
}

companion object {
private lateinit var instance: PlayerHost
private val service: PlayerService?

lateinit var p_status: PlayerStatus

val service: PlayerService
get() = instance.service
val player: ExoPlayer
get() = service.player
val service_connected: Boolean
get() = instance.service_connected

fun release() {
instance.release()
}

fun interact(action: (player: ExoPlayer) -> Unit) {
interactService {
action(it.player)
}
}
fun interactService(action: (service: PlayerService) -> Unit) {
if (service == null) {
instance.getService {
action(service!!)
}
}
else {
action(service!!)
}
}
}

private fun release() {
Expand All @@ -79,17 +77,20 @@ class PlayerHost(private var context: Context) {
context.startForegroundService(service_intent)
}

println("binding service")

context.bindService(service_intent,
object : ServiceConnection {

override fun onServiceConnected(className: ComponentName, binder: IBinder) {
println("service connected")
service = (binder as PlayerService.PlayerBinder).getService()
service_bound = true
service_connected = true
on_connected?.invoke()
}

override fun onServiceDisconnected(arg0: ComponentName) {
service_bound = false
service_connected = false
}

}, 0)
Expand Down
35 changes: 13 additions & 22 deletions app/src/main/java/com/spectre7/spmp/api/DataApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ class DataApi {
fun getSongLyrics(song: Song, callback: (Song.Lyrics?) -> Unit) {
thread {
val params = mapOf("title" to song.title, "artist" to song.artist.nativeData.name)
val result = queryServer("/lyrics", parameters = params)
val result = queryServer("/lyrics", parameters = params, max_retries = 15)

if (result == null) {
callback(null)
Expand Down Expand Up @@ -500,7 +500,14 @@ class DataApi {
var request = getRequest(_tunnel)

fun getResult(): Response? {
val ret = OkHttpClient.Builder().readTimeout(timeout, TimeUnit.SECONDS).build().newCall(request).execute()
val ret: Response
try {
ret = OkHttpClient.Builder().readTimeout(timeout, TimeUnit.SECONDS).build().newCall(request).execute()
}
catch (e: java.net.ConnectException) {
println(e)
return null
}
if (ret.code == 401) {
throw RuntimeException("Server API key is invalid")
}
Expand All @@ -527,7 +534,7 @@ class DataApi {
}

if (result == null && throw_on_fail) {
throw RuntimeException("Request to server failed\nURL: ${request.url}")
throw RuntimeException("Request to server failed. Request URL: ${request.url}")
}
}

Expand All @@ -547,25 +554,9 @@ class DataApi {
}
}

fun getRecommendedFeed(): List<RecommendedFeedRow>? {
val data = queryServer("/feed", timeout=30)
if (data != null) {
return klaxon.parseArray(data)
}
else {
// TODO (this is temporary, maybe use radio of recent songs?)
// If server fetch fails, use fallback method
val songs = listOf(
Pair("XqKbuEDvaf8", "Quick picks"),
Pair("wPS_x6FiBx0", "Listen again"),
Pair("rgNdeflYdYw", "Listen again"),
Pair("KnPUJwZNV8Y", "Listen again"),
)
return List(songs.size) { song ->
val radio = getSongRadio(songs[song].first)
RecommendedFeedRow(songs[song].second, "(fallback)", List(radio.size) { RecommendedFeedRow.Item("song", radio[it]) })
}
}
fun getRecommendedFeed(): List<RecommendedFeedRow> {
val data = queryServer("/feed", timeout=30, throw_on_fail = true)!!
return klaxon.parseArray(data)!!
}
}
}
Expand Down
90 changes: 54 additions & 36 deletions app/src/main/java/com/spectre7/spmp/api/TextWithReading.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.SubcomposeLayout
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.platform.LocalDensity
Expand All @@ -23,12 +25,29 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.*

class TermInfo(val text: String, val data: Any?) {
var position: Offset = Offset(0f, 0f)
var rect: Rect = Rect(0f, 0f, 0f, 0f)
}

@Composable
fun MeasureUnconstrainedView(
viewToMeasure: @Composable () -> Unit,
content: @Composable (width: Int, height: Int) -> Unit,
) {
SubcomposeLayout { constraints ->
val measured = subcompose("viewToMeasure", viewToMeasure)[0]
.measure(Constraints())

val contentPlaceable = subcompose("content") {
content(measured.width, measured.height)
}[0].measure(constraints)

layout(contentPlaceable.width, contentPlaceable.height) {
contentPlaceable.place(0, 0)
}
}
}

@Composable
Expand Down Expand Up @@ -61,7 +80,6 @@ fun TextWithReading(
return buildAnnotatedString {

var child_index = 0
var children_length = 0

for (elem in textContent) {
val text = elem.text
Expand Down Expand Up @@ -91,43 +109,43 @@ fun TextWithReading(
val boxHeight = with(LocalDensity.current) { readingFontSize.toDp() }
val index = remember { child_index++ }

// LaunchedEffect(Unit) {
// if (text_positions != null) {
// text_positions[index].index = children_length
// children_length += text.length
// }
// }

val column_modifier = remember(text_positions == null) {
Modifier.fillMaxHeight().run {
if (text_positions != null) {
onPlaced { coords ->
text_positions[index].position = coords.positionInRoot()
val textElement = @Composable {
Text(text = text, fontSize = _fontSize, color = color)
}

MeasureUnconstrainedView(textElement) { width: Int, height: Int ->
val column_modifier = remember(text_positions == null) {
Modifier.fillMaxHeight().run {
if (text_positions != null) {
onPlaced { coords ->
text_positions[index].rect = Rect(coords.positionInRoot(), Size(width.toFloat(), height.toFloat()))
}
}
else {
this
}
}
else {
this
}
}
}

Column(
modifier = column_modifier,
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Bottom,
) {
Box(modifier = Modifier.requiredHeight(boxHeight + 3.dp)) {
if (showReadings && reading != null) {
Text(
modifier = Modifier.wrapContentWidth(unbounded = true),
text = reading,
style = TextStyle.Default.copy(fontSize = readingFontSize),
color = color
)
Column(
modifier = column_modifier,
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Bottom,
) {
Box(modifier = Modifier.requiredHeight(boxHeight + 3.dp)) {
if (showReadings && reading != null) {
Text(
modifier = Modifier.wrapContentWidth(unbounded = true),
text = reading,
style = TextStyle.Default.copy(fontSize = readingFontSize),
color = color
)
}
}
textElement()
}
Text(text = text, fontSize = _fontSize, color = color)
}

}
)
}
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/java/com/spectre7/spmp/model/Artist.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import com.spectre7.spmp.api.DataApi
import com.spectre7.spmp.ui.components.ArtistPreview
import com.spectre7.spmp.MainActivity
import com.spectre7.spmp.ui.component.ArtistPreview
import java.util.*

data class ArtistData (
Expand Down
5 changes: 1 addition & 4 deletions app/src/main/java/com/spectre7/spmp/model/Song.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@ import androidx.compose.ui.graphics.toArgb
import androidx.core.content.edit
import com.beust.klaxon.Json
import com.beust.klaxon.Klaxon
import com.spectre7.ptl.Ptl
import com.spectre7.spmp.MainActivity
import com.spectre7.spmp.R
import com.spectre7.spmp.api.DataApi
import com.spectre7.spmp.ui.components.SongPreview
import com.spectre7.utils.getString
import com.spectre7.spmp.ui.component.SongPreview
import java.io.FileNotFoundException
import java.net.URL
import java.time.Duration
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.spectre7.spmp.ui.components
package com.spectre7.spmp.ui.component

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
Expand All @@ -7,7 +7,6 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Info
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.spectre7.spmp.ui.components
package com.spectre7.spmp.ui.component

import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.FastOutSlowInEasing
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.spectre7.spmp.ui.components
package com.spectre7.spmp.ui.component

import androidx.compose.animation.*
import androidx.compose.animation.core.tween
Expand Down
Loading

0 comments on commit cf752f2

Please sign in to comment.