Skip to content

Commit

Permalink
feat: Implement "Open Cart After Creation" functionality
Browse files Browse the repository at this point in the history
- Added DataStore preference `openCartsAfterCreation` to toggle automatic navigation after adding a cart.
- Updated `HomeViewModel` to observe the DataStore setting and navigate to the newly created cart when enabled.
- Modified `HomeScreen` composable to handle navigation based on the ViewModel's state.
- Fixed cartId handling to ensure the correct cart is opened automatically.
- Removed navigation logic from `HomeRepository` to maintain separation of concerns.
- Enhanced code clarity by adding explicit type annotations and cleaning up unnecessary lint suppressions.
- Set `android:windowSoftInputMode="adjustResize"` for all activities to ensure proper UI resizing when the keyboard appears.
- Updated the changelog to document the new feature and related improvements.
  • Loading branch information
Mihai-Cristian Condrea committed Dec 30, 2024
1 parent 60aabf8 commit aa418ed
Show file tree
Hide file tree
Showing 25 changed files with 451 additions and 412 deletions.
14 changes: 11 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Version 1.1.4:

- **Minor**: Small optimizations to ad initialization.
# Version 1.2.0:

- **New**: Added an "Open Cart After Creation" feature in settings, allowing you to automatically
view newly created carts.
- **Minor**: Improved UI handling when the keyboard appears, ensuring smoother interactions during
cart creation.
- **Minor**: Updated Gradle dependencies to the latest versions for enhanced stability and speed.
- **Patch**: Fixed an issue where newly created carts wouldn’t open correctly.
- **Patch**: Updated string resources for better clarity and consistency across the app.
- **Patch**: Cleaned up unused code and optimized existing features for better performance.
- **Patch**: Refactored some parts of the code to improve maintainability and efficiency.

# Version 1.1.3:

Expand Down
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ android {
minSdk = 23
targetSdk = 35
versionCode = 77
versionName = "1.1.4"
versionName = "1.2.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
resourceConfigurations += listOf(
"en" ,
Expand Down
45 changes: 30 additions & 15 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@

<activity
android:name=".ui.screens.startup.StartupActivity"
android:noHistory="true" />
android:noHistory="true"
android:windowSoftInputMode="adjustResize" />

<activity
android:name=".ui.screens.main.MainActivity"
android:exported="true"
android:theme="@style/SplashScreenTheme">
android:theme="@style/SplashScreenTheme"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.MAIN" />
Expand All @@ -55,48 +57,57 @@

<activity
android:name=".ui.screens.support.SupportActivity"
android:parentActivityName=".ui.screens.main.MainActivity" />
android:parentActivityName=".ui.screens.main.MainActivity"
android:windowSoftInputMode="adjustResize" />

<activity
android:name=".ui.screens.cart.CartActivity"
android:launchMode="singleTask"
android:parentActivityName=".ui.screens.main.MainActivity" />
android:parentActivityName=".ui.screens.main.MainActivity"
android:windowSoftInputMode="adjustResize" />

<activity
android:name=".ui.screens.settings.SettingsActivity"
android:exported="true"
android:label="@string/settings"
android:parentActivityName=".ui.screens.main.MainActivity">
android:parentActivityName=".ui.screens.main.MainActivity"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
</intent-filter>
</activity>

<activity
android:name=".ui.screens.settings.display.DisplaySettingsActivity"
android:parentActivityName=".ui.screens.settings.SettingsActivity" />
android:parentActivityName=".ui.screens.settings.SettingsActivity"
android:windowSoftInputMode="adjustResize" />

<activity
android:name=".ui.screens.settings.display.theme.ThemeSettingsActivity"
android:parentActivityName=".ui.screens.settings.display.DisplaySettingsActivity" />
android:parentActivityName=".ui.screens.settings.display.DisplaySettingsActivity"
android:windowSoftInputMode="adjustResize" />

<activity
android:name=".ui.screens.settings.cart.CartSettingsActivity"
android:parentActivityName=".ui.screens.settings.SettingsActivity" />
android:parentActivityName=".ui.screens.settings.SettingsActivity"
android:windowSoftInputMode="adjustResize" />

<activity
android:name=".ui.screens.settings.advanced.AdvancedSettingsActivity"
android:parentActivityName=".ui.screens.settings.SettingsActivity" />
android:parentActivityName=".ui.screens.settings.SettingsActivity"
android:windowSoftInputMode="adjustResize" />

<activity
android:name=".ui.screens.settings.privacy.PrivacySettingsActivity"
android:parentActivityName=".ui.screens.settings.SettingsActivity" />
android:parentActivityName=".ui.screens.settings.SettingsActivity"
android:windowSoftInputMode="adjustResize" />

<activity
android:name=".ui.screens.settings.privacy.permissions.PermissionsSettingsActivity"
android:exported="true"
android:parentActivityName=".ui.screens.settings.privacy.PrivacySettingsActivity"
android:permission="android.permission.START_VIEW_PERMISSION_USAGE">
android:permission="android.permission.START_VIEW_PERMISSION_USAGE"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
<action android:name="android.intent.action.VIEW_PERMISSION_USAGE_FOR_PERIOD" />
Expand All @@ -107,19 +118,23 @@

<activity
android:name=".ui.screens.settings.privacy.usage.UsageAndDiagnosticsActivity"
android:parentActivityName=".ui.screens.settings.privacy.PrivacySettingsActivity" />
android:parentActivityName=".ui.screens.settings.privacy.PrivacySettingsActivity"
android:windowSoftInputMode="adjustResize" />

<activity
android:name=".ui.screens.settings.privacy.ads.AdsSettingsActivity"
android:parentActivityName=".ui.screens.settings.privacy.PrivacySettingsActivity" />
android:parentActivityName=".ui.screens.settings.privacy.PrivacySettingsActivity"
android:windowSoftInputMode="adjustResize" />

<activity
android:name=".ui.screens.settings.about.AboutSettingsActivity"
android:parentActivityName=".ui.screens.settings.SettingsActivity" />
android:parentActivityName=".ui.screens.settings.SettingsActivity"
android:windowSoftInputMode="adjustResize" />

<activity
android:name=".ui.screens.help.HelpActivity"
android:parentActivityName=".ui.screens.main.MainActivity" />
android:parentActivityName=".ui.screens.main.MainActivity"
android:windowSoftInputMode="adjustResize" />

<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ import kotlinx.coroutines.supervisorScope
class AppCoreManager : MultiDexApplication() , Application.ActivityLifecycleCallbacks ,
LifecycleObserver {

private val dataStoreCoreManager by lazy {
private val dataStoreCoreManager : DataStoreCoreManager by lazy {
DataStoreCoreManager(context = this)
}

private val adsCoreManager by lazy {
private val adsCoreManager : AdsCoreManager by lazy {
AdsCoreManager(context = this)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.d4rk.cartcalculator.data.datastore

import android.content.Context
import androidx.compose.runtime.mutableStateOf
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.longPreferencesKey
Expand Down Expand Up @@ -117,7 +118,8 @@ class DataStore(context : Context) {
}
}

private val currencyKey = stringPreferencesKey(name = DataStoreNamesConstants.DATA_STORE_PREFERRED_CURRENCY)
// Carts
private val currencyKey : Preferences.Key<String> = stringPreferencesKey(name = DataStoreNamesConstants.DATA_STORE_PREFERRED_CURRENCY)

fun getCurrency(): Flow<String> {
return dataStore.data.map { preferences ->
Expand All @@ -131,6 +133,18 @@ class DataStore(context : Context) {
}
}

private val openCartsAfterCreationKey : Preferences.Key<Boolean> = booleanPreferencesKey(name = DataStoreNamesConstants.DATA_STORE_OPEN_CARTS_AFTER_CREATION)

val openCartsAfterCreation: Flow<Boolean> = dataStore.data.map { preferences ->
preferences[openCartsAfterCreationKey] ?: true
}

suspend fun saveOpenCartsAfterCreation(isEnabled: Boolean) {
dataStore.edit { preferences ->
preferences[openCartsAfterCreationKey] = isEnabled
}
}

// Usage and Diagnostics
private val usageAndDiagnosticsKey =
booleanPreferencesKey(name = DataStoreNamesConstants.DATA_STORE_USAGE_AND_DIAGNOSTICS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class AppUsageNotificationWorker(context: Context, workerParams: WorkerParameter
if (currentTimestamp - lastUsedTimestamp > notificationThreshold) {
val notificationManager : NotificationManager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val appUsageChannel : NotificationChannel = NotificationChannel(
val appUsageChannel = NotificationChannel(
appUsageChannelId,
applicationContext.getString(R.string.app_usage_notifications),
NotificationManager.IMPORTANCE_HIGH
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,6 @@ fun AdBanner(
}
}

@Composable
fun AdBannerFull(
modifier : Modifier = Modifier
) {
val showAds : Boolean by AppCoreManager.dataStore.ads.collectAsState(initial = true)

if (showAds) {
AndroidView(modifier = modifier.fillMaxWidth() , factory = { context ->
AdView(context).apply {
setAdSize(AdSize.FULL_BANNER)
adUnitId = AdsConstants.BANNER_AD_UNIT_ID
loadAd(AdRequest.Builder().build())
}
})
}
}

@Composable
fun LargeBannerAdsComposable(
modifier : Modifier = Modifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.SoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardCapitalization
Expand All @@ -33,9 +34,10 @@ import com.d4rk.cartcalculator.data.database.table.ShoppingCartItemsTable
fun AddNewCartItemAlertDialog(
cartId : Int , onDismiss : () -> Unit , onCartCreated : (ShoppingCartItemsTable) -> Unit
) {
val newCartItem = remember { mutableStateOf<ShoppingCartItemsTable?>(null) }
val newCartItem : MutableState<ShoppingCartItemsTable?> =
remember { mutableStateOf(value = null) }
AlertDialog(onDismissRequest = onDismiss , text = {
AddNewCartItemAlertDialogContent(cartId , newCartItem)
AddNewCartItemAlertDialogContent(cartId = cartId , newCartItem = newCartItem)
} , icon = {
Icon(
Icons.Outlined.ShoppingBag , contentDescription = null
Expand All @@ -46,13 +48,13 @@ fun AddNewCartItemAlertDialog(
onCartCreated(cartItem)
}
} , enabled = newCartItem.value != null) {
Text(text = stringResource(android.R.string.ok))
Text(text = stringResource(id = android.R.string.ok))
}
} , dismissButton = {
TextButton(onClick = {
onDismiss()
}) {
Text(text = stringResource(android.R.string.cancel))
Text(text = stringResource(id = android.R.string.cancel))
}
})
}
Expand All @@ -61,14 +63,14 @@ fun AddNewCartItemAlertDialog(
fun AddNewCartItemAlertDialogContent(
cartId : Int , newCartItem : MutableState<ShoppingCartItemsTable?>
) {
val nameText = remember { mutableStateOf(value = "") }
val priceText = remember { mutableStateOf(value = "") }
val quantityText = remember { mutableStateOf(value = "") }
val nameText : MutableState<String> = remember { mutableStateOf(value = "") }
val priceText : MutableState<String> = remember { mutableStateOf(value = "") }
val quantityText : MutableState<String> = remember { mutableStateOf(value = "") }

val nameFocusRequester = remember { FocusRequester() }
val priceFocusRequester = remember { FocusRequester() }
val quantityFocusRequester = remember { FocusRequester() }
val keyboardController = LocalSoftwareKeyboardController.current
val nameFocusRequester : FocusRequester = remember { FocusRequester() }
val priceFocusRequester : FocusRequester = remember { FocusRequester() }
val quantityFocusRequester : FocusRequester = remember { FocusRequester() }
val keyboardController : SoftwareKeyboardController? = LocalSoftwareKeyboardController.current

Column {
OutlinedTextField(value = nameText.value ,
Expand All @@ -81,7 +83,7 @@ fun AddNewCartItemAlertDialogContent(
) ,
keyboardActions = KeyboardActions(onNext = { priceFocusRequester.requestFocus() }) ,
placeholder = { Text(text = stringResource(id = R.string.enter_item_name)) } ,
modifier = Modifier.focusRequester(nameFocusRequester))
modifier = Modifier.focusRequester(focusRequester = nameFocusRequester))

OutlinedTextField(value = priceText.value ,
singleLine = true ,
Expand All @@ -92,7 +94,7 @@ fun AddNewCartItemAlertDialogContent(
keyboardType = KeyboardType.Number , imeAction = ImeAction.Next
) ,
keyboardActions = KeyboardActions(onNext = { quantityFocusRequester.requestFocus() }) ,
modifier = Modifier.focusRequester(priceFocusRequester)
modifier = Modifier.focusRequester(focusRequester = priceFocusRequester)
)

OutlinedTextField(value = quantityText.value ,
Expand All @@ -106,18 +108,19 @@ fun AddNewCartItemAlertDialogContent(
keyboardActions = KeyboardActions(onDone = {
keyboardController?.hide()
}) ,
modifier = Modifier.focusRequester(quantityFocusRequester)
modifier = Modifier.focusRequester(focusRequester = quantityFocusRequester)
)

Spacer(modifier = Modifier.height(24.dp))
Spacer(modifier = Modifier.height(height = 24.dp))
Icon(imageVector = Icons.Outlined.Info , contentDescription = null)
Spacer(modifier = Modifier.height(12.dp))
Text(stringResource(id = R.string.dialog_info_cart_item))
Spacer(modifier = Modifier.height(height = 12.dp))
Text(text = stringResource(id = R.string.dialog_info_cart_item))
}

if (nameText.value.isNotBlank() && priceText.value.isNotBlank() && quantityText.value.isNotBlank()) {
val price = priceText.value.replace(oldChar = ',' , newChar = '.').toDoubleOrNull()
val quantity = quantityText.value.toIntOrNull()
val price : Double? =
priceText.value.replace(oldChar = ',' , newChar = '.').toDoubleOrNull()
val quantity : Int? = quantityText.value.toIntOrNull()
if (price != null && quantity != null) {
newCartItem.value = ShoppingCartItemsTable(
cartId = cartId ,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ fun DeleteCartAlertDialog(
onDeleteConfirmed(cart !!)
onDismiss()
}) {
Text(text =stringResource(android.R.string.ok))
Text(text =stringResource(id = android.R.string.ok))
}
} , dismissButton = {
TextButton(onClick = {
onDismiss() }) {
Text(text =stringResource(android.R.string.cancel))
Text(text =stringResource(id = android.R.string.cancel))
}
})
}
Expand All @@ -54,14 +54,14 @@ fun DeleteCartAlertDialogContent(cart : ShoppingCartTable?) {
modifier = Modifier.align(Alignment.CenterHorizontally) ,
tint = MaterialTheme.colorScheme.error
)
Spacer(modifier = Modifier.height(24.dp))
Spacer(modifier = Modifier.height(height = 24.dp))
Text(
text = stringResource(id= R.string.delete_cart_message) ,
style = MaterialTheme.typography.bodyLarge
)
Spacer(modifier = Modifier.height(24.dp))
Spacer(modifier = Modifier.height(height = 24.dp))
Icon(imageVector = Icons.Outlined.Info , contentDescription = null)
Spacer(modifier = Modifier.height(12.dp))
Spacer(modifier = Modifier.height(height = 12.dp))
Text(
text = stringResource(id= R.string.delete_cart_warning , cart?.name ?: "") ,
style = MaterialTheme.typography.bodyLarge
Expand Down
Loading

0 comments on commit aa418ed

Please sign in to comment.