Calculator history (#2):

this is a squashed commit
This commit is contained in:
Sad Ellie 2023-02-17 15:58:17 +04:00
parent 31f59ca038
commit 39f4997c73
88 changed files with 1139 additions and 256 deletions

View File

@ -116,6 +116,7 @@ dependencies {
implementation(project(mapOf("path" to ":feature:tools")))
implementation(project(mapOf("path" to ":feature:epoch")))
implementation(project(mapOf("path" to ":data:units")))
implementation(project(mapOf("path" to ":data:model")))
implementation(project(mapOf("path" to ":data:userprefs")))
implementation(project(mapOf("path" to ":core:ui")))
}

View File

@ -1025,6 +1025,9 @@
<!--Calculator-->
<string name="calculator">Calculator</string>
<string name="calculator_support">Calculate, but don\'t convert</string>
<string name="calculator_clear_history_label">Clear</string>
<string name="calculator_clear_history_title">Clear history</string>
<string name="calculator_clear_history_support">All expressions from history will be deleted forever. This action can\'t be undone!</string>
<!--Precision-->
<string name="precision_setting_support">Number of decimal places</string>

View File

@ -19,6 +19,7 @@
package com.sadellie.unitto.core.ui.common
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.RowScope
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
@ -36,6 +37,7 @@ import androidx.compose.ui.Modifier
fun UnittoTopAppBar(
title: String,
navigateUpAction: () -> Unit,
actions: @Composable RowScope.() -> Unit = {},
content: @Composable (PaddingValues) -> Unit
) {
Scaffold(
@ -47,7 +49,8 @@ fun UnittoTopAppBar(
},
navigationIcon = {
NavigateUpButton { navigateUpAction() }
}
},
actions = actions
)
},
content = content

1
data/calculator/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -1,6 +1,6 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2022 Elshan Agaev
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,12 +16,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units.database
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [MyBasedUnit::class], version = 1, exportSchema = false)
abstract class MyBasedUnitDatabase : RoomDatabase() {
abstract fun myBasedUnitDao(): MyBasedUnitDao
plugins {
id("unitto.library")
id("unitto.android.hilt")
}
android {
namespace = "com.sadellie.unitto.data.calculator"
}
dependencies {
implementation(project(mapOf("path" to ":data:model")))
implementation(project(mapOf("path" to ":data:database")))
}

View File

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Unitto is a unit converter for Android
~ Copyright (c) 2023 Elshan Agaev
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View File

@ -0,0 +1,68 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.calculator
import com.sadellie.unitto.data.database.CalculatorHistoryDao
import com.sadellie.unitto.data.database.CalculatorHistoryEntity
import com.sadellie.unitto.data.model.HistoryItem
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import java.util.*
import javax.inject.Inject
class CalculatorHistoryRepository @Inject constructor(
private val calculatorHistoryDao: CalculatorHistoryDao
) {
/**
* Calculator history sorted by [CalculatorHistoryEntity.timestamp] from new to old (DESC).
*/
val historyFlow: Flow<List<HistoryItem>> = calculatorHistoryDao
.getAllDescending()
.map { it.toHistoryItemList() }
.flowOn(Dispatchers.IO)
suspend fun add(
expression: String,
result: String
) {
calculatorHistoryDao.insert(
CalculatorHistoryEntity(
timestamp = System.currentTimeMillis(),
expression = expression,
result = result
)
)
}
suspend fun clear() {
calculatorHistoryDao.clear()
}
private fun List<CalculatorHistoryEntity>.toHistoryItemList(): List<HistoryItem> {
return this.map {
HistoryItem(
date = Date(it.timestamp),
expression = it.expression,
result = it.result
)
}
}
}

1
data/common/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,29 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
plugins {
id("unitto.library")
}
android {
namespace = "com.sadellie.unitto.data.common"
}
dependencies {
implementation(project(mapOf("path" to ":core:base")))
}

View File

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Unitto is a unit converter for Android
~ Copyright (c) 2023 Elshan Agaev
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View File

@ -1,6 +1,6 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022 Elshan Agaev
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data
package com.sadellie.unitto.data.common
import com.sadellie.unitto.core.base.OutputFormat
import java.math.BigDecimal

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data
package com.sadellie.unitto.data.common
/**
* Compute Levenshtein Distance between this string and [secondString]. Doesn't matter which string is

1
data/database/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,40 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
plugins {
id("unitto.library")
id("unitto.android.hilt")
}
android {
namespace = "com.sadellie.unitto.data.database"
// Long thingy
val schemaLocation = "$projectDir/schemas"
defaultConfig
.javaCompileOptions
.annotationProcessorOptions
.arguments["room.schemaLocation"] = schemaLocation
println("Exported Database schema to $schemaLocation")
}
dependencies {
implementation(libs.androidx.room.runtime)
implementation(libs.androidx.room.ktx)
kapt(libs.androidx.room.compiler)
}

View File

View File

@ -0,0 +1,52 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "96a05166e4b7d08a4595ac65138aff62",
"entities": [
{
"tableName": "units",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`unitId` TEXT NOT NULL, `is_favorite` INTEGER, `paired_unit_id` TEXT, `frequency` INTEGER, PRIMARY KEY(`unitId`))",
"fields": [
{
"fieldPath": "unitId",
"columnName": "unitId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "isFavorite",
"columnName": "is_favorite",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "pairedUnitId",
"columnName": "paired_unit_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "frequency",
"columnName": "frequency",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"unitId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '96a05166e4b7d08a4595ac65138aff62')"
]
}
}

View File

@ -0,0 +1,90 @@
{
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "d5dca9e0346c3400b7ff5b31e85c7827",
"entities": [
{
"tableName": "units",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`unitId` TEXT NOT NULL, `is_favorite` INTEGER, `paired_unit_id` TEXT, `frequency` INTEGER, PRIMARY KEY(`unitId`))",
"fields": [
{
"fieldPath": "unitId",
"columnName": "unitId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "isFavorite",
"columnName": "is_favorite",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "pairedUnitId",
"columnName": "paired_unit_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "frequency",
"columnName": "frequency",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"unitId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "calculator_history",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`entityId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `expression` TEXT NOT NULL, `result` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "entityId",
"columnName": "entityId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "expression",
"columnName": "expression",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "result",
"columnName": "result",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"entityId"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd5dca9e0346c3400b7ff5b31e85c7827')"
]
}
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Unitto is a unit converter for Android
~ Copyright (c) 2023 Elshan Agaev
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View File

@ -0,0 +1,37 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.database
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import kotlinx.coroutines.flow.Flow
@Dao
interface CalculatorHistoryDao {
@Query("SELECT * FROM calculator_history ORDER BY timestamp DESC")
fun getAllDescending(): Flow<List<CalculatorHistoryEntity>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(vararg historyEntity: CalculatorHistoryEntity)
@Query("DELETE FROM calculator_history")
suspend fun clear()
}

View File

@ -0,0 +1,31 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.database
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "calculator_history")
class CalculatorHistoryEntity(
@PrimaryKey(autoGenerate = true) val entityId: Int = 0,
@ColumnInfo(name = "timestamp") val timestamp: Long,
@ColumnInfo(name = "expression") val expression: String,
@ColumnInfo(name = "result") val result: String
)

View File

@ -1,6 +1,6 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2022 Elshan Agaev
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units.database
package com.sadellie.unitto.data.database
import androidx.room.Dao
import androidx.room.Insert
@ -24,10 +24,10 @@ import androidx.room.OnConflictStrategy
import androidx.room.Query
@Dao
interface MyBasedUnitDao {
interface UnitsDao {
@Query("SELECT * FROM units")
suspend fun getAll(): List<MyBasedUnit>
suspend fun getAll(): List<UnitsEntity>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertUnits(vararg units: MyBasedUnit)
suspend fun insertUnits(vararg units: UnitsEntity)
}

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units.database
package com.sadellie.unitto.data.database
import androidx.room.ColumnInfo
import androidx.room.Entity
@ -30,7 +30,7 @@ import androidx.room.PrimaryKey
* @param frequency Show the amount of time this unit was used
*/
@Entity(tableName = "units")
class MyBasedUnit(
class UnitsEntity(
@PrimaryKey val unitId: String,
@ColumnInfo(name = "is_favorite") val isFavorite: Boolean?,
@ColumnInfo(name = "paired_unit_id") val pairedUnitId: String?,

View File

@ -1,6 +1,6 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2022 Elshan Agaev
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,26 +16,26 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units.database
package com.sadellie.unitto.data.database
import javax.inject.Inject
class MyBasedUnitsRepository @Inject constructor (private val myBasedUnitDao: MyBasedUnitDao) {
class UnitsRepository @Inject constructor (private val unitsDao: UnitsDao) {
/**
* Method to insert units. Will rewrite row if unit's id is already in database
*
* @param unit Unit to add
*/
suspend fun insertUnits(unit: MyBasedUnit) {
myBasedUnitDao.insertUnits(unit)
suspend fun insertUnits(unit: UnitsEntity) {
unitsDao.insertUnits(unit)
}
/**
* Method to get all units from units table
*
* @return List of [MyBasedUnit] objects that represent one row in table
* @return List of [UnitsEntity] objects that represent one row in table
*/
suspend fun getAll(): List<MyBasedUnit> {
return myBasedUnitDao.getAll()
suspend fun getAll(): List<UnitsEntity> {
return unitsDao.getAll()
}
}

View File

@ -0,0 +1,39 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.database
import androidx.room.AutoMigration
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(
version = 2,
exportSchema = true,
entities = [
UnitsEntity::class,
CalculatorHistoryEntity::class
],
autoMigrations = [
AutoMigration (from = 1, to = 2)
]
)
abstract class UnittoDatabase : RoomDatabase() {
abstract fun unitsDao(): UnitsDao
abstract fun calculatorHistoryDao(): CalculatorHistoryDao
}

View File

@ -1,6 +1,6 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2022 Elshan Agaev
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units.database
package com.sadellie.unitto.data.database
import android.content.Context
import androidx.room.Room
@ -33,30 +33,41 @@ import javax.inject.Singleton
*/
@InstallIn(SingletonComponent::class)
@Module
class BasedUnitDatabaseModule {
class UnittoDatabaseModule {
/**
* Tells Hilt to use this method to get [MyBasedUnitDao]
* Tells Hilt to use this method to get [UnitsDao]
*
* @param myBasedUnitDatabase Database for which we need DAO
* @return Singleton of [MyBasedUnitDao]
* @param unittoDatabase Database for which we need DAO
* @return Singleton of [UnitsDao]
*/
@Provides
fun provideMyBasedUnitDao(myBasedUnitDatabase: MyBasedUnitDatabase): MyBasedUnitDao {
return myBasedUnitDatabase.myBasedUnitDao()
fun provideUnitsDao(unittoDatabase: UnittoDatabase): UnitsDao {
return unittoDatabase.unitsDao()
}
/**
* Tells Hilt to use this method to get [MyBasedUnitDatabase]
* Tells Hilt to use this method to get [CalculatorHistoryDao]
*
* @param unittoDatabase Database for which we need DAO
* @return Singleton of [CalculatorHistoryDao]
*/
@Provides
fun provideCalculatorHistoryDao(unittoDatabase: UnittoDatabase): CalculatorHistoryDao {
return unittoDatabase.calculatorHistoryDao()
}
/**
* Tells Hilt to use this method to get [UnittoDatabase]
*
* @param appContext Context
* @return Singleton of [MyBasedUnitDatabase]
* @return Singleton of [UnittoDatabase]
*/
@Provides
@Singleton
fun provideMyBasedUnitDatabase(@ApplicationContext appContext: Context): MyBasedUnitDatabase {
fun provideUnittoDatabase(@ApplicationContext appContext: Context): UnittoDatabase {
return Room.databaseBuilder(
appContext.applicationContext,
MyBasedUnitDatabase::class.java,
UnittoDatabase::class.java,
"unitto_database"
).build()
}

View File

@ -1,21 +0,0 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

1
data/model/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,30 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
plugins {
id("unitto.library")
}
android {
namespace = "com.sadellie.unitto.data.model"
}
dependencies {
implementation(project(mapOf("path" to ":core:base")))
implementation(project(mapOf("path" to ":data:common")))
}

View File

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Unitto is a unit converter for Android
~ Copyright (c) 2023 Elshan Agaev
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View File

@ -16,11 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units
package com.sadellie.unitto.data.model
import androidx.annotation.StringRes
import com.sadellie.unitto.data.lev
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.common.lev
import java.math.BigDecimal
/**

View File

@ -0,0 +1,27 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.model
import java.util.*
data class HistoryItem(
val date: Date,
val expression: String,
val result: String
)

View File

@ -16,13 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units
package com.sadellie.unitto.data.model
import androidx.annotation.StringRes
import com.sadellie.unitto.core.base.MAX_PRECISION
import com.sadellie.unitto.data.setMinimumRequiredScale
import com.sadellie.unitto.data.trimZeros
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.common.setMinimumRequiredScale
import com.sadellie.unitto.data.common.trimZeros
import java.math.BigDecimal
/**

View File

@ -16,10 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units
package com.sadellie.unitto.data.model
import androidx.annotation.StringRes
import com.sadellie.unitto.data.unitgroups.UnitGroup
import java.math.BigDecimal
class NumberBaseUnit(

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.unitgroups
package com.sadellie.unitto.data.model
import androidx.annotation.StringRes

View File

@ -30,4 +30,5 @@ dependencies {
implementation(libs.org.burnoutcrew.composereorderable)
implementation(project(mapOf("path" to ":core:base")))
implementation(project(mapOf("path" to ":data:model")))
}

View File

@ -18,6 +18,8 @@
package com.sadellie.unitto.data.unitgroups
import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS
import com.sadellie.unitto.data.model.UnitGroup
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

View File

@ -30,9 +30,6 @@ dependencies {
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.androidx.datastore)
implementation(libs.androidx.room.runtime)
implementation(libs.androidx.room.ktx)
kapt(libs.androidx.room.compiler)
implementation(libs.com.squareup.moshi)
implementation(libs.com.squareup.retrofit2)
@ -40,6 +37,8 @@ dependencies {
implementation(libs.org.burnoutcrew.composereorderable)
implementation(libs.com.github.sadellie.themmo)
implementation(project(mapOf("path" to ":data:unitgroups")))
implementation(project(mapOf("path" to ":core:base")))
implementation(project(mapOf("path" to ":data:database")))
implementation(project(mapOf("path" to ":data:common")))
implementation(project(mapOf("path" to ":data:model")))
}

View File

@ -20,7 +20,9 @@ package com.sadellie.unitto.data.units
import android.content.Context
import com.sadellie.unitto.core.base.MAX_PRECISION
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.sortByLev
import com.sadellie.unitto.data.units.collections.accelerationCollection
import com.sadellie.unitto.data.units.collections.angleCollection
import com.sadellie.unitto.data.units.collections.areaCollection
@ -38,7 +40,7 @@ import com.sadellie.unitto.data.units.collections.speedCollection
import com.sadellie.unitto.data.units.collections.temperatureCollection
import com.sadellie.unitto.data.units.collections.timeCollection
import com.sadellie.unitto.data.units.collections.volumeCollection
import com.sadellie.unitto.data.units.database.MyBasedUnit
import com.sadellie.unitto.data.database.UnitsEntity
import java.math.BigDecimal
import javax.inject.Inject
import javax.inject.Singleton
@ -153,19 +155,19 @@ class AllUnitsRepository @Inject constructor() {
*
* @param context [Context] that is used to fill [AbstractUnit.renderedName]. Rendered names are used when
* searching.
* @param allBasedUnits List from database. See: [MyBasedUnit].
* @param allUnits List from database. See: [UnitsEntity].
*/
fun loadFromDatabase(context: Context, allBasedUnits: List<MyBasedUnit>) {
allUnits.forEach {
fun loadFromDatabase(context: Context, allUnits: List<UnitsEntity>) {
this.allUnits.forEach {
// Loading unit names so that we can search through them
it.renderedName = context.getString(it.displayName)
it.renderedShortName = context.getString(it.shortName)
val based = allBasedUnits.firstOrNull { based -> based.unitId == it.unitId }
val fromDb = allUnits.firstOrNull { fromDb -> fromDb.unitId == it.unitId }
// Loading paired units
it.pairedUnit = based?.pairedUnitId
it.pairedUnit = fromDb?.pairedUnitId
// Loading favorite state
it.isFavorite = based?.isFavorite ?: false
it.counter = based?.frequency ?: 0
it.isFavorite = fromDb?.isFavorite ?: false
it.counter = fromDb?.frequency ?: 0
}
}

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data
package com.sadellie.unitto.data.units
import kotlinx.coroutines.flow.Flow

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.unitgroups.UnitGroup
import java.math.BigDecimal
internal val accelerationCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val angleCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val areaCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val currencyCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val dataCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val dataTransferCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val energyCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val fluxCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val lengthCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val massCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.NumberBaseUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.units.NumberBaseUnit
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
internal val numberBaseCollection: List<AbstractUnit> by lazy {
listOf(

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val powerCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val pressureCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val speedCollection: List<AbstractUnit> by lazy {

View File

@ -19,12 +19,12 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.MAX_PRECISION
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.setMinimumRequiredScale
import com.sadellie.unitto.data.trimZeros
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.common.setMinimumRequiredScale
import com.sadellie.unitto.data.common.trimZeros
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
import java.math.RoundingMode

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val timeCollection: List<AbstractUnit> by lazy {

View File

@ -18,11 +18,11 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.data.units.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.MyUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.R
import java.math.BigDecimal
internal val volumeCollection: List<AbstractUnit> by lazy {

View File

@ -18,8 +18,8 @@
package com.sadellie.unitto.data.units
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.model.NumberBaseUnit
import com.sadellie.unitto.data.model.UnitGroup
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Test

View File

@ -18,7 +18,10 @@
package com.sadellie.unitto.data.units
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.MyUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.sortByLev
import org.junit.Assert.assertEquals
import org.junit.Test
import java.math.BigDecimal

View File

@ -18,7 +18,7 @@
package com.sadellie.unitto.data.units
import com.sadellie.unitto.data.lev
import com.sadellie.unitto.data.common.lev
import org.junit.Assert.assertEquals
import org.junit.Test

View File

@ -18,7 +18,7 @@
package com.sadellie.unitto.data.units
import com.sadellie.unitto.data.setMinimumRequiredScale
import com.sadellie.unitto.data.common.setMinimumRequiredScale
import org.junit.Assert.assertEquals
import org.junit.Test
import java.math.BigDecimal

View File

@ -29,7 +29,7 @@ dependencies {
implementation(libs.androidx.datastore)
implementation(libs.com.github.sadellie.themmo)
implementation(project(mapOf("path" to ":data:units")))
implementation(project(mapOf("path" to ":data:unitgroups")))
implementation(project(mapOf("path" to ":core:base")))
implementation(project(mapOf("path" to ":data:model")))
implementation(project(mapOf("path" to ":data:units")))
}

View File

@ -27,9 +27,9 @@ import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import com.sadellie.unitto.core.base.OutputFormat
import com.sadellie.unitto.core.base.Separator
import com.sadellie.unitto.data.unitgroups.ALL_UNIT_GROUPS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import io.github.sadellie.themmo.ThemingMode
import kotlinx.coroutines.flow.Flow

View File

@ -32,7 +32,9 @@ dependencies {
implementation(libs.org.mariuszgromada.math.mxparser)
implementation(libs.com.github.sadellie.themmo)
implementation(project(mapOf("path" to ":data:common")))
implementation(project(mapOf("path" to ":data:userprefs")))
implementation(project(mapOf("path" to ":data:unitgroups")))
implementation(project(mapOf("path" to ":data:units")))
implementation(project(mapOf("path" to ":data:database")))
implementation(project(mapOf("path" to ":data:calculator")))
implementation(project(mapOf("path" to ":data:model")))
}

View File

@ -18,14 +18,30 @@
package com.sadellie.unitto.feature.calculator
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.TextFieldValue
@ -35,8 +51,15 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sadellie.unitto.core.ui.common.UnittoTopAppBar
import com.sadellie.unitto.core.ui.theme.NumbersTextStyleDisplayMedium
import com.sadellie.unitto.data.model.HistoryItem
import com.sadellie.unitto.feature.calculator.components.CalculatorKeyboard
import com.sadellie.unitto.feature.calculator.components.DragDownView
import com.sadellie.unitto.feature.calculator.components.HistoryList
import com.sadellie.unitto.feature.calculator.components.InputTextField
import java.text.SimpleDateFormat
import java.util.*
import kotlin.math.abs
import kotlin.math.roundToInt
@Composable
internal fun CalculatorRoute(
@ -53,7 +76,8 @@ internal fun CalculatorRoute(
deleteSymbol = viewModel::deleteSymbol,
onCursorChange = viewModel::onCursorChange,
toggleAngleMode = viewModel::toggleCalculatorMode,
evaluate = viewModel::evaluate
evaluate = viewModel::evaluate,
clearHistory = viewModel::clearHistory
)
}
@ -66,57 +90,144 @@ private fun CalculatorScreen(
deleteSymbol: () -> Unit,
onCursorChange: (IntRange) -> Unit,
toggleAngleMode: () -> Unit,
evaluate: () -> Unit
evaluate: () -> Unit,
clearHistory: () -> Unit
) {
var showClearHistoryDialog by rememberSaveable { mutableStateOf(false) }
var draggedAmount by remember { mutableStateOf(0f) }
val dragAmountAnimated by animateFloatAsState(draggedAmount)
// val dragAmountAnimated = draggedAmount
var textThingyHeight by remember { mutableStateOf(0) }
var historyItemHeight by remember { mutableStateOf(0) }
UnittoTopAppBar(
title = stringResource(R.string.calculator),
navigateUpAction = navigateUpAction,
) {
Column(Modifier.padding(it)) {
InputTextField(
modifier = Modifier.fillMaxWidth(),
value = TextFieldValue(
text = uiState.input,
selection = TextRange(uiState.selection.first, uiState.selection.last)
),
onCursorChange = onCursorChange,
pasteCallback = addSymbol
)
AnimatedVisibility(visible = uiState.output.isNotEmpty()) {
Text(
modifier = Modifier.fillMaxWidth(),
// Quick fix to prevent the UI from crashing
text = uiState.output,
textAlign = TextAlign.End,
softWrap = false,
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f),
style = NumbersTextStyleDisplayMedium,
)
}
CalculatorKeyboard(
modifier = Modifier,
addSymbol = addSymbol,
clearSymbols = clearSymbols,
deleteSymbol = deleteSymbol,
toggleAngleMode = toggleAngleMode,
angleMode = uiState.angleMode,
evaluate = evaluate
actions = {
IconButton(
onClick = { showClearHistoryDialog = true },
content = { Icon(Icons.Default.Delete, stringResource(R.string.calculator_clear_history_title)) }
)
}
) { paddingValues ->
DragDownView(
modifier = Modifier.padding(paddingValues),
drag = dragAmountAnimated.toInt(),
historyItemHeight = historyItemHeight,
historyList = {
HistoryList(
modifier = Modifier.fillMaxSize(),
historyItems = uiState.history,
historyItemHeightCallback = { historyItemHeight = it }
)
},
textFields = { maxDragAmount ->
Column(
Modifier
.onPlaced { textThingyHeight = it.size.height }
.draggable(
orientation = Orientation.Vertical,
state = rememberDraggableState { delta ->
draggedAmount = (draggedAmount + delta).coerceAtLeast(0f)
},
onDragStopped = {
// Snap to closest anchor (0, one history item, all history items)
draggedAmount = listOf(0, historyItemHeight, maxDragAmount)
.minBy { abs(draggedAmount.roundToInt() - it) }
.toFloat()
}
)
) {
InputTextField(
modifier = Modifier.fillMaxWidth(),
value = TextFieldValue(
text = uiState.input,
selection = TextRange(uiState.selection.first, uiState.selection.last)
),
onCursorChange = onCursorChange,
pasteCallback = addSymbol
)
Text(
modifier = Modifier.fillMaxWidth(),
text = uiState.output,
textAlign = TextAlign.End,
softWrap = false,
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f),
style = NumbersTextStyleDisplayMedium,
)
}
},
numPad = {
CalculatorKeyboard(
modifier = Modifier,
addSymbol = addSymbol,
clearSymbols = clearSymbols,
deleteSymbol = deleteSymbol,
toggleAngleMode = toggleAngleMode,
angleMode = uiState.angleMode,
evaluate = evaluate
)
}
)
}
if (showClearHistoryDialog) {
AlertDialog(
icon = {
Icon(Icons.Default.Delete, stringResource(R.string.calculator_clear_history_title))
},
title = {
Text(stringResource(R.string.calculator_clear_history_title))
},
text = {
Text(stringResource(R.string.calculator_clear_history_support))
},
confirmButton = {
TextButton(onClick = clearHistory) { Text(stringResource(R.string.calculator_clear_history_label)) }
},
dismissButton = {
TextButton(onClick = { showClearHistoryDialog = false }) { Text(stringResource(R.string.cancel_label)) }
},
onDismissRequest = { showClearHistoryDialog = false }
)
}
}
@Preview
@Composable
private fun PreviewCalculatorScreen() {
val dtf = SimpleDateFormat("dd.MM.yyyy HH:mm:ss", Locale.getDefault())
val historyItems = listOf(
"13.06.1989 23:59:15",
"13.06.1989 23:59:16",
"13.06.1989 23:59:17",
"14.06.1989 23:59:17",
"14.06.1989 23:59:18",
"14.07.1989 23:59:18",
"14.07.1989 23:59:19",
"14.07.2005 23:59:19",
).map {
HistoryItem(
date = dtf.parse(it)!!,
expression = "12345123451234512345123451234512345123451234512345123451234512345",
result = "67890"
)
}
CalculatorScreen(
uiState = CalculatorUIState(),
uiState = CalculatorUIState(
input = "12345",
output = "12345",
history = historyItems
),
navigateUpAction = {},
addSymbol = {},
clearSymbols = {},
deleteSymbol = {},
onCursorChange = {},
toggleAngleMode = {},
evaluate = {}
evaluate = {},
clearHistory = {}
)
}

View File

@ -18,9 +18,12 @@
package com.sadellie.unitto.feature.calculator
import com.sadellie.unitto.data.model.HistoryItem
internal data class CalculatorUIState(
val input: String = "",
val output: String = "",
val selection: IntRange = 0..0,
val angleMode: AngleMode = AngleMode.RAD
val angleMode: AngleMode = AngleMode.RAD,
val history: List<HistoryItem> = emptyList()
)

View File

@ -24,9 +24,10 @@ import com.sadellie.unitto.core.base.KEY_LEFT_BRACKET
import com.sadellie.unitto.core.base.KEY_MINUS
import com.sadellie.unitto.core.base.KEY_MINUS_DISPLAY
import com.sadellie.unitto.core.base.KEY_RIGHT_BRACKET
import com.sadellie.unitto.data.setMinimumRequiredScale
import com.sadellie.unitto.data.toStringWith
import com.sadellie.unitto.data.trimZeros
import com.sadellie.unitto.data.calculator.CalculatorHistoryRepository
import com.sadellie.unitto.data.common.setMinimumRequiredScale
import com.sadellie.unitto.data.common.toStringWith
import com.sadellie.unitto.data.common.trimZeros
import com.sadellie.unitto.data.userprefs.UserPreferences
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
@ -47,7 +48,8 @@ import org.mariuszgromada.math.mxparser.mXparser as MathParser
@HiltViewModel
internal class CalculatorViewModel @Inject constructor(
userPrefsRepository: UserPreferencesRepository
userPrefsRepository: UserPreferencesRepository,
private val calculatorHistoryRepository: CalculatorHistoryRepository
) : ViewModel() {
private val _userPrefs: StateFlow<UserPreferences> =
userPrefsRepository.userPreferencesFlow.stateIn(
@ -60,15 +62,17 @@ internal class CalculatorViewModel @Inject constructor(
private val _output: MutableStateFlow<String> = MutableStateFlow("")
private val _selection: MutableStateFlow<IntRange> = MutableStateFlow(IntRange(0, 0))
private val _angleMode: MutableStateFlow<AngleMode> = MutableStateFlow(AngleMode.RAD)
private val _history = calculatorHistoryRepository.historyFlow
val uiState = combine(
_input, _output, _selection, _angleMode
) { input, output, selection, angleMode ->
_input, _output, _selection, _angleMode, _history
) { input, output, selection, angleMode, history ->
return@combine CalculatorUIState(
input = input,
output = output,
selection = selection,
angleMode = angleMode
angleMode = angleMode,
history = history
)
}.stateIn(
viewModelScope, SharingStarted.WhileSubscribed(5000L), CalculatorUIState()
@ -115,11 +119,28 @@ internal class CalculatorViewModel @Inject constructor(
fun evaluate() {
if (!Expression(_input.value.clean).checkSyntax()) return
// Input and output can change while saving in history. This way we cache it here (i think)
val input = _input.value
val output = _output.value
viewModelScope.launch(Dispatchers.IO) {
calculatorHistoryRepository.add(
expression = input,
result = output
)
}
_input.update { _output.value }
_selection.update { _input.value.length.._input.value.length }
_output.update { "" }
}
fun clearHistory() {
viewModelScope.launch(Dispatchers.IO) {
calculatorHistoryRepository.clear()
}
}
fun onCursorChange(selection: IntRange) {
// When we paste, selection is set to the length of the pasted text (start and end)
if (selection.first > _input.value.length) return

View File

@ -0,0 +1,92 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.calculator.components
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.SubcomposeLayout
import androidx.compose.ui.unit.offset
/**
* Screen layout where [historyList] can be seen only when you drag [textFields] down.
*
* @param modifier [Modifier] that will be applied to [SubcomposeLayout].
* @param drag Drag amount. Update this when dragging [textFields].
* @param historyItemHeight Height of one item in [historyList].
* @param textFields This part of the UI should be used as a handle. Offsets when dragging.
* @param numPad Composable with buttons. Offsets when drag amount is higher than [historyItemHeight]
* (otherwise will just shrink).
*/
@Composable
internal fun DragDownView(
modifier: Modifier,
drag: Int,
historyItemHeight: Int,
historyList: @Composable () -> Unit,
textFields: @Composable (maxDragAmount: Int) -> Unit,
numPad: @Composable () -> Unit
) {
SubcomposeLayout(modifier = modifier) { constraints ->
val showHistory = drag < historyItemHeight
val offset = if (showHistory) (drag - historyItemHeight).coerceAtLeast(0) else 0
val textFieldPlaceables = subcompose(DragDownContent.TextFields) {
textFields(constraints.maxHeight)
}.map { it.measure(constraints.offset(offset)) }
val textFieldsHeight = textFieldPlaceables.maxByOrNull { it.height }?.height ?: 0
val historyListPlaceables = subcompose(DragDownContent.HistoryList) {
historyList()
}.map {
it.measure(
constraints.copy(
maxHeight = drag.coerceAtMost(constraints.maxHeight - textFieldsHeight)
)
)
}
val padding = if (showHistory) drag.coerceAtLeast(0) else historyItemHeight
val numPadConstraints = constraints
.offset(offset)
.copy(maxHeight = constraints.maxHeight - textFieldsHeight - padding)
val numPadPlaceables = subcompose(DragDownContent.NumPad, numPad).map {
it.measure(numPadConstraints)
}
layout(constraints.maxWidth, constraints.maxHeight) {
var yPos = 0
historyListPlaceables.forEach {
it.place(0, yPos)
yPos += it.height
}
textFieldPlaceables.forEach {
it.place(0, yPos)
yPos += it.height
}
numPadPlaceables.forEach {
it.place(0, yPos)
yPos += it.height
}
}
}
}
private enum class DragDownContent { HistoryList, TextFields, NumPad }

View File

@ -0,0 +1,104 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.calculator.components
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import com.sadellie.unitto.core.ui.theme.NumbersTextStyleDisplayMedium
import com.sadellie.unitto.data.model.HistoryItem
import java.text.SimpleDateFormat
import java.util.*
@Composable
internal fun HistoryList(
modifier: Modifier,
historyItems: List<HistoryItem>,
historyItemHeightCallback: (Int) -> Unit
) {
LazyColumn(
modifier = modifier,
reverseLayout = true
) {
items(historyItems) { historyItem ->
Column(
Modifier.onPlaced { historyItemHeightCallback(it.size.height) }
) {
Text(
text = historyItem.expression,
maxLines = 1,
modifier = Modifier
.fillMaxWidth()
.horizontalScroll(rememberScrollState(), reverseScrolling = true),
style = NumbersTextStyleDisplayMedium,
textAlign = TextAlign.End
)
Text(
text = historyItem.result,
maxLines = 1,
modifier = Modifier
.fillMaxWidth()
.horizontalScroll(rememberScrollState(), reverseScrolling = true),
style = NumbersTextStyleDisplayMedium,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.5f),
textAlign = TextAlign.End
)
}
}
}
}
@Preview
@Composable
private fun PreviewHistoryList() {
val dtf = SimpleDateFormat("dd.MM.yyyy HH:mm:ss", Locale.getDefault())
val historyItems = listOf(
"13.06.1989 23:59:15",
"13.06.1989 23:59:16",
"13.06.1989 23:59:17",
"14.06.1989 23:59:17",
"14.06.1989 23:59:18",
"14.07.1989 23:59:18",
"14.07.1989 23:59:19",
"14.07.2005 23:59:19",
).map {
HistoryItem(
date = dtf.parse(it)!!,
expression = "12345".repeat(10),
result = "67890"
)
}
HistoryList(
modifier = Modifier.fillMaxWidth(),
historyItems = historyItems,
historyItemHeightCallback = {}
)
}

View File

@ -41,7 +41,9 @@ dependencies {
implementation(libs.com.squareup.moshi)
implementation(libs.com.squareup.retrofit2)
implementation(project(mapOf("path" to ":data:common")))
implementation(project(mapOf("path" to ":data:database")))
implementation(project(mapOf("path" to ":data:model")))
implementation(project(mapOf("path" to ":data:userprefs")))
implementation(project(mapOf("path" to ":data:unitgroups")))
implementation(project(mapOf("path" to ":data:units")))
}

View File

@ -19,7 +19,7 @@
package com.sadellie.unitto.feature.converter
import com.sadellie.unitto.core.base.KEY_0
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.model.AbstractUnit
/**
* Represents current state of the ConverterScreen

View File

@ -43,19 +43,20 @@ import com.sadellie.unitto.core.base.KEY_PLUS
import com.sadellie.unitto.core.base.KEY_RIGHT_BRACKET
import com.sadellie.unitto.core.base.KEY_SQRT
import com.sadellie.unitto.core.base.OPERATORS
import com.sadellie.unitto.data.combine
import com.sadellie.unitto.data.setMinimumRequiredScale
import com.sadellie.unitto.data.toStringWith
import com.sadellie.unitto.data.trimZeros
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.common.setMinimumRequiredScale
import com.sadellie.unitto.data.common.toStringWith
import com.sadellie.unitto.data.common.trimZeros
import com.sadellie.unitto.data.database.UnitsEntity
import com.sadellie.unitto.data.database.UnitsRepository
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.NumberBaseUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.AllUnitsRepository
import com.sadellie.unitto.data.units.MyUnitIDS
import com.sadellie.unitto.data.units.NumberBaseUnit
import com.sadellie.unitto.data.units.database.MyBasedUnit
import com.sadellie.unitto.data.units.database.MyBasedUnitsRepository
import com.sadellie.unitto.data.units.combine
import com.sadellie.unitto.data.units.remote.CurrencyApi
import com.sadellie.unitto.data.units.remote.CurrencyUnitResponse
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
@ -77,8 +78,8 @@ import javax.inject.Inject
@HiltViewModel
class ConverterViewModel @Inject constructor(
private val userPrefsRepository: com.sadellie.unitto.data.userprefs.UserPreferencesRepository,
private val basedUnitRepository: MyBasedUnitsRepository,
private val userPrefsRepository: UserPreferencesRepository,
private val unitRepository: UnitsRepository,
private val allUnitsRepository: AllUnitsRepository
) : ViewModel() {
@ -501,8 +502,8 @@ class ConverterViewModel @Inject constructor(
private fun incrementCounter(unit: AbstractUnit) {
viewModelScope.launch(Dispatchers.IO) {
basedUnitRepository.insertUnits(
MyBasedUnit(
unitRepository.insertUnits(
UnitsEntity(
unitId = unit.unitId,
isFavorite = unit.isFavorite,
pairedUnitId = unit.pairedUnit,
@ -515,8 +516,8 @@ class ConverterViewModel @Inject constructor(
private fun updatePairedUnit(unit: AbstractUnit) {
viewModelScope.launch(Dispatchers.IO) {
basedUnitRepository.insertUnits(
MyBasedUnit(
unitRepository.insertUnits(
UnitsEntity(
unitId = unit.unitId,
isFavorite = unit.isFavorite,
pairedUnitId = unit.pairedUnit,

View File

@ -42,8 +42,8 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.sadellie.unitto.core.ui.Formatter
import com.sadellie.unitto.core.ui.R
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.feature.converter.ConverterMode
/**

View File

@ -40,8 +40,8 @@ import com.sadellie.unitto.core.base.KEY_PLUS
import com.sadellie.unitto.core.base.KEY_RIGHT_BRACKET
import com.sadellie.unitto.core.base.KEY_SQRT
import com.sadellie.unitto.data.units.AllUnitsRepository
import com.sadellie.unitto.data.units.database.MyBasedUnitDatabase
import com.sadellie.unitto.data.units.database.MyBasedUnitsRepository
import com.sadellie.unitto.data.database.UnittoDatabase
import com.sadellie.unitto.data.database.UnitsRepository
import com.sadellie.unitto.data.userprefs.DataStoreModule
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import junit.framework.TestCase.assertEquals
@ -72,7 +72,7 @@ class ConverterViewModelTest {
private val allUnitsRepository = AllUnitsRepository()
private val database = Room.inMemoryDatabaseBuilder(
RuntimeEnvironment.getApplication(),
MyBasedUnitDatabase::class.java
UnittoDatabase::class.java
).build()
@Before
@ -84,8 +84,8 @@ class ConverterViewModelTest {
RuntimeEnvironment.getApplication()
)
),
basedUnitRepository = MyBasedUnitsRepository(
database.myBasedUnitDao()
unitRepository = UnitsRepository(
database.unitsDao()
),
allUnitsRepository = allUnitsRepository
)

View File

@ -31,7 +31,8 @@ dependencies {
implementation(libs.com.github.sadellie.themmo)
implementation(libs.org.burnoutcrew.composereorderable)
implementation(project(mapOf("path" to ":data:model")))
implementation(project(mapOf("path" to ":data:unitgroups")))
implementation(project(mapOf("path" to ":data:userprefs")))
implementation(project(mapOf("path" to ":data:licenses")))
implementation(project(mapOf("path" to ":data:unitgroups")))
}

View File

@ -21,7 +21,7 @@ package com.sadellie.unitto.feature.settings
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.core.ui.Formatter
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.unitgroups.UnitGroupsRepository
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel

View File

@ -28,6 +28,8 @@ android {
}
dependencies {
implementation(project(mapOf("path" to ":data:model")))
implementation(project(mapOf("path" to ":data:units")))
implementation(project(mapOf("path" to ":data:database")))
implementation(project(mapOf("path" to ":data:unitgroups")))
}

View File

@ -45,7 +45,7 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.feature.unitslist.components.ChipsRow
import com.sadellie.unitto.feature.unitslist.components.SearchBar
import com.sadellie.unitto.feature.unitslist.components.SearchPlaceholder

View File

@ -33,9 +33,9 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sadellie.unitto.core.ui.Formatter
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.units.NumberBaseUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.NumberBaseUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.feature.unitslist.components.SearchBar
import com.sadellie.unitto.feature.unitslist.components.SearchPlaceholder
import com.sadellie.unitto.feature.unitslist.components.UnitGroupHeader

View File

@ -18,8 +18,8 @@
package com.sadellie.unitto.feature.unitslist
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.UnitGroup
/**
* Second (unit list) screen UI state.

View File

@ -21,11 +21,11 @@ package com.sadellie.unitto.feature.unitslist
import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.database.UnitsEntity
import com.sadellie.unitto.data.database.UnitsRepository
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.AllUnitsRepository
import com.sadellie.unitto.data.units.database.MyBasedUnit
import com.sadellie.unitto.data.units.database.MyBasedUnitsRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
@ -39,7 +39,7 @@ import javax.inject.Inject
@HiltViewModel
class SecondViewModel @Inject constructor(
private val basedUnitRepository: MyBasedUnitsRepository,
private val unitRepository: UnitsRepository,
private val allUnitsRepository: AllUnitsRepository,
private val mContext: Application,
unitGroupsRepository: com.sadellie.unitto.data.unitgroups.UnitGroupsRepository,
@ -136,8 +136,8 @@ class SecondViewModel @Inject constructor(
// Changing unit in list to the opposite
unit.isFavorite = !unit.isFavorite
// Updating it in database
basedUnitRepository.insertUnits(
MyBasedUnit(
unitRepository.insertUnits(
UnitsEntity(
unitId = unit.unitId,
isFavorite = unit.isFavorite,
pairedUnitId = unit.pairedUnit,
@ -147,15 +147,15 @@ class SecondViewModel @Inject constructor(
}
}
private fun loadBasedUnits() {
private fun loadUnits() {
viewModelScope.launch(Dispatchers.IO) {
// Now we load units data from database
val allBasedUnits = basedUnitRepository.getAll()
allUnitsRepository.loadFromDatabase(mContext, allBasedUnits)
val allUnits = unitRepository.getAll()
allUnitsRepository.loadFromDatabase(mContext, allUnits)
}
}
init {
loadBasedUnits()
loadUnits()
}
}

View File

@ -46,8 +46,8 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.sadellie.unitto.data.unitgroups.ALL_UNIT_GROUPS
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.feature.unitslist.R
/**

View File

@ -24,7 +24,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.sadellie.unitto.core.ui.common.Header
import com.sadellie.unitto.data.unitgroups.UnitGroup
import com.sadellie.unitto.data.model.UnitGroup
@Composable
internal fun UnitGroupHeader(modifier: Modifier, unitGroup: UnitGroup) {

View File

@ -53,7 +53,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.feature.unitslist.R
/**

View File

@ -21,7 +21,7 @@ package com.sadellie.unitto.feature.unitslist.navigation
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import com.sadellie.unitto.data.units.AbstractUnit
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.units.AllUnitsRepository
import com.sadellie.unitto.feature.unitslist.LeftSideScreen
import com.sadellie.unitto.feature.unitslist.RightSideScreen

View File

@ -30,3 +30,7 @@ include(":data:userprefs")
include(":data:unitgroups")
include(":data:licenses")
include(":data:epoch")
include(":data:calculator")
include(":data:database")
include(":data:model")
include(":data:common")