From bea1235502630bf837c56f246efaa25278317395 Mon Sep 17 00:00:00 2001 From: Gary Wang Date: Sat, 20 Nov 2021 00:12:02 +0800 Subject: [PATCH] prepare server summary bottom drawer --- README.org => TODO.org | 16 +- .../pcmdroid/ui/screen/main/MainPlayer.kt | 144 +++++------------- .../pcmdroid/ui/screen/main/ServerSummary.kt | 117 ++++++++++++++ .../blumia/pcmdroid/ui/screen/main/Sidebar.kt | 116 ++++++++++++++ app/src/main/res/values-zh/strings.xml | 3 + app/src/main/res/values/strings.xml | 3 + 6 files changed, 283 insertions(+), 116 deletions(-) rename README.org => TODO.org (51%) create mode 100644 app/src/main/java/net/blumia/pcmdroid/ui/screen/main/ServerSummary.kt create mode 100644 app/src/main/java/net/blumia/pcmdroid/ui/screen/main/Sidebar.kt diff --git a/README.org b/TODO.org similarity index 51% rename from README.org rename to TODO.org index 76f2bd3..8b97417 100644 --- a/README.org +++ b/TODO.org @@ -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 diff --git a/app/src/main/java/net/blumia/pcmdroid/ui/screen/main/MainPlayer.kt b/app/src/main/java/net/blumia/pcmdroid/ui/screen/main/MainPlayer.kt index 695c37e..8fbc487 100644 --- a/app/src/main/java/net/blumia/pcmdroid/ui/screen/main/MainPlayer.kt +++ b/app/src/main/java/net/blumia/pcmdroid/ui/screen/main/MainPlayer.kt @@ -69,99 +69,6 @@ fun NowPlaying() { } } -@Preview(showBackground = true) -@OptIn(ExperimentalMaterialApi::class) -@Composable -fun DrawerContent( - currentServer: Server? = null, - servers: List = listOf(), - drawerFolders: List = 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( diff --git a/app/src/main/java/net/blumia/pcmdroid/ui/screen/main/ServerSummary.kt b/app/src/main/java/net/blumia/pcmdroid/ui/screen/main/ServerSummary.kt new file mode 100644 index 0000000..348a572 --- /dev/null +++ b/app/src/main/java/net/blumia/pcmdroid/ui/screen/main/ServerSummary.kt @@ -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)) + }, + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/net/blumia/pcmdroid/ui/screen/main/Sidebar.kt b/app/src/main/java/net/blumia/pcmdroid/ui/screen/main/Sidebar.kt new file mode 100644 index 0000000..0945a8b --- /dev/null +++ b/app/src/main/java/net/blumia/pcmdroid/ui/screen/main/Sidebar.kt @@ -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 = listOf(), + drawerFolders: List = 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 + ) + } + ) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 3a438ee..1a63def 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -2,4 +2,7 @@ 私有云音乐 设置 添加 + 分享此服务器 + 删除服务器 + 编辑服务器信息 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9efca95..e806240 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,4 +2,7 @@ Private Cloud Music Settings Add + Share This Server + Delete Server + Edit Server Information \ No newline at end of file