prepare server summary bottom drawer
This commit is contained in:
parent
1d2ded1eee
commit
bea1235502
|
@ -1,23 +1,25 @@
|
|||
TODO
|
||||
|
||||
* TODO Add server
|
||||
* Basic functionality
|
||||
|
||||
- [x] Create
|
||||
- [ ] Delete
|
||||
** TODO Manage servers [1/3]
|
||||
|
||||
- [X] Create
|
||||
- [ ] Update
|
||||
- [ ] Delete
|
||||
|
||||
* TODO Music playback
|
||||
** TODO Music playback [0/3]
|
||||
|
||||
- [ ] Regular playback
|
||||
- [ ] Playlist
|
||||
- [ ] Media session
|
||||
|
||||
* TODO Download music to local folder
|
||||
** TODO Download music to local folder [0/2]
|
||||
|
||||
- [ ] Select and remember selected folder
|
||||
- [ ] Download music
|
||||
|
||||
* TODO Misc.
|
||||
|
||||
** TODO Misc. [0/1]
|
||||
|
||||
- [ ] Back key to navigate folder up
|
||||
|
|
@ -69,99 +69,6 @@ fun NowPlaying() {
|
|||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun DrawerContent(
|
||||
currentServer: Server? = null,
|
||||
servers: List<Server> = listOf(),
|
||||
drawerFolders: List<Folder> = listOf(),
|
||||
addServerActionTriggered: () -> Unit = {},
|
||||
onServerItemIconClicked: (Server) -> Unit = {},
|
||||
onDrawerFolderItemClicked: (Folder) -> Unit = {},
|
||||
settingsActionTriggered: () -> Unit = {},
|
||||
) {
|
||||
val currentServerApiUrl = currentServer?.url
|
||||
|
||||
Row(modifier = Modifier.fillMaxSize()) {
|
||||
NavigationRail {
|
||||
servers.forEachIndexed { index, server ->
|
||||
NavigationRailItem(
|
||||
icon = {
|
||||
Icon(
|
||||
Icons.Filled.LibraryMusic, server.name
|
||||
)
|
||||
},
|
||||
label = {
|
||||
Text(server.displayName())
|
||||
},
|
||||
selected = server.url == currentServerApiUrl,
|
||||
onClick = {
|
||||
onServerItemIconClicked(server)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
NavigationRailItem(
|
||||
icon = { Icon(Icons.Filled.AddCircle, null) },
|
||||
label = { Text(stringResource(id = R.string.add)) },
|
||||
selected = false,
|
||||
onClick = addServerActionTriggered,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
NavigationRailItem(
|
||||
icon = { Icon(Icons.Filled.Settings, null) },
|
||||
label = { Text(stringResource(id = R.string.settings)) },
|
||||
selected = false,
|
||||
onClick = settingsActionTriggered,
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
) {
|
||||
ListItem(
|
||||
text = {
|
||||
Text(
|
||||
text = currentServer?.displayName() ?: "No server selected",
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
},
|
||||
trailing = {
|
||||
IconButton(onClick = { /*TODO*/ }) {
|
||||
Icon(imageVector = Icons.Filled.MoreVert, contentDescription = "Menu")
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
Divider()
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f, fill = true)
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
drawerFolders.forEach { folder ->
|
||||
ListItem(
|
||||
modifier = Modifier.clickable{
|
||||
onDrawerFolderItemClicked(folder)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
text = folder.displayName(),
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
|
@ -177,30 +84,33 @@ fun MainPlayer(
|
|||
onFolderItemClicked: (Folder) -> Unit = {},
|
||||
settingsActionTriggered: () -> Unit = {},
|
||||
) {
|
||||
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
||||
val drawerScope = rememberCoroutineScope()
|
||||
ModalDrawer(
|
||||
drawerState = drawerState,
|
||||
val bottomDrawerState = rememberBottomDrawerState(initialValue = BottomDrawerValue.Closed)
|
||||
val bottomDrawerScope = rememberCoroutineScope()
|
||||
BottomDrawer(
|
||||
drawerState = bottomDrawerState,
|
||||
gesturesEnabled = bottomDrawerState.isOpen,
|
||||
drawerContent = {
|
||||
DrawerContent(
|
||||
currentServer = currentServer,
|
||||
servers = servers,
|
||||
drawerFolders = drawerFolders,
|
||||
addServerActionTriggered = addServerActionTriggered,
|
||||
onServerItemIconClicked = onServerItemIconClicked,
|
||||
onDrawerFolderItemClicked = onFolderItemClicked,
|
||||
settingsActionTriggered = settingsActionTriggered,
|
||||
)
|
||||
}
|
||||
if (currentServer != null) {
|
||||
ServerSummaryDrawer(currentServer)
|
||||
} else {
|
||||
Text(
|
||||
"TODO: play control and playlist?",
|
||||
modifier = Modifier.fillMaxWidth().padding(16.dp),
|
||||
)
|
||||
}
|
||||
},
|
||||
) {
|
||||
val scaffoldState = rememberScaffoldState()
|
||||
val scaffoldScope = rememberCoroutineScope()
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(id = R.string.app_name)) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = {
|
||||
drawerScope.launch {
|
||||
drawerState.open()
|
||||
scaffoldScope.launch {
|
||||
scaffoldState.drawerState.open()
|
||||
}
|
||||
}) {
|
||||
Icon(imageVector = Icons.Filled.Menu, contentDescription = "Open drawer")
|
||||
|
@ -212,6 +122,22 @@ fun MainPlayer(
|
|||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
drawerContent = {
|
||||
SidebarContent(
|
||||
currentServer = currentServer,
|
||||
servers = servers,
|
||||
drawerFolders = drawerFolders,
|
||||
addServerActionTriggered = addServerActionTriggered,
|
||||
onServerItemIconClicked = onServerItemIconClicked,
|
||||
onServerMenuIconClicked = {
|
||||
bottomDrawerScope.launch {
|
||||
bottomDrawerState.open()
|
||||
}
|
||||
},
|
||||
onDrawerFolderItemClicked = onFolderItemClicked,
|
||||
settingsActionTriggered = settingsActionTriggered,
|
||||
)
|
||||
}
|
||||
) {
|
||||
Column(
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
package net.blumia.pcmdroid.ui.screen.main
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import net.blumia.pcmdroid.R
|
||||
import net.blumia.pcmdroid.model.Server
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun RowScope.ActionIcon(
|
||||
imageVector: ImageVector = Icons.Filled.Share,
|
||||
contentDescription: String = "Share",
|
||||
onActionTriggered: () -> Unit = {},
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier.weight(1f),
|
||||
onClick = onActionTriggered,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(10.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Icon(imageVector = imageVector, contentDescription = contentDescription)
|
||||
Text(contentDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun ServerSummaryDrawer(
|
||||
server: Server = Server("http://localhost/", "Demo server", "pcm"),
|
||||
onShareActionTriggered: (Server) -> Unit = {},
|
||||
onEditActionTriggered: (Server) -> Unit = {},
|
||||
onDeleteActionTriggered: (Server) -> Unit = {},
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = 16.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(horizontal = 16.dp)
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(50.dp),
|
||||
imageVector = Icons.Filled.LibraryMusic,
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 10.dp),
|
||||
text = server.displayName(),
|
||||
// textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.h5,
|
||||
)
|
||||
}
|
||||
// Row(
|
||||
// modifier = Modifier.fillMaxWidth(),
|
||||
// ) {
|
||||
// ActionIcon(
|
||||
// imageVector = Icons.Filled.Share,
|
||||
// contentDescription = "Share",
|
||||
// )
|
||||
// ActionIcon(
|
||||
// imageVector = Icons.Filled.Edit,
|
||||
// contentDescription = "Edit",
|
||||
// )
|
||||
// }
|
||||
ListItem(
|
||||
modifier = Modifier.clickable {
|
||||
onShareActionTriggered(server)
|
||||
},
|
||||
icon = {
|
||||
Icon(Icons.Filled.Share, null)
|
||||
},
|
||||
text = {
|
||||
Text(stringResource(id = R.string.share_this_server))
|
||||
},
|
||||
)
|
||||
ListItem(
|
||||
modifier = Modifier.clickable {
|
||||
onEditActionTriggered(server)
|
||||
},
|
||||
icon = {
|
||||
Icon(Icons.Filled.Edit, null)
|
||||
},
|
||||
text = {
|
||||
Text(stringResource(id = R.string.edit_server_info))
|
||||
},
|
||||
)
|
||||
ListItem(
|
||||
modifier = Modifier.clickable {
|
||||
onDeleteActionTriggered(server)
|
||||
},
|
||||
icon = {
|
||||
Icon(Icons.Filled.Delete, null)
|
||||
},
|
||||
text = {
|
||||
Text(stringResource(id = R.string.delete_server))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
116
app/src/main/java/net/blumia/pcmdroid/ui/screen/main/Sidebar.kt
Normal file
116
app/src/main/java/net/blumia/pcmdroid/ui/screen/main/Sidebar.kt
Normal file
|
@ -0,0 +1,116 @@
|
|||
package net.blumia.pcmdroid.ui.screen.main
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.AddCircle
|
||||
import androidx.compose.material.icons.filled.LibraryMusic
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import net.blumia.pcmdroid.R
|
||||
import net.blumia.pcmdroid.model.Folder
|
||||
import net.blumia.pcmdroid.model.Server
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun SidebarContent(
|
||||
currentServer: Server? = null,
|
||||
servers: List<Server> = listOf(),
|
||||
drawerFolders: List<Folder> = listOf(),
|
||||
addServerActionTriggered: () -> Unit = {},
|
||||
onServerItemIconClicked: (Server) -> Unit = {},
|
||||
onServerMenuIconClicked: () -> Unit = {},
|
||||
onDrawerFolderItemClicked: (Folder) -> Unit = {},
|
||||
settingsActionTriggered: () -> Unit = {},
|
||||
) {
|
||||
val currentServerApiUrl = currentServer?.url
|
||||
|
||||
Row(modifier = Modifier.fillMaxSize()) {
|
||||
NavigationRail {
|
||||
servers.forEachIndexed { index, server ->
|
||||
NavigationRailItem(
|
||||
icon = {
|
||||
Icon(
|
||||
Icons.Filled.LibraryMusic, server.name
|
||||
)
|
||||
},
|
||||
label = {
|
||||
Text(server.displayName())
|
||||
},
|
||||
selected = server.url == currentServerApiUrl,
|
||||
onClick = {
|
||||
onServerItemIconClicked(server)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
NavigationRailItem(
|
||||
icon = { Icon(Icons.Filled.AddCircle, null) },
|
||||
label = { Text(stringResource(id = R.string.add)) },
|
||||
selected = false,
|
||||
onClick = addServerActionTriggered,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
NavigationRailItem(
|
||||
icon = { Icon(Icons.Filled.Settings, null) },
|
||||
label = { Text(stringResource(id = R.string.settings)) },
|
||||
selected = false,
|
||||
onClick = settingsActionTriggered,
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
) {
|
||||
ListItem(
|
||||
text = {
|
||||
Text(
|
||||
text = currentServer?.displayName() ?: "No server selected",
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
},
|
||||
trailing = {
|
||||
IconButton(onClick = onServerMenuIconClicked) {
|
||||
Icon(imageVector = Icons.Filled.MoreVert, contentDescription = "Menu")
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
Divider()
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f, fill = true)
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
drawerFolders.forEach { folder ->
|
||||
ListItem(
|
||||
modifier = Modifier.clickable{
|
||||
onDrawerFolderItemClicked(folder)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
text = folder.displayName(),
|
||||
style = MaterialTheme.typography.subtitle1
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,4 +2,7 @@
|
|||
<string name="app_name">私有云音乐</string>
|
||||
<string name="settings">设置</string>
|
||||
<string name="add">添加</string>
|
||||
<string name="share_this_server">分享此服务器</string>
|
||||
<string name="delete_server">删除服务器</string>
|
||||
<string name="edit_server_info">编辑服务器信息</string>
|
||||
</resources>
|
|
@ -2,4 +2,7 @@
|
|||
<string name="app_name">Private Cloud Music</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="add">Add</string>
|
||||
<string name="share_this_server">Share This Server</string>
|
||||
<string name="delete_server">Delete Server</string>
|
||||
<string name="edit_server_info">Edit Server Information</string>
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user