From 8564f645760572dac1b828b4c311d891fcd3eeb8 Mon Sep 17 00:00:00 2001 From: soraefir Date: Sun, 6 Sep 2026 02:56:32 +0200 Subject: [PATCH] Project Cleanup/Refactor --- .../project/edit/EditProjectActivity.kt | 45 ++++++++++--------- .../project/edit/EditProjectViewModel.kt | 26 +++++++++++ .../statistics/ProjectStatisticsTable.kt | 19 +++++--- 3 files changed, 64 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/net/helcel/cowspent/android/project/edit/EditProjectActivity.kt b/app/src/main/java/net/helcel/cowspent/android/project/edit/EditProjectActivity.kt index 1839fa2..b500a27 100644 --- a/app/src/main/java/net/helcel/cowspent/android/project/edit/EditProjectActivity.kt +++ b/app/src/main/java/net/helcel/cowspent/android/project/edit/EditProjectActivity.kt @@ -3,8 +3,8 @@ package net.helcel.cowspent.android.project.edit import android.content.Intent import android.os.Bundle import android.widget.Toast -import androidx.activity.enableEdgeToEdge import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope @@ -13,12 +13,11 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import net.helcel.cowspent.R import net.helcel.cowspent.android.helper.showToast +import net.helcel.cowspent.android.main.MainConstants import net.helcel.cowspent.model.DBProject import net.helcel.cowspent.persistence.CowspentSQLiteOpenHelper import net.helcel.cowspent.theme.ThemeUtils import net.helcel.cowspent.util.ICallback -import net.helcel.cowspent.util.SupportUtil -import net.helcel.cowspent.android.main.MainConstants class EditProjectActivity : AppCompatActivity() { @@ -56,29 +55,33 @@ class EditProjectActivity : AppCompatActivity() { } private fun onSave() { + when (viewModel.validate()) { + EditProjectViewModel.ValidationError.EMPTY_NAME -> { + showToast(this, getString(R.string.error_invalid_project_name), Toast.LENGTH_LONG) + return + } + EditProjectViewModel.ValidationError.INVALID_EMAIL -> { + showToast(this, getString(R.string.error_invalid_email), Toast.LENGTH_LONG) + return + } + null -> Unit + } + + val changes = viewModel.changesFrom(project) + if (!changes.any) { + showToast(this, getString(R.string.project_edition_no_change), Toast.LENGTH_LONG) + return + } + val currentPwd = viewModel.password val newPwd = viewModel.newPassword val newName = viewModel.name val newEmail = viewModel.email - if (newName.isEmpty()) { - showToast(this, getString(R.string.error_invalid_project_name), Toast.LENGTH_LONG) - return - } - if (newEmail.isNotEmpty() && !SupportUtil.isValidEmail(newEmail)) { - showToast(this, getString(R.string.error_invalid_email), Toast.LENGTH_LONG) - return - } - - val nameChanged = newName != project.name - val emailChanged = newEmail != project.email - val pwdChanged = newPwd != project.password - val currentPwdChanged = currentPwd != project.password - - if (!nameChanged && !emailChanged && !pwdChanged && !currentPwdChanged) { - showToast(this, getString(R.string.project_edition_no_change), Toast.LENGTH_LONG) - return - } + val nameChanged = changes.name + val emailChanged = changes.email + val pwdChanged = changes.newPassword + val currentPwdChanged = changes.currentPassword if (project.isLocal) { val targetPwd = if (pwdChanged) newPwd else currentPwd diff --git a/app/src/main/java/net/helcel/cowspent/android/project/edit/EditProjectViewModel.kt b/app/src/main/java/net/helcel/cowspent/android/project/edit/EditProjectViewModel.kt index 8b7d26e..ceee11a 100644 --- a/app/src/main/java/net/helcel/cowspent/android/project/edit/EditProjectViewModel.kt +++ b/app/src/main/java/net/helcel/cowspent/android/project/edit/EditProjectViewModel.kt @@ -7,6 +7,7 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.lifecycle.ViewModel import net.helcel.cowspent.android.helper.DialogState import net.helcel.cowspent.model.DBProject +import net.helcel.cowspent.util.SupportUtil class EditProjectViewModel : ViewModel() { var name by mutableStateOf("") @@ -17,6 +18,31 @@ class EditProjectViewModel : ViewModel() { var dialogState by mutableStateOf(null) + enum class ValidationError { EMPTY_NAME, INVALID_EMAIL } + + fun validate(): ValidationError? = when { + name.isBlank() -> ValidationError.EMPTY_NAME + email.isNotEmpty() && !SupportUtil.isValidEmail(email) -> ValidationError.INVALID_EMAIL + else -> null + } + + data class Changes( + val name: Boolean, + val email: Boolean, + val newPassword: Boolean, + val currentPassword: Boolean + ) { + val any: Boolean get() = name || email || newPassword || currentPassword + } + + fun changesFrom(project: DBProject) = Changes( + name = name != project.name, + // initFromProject maps a null or "null" email to "", so treat those as unchanged + email = email != project.email && !(email.isEmpty() && project.email == null), + newPassword = newPassword != project.password, + currentPassword = password != project.password + ) + fun showDialog( title: String? = null, message: String? = null, diff --git a/app/src/main/java/net/helcel/cowspent/android/statistics/ProjectStatisticsTable.kt b/app/src/main/java/net/helcel/cowspent/android/statistics/ProjectStatisticsTable.kt index 71f21a1..2ecff81 100644 --- a/app/src/main/java/net/helcel/cowspent/android/statistics/ProjectStatisticsTable.kt +++ b/app/src/main/java/net/helcel/cowspent/android/statistics/ProjectStatisticsTable.kt @@ -3,8 +3,8 @@ package net.helcel.cowspent.android.statistics import android.app.DatePickerDialog import android.content.Context import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* @@ -285,9 +285,18 @@ fun ProjectStatisticsTable( Spacer(modifier = Modifier.height(4.dp)) - LazyColumn(modifier = Modifier.weight(1f)) { - items(stats.memberStats) { m -> - Row(modifier = Modifier.fillMaxWidth().padding(vertical = 12.dp, horizontal = 8.dp), verticalAlignment = Alignment.CenterVertically) { + Column( + modifier = Modifier + .weight(1f) + .verticalScroll(rememberScrollState()) + ) { + stats.memberStats.forEach { m -> + Row( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 12.dp, horizontal = 8.dp), + verticalAlignment = Alignment.CenterVertically + ) { Text(m.name, modifier = Modifier.weight(2f), color = MaterialTheme.colors.onSurface, fontWeight = FontWeight.Medium) Text(