diff --git a/.run/Run Desktop.run.xml b/.run/Run Desktop.run.xml new file mode 100644 index 0000000..0c41dd4 --- /dev/null +++ b/.run/Run Desktop.run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/Run Server.run.xml b/.run/Run Server.run.xml new file mode 100644 index 0000000..f396ec1 --- /dev/null +++ b/.run/Run Server.run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index e54362b..b95b52e 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -1,5 +1,5 @@ import org.jetbrains.compose.desktop.application.dsl.TargetFormat -import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl +import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl plugins { alias(libs.plugins.compose.compiler) @@ -32,6 +32,7 @@ kotlin { implementation(compose.runtime) implementation(compose.foundation) implementation(compose.material3) + implementation(compose.material3AdaptiveNavigationSuite) implementation(compose.materialIconsExtended) implementation(compose.ui) implementation(compose.components.resources) diff --git a/composeApp/src/commonMain/kotlin/ui/BackupsScreen.kt b/composeApp/src/commonMain/kotlin/ui/BackupsScreen.kt index 152c6e5..638459e 100644 --- a/composeApp/src/commonMain/kotlin/ui/BackupsScreen.kt +++ b/composeApp/src/commonMain/kotlin/ui/BackupsScreen.kt @@ -1,13 +1,32 @@ package ui -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +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.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Archive import androidx.compose.material.icons.sharp.Delete -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material3.Card +import androidx.compose.material3.ElevatedButton +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedCard +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign @@ -19,114 +38,103 @@ import kotlinx.datetime.TimeZone import kotlinx.datetime.toLocalDateTime import org.koin.compose.koinInject import ui.model.ModelState -import ui.model.Screen import viewmodels.BackupScreenViewModel -object BackupsScreen : Screen { +private val padding = Modifier.padding(16.dp) +private val paddingSmall = Modifier.padding(8.dp) +private val filePattern = Regex(".*\\.([0-9]+)\\.bkp$") - private val padding = Modifier.padding(16.dp) - private val paddingSmall = Modifier.padding(8.dp) - private val filePattern = Regex(".*\\.([0-9]+)\\.bkp$") - - override val name: String - get() = "Backups" - - @Composable - override fun icon() { - Icon(Icons.Filled.Archive, contentDescription = name) - } - - @Composable - override fun content() { - Column( - modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - val backupScreenViewModel = koinInject() - val scope = rememberCoroutineScope() - var backups by remember { mutableStateOf(listOf()) } - suspend fun loadBackups() { - backupScreenViewModel.backupFiles.collect { - if (it is ModelState.Success) { - backups = it.result - } +@Composable +fun BackupsScreen() { + Column( + modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + val backupScreenViewModel = koinInject() + val scope = rememberCoroutineScope() + var backups by remember { mutableStateOf(listOf()) } + suspend fun loadBackups() { + backupScreenViewModel.backupFiles.collect { + if (it is ModelState.Success) { + backups = it.result } } - LaunchedEffect(Unit) { + } + LaunchedEffect(Unit) { + scope.launch { + loadBackups() + } + } + BackupContent( + backups, + onClear = { scope.launch { + backupScreenViewModel.clearBackups() loadBackups() } - } - BackupContent( - backups, - onClear = { - scope.launch { - backupScreenViewModel.clearBackups() - loadBackups() - } - }, - onDelete = { - scope.launch { - backupScreenViewModel.delete(it) - loadBackups() - } - }) - - } + }, + onDelete = { + scope.launch { + backupScreenViewModel.delete(it) + loadBackups() + } + }) } - @Composable - fun BackupContent(backups: List, onDelete: (String) -> Unit, onClear: () -> Unit) { - Card( - modifier = Modifier.width(width = 900.dp).fillMaxHeight().padding(20.dp) - ) { - Column(modifier = padding) { - Row { - Text( - text = "Backups", - fontSize = 30.sp, - modifier = padding, - textAlign = TextAlign.Center, - ) - } - Column { - backups.forEach { backup -> BackupItem(backup) { onDelete(backup) } } - } - Row(modifier = Modifier.fillMaxSize()) { - Spacer(modifier = Modifier.weight(1f)) - ElevatedButton(onClick = onClear, modifier = padding) { - Text("Clear All Backups") - } - Spacer(modifier = Modifier.weight(1f)) +} + +@Composable +fun BackupContent(backups: List, onDelete: (String) -> Unit, onClear: () -> Unit) { + Card( + modifier = Modifier.width(width = 900.dp).fillMaxHeight().padding(20.dp) + ) { + Column(modifier = padding) { + Row { + Text( + text = "Backups", + fontSize = 30.sp, + modifier = padding, + textAlign = TextAlign.Center, + ) + } + Column { + backups.forEach { backup -> BackupItem(backup) { onDelete(backup) } } + } + Row(modifier = Modifier.fillMaxSize()) { + Spacer(modifier = Modifier.weight(1f)) + ElevatedButton(onClick = onClear, modifier = padding) { + Text("Clear All Backups") } + Spacer(modifier = Modifier.weight(1f)) } } } +} - @Composable - fun BackupItem(backup: String, onDelete: () -> Unit) { - Column { - OutlinedCard( - modifier = Modifier.padding(16.dp, 4.dp).fillMaxWidth() - ) { - val ts = filePattern.find(backup)?.groupValues?.get(1)?.toLongOrNull() ?: 0 - val modified = Instant.fromEpochSeconds(ts).toLocalDateTime(TimeZone.currentSystemDefault()) - Row(verticalAlignment = Alignment.CenterVertically) { - Column(modifier = Modifier.weight(1f).padding(8.dp)) { - Text(backup.substringAfterLast('/'), modifier = paddingSmall) - Text( - "Completed at ${modified.date} ${modified.time}", - style = MaterialTheme.typography.labelSmall, - modifier = paddingSmall - ) - } - IconButton(onClick = onDelete) { - Icon(Icons.Sharp.Delete, "Delete Backup") - } +@Composable +fun BackupItem(backup: String, onDelete: () -> Unit) { + Column { + OutlinedCard( + modifier = Modifier.padding(16.dp, 4.dp).fillMaxWidth() + ) { + val ts = filePattern.find(backup)?.groupValues?.get(1)?.toLongOrNull() ?: 0 + val modified = Instant.fromEpochSeconds(ts).toLocalDateTime(TimeZone.currentSystemDefault()) + Row(verticalAlignment = Alignment.CenterVertically) { + Column(modifier = Modifier.weight(1f).padding(8.dp)) { + Text(backup.substringAfterLast('/'), modifier = paddingSmall) + Text( + "Completed at ${modified.date} ${modified.time}", + style = MaterialTheme.typography.labelSmall, + modifier = paddingSmall + ) + } + IconButton(onClick = onDelete) { + Icon(Icons.Sharp.Delete, "Delete Backup") } } } } } + diff --git a/composeApp/src/commonMain/kotlin/ui/JobsScreen.kt b/composeApp/src/commonMain/kotlin/ui/JobsScreen.kt index d58e9eb..be95501 100644 --- a/composeApp/src/commonMain/kotlin/ui/JobsScreen.kt +++ b/composeApp/src/commonMain/kotlin/ui/JobsScreen.kt @@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Inbox import androidx.compose.material.icons.sharp.Close import androidx.compose.material3.Card import androidx.compose.material3.ElevatedButton @@ -43,24 +42,15 @@ import io.github.jsixface.common.JobStatus.Starting import kotlinx.coroutines.launch import org.koin.compose.koinInject import ui.model.ModelState -import ui.model.Screen import viewmodels.JobsScreenModel -object JobsScreen : Screen { - private val padding = Modifier.padding(16.dp) +private val padding = Modifier.padding(16.dp) private val paddingSmall = Modifier.padding(8.dp) - override val name: String - get() = "Jobs" @Composable - override fun icon() { - Icon(Icons.Filled.Inbox, contentDescription = name) - } - - @Composable - override fun content() { + fun JobsScreen() { Column( modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.Center, @@ -160,4 +150,4 @@ object JobsScreen : Screen { } } } -} + diff --git a/composeApp/src/commonMain/kotlin/ui/MainScreen.kt b/composeApp/src/commonMain/kotlin/ui/MainScreen.kt index 831e03c..8841bae 100644 --- a/composeApp/src/commonMain/kotlin/ui/MainScreen.kt +++ b/composeApp/src/commonMain/kotlin/ui/MainScreen.kt @@ -1,16 +1,20 @@ package ui import Backend -import androidx.compose.foundation.layout.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Cloud -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Icon +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp import ui.home.HomeScreen -import ui.model.Screen +import ui.model.AppPages @Composable @@ -18,28 +22,33 @@ fun MainScreen() { Surface(modifier = Modifier.fillMaxSize()) { var showCloudDialog by remember { mutableStateOf(false) } - var currentScreen: Screen by remember { mutableStateOf(HomeScreen) } + var currentPage by rememberSaveable { mutableStateOf(AppPages.HOME) } - Row(modifier = Modifier.fillMaxSize()) { - if (showCloudDialog) { - BackendDialog(Backend.host, { showCloudDialog = false }) { Backend.host = it } - } + if (showCloudDialog) { + BackendDialog(Backend.host, { showCloudDialog = false }) { Backend.host = it } + } - NavigationRail(modifier = Modifier.fillMaxHeight()) { - listOf(HomeScreen, JobsScreen,BackupsScreen, SettingsScreen).forEach { screen -> - NavigationRailItem(icon = { screen.icon() }, - label = { Text(screen.name) }, - selected = currentScreen == screen, - onClick = { currentScreen = screen }) - } - Spacer(modifier = Modifier.weight(1f)) - FloatingActionButton(onClick = { showCloudDialog = true }, modifier = Modifier.padding(8.dp)) { - Icon(Icons.Filled.Cloud, contentDescription = "Backend") + NavigationSuiteScaffold( + navigationSuiteItems = { + AppPages.entries.forEach { page -> + item( + icon = { Icon(page.icon, contentDescription = page.title) }, + onClick = { currentPage = page }, + label = { Text(page.title) }, + selected = currentPage == page + ) } } - Box(modifier = Modifier.fillMaxSize().weight(1f), contentAlignment = Alignment.Center) { - currentScreen.content() + ) { + when (currentPage) { + AppPages.HOME -> HomeScreen.content() + AppPages.JOBS -> JobsScreen() + AppPages.BACKUPS -> BackupsScreen() + AppPages.SETTINGS -> SettingsScreen() } } +// FloatingActionButton(onClick = { showCloudDialog = true }, modifier = Modifier.padding(8.dp)) { +// Icon(Icons.Filled.Cloud, contentDescription = "Backend") +// } } } diff --git a/composeApp/src/commonMain/kotlin/ui/SettingsScreen.kt b/composeApp/src/commonMain/kotlin/ui/SettingsScreen.kt index e1beb17..7ed0ab2 100644 --- a/composeApp/src/commonMain/kotlin/ui/SettingsScreen.kt +++ b/composeApp/src/commonMain/kotlin/ui/SettingsScreen.kt @@ -12,7 +12,6 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add -import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.sharp.Delete import androidx.compose.material3.Card import androidx.compose.material3.CircularProgressIndicator @@ -41,158 +40,148 @@ import io.github.jsixface.common.Settings import kotlinx.coroutines.launch import org.koin.compose.koinInject import ui.model.ModelState -import ui.model.Screen import ui.utils.ComboBox import viewmodels.SettingsScreenModel import kotlin.time.Duration import kotlin.time.Duration.Companion.hours import kotlin.time.Duration.Companion.minutes -object SettingsScreen : Screen { +private val padding = Modifier.padding(16.dp) +private val paddingSmall = Modifier.padding(8.dp) - private val padding = Modifier.padding(16.dp) - private val paddingSmall = Modifier.padding(8.dp) - - override val name: String - get() = "Settings" - - @Composable - override fun icon() { - Icon(Icons.Filled.Settings, contentDescription = name) - } - - @Composable - override fun content() { - Column( - modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, +@Composable +fun SettingsScreen() { + Column( + modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Card( + modifier = Modifier.width(width = 600.dp).padding(20.dp) ) { - Card( - modifier = Modifier.width(width = 600.dp).padding(20.dp) - ) { - val settingsModel = koinInject() - val scope = rememberCoroutineScope() - var loading by remember { mutableStateOf(true) } - var errorLoading by remember { mutableStateOf(false) } - var workspace by remember { mutableStateOf("") } - val extensions = remember { mutableStateListOf() } - val locations = remember { mutableStateListOf() } - var refreshDuration by remember { mutableStateOf(null) } + val settingsModel = koinInject() + val scope = rememberCoroutineScope() + var loading by remember { mutableStateOf(true) } + var errorLoading by remember { mutableStateOf(false) } + var workspace by remember { mutableStateOf("") } + val extensions = remember { mutableStateListOf() } + val locations = remember { mutableStateListOf() } + var refreshDuration by remember { mutableStateOf(null) } - LaunchedEffect(Unit) { - scope.launch { - settingsModel.state.collect { state -> - when (state) { - is ModelState.Error -> { - loading = false - errorLoading = true - } + LaunchedEffect(Unit) { + scope.launch { + settingsModel.state.collect { state -> + when (state) { + is ModelState.Error -> { + loading = false + errorLoading = true + } - is ModelState.Init -> { - loading = true - } + is ModelState.Init -> { + loading = true + } - is ModelState.Success -> { - loading = false - val settings = state.result - val locationsToAdd = settings.libraryLocations.filterNot { - locations.contains(it) - } - locations.addAll(locationsToAdd) - val extsToAdd = settings.videoExtensions.filterNot { - extensions.contains(it) - } - extensions.addAll(extsToAdd) - workspace = settings.workspaceLocation - refreshDuration = settings.watchDuration + is ModelState.Success -> { + loading = false + val settings = state.result + val locationsToAdd = settings.libraryLocations.filterNot { + locations.contains(it) + } + locations.addAll(locationsToAdd) + val extsToAdd = settings.videoExtensions.filterNot { + extensions.contains(it) } + extensions.addAll(extsToAdd) + workspace = settings.workspaceLocation + refreshDuration = settings.watchDuration } } } } + } - Column(modifier = padding) { - Row { - Text( - text = "Settings", - fontSize = 30.sp, - modifier = padding, - textAlign = TextAlign.Center, - ) - if (loading) { - CircularProgressIndicator(modifier = padding.width(30.dp)) - } + Column(modifier = padding) { + Row { + Text( + text = "Settings", + fontSize = 30.sp, + modifier = padding, + textAlign = TextAlign.Center, + ) + if (loading) { + CircularProgressIndicator(modifier = padding.width(30.dp)) } - Column { - ListEditor("Locations", locations, { locations.remove(it) }, { locations.add(it) }) - HorizontalDivider() - ListEditor("Extensions", extensions, { extensions.remove(it) }, { extensions.add(it) }) - HorizontalDivider() - OutlinedTextField(value = workspace, - onValueChange = { workspace = it }, - modifier = padding, - label = { Text("Workspace Location") }) - ComboBox( - title = "Media Scan Duration", - options = listOf(1.minutes, 5.minutes, 15.minutes, 30.minutes, 1.hours), - selected = refreshDuration - ) { refreshDuration = it } + } + Column { + ListEditor("Locations", locations, { locations.remove(it) }, { locations.add(it) }) + HorizontalDivider() + ListEditor("Extensions", extensions, { extensions.remove(it) }, { extensions.add(it) }) + HorizontalDivider() + OutlinedTextField( + value = workspace, + onValueChange = { workspace = it }, + modifier = padding, + label = { Text("Workspace Location") }) + ComboBox( + title = "Media Scan Duration", + options = listOf(1.minutes, 5.minutes, 15.minutes, 30.minutes, 1.hours), + selected = refreshDuration + ) { refreshDuration = it } - } - Row(modifier = Modifier.fillMaxSize()) { - Spacer(modifier = Modifier.weight(1f)) - ElevatedButton(onClick = { - scope.launch { - settingsModel.save(Settings(locations, workspace, extensions, refreshDuration)) - } - }, modifier = padding) { - Text("Save") + } + Row(modifier = Modifier.fillMaxSize()) { + Spacer(modifier = Modifier.weight(1f)) + ElevatedButton(onClick = { + scope.launch { + settingsModel.save(Settings(locations, workspace, extensions, refreshDuration)) } + }, modifier = padding) { + Text("Save") } } } - } + } +} - @Composable - fun ListEditor( - title: String, items: List, onDelete: (String) -> Unit, onAdd: (String) -> Unit - ) { - Column { - Text( - text = title, - fontSize = 18.sp, - fontWeight = FontWeight.SemiBold, - modifier = padding, - textAlign = TextAlign.Center, - ) - items.forEach { i -> - OutlinedCard( - modifier = Modifier.padding(16.dp, 4.dp).fillMaxWidth() - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - Text(i, paddingSmall) - Spacer(Modifier.weight(1f)) - IconButton(onClick = { onDelete(i) }) { - Icon(Icons.Sharp.Delete, "Delete") - } +@Composable +fun ListEditor( + title: String, items: List, onDelete: (String) -> Unit, onAdd: (String) -> Unit +) { + Column { + Text( + text = title, + fontSize = 18.sp, + fontWeight = FontWeight.SemiBold, + modifier = padding, + textAlign = TextAlign.Center, + ) + items.forEach { i -> + OutlinedCard( + modifier = Modifier.padding(16.dp, 4.dp).fillMaxWidth() + ) { + Row(verticalAlignment = Alignment.CenterVertically) { + Text(i, paddingSmall) + Spacer(Modifier.weight(1f)) + IconButton(onClick = { onDelete(i) }) { + Icon(Icons.Sharp.Delete, "Delete") } } } - Row(verticalAlignment = Alignment.CenterVertically) { - var newExt by remember { mutableStateOf("") } - OutlinedTextField(value = newExt, - onValueChange = { newExt = it }, - modifier = padding, - label = { Text("Add new") }) - ElevatedButton(onClick = { - onAdd(newExt) - newExt = "" - }) { - Icon(Icons.Filled.Add, "Add") - } + } + Row(verticalAlignment = Alignment.CenterVertically) { + var newExt by remember { mutableStateOf("") } + OutlinedTextField( + value = newExt, + onValueChange = { newExt = it }, + modifier = padding, + label = { Text("Add new") }) + ElevatedButton(onClick = { + onAdd(newExt) + newExt = "" + }) { + Icon(Icons.Filled.Add, "Add") } } } diff --git a/composeApp/src/commonMain/kotlin/ui/home/HomeScreen.kt b/composeApp/src/commonMain/kotlin/ui/home/HomeScreen.kt index 44d9769..6085649 100644 --- a/composeApp/src/commonMain/kotlin/ui/home/HomeScreen.kt +++ b/composeApp/src/commonMain/kotlin/ui/home/HomeScreen.kt @@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Home import androidx.compose.material.icons.rounded.Close import androidx.compose.material.icons.rounded.Refresh import androidx.compose.material.icons.rounded.Search @@ -37,12 +36,11 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.launch import org.koin.compose.koinInject import ui.model.ModelState -import ui.model.Screen import ui.utils.ComboBox import viewmodels.VideoListViewModel -object HomeScreen : Screen { +object HomeScreen { private var filteredAudioCodec by mutableStateOf(null) private var filteredVideoCodec by mutableStateOf(null) @@ -52,16 +50,8 @@ object HomeScreen : Screen { private val bottomPad = Modifier.padding(0.dp, 0.dp, 0.dp, 8.dp) private val sidePad = Modifier.padding(8.dp, 0.dp, 0.dp, 0.dp) - override val name: String - get() = "Home" - - @Composable - override fun icon() { - Icon(Icons.Filled.Home, contentDescription = name) - } - @Composable - override fun content() { + fun content() { var loadingJob: Job? by remember { mutableStateOf(null) } var loading by remember { mutableStateOf(true) } @@ -100,9 +90,7 @@ object HomeScreen : Screen { // Heading & status Row(modifier = bottomPad) { Text( - "Video files", - style = MaterialTheme.typography.headlineLarge, - modifier = sidePad + "Video files", style = MaterialTheme.typography.headlineLarge, modifier = sidePad ) if (loading) { CircularProgressIndicator(modifier = sidePad) @@ -141,15 +129,18 @@ object HomeScreen : Screen { @OptIn(ExperimentalFoundationApi::class) @Composable fun PageContent(list: List, videoSelected: (VideoFile) -> Unit, onRefresh: () -> Unit) { - val filteredVideos = - list.filter { - it.fileName.contains(filteredName, ignoreCase = true) - && it.videos.any { v -> filteredVideoCodec?.let { fv -> v.codec == fv } ?: true } - && it.audios.any { a -> filteredAudioCodec?.let { fa -> a.codec == fa } ?: true } - } + val filteredVideos = list.filter { + it.fileName.contains( + filteredName, + ignoreCase = true + ) && it.videos.any { v -> + filteredVideoCodec?.let { fv -> v.codec == fv } ?: true + } && it.audios.any { a -> filteredAudioCodec?.let { fa -> a.codec == fa } ?: true } + } Column { Row(modifier = bottomPad.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { - OutlinedTextField(value = filteredName, + OutlinedTextField( + value = filteredName, modifier = sidePad, onValueChange = { filteredName = it }, label = { Text("File name") }, diff --git a/composeApp/src/commonMain/kotlin/ui/model/AppPages.kt b/composeApp/src/commonMain/kotlin/ui/model/AppPages.kt new file mode 100644 index 0000000..1c87206 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ui/model/AppPages.kt @@ -0,0 +1,15 @@ +package ui.model + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Archive +import androidx.compose.material.icons.filled.Home +import androidx.compose.material.icons.filled.Inbox +import androidx.compose.material.icons.filled.Settings +import androidx.compose.ui.graphics.vector.ImageVector + +enum class AppPages(val icon: ImageVector, val title: String) { + HOME(Icons.Filled.Home, "Home"), + JOBS(Icons.Filled.Inbox, "Jobs"), + BACKUPS(Icons.Filled.Archive, "Backups"), // Icons.Filled.Archive + SETTINGS(Icons.Filled.Settings, "Settings"), +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/ui/model/Screen.kt b/composeApp/src/commonMain/kotlin/ui/model/Screen.kt deleted file mode 100644 index f5f1081..0000000 --- a/composeApp/src/commonMain/kotlin/ui/model/Screen.kt +++ /dev/null @@ -1,14 +0,0 @@ -package ui.model - -import androidx.compose.runtime.Composable - -interface Screen { - - val name: String - - @Composable - fun icon() - - @Composable - fun content() -} diff --git a/composeApp/src/desktopMain/kotlin/Previews.kt b/composeApp/src/desktopMain/kotlin/Previews.kt index 27976d0..39290ba 100644 --- a/composeApp/src/desktopMain/kotlin/Previews.kt +++ b/composeApp/src/desktopMain/kotlin/Previews.kt @@ -6,14 +6,14 @@ import io.github.jsixface.common.JobStatus import io.github.jsixface.common.MediaTrack import io.github.jsixface.common.TrackType import io.github.jsixface.common.VideoFile -import kotlin.random.Random import ui.BackendDialogContent -import ui.BackupsScreen -import ui.JobsScreen -import ui.SettingsScreen +import ui.BackupContent +import ui.JobContent +import ui.ListEditor import ui.home.FileDetails import ui.home.HomeScreen import ui.theme.AppTheme +import kotlin.random.Random private val videos = listOf( @@ -60,7 +60,7 @@ private val jobs = videos.mapIndexed { i, v -> @Preview fun seeSetting() { AppTheme { - SettingsScreen.ListEditor("Elite list", listOf("One", "Two", "Three"), {}, {}) + ListEditor("Elite list", listOf("One", "Two", "Three"), {}, {}) } } @@ -69,7 +69,7 @@ fun seeSetting() { fun seeJobs() { AppTheme { println(jobs.size) - JobsScreen.JobContent(jobs, onDelete = {}, onClear = {}) + JobContent(jobs, onDelete = {}, onClear = {}) } } @@ -78,7 +78,7 @@ fun seeJobs() { fun seeBackups() { AppTheme { val backups = listOf("The-Boys-S03E01-Payback-WEBDL-1080p.mkv.1710158838.bkp" ) - BackupsScreen.BackupContent(backups, {}, {}) + BackupContent(backups, {}, {}) } } diff --git a/gradle.properties b/gradle.properties index 9ae75d0..03164c4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,8 @@ kotlin.code.style=official #Gradle -org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M" - - +org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8" +kotlin.daemon.jvmargs=-Xmx3096M #Compose org.jetbrains.compose.experimental.wasm.enabled=true