diff --git a/app/build.gradle b/app/build.gradle index f5adace..d195e9e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,7 +14,7 @@ android { applicationId "net.helcel.cowspent" minSdk = 26 targetSdk = 37 - versionName project.hasProperty('VERSION_NAME') ? project.property('VERSION_NAME') : "1" + versionName project.hasProperty('VERSION_NAME') ? project.property('VERSION_NAME') : "1.4" versionCode project.hasProperty('VERSION_CODE') ? project.property('VERSION_CODE').toInteger() : 1 } diff --git a/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillScreen.kt b/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillScreen.kt index 901469b..42fddcc 100644 --- a/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillScreen.kt +++ b/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillScreen.kt @@ -467,7 +467,7 @@ fun BillAdditionalDetailsSection( modifier = Modifier.padding(bottom = 8.dp, top = 16.dp) ) - val context = androidx.compose.ui.platform.LocalContext.current + val context = LocalContext.current var categoryExpanded by remember { mutableStateOf(false) } val selectedCategory = categories.find { it.id == viewModel.categoryId } ?: CategoryUtils.getCategoryById(context, viewModel.categoryId) diff --git a/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillViewModel.kt b/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillViewModel.kt index cd9b3ba..16918d8 100644 --- a/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillViewModel.kt +++ b/app/src/main/java/net/helcel/cowspent/android/bill_edit/EditBillViewModel.kt @@ -2,22 +2,20 @@ package net.helcel.cowspent.android.bill_edit import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableDoubleStateOf -import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue +import androidx.compose.ui.graphics.vector.ImageVector import androidx.lifecycle.ViewModel -import net.helcel.cowspent.model.DBBill -import net.helcel.cowspent.model.DBMember import net.helcel.cowspent.android.helper.DialogState import net.helcel.cowspent.android.helper.parseAmount +import net.helcel.cowspent.model.DBBill +import net.helcel.cowspent.model.DBCurrency +import net.helcel.cowspent.model.DBMember import net.helcel.cowspent.util.SupportUtil import net.helcel.cowspent.util.evalMath -import net.helcel.cowspent.model.DBCurrency -import androidx.compose.ui.graphics.vector.ImageVector - class EditBillViewModel : ViewModel() { var what by mutableStateOf("") var amount by mutableStateOf("") diff --git a/app/src/main/java/net/helcel/cowspent/android/main/BillsListScreen.kt b/app/src/main/java/net/helcel/cowspent/android/main/BillsListScreen.kt index 3057b91..bf4d881 100644 --- a/app/src/main/java/net/helcel/cowspent/android/main/BillsListScreen.kt +++ b/app/src/main/java/net/helcel/cowspent/android/main/BillsListScreen.kt @@ -103,6 +103,10 @@ fun BillsListScreen( val context = LocalContext.current val sharedPreferences = remember { PreferenceManager.getDefaultSharedPreferences(context) } val showArchived = sharedPreferences.getBoolean(stringResource(R.string.pref_key_show_archived), false) + val keyBetaFeatures = stringResource(R.string.pref_key_beta_features) + var showBetaFeatures by remember(keyBetaFeatures) { + mutableStateOf(sharedPreferences.getBoolean(keyBetaFeatures, false)) + } StatefulAlertDialog( state = viewModel.dialogState, @@ -158,7 +162,8 @@ fun BillsListScreen( isArchived = proj?.isArchived == true, projectType = proj?.type ?: ProjectType.LOCAL, accessLevel = proj?.myAccessLevel ?: DBProject.ACCESS_LEVEL_ADMIN, - isShareable = proj?.isShareable() ?: true + isShareable = proj?.isShareable() ?: true, + showBetaFeatures = showBetaFeatures ) } } @@ -327,7 +332,7 @@ fun BillsListScreen( }, actions = { if (!isSearchExpanded) { - if (viewModel.hasUnlabeledBills) { + if (showBetaFeatures && viewModel.hasUnlabeledBills) { IconButton(onClick = onLabelBillsClick) { Icon( Icons.Default.Category, diff --git a/app/src/main/java/net/helcel/cowspent/android/project/ProjectOptionsDialog.kt b/app/src/main/java/net/helcel/cowspent/android/project/ProjectOptionsDialog.kt index 4bba2d9..13e2cfb 100644 --- a/app/src/main/java/net/helcel/cowspent/android/project/ProjectOptionsDialog.kt +++ b/app/src/main/java/net/helcel/cowspent/android/project/ProjectOptionsDialog.kt @@ -35,7 +35,8 @@ fun ProjectOptionsDialogContent( isArchived: Boolean = false, projectType: ProjectType = ProjectType.LOCAL, accessLevel: Int = DBProject.ACCESS_LEVEL_ADMIN, - isShareable: Boolean = true + isShareable: Boolean = true, + showBetaFeatures: Boolean = false ) { Surface( shape = MaterialTheme.shapes.large, @@ -79,7 +80,7 @@ fun ProjectOptionsDialogContent( // Row 2: Manage Member, Manage Labels, Manage Currencies if (!isArchived && isMaintainer) { row2.add(ProjectOption(stringResource(R.string.action_members), Icons.Default.Group, onManageMembers)) - if (false && (projectType == ProjectType.LOCAL || projectType == ProjectType.COSPEND)) { + if (showBetaFeatures && (projectType == ProjectType.LOCAL || projectType == ProjectType.COSPEND)) { row2.add(ProjectOption(stringResource(R.string.action_labels), Icons.AutoMirrored.Filled.Label, onManageLabels)) } row2.add(ProjectOption(stringResource(R.string.action_currencies), Icons.Default.MonetizationOn, onManageCurrencies)) @@ -181,7 +182,8 @@ fun ProjectOptionsDialogPreview() { isArchived = false, projectType = ProjectType.COSPEND, accessLevel = DBProject.ACCESS_LEVEL_ADMIN, - isShareable = true + isShareable = true, + showBetaFeatures = true ) } } @@ -205,7 +207,8 @@ fun ProjectOptionsDialogPreview2() { isArchived = true, projectType = ProjectType.COSPEND, accessLevel = DBProject.ACCESS_LEVEL_ADMIN, - isShareable = true + isShareable = true, + showBetaFeatures = true ) } } @@ -228,7 +231,8 @@ fun ProjectOptionsDialogPreview3() { isArchived = false, projectType = ProjectType.LOCAL, accessLevel = DBProject.ACCESS_LEVEL_ADMIN, - isShareable = true + isShareable = true, + showBetaFeatures = true ) } } diff --git a/app/src/main/java/net/helcel/cowspent/android/settings/SettingsScreen.kt b/app/src/main/java/net/helcel/cowspent/android/settings/SettingsScreen.kt index 71f0e33..dc3ffa1 100644 --- a/app/src/main/java/net/helcel/cowspent/android/settings/SettingsScreen.kt +++ b/app/src/main/java/net/helcel/cowspent/android/settings/SettingsScreen.kt @@ -79,6 +79,7 @@ fun SettingsScreen( val keyColor = stringResource(R.string.pref_key_color) val keyOfflineMode = stringResource(R.string.pref_key_offline_mode) val keyShowArchived = stringResource(R.string.pref_key_show_archived) + val keyBetaFeatures = stringResource(R.string.pref_key_beta_features) // States for preferences var nightMode by remember(keyNightMode) { @@ -113,6 +114,9 @@ fun SettingsScreen( var showArchived by remember(keyShowArchived) { mutableStateOf(sharedPreferences.getBoolean(keyShowArchived, false)) } + var betaFeatures by remember(keyBetaFeatures) { + mutableStateOf(sharedPreferences.getBoolean(keyBetaFeatures, false)) + } Scaffold( topBar = { @@ -242,6 +246,19 @@ fun SettingsScreen( // Other SettingsCategory(stringResource(R.string.settings_other)) + SettingsSwitchPreference( + title = stringResource(R.string.settings_beta_features), + summary = stringResource(R.string.settings_beta_features_summary), + icon = Icons.Default.Info, + checked = betaFeatures, + onCheckedChange = { + betaFeatures = it + sharedPreferences.edit { + putBoolean(keyBetaFeatures, it) + } + } + ) + SettingsPreference( title = stringResource(R.string.title_about), icon = Icons.Default.Info, diff --git a/app/src/main/java/net/helcel/cowspent/model/DBBill.kt b/app/src/main/java/net/helcel/cowspent/model/DBBill.kt index 91fd0e5..66b85c4 100644 --- a/app/src/main/java/net/helcel/cowspent/model/DBBill.kt +++ b/app/src/main/java/net/helcel/cowspent/model/DBBill.kt @@ -1,6 +1,5 @@ package net.helcel.cowspent.model -import android.util.Log import java.io.Serializable import java.util.Calendar import java.util.Locale diff --git a/app/src/main/java/net/helcel/cowspent/persistence/CowspentSQLiteOpenHelper.kt b/app/src/main/java/net/helcel/cowspent/persistence/CowspentSQLiteOpenHelper.kt index ee1cb76..e4b082e 100644 --- a/app/src/main/java/net/helcel/cowspent/persistence/CowspentSQLiteOpenHelper.kt +++ b/app/src/main/java/net/helcel/cowspent/persistence/CowspentSQLiteOpenHelper.kt @@ -7,16 +7,22 @@ import android.database.Cursor import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper import android.text.TextUtils -import android.util.Log import androidx.annotation.WorkerThread import androidx.preference.PreferenceManager import net.helcel.cowspent.R -import net.helcel.cowspent.android.main.BillsListViewActivity -import net.helcel.cowspent.model.* +import net.helcel.cowspent.model.DBAccountProject +import net.helcel.cowspent.model.DBBill +import net.helcel.cowspent.model.DBBillOwer +import net.helcel.cowspent.model.DBCategory +import net.helcel.cowspent.model.DBCurrency +import net.helcel.cowspent.model.DBMember +import net.helcel.cowspent.model.DBPaymentMode +import net.helcel.cowspent.model.DBProject +import net.helcel.cowspent.model.ProjectType import net.helcel.cowspent.util.CategoryUtils import net.helcel.cowspent.util.SecureStorage import net.helcel.cowspent.util.SupportUtil -import java.util.* +import java.util.Locale /** * Helps to add, get, update and delete bills, members, projects with the option to trigger a sync with the server. @@ -1177,7 +1183,6 @@ class CowspentSQLiteOpenHelper private constructor(val context: Context) : @Suppress("ConstPropertyName") companion object { - private val TAG = CowspentSQLiteOpenHelper::class.java.simpleName private const val database_version = 1 private const val database_name = "COWSPENT" private const val table_members = "MEMBERS" diff --git a/app/src/main/java/net/helcel/cowspent/persistence/CowspentServerSyncHelper.kt b/app/src/main/java/net/helcel/cowspent/persistence/CowspentServerSyncHelper.kt index a750d01..d6272ca 100644 --- a/app/src/main/java/net/helcel/cowspent/persistence/CowspentServerSyncHelper.kt +++ b/app/src/main/java/net/helcel/cowspent/persistence/CowspentServerSyncHelper.kt @@ -29,11 +29,9 @@ import net.helcel.cowspent.android.account.AccountActivity import net.helcel.cowspent.android.main.BillsListViewActivity import net.helcel.cowspent.android.main.MainConstants import net.helcel.cowspent.model.DBBill -import net.helcel.cowspent.model.DBCategory import net.helcel.cowspent.model.DBProject import net.helcel.cowspent.model.ProjectType import net.helcel.cowspent.util.CospendClientUtil.LoginStatus -import net.helcel.cowspent.util.CategoryUtils import net.helcel.cowspent.util.ICallback import net.helcel.cowspent.util.IProjectCreationCallback import net.helcel.cowspent.util.NextcloudClient diff --git a/app/src/main/java/net/helcel/cowspent/util/NextcloudClient.kt b/app/src/main/java/net/helcel/cowspent/util/NextcloudClient.kt index b8a1ded..5d0e244 100644 --- a/app/src/main/java/net/helcel/cowspent/util/NextcloudClient.kt +++ b/app/src/main/java/net/helcel/cowspent/util/NextcloudClient.kt @@ -103,9 +103,6 @@ class NextcloudClient( val acceptHeader: MutableList = ArrayList() acceptHeader.add("application/json") headers["Accept"] = acceptHeader - val ocsHeader: MutableList = ArrayList() - ocsHeader.add("true") - headers["OCS-APIRequest"] = ocsHeader } val nextcloudRequest: NextcloudRequest = if (params == null) { NextcloudRequest.Builder() diff --git a/app/src/main/java/net/helcel/cowspent/util/ServerResponse.kt b/app/src/main/java/net/helcel/cowspent/util/ServerResponse.kt index 4ae3e17..d1feac3 100644 --- a/app/src/main/java/net/helcel/cowspent/util/ServerResponse.kt +++ b/app/src/main/java/net/helcel/cowspent/util/ServerResponse.kt @@ -68,7 +68,7 @@ open class ServerResponse( } val rawData = JSONObject(content) val data = rawData.getJSONObject("ocs") - return data.get("data").toString() + return data.getString("data") } class ProjectResponse(response: VersatileProjectSyncClient.ResponseData, isOcsResponse: Boolean) : diff --git a/app/src/main/java/net/helcel/cowspent/util/VersatileProjectSyncClient.kt b/app/src/main/java/net/helcel/cowspent/util/VersatileProjectSyncClient.kt index 2312552..1918ecb 100644 --- a/app/src/main/java/net/helcel/cowspent/util/VersatileProjectSyncClient.kt +++ b/app/src/main/java/net/helcel/cowspent/util/VersatileProjectSyncClient.kt @@ -88,7 +88,7 @@ class VersatileProjectSyncClient( "/ocs/v2.php/apps/cospend/api/v1/projects/" + project.remoteId else "/index.php/apps/cospend/api-priv/projects/" + project.remoteId - return ServerResponse.ProjectResponse(requestServerWithSSO(nextcloudAPI!!, target, METHOD_GET, null, null, true), true) + return ServerResponse.ProjectResponse(requestServerWithSSO(nextcloudAPI!!, target, METHOD_GET, null, null, cospendVersionGT161), cospendVersionGT161) } else { useOcsApiRequest = cospendVersionGT161 target = if (cospendVersionGT161) @@ -1348,9 +1348,6 @@ class VersatileProjectSyncClient( val acceptHeader: MutableList = ArrayList() acceptHeader.add("application/json") headers["Accept"] = acceptHeader - val ocsHeader: MutableList = ArrayList() - ocsHeader.add("true") - headers["OCS-APIRequest"] = ocsHeader } val nextcloudRequest: NextcloudRequest = if (params == null) { NextcloudRequest.Builder() diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fbdadd5..c11e725 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -135,6 +135,8 @@ Custom color Color Selection Show archived projects + Beta Features + Enable experimental features. Use at your own risk. WARNING: "http" is unsafe. Use "https". Choose Color @@ -155,6 +157,7 @@ colorMode offlineMode showArchived + betaFeatures 1 2 -1