diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 536aed0c..d7512aae 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -11,8 +11,8 @@
android:supportsRtl="true"
android:theme="@style/Theme.Unitto">
+ android:name="firebase_analytics_collection_enabled"
+ android:value="false" />
diff --git a/app/src/main/java/com/sadellie/unitto/data/preferences/UserPreferences.kt b/app/src/main/java/com/sadellie/unitto/data/preferences/UserPreferences.kt
index ad4145cf..f6c78067 100644
--- a/app/src/main/java/com/sadellie/unitto/data/preferences/UserPreferences.kt
+++ b/app/src/main/java/com/sadellie/unitto/data/preferences/UserPreferences.kt
@@ -1,10 +1,7 @@
package com.sadellie.unitto.data.preferences
import android.content.Context
-import androidx.datastore.preferences.core.Preferences
-import androidx.datastore.preferences.core.edit
-import androidx.datastore.preferences.core.intPreferencesKey
-import androidx.datastore.preferences.core.stringPreferencesKey
+import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.preferencesDataStore
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.Flow
@@ -26,6 +23,7 @@ object UserPreferenceKeys {
val OUTPUT_FORMAT = intPreferencesKey("OUTPUT_FORMAT_PREF_KEY")
val LATEST_LEFT_SIDE = stringPreferencesKey("LATEST_LEFT_SIDE_PREF_KEY")
val LATEST_RIGHT_SIDE = stringPreferencesKey("LATEST_RIGHT_SIDE_PREF_KEY")
+ val ENABLE_ANALYTICS = booleanPreferencesKey("ENABLE_ANALYTICS_PREF_KEY")
}
/**
@@ -56,10 +54,21 @@ class UserPreferences @Inject constructor(@ApplicationContext private val contex
}
}
+ /**
+ * Gets boolean from datastore
+ *
+ * @param[default] Value to return if didn't find anything on fresh install
+ */
+ fun getItem(key: Preferences.Key, default: Boolean): Flow {
+ return context.settingsDataStore.data.map {
+ it[key] ?: default
+ }
+ }
+
/**
* Saves string value by key
*/
- suspend fun saveString(key: Preferences.Key, value: String) {
+ suspend fun saveItem(key: Preferences.Key, value: String) {
context.settingsDataStore.edit {
it[key] = value
}
@@ -68,7 +77,16 @@ class UserPreferences @Inject constructor(@ApplicationContext private val contex
/**
* Saves int value by key
*/
- suspend fun saveInt(key: Preferences.Key, value: Int) {
+ suspend fun saveItem(key: Preferences.Key, value: Int) {
+ context.settingsDataStore.edit {
+ it[key] = value
+ }
+ }
+
+ /**
+ * Saves boolean value by key
+ */
+ suspend fun saveItem(key: Preferences.Key, value: Boolean) {
context.settingsDataStore.edit {
it[key] = value
}
diff --git a/app/src/main/java/com/sadellie/unitto/screens/MainViewModel.kt b/app/src/main/java/com/sadellie/unitto/screens/MainViewModel.kt
index 9b3e886a..07f0c935 100644
--- a/app/src/main/java/com/sadellie/unitto/screens/MainViewModel.kt
+++ b/app/src/main/java/com/sadellie/unitto/screens/MainViewModel.kt
@@ -7,6 +7,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.sadellie.unitto.data.KEY_0
import com.sadellie.unitto.data.KEY_DOT
@@ -45,7 +46,7 @@ class MainViewModel @Inject constructor(
fun saveCurrentAppTheme(value: Int) {
viewModelScope.launch {
- mySettingsPrefs.saveInt(key = UserPreferenceKeys.CURRENT_APP_THEME, value)
+ mySettingsPrefs.saveItem(key = UserPreferenceKeys.CURRENT_APP_THEME, value)
}
}
@@ -58,7 +59,7 @@ class MainViewModel @Inject constructor(
fun setPrecisionPref(value: Int) {
viewModelScope.launch {
precision = value
- mySettingsPrefs.saveInt(UserPreferenceKeys.DIGITS_PRECISION, value)
+ mySettingsPrefs.saveItem(UserPreferenceKeys.DIGITS_PRECISION, value)
convertValue()
}
}
@@ -73,7 +74,7 @@ class MainViewModel @Inject constructor(
separator = value
viewModelScope.launch {
Formatter.setSeparator(value)
- mySettingsPrefs.saveInt(UserPreferenceKeys.SEPARATOR, value)
+ mySettingsPrefs.saveItem(UserPreferenceKeys.SEPARATOR, value)
convertValue()
}
}
@@ -93,11 +94,24 @@ class MainViewModel @Inject constructor(
outputFormat = value
// Updating value on disk
viewModelScope.launch {
- mySettingsPrefs.saveInt(UserPreferenceKeys.OUTPUT_FORMAT, value)
+ mySettingsPrefs.saveItem(UserPreferenceKeys.OUTPUT_FORMAT, value)
convertValue()
}
}
+ /**
+ * ANALYTICS
+ */
+ var enableAnalytics: Boolean by mutableStateOf(false)
+
+ fun setAnalyticsPref(value: Boolean) {
+ enableAnalytics = value
+ viewModelScope.launch {
+ mySettingsPrefs.saveItem(UserPreferenceKeys.ENABLE_ANALYTICS, value)
+ FirebaseAnalytics.getInstance(application).setAnalyticsCollectionEnabled(enableAnalytics)
+ }
+ }
+
/**
* Unit we converting from (left side)
*/
@@ -400,8 +414,8 @@ class MainViewModel @Inject constructor(
*/
fun saveMe() {
viewModelScope.launch {
- mySettingsPrefs.saveString(UserPreferenceKeys.LATEST_LEFT_SIDE, unitFrom.unitId)
- mySettingsPrefs.saveString(UserPreferenceKeys.LATEST_RIGHT_SIDE, unitTo.unitId)
+ mySettingsPrefs.saveItem(UserPreferenceKeys.LATEST_LEFT_SIDE, unitFrom.unitId)
+ mySettingsPrefs.saveItem(UserPreferenceKeys.LATEST_RIGHT_SIDE, unitTo.unitId)
}
}
@@ -532,6 +546,9 @@ class MainViewModel @Inject constructor(
* He can choose another unit group and doesn't need to wait for network to appear.
* */
updateCurrenciesBasicUnits()
+
+ enableAnalytics = mySettingsPrefs.getItem(UserPreferenceKeys.ENABLE_ANALYTICS, true).first()
+ FirebaseAnalytics.getInstance(application).setAnalyticsCollectionEnabled(enableAnalytics)
}
}
}
diff --git a/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsListItem.kt b/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsListItem.kt
index 339e7f9f..3ed473b5 100644
--- a/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsListItem.kt
+++ b/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsListItem.kt
@@ -2,12 +2,10 @@ package com.sadellie.unitto.screens.setttings
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.*
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@@ -17,22 +15,24 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
/**
- * Represents one item in list on Settings screen
+ * Basic list item for settings screen. By default only has label and support text, clickable.
+ * This component can be easily modified if you provide additional component to it,
+ * for example a switch or a checkbox
*
- * @param modifier Modifier that is applied to a [Row]
- * @param onClick Action to perform when clicking this item
- * @param label Big text that is above support text
- * @param supportText Smaller text that is below label
+ * @param label Main text
+ * @param supportText Text that is located below label
+ * @param onClick Action to perform when user clicks on this component (whole component is clickable)
+ * @param content Additional composable: buttons, switches, checkboxes or something else
*/
@Composable
-fun SettingsListItem(
- modifier: Modifier = Modifier,
- onClick: () -> Unit,
+private fun BasicSettingsListItem(
label: String,
supportText: String? = null,
+ onClick: () -> Unit = {},
+ content: @Composable RowScope.() -> Unit = {}
) {
Row(
- modifier = modifier
+ modifier = Modifier
.fillMaxWidth()
.clickable(
interactionSource = remember { MutableInteractionSource() },
@@ -43,7 +43,9 @@ fun SettingsListItem(
verticalAlignment = Alignment.CenterVertically,
) {
Column(
- Modifier.padding(horizontal = 0.dp)
+ Modifier
+ .padding(horizontal = 0.dp)
+ .weight(1f) // This makes additional composable to be seen
) {
Text(
modifier = Modifier
@@ -62,5 +64,38 @@ fun SettingsListItem(
)
}
}
+ content()
}
}
+
+/**
+ * Represents one item in list on Settings screen
+ *
+ * @param label Main text
+ * @param supportText Text that is located below label
+ * @param onClick Action to perform when user clicks on this component (whole component is clickable)
+ */
+@Composable
+fun SettingsListItem(
+ label: String,
+ supportText: String? = null,
+ onClick: () -> Unit,
+) = BasicSettingsListItem(label, supportText, onClick)
+
+/**
+ * Represents one item in list on Settings screen
+ *
+ * @param label Main text
+ * @param supportText Text that is located below label
+ * @param switchState Current switch state
+ * @param onSwitchChange Action to perform when user clicks on this component or just switch
+ */
+@Composable
+fun SettingsListItem(
+ label: String,
+ supportText: String? = null,
+ switchState: Boolean,
+ onSwitchChange: (Boolean) -> Unit
+) = BasicSettingsListItem(label, supportText, { onSwitchChange(switchState) }) {
+ Switch(checked = switchState, onCheckedChange = { onSwitchChange(!it) })
+}
diff --git a/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsScreen.kt b/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsScreen.kt
index 6a5aa2ec..9dd14622 100644
--- a/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsScreen.kt
+++ b/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsScreen.kt
@@ -130,6 +130,11 @@ fun SettingsScreen(
)
}
)
+ SettingsListItem(
+ label = stringResource(id = R.string.send_usage_statistics),
+ supportText = stringResource(id = R.string.send_usage_statistics_support),
+ switchState = mainViewModel.enableAnalytics,
+ onSwitchChange = { mainViewModel.setAnalyticsPref(!it) })
SettingsListItem(
label = stringResource(R.string.third_party_licenses),
onClick = { navControllerAction(ABOUT_SCREEN) }
diff --git a/app/src/main/res/values-en-rUS/strings.xml b/app/src/main/res/values-en-rUS/strings.xml
index 0ae5ac70..3221f378 100644
--- a/app/src/main/res/values-en-rUS/strings.xml
+++ b/app/src/main/res/values-en-rUS/strings.xml
@@ -718,5 +718,7 @@
Clear input
Add or remove unit from favorites
Empty search result
+ Send usage statistics
+ All data is anonymous and encrypted
\ No newline at end of file
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 796b556d..a473fcdb 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -670,5 +670,7 @@
Солнце M
Давление
Ускорение
+ Отправлять статистику использования
+ Все данные анонимны и зашифрованы
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 899f646f..1167b838 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -930,6 +930,8 @@
Privacy Policy
Third party licenses
Rate this app
+ Send usage statistics
+ All data is anonymous and encrypted
General
Additional