Fix some migration issues

* Fix getting wrong AccountType from db

* Add credentials migration from old shared preferences to encrypted preferences
This commit is contained in:
Shinokuni 2024-08-29 17:45:58 +02:00
parent 420cd1d9d1
commit ee931abc17
9 changed files with 90 additions and 18 deletions

View File

@ -12,8 +12,8 @@ android {
defaultConfig {
applicationId = "com.readrops.app"
versionCode = 15
versionName = "2.0-beta01"
versionCode = 16
versionName = "2.0-beta02"
}
buildTypes {
@ -68,6 +68,7 @@ dependencies {
implementation(libs.datastore)
implementation(libs.browser)
implementation(libs.splashscreen)
implementation(libs.preferences)
implementation(libs.jsoup)

View File

@ -17,6 +17,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.toArgb
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import cafe.adriel.voyager.core.annotation.ExperimentalVoyagerApi
import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.navigator.NavigatorDisposeBehavior
@ -26,6 +27,7 @@ import com.readrops.app.account.selection.AccountSelectionScreenModel
import com.readrops.app.home.HomeScreen
import com.readrops.app.sync.SyncWorker
import com.readrops.app.timelime.TimelineTab
import com.readrops.app.util.Migrations
import com.readrops.app.util.Preferences
import com.readrops.app.util.theme.ReadropsTheme
import com.readrops.db.Database
@ -46,6 +48,15 @@ class MainActivity : ComponentActivity(), KoinComponent {
installSplashScreen()
super.onCreate(savedInstanceState)
runBlocking {
Migrations.upgrade(
appPreferences = get(),
encryptedPreferences = get(),
oldPreferences = PreferenceManager.getDefaultSharedPreferences(this@MainActivity),
database = get(),
)
}
val screenModel = get<AccountSelectionScreenModel>()
val accountExists = screenModel.accountExists()

View File

@ -6,8 +6,8 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.readrops.app.R
import com.readrops.app.util.components.dialog.BaseDialog
import com.readrops.app.util.components.SelectableImageText
import com.readrops.app.util.components.dialog.BaseDialog
import com.readrops.app.util.theme.spacing
import com.readrops.db.entities.account.AccountType
@ -21,16 +21,18 @@ fun AccountSelectionDialog(
icon = painterResource(id = R.drawable.ic_add_account),
onDismiss = onDismiss
) {
AccountType.entries.forEach { type ->
SelectableImageText(
image = adaptiveIconPainterResource(id = type.iconRes),
text = stringResource(id = type.typeName),
style = MaterialTheme.typography.titleMedium,
spacing = MaterialTheme.spacing.mediumSpacing,
padding = MaterialTheme.spacing.shortSpacing,
imageSize = 36.dp,
onClick = { onValidate(type) }
)
}
AccountType.entries
.filter { it != AccountType.FEEDLY }
.forEach { type ->
SelectableImageText(
image = adaptiveIconPainterResource(id = type.iconRes),
text = stringResource(id = type.typeName),
style = MaterialTheme.typography.titleMedium,
spacing = MaterialTheme.spacing.mediumSpacing,
padding = MaterialTheme.spacing.shortSpacing,
imageSize = 36.dp,
onClick = { onValidate(type) }
)
}
}
}

View File

@ -185,7 +185,9 @@ class AccountSelectionScreen : AndroidScreen() {
modifier = Modifier.padding(start = MaterialTheme.spacing.mediumSpacing)
)
AccountType.entries.filter { it != AccountType.LOCAL }
AccountType.entries
.filter { it != AccountType.LOCAL }
.filter { it != AccountType.FEEDLY }
.forEach { accountType ->
SelectableImageText(
image = adaptiveIconPainterResource(id = accountType.iconRes),
@ -197,8 +199,6 @@ class AccountSelectionScreen : AndroidScreen() {
onClick = { screenModel.createAccount(accountType) }
)
}
}
}
}

View File

@ -0,0 +1,48 @@
package com.readrops.app.util
import android.content.SharedPreferences
import com.readrops.app.BuildConfig
import com.readrops.db.Database
import kotlinx.coroutines.flow.first
object Migrations {
suspend fun upgrade(
appPreferences: Preferences,
encryptedPreferences: SharedPreferences,
oldPreferences: SharedPreferences,
database: Database
) {
val lastVersionCode = appPreferences.lastVersionCode.flow
.first()
// 2.0-beta02
if (lastVersionCode < 16) {
val accounts = database.accountDao().selectAllAccounts().first()
for (account in accounts) {
oldPreferences.getString(account.loginKey, null)?.run {
encryptedPreferences.edit()
.putString(account.loginKey, this)
.apply()
oldPreferences.edit()
.remove(account.loginKey)
.apply()
}
oldPreferences.getString(account.passwordKey, null)?.run {
encryptedPreferences.edit()
.putString(account.password, this)
.apply()
oldPreferences.edit()
.remove(account.passwordKey)
.apply()
}
}
}
appPreferences.lastVersionCode.write(BuildConfig.VERSION_CODE)
}
}

View File

@ -4,6 +4,7 @@ import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
@ -66,6 +67,12 @@ class Preferences(
key = booleanPreferencesKey("display_notification_permission"),
default = true
)
val lastVersionCode = Preference(
dataStore = dataStore,
key = intPreferencesKey("last_version_code"),
default = 0
)
}

View File

@ -4,12 +4,13 @@ import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import com.readrops.db.R
// TODO comment Feedly
enum class AccountType(@DrawableRes val iconRes: Int,
@StringRes val typeName: Int,
val accountConfig: AccountConfig?) {
LOCAL(R.mipmap.ic_launcher, R.string.local_account, AccountConfig.LOCAL),
NEXTCLOUD_NEWS(R.drawable.ic_nextcloud_news, R.string.nextcloud_news, AccountConfig.NEXTCLOUD_NEWS),
//FEEDLY(R.drawable.ic_feedly, R.string.feedly, null),
FEEDLY(R.drawable.ic_feedly, R.string.feedly, null),
FRESHRSS(R.drawable.ic_freshrss, R.string.freshrss, AccountConfig.FRESHRSS),
FEVER(R.drawable.ic_fever, R.string.fever, AccountConfig.FEVER)
}

View File

@ -16,6 +16,7 @@ class Converters {
return localDateTime.toInstant(DateUtils.defaultOffset).toEpochMilli()
}
// TODO Use Room built-in enum converter, ordinal is not reliable
@TypeConverter
fun fromAccountTypeCode(ordinal: Int): AccountType {
return AccountType.entries[ordinal]

View File

@ -97,6 +97,7 @@ encrypted-preferences = "androidx.security:security-crypto:1.1.0-alpha06"
datastore = "androidx.datastore:datastore-preferences:1.1.1"
browser = "androidx.browser:browser:1.8.0"
splashscreen = "androidx.core:core-splashscreen:1.0.1"
preferences = "androidx.preference:preference-ktx:1.2.1"
# test
junit4 = "junit:junit:4.13.2"