Skip to content

Commit

Permalink
Merge pull request #26 from NielsLee/dev
Browse files Browse the repository at this point in the history
Publish v1.6
  • Loading branch information
NielsLee authored Jul 30, 2024
2 parents 01d42e4 + 80835ac commit 315b51e
Show file tree
Hide file tree
Showing 25 changed files with 493 additions and 169 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ android {
applicationId "lying.fengfeng.foodrecords"
minSdk 26
targetSdk 34
versionCode 6
versionName "1.5"
versionCode 7
versionName "1.6"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
4 changes: 2 additions & 2 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 2,
"versionName": "1.1",
"versionCode": 7,
"versionName": "1.6",
"outputFile": "app-release.apk"
}
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "2353f822fae49423025f80357796df97",
"entities": [
{
"tableName": "FoodInfo",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`foodName` TEXT NOT NULL, `productionDate` TEXT NOT NULL, `foodType` TEXT NOT NULL, `shelfLife` TEXT NOT NULL, `expirationDate` TEXT NOT NULL, `uuid` TEXT NOT NULL, `tips` TEXT NOT NULL, PRIMARY KEY(`uuid`))",
"fields": [
{
"fieldPath": "foodName",
"columnName": "foodName",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "productionDate",
"columnName": "productionDate",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "foodType",
"columnName": "foodType",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "shelfLife",
"columnName": "shelfLife",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "expirationDate",
"columnName": "expirationDate",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "uuid",
"columnName": "uuid",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "tips",
"columnName": "tips",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"uuid"
]
},
"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, '2353f822fae49423025f80357796df97')"
]
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
package lying.fengfeng.foodrecords

import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase
import android.util.Log
import androidx.room.migration.Migration
import androidx.room.testing.MigrationTestHelper
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.SupportSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQueryBuilder
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import lying.fengfeng.foodrecords.repository.AppRepo
import lying.fengfeng.foodrecords.repository.FoodInfoDatabase
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Locale

@RunWith(AndroidJUnit4::class)
class MigrationTest {
Expand Down Expand Up @@ -45,4 +53,53 @@ class MigrationTest {
// MigrationTestHelper automatically verifies the schema changes,
// but you need to validate that the data was migrated properly.
}

@Test
@Throws(IOException::class)
fun migrate2To3() {
var db = helper.createDatabase("FoodInfoDatabase", 2).apply {

val contentValues = ContentValues().apply {
put("foodName", "FoodName")
put("productionDate", "24-07-30")
put("foodType", "Test")
put("shelfLife", "5")
put("expirationDate", "--")
put("uuid", "uuid-test")
put("tips", "")
}

insert("FoodInfo", SQLiteDatabase. CONFLICT_REPLACE, contentValues)
close()
}

val MIGRATION_2_3 = object : Migration(2, 3) {
override fun migrate(db: SupportSQLiteDatabase) {

val cursor = db.query("SELECT uuid, productionDate, expirationDate FROM FoodInfo",
emptyArray())
if (cursor.moveToFirst()) {
do {
val uuid = cursor.getString(cursor.getColumnIndex("uuid"))
val productionDate = cursor.getString(cursor.getColumnIndex("productionDate"))
val expirationDate = cursor.getString(cursor.getColumnIndex("expirationDate"))

val dateFormatter = SimpleDateFormat("yy-MM-dd", Locale.getDefault())
val productionDateTimestamp = dateFormatter.parse(productionDate)?.time ?: 0
val expirationDateTimestamp = if (expirationDate == "--") 0 else dateFormatter.parse(expirationDate)?.time ?: 0
val updateQuery = "UPDATE FoodInfo SET productionDate = ?, expirationDate = ? " +
"WHERE uuid = ?"

db.execSQL(updateQuery, arrayOf(productionDateTimestamp, expirationDateTimestamp,
uuid))

} while (cursor.moveToNext())
}
cursor.close()

}
}

db = helper.runMigrationsAndValidate("FoodInfoDatabase", 3, true, MIGRATION_2_3)
}
}
2 changes: 1 addition & 1 deletion app/src/main/java/lying/fengfeng/foodrecords/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ object Constants {
const val DB_NAME_FOOD_INFO = "FoodInfoDatabase"
const val DB_NAME_FOOD_TYPE_INFO = "FoodTypeInfoDatabase"
const val DB_NAME_SHELF_LIFE_INFO = "ShelfLifeInfoDatabase"
const val FOOD_INFO_DB_VERSION = 2
const val FOOD_INFO_DB_VERSION = 3
const val FOOD_TYPE_DB_VERSION = 1
const val SHELF_LIFE_DB_VERSION = 1
}
37 changes: 37 additions & 0 deletions app/src/main/java/lying/fengfeng/foodrecords/repository/AppRepo.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package lying.fengfeng.foodrecords.repository

import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import android.content.SharedPreferences
Expand All @@ -17,6 +18,8 @@ import lying.fengfeng.foodrecords.R
import lying.fengfeng.foodrecords.entities.FoodInfo
import lying.fengfeng.foodrecords.entities.FoodTypeInfo
import lying.fengfeng.foodrecords.entities.ShelfLifeInfo
import java.text.SimpleDateFormat
import java.util.Locale

object AppRepo {

Expand All @@ -38,6 +41,31 @@ object AppRepo {
db.execSQL("ALTER TABLE FoodInfo ADD COLUMN tips TEXT NOT NULL DEFAULT '' ")
}
}
private val MIGRATION_2_3 = object : Migration(2, 3) {
@SuppressLint("Range")
override fun migrate(db: SupportSQLiteDatabase) {
val cursor = db.query("SELECT uuid, productionDate, expirationDate FROM FoodInfo",
emptyArray())
if (cursor.moveToFirst()) {
do {
val uuid = cursor.getString(cursor.getColumnIndex("uuid"))
val productionDate = cursor.getString(cursor.getColumnIndex("productionDate"))
val expirationDate = cursor.getString(cursor.getColumnIndex("expirationDate"))

val dateFormatter = SimpleDateFormat("yy-MM-dd", Locale.getDefault())
val productionDateTimestamp = dateFormatter.parse(productionDate)?.time ?: 0
val expirationDateTimestamp = if (expirationDate == "--") 0 else dateFormatter.parse(expirationDate)?.time ?: 0
val updateQuery = "UPDATE FoodInfo SET productionDate = ?, expirationDate = ? " +
"WHERE uuid = ?"

db.execSQL(updateQuery, arrayOf(productionDateTimestamp, expirationDateTimestamp,
uuid))

} while (cursor.moveToNext())
}
cursor.close()
}
}

fun init(application: Application) {

Expand All @@ -46,6 +74,7 @@ object AppRepo {

foodInfoDB = Room.databaseBuilder(app, FoodInfoDatabase::class.java, DB_NAME_FOOD_INFO)
.addMigrations(MIGRATION_1_2)
.addMigrations(MIGRATION_2_3)
.build()
foodInfoDao = foodInfoDB.foodInfoDao()

Expand Down Expand Up @@ -134,6 +163,14 @@ object AppRepo {
return sp.getLong("next_notification_time", -1)
}

fun setDateFormat(format: String) {
sp.edit().putString("date_format", format).apply()
}

fun getDateFormat(): String {
return sp.getString("date_format", "yy-MM-dd") ?: "yy-MM-dd"
}

private fun addInitializedData() {
CoroutineScope(Dispatchers.IO).launch {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.content.pm.PackageManager
import android.os.Build
import android.widget.Toast
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.app.ActivityCompat
Expand All @@ -31,7 +32,8 @@ class FoodRecordsAppViewModel: ViewModel() {
var foodTypeList = mutableStateListOf<FoodTypeInfo>()
var shelfLifeList = mutableStateListOf<ShelfLifeInfo>()
var isNotificationEnabled = mutableStateOf(false)
var daysBeforeNotification = mutableStateOf(AppRepo.getDaysBeforeNotification())
var daysBeforeNotification = mutableIntStateOf(AppRepo.getDaysBeforeNotification())
var dateFormat = mutableStateOf(AppRepo.getDateFormat())

init {
CoroutineScope(Dispatchers.Main).launch {
Expand Down Expand Up @@ -109,6 +111,11 @@ class FoodRecordsAppViewModel: ViewModel() {
AppRepo.removeShelfLifeInfo(shelfLifeInfo)
}

fun updateDaysBeforeNotification(days: Int) {
daysBeforeNotification.value = days
AppRepo.setDaysBeforeNotification(days)
}

fun enableNotification(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS)
Expand All @@ -130,9 +137,9 @@ class FoodRecordsAppViewModel: ViewModel() {
}
}

fun updateDaysBeforeNotification(days: Int) {
daysBeforeNotification.value = days
AppRepo.setDaysBeforeNotification(days)
fun updateDateFormat(dateFormat: String) {
this.dateFormat.value = dateFormat
AppRepo.setDateFormat(dateFormat)
}

private fun scheduleNotifications(context: Context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import lying.fengfeng.foodrecords.MainActivity
import lying.fengfeng.foodrecords.R
import lying.fengfeng.foodrecords.repository.AppRepo
import lying.fengfeng.foodrecords.utils.EffectUtil
import java.text.SimpleDateFormat
import java.util.Date
Expand Down Expand Up @@ -186,6 +187,6 @@ fun FoodRecordsBottomBar(
}

private fun getCurrentDate(): String {
val dateFormat = SimpleDateFormat("yy-MM-dd", Locale.getDefault())
val dateFormat = SimpleDateFormat(AppRepo.getDateFormat(), Locale.getDefault())
return dateFormat.format(Date())
}
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ fun RemainingDaysWindow(
.fillMaxWidth(),
contentAlignment = Alignment.Center
) {
val fontSize = 36.sp
val fontSize = 32.sp

val (remainingTitleColor, remainingTitleText) = if (remainingDays > 0) {
ExpiredGreen to context.getString(R.string.valid_in)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ import androidx.compose.material3.TextButton
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand All @@ -76,6 +74,7 @@ import com.ujizin.camposer.state.rememberCameraState
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import lying.fengfeng.foodrecords.R
import lying.fengfeng.foodrecords.repository.AppRepo
import lying.fengfeng.foodrecords.ui.FoodRecordsAppViewModel
import lying.fengfeng.foodrecords.ui.LocalScreenParams
import lying.fengfeng.foodrecords.utils.DateUtil.dateWithFormat
Expand Down Expand Up @@ -132,7 +131,9 @@ fun InsertionDialog() {
dismissOnClickOutside = false
),
) {
Column {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Card(
shape = RoundedCornerShape(12.dp),
elevation = CardDefaults.cardElevation(4.dp),
Expand Down Expand Up @@ -285,10 +286,10 @@ fun InsertionDialog() {
datePickerState.selectedDateMillis?.also {
if (isExpireDate) {
expirationDate =
dateWithFormat(it, "YY-MM-dd")
dateWithFormat(it, AppRepo.getDateFormat())
} else {
productionDate =
dateWithFormat(it, "YY-MM-dd")
dateWithFormat(it, AppRepo.getDateFormat())
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class InsertionDialogViewModel : ViewModel() {
var productionDate: MutableState<String> = mutableStateOf(
DateUtil.dateWithFormat(
DateUtil.todayMillis(),
"YY-MM-dd"
AppRepo.getDateFormat()
)
)

Expand All @@ -31,11 +31,11 @@ class InsertionDialogViewModel : ViewModel() {
var uuid: MutableState<String> = mutableStateOf("")
var tips: MutableState<String> = mutableStateOf("")

init {
// initParams()
}

fun refreshParams() {
productionDate.value = DateUtil.dateWithFormat(
DateUtil.todayMillis(),
AppRepo.getDateFormat()
)
CoroutineScope(Dispatchers.IO).launch {
foodTypes = AppRepo.getAllTypeInfo().map { it.type }
shelfLifeList = AppRepo.getAllShelfLifeInfo().map { it.life }
Expand All @@ -62,7 +62,7 @@ class InsertionDialogViewModel : ViewModel() {
productionDate = mutableStateOf(
DateUtil.dateWithFormat(
DateUtil.todayMillis(),
"YY-MM-dd"
AppRepo.getDateFormat()
)
)
expirationDate = mutableStateOf("")
Expand Down
Loading

0 comments on commit 315b51e

Please sign in to comment.