basic ui mock-up
This commit is contained in:
		
							
								
								
									
										6
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<project version="4">
 | 
				
			||||||
 | 
					  <component name="VcsDirectoryMappings">
 | 
				
			||||||
 | 
					    <mapping directory="$PROJECT_DIR$" vcs="Git" />
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
@ -53,6 +53,7 @@ dependencies {
 | 
				
			|||||||
    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.material:material:$compose_version"
 | 
					    implementation "androidx.compose.material:material:$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"
 | 
				
			||||||
    implementation "androidx.navigation:navigation-compose:$nav_compose_version"
 | 
					    implementation "androidx.navigation:navigation-compose:$nav_compose_version"
 | 
				
			||||||
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
 | 
					    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,8 @@
 | 
				
			|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
					<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
    package="net.blumia.pcmdroid">
 | 
					    package="net.blumia.pcmdroid">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <uses-permission android:name="android.permission.INTERNET"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <application
 | 
					    <application
 | 
				
			||||||
        android:allowBackup="true"
 | 
					        android:allowBackup="true"
 | 
				
			||||||
        android:icon="@mipmap/ic_launcher"
 | 
					        android:icon="@mipmap/ic_launcher"
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,7 @@ package net.blumia.pcmdroid
 | 
				
			|||||||
import android.os.Bundle
 | 
					import android.os.Bundle
 | 
				
			||||||
import androidx.activity.ComponentActivity
 | 
					import androidx.activity.ComponentActivity
 | 
				
			||||||
import androidx.activity.compose.setContent
 | 
					import androidx.activity.compose.setContent
 | 
				
			||||||
 | 
					import androidx.activity.viewModels
 | 
				
			||||||
import androidx.compose.material.MaterialTheme
 | 
					import androidx.compose.material.MaterialTheme
 | 
				
			||||||
import androidx.compose.material.Surface
 | 
					import androidx.compose.material.Surface
 | 
				
			||||||
import androidx.compose.material.Text
 | 
					import androidx.compose.material.Text
 | 
				
			||||||
@ -13,28 +14,18 @@ import net.blumia.pcmdroid.ui.screen.main.MainPlayer
 | 
				
			|||||||
import net.blumia.pcmdroid.ui.theme.PrivateCloudMusicTheme
 | 
					import net.blumia.pcmdroid.ui.theme.PrivateCloudMusicTheme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MainActivity : ComponentActivity() {
 | 
					class MainActivity : ComponentActivity() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private val model: MainViewModel by viewModels()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
					    override fun onCreate(savedInstanceState: Bundle?) {
 | 
				
			||||||
        super.onCreate(savedInstanceState)
 | 
					        super.onCreate(savedInstanceState)
 | 
				
			||||||
        setContent {
 | 
					        setContent {
 | 
				
			||||||
            PrivateCloudMusicTheme {
 | 
					            PrivateCloudMusicTheme {
 | 
				
			||||||
                // A surface container using the 'background' color from the theme
 | 
					                // A surface container using the 'background' color from the theme
 | 
				
			||||||
                Surface(color = MaterialTheme.colors.background) {
 | 
					                Surface(color = MaterialTheme.colors.background) {
 | 
				
			||||||
                    NavGraph()
 | 
					                    NavGraph(model)
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
@Composable
 | 
					 | 
				
			||||||
fun Greeting(name: String) {
 | 
					 | 
				
			||||||
    Text(text = "Hello $name!")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Preview(showBackground = true)
 | 
					 | 
				
			||||||
@Composable
 | 
					 | 
				
			||||||
fun DefaultPreview() {
 | 
					 | 
				
			||||||
    PrivateCloudMusicTheme {
 | 
					 | 
				
			||||||
        Greeting("Android")
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										63
									
								
								app/src/main/java/net/blumia/pcmdroid/MainViewModel.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								app/src/main/java/net/blumia/pcmdroid/MainViewModel.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					package net.blumia.pcmdroid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.net.Uri
 | 
				
			||||||
 | 
					import androidx.lifecycle.LiveData
 | 
				
			||||||
 | 
					import androidx.lifecycle.MutableLiveData
 | 
				
			||||||
 | 
					import androidx.lifecycle.ViewModel
 | 
				
			||||||
 | 
					import net.blumia.pcmdroid.model.Folder
 | 
				
			||||||
 | 
					import net.blumia.pcmdroid.model.Server
 | 
				
			||||||
 | 
					import net.blumia.pcmdroid.model.Song
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MainViewModel : ViewModel() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val servers: LiveData<List<Server>> = MutableLiveData<List<Server>>(
 | 
				
			||||||
 | 
					        listOf(
 | 
				
			||||||
 | 
					            Server(
 | 
				
			||||||
 | 
					                url = Uri.parse("https://localhost/api.php"),
 | 
				
			||||||
 | 
					                name = "PCM",
 | 
				
			||||||
 | 
					                baseFolderName = "pcm",
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            Server(
 | 
				
			||||||
 | 
					                url = Uri.parse("https://localhost/api.php"),
 | 
				
			||||||
 | 
					                name = "PCM2",
 | 
				
			||||||
 | 
					                baseFolderName = "pcm2",
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val currentPath: LiveData<String> = MutableLiveData("")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val drawerFolders: LiveData<List<Folder>> = MutableLiveData(
 | 
				
			||||||
 | 
					        listOf(
 | 
				
			||||||
 | 
					            Folder("Test/"),
 | 
				
			||||||
 | 
					            Folder("Folder/")
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val folders: LiveData<List<Folder>> = MutableLiveData(
 | 
				
			||||||
 | 
					        listOf(
 | 
				
			||||||
 | 
					            Folder("Test/Converted-Modules/")
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val songs: LiveData<List<Song>> = MutableLiveData(
 | 
				
			||||||
 | 
					        listOf(
 | 
				
			||||||
 | 
					            Song(
 | 
				
			||||||
 | 
					                filePath = "Test/Rick Astley - Never Gonna Give You Up.mp3",
 | 
				
			||||||
 | 
					                url = Uri.parse("http://localhost/rickroll.mp3")
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            Song(
 | 
				
			||||||
 | 
					                filePath = "Test/哇 好东西一堆.xm",
 | 
				
			||||||
 | 
					                url = Uri.parse("http://localhost/rickroll.mp3")
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun fetchServer(srv: Server) {
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun fetchFolder(folder: Folder) {
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										23
									
								
								app/src/main/java/net/blumia/pcmdroid/model/Song.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/src/main/java/net/blumia/pcmdroid/model/Song.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					package net.blumia.pcmdroid.model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.net.Uri
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data class Song (
 | 
				
			||||||
 | 
					    val filePath: String, // with file name
 | 
				
			||||||
 | 
					    val modifiedTime: Int = 0,
 | 
				
			||||||
 | 
					    val fileSize: Int = 0,
 | 
				
			||||||
 | 
					    val additionalInfo: Boolean = false, // if sidecar meta-info json file exist.
 | 
				
			||||||
 | 
					    val url: Uri,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    fun displayName(): String {
 | 
				
			||||||
 | 
					        return Uri.parse(filePath).lastPathSegment ?: "???"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data class Folder (
 | 
				
			||||||
 | 
					    val folderPath: String,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    fun displayName(): String {
 | 
				
			||||||
 | 
					        return Uri.parse(folderPath).lastPathSegment ?: "???"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					package net.blumia.pcmdroid.repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ServerRepository {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,11 +1,11 @@
 | 
				
			|||||||
package net.blumia.pcmdroid.ui
 | 
					package net.blumia.pcmdroid.ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.compose.runtime.Composable
 | 
					import androidx.compose.runtime.Composable
 | 
				
			||||||
import androidx.compose.ui.Modifier
 | 
					 | 
				
			||||||
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.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
 | 
				
			||||||
@ -18,6 +18,7 @@ object MainDestinations {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@Composable
 | 
					@Composable
 | 
				
			||||||
fun NavGraph(
 | 
					fun NavGraph(
 | 
				
			||||||
 | 
					    viewModel: MainViewModel,
 | 
				
			||||||
    navController: NavHostController = rememberNavController(),
 | 
					    navController: NavHostController = rememberNavController(),
 | 
				
			||||||
    startDestination: String = MainDestinations.MAIN_ROUTE,
 | 
					    startDestination: String = MainDestinations.MAIN_ROUTE,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
@ -27,6 +28,7 @@ fun NavGraph(
 | 
				
			|||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        composable(MainDestinations.MAIN_ROUTE) {
 | 
					        composable(MainDestinations.MAIN_ROUTE) {
 | 
				
			||||||
            MainPlayer(
 | 
					            MainPlayer(
 | 
				
			||||||
 | 
					                viewModel = viewModel,
 | 
				
			||||||
                addServerActionTriggered = {
 | 
					                addServerActionTriggered = {
 | 
				
			||||||
                    navController.navigate(MainDestinations.ADD_SERVER_ROUTE)
 | 
					                    navController.navigate(MainDestinations.ADD_SERVER_ROUTE)
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
				
			|||||||
@ -1,50 +1,72 @@
 | 
				
			|||||||
package net.blumia.pcmdroid.ui.screen.main
 | 
					package net.blumia.pcmdroid.ui.screen.main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.net.Uri
 | 
				
			||||||
import androidx.compose.foundation.Image
 | 
					import androidx.compose.foundation.Image
 | 
				
			||||||
 | 
					import androidx.compose.foundation.clickable
 | 
				
			||||||
 | 
					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.*
 | 
				
			||||||
 | 
					import androidx.compose.material.icons.rounded.FeaturedPlayList
 | 
				
			||||||
import androidx.compose.material.icons.rounded.PlayArrow
 | 
					import androidx.compose.material.icons.rounded.PlayArrow
 | 
				
			||||||
 | 
					import androidx.compose.material.icons.rounded.PlayCircle
 | 
				
			||||||
 | 
					import androidx.compose.material.icons.rounded.PlayCircleOutline
 | 
				
			||||||
import androidx.compose.runtime.*
 | 
					import androidx.compose.runtime.*
 | 
				
			||||||
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
 | 
				
			||||||
 | 
					import androidx.compose.ui.layout.VerticalAlignmentLine
 | 
				
			||||||
import androidx.compose.ui.res.painterResource
 | 
					import androidx.compose.ui.res.painterResource
 | 
				
			||||||
 | 
					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.Server
 | 
				
			||||||
 | 
					import net.blumia.pcmdroid.model.Song
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Preview(showBackground = true)
 | 
					@Preview(showBackground = true)
 | 
				
			||||||
@OptIn(ExperimentalMaterialApi::class)
 | 
					@OptIn(ExperimentalMaterialApi::class)
 | 
				
			||||||
@Composable
 | 
					@Composable
 | 
				
			||||||
fun NowPlaying() {
 | 
					fun NowPlaying() {
 | 
				
			||||||
    Row(
 | 
					    Column(
 | 
				
			||||||
        modifier = Modifier
 | 
					        modifier = Modifier
 | 
				
			||||||
            .fillMaxWidth()
 | 
					            .fillMaxWidth(),
 | 
				
			||||||
            .height(56.dp),
 | 
					 | 
				
			||||||
        verticalAlignment = Alignment.CenterVertically,
 | 
					 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        Image(
 | 
					        LinearProgressIndicator(
 | 
				
			||||||
            painter = painterResource(id = R.drawable.ic_launcher_background),
 | 
					            modifier = Modifier.fillMaxWidth(),
 | 
				
			||||||
            contentDescription = "Album cover",
 | 
					            progress = 0f,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ListItem(
 | 
					        Row(
 | 
				
			||||||
            text = {
 | 
					            modifier = Modifier
 | 
				
			||||||
                Text(
 | 
					                .fillMaxWidth()
 | 
				
			||||||
                    text = "Not playing at all.",
 | 
					                .height(56.dp),
 | 
				
			||||||
                )
 | 
					            verticalAlignment = Alignment.CenterVertically,
 | 
				
			||||||
            },
 | 
					        ) {
 | 
				
			||||||
            trailing = {
 | 
					            Image(
 | 
				
			||||||
                IconButton(onClick = { /*TODO*/ }) {
 | 
					                painter = painterResource(id = R.drawable.ic_launcher_background),
 | 
				
			||||||
                    Icon(imageVector = Icons.Rounded.PlayArrow, contentDescription = "Menu")
 | 
					                contentDescription = "Album cover",
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ListItem(
 | 
				
			||||||
 | 
					                text = {
 | 
				
			||||||
 | 
					                    Text(
 | 
				
			||||||
 | 
					                        text = "Not playing at all.",
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                trailing = {
 | 
				
			||||||
 | 
					                    IconButton(onClick = { /*TODO*/ }) {
 | 
				
			||||||
 | 
					                        Icon(imageVector = Icons.Rounded.PlayCircleOutline, contentDescription = "Menu")
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            )
 | 
				
			||||||
        )
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -52,32 +74,34 @@ fun NowPlaying() {
 | 
				
			|||||||
@OptIn(ExperimentalMaterialApi::class)
 | 
					@OptIn(ExperimentalMaterialApi::class)
 | 
				
			||||||
@Composable
 | 
					@Composable
 | 
				
			||||||
fun DrawerContent(
 | 
					fun DrawerContent(
 | 
				
			||||||
 | 
					    viewModel: MainViewModel = MainViewModel(),
 | 
				
			||||||
    addServerActionTriggered: () -> Unit = {},
 | 
					    addServerActionTriggered: () -> Unit = {},
 | 
				
			||||||
    settingsActionTriggered: () -> Unit = {},
 | 
					    settingsActionTriggered: () -> Unit = {},
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    Row(modifier = Modifier.fillMaxSize()) {
 | 
					    Row(modifier = Modifier.fillMaxSize()) {
 | 
				
			||||||
        var selectedItem by remember { mutableStateOf<Int?>(null) }
 | 
					        var selectedItem by remember { mutableStateOf<Int?>(0) }
 | 
				
			||||||
        val items = listOf<String>()
 | 
					        val servers = viewModel.servers.value
 | 
				
			||||||
        val icons = listOf<ImageVector>()
 | 
					 | 
				
			||||||
        NavigationRail {
 | 
					        NavigationRail {
 | 
				
			||||||
            items.forEachIndexed { index, item ->
 | 
					            servers?.forEachIndexed { index, server ->
 | 
				
			||||||
                NavigationRailItem(
 | 
					                NavigationRailItem(
 | 
				
			||||||
                    icon = {
 | 
					                    icon = {
 | 
				
			||||||
                        Icon(
 | 
					                        Icon(
 | 
				
			||||||
                            icons[index], item
 | 
					                            Icons.Filled.LibraryMusic, server.name
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    label = {
 | 
					                    label = {
 | 
				
			||||||
                        Text(item)
 | 
					                        Text(server.name)
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    selected = selectedItem == index,
 | 
					                    selected = selectedItem == index,
 | 
				
			||||||
                    onClick = { /*TODO*/ }
 | 
					                    onClick = {
 | 
				
			||||||
 | 
					                        viewModel.fetchServer(server)
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            NavigationRailItem(
 | 
					            NavigationRailItem(
 | 
				
			||||||
                icon = { Icon(Icons.Filled.AddCircle, null) },
 | 
					                icon = { Icon(Icons.Filled.AddCircle, null) },
 | 
				
			||||||
                label = { Text("Add") },
 | 
					                label = { Text(stringResource(id = R.string.add)) },
 | 
				
			||||||
                selected = false,
 | 
					                selected = false,
 | 
				
			||||||
                onClick = addServerActionTriggered,
 | 
					                onClick = addServerActionTriggered,
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@ -86,7 +110,7 @@ fun DrawerContent(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            NavigationRailItem(
 | 
					            NavigationRailItem(
 | 
				
			||||||
                icon = { Icon(Icons.Filled.Settings, null) },
 | 
					                icon = { Icon(Icons.Filled.Settings, null) },
 | 
				
			||||||
                label = { Text("Settings") },
 | 
					                label = { Text(stringResource(id = R.string.settings)) },
 | 
				
			||||||
                selected = false,
 | 
					                selected = false,
 | 
				
			||||||
                onClick = settingsActionTriggered,
 | 
					                onClick = settingsActionTriggered,
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@ -108,13 +132,30 @@ fun DrawerContent(
 | 
				
			|||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Divider()
 | 
					            Divider()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            val drawerFolders = viewModel.drawerFolders.value
 | 
				
			||||||
 | 
					            drawerFolders?.forEach { folder ->
 | 
				
			||||||
 | 
					                ListItem(
 | 
				
			||||||
 | 
					                    modifier = Modifier.clickable{
 | 
				
			||||||
 | 
					                        viewModel.fetchFolder(folder)
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    text = {
 | 
				
			||||||
 | 
					                        Text(
 | 
				
			||||||
 | 
					                            text = folder.displayName(),
 | 
				
			||||||
 | 
					                            style = MaterialTheme.typography.subtitle1
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Preview(showBackground = true)
 | 
					@Preview(showBackground = true)
 | 
				
			||||||
 | 
					@OptIn(ExperimentalMaterialApi::class)
 | 
				
			||||||
@Composable
 | 
					@Composable
 | 
				
			||||||
fun MainPlayer(
 | 
					fun MainPlayer(
 | 
				
			||||||
 | 
					    viewModel: MainViewModel = MainViewModel(),
 | 
				
			||||||
    addServerActionTriggered: () -> Unit = {},
 | 
					    addServerActionTriggered: () -> Unit = {},
 | 
				
			||||||
    settingsActionTriggered: () -> Unit = {},
 | 
					    settingsActionTriggered: () -> Unit = {},
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
@ -124,6 +165,7 @@ fun MainPlayer(
 | 
				
			|||||||
        drawerState = drawerState,
 | 
					        drawerState = drawerState,
 | 
				
			||||||
        drawerContent = {
 | 
					        drawerContent = {
 | 
				
			||||||
            DrawerContent(
 | 
					            DrawerContent(
 | 
				
			||||||
 | 
					                viewModel = viewModel,
 | 
				
			||||||
                addServerActionTriggered = addServerActionTriggered,
 | 
					                addServerActionTriggered = addServerActionTriggered,
 | 
				
			||||||
                settingsActionTriggered = settingsActionTriggered,
 | 
					                settingsActionTriggered = settingsActionTriggered,
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@ -132,7 +174,7 @@ fun MainPlayer(
 | 
				
			|||||||
        Scaffold(
 | 
					        Scaffold(
 | 
				
			||||||
            topBar = {
 | 
					            topBar = {
 | 
				
			||||||
                TopAppBar(
 | 
					                TopAppBar(
 | 
				
			||||||
                    title = { Text("Private Cloud Music") },
 | 
					                    title = { Text(stringResource(id = R.string.app_name)) },
 | 
				
			||||||
                    navigationIcon = {
 | 
					                    navigationIcon = {
 | 
				
			||||||
                        IconButton(onClick = {
 | 
					                        IconButton(onClick = {
 | 
				
			||||||
                            drawerScope.launch {
 | 
					                            drawerScope.launch {
 | 
				
			||||||
@ -154,7 +196,68 @@ fun MainPlayer(
 | 
				
			|||||||
                modifier = Modifier.fillMaxSize()
 | 
					                modifier = Modifier.fillMaxSize()
 | 
				
			||||||
            ) {
 | 
					            ) {
 | 
				
			||||||
                Column(modifier = Modifier.weight(1f, fill = true)) {
 | 
					                Column(modifier = Modifier.weight(1f, fill = true)) {
 | 
				
			||||||
                    //
 | 
					
 | 
				
			||||||
 | 
					                    val iconLeftPadding = 16.dp
 | 
				
			||||||
 | 
					                    val iconVerticalPadding = 12.dp
 | 
				
			||||||
 | 
					                    Row(
 | 
				
			||||||
 | 
					                        modifier = Modifier
 | 
				
			||||||
 | 
					                            .fillMaxWidth()
 | 
				
			||||||
 | 
					                            .horizontalScroll(rememberScrollState())
 | 
				
			||||||
 | 
					                            .padding(
 | 
				
			||||||
 | 
					                                horizontal = iconLeftPadding,
 | 
				
			||||||
 | 
					                                vertical = iconVerticalPadding,
 | 
				
			||||||
 | 
					                            ),
 | 
				
			||||||
 | 
					                        verticalAlignment = Alignment.CenterVertically,
 | 
				
			||||||
 | 
					                    ) {
 | 
				
			||||||
 | 
					                        val pathSeg = listOf("Deep", "Dark", "Folder")
 | 
				
			||||||
 | 
					                        pathSeg.forEach { seg ->
 | 
				
			||||||
 | 
					                            val isLastSeg = seg == pathSeg.last()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            Text(
 | 
				
			||||||
 | 
					                                text = seg,
 | 
				
			||||||
 | 
					                                style = MaterialTheme.typography.body1,
 | 
				
			||||||
 | 
					                                color = if (isLastSeg) MaterialTheme.colors.primary else MaterialTheme.colors.onSurface
 | 
				
			||||||
 | 
					                            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            if (!isLastSeg) {
 | 
				
			||||||
 | 
					                                Icon(
 | 
				
			||||||
 | 
					                                    modifier = Modifier.padding(horizontal = 5.dp),
 | 
				
			||||||
 | 
					                                    imageVector = Icons.Filled.NavigateNext,
 | 
				
			||||||
 | 
					                                    contentDescription = null,
 | 
				
			||||||
 | 
					                                )
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    viewModel.folders.value?.forEach { folder ->
 | 
				
			||||||
 | 
					                        ListItem(
 | 
				
			||||||
 | 
					                            modifier = Modifier.clickable {  },
 | 
				
			||||||
 | 
					                            icon = {
 | 
				
			||||||
 | 
					                                Icon(
 | 
				
			||||||
 | 
					                                    imageVector = Icons.Filled.FolderOpen,
 | 
				
			||||||
 | 
					                                    contentDescription = null,
 | 
				
			||||||
 | 
					                                )
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                            text = {
 | 
				
			||||||
 | 
					                                Text(folder.displayName())
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    viewModel.songs.value?.forEach { song ->
 | 
				
			||||||
 | 
					                        ListItem(
 | 
				
			||||||
 | 
					                            modifier = Modifier.clickable {  },
 | 
				
			||||||
 | 
					                            icon = {
 | 
				
			||||||
 | 
					                                Icon(
 | 
				
			||||||
 | 
					                                    imageVector = Icons.Filled.MusicNote,
 | 
				
			||||||
 | 
					                                    contentDescription = null
 | 
				
			||||||
 | 
					                                )
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                            text = {
 | 
				
			||||||
 | 
					                                Text(song.displayName())
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                NowPlaying()
 | 
					                NowPlaying()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										5
									
								
								app/src/main/res/values-zh/strings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/src/main/res/values-zh/strings.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<resources>
 | 
				
			||||||
 | 
					    <string name="app_name">私有云音乐</string>
 | 
				
			||||||
 | 
					    <string name="settings">设置</string>
 | 
				
			||||||
 | 
					    <string name="add">添加</string>
 | 
				
			||||||
 | 
					</resources>
 | 
				
			||||||
@ -1,3 +1,5 @@
 | 
				
			|||||||
<resources>
 | 
					<resources>
 | 
				
			||||||
    <string name="app_name">Private Cloud Music</string>
 | 
					    <string name="app_name">Private Cloud Music</string>
 | 
				
			||||||
 | 
					    <string name="settings">Settings</string>
 | 
				
			||||||
 | 
					    <string name="add">Add</string>
 | 
				
			||||||
</resources>
 | 
					</resources>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user