Pith - kerf
kerf/app/src/main/java/com/vgmlr/kerf/HomeScreen.kt [8.0 kb]
Modified: 23:09:03 55 026 (13 May 026)
17 Days Ago
package com.vgmlr.kerf

import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.outlined.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HomeScreen(vm: NoteViewModel, nav: NavHostController) {
    val notesList by vm.allNotes.collectAsState()
    val ctx = LocalContext.current

    val showMenu = remember { mutableStateOf(false) }
    val showVersionDialog = remember { mutableStateOf(false) }
    val showSearchDialog = remember { mutableStateOf(false) }

    val kerfColors = LocalKerfColors.current!!
    val listState = rememberLazyListState()

    val importLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.OpenDocument()
    ) { uri ->
        uri?.let {
            vm.setSharedFile(KerfUtils.importNoteFromUri(ctx, it))
        }
    }

    if (showVersionDialog.value) VersionDialog { showVersionDialog.value = false }

    if (showSearchDialog.value) {
        SearchDialog(
            notes = notesList,
            onSelect = { id ->
                showSearchDialog.value = false
                nav.navigate(KerfScreen.Edit.createRoute(id))
            },
            onDismiss = { showSearchDialog.value = false }
        )
    }

    Scaffold(
        topBar = {
            TopAppBar(
                title = { },
                actions = {
                    Text(
                        text = "kerf",
                        color = MaterialTheme.colorScheme.onPrimary,
                        fontSize = KerfDimens.TextSizeTitle,
                        modifier = Modifier.padding(end = KerfDimens.PaddingLarge)
                    )
                    IconButton(onClick = { vm.addNote { nav.navigate(KerfScreen.Edit.createRoute(it)) } }) {
                        Icon(Icons.Default.Add, "New List", tint = MaterialTheme.colorScheme.onPrimary)
                    }
                    IconButton(onClick = { showSearchDialog.value = true }) {
                        Icon(Icons.Default.Search, "Search", tint = MaterialTheme.colorScheme.onPrimary)
                    }
                    Box {
                        IconButton(onClick = { showMenu.value = true }) { Icon(Icons.Default.MoreVert, null, tint = MaterialTheme.colorScheme.onPrimary) }
                        DropdownMenu(expanded = showMenu.value, onDismissRequest = { showMenu.value = false }, modifier = Modifier.background(kerfColors.menuBackground).padding(horizontal = 6.dp)) {
                            DropdownMenuItem(
                                leadingIcon = { Icon(Icons.Outlined.FileOpen, null, tint = kerfColors.menuText) },
                                text = { Text("Import", color = kerfColors.menuText) },
                                onClick = {
                                    showMenu.value = false
                                    importLauncher.launch(arrayOf("*/*"))
                                }
                            )
                            DropdownMenuItem(
                                leadingIcon = { Icon(Icons.Outlined.History, null, tint = kerfColors.menuText) },
                                text = { Text("Version", color = kerfColors.menuText) },
                                onClick = { showMenu.value = false; showVersionDialog.value = true }
                            )
                        }
                    }
                },
                colors = TopAppBarDefaults.topAppBarColors(containerColor = kerfColors.appTopbar)
            )
        },
        containerColor = kerfColors.appTopbar
    ) { padding ->
        Surface(modifier = Modifier.padding(padding).fillMaxSize(), shape = RectangleShape, color = MaterialTheme.colorScheme.background) {
            LazyColumn(state = listState, contentPadding = PaddingValues(bottom = KerfDimens.PaddingLarge), modifier = Modifier.fillMaxSize()) {
                items(items = notesList, key = { it.id }) { note ->
                    Card(
                        colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
                        shape = RectangleShape,
                        modifier = Modifier
                            .fillMaxWidth()
                            .clickable { nav.navigate(KerfScreen.Edit.createRoute(note.id)) }
                    ) {
                        Column {
                            Box(Modifier.fillMaxWidth().background(kerfColors.noteHeaderMain).padding(horizontal = KerfDimens.PaddingLarge, vertical = 12.dp)) {
                                Text(
                                    text = note.title.ifBlank { "Untitled" },
                                    fontWeight = FontWeight.Bold,
                                    maxLines = 1,
                                    overflow = TextOverflow.Ellipsis,
                                    modifier = Modifier.align(Alignment.CenterStart)
                                )
                                Row(Modifier.align(Alignment.CenterEnd), verticalAlignment = Alignment.CenterVertically) {
                                    if (note.content.length > 3) {
                                        val itemCount = KerfUtils.countNumberedItems(note.content)
                                        Text(text = "$itemCount / ${note.content.length}", color = MaterialTheme.colorScheme.onPrimary, fontSize = KerfDimens.TextSizeMedium)
                                    }
                                    if (note.isPinned) {
                                        Icon(
                                            imageVector = Icons.Outlined.PushPin,
                                            contentDescription = null,
                                            tint = MaterialTheme.colorScheme.onPrimary,
                                            modifier = Modifier.padding(start = 12.dp).size(20.dp)
                                        )
                                    }
                                    IconButton(onClick = { vm.deleteNote(note.id) }, Modifier.padding(start = 8.dp).size(24.dp)) { Icon(Icons.Default.Close, null) }
                                }
                            }
                            Column(Modifier.padding(KerfDimens.PaddingLarge)) {
                                val visibleLines = note.content.lineSequence().filter { it.isNotBlank() }.toList()
                                val previewLines = visibleLines.take(7)

                                previewLines.forEach { line ->
                                    Text(
                                        text = line,
                                        color = MaterialTheme.colorScheme.onSurfaceVariant,
                                        maxLines = 1,
                                        overflow = TextOverflow.Ellipsis,
                                        modifier = Modifier.fillMaxWidth()
                                    )
                                }

                                if (visibleLines.size > 7) {
                                    Text(text = "[more]", color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.fillMaxWidth())
                                }
                            }
                        }
                    }
                    HorizontalDivider(color = Color.Gray.copy(0.2f))
                }
            }
        }
    }
}
Updates
Shim - Android 70.026.1
Wedge - Linux 68.026.1
Wedge - Android 68.026.1
Taper - Linux 64.026.1
Ayh Extension - Chrome 63.026.1
Dev
TVShow (227) 'CSA'
TVShow (228) 'APT'
TVProgram (83) 'BXT'
Miter Update(s)
Shim (Dictation)

Menu
Calendar
Project Tin (024/029)
Miter
RSS Feed
User Avatar
@vgmlr
=SUM(parts)