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