diff --git a/.gitignore b/.gitignore
index 9e28947a..6f45ca55 100644
--- a/.gitignore
+++ b/.gitignore
@@ -91,3 +91,4 @@ lint/tmp/
/app/google-services.json
/tools
+/dirty
diff --git a/README.md b/README.md
index f1c69866..4ad6519f 100644
--- a/README.md
+++ b/README.md
@@ -10,25 +10,44 @@
## đČ Download
-
-
+
+
+
## đ Features
- **Instant** expression evaluation
- Expressions **history**
- **Copy**, **paste** and **cut** expression
- **Material You** Theme even for **old devices**
-- **569** units and currencies
+- **583** units and currencies
- **Smart** units search
- **Adaptive** units sorting algorithm
- **Small** app size
- **Bulk convert** units
- **Favorite** units
- Ability to **disable unit groups**
+- Built-in **Date calculator**
- Customizable number **formatter**
- **SI Standard**
-**Currency converter** needs Internet connection, stop asking stupid questions.
+## â Security
+
+### `com.sadellie.unitto.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION`
+Read (boring): https://developer.android.com/about/versions/14/behavior-changes-14#runtime-receivers-exported
+
+### `android.permission.INTERNET`
+Used in **Unit Converter** to update currency rates. Requests are made *only* when you select a currency unit. See: [CurrencyApiService.kt](https://github.com/sadellie/unitto/blob/2405a2656ac8de3877a647f19813b4498f24c7a8/data/units/src/main/java/com/sadellie/unitto/data/units/remote/CurrencyApiService.kt) and [UnitsRepository.kt](https://github.com/sadellie/unitto/blob/49f1520d88843ed3cc7ebc02307e877950c9899b/data/units/src/main/java/com/sadellie/unitto/data/units/UnitsRepository.kt)
+
+### `android.permission.ACCESS_NETWORK_STATE`
+Used in **Unit Converter** as a callback. Retries to update currency rates if there was an error (no network, for example) and the Internet connection is back. See: [NetworkUtils.kt](https://github.com/sadellie/unitto/blob/d7db2780c83cdda33335c5278cafe4148c5e7778/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/NetworkUtils.kt) and [ConverterScreen.kt](https://github.com/sadellie/unitto/blob/6fcf340abac7d34d2de9b142bf8208b55a09079f/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterScreen.kt)
+
+### Non-free network service
+*Non-free* doesn't mean that you need to pay, put your credit card away. In this context it means that you can't host it on your machine (why the fuck would anyone want to host a currency API service?).
+
+The app uses [Free Currency Rates API](https://github.com/fawazahmed0/currency-api) by [fawazahmed0](https://github.com/fawazahmed0).
+Requests are send to `cdn.jsdelivr.net`.
+
+TL;DR: the app is legit
## đ
[Translate](https://poeditor.com/join/project/T4zjmoq8dx)
Join on **POEditor** to help.
@@ -40,9 +59,8 @@ Report bugs or request improvements. I may close your issue as not planned and r
If you think that your question will not fit in "Issues", start a discussion.
## đ©âđ» ~~Contribute code~~
-Code contributions are **not** welcomed. If you really want to, **ask me** first.
-
-Hard forks and alterations of Unitto are **not** welcomed. Use a "Fork" button so that commits' author is not lost.
+1. At the moment I do not need any help in code.
+2. Hard forks and alterations of Unitto are **not** welcomed. Use a "Fork" button so that commits' author is not lost.
## đ Additional
Terms and Conditions: https://sadellie.github.io/unitto/terms
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 9d3bcad9..8e01d9c6 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -16,8 +16,6 @@
* along with this program. If not, see .
*/
-@file:Suppress("UnstableApiUsage")
-
plugins {
// Basic stuff
id("com.android.application")
@@ -34,8 +32,21 @@ android {
applicationId = "com.sadellie.unitto"
minSdk = 21
targetSdk = 34
- versionCode = 24
- versionName = "Mikado Yellow"
+ versionCode = 26
+ versionName = "Nadeshiko Pink"
+ resourceConfigurations += setOf(
+ "en",
+ "en-rGB",
+ "de",
+ "es",
+ "fr",
+ "hu",
+ "in",
+ "it",
+ "nl",
+ "ru",
+ "tr",
+ )
}
buildTypes {
@@ -91,9 +102,6 @@ android {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
- freeCompilerArgs = freeCompilerArgs + listOf(
- "-opt-in=androidx.lifecycle.compose.ExperimentalLifecycleComposeApi"
- )
}
composeOptions {
@@ -108,24 +116,24 @@ tasks.withType().configureEach
}
dependencies {
- implementation(libs.androidx.core)
- coreLibraryDesugaring(libs.android.desugarJdkLibs)
+ implementation(libs.androidx.core.core.ktx)
+ coreLibraryDesugaring(libs.com.android.tools.desugar.jdk.libs)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.material.icons.extended)
- implementation(libs.androidx.lifecycle.runtime.compose)
+ implementation(libs.androidx.lifecycle.lifecycle.runtime.compose)
implementation(libs.com.github.sadellie.themmo)
- implementation(libs.com.google.accompanist.systemuicontroller)
- implementation(libs.androidx.datastore)
+ implementation(libs.com.google.accompanist.accompanist.systemuicontroller)
+ implementation(libs.androidx.datastore.datastore.preferences)
+ implementation(libs.androidx.appcompat.appcompat)
- implementation(project(mapOf("path" to ":feature:converter")))
- implementation(project(mapOf("path" to ":feature:calculator")))
- implementation(project(mapOf("path" to ":feature:settings")))
- implementation(project(mapOf("path" to ":feature:unitslist")))
- implementation(project(mapOf("path" to ":feature:datecalculator")))
- implementation(project(mapOf("path" to ":feature:timezone")))
- implementation(project(mapOf("path" to ":data:model")))
- implementation(project(mapOf("path" to ":data:userprefs")))
- implementation(project(mapOf("path" to ":core:ui")))
- implementation(project(mapOf("path" to ":core:base")))
+ implementation(project(":feature:converter"))
+ implementation(project(":feature:calculator"))
+ implementation(project(":feature:settings"))
+ implementation(project(":feature:datecalculator"))
+ implementation(project(":feature:timezone"))
+ implementation(project(":data:model"))
+ implementation(project(":data:userprefs"))
+ implementation(project(":core:ui"))
+ implementation(project(":core:base"))
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 4d47d3f2..ba0a4a1f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,8 +7,8 @@
android:name=".UnittoApplication"
android:icon="@mipmap/ic_launcher_icon"
android:label="@string/calculator"
-
android:supportsRtl="false"
+ android:localeConfig="@xml/locales_config"
android:theme="@style/Theme.Unitto">
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/sadellie/unitto/MainActivity.kt b/app/src/main/java/com/sadellie/unitto/MainActivity.kt
index b68879ed..f7935a0d 100644
--- a/app/src/main/java/com/sadellie/unitto/MainActivity.kt
+++ b/app/src/main/java/com/sadellie/unitto/MainActivity.kt
@@ -23,8 +23,8 @@ import android.content.Context
import android.os.Bundle
import android.util.AttributeSet
import android.view.View
-import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
+import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
@@ -32,7 +32,7 @@ import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
-internal class MainActivity : ComponentActivity() {
+internal class MainActivity : AppCompatActivity() {
@Inject
lateinit var userPrefsRepository: UserPreferencesRepository
@@ -41,10 +41,10 @@ internal class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
setContent {
- val uiPrefs = userPrefsRepository.uiPreferencesFlow
+ val prefs = userPrefsRepository.appPrefs
.collectAsStateWithLifecycle(null).value
- if (uiPrefs != null) UnittoApp(uiPrefs)
+ if (prefs != null) UnittoApp(prefs)
}
}
diff --git a/app/src/main/java/com/sadellie/unitto/UnittoApp.kt b/app/src/main/java/com/sadellie/unitto/UnittoApp.kt
index 48797e95..93d72b12 100644
--- a/app/src/main/java/com/sadellie/unitto/UnittoApp.kt
+++ b/app/src/main/java/com/sadellie/unitto/UnittoApp.kt
@@ -46,27 +46,29 @@ import com.sadellie.unitto.core.ui.common.isOpen
import com.sadellie.unitto.core.ui.common.open
import com.sadellie.unitto.core.ui.common.rememberUnittoDrawerState
import com.sadellie.unitto.core.ui.model.DrawerItems
-import com.sadellie.unitto.core.ui.theme.AppTypography
+import com.sadellie.unitto.core.ui.pushDynamicShortcut
+import com.sadellie.unitto.core.ui.theme.TypographySystem
+import com.sadellie.unitto.core.ui.theme.TypographyUnitto
import com.sadellie.unitto.core.ui.theme.DarkThemeColors
import com.sadellie.unitto.core.ui.theme.LightThemeColors
-import com.sadellie.unitto.data.userprefs.UIPreferences
+import com.sadellie.unitto.data.userprefs.AppPreferences
import io.github.sadellie.themmo.Themmo
import io.github.sadellie.themmo.rememberThemmoController
import kotlinx.coroutines.launch
@OptIn(ExperimentalFoundationApi::class)
@Composable
-internal fun UnittoApp(uiPrefs: UIPreferences) {
+internal fun UnittoApp(prefs: AppPreferences) {
val mContext = LocalContext.current
val themmoController = rememberThemmoController(
lightColorScheme = LightThemeColors,
darkColorScheme = DarkThemeColors,
- themingMode = uiPrefs.themingMode,
- dynamicThemeEnabled = uiPrefs.enableDynamicTheme,
- amoledThemeEnabled = uiPrefs.enableAmoledTheme,
- customColor = uiPrefs.customColor,
- monetMode = uiPrefs.monetMode
+ themingMode = prefs.themingMode,
+ dynamicThemeEnabled = prefs.enableDynamicTheme,
+ amoledThemeEnabled = prefs.enableAmoledTheme,
+ customColor = prefs.customColor,
+ monetMode = prefs.monetMode
)
val navController = rememberNavController()
val sysUiController = rememberSystemUiController()
@@ -77,9 +79,9 @@ internal fun UnittoApp(uiPrefs: UIPreferences) {
val shortcutsScope = rememberCoroutineScope()
- val tabs by remember(uiPrefs.enableToolsExperiment) {
+ val tabs by remember(prefs.enableToolsExperiment) {
derivedStateOf {
- if (uiPrefs.enableToolsExperiment) {
+ if (prefs.enableToolsExperiment) {
listOf(
DrawerItems.Calculator,
DrawerItems.Converter,
@@ -105,7 +107,7 @@ internal fun UnittoApp(uiPrefs: UIPreferences) {
Themmo(
themmoController = themmoController,
- typography = AppTypography,
+ typography = if (prefs.systemFont) TypographySystem else TypographyUnitto,
animationSpec = tween(250)
) {
val backgroundColor = MaterialTheme.colorScheme.background
@@ -150,7 +152,7 @@ internal fun UnittoApp(uiPrefs: UIPreferences) {
UnittoNavigation(
navController = navController,
themmoController = it,
- startDestination = uiPrefs.startingScreen,
+ startDestination = prefs.startingScreen,
openDrawer = { drawerScope.launch { drawerState.open() } }
)
}
diff --git a/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt b/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt
index 69ab8f48..1b205fa3 100644
--- a/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt
+++ b/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt
@@ -18,25 +18,20 @@
package com.sadellie.unitto
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import com.sadellie.unitto.feature.calculator.navigation.calculatorGraph
-import com.sadellie.unitto.feature.converter.ConverterViewModel
import com.sadellie.unitto.feature.converter.navigation.converterGraph
import com.sadellie.unitto.feature.datecalculator.navigation.dateCalculatorGraph
import com.sadellie.unitto.feature.settings.navigation.navigateToSettings
import com.sadellie.unitto.feature.settings.navigation.navigateToUnitGroups
import com.sadellie.unitto.feature.settings.navigation.settingGraph
-import com.sadellie.unitto.feature.unitslist.UnitsListViewModel
-import com.sadellie.unitto.feature.unitslist.navigation.leftScreen
-import com.sadellie.unitto.feature.unitslist.navigation.navigateToLeftSide
-import com.sadellie.unitto.feature.unitslist.navigation.navigateToRightSide
-import com.sadellie.unitto.feature.unitslist.navigation.rightScreen
import com.sadellie.unitto.timezone.navigation.timeZoneGraph
import io.github.sadellie.themmo.ThemmoController
@@ -47,34 +42,18 @@ internal fun UnittoNavigation(
startDestination: String,
openDrawer: () -> Unit
) {
- val converterViewModel: ConverterViewModel = hiltViewModel()
- val unitsListViewModel: UnitsListViewModel = hiltViewModel()
-
NavHost(
navController = navController,
startDestination = startDestination,
- modifier = Modifier.background(MaterialTheme.colorScheme.background)
+ modifier = Modifier.background(MaterialTheme.colorScheme.background),
+ enterTransition = { fadeIn() },
+ exitTransition = { fadeOut() }
) {
converterGraph(
- navigateToLeftScreen = navController::navigateToLeftSide,
- navigateToRightScreen = navController::navigateToRightSide,
+ openDrawer = openDrawer,
+ navController = navController,
navigateToSettings = navController::navigateToSettings,
- navigateToMenu = openDrawer,
- viewModel = converterViewModel
- )
-
- leftScreen(
- viewModel = unitsListViewModel,
- navigateUp = navController::navigateUp,
- navigateToUnitGroups = navController::navigateToUnitGroups,
- onSelect = converterViewModel::updateUnitFrom
- )
-
- rightScreen(
- viewModel = unitsListViewModel,
- navigateUp = navController::navigateUp,
- navigateToUnitGroups = navController::navigateToUnitGroups,
- onSelect = converterViewModel::updateUnitTo
+ navigateToUnitGroups = navController::navigateToUnitGroups
)
settingGraph(
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 4f6a9a46..ecaeb63c 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,5 +1,5 @@
-