Skip to content

Commit

Permalink
[feature|fix|build] Support remove WebDAV server and account info; fix
Browse files Browse the repository at this point in the history
…#40; update dependencies
  • Loading branch information
SkyD666 committed Oct 31, 2024
1 parent 41cb7ee commit 36ff7c1
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 22 deletions.
26 changes: 13 additions & 13 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ android {
minSdk = 24
targetSdk = 35
versionCode = 67
versionName = "2.3-beta01"
versionName = "2.3-beta02"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down Expand Up @@ -146,16 +146,16 @@ tasks.withType(KotlinCompile::class.java).configureEach {
}

dependencies {
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.compose.ui:ui:1.7.4")
implementation("androidx.compose.material3:material3:1.3.0")
implementation("androidx.compose.material3:material3-window-size-class:1.3.0")
implementation("androidx.compose.material:material:1.7.4")
implementation("androidx.compose.material:material-icons-extended:1.7.4")
implementation("androidx.compose.ui:ui-tooling-preview:1.7.4")
implementation("androidx.core:core-ktx:1.15.0")
implementation("androidx.compose.ui:ui:1.7.5")
implementation("androidx.compose.material3:material3:1.3.1")
implementation("androidx.compose.material3:material3-window-size-class:1.3.1")
implementation("androidx.compose.material:material:1.7.5")
implementation("androidx.compose.material:material-icons-extended:1.7.5")
implementation("androidx.compose.ui:ui-tooling-preview:1.7.5")
implementation("com.google.android.material:material:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.8.6")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.6")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.8.7")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7")
implementation("androidx.activity:activity-compose:1.9.3")
implementation("androidx.palette:palette-ktx:1.0.0")
implementation("com.google.dagger:hilt-android:2.52")
Expand All @@ -176,7 +176,7 @@ dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
implementation("com.materialkolor:material-kolor:2.0.0")
implementation("androidx.datastore:datastore-preferences:1.1.1")
implementation("com.airbnb.android:lottie-compose:6.5.2")
implementation("com.airbnb.android:lottie-compose:6.6.0")

implementation("com.squareup.retrofit2:retrofit:2.11.0")
implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")
Expand All @@ -195,6 +195,6 @@ dependencies {

implementation("com.github.penfeizhou.android.animation:apng:3.0.1")

debugImplementation("androidx.compose.ui:ui-tooling:1.7.4")
debugImplementation("androidx.compose.ui:ui-test-manifest:1.7.4")
debugImplementation("androidx.compose.ui:ui-tooling:1.7.5")
debugImplementation("androidx.compose.ui:ui-test-manifest:1.7.5")
}
5 changes: 3 additions & 2 deletions app/src/main/java/com/skyd/rays/ext/SharedPreferencesExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import android.content.SharedPreferences
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import com.skyd.rays.appContext
import com.skyd.rays.model.AniVuEncryptedSharedPreferences

fun SharedPreferences.editor(editorBuilder: SharedPreferences.Editor.() -> Unit) =
edit().apply(editorBuilder).apply()

fun secretSharedPreferences(name: String = "Secret"): SharedPreferences {
fun secretSharedPreferences(name: String = "Secret"): AniVuEncryptedSharedPreferences {
val masterKey = MasterKey.Builder(appContext)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()

return EncryptedSharedPreferences.create(
return AniVuEncryptedSharedPreferences.create(
appContext,
name,
masterKey,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.skyd.rays.model

import android.content.Context
import android.content.SharedPreferences
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.EncryptedSharedPreferences.PrefKeyEncryptionScheme
import androidx.security.crypto.EncryptedSharedPreferences.PrefValueEncryptionScheme
import androidx.security.crypto.MasterKey
import javax.crypto.AEADBadTagException

class AniVuEncryptedSharedPreferences(
private val encryptedSharedPreferences: EncryptedSharedPreferences,
) : SharedPreferences {

companion object {
fun create(
context: Context,
fileName: String,
masterKey: MasterKey,
prefKeyEncryptionScheme: PrefKeyEncryptionScheme,
prefValueEncryptionScheme: PrefValueEncryptionScheme,
): AniVuEncryptedSharedPreferences {
val creator: () -> EncryptedSharedPreferences = {
EncryptedSharedPreferences.create(
context,
fileName,
masterKey,
prefKeyEncryptionScheme,
prefValueEncryptionScheme
) as EncryptedSharedPreferences
}
return AniVuEncryptedSharedPreferences(
safeBlock(creator)
?: context.deleteSharedPreferences(fileName).run { creator() }
)
}

private fun <T> safeBlock(block: () -> T): T? {
return try {
block()
} catch (e: AEADBadTagException) {
e.printStackTrace()
null
}
}
}

override fun getAll() = safeBlock { encryptedSharedPreferences.all }.orEmpty().toMutableMap()

override fun getString(key: String?, defValue: String?): String? = safeBlock {
encryptedSharedPreferences.getString(key, defValue)
} ?: defValue

override fun getStringSet(
key: String?,
defValues: MutableSet<String>?,
): MutableSet<String>? = safeBlock {
encryptedSharedPreferences.getStringSet(key, defValues)
} ?: defValues

override fun getInt(key: String?, defValue: Int): Int = safeBlock {
encryptedSharedPreferences.getInt(key, defValue)
} ?: defValue

override fun getLong(key: String?, defValue: Long): Long = safeBlock {
encryptedSharedPreferences.getLong(key, defValue)
} ?: defValue

override fun getFloat(key: String?, defValue: Float): Float = safeBlock {
encryptedSharedPreferences.getFloat(key, defValue)
} ?: defValue

override fun getBoolean(key: String?, defValue: Boolean): Boolean = safeBlock {
encryptedSharedPreferences.getBoolean(key, defValue)
} ?: defValue

override fun contains(key: String?): Boolean = safeBlock {
encryptedSharedPreferences.contains(key)
} ?: false

override fun edit(): SharedPreferences.Editor = encryptedSharedPreferences.edit()

override fun registerOnSharedPreferenceChangeListener(
listener: SharedPreferences.OnSharedPreferenceChangeListener,
) = encryptedSharedPreferences.registerOnSharedPreferenceChangeListener(listener)

override fun unregisterOnSharedPreferenceChangeListener(
listener: SharedPreferences.OnSharedPreferenceChangeListener,
) = encryptedSharedPreferences.unregisterOnSharedPreferenceChangeListener(listener)
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ fun TextFieldDialog(
errorText: String = "",
dismissText: String = stringResource(R.string.cancel),
confirmText: String = stringResource(R.string.dialog_ok),
disableConfirmWhenBlank: Boolean = true,
onValueChange: (String) -> Unit = {},
onDismissRequest: () -> Unit = {},
onConfirm: (String) -> Unit = {},
Expand Down Expand Up @@ -64,15 +65,15 @@ fun TextFieldDialog(
},
confirmButton = {
TextButton(
enabled = value.isNotBlank(),
enabled = if (disableConfirmWhenBlank) value.isNotBlank() else true,
onClick = {
focusManager.clearFocus()
onConfirm(value)
}
) {
Text(
text = confirmText,
color = if (value.isNotBlank()) {
color = if (!disableConfirmWhenBlank || value.isNotBlank()) {
Color.Unspecified
} else {
MaterialTheme.colorScheme.outline.copy(alpha = 0.7f)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ import kotlinx.coroutines.launch

const val WEBDAV_SCREEN_ROUTE = "webDavScreen"

private const val WEBDAV_ACCOUNT_KEY = "webDavAccount"
private const val WEBDAV_PASSWORD_KEY = "webDavPassword"

@Composable
fun WebDavScreen(viewModel: WebDavViewModel = hiltViewModel()) {
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Expand Down Expand Up @@ -146,7 +149,11 @@ fun WebDavScreen(viewModel: WebDavViewModel = hiltViewModel()) {
WebDavServerPreference.put(
context = context,
scope = scope,
value = if (!it.endsWith("/")) "$it/" else it
value = if (it.isBlank()) {
WebDavServerPreference.default
} else {
if (it.endsWith("/")) it else "$it/"
}
)
}
inputDialogIsPassword = false
Expand All @@ -156,9 +163,14 @@ fun WebDavScreen(viewModel: WebDavViewModel = hiltViewModel()) {
inputDialogInfo = Triple(
context.getString(R.string.webdav_screen_input_account), account
) {
account = it
openInputDialog = false
secretSharedPreferences().editor { putString("webDavAccount", it) }
if (it.isBlank()) {
account = ""
secretSharedPreferences().editor { remove(WEBDAV_ACCOUNT_KEY) }
} else {
account = it
secretSharedPreferences().editor { putString(WEBDAV_ACCOUNT_KEY, it) }
}
}
inputDialogIsPassword = false
openInputDialog = true
Expand All @@ -167,9 +179,14 @@ fun WebDavScreen(viewModel: WebDavViewModel = hiltViewModel()) {
inputDialogInfo = Triple(
context.getString(R.string.webdav_screen_input_password), password
) {
password = it
openInputDialog = false
secretSharedPreferences().editor { putString("webDavPassword", it) }
if (it.isBlank()) {
password = ""
secretSharedPreferences().editor { remove(WEBDAV_PASSWORD_KEY) }
} else {
password = it
secretSharedPreferences().editor { putString(WEBDAV_PASSWORD_KEY, it) }
}
}
inputDialogIsPassword = true
openInputDialog = true
Expand Down Expand Up @@ -284,6 +301,7 @@ fun WebDavScreen(viewModel: WebDavViewModel = hiltViewModel()) {
isPassword = inputDialogIsPassword,
onDismissRequest = { openInputDialog = false },
onConfirm = inputDialogInfo.third,
disableConfirmWhenBlank = false,
onValueChange = {
inputDialogInfo = inputDialogInfo.copy(second = it)
},
Expand Down

0 comments on commit 36ff7c1

Please sign in to comment.