diff --git a/README.md b/README.md deleted file mode 100644 index 5dff559..0000000 --- a/README.md +++ /dev/null @@ -1,6 +0,0 @@ -TODO: - -- [ ] Add server -- [ ] Music playback -- [ ] Download music to local folder -- [ ] Back key to navigate folder up \ No newline at end of file diff --git a/README.org b/README.org new file mode 100644 index 0000000..76f2bd3 --- /dev/null +++ b/README.org @@ -0,0 +1,23 @@ +TODO + +* TODO Add server + +- [x] Create +- [ ] Delete +- [ ] Update + +* TODO Music playback + +- [ ] Regular playback +- [ ] Playlist +- [ ] Media session + +* TODO Download music to local folder + +- [ ] Select and remember selected folder +- [ ] Download music + +* TODO Misc. + +- [ ] Back key to navigate folder up + diff --git a/app/src/main/java/net/blumia/pcmdroid/MainViewModel.kt b/app/src/main/java/net/blumia/pcmdroid/MainViewModel.kt index 3f08fe6..397850e 100644 --- a/app/src/main/java/net/blumia/pcmdroid/MainViewModel.kt +++ b/app/src/main/java/net/blumia/pcmdroid/MainViewModel.kt @@ -36,33 +36,13 @@ class MainViewModel(private val repository: ServerRepository) : ViewModel() { _currentFolder.postValue(folder) } - private val _drawerFolders: MutableLiveData> = MutableLiveData( - listOf( - Folder("Test/"), - Folder("Folder/"), - ) - ) + private val _drawerFolders: MutableLiveData> = MutableLiveData(listOf()) val drawerFolders: LiveData> = _drawerFolders - private val _folders: MutableLiveData> = MutableLiveData( - listOf( - Folder("Test/Converted-Modules/") - ) - ) + private val _folders: MutableLiveData> = MutableLiveData(listOf()) val folders: LiveData> = _folders - private val _songs: MutableLiveData> = MutableLiveData( - listOf( - Song( - filePath = "Test/Rick Astley - Never Gonna Give You Up.mp3", - url = "http://localhost/rickroll.mp3" - ), - Song( - filePath = "Test/哇 好东西一堆.xm", - url = "http://localhost/rickroll.mp3" - ) - ) - ) + private val _songs: MutableLiveData> = MutableLiveData(listOf()) val songs: LiveData> = _songs fun fetchServer(srv: Server) { diff --git a/app/src/main/java/net/blumia/pcmdroid/model/Server.kt b/app/src/main/java/net/blumia/pcmdroid/model/Server.kt index 58853f4..ec9f1c5 100644 --- a/app/src/main/java/net/blumia/pcmdroid/model/Server.kt +++ b/app/src/main/java/net/blumia/pcmdroid/model/Server.kt @@ -26,6 +26,9 @@ interface ServerDao { @Insert(onConflict = OnConflictStrategy.IGNORE) suspend fun insert(server: Server) + @Delete + suspend fun delete(server: Server) + @Query("DELETE FROM server_table") suspend fun deleteAll() } \ No newline at end of file diff --git a/app/src/main/java/net/blumia/pcmdroid/ui/NavGraph.kt b/app/src/main/java/net/blumia/pcmdroid/ui/NavGraph.kt index 4a1caaa..7f32b1c 100644 --- a/app/src/main/java/net/blumia/pcmdroid/ui/NavGraph.kt +++ b/app/src/main/java/net/blumia/pcmdroid/ui/NavGraph.kt @@ -66,6 +66,10 @@ fun NavGraph( AddServerScreen( onCloseActionTriggered = { navController.navigateUp() + }, + onSubmitServerTriggered = { srv -> + viewModel.addServer(srv) + navController.navigateUp() } ) } diff --git a/app/src/main/java/net/blumia/pcmdroid/ui/screen/addserver/AddServer.kt b/app/src/main/java/net/blumia/pcmdroid/ui/screen/addserver/AddServer.kt index b2b1419..649c99b 100644 --- a/app/src/main/java/net/blumia/pcmdroid/ui/screen/addserver/AddServer.kt +++ b/app/src/main/java/net/blumia/pcmdroid/ui/screen/addserver/AddServer.kt @@ -2,24 +2,119 @@ package net.blumia.pcmdroid.ui.screen.addserver import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.AddCircle import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.rounded.AddCircle -import androidx.compose.runtime.Composable +import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import net.blumia.pcmdroid.model.Server + +@Composable +fun StepEnterApiUrl( + urlStr: String = "", + onUrlStrChange: (String) -> Unit = {}, +) { + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Icon( + modifier = Modifier.size(50.dp), + imageVector = Icons.Filled.AddCircle, + contentDescription = null, + ) + Text( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 10.dp), + text = "Add Server", + textAlign = TextAlign.Center, + style = MaterialTheme.typography.h5, + ) + Text( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 10.dp), + text = "Add Private Cloud Music server", + textAlign = TextAlign.Center, + style = MaterialTheme.typography.subtitle2, + ) + OutlinedTextField( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 10.dp), + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Uri, + ), + value = urlStr, + onValueChange = onUrlStrChange, + label = { Text("Server API Url") }, + ) + } +} + +@Composable +fun StepOtherDetail( + nameStr: String = "", + onNameStrChange: (String) -> Unit = {}, + baseFolderNameStr: String = "", + onBaseFolderNameStrChange: (String) -> Unit = {}, +) { + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + OutlinedTextField( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 10.dp), + value = nameStr, + onValueChange = onNameStrChange, + label = { Text("Server name") }, + ) + + OutlinedTextField( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 10.dp), + value = baseFolderNameStr, + onValueChange = onBaseFolderNameStrChange, + label = { Text("Base folder name") }, + ) + } +} @Preview(showBackground = true) @Composable fun AddServerScreen( onCloseActionTriggered: () -> Unit = {}, + onSubmitServerTriggered: (Server) -> Unit = {}, ) { + var stepState by remember { mutableStateOf(0) } + val finalStep = 1 + + fun onNextStepButtonTriggered() { + if (stepState < 1) { + stepState++ + } + } + + fun onPreviousStepButtonTriggered() { + if (stepState > 0) { + stepState-- + } + } + Scaffold( topBar = { TopAppBar( @@ -40,52 +135,69 @@ fun AddServerScreen( .padding(20.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - Icon( - modifier = Modifier.size(50.dp), - imageVector = Icons.Filled.AddCircle, - contentDescription = null, - ) - Text( + var urlStr by rememberSaveable { mutableStateOf("") } + var nameStr by rememberSaveable { mutableStateOf("") } + var baseFolderNameStr by rememberSaveable { mutableStateOf("") } + + Column( modifier = Modifier .fillMaxWidth() - .padding(vertical = 10.dp), - text = "Add Server", - textAlign = TextAlign.Center, - style = MaterialTheme.typography.h5, - ) - Text( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 10.dp), - text = "Add Private Cloud Music server", - textAlign = TextAlign.Center, - style = MaterialTheme.typography.subtitle2, - ) - OutlinedTextField( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 10.dp), - value = "", - onValueChange = {}, - label = { Text("Server API Url") }, - ) - Spacer(modifier = Modifier.weight(1f)) + .weight(1f) + ) { + + when (stepState) { + 0 -> { + StepEnterApiUrl( + urlStr, + onUrlStrChange = { value -> + urlStr = value + }, + ) + } + 1 -> { + StepOtherDetail( + nameStr, + onNameStrChange = { value -> + nameStr = value + }, + baseFolderNameStr, + onBaseFolderNameStrChange = { value -> + baseFolderNameStr = value + }, + ) + } + } + + + } + Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { TextButton( - onClick = { /*TODO*/ }, - enabled = false + onClick = ::onPreviousStepButtonTriggered, + enabled = stepState != 0, ) { Text("Back") } Button( - onClick = { /*TODO*/ }, + onClick = { + if (stepState != finalStep) { + onNextStepButtonTriggered() + } else { + val srv = Server( + url = urlStr, + name = nameStr, + baseFolderName = baseFolderNameStr, + ) + onSubmitServerTriggered(srv) + } + }, shape = RoundedCornerShape(50) ) { Text( - text = "Next", + text = if (stepState != finalStep) "Next" else "Done", modifier = Modifier.padding(horizontal = 5.dp) ) }