Skip to content

Commit

Permalink
desktop ui
Browse files Browse the repository at this point in the history
  • Loading branch information
andannn authored and QIngnan Jianag committed Nov 28, 2024
1 parent 1f4a5f9 commit 5892e12
Show file tree
Hide file tree
Showing 14 changed files with 685 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.runtime.Composable
Expand Down
172 changes: 163 additions & 9 deletions composeApp/src/commonMain/kotlin/com/andannn/melodify/ModalDrawer.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,49 @@
package com.andannn.melodify

import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Add
import androidx.compose.material.icons.rounded.CheckCircle
import androidx.compose.material.icons.rounded.ExpandLess
import androidx.compose.material.icons.rounded.ExpandMore
import androidx.compose.material3.DrawerState
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.NavigationDrawerItem
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.andannn.melodify.core.data.model.CustomTab
import com.andannn.melodify.feature.common.util.getCategoryResource
import com.andannn.melodify.feature.customtab.TabSector
import com.andannn.melodify.feature.customtab.UiEvent
import com.andannn.melodify.feature.customtab.rememberCustomTabSettingViewStateHolder
import io.github.aakira.napier.Napier
import melodify.feature.common.generated.resources.Res
import melodify.feature.common.generated.resources.audio_page_title
import melodify.feature.common.generated.resources.library_title
import org.jetbrains.compose.resources.stringResource

private const val TAG = "ModalDrawer"

Expand All @@ -21,24 +53,146 @@ fun ModalDrawer(
drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),
content: @Composable () -> Unit
) {

ModalNavigationDrawer(
modifier = modifier,
drawerState = drawerState,
drawerContent = {
Napier.d(tag = TAG) { "Drawer initialized" }
val stateHolder = rememberCustomTabSettingViewStateHolder()
stateHolder.state.collectAsState()
ModalDrawerSheet(
modifier = modifier,
drawerState = drawerState
) {
NavigationDrawerItem(
label = { Text("Home") },
onClick = { /*TODO*/ },
selected = true,
Text(
modifier = Modifier.padding(16.dp),
text = stringResource(Res.string.library_title),
style = MaterialTheme.typography.titleLarge,
)

CustomShrinkableTabSelector()
}
},
content = content,
)
}

@Composable
@OptIn(ExperimentalFoundationApi::class)
fun CustomShrinkableTabSelector(
modifier: Modifier = Modifier,
) {
val stateHolder = rememberCustomTabSettingViewStateHolder()
val state by stateHolder.state.collectAsState()
val expandState = remember {
mutableStateOf<Map<TabSector, Boolean>>(emptyMap())
}

LazyColumn(
modifier = modifier.fillMaxHeight(),
) {
item {
val selected by rememberUpdatedState(state.currentTabs.contains(CustomTab.AllMusic))
SelectableNavigationDrawerItem(
label = stringResource(Res.string.audio_page_title),
selected = selected,
onClick = {
stateHolder.onEvent(
UiEvent.OnSelectedChange(
CustomTab.AllMusic,
!selected
)
)
}
)
}

state.allAvailableTabSectors.forEach { sector ->
val expand = expandState.value[sector] ?: false
stickyHeader {
Surface(
color = MaterialTheme.colorScheme.background,
) {
NavigationDrawerItem(
icon = {
Icon(
imageVector = if (expand) Icons.Rounded.ExpandLess else Icons.Rounded.ExpandMore,
contentDescription = ""
)
},
label = { Text(stringResource(sector.sectorTitle)) },
onClick = {
expandState.value = expandState.value.toMutableMap().apply {
this[sector] = !(this[sector] ?: false)
}
},
selected = false,
)
}
}

item {
AnimatedContent(expand) { isExpandContent ->
if (!isExpandContent) return@AnimatedContent Spacer(Modifier)

Column {
sector.sectorContent.forEach { tab ->
val itemSelected by rememberUpdatedState(
state.currentTabs.contains(
tab
)
)

SelectableNavigationDrawerItem(
label = getCategoryResource(tab),
selected = itemSelected,
onClick = {
stateHolder.onEvent(
UiEvent.OnSelectedChange(
tab,
!itemSelected
)
)
}
)
}
}
}
}
}
}
}

@Composable
fun SelectableNavigationDrawerItem(
modifier: Modifier = Modifier,
label: String,
selected: Boolean,
onClick: () -> Unit
) {
NavigationDrawerItem(
modifier = modifier,
icon = {
Spacer(modifier = Modifier.size(24.dp))
},
label = {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
modifier = Modifier.weight(1f),
text = label
)
if (selected) {
Icon(
imageVector = Icons.Rounded.CheckCircle,
tint = MaterialTheme.colorScheme.primary,
contentDescription = ""
)
} else {
Icon(
imageVector = Icons.Rounded.Add,
contentDescription = ""
)
}
}
},
onClick = onClick,
selected = false,
)
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
package com.andannn.melodify

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.width
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.window.MenuBar
import androidx.compose.ui.window.Window
import com.andannn.melodify.core.data.model.AudioItemModel
import com.andannn.melodify.core.syncer.MediaLibrarySyncer
import com.andannn.melodify.feature.drawer.DrawerController
import com.andannn.melodify.feature.home.HomeRoute
import com.andannn.melodify.feature.home.HomeUiContent
import com.andannn.melodify.feature.home.HomeUiEvent
import com.andannn.melodify.feature.home.HomeViewModel
import com.andannn.melodify.feature.message.MessageController
import com.andannn.melodify.feature.player.PlayerSector
import org.koin.compose.viewmodel.koinViewModel
import org.koin.core.parameter.parametersOf
import org.koin.java.KoinJavaComponent.getKoin

@Composable
Expand All @@ -23,5 +46,58 @@ fun MelodifyDeskTopApp() {
}
}

MainWindowContent()
}
}

@Composable
fun MainWindowContent(
modifier: Modifier = Modifier,
) {
Row(modifier = modifier.fillMaxSize()) {
CustomShrinkableTabSelector(
modifier = Modifier
.weight(1f)
.background(MaterialTheme.colorScheme.surface)
)

VerticalDivider()

Column(
modifier = Modifier.weight(2f),
) {
HomeSector(
modifier = Modifier.weight(1f)
)

HorizontalDivider()

PlayerSector(
modifier = Modifier
)
}
}
}

@Composable
fun HomeSector(
modifier: Modifier = Modifier,
homeViewModel: HomeViewModel = koinViewModel(),
) {
val state by homeViewModel.state.collectAsState()

Surface(
modifier = modifier
) {
HomeUiContent(
modifier = Modifier,
uiState = state,
onEvent = homeViewModel::onEvent,
onMediaItemClick = {
if (it is AudioItemModel) {
homeViewModel.onEvent(HomeUiEvent.OnMusicItemClick(it))
}
}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ class PlatformInfoImpl(private val context: Context) : PlatformInfo {
get() = context.cacheDir.toString()
override val databasePath: String
get() = context.getDatabasePath(DATABASE_FILE_NAME).absolutePath
override val platform: Platform
get() = Mobile.Android
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@ package com.andannn.melodify.core.platform

internal const val DATABASE_FILE_NAME = "melodify_database.db"

sealed interface Platform

data object Desktop : Platform

interface Mobile : Platform {
data object Android: Mobile

data object IOS: Mobile
}

interface PlatformInfo {
val fileDir: String

val cacheDir: String

val databasePath: String

val platform: Platform
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ class PlatformInfoImpl : PlatformInfo {
get() = File(System.getProperty("user.home") + "/.melodify/database/").resolve(
DATABASE_FILE_NAME
).toString()
override val platform: Platform
get() = Desktop
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class MediaLibraryScannerImpl(
// TODO Get Path from DataStore after implement library path setting feature.
// val libraryPathSet = userSettingPreferences.userDate.first().libraryPath
val libraryPathSet = setOf(
"/mnt/chromeos/MyFiles/Shared"
"/Volumes/PS2000/Music"
)

val audioFileWithLastModifyDateList = scanAllLibraryAudioFile(libraryPathSet)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="home">Home</string>
<string name="audio_page_title">Songs</string>
<string name="audio_page_title">All Songs</string>
<string name="album_page_title">Album</string>
<string name="artist_page_title">Artist</string>
<string name="playlist_page_title">Play List</string>
Expand Down Expand Up @@ -36,4 +36,5 @@
<string name="new_playlist_dialog_title">Create new playlist</string>
<string name="new_playlist_dialog_input_hint">Title</string>
<string name="remove_playlist">Delete playlist</string>
<string name="library_title">Library</string>
</resources>
Loading

0 comments on commit 5892e12

Please sign in to comment.