diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index 5815a4a..c224ad5 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/app/src/androidTest/kotlin/com/d4rk/cartcalculator/ExampleInstrumentedTest.kt b/app/src/androidTest/kotlin/com/d4rk/cartcalculator/ExampleInstrumentedTest.kt deleted file mode 100644 index 4f996d6..0000000 --- a/app/src/androidTest/kotlin/com/d4rk/cartcalculator/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.d4rk.cartcalculator - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.d4rk.cartcalculator", appContext.packageName) - } -} \ No newline at end of file diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/data/core/AppCoreManager.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/data/core/AppCoreManager.kt index 774bb6d..c38bb27 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/data/core/AppCoreManager.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/data/core/AppCoreManager.kt @@ -22,6 +22,7 @@ import com.d4rk.cartcalculator.data.database.migrations.MIGRATION_2_3 import com.d4rk.cartcalculator.data.datastore.DataStore import com.d4rk.cartcalculator.utils.error.ErrorHandler.handleInitializationFailure import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Deferred import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.launch @@ -51,8 +52,8 @@ class AppCoreManager : MultiDexApplication() , Application.ActivityLifecycleCall } private suspend fun initializeApp() = supervisorScope { - val dataBase = async { initializeDatabase() } - val dataStore = async { initializeDataStore() } + val dataBase : Deferred = async { initializeDatabase() } + val dataStore : Deferred = async { initializeDataStore() } dataBase.await() dataStore.await() diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/data/database/migrations/Migrations.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/data/database/migrations/Migrations.kt index 821a835..4914c50 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/data/database/migrations/Migrations.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/data/database/migrations/Migrations.kt @@ -3,8 +3,8 @@ package com.d4rk.cartcalculator.data.database.migrations import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase -val MIGRATION_2_3 = object : Migration(2 , 3) { +val MIGRATION_2_3 : Migration = object : Migration(startVersion = 2 , endVersion = 3) { override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE ShoppingCartItemsTable ADD COLUMN isChecked INTEGER NOT NULL DEFAULT 0") + db.execSQL(sql = "ALTER TABLE ShoppingCartItemsTable ADD COLUMN isChecked INTEGER NOT NULL DEFAULT 0") } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/data/model/ui/screens/UiMainScreen.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/data/model/ui/screens/UiMainScreen.kt new file mode 100644 index 0000000..1cf557d --- /dev/null +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/data/model/ui/screens/UiMainScreen.kt @@ -0,0 +1,7 @@ +package com.d4rk.cartcalculator.data.model.ui.screens + +import com.d4rk.cartcalculator.data.model.ui.navigation.NavigationDrawerItem + +data class UiMainScreen( + val navigationDrawerItems : List = listOf() , +) \ No newline at end of file diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/managers/AppUpdateNotificationsManager.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/managers/AppUpdateNotificationsManager.kt index 134d4b4..7cdaa2b 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/managers/AppUpdateNotificationsManager.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/managers/AppUpdateNotificationsManager.kt @@ -23,8 +23,8 @@ import com.google.android.play.core.install.model.UpdateAvailability * @property context The application context used for notification management. */ class AppUpdateNotificationsManager(private val context: Context) { - private val updateChannelId = "update_channel" - private val updateNotificationId = 0 + private val updateChannelId : String = "update_channel" + private val updateNotificationId : Int = 0 /** * Checks for available app updates and sends a notification if an update is available. diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/managers/AppUsageNotificationsManager.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/managers/AppUsageNotificationsManager.kt index 28b2432..2d1a616 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/managers/AppUsageNotificationsManager.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/managers/AppUsageNotificationsManager.kt @@ -16,8 +16,8 @@ import java.util.concurrent.TimeUnit * @property context The application context used for scheduling app usage checks. */ class AppUsageNotificationsManager(private val context: Context) { - private val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager - private val notificationIntent = + private val alarmManager : AlarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager + private val notificationIntent : PendingIntent = Intent(context, AppUsageNotificationReceiver::class.java).let { intent -> PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) } @@ -30,7 +30,7 @@ class AppUsageNotificationsManager(private val context: Context) { * an instance of the AppUsageNotificationWorker to handle the app usage check. */ fun scheduleAppUsageCheck() { - val triggerTime = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(3) + val triggerTime : Long = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(3) alarmManager.setRepeating( AlarmManager.RTC_WAKEUP, triggerTime, TimeUnit.DAYS.toMillis(3), notificationIntent ) diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/receivers/AppUsageNotificationReceiver.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/receivers/AppUsageNotificationReceiver.kt index 70e993d..1a2da86 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/receivers/AppUsageNotificationReceiver.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/receivers/AppUsageNotificationReceiver.kt @@ -3,13 +3,14 @@ package com.d4rk.cartcalculator.notifications.receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import androidx.work.OneTimeWorkRequest import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager import com.d4rk.cartcalculator.notifications.workers.AppUsageNotificationWorker class AppUsageNotificationReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent?) { - val workRequest = OneTimeWorkRequestBuilder().build() + val workRequest : OneTimeWorkRequest = OneTimeWorkRequestBuilder().build() WorkManager.getInstance(context).enqueue(workRequest) } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/workers/AppUsageNotificationWorker.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/workers/AppUsageNotificationWorker.kt index aa38d97..0411649 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/workers/AppUsageNotificationWorker.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/notifications/workers/AppUsageNotificationWorker.kt @@ -26,9 +26,9 @@ import kotlinx.coroutines.runBlocking */ class AppUsageNotificationWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) { - private val dataStore = AppCoreManager.dataStore - private val appUsageChannelId = "app_usage_channel" - private val appUsageNotificationId = 0 + private val dataStore : DataStore = AppCoreManager.dataStore + private val appUsageChannelId : String = "app_usage_channel" + private val appUsageNotificationId : Int = 0 /** * Performs the background work for app usage notification checks. @@ -41,13 +41,13 @@ class AppUsageNotificationWorker(context: Context, workerParams: WorkerParameter */ @RequiresApi(Build.VERSION_CODES.O) override fun doWork(): Result { - val currentTimestamp = System.currentTimeMillis() - val notificationThreshold = 3 * 24 * 60 * 60 * 1000 - val lastUsedTimestamp = runBlocking { dataStore.lastUsed.first() } + val currentTimestamp : Long = System.currentTimeMillis() + val notificationThreshold : Int = 3 * 24 * 60 * 60 * 1000 + val lastUsedTimestamp : Long = runBlocking { dataStore.lastUsed.first() } if (currentTimestamp - lastUsedTimestamp > notificationThreshold) { - val notificationManager = + val notificationManager : NotificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - val appUsageChannel = NotificationChannel( + val appUsageChannel : NotificationChannel = NotificationChannel( appUsageChannelId, applicationContext.getString(R.string.app_usage_notifications), NotificationManager.IMPORTANCE_HIGH diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/ads/BannerAds.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/ads/BannerAds.kt index f1120ff..1599c4d 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/ads/BannerAds.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/ads/BannerAds.kt @@ -6,20 +6,20 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.viewinterop.AndroidView +import com.d4rk.cartcalculator.data.core.AppCoreManager import com.d4rk.cartcalculator.utils.constants.ads.AdsConstants -import com.d4rk.cartcalculator.data.datastore.DataStore import com.google.android.gms.ads.AdRequest import com.google.android.gms.ads.AdSize import com.google.android.gms.ads.AdView @Composable fun AdBanner( - modifier: Modifier = Modifier, dataStore: DataStore + modifier : Modifier = Modifier ) { - val showAds: Boolean by dataStore.ads.collectAsState(initial = true) + val showAds : Boolean by AppCoreManager.dataStore.ads.collectAsState(initial = true) if (showAds) { - AndroidView(modifier = modifier.fillMaxWidth(), factory = { context -> + AndroidView(modifier = modifier.fillMaxWidth() , factory = { context -> AdView(context).apply { setAdSize(AdSize.BANNER) adUnitId = AdsConstants.BANNER_AD_UNIT_ID @@ -29,14 +29,31 @@ 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, dataStore: DataStore + modifier : Modifier = Modifier ) { - val showAds: Boolean by dataStore.ads.collectAsState(initial = true) + val showAds : Boolean by AppCoreManager.dataStore.ads.collectAsState(initial = true) if (showAds) { - AndroidView(modifier = modifier.fillMaxWidth(), factory = { context -> + AndroidView(modifier = modifier.fillMaxWidth() , factory = { context -> AdView(context).apply { setAdSize(AdSize.LARGE_BANNER) adUnitId = AdsConstants.BANNER_AD_UNIT_ID diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/dialogs/SelectLanguageAlertDialog.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/dialogs/SelectLanguageAlertDialog.kt index 564a840..2a06d18 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/dialogs/SelectLanguageAlertDialog.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/dialogs/SelectLanguageAlertDialog.kt @@ -30,32 +30,33 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.d4rk.cartcalculator.R import com.d4rk.cartcalculator.data.datastore.DataStore +import com.d4rk.cartcalculator.ui.components.spacers.MediumVerticalSpacer import kotlinx.coroutines.flow.firstOrNull @Composable fun SelectLanguageAlertDialog( - dataStore: DataStore, onDismiss: () -> Unit, onLanguageSelected: (String) -> Unit + dataStore : DataStore , onDismiss : () -> Unit , onLanguageSelected : (String) -> Unit ) { - val selectedLanguage: MutableState = remember { mutableStateOf(value = "") } - val languageEntries: List = - stringArrayResource(R.array.preference_language_entries).toList() - val languageValues: List = - stringArrayResource(R.array.preference_language_values).toList() + val selectedLanguage : MutableState = remember { mutableStateOf(value = "") } + val languageEntries : List = + stringArrayResource(id = R.array.preference_language_entries).toList() + val languageValues : List = + stringArrayResource(id = R.array.preference_language_values).toList() - AlertDialog(onDismissRequest = onDismiss, text = { + AlertDialog(onDismissRequest = onDismiss , text = { SelectLanguageAlertDialogContent( - selectedLanguage, dataStore, languageEntries, languageValues + selectedLanguage , dataStore , languageEntries , languageValues ) - }, icon = { - Icon(Icons.Outlined.Language, contentDescription = null) - }, confirmButton = { + } , icon = { + Icon(Icons.Outlined.Language , contentDescription = null) + } , confirmButton = { TextButton(onClick = { onLanguageSelected(selectedLanguage.value) onDismiss() }) { Text(text = stringResource(id = android.R.string.ok)) } - }, dismissButton = { + } , dismissButton = { TextButton(onClick = onDismiss) { Text(text = stringResource(id = android.R.string.cancel)) } @@ -64,12 +65,12 @@ fun SelectLanguageAlertDialog( @Composable fun SelectLanguageAlertDialogContent( - selectedLanguage: MutableState, - dataStore: DataStore, - languageEntries: List, - languageValues: List + selectedLanguage : MutableState , + dataStore : DataStore , + languageEntries : List , + languageValues : List ) { - LaunchedEffect(Unit) { + LaunchedEffect(key1 = Unit) { selectedLanguage.value = dataStore.getLanguage().firstOrNull() ?: "" } @@ -77,36 +78,37 @@ fun SelectLanguageAlertDialogContent( Text(text = stringResource(id = R.string.dialog_language_subtitle)) Box( modifier = Modifier - .fillMaxWidth() - .weight(1f) + .fillMaxWidth() + .weight(weight = 1f) ) { LazyColumn { items(languageEntries.size) { index -> Row( - Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, + Modifier.fillMaxWidth() , + verticalAlignment = Alignment.CenterVertically , horizontalArrangement = Arrangement.Start ) { - RadioButton(selected = selectedLanguage.value == languageValues[index], + RadioButton( + selected = selectedLanguage.value == languageValues[index] , onClick = { selectedLanguage.value = languageValues[index] }) Text( - modifier = Modifier.padding(start = 8.dp), - text = languageEntries[index], + modifier = Modifier.padding(start = 8.dp) , + text = languageEntries[index] , style = MaterialTheme.typography.bodyMedium.merge() ) } } } } - Spacer(modifier = Modifier.height(24.dp)) - Icon(imageVector = Icons.Outlined.Info, contentDescription = null) - Spacer(modifier = Modifier.height(12.dp)) + Spacer(modifier = Modifier.height(height = 24.dp)) + Icon(imageVector = Icons.Outlined.Info , contentDescription = null) + MediumVerticalSpacer() Text(text = stringResource(id = R.string.dialog_info_language)) } - LaunchedEffect(selectedLanguage.value) { - dataStore.saveLanguage(selectedLanguage.value) + LaunchedEffect(key1 = selectedLanguage.value) { + dataStore.saveLanguage(language = selectedLanguage.value) } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/dialogs/VersionInfoAlertDialog.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/dialogs/VersionInfoAlertDialog.kt index f435db7..71bd3da 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/dialogs/VersionInfoAlertDialog.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/dialogs/VersionInfoAlertDialog.kt @@ -4,11 +4,8 @@ import android.content.Context import android.graphics.drawable.Drawable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width import androidx.compose.material3.AlertDialog import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -21,6 +18,8 @@ import coil.ImageLoader import coil.compose.AsyncImage import com.d4rk.cartcalculator.BuildConfig import com.d4rk.cartcalculator.R +import com.d4rk.cartcalculator.ui.components.spacers.LargeHorizontalSpacer +import com.d4rk.cartcalculator.ui.components.spacers.LargeVerticalSpacer @Composable fun VersionInfoAlertDialog(onDismiss : () -> Unit) { @@ -47,17 +46,17 @@ fun VersionInfoAlertDialogContent() { modifier = Modifier.size(48.dp) , imageLoader = imageLoader ) - Spacer(modifier = Modifier.width(16.dp)) + LargeHorizontalSpacer() Column { Text( - text = context.getString(R.string.app_full_name) , + text = context.getString(R.string.app_name) , style = MaterialTheme.typography.titleLarge ) Text( text = stringResource(id = R.string.version , BuildConfig.VERSION_NAME) , style = MaterialTheme.typography.bodyMedium ) - Spacer(modifier = Modifier.height(16.dp)) + LargeVerticalSpacer() Text( text = copyright , style = MaterialTheme.typography.bodyMedium ) diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/navigation/NavigationDrawer.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/navigation/NavigationDrawer.kt index bc37f4e..924a97f 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/navigation/NavigationDrawer.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/components/navigation/NavigationDrawer.kt @@ -1,16 +1,8 @@ package com.d4rk.cartcalculator.ui.components.navigation import android.content.Context -import android.view.SoundEffectConstants import android.view.View -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.EventNote -import androidx.compose.material.icons.automirrored.outlined.HelpOutline -import androidx.compose.material.icons.outlined.Settings -import androidx.compose.material.icons.outlined.Share import androidx.compose.material3.DrawerState import androidx.compose.material3.Icon import androidx.compose.material3.ModalDrawerSheet @@ -19,19 +11,21 @@ import androidx.compose.material3.NavigationDrawerItem import androidx.compose.material3.NavigationDrawerItemDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp import com.d4rk.cartcalculator.R import com.d4rk.cartcalculator.data.model.ui.navigation.NavigationDrawerItem +import com.d4rk.cartcalculator.data.model.ui.screens.UiMainScreen import com.d4rk.cartcalculator.ui.components.modifiers.bounceClick import com.d4rk.cartcalculator.ui.components.modifiers.hapticDrawerSwipe +import com.d4rk.cartcalculator.ui.components.spacers.LargeVerticalSpacer import com.d4rk.cartcalculator.ui.screens.help.HelpActivity import com.d4rk.cartcalculator.ui.screens.main.MainScreenContent +import com.d4rk.cartcalculator.ui.screens.main.MainViewModel +import com.d4rk.cartcalculator.ui.screens.settings.SettingsActivity import com.d4rk.cartcalculator.utils.helpers.IntentsHelper import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -40,78 +34,52 @@ import kotlinx.coroutines.launch fun NavigationDrawer( drawerState : DrawerState , view : View , - context : Context , + viewModel : MainViewModel , + context : Context ) { - val coroutineScope : CoroutineScope = rememberCoroutineScope() - val drawerItems : List = listOf( - NavigationDrawerItem( - title = R.string.settings , - selectedIcon = Icons.Outlined.Settings , - ) , - NavigationDrawerItem( - title = R.string.help_and_feedback , - selectedIcon = Icons.AutoMirrored.Outlined.HelpOutline , - ) , - NavigationDrawerItem( - title = R.string.updates , - selectedIcon = Icons.AutoMirrored.Outlined.EventNote , - ) , - NavigationDrawerItem( - title = R.string.share , selectedIcon = Icons.Outlined.Share - ) , - ) + val uiState : UiMainScreen by viewModel.uiState.collectAsState() + val drawerItems : List = uiState.navigationDrawerItems + val scope : CoroutineScope = rememberCoroutineScope() - val selectedItemIndex : Int by rememberSaveable { mutableIntStateOf(value = - 1) } - - ModalNavigationDrawer(modifier = Modifier.hapticDrawerSwipe(drawerState) , + ModalNavigationDrawer(modifier = Modifier.hapticDrawerSwipe(drawerState = drawerState) , drawerState = drawerState , drawerContent = { ModalDrawerSheet { - Spacer(modifier = Modifier.height(16.dp)) - drawerItems.forEachIndexed { index , item -> - val title : String = stringResource(id = item.title) + LargeVerticalSpacer() + drawerItems.forEach { item -> + val title = stringResource(id = item.title) NavigationDrawerItem(label = { Text(text = title) } , - selected = index == selectedItemIndex , + selected = false , onClick = { when (item.title) { R.string.settings -> { - view.playSoundEffect( - SoundEffectConstants.CLICK - ) IntentsHelper.openActivity( - context , - com.d4rk.cartcalculator.ui.screens.settings.SettingsActivity::class.java + context = context , + activityClass = SettingsActivity::class.java ) } R.string.help_and_feedback -> { - view.playSoundEffect( - SoundEffectConstants.CLICK - ) IntentsHelper.openActivity( - context , - HelpActivity::class.java + context = context , + activityClass = HelpActivity::class.java ) } R.string.updates -> { - view.playSoundEffect( - SoundEffectConstants.CLICK - ) IntentsHelper.openUrl( - context , + context = context , url = "https://github.com/D4rK7355608/${context.packageName}/blob/master/CHANGELOG.md" ) } R.string.share -> { - view.playSoundEffect( - SoundEffectConstants.CLICK + IntentsHelper.shareApp( + context = context ) - IntentsHelper.shareApp(context) } } - coroutineScope.launch { drawerState.close() } + scope.launch { drawerState.close() } } , icon = { Icon( @@ -119,9 +87,14 @@ fun NavigationDrawer( contentDescription = title ) } , + badge = { + if (item.badgeText.isNotBlank()) { + Text(text = item.badgeText) + } + } , modifier = Modifier .padding( - NavigationDrawerItemDefaults.ItemPadding + paddingValues = NavigationDrawerItemDefaults.ItemPadding ) .bounceClick()) } @@ -129,10 +102,10 @@ fun NavigationDrawer( } , content = { MainScreenContent( - view = view , drawerState = drawerState , context = context , - coroutineScope = coroutineScope + coroutineScope = scope , + view = view ) }) } \ No newline at end of file diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/CartActivity.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/CartActivity.kt index f895a6b..58e4b95 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/CartActivity.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/CartActivity.kt @@ -10,7 +10,6 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.ui.Modifier import com.d4rk.cartcalculator.data.core.AppCoreManager -import com.d4rk.cartcalculator.data.datastore.DataStore import com.d4rk.cartcalculator.ui.screens.settings.display.theme.style.AppTheme import com.google.android.gms.ads.MobileAds diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/CartScreen.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/CartScreen.kt index 08cdcfc..f19910d 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/CartScreen.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/CartScreen.kt @@ -59,22 +59,19 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.nestedscroll.nestedScroll -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.d4rk.cartcalculator.R -import com.d4rk.cartcalculator.data.core.AppCoreManager import com.d4rk.cartcalculator.data.database.table.ShoppingCartItemsTable -import com.d4rk.cartcalculator.data.datastore.DataStore import com.d4rk.cartcalculator.data.model.ui.screens.UiCartModel import com.d4rk.cartcalculator.ui.components.ads.AdBanner +import com.d4rk.cartcalculator.ui.components.dialogs.AddNewCartItemAlertDialog +import com.d4rk.cartcalculator.ui.components.dialogs.DeleteCartItemAlertDialog import com.d4rk.cartcalculator.ui.components.modifiers.animateVisibility import com.d4rk.cartcalculator.ui.components.modifiers.bounceClick import com.d4rk.cartcalculator.ui.components.modifiers.hapticSwipeToDismissBox -import com.d4rk.cartcalculator.ui.components.dialogs.AddNewCartItemAlertDialog -import com.d4rk.cartcalculator.ui.components.dialogs.DeleteCartItemAlertDialog import java.util.Locale @OptIn(ExperimentalMaterial3Api::class) @@ -85,14 +82,11 @@ fun CartScreen(activity : CartActivity , cartId : Int) { val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState()) val primaryColor = MaterialTheme.colorScheme.primary - val context = LocalContext.current val uiState : UiCartModel by viewModel.uiState.collectAsState() val isLoading : Boolean by viewModel.isLoading.collectAsState() val visibilityStates by viewModel.visibilityStates.collectAsState() - val dataStore = AppCoreManager.dataStore - Box(modifier = Modifier.fillMaxSize()) { Scaffold(modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection) , topBar = { @@ -131,7 +125,7 @@ fun CartScreen(activity : CartActivity , cartId : Int) { modifier = Modifier.align(Alignment.Center) ) AdBanner( - modifier = Modifier.align(Alignment.BottomCenter) , dataStore = dataStore + modifier = Modifier.align(Alignment.BottomCenter) ) } else { @@ -210,7 +204,7 @@ fun CartScreen(activity : CartActivity , cartId : Int) { } AdBanner( - modifier = Modifier.padding(all = 12.dp) , dataStore = dataStore + modifier = Modifier.padding(all = 12.dp) ) Card( diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/CartViewModel.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/CartViewModel.kt index 6535ad9..5037e5d 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/CartViewModel.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/CartViewModel.kt @@ -3,6 +3,7 @@ package com.d4rk.cartcalculator.ui.screens.cart import android.app.Application import androidx.lifecycle.viewModelScope import com.d4rk.cartcalculator.data.database.table.ShoppingCartItemsTable +import com.d4rk.cartcalculator.data.database.table.ShoppingCartTable import com.d4rk.cartcalculator.data.datastore.DataStore import com.d4rk.cartcalculator.data.model.ui.screens.UiCartModel import com.d4rk.cartcalculator.ui.screens.cart.repository.CartRepository @@ -16,15 +17,15 @@ import kotlinx.coroutines.launch class CartViewModel(application : Application) : BaseViewModel(application) { - private val repository = CartRepository() + private val repository : CartRepository = CartRepository() - private val _uiState = MutableStateFlow(UiCartModel()) + private val _uiState : MutableStateFlow = MutableStateFlow(UiCartModel()) val uiState : StateFlow = _uiState fun loadCart(cartId : Int) { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { showLoading() - val cart = repository.loadCartIdImplementation(cartId = cartId) + val cart : ShoppingCartTable = repository.loadCartIdImplementation(cartId = cartId) repository.loadCartItemsRepository(cartId = cartId) { items -> _uiState.update { currentState -> currentState.copy( @@ -41,10 +42,10 @@ class CartViewModel(application : Application) : BaseViewModel(application) { private fun initializeVisibilityStates() { viewModelScope.launch(coroutineExceptionHandler) { delay(timeMillis = 50L) - _visibilityStates.value = List(_uiState.value.cartItems.size) { false } + _visibilityStates.value = List(size = _uiState.value.cartItems.size) { false } _uiState.value.cartItems.indices.forEach { index -> delay(timeMillis = index * 8L) - _visibilityStates.value = List(_visibilityStates.value.size) { lessonIndex -> + _visibilityStates.value = List(size = _visibilityStates.value.size) { lessonIndex -> lessonIndex == index || _visibilityStates.value[lessonIndex] } } @@ -52,7 +53,7 @@ class CartViewModel(application : Application) : BaseViewModel(application) { } fun loadSelectedCurrency(dataStore : DataStore) { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { _uiState.update { currentState -> currentState.copy( selectedCurrency = dataStore.getCurrency().firstOrNull() ?: "" @@ -62,11 +63,11 @@ class CartViewModel(application : Application) : BaseViewModel(application) { } fun addCartItem(cartId : Int , cartItem : ShoppingCartItemsTable) { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { cartItem.cartId = cartId - repository.addCartItemRepository(cartItem) { newItem -> + repository.addCartItemRepository(cartItem = cartItem) { newItem -> _uiState.update { currentState -> - val cartItems = currentState.cartItems + newItem + val cartItems : List = currentState.cartItems + newItem currentState.copy(cartItems = cartItems) } calculateTotalPrice() @@ -76,16 +77,16 @@ class CartViewModel(application : Application) : BaseViewModel(application) { } fun increaseQuantity(cartItem : ShoppingCartItemsTable) { - viewModelScope.launch(coroutineExceptionHandler) { - val currentQuantity = getQuantityStateForItem(cartItem = cartItem) + viewModelScope.launch(context = coroutineExceptionHandler) { + val currentQuantity : Int = getQuantityStateForItem(cartItem = cartItem) updateItemQuantity(cartItem = cartItem , newQuantity = currentQuantity + 1) } } fun decreaseQuantity(cartItem : ShoppingCartItemsTable) { - viewModelScope.launch(coroutineExceptionHandler) { - val currentQuantity = getQuantityStateForItem(cartItem = cartItem) - val newQuantity = maxOf(a = currentQuantity - 1 , b = 0) + viewModelScope.launch(context = coroutineExceptionHandler) { + val currentQuantity : Int = getQuantityStateForItem(cartItem = cartItem) + val newQuantity : Int = maxOf(a = currentQuantity - 1 , b = 0) if (newQuantity > 0) { updateItemQuantity(cartItem = cartItem , newQuantity = newQuantity) } @@ -104,11 +105,11 @@ class CartViewModel(application : Application) : BaseViewModel(application) { } private fun updateItemQuantity(cartItem : ShoppingCartItemsTable , newQuantity : Int) { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { cartItem.quantity = newQuantity repository.updateCartItemRepository(cartItem = cartItem) { _uiState.update { currentState -> - val updatedQuantities = currentState.itemQuantities.toMutableMap() + val updatedQuantities : MutableMap = currentState.itemQuantities.toMutableMap() updatedQuantities[cartItem.itemId] = newQuantity return@update currentState.copy(itemQuantities = updatedQuantities) } @@ -119,9 +120,9 @@ class CartViewModel(application : Application) : BaseViewModel(application) { fun deleteCartItem(cartItem : ShoppingCartItemsTable) { viewModelScope.launch(coroutineExceptionHandler) { - repository.deleteCartItemRepository(cartItem) { + repository.deleteCartItemRepository(cartItem = cartItem) { _uiState.update { currentState -> - val updatedItems = currentState.cartItems.filter { it != cartItem } + val updatedItems : List = currentState.cartItems.filter { it != cartItem } return@update currentState.copy(cartItems = updatedItems) } calculateTotalPrice() @@ -130,26 +131,26 @@ class CartViewModel(application : Application) : BaseViewModel(application) { } fun onItemCheckedChange(cartItem : ShoppingCartItemsTable , isChecked : Boolean) { - viewModelScope.launch(coroutineExceptionHandler) { - val updatedCartItems = _uiState.value.cartItems.map { item -> + viewModelScope.launch(context = coroutineExceptionHandler) { + val updatedCartItems : List = _uiState.value.cartItems.map { item -> if (item.itemId == cartItem.itemId) item.copy(isChecked = isChecked) else item } _uiState.value = _uiState.value.copy(cartItems = updatedCartItems) - repository.updateCartItemRepository(cartItem.copy(isChecked = isChecked)) { } + repository.updateCartItemRepository(cartItem = cartItem.copy(isChecked = isChecked)) { } } } fun saveCartItems() { - viewModelScope.launch(coroutineExceptionHandler) { - val cartItems = uiState.value.cartItems + viewModelScope.launch(context = coroutineExceptionHandler) { + val cartItems : List = uiState.value.cartItems cartItems.forEach { cartItem -> - repository.saveCartItemsRepository(cartItem) { } + repository.saveCartItemsRepository(cartItem = cartItem) { } } } } private fun calculateTotalPrice() { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { val total = uiState.value.cartItems.sumOf { item -> item.price.toDouble() * item.quantity } _uiState.update { currentState -> @@ -159,7 +160,7 @@ class CartViewModel(application : Application) : BaseViewModel(application) { } fun toggleOpenDialog() { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { _uiState.update { currentState -> currentState.copy(openDialog = ! currentState.openDialog) } @@ -167,7 +168,7 @@ class CartViewModel(application : Application) : BaseViewModel(application) { } fun toggleDeleteDialog(cartItem : ShoppingCartItemsTable?) { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { _uiState.update { currentState -> currentState.copy( openDeleteDialog = cartItem != null , currentCartItemForDeletion = cartItem diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/repository/CartRepository.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/repository/CartRepository.kt index 1ad6b33..a241d85 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/repository/CartRepository.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/repository/CartRepository.kt @@ -8,7 +8,7 @@ class CartRepository : CartRepositoryImplementation() { suspend fun loadCartItemsRepository(cartId: Int , onSuccess: (List) -> Unit) { withContext(Dispatchers.IO) { - val items = fetchItemsForCartImplementation(cartId) + val items : List = fetchItemsForCartImplementation(cartId = cartId) withContext(Dispatchers.Main) { onSuccess(items) } @@ -20,7 +20,7 @@ class CartRepository : CartRepositoryImplementation() { onSuccess : (ShoppingCartItemsTable) -> Unit , ) { withContext(Dispatchers.IO) { - val newItemId = addCartItemImplementation(cartItem).toInt() + val newItemId : Int = addCartItemImplementation(cartItem = cartItem).toInt() cartItem.itemId = newItemId withContext(Dispatchers.Main) { onSuccess(cartItem) @@ -30,7 +30,7 @@ class CartRepository : CartRepositoryImplementation() { suspend fun updateCartItemRepository(cartItem : ShoppingCartItemsTable , onSuccess : () -> Unit) { withContext(Dispatchers.IO) { - modifyCartItemImplementation(cartItem) + modifyCartItemImplementation(cartItem = cartItem) withContext(Dispatchers.Main) { onSuccess() } @@ -39,7 +39,7 @@ class CartRepository : CartRepositoryImplementation() { suspend fun deleteCartItemRepository(cartItem : ShoppingCartItemsTable , onSuccess : () -> Unit) { withContext(Dispatchers.IO) { - removeCartItemImplementation(cartItem) + removeCartItemImplementation(cartItem = cartItem) withContext(Dispatchers.Main) { onSuccess() } @@ -48,7 +48,7 @@ class CartRepository : CartRepositoryImplementation() { suspend fun saveCartItemsRepository(cartItem: ShoppingCartItemsTable , onSuccess: () -> Unit) { withContext(Dispatchers.IO) { - saveCartItemsImplementation(cartItem) + saveCartItemsImplementation(cartItems = cartItem) withContext(Dispatchers.Main) { onSuccess() } diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/repository/CartRepositoryImplementation.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/repository/CartRepositoryImplementation.kt index 277079b..4292152 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/repository/CartRepositoryImplementation.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/cart/repository/CartRepositoryImplementation.kt @@ -7,26 +7,26 @@ import com.d4rk.cartcalculator.data.database.table.ShoppingCartTable abstract class CartRepositoryImplementation { suspend fun loadCartIdImplementation(cartId : Int) : ShoppingCartTable { - return AppCoreManager.database.newCartDao().getCartById(cartId) + return AppCoreManager.database.newCartDao().getCartById(cartId = cartId) } suspend fun fetchItemsForCartImplementation(cartId : Int) : List { - return AppCoreManager.database.shoppingCartItemsDao().getItemsByCartId(cartId) + return AppCoreManager.database.shoppingCartItemsDao().getItemsByCartId(cartId = cartId) } suspend fun addCartItemImplementation(cartItem : ShoppingCartItemsTable) : Long { - return AppCoreManager.database.shoppingCartItemsDao().insert(cartItem) + return AppCoreManager.database.shoppingCartItemsDao().insert(item = cartItem) } suspend fun modifyCartItemImplementation(cartItem : ShoppingCartItemsTable) { - AppCoreManager.database.shoppingCartItemsDao().update(cartItem) + AppCoreManager.database.shoppingCartItemsDao().update(item = cartItem) } suspend fun removeCartItemImplementation(cartItem : ShoppingCartItemsTable) { - AppCoreManager.database.shoppingCartItemsDao().delete(cartItem) + AppCoreManager.database.shoppingCartItemsDao().delete(item = cartItem) } suspend fun saveCartItemsImplementation(cartItems: ShoppingCartItemsTable) { - AppCoreManager.database.shoppingCartItemsDao().update(cartItems) + AppCoreManager.database.shoppingCartItemsDao().update(item = cartItems) } } diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/HomeScreen.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/HomeScreen.kt index a706df3..472fe7e 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/HomeScreen.kt @@ -24,6 +24,7 @@ import androidx.compose.material3.OutlinedCard import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult import androidx.compose.material3.SwipeToDismissBox +import androidx.compose.material3.SwipeToDismissBoxState import androidx.compose.material3.SwipeToDismissBoxValue import androidx.compose.material3.Text import androidx.compose.material3.rememberSwipeToDismissBoxState @@ -57,12 +58,12 @@ fun HomeScreen( ) { val uiState : UiHomeModel by viewModel.uiState.collectAsState() val isLoading : Boolean by viewModel.isLoading.collectAsState() - val visibilityStates by viewModel.visibilityStates.collectAsState() - val okStringResource = stringResource(id = android.R.string.ok) + val visibilityStates : List by viewModel.visibilityStates.collectAsState() + val okStringResource : String = stringResource(id = android.R.string.ok) - LaunchedEffect(uiState.showSnackbar) { + LaunchedEffect(key1 = uiState.showSnackbar) { if (uiState.showSnackbar) { - val result = snackbarHostState.showSnackbar( + val result : SnackbarResult = snackbarHostState.showSnackbar( message = uiState.snackbarMessage , actionLabel = okStringResource , ) @@ -80,7 +81,7 @@ fun HomeScreen( Box( modifier = Modifier .fillMaxSize() - .wrapContentSize(Alignment.Center) + .wrapContentSize(align = Alignment.Center) ) { Column( verticalArrangement = Arrangement.Center , @@ -98,28 +99,24 @@ fun HomeScreen( else { LazyColumn( modifier = Modifier - .weight(1f) + .weight(weight = 1f) .padding(bottom = uiState.fabAdHeight) ) { - itemsIndexed( - items = uiState.carts, - key = { _, cart -> cart.cartId } - ) { index, cart -> - val isVisible = visibilityStates.getOrElse(index) { false } - CartItemComposable( - cart = cart, - onDelete = { viewModel.openDeleteCartDialog(cart) }, - onCardClick = { - view.playSoundEffect(SoundEffectConstants.CLICK) - viewModel.openCart(cart) - }, - uiState = uiState, - modifier = Modifier - .animateItem() - .animateVisibility( - visible = isVisible, - index = index - ) + itemsIndexed(items = uiState.carts , + key = { _ , cart -> cart.cartId }) { index , cart -> + val isVisible : Boolean = visibilityStates.getOrElse(index) { false } + CartItemComposable(cart = cart , + onDelete = { viewModel.openDeleteCartDialog(cart) } , + onCardClick = { + view.playSoundEffect(SoundEffectConstants.CLICK) + viewModel.openCart(cart = cart) + } , + uiState = uiState , + modifier = Modifier + .animateItem() + .animateVisibility( + visible = isVisible , index = index + ) ) } } @@ -131,7 +128,7 @@ fun HomeScreen( if (uiState.showCreateCartDialog) { AddNewCartAlertDialog(onDismiss = { viewModel.dismissNewCartDialog() } , onCartCreated = { cart -> - viewModel.addCart(cart) + viewModel.addCart(cart = cart) }) } @@ -143,7 +140,7 @@ fun HomeScreen( } , onDeleteConfirmed = { with(viewModel) { - deleteCart(it) + deleteCart(cartToDelete = it) showSnackbar(context.getString(R.string.snackbar_cart_deleted_success)) } } , @@ -160,16 +157,17 @@ fun CartItemComposable( modifier : Modifier , ) { val dateFormat = SimpleDateFormat("dd-MM-yyyy" , Locale.getDefault()) - val dateString = dateFormat.format(cart.date) + val dateString : String = dateFormat.format(cart.date) - val dismissState = rememberSwipeToDismissBoxState(confirmValueChange = { - if (it == SwipeToDismissBoxValue.StartToEnd || it == SwipeToDismissBoxValue.EndToStart) { - ! uiState.showDeleteCartDialog - } - else { - true - } - }) + val dismissState : SwipeToDismissBoxState = + rememberSwipeToDismissBoxState(confirmValueChange = { + if (it == SwipeToDismissBoxValue.StartToEnd || it == SwipeToDismissBoxValue.EndToStart) { + ! uiState.showDeleteCartDialog + } + else { + true + } + }) LaunchedEffect(key1 = dismissState.targetValue , key2 = dismissState.currentValue) { when { @@ -183,22 +181,22 @@ fun CartItemComposable( } } - SwipeToDismissBox(modifier = modifier.hapticSwipeToDismissBox(dismissState) , + SwipeToDismissBox(modifier = modifier.hapticSwipeToDismissBox(swipeToDismissBoxState = dismissState) , state = dismissState , backgroundContent = {} , content = { - OutlinedCard(shape = RoundedCornerShape(12.dp) , + OutlinedCard(shape = RoundedCornerShape(size = 12.dp) , modifier = Modifier .fillMaxWidth() .padding(top = 8.dp) , onClick = { onCardClick() }) { - Box(modifier = Modifier.clip(MaterialTheme.shapes.medium)) { + Box(modifier = Modifier.clip(shape = MaterialTheme.shapes.medium)) { Column( modifier = Modifier .fillMaxWidth() - .padding(8.dp) + .padding(all = 8.dp) ) { Row( horizontalArrangement = Arrangement.SpaceBetween , @@ -207,11 +205,10 @@ fun CartItemComposable( Text( text = cart.name , style = MaterialTheme.typography.titleMedium , - modifier = Modifier.weight(1f) + modifier = Modifier.weight(weight = 1f) ) - IconButton( - modifier = Modifier.bounceClick() , - onClick = { onDelete(cart) }) { + IconButton(modifier = Modifier.bounceClick() , + onClick = { onDelete(cart) }) { Icon( imageVector = Icons.Outlined.DeleteForever , contentDescription = "Delete cart" , diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/HomeViewModel.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/HomeViewModel.kt index 7012414..70bccca 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/HomeViewModel.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/HomeViewModel.kt @@ -13,9 +13,9 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch class HomeViewModel(application : Application) : BaseViewModel(application) { - private val repository = HomeRepository(application = application) + private val repository : HomeRepository = HomeRepository(application = application) - private val _uiState = MutableStateFlow(UiHomeModel()) + private val _uiState : MutableStateFlow = MutableStateFlow(UiHomeModel()) val uiState : StateFlow = _uiState init { @@ -23,7 +23,7 @@ class HomeViewModel(application : Application) : BaseViewModel(application) { } private fun loadCarts() { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { showLoading() repository.loadCartsRepository { carts -> _uiState.update { currentState -> @@ -36,12 +36,12 @@ class HomeViewModel(application : Application) : BaseViewModel(application) { } private fun initializeVisibilityStates() { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { delay(timeMillis = 50L) - _visibilityStates.value = List(_uiState.value.carts.size) { false } + _visibilityStates.value = List(size = _uiState.value.carts.size) { false } _uiState.value.carts.indices.forEach { index -> delay(timeMillis = index * 8L) - _visibilityStates.value = List(_visibilityStates.value.size) { lessonIndex -> + _visibilityStates.value = List(size = _visibilityStates.value.size) { lessonIndex -> lessonIndex == index || _visibilityStates.value[lessonIndex] } } @@ -51,14 +51,14 @@ class HomeViewModel(application : Application) : BaseViewModel(application) { } fun openCart(cart : ShoppingCartTable) { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { repository.openCartRepository(cart = cart) {} } } fun addCart(cart : ShoppingCartTable) { - viewModelScope.launch(coroutineExceptionHandler) { - repository.addCartRepository(cart) { addedCart -> + viewModelScope.launch(context = coroutineExceptionHandler) { + repository.addCartRepository(cart = cart) { addedCart -> _uiState.update { currentState -> currentState.copy(carts = (currentState.carts + addedCart).toMutableList()) } @@ -71,7 +71,7 @@ class HomeViewModel(application : Application) : BaseViewModel(application) { viewModelScope.launch(coroutineExceptionHandler) { repository.deleteCartRepository(cart = cartToDelete) { _uiState.update { currentState -> - val newList = currentState.carts.toMutableList() + val newList : MutableList = currentState.carts.toMutableList() newList.remove(element = cartToDelete) return@update currentState.copy(carts = newList) } @@ -80,7 +80,7 @@ class HomeViewModel(application : Application) : BaseViewModel(application) { } fun openDeleteCartDialog(cart : ShoppingCartTable) { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { _uiState.update { currentState -> currentState.copy(showDeleteCartDialog = true , cartToDelete = cart) } @@ -88,7 +88,7 @@ class HomeViewModel(application : Application) : BaseViewModel(application) { } fun dismissDeleteCartDialog() { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { _uiState.update { currentState -> currentState.copy(showDeleteCartDialog = false) } @@ -96,7 +96,7 @@ class HomeViewModel(application : Application) : BaseViewModel(application) { } fun openNewCartDialog() { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { _uiState.update { currentState -> currentState.copy(showCreateCartDialog = true) } @@ -104,7 +104,7 @@ class HomeViewModel(application : Application) : BaseViewModel(application) { } fun dismissNewCartDialog() { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { _uiState.update { currentState -> currentState.copy(showCreateCartDialog = false) } @@ -112,7 +112,7 @@ class HomeViewModel(application : Application) : BaseViewModel(application) { } fun dismissSnackbar() { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { _uiState.update { currentState -> currentState.copy(showSnackbar = false) } @@ -120,7 +120,7 @@ class HomeViewModel(application : Application) : BaseViewModel(application) { } fun showSnackbar(message : String) { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { _uiState.update { currentState -> currentState.copy(showSnackbar = true , snackbarMessage = message) } diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/repository/HomeRepository.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/repository/HomeRepository.kt index 1752a33..900a70c 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/repository/HomeRepository.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/repository/HomeRepository.kt @@ -10,7 +10,7 @@ class HomeRepository(application : Application) : suspend fun loadCartsRepository(onSuccess : (List) -> Unit) { withContext(Dispatchers.IO) { - val carts = loadCartsImplementation() + val carts : List = loadCartsImplementation() withContext(Dispatchers.Main) { onSuccess(carts) } @@ -28,7 +28,7 @@ class HomeRepository(application : Application) : suspend fun addCartRepository(cart : ShoppingCartTable , onSuccess : (ShoppingCartTable) -> Unit) { withContext(Dispatchers.IO) { - val addedCart = addCartImplementation(cart = cart) + val addedCart : ShoppingCartTable = addCartImplementation(cart = cart) withContext(Dispatchers.Main) { onSuccess(addedCart) } diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/repository/HomeRepositoryImplementation.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/repository/HomeRepositoryImplementation.kt index 33413f2..9813c56 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/repository/HomeRepositoryImplementation.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/home/repository/HomeRepositoryImplementation.kt @@ -24,7 +24,7 @@ abstract class HomeRepositoryImplementation(val application : Application) { } suspend fun deleteCartImplementation(cart : ShoppingCartTable) { - with(AppCoreManager.database) { + with(receiver = AppCoreManager.database) { newCartDao().delete(cart = cart) shoppingCartItemsDao().deleteItemsFromCart(cartId = cart.cartId) } diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/MainActivity.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/MainActivity.kt index 591412c..b038914 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/MainActivity.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/MainActivity.kt @@ -15,7 +15,6 @@ import androidx.compose.ui.Modifier import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import com.d4rk.cartcalculator.R import com.d4rk.cartcalculator.data.core.AppCoreManager -import com.d4rk.cartcalculator.data.datastore.DataStore import com.d4rk.cartcalculator.notifications.managers.AppUpdateNotificationsManager import com.d4rk.cartcalculator.ui.screens.settings.display.theme.style.AppTheme import com.google.android.gms.ads.MobileAds @@ -26,7 +25,6 @@ import com.google.android.play.core.appupdate.AppUpdateManagerFactory import com.google.android.play.core.install.model.ActivityResult class MainActivity : AppCompatActivity() { - private lateinit var dataStore : DataStore private val viewModel : MainViewModel by viewModels() private lateinit var appUpdateManager : AppUpdateManager private lateinit var appUpdateNotificationsManager : AppUpdateNotificationsManager @@ -45,7 +43,7 @@ class MainActivity : AppCompatActivity() { Surface( modifier = Modifier.fillMaxSize() , color = MaterialTheme.colorScheme.background ) { - MainScreen() + MainScreen(viewModel = viewModel) } } } @@ -54,11 +52,11 @@ class MainActivity : AppCompatActivity() { @RequiresApi(Build.VERSION_CODES.O) override fun onResume() { super.onResume() - with(viewModel) { + with(receiver = viewModel) { checkAndHandleStartup() configureSettings() checkForUpdates(activity = this@MainActivity , appUpdateManager = appUpdateManager) - checkAndScheduleUpdateNotifications(appUpdateNotificationsManager) + checkAndScheduleUpdateNotifications(appUpdateNotificationsManager = appUpdateNotificationsManager) checkAppUsageNotifications() } } @@ -99,7 +97,6 @@ class MainActivity : AppCompatActivity() { @Deprecated("Deprecated in Java") override fun onActivityResult(requestCode : Int , resultCode : Int , data : Intent?) { super.onActivityResult(requestCode , resultCode , data) - println("Cleaner for Android -> Play Update: onActivityResult: requestCode=$requestCode, resultCode=$resultCode") if (requestCode == 1) { when (resultCode) { RESULT_OK -> { @@ -115,9 +112,8 @@ class MainActivity : AppCompatActivity() { private fun initializeActivityComponents() { MobileAds.initialize(this@MainActivity) - dataStore = AppCoreManager.dataStore appUpdateManager = AppUpdateManagerFactory.create(this@MainActivity) - appUpdateNotificationsManager = AppUpdateNotificationsManager(this) + appUpdateNotificationsManager = AppUpdateNotificationsManager(context = this) } private fun showUpdateSuccessfulSnackbar() { diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/MainScreen.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/MainScreen.kt index 33cba34..8fb6b5d 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/MainScreen.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/MainScreen.kt @@ -29,10 +29,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.d4rk.cartcalculator.R -import com.d4rk.cartcalculator.data.core.AppCoreManager -import com.d4rk.cartcalculator.data.datastore.DataStore -import com.d4rk.cartcalculator.ui.components.buttons.AnimatedExtendedFloatingActionButton import com.d4rk.cartcalculator.ui.components.ads.AdBanner +import com.d4rk.cartcalculator.ui.components.buttons.AnimatedExtendedFloatingActionButton import com.d4rk.cartcalculator.ui.components.navigation.NavigationDrawer import com.d4rk.cartcalculator.ui.components.navigation.TopAppBarMain import com.d4rk.cartcalculator.ui.screens.home.HomeScreen @@ -40,7 +38,7 @@ import com.d4rk.cartcalculator.ui.screens.home.HomeViewModel import kotlinx.coroutines.CoroutineScope @Composable -fun MainScreen() { +fun MainScreen(viewModel : MainViewModel) { val drawerState : DrawerState = rememberDrawerState(initialValue = DrawerValue.Closed) val context : Context = LocalContext.current val view : View = LocalView.current @@ -49,6 +47,7 @@ fun MainScreen() { drawerState = drawerState , view = view , context = context , + viewModel = viewModel ) } @@ -57,8 +56,8 @@ fun MainScreenContent( view : View , drawerState : DrawerState , context : Context , coroutineScope : CoroutineScope ) { val viewModel : HomeViewModel = viewModel() - val snackbarHostState = remember { SnackbarHostState() } - val isFabVisible by viewModel.isFabVisible.collectAsState() + val snackbarHostState : SnackbarHostState = remember { SnackbarHostState() } + val isFabVisible : Boolean by viewModel.isFabVisible.collectAsState() Scaffold(topBar = { TopAppBarMain( @@ -79,16 +78,15 @@ fun MainScreenContent( } , snackbarHost = { SnackbarHost(hostState = snackbarHostState) } , bottomBar = { - val dataStore = AppCoreManager.dataStore AdBanner( - dataStore = dataStore , modifier = Modifier.padding( + modifier = Modifier.padding( bottom = (WindowInsets.navigationBars.asPaddingValues() .calculateBottomPadding() + 8.dp) ) ) }) { paddingValues -> Box( - modifier = Modifier.padding(paddingValues) + modifier = Modifier.padding(paddingValues = paddingValues) ) { HomeScreen( context = context , diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/MainViewModel.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/MainViewModel.kt index debf546..281e696 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/MainViewModel.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/MainViewModel.kt @@ -4,53 +4,90 @@ import android.app.Activity import android.app.Application import android.os.Build import androidx.annotation.RequiresApi +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.outlined.EventNote +import androidx.compose.material.icons.automirrored.outlined.HelpOutline +import androidx.compose.material.icons.outlined.Settings +import androidx.compose.material.icons.outlined.Share import androidx.lifecycle.viewModelScope -import com.d4rk.cartcalculator.data.datastore.DataStore +import com.d4rk.cartcalculator.R +import com.d4rk.cartcalculator.data.core.AppCoreManager +import com.d4rk.cartcalculator.data.model.ui.navigation.NavigationDrawerItem +import com.d4rk.cartcalculator.data.model.ui.screens.UiMainScreen import com.d4rk.cartcalculator.notifications.managers.AppUpdateNotificationsManager import com.d4rk.cartcalculator.ui.screens.main.repository.MainRepository import com.d4rk.cartcalculator.ui.screens.startup.StartupActivity import com.d4rk.cartcalculator.ui.viewmodel.BaseViewModel import com.d4rk.cartcalculator.utils.helpers.IntentsHelper import com.google.android.play.core.appupdate.AppUpdateManager +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch class MainViewModel(application : Application) : BaseViewModel(application) { - private val repository = MainRepository(DataStore(application) , application) + private val repository = MainRepository( + dataStore = AppCoreManager.dataStore , + application = application + ) + private val _uiState : MutableStateFlow = MutableStateFlow(initializeUiState()) + val uiState : StateFlow = _uiState fun checkForUpdates(activity : Activity , appUpdateManager : AppUpdateManager) { - viewModelScope.launch(coroutineExceptionHandler) { + viewModelScope.launch(context = coroutineExceptionHandler) { repository.checkForUpdates( appUpdateManager = appUpdateManager , activity = activity ) } } + private fun initializeUiState() : UiMainScreen { + return UiMainScreen( + navigationDrawerItems = listOf( + NavigationDrawerItem( + title = R.string.settings , + selectedIcon = Icons.Outlined.Settings , + ) , NavigationDrawerItem( + title = R.string.help_and_feedback , + selectedIcon = Icons.AutoMirrored.Outlined.HelpOutline , + ) , NavigationDrawerItem( + title = R.string.updates , + selectedIcon = Icons.AutoMirrored.Outlined.EventNote , + ) , NavigationDrawerItem( + title = R.string.share , + selectedIcon = Icons.Outlined.Share , + ) + ) + ) + } + @RequiresApi(Build.VERSION_CODES.O) fun checkAndScheduleUpdateNotifications(appUpdateNotificationsManager : AppUpdateNotificationsManager) { - viewModelScope.launch(coroutineExceptionHandler) { - repository.checkAndScheduleUpdateNotifications(appUpdateNotificationsManager) + viewModelScope.launch(context = coroutineExceptionHandler) { + repository.checkAndScheduleUpdateNotificationsRepository(appUpdateNotificationsManager = appUpdateNotificationsManager) } } fun checkAppUsageNotifications() { - viewModelScope.launch(coroutineExceptionHandler) { - repository.checkAppUsageNotifications() + viewModelScope.launch(context = coroutineExceptionHandler) { + repository.checkAppUsageNotificationsRepository() } } fun checkAndHandleStartup() { - viewModelScope.launch(coroutineExceptionHandler) { - repository.checkAndHandleStartup { isFirstTime -> + viewModelScope.launch(context = coroutineExceptionHandler) { + repository.checkAndHandleStartupRepository { isFirstTime -> if (isFirstTime) { - IntentsHelper.openActivity(getApplication() , StartupActivity::class.java) + IntentsHelper.openActivity( + context = getApplication() , activityClass = StartupActivity::class.java + ) } } } } fun configureSettings() { - viewModelScope.launch(coroutineExceptionHandler) { - repository.setupSettings() + viewModelScope.launch(context = coroutineExceptionHandler) { + repository.setupSettingsRepository() } } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/repository/MainRepository.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/repository/MainRepository.kt index 1745ee8..048b5e9 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/repository/MainRepository.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/repository/MainRepository.kt @@ -17,15 +17,15 @@ import kotlinx.coroutines.withContext * @property dataStore The data store used to persist settings and startup information. * @property application The application context. */ -class MainRepository(val dataStore : DataStore , application : Application) : - MainRepositoryImplementation(application) { +class MainRepository(dataStore : DataStore , application : Application) : + MainRepositoryImplementation(application = application , dataStore = dataStore) { suspend fun checkForUpdates( activity : Activity , appUpdateManager : AppUpdateManager , ) { withContext(Dispatchers.IO) { - checkForUpdatesLogic(activity , appUpdateManager) + checkForUpdatesImplementation(activity = activity , appUpdateManager = appUpdateManager) } } @@ -37,9 +37,9 @@ class MainRepository(val dataStore : DataStore , application : Application) : * * @param onSuccess A callback function that receives a boolean indicating if it's the first launch. */ - suspend fun checkAndHandleStartup(onSuccess : (Boolean) -> Unit) { + suspend fun checkAndHandleStartupRepository(onSuccess : (Boolean) -> Unit) { withContext(Dispatchers.IO) { - val isFirstTime : Boolean = checkStartup() + val isFirstTime : Boolean = checkStartupImplementation() withContext(Dispatchers.Main) { onSuccess(isFirstTime) } @@ -47,15 +47,15 @@ class MainRepository(val dataStore : DataStore , application : Application) : } @RequiresApi(Build.VERSION_CODES.O) - suspend fun checkAndScheduleUpdateNotifications(appUpdateNotificationsManager : AppUpdateNotificationsManager) { + suspend fun checkAndScheduleUpdateNotificationsRepository(appUpdateNotificationsManager : AppUpdateNotificationsManager) { withContext(Dispatchers.IO) { - checkAndScheduleUpdateNotificationsLogic(appUpdateNotificationsManager) + checkAndScheduleUpdateNotificationsImplementation(appUpdateNotificationsManager = appUpdateNotificationsManager) } } - suspend fun checkAppUsageNotifications() { + suspend fun checkAppUsageNotificationsRepository() { withContext(Dispatchers.IO) { - checkAppUsageNotificationsManager() + checkAppUsageNotificationsManagerImplementation() } } @@ -65,11 +65,11 @@ class MainRepository(val dataStore : DataStore , application : Application) : * This function retrieves the "usageAndDiagnostics" setting from the data store and configures * Firebase Analytics and Crashlytics accordingly. */ - suspend fun setupSettings() { + suspend fun setupSettingsRepository() { withContext(Dispatchers.IO) { val isEnabled : Boolean = dataStore.usageAndDiagnostics.first() withContext(Dispatchers.Main) { - setupDiagnosticSettings(isEnabled) + setupDiagnosticSettingsImplementation(isEnabled = isEnabled) } } } diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/repository/MainRepositoryImplementation.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/repository/MainRepositoryImplementation.kt index 88e1f36..14148dd 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/repository/MainRepositoryImplementation.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/main/repository/MainRepositoryImplementation.kt @@ -7,6 +7,7 @@ import androidx.annotation.RequiresApi import com.d4rk.cartcalculator.data.datastore.DataStore import com.d4rk.cartcalculator.notifications.managers.AppUpdateNotificationsManager import com.d4rk.cartcalculator.notifications.managers.AppUsageNotificationsManager +import com.google.android.play.core.appupdate.AppUpdateInfo import com.google.android.play.core.appupdate.AppUpdateManager import com.google.android.play.core.install.model.ActivityResult import com.google.android.play.core.install.model.AppUpdateType @@ -15,7 +16,6 @@ import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.crashlytics.FirebaseCrashlytics import kotlinx.coroutines.flow.first import kotlinx.coroutines.tasks.await -import com.d4rk.cartcalculator.data.datastore.DataStore.Companion as DataStore1 /** * Abstract base class for repository implementations related to main application functionality. @@ -24,7 +24,7 @@ import com.d4rk.cartcalculator.data.datastore.DataStore.Companion as DataStore1 * * @property application The application context. */ -abstract class MainRepositoryImplementation(val application : Application) { +abstract class MainRepositoryImplementation(val application : Application, val dataStore : DataStore) { /** * Checks if the application is being launched for the first time. @@ -33,8 +33,7 @@ abstract class MainRepositoryImplementation(val application : Application) { * * @return `true` if it's the first launch, `false` otherwise. */ - suspend fun checkStartup() : Boolean { - val dataStore : DataStore = DataStore1.getInstance(application) + suspend fun checkStartupImplementation() : Boolean { val isFirstTime : Boolean = dataStore.startup.first() if (isFirstTime) { dataStore.saveStartup(isFirstTime = false) @@ -50,44 +49,46 @@ abstract class MainRepositoryImplementation(val application : Application) { * * @param isEnabled `true` to enable data collection, `false` to disable. */ - fun setupDiagnosticSettings(isEnabled : Boolean) { + fun setupDiagnosticSettingsImplementation(isEnabled : Boolean) { FirebaseAnalytics.getInstance(application).setAnalyticsCollectionEnabled(isEnabled) FirebaseCrashlytics.getInstance().isCrashlyticsCollectionEnabled = isEnabled } - suspend fun checkForUpdatesLogic(activity : Activity, appUpdateManager : AppUpdateManager) : Int { + suspend fun checkForUpdatesImplementation( + activity: Activity, + appUpdateManager: AppUpdateManager + ): Int { + return runCatching { + var updateResult: Int = Activity.RESULT_CANCELED + val appUpdateInfo: AppUpdateInfo = appUpdateManager.appUpdateInfo.await() - try { - var updateResult = Activity.RESULT_CANCELED - val appUpdateInfo = appUpdateManager.appUpdateInfo.await() - - if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.isUpdateTypeAllowed( - AppUpdateType.IMMEDIATE - ) && appUpdateInfo.updateAvailability() != UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS + if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && + appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE) && + appUpdateInfo.updateAvailability() != UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS ) { appUpdateInfo.clientVersionStalenessDays()?.let { stalenessDays -> val updateType = if (stalenessDays > 90) AppUpdateType.IMMEDIATE else AppUpdateType.FLEXIBLE - @Suppress("DEPRECATION") appUpdateManager.startUpdateFlowForResult( - appUpdateInfo , updateType , activity , 1 + @Suppress("DEPRECATION") + appUpdateManager.startUpdateFlowForResult( + appUpdateInfo, updateType, activity, 1 ) updateResult = Activity.RESULT_OK } } - return updateResult - - } catch (e : Exception) { - return ActivityResult.RESULT_IN_APP_UPDATE_FAILED + updateResult + }.getOrElse { + ActivityResult.RESULT_IN_APP_UPDATE_FAILED } } @RequiresApi(Build.VERSION_CODES.O) - fun checkAndScheduleUpdateNotificationsLogic(appUpdateNotificationsManager : AppUpdateNotificationsManager) { + fun checkAndScheduleUpdateNotificationsImplementation(appUpdateNotificationsManager : AppUpdateNotificationsManager) { appUpdateNotificationsManager.checkAndSendUpdateNotification() } - fun checkAppUsageNotificationsManager() { - val appUsageNotificationsManager = AppUsageNotificationsManager(application) + fun checkAppUsageNotificationsManagerImplementation() { + val appUsageNotificationsManager = AppUsageNotificationsManager(context = application) appUsageNotificationsManager.scheduleAppUsageCheck() } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/settings/cart/CartSettingsComposable.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/settings/cart/CartSettingsComposable.kt index 00ba90e..15824c9 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/settings/cart/CartSettingsComposable.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/settings/cart/CartSettingsComposable.kt @@ -12,11 +12,10 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import com.d4rk.cartcalculator.R import com.d4rk.cartcalculator.data.core.AppCoreManager -import com.d4rk.cartcalculator.data.datastore.DataStore -import com.d4rk.cartcalculator.ui.components.preferences.PreferenceCategoryItem -import com.d4rk.cartcalculator.ui.components.preferences.PreferenceItem import com.d4rk.cartcalculator.ui.components.dialogs.SelectCurrencyAlertDialog import com.d4rk.cartcalculator.ui.components.navigation.TopAppBarScaffoldWithBackButton +import com.d4rk.cartcalculator.ui.components.preferences.PreferenceCategoryItem +import com.d4rk.cartcalculator.ui.components.preferences.PreferenceItem @Composable fun CartSettingsComposable(activity : CartSettingsActivity) { diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/settings/display/theme/ThemeSettingsComposable.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/settings/display/theme/ThemeSettingsComposable.kt index 3ec4226..0472ddc 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/settings/display/theme/ThemeSettingsComposable.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/settings/display/theme/ThemeSettingsComposable.kt @@ -1,6 +1,5 @@ package com.d4rk.cartcalculator.ui.screens.settings.display.theme -import android.content.Context import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -22,15 +21,14 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.d4rk.cartcalculator.R import com.d4rk.cartcalculator.data.core.AppCoreManager import com.d4rk.cartcalculator.data.datastore.DataStore -import com.d4rk.cartcalculator.ui.components.preferences.SwitchCardComposable import com.d4rk.cartcalculator.ui.components.modifiers.bounceClick import com.d4rk.cartcalculator.ui.components.navigation.TopAppBarScaffoldWithBackButton +import com.d4rk.cartcalculator.ui.components.preferences.SwitchCardComposable import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/support/SupportScreen.kt b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/support/SupportScreen.kt index 1af31ab..bfab4f8 100644 --- a/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/support/SupportScreen.kt +++ b/app/src/main/kotlin/com/d4rk/cartcalculator/ui/screens/support/SupportScreen.kt @@ -35,18 +35,15 @@ import com.android.billingclient.api.BillingClient import com.android.billingclient.api.BillingClientStateListener import com.android.billingclient.api.BillingResult import com.d4rk.cartcalculator.R -import com.d4rk.cartcalculator.data.core.AppCoreManager import com.d4rk.cartcalculator.ui.components.ads.LargeBannerAdsComposable -import com.d4rk.cartcalculator.data.datastore.DataStore -import com.d4rk.cartcalculator.utils.helpers.IntentsHelper import com.d4rk.cartcalculator.ui.components.modifiers.bounceClick import com.d4rk.cartcalculator.ui.components.navigation.TopAppBarScaffoldWithBackButton +import com.d4rk.cartcalculator.utils.helpers.IntentsHelper @Composable fun SupportComposable(viewModel: SupportViewModel , activity: SupportActivity) { val context: Context = LocalContext.current val view: View = LocalView.current - val dataStore: DataStore = AppCoreManager.dataStore val billingClient: BillingClient = rememberBillingClient(context, viewModel) TopAppBarScaffoldWithBackButton( title = stringResource(id = R.string.support_us), @@ -227,7 +224,7 @@ fun SupportComposable(viewModel: SupportViewModel , activity: SupportActivity) { } item { LargeBannerAdsComposable( - modifier = Modifier.padding(bottom = 12.dp), dataStore = dataStore + modifier = Modifier.padding(bottom = 12.dp) ) } } diff --git a/app/src/test/kotlin/com/d4rk/cartcalculator/ExampleUnitTest.kt b/app/src/test/kotlin/com/d4rk/cartcalculator/ExampleUnitTest.kt deleted file mode 100644 index 4bfcc05..0000000 --- a/app/src/test/kotlin/com/d4rk/cartcalculator/ExampleUnitTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.d4rk.cartcalculator - -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file