fix livedata not updated, playlist not scrollable
This commit is contained in:
parent
4312d1fdea
commit
8edcb91242
|
@ -52,6 +52,7 @@ dependencies {
|
||||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||||
implementation 'com.google.android.material:material:1.4.0'
|
implementation 'com.google.android.material:material:1.4.0'
|
||||||
implementation "androidx.compose.ui:ui:$compose_version"
|
implementation "androidx.compose.ui:ui:$compose_version"
|
||||||
|
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
|
||||||
implementation "androidx.compose.material:material:$compose_version"
|
implementation "androidx.compose.material:material:$compose_version"
|
||||||
implementation "androidx.compose.material:material-icons-extended:$compose_version"
|
implementation "androidx.compose.material:material-icons-extended:$compose_version"
|
||||||
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
|
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
|
||||||
|
@ -59,6 +60,9 @@ dependencies {
|
||||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
|
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
|
||||||
implementation 'androidx.activity:activity-compose:1.4.0'
|
implementation 'androidx.activity:activity-compose:1.4.0'
|
||||||
implementation "androidx.datastore:datastore-preferences:1.0.0"
|
implementation "androidx.datastore:datastore-preferences:1.0.0"
|
||||||
|
|
||||||
|
implementation("com.squareup.okhttp3:okhttp:4.9.0")
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.+'
|
testImplementation 'junit:junit:4.+'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||||
|
|
|
@ -1,63 +1,132 @@
|
||||||
package net.blumia.pcmdroid
|
package net.blumia.pcmdroid
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.util.Log
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import net.blumia.pcmdroid.model.Folder
|
import net.blumia.pcmdroid.model.Folder
|
||||||
import net.blumia.pcmdroid.model.Server
|
import net.blumia.pcmdroid.model.Server
|
||||||
import net.blumia.pcmdroid.model.Song
|
import net.blumia.pcmdroid.model.Song
|
||||||
|
import net.blumia.pcmdroid.model.parseFromJsonString
|
||||||
|
import okhttp3.FormBody
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
|
||||||
class MainViewModel : ViewModel() {
|
class MainViewModel : ViewModel() {
|
||||||
|
|
||||||
|
private val httpClient: OkHttpClient = OkHttpClient()
|
||||||
|
|
||||||
val servers: LiveData<List<Server>> = MutableLiveData<List<Server>>(
|
val servers: LiveData<List<Server>> = MutableLiveData<List<Server>>(
|
||||||
listOf(
|
listOf(
|
||||||
Server(
|
Server(
|
||||||
url = Uri.parse("https://localhost/api.php"),
|
url = "http://localhost/api.php",
|
||||||
name = "PCM",
|
name = "PCM",
|
||||||
baseFolderName = "pcm",
|
baseFolderName = "pcm",
|
||||||
),
|
),
|
||||||
Server(
|
Server(
|
||||||
url = Uri.parse("https://localhost/api.php"),
|
url = "http://localhost/api.php",
|
||||||
name = "PCM2",
|
name = "PCM2",
|
||||||
baseFolderName = "pcm2",
|
baseFolderName = "pcm2",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val currentPath: LiveData<String> = MutableLiveData("")
|
private val _currentServer: MutableLiveData<Server> = MutableLiveData(null)
|
||||||
|
val currentServer: LiveData<Server> = _currentServer;
|
||||||
|
fun setCurrentServer(srv: Server) {
|
||||||
|
_currentServer.postValue(srv)
|
||||||
|
}
|
||||||
|
|
||||||
val drawerFolders: LiveData<List<Folder>> = MutableLiveData(
|
private val _currentPath: MutableLiveData<String> = MutableLiveData("")
|
||||||
|
val currentPath: LiveData<String> = _currentPath
|
||||||
|
|
||||||
|
private val _drawerFolders: MutableLiveData<List<Folder>> = MutableLiveData(
|
||||||
listOf(
|
listOf(
|
||||||
Folder("Test/"),
|
Folder("Test/"),
|
||||||
Folder("Folder/")
|
Folder("Folder/")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
val drawerFolders: LiveData<List<Folder>> = _drawerFolders
|
||||||
|
|
||||||
val folders: LiveData<List<Folder>> = MutableLiveData(
|
private val _folders: MutableLiveData<List<Folder>> = MutableLiveData(
|
||||||
listOf(
|
listOf(
|
||||||
Folder("Test/Converted-Modules/")
|
Folder("Test/Converted-Modules/")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
val folders: LiveData<List<Folder>> = _folders
|
||||||
|
|
||||||
val songs: LiveData<List<Song>> = MutableLiveData(
|
private val _songs: MutableLiveData<List<Song>> = MutableLiveData(
|
||||||
listOf(
|
listOf(
|
||||||
Song(
|
Song(
|
||||||
filePath = "Test/Rick Astley - Never Gonna Give You Up.mp3",
|
filePath = "Test/Rick Astley - Never Gonna Give You Up.mp3",
|
||||||
url = Uri.parse("http://localhost/rickroll.mp3")
|
url = "http://localhost/rickroll.mp3"
|
||||||
),
|
),
|
||||||
Song(
|
Song(
|
||||||
filePath = "Test/哇 好东西一堆.xm",
|
filePath = "Test/哇 好东西一堆.xm",
|
||||||
url = Uri.parse("http://localhost/rickroll.mp3")
|
url = "http://localhost/rickroll.mp3"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
val songs: LiveData<List<Song>> = _songs
|
||||||
|
|
||||||
fun fetchServer(srv: Server) {
|
fun fetchServer(srv: Server) {
|
||||||
//
|
viewModelScope.launch(context = Dispatchers.IO) {
|
||||||
|
|
||||||
|
val formBody = FormBody.Builder()
|
||||||
|
.add("do", "getfilelist")
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url(srv.url)
|
||||||
|
.post(formBody)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
httpClient.newCall(request).execute().use { response ->
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
// TODO: non-200 response will go to here too.
|
||||||
|
return@use
|
||||||
|
}
|
||||||
|
val pair = parseFromJsonString(response.body!!.string())
|
||||||
|
_drawerFolders.postValue(pair.first)
|
||||||
|
setCurrentServer(srv)
|
||||||
|
Log.d("vvv", drawerFolders.value.toString())
|
||||||
|
}
|
||||||
|
// Thread.sleep(5_000)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchFolder(folder: Folder) {
|
fun fetchFolder(folder: Folder) {
|
||||||
//
|
if (currentServer.value == null) return
|
||||||
|
val srv = currentServer.value!!
|
||||||
|
|
||||||
|
viewModelScope.launch(context = Dispatchers.IO) {
|
||||||
|
|
||||||
|
val formBody = FormBody.Builder()
|
||||||
|
.add("do", "getfilelist")
|
||||||
|
.add("folder", folder.folderPath)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url(srv.url)
|
||||||
|
.post(formBody)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
httpClient.newCall(request).execute().use { response ->
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
// TODO: non-200 response will go to here too.
|
||||||
|
return@use
|
||||||
|
}
|
||||||
|
val pair = parseFromJsonString(response.body!!.string())
|
||||||
|
_folders.postValue(pair.first)
|
||||||
|
_songs.postValue(pair.second)
|
||||||
|
Log.d("vvv", folders.value.toString())
|
||||||
|
}
|
||||||
|
// Thread.sleep(5_000)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,9 +1,7 @@
|
||||||
package net.blumia.pcmdroid.model
|
package net.blumia.pcmdroid.model
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
|
|
||||||
data class Server (
|
data class Server (
|
||||||
val url: Uri,
|
val url: String,
|
||||||
val name: String,
|
val name: String,
|
||||||
val baseFolderName: String,
|
val baseFolderName: String,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
package net.blumia.pcmdroid.model
|
package net.blumia.pcmdroid.model
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import org.json.JSONException
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.net.URLDecoder
|
||||||
|
|
||||||
data class Song (
|
data class Song (
|
||||||
val filePath: String, // with file name
|
val filePath: String, // with file name
|
||||||
val modifiedTime: Int = 0,
|
val modifiedTime: Long = 0,
|
||||||
val fileSize: Int = 0,
|
val fileSize: Int = 0,
|
||||||
val additionalInfo: Boolean = false, // if sidecar meta-info json file exist.
|
val additionalInfo: Boolean = false, // if sidecar meta-info json file exist.
|
||||||
val url: Uri,
|
val url: String,
|
||||||
) {
|
) {
|
||||||
fun displayName(): String {
|
fun displayName(): String {
|
||||||
return Uri.parse(filePath).lastPathSegment ?: "???"
|
return Uri.parse(filePath).lastPathSegment ?: "???"
|
||||||
|
@ -18,6 +21,41 @@ data class Folder (
|
||||||
val folderPath: String,
|
val folderPath: String,
|
||||||
) {
|
) {
|
||||||
fun displayName(): String {
|
fun displayName(): String {
|
||||||
return Uri.parse(folderPath).lastPathSegment ?: "???"
|
return URLDecoder.decode(Uri.parse(folderPath).lastPathSegment ?: "???", "UTF-8")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun parseFromJsonString(jsonString: String): Pair<List<Folder>, List<Song>> {
|
||||||
|
val folders = mutableListOf<Folder>()
|
||||||
|
val songs = mutableListOf<Song>()
|
||||||
|
|
||||||
|
try {
|
||||||
|
val jsonObj = JSONObject(jsonString)
|
||||||
|
val result = jsonObj.getJSONObject("result")
|
||||||
|
val data = result.getJSONObject("data")
|
||||||
|
val subFolders = data.getJSONArray("subFolderList")
|
||||||
|
val musicList = data.getJSONArray("musicList")
|
||||||
|
for (i in 0 until subFolders.length()) {
|
||||||
|
val rawFolderName = subFolders.getString(i)
|
||||||
|
folders.add(Folder(rawFolderName))
|
||||||
|
}
|
||||||
|
for (i in 0 until musicList.length()) {
|
||||||
|
val fileObject = musicList.getJSONObject(i)
|
||||||
|
val rawFileName = fileObject.getString("fileName")
|
||||||
|
val fileName = URLDecoder.decode(rawFileName, "UTF-8")
|
||||||
|
val modifiedTime = fileObject.getLong("modifiedTime")
|
||||||
|
val fileSize = fileObject.getLong("fileSize")
|
||||||
|
songs.add(
|
||||||
|
Song(
|
||||||
|
rawFileName,
|
||||||
|
modifiedTime = modifiedTime,
|
||||||
|
url = rawFileName
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (e: JSONException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pair(folders, songs)
|
||||||
}
|
}
|
|
@ -1,11 +1,16 @@
|
||||||
package net.blumia.pcmdroid.ui
|
package net.blumia.pcmdroid.ui
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import net.blumia.pcmdroid.MainViewModel
|
import net.blumia.pcmdroid.MainViewModel
|
||||||
|
import net.blumia.pcmdroid.model.Folder
|
||||||
|
import net.blumia.pcmdroid.model.Server
|
||||||
|
import net.blumia.pcmdroid.model.Song
|
||||||
import net.blumia.pcmdroid.ui.screen.addserver.AddServerScreen
|
import net.blumia.pcmdroid.ui.screen.addserver.AddServerScreen
|
||||||
import net.blumia.pcmdroid.ui.screen.main.MainPlayer
|
import net.blumia.pcmdroid.ui.screen.main.MainPlayer
|
||||||
import net.blumia.pcmdroid.ui.screen.settings.SettingsScreen
|
import net.blumia.pcmdroid.ui.screen.settings.SettingsScreen
|
||||||
|
@ -27,11 +32,26 @@ fun NavGraph(
|
||||||
startDestination = startDestination
|
startDestination = startDestination
|
||||||
) {
|
) {
|
||||||
composable(MainDestinations.MAIN_ROUTE) {
|
composable(MainDestinations.MAIN_ROUTE) {
|
||||||
|
|
||||||
|
val servers: List<Server> by viewModel.servers.observeAsState(initial = listOf())
|
||||||
|
val drawerFolders: List<Folder> by viewModel.drawerFolders.observeAsState(initial = listOf())
|
||||||
|
val folders: List<Folder> by viewModel.folders.observeAsState(listOf())
|
||||||
|
val songs: List<Song> by viewModel.songs.observeAsState(listOf())
|
||||||
|
|
||||||
MainPlayer(
|
MainPlayer(
|
||||||
viewModel = viewModel,
|
servers = servers,
|
||||||
|
drawerFolders = drawerFolders,
|
||||||
|
folders = folders,
|
||||||
|
songs = songs,
|
||||||
addServerActionTriggered = {
|
addServerActionTriggered = {
|
||||||
navController.navigate(MainDestinations.ADD_SERVER_ROUTE)
|
navController.navigate(MainDestinations.ADD_SERVER_ROUTE)
|
||||||
},
|
},
|
||||||
|
onServerItemIconClicked = { server ->
|
||||||
|
viewModel.fetchServer(server)
|
||||||
|
},
|
||||||
|
onDrawerFolderItemClicked = { folder ->
|
||||||
|
viewModel.fetchFolder(folder)
|
||||||
|
},
|
||||||
settingsActionTriggered = {
|
settingsActionTriggered = {
|
||||||
navController.navigate(MainDestinations.SETTINGS_ROUTE)
|
navController.navigate(MainDestinations.SETTINGS_ROUTE)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
package net.blumia.pcmdroid.ui.screen.main
|
package net.blumia.pcmdroid.ui.screen.main
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.*
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.gestures.scrollable
|
import androidx.compose.foundation.gestures.scrollable
|
||||||
import androidx.compose.foundation.horizontalScroll
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.*
|
import androidx.compose.material.icons.filled.*
|
||||||
|
@ -15,6 +12,9 @@ import androidx.compose.material.icons.rounded.PlayArrow
|
||||||
import androidx.compose.material.icons.rounded.PlayCircle
|
import androidx.compose.material.icons.rounded.PlayCircle
|
||||||
import androidx.compose.material.icons.rounded.PlayCircleOutline
|
import androidx.compose.material.icons.rounded.PlayCircleOutline
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
@ -24,7 +24,6 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.blumia.pcmdroid.MainViewModel
|
|
||||||
import net.blumia.pcmdroid.R
|
import net.blumia.pcmdroid.R
|
||||||
import net.blumia.pcmdroid.model.Folder
|
import net.blumia.pcmdroid.model.Folder
|
||||||
import net.blumia.pcmdroid.model.Server
|
import net.blumia.pcmdroid.model.Server
|
||||||
|
@ -74,15 +73,17 @@ fun NowPlaying() {
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun DrawerContent(
|
fun DrawerContent(
|
||||||
viewModel: MainViewModel = MainViewModel(),
|
servers: List<Server> = listOf(),
|
||||||
|
drawerFolders: List<Folder> = listOf(),
|
||||||
addServerActionTriggered: () -> Unit = {},
|
addServerActionTriggered: () -> Unit = {},
|
||||||
|
onServerItemIconClicked: (Server) -> Unit = {},
|
||||||
|
onDrawerFolderItemClicked: (Folder) -> Unit = {},
|
||||||
settingsActionTriggered: () -> Unit = {},
|
settingsActionTriggered: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
Row(modifier = Modifier.fillMaxSize()) {
|
Row(modifier = Modifier.fillMaxSize()) {
|
||||||
var selectedItem by remember { mutableStateOf<Int?>(0) }
|
var selectedItem by remember { mutableStateOf<Int?>(0) }
|
||||||
val servers = viewModel.servers.value
|
|
||||||
NavigationRail {
|
NavigationRail {
|
||||||
servers?.forEachIndexed { index, server ->
|
servers.forEachIndexed { index, server ->
|
||||||
NavigationRailItem(
|
NavigationRailItem(
|
||||||
icon = {
|
icon = {
|
||||||
Icon(
|
Icon(
|
||||||
|
@ -94,7 +95,7 @@ fun DrawerContent(
|
||||||
},
|
},
|
||||||
selected = selectedItem == index,
|
selected = selectedItem == index,
|
||||||
onClick = {
|
onClick = {
|
||||||
viewModel.fetchServer(server)
|
onServerItemIconClicked(server)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -133,11 +134,10 @@ fun DrawerContent(
|
||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
|
|
||||||
val drawerFolders = viewModel.drawerFolders.value
|
drawerFolders.forEach { folder ->
|
||||||
drawerFolders?.forEach { folder ->
|
|
||||||
ListItem(
|
ListItem(
|
||||||
modifier = Modifier.clickable{
|
modifier = Modifier.clickable{
|
||||||
viewModel.fetchFolder(folder)
|
onDrawerFolderItemClicked(folder)
|
||||||
},
|
},
|
||||||
text = {
|
text = {
|
||||||
Text(
|
Text(
|
||||||
|
@ -155,8 +155,13 @@ fun DrawerContent(
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun MainPlayer(
|
fun MainPlayer(
|
||||||
viewModel: MainViewModel = MainViewModel(),
|
servers: List<Server> = listOf(),
|
||||||
|
drawerFolders: List<Folder> = listOf(),
|
||||||
|
folders: List<Folder> = listOf(),
|
||||||
|
songs: List<Song> = listOf(),
|
||||||
addServerActionTriggered: () -> Unit = {},
|
addServerActionTriggered: () -> Unit = {},
|
||||||
|
onServerItemIconClicked: (Server) -> Unit = {},
|
||||||
|
onDrawerFolderItemClicked: (Folder) -> Unit = {},
|
||||||
settingsActionTriggered: () -> Unit = {},
|
settingsActionTriggered: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
||||||
|
@ -165,8 +170,11 @@ fun MainPlayer(
|
||||||
drawerState = drawerState,
|
drawerState = drawerState,
|
||||||
drawerContent = {
|
drawerContent = {
|
||||||
DrawerContent(
|
DrawerContent(
|
||||||
viewModel = viewModel,
|
servers = servers,
|
||||||
|
drawerFolders = drawerFolders,
|
||||||
addServerActionTriggered = addServerActionTriggered,
|
addServerActionTriggered = addServerActionTriggered,
|
||||||
|
onServerItemIconClicked = onServerItemIconClicked,
|
||||||
|
onDrawerFolderItemClicked = onDrawerFolderItemClicked,
|
||||||
settingsActionTriggered = settingsActionTriggered,
|
settingsActionTriggered = settingsActionTriggered,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -195,7 +203,11 @@ fun MainPlayer(
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
Column(modifier = Modifier.weight(1f, fill = true)) {
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f, fill = true)
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
|
) {
|
||||||
|
|
||||||
val iconLeftPadding = 16.dp
|
val iconLeftPadding = 16.dp
|
||||||
val iconVerticalPadding = 12.dp
|
val iconVerticalPadding = 12.dp
|
||||||
|
@ -229,7 +241,7 @@ fun MainPlayer(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.folders.value?.forEach { folder ->
|
folders.forEach { folder ->
|
||||||
ListItem(
|
ListItem(
|
||||||
modifier = Modifier.clickable { },
|
modifier = Modifier.clickable { },
|
||||||
icon = {
|
icon = {
|
||||||
|
@ -244,7 +256,7 @@ fun MainPlayer(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.songs.value?.forEach { song ->
|
songs.forEach { song ->
|
||||||
ListItem(
|
ListItem(
|
||||||
modifier = Modifier.clickable { },
|
modifier = Modifier.clickable { },
|
||||||
icon = {
|
icon = {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user