Skip to content

Commit

Permalink
Include new module for preferences (Shared and DataStore)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeluchu committed Jul 8, 2023
1 parent af4cc87 commit 9cdb99d
Show file tree
Hide file tree
Showing 15 changed files with 304 additions and 8 deletions.
17 changes: 16 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ org-jetbrains-kotlinx = "1.7.2"
billing-ktx = "6.0.1"

[libraries]
androidx-datastore = "androidx.datastore:datastore-preferences:1.0.0"
androidx-activity-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
androidx-browser = "androidx.browser:browser:1.5.0"
androidx-compose-animation = { module = "androidx.compose.animation:animation", version.ref = "androidx-compose-animation" }
Expand All @@ -30,6 +31,7 @@ androidx-compose-ui-ui-tooling = { module = "androidx.compose.ui:ui-tooling", ve
androidx-compose-ui-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "androidx-compose-ui" }
androidx-core-core-ktx = "androidx.core:core-ktx:1.10.1"
androidx-core-core-splashscreen = "androidx.core:core-splashscreen:1.0.1"
androidx-lifecycle-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
androidx-lifecycle-lifecycle-livedata-core-ktx = { module = "androidx.lifecycle:lifecycle-livedata-core-ktx", version.ref = "androidx-lifecycle" }
androidx-lifecycle-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }
androidx-navigation-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "androidx-navigation" }
Expand Down Expand Up @@ -72,7 +74,6 @@ core-squareup = [
ktx-androidx = [
"androidx-browser",
"androidx-navigation-navigation-compose",
"androidx-preference",
]
# FOR JCHUCOMPONENTS KTX
ktx-google = [
Expand Down Expand Up @@ -117,4 +118,18 @@ pay-android = [
pay-jetbrains = [
"org-jetbrains-kotlinx-kotlinx-coroutines-android",
"org-jetbrains-kotlinx-kotlinx-coroutines-core",
]

# FOR JCHUCOMPONENTS PREFERENCES
preferences-androidx = [
"androidx-datastore",
"androidx-preference",
"androidx-lifecycle-lifecycle-runtime-compose",
]
preferences-google = [
"com-google-code-gson",
]
preferences-compose = [
"androidx-compose-runtime",
"androidx-compose-ui",
]
2 changes: 1 addition & 1 deletion jchucomponents-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ afterEvaluate {
from components.release
groupId = "com.github.jeluchu"
artifactId = "jchucomponents-core"
version = "1.6.0"
version = "1.7.0"
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion jchucomponents-ktx/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ afterEvaluate {
from components.release
groupId = "com.github.jeluchu"
artifactId = "jchucomponents-ktx"
version = "1.6.0"
version = "1.7.0"
}
}
}
Expand Down
1 change: 1 addition & 0 deletions jchucomponents-prefs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
67 changes: 67 additions & 0 deletions jchucomponents-prefs/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'maven-publish'
id 'org.jetbrains.dokka'
}

android {

compileSdkVersion 33
buildToolsVersion "30.0.3"

defaultConfig {
minSdkVersion 21
targetSdkVersion 33
consumerProguardFiles "consumer-rules.pro"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

kotlinOptions.jvmTarget = JavaVersion.VERSION_17.toString()
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}

dokkaHtml.configure {

outputDirectory.set(file("../docs"))
moduleName.set("$rootProject.name")
suppressInheritedMembers.set(true)
pluginsMapConfiguration.set(
[
"org.jetbrains.dokka.base.DokkaBase": """{
"footerMessage": "Made with ❤️ at <b><a href=\\"https://about.jeluchu.com\\">Jéluchu</a></b> © 2022",
"customStyleSheets": ["${file("../logo-style.css")}"]
}"""
]
)
}

namespace 'com.jeluchu.jchucomponents.qr'
}

dependencies {
implementation libs.bundles.preferences.androidx
implementation libs.bundles.preferences.google
implementation libs.bundles.preferences.compose
}

afterEvaluate {
publishing {
publications {
release(MavenPublication) {
from components.release
groupId = "com.github.jeluchu"
artifactId = "jchucomponents-preferences"
version = "1.7.0"
}
}
}
}
Empty file.
21 changes: 21 additions & 0 deletions jchucomponents-prefs/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 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
4 changes: 4 additions & 0 deletions jchucomponents-prefs/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package com.jeluchu.prefs.datastore

import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.preferencesDataStore
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.jeluchu.prefs.extensions.empty
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

class DataStoreHelpers {
fun <T> savePreference(key: Preferences.Key<T>, value: T) {
CoroutineScope(Dispatchers.IO).launch {
dataStore?.edit { preferences ->
preferences[key] = value
}
}
}

fun savePreference(key: Preferences.Key<Int>, value: Int) {
CoroutineScope(Dispatchers.IO).launch {
dataStore?.edit { preferences ->
preferences[key] = value
}
}
}

fun savePreference(key: Preferences.Key<Long>, value: Long) {
CoroutineScope(Dispatchers.IO).launch {
dataStore?.edit { preferences ->
preferences[key] = value
}
}
}

fun savePreference(key: Preferences.Key<Float>, value: Float) {
CoroutineScope(Dispatchers.IO).launch {
dataStore?.edit { preferences ->
preferences[key] = value
}
}
}

fun savePreference(key: Preferences.Key<String>, value: String) {
CoroutineScope(Dispatchers.IO).launch {
dataStore?.edit { preferences ->
preferences[key] = value
}
}
}

fun savePreference(key: Preferences.Key<Boolean>, value: Boolean) {
CoroutineScope(Dispatchers.IO).launch {
dataStore?.edit { preferences ->
preferences[key] = value
}
}
}

fun <T> getPreference(
key: Preferences.Key<T>
) = runBlocking {
dataStore?.data?.first()?.toPreferences()?.get(key)
}

fun getPreference(
key: Preferences.Key<Int>,
default: Int = Int.empty()
) = runBlocking {
dataStore?.data?.first()?.toPreferences()?.get(key) ?: default
}

fun getPreference(
key: Preferences.Key<Long>,
default: Long = Long.empty()
) = runBlocking {
dataStore?.data?.first()?.toPreferences()?.get(key) ?: default
}

fun getPreference(
key: Preferences.Key<Float>,
default: Float = Float.empty()
) = runBlocking {
dataStore?.data?.first()?.toPreferences()?.get(key) ?: default
}

fun getPreference(
key: Preferences.Key<String>,
default: String = String.empty()
) = runBlocking {
dataStore?.data?.first()?.toPreferences()?.get(key) ?: default
}

fun getPreference(
key: Preferences.Key<Boolean>,
default: Boolean = false
) = runBlocking {
dataStore?.data?.first()?.toPreferences()?.get(key) ?: default
}

companion object {
var dataStore: DataStore<Preferences>? = null
val Context.defaultPreferencesDataStore by preferencesDataStore(name = "default")

fun initDataStore(context: Context) {
dataStore = context.defaultPreferencesDataStore
}

fun <T> DataStore<Preferences>.getValueSync(
key: Preferences.Key<T>
) = runBlocking { data.first() }[key]

fun DataStore<Preferences>.getValueSync(
key: Preferences.Key<Int>,
default: Int = Int.empty()
) = runBlocking { data.first() }[key] ?: default

fun DataStore<Preferences>.getValueSync(
key: Preferences.Key<Long>,
default: Long = Long.empty()
) = runBlocking { data.first() }[key] ?: default

fun DataStore<Preferences>.getValueSync(
key: Preferences.Key<Float>,
default: Float = Float.empty()
) = runBlocking { data.first() }[key] ?: default

fun DataStore<Preferences>.getValueSync(
key: Preferences.Key<String>,
default: String = String.empty()
) = runBlocking { data.first() }[key] ?: default

fun DataStore<Preferences>.getValueSync(
key: Preferences.Key<Boolean>,
default: Boolean = false
) = runBlocking { data.first() }[key] ?: default

@Composable
fun <T> rememberPreference(
key: Preferences.Key<T>,
defaultValue: T,
): MutableState<T> {
val coroutineScope = rememberCoroutineScope()
val context = LocalContext.current
val state = remember {
context.defaultPreferencesDataStore.data
.map {
it[key] ?: defaultValue
}
}.collectAsStateWithLifecycle(initialValue = defaultValue)

return remember {
object : MutableState<T> {
override var value: T
get() = state.value
set(value) {
coroutineScope.launch {
context.defaultPreferencesDataStore.edit {
it[key] = value
}
}
}

override fun component1() = value
override fun component2(): (T) -> Unit = { value = it }
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.jeluchu.prefs.extensions

fun Int.Companion.empty() = 0
fun Long.Companion.empty() = 0L
fun Float.Companion.empty() = 0f
fun String.Companion.empty() = ""
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
*
*/

package com.jeluchu.jchucomponents.ktx.sharedprefs
package com.jeluchu.prefs.sharedprefs

class SharedPrefsExceptions(message: String?) : RuntimeException(message)
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
*/

package com.jeluchu.jchucomponents.ktx.sharedprefs
package com.jeluchu.prefs.sharedprefs

import android.content.Context
import android.content.SharedPreferences
Expand Down Expand Up @@ -161,7 +161,7 @@ class SharedPrefsHelpers {
private set
private var mSharedPreferences: SharedPreferences? = null

fun init(context: Context) {
fun initSharedPrefs(context: Context) {
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
}

Expand Down
2 changes: 1 addition & 1 deletion jchucomponents-qr/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ afterEvaluate {
from components.release
groupId = "com.github.jeluchu"
artifactId = "jchucomponents-qr"
version = "1.6.0"
version = "1.7.0"
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion jchucomponents-ui/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ afterEvaluate {
from components.release
groupId = "com.github.jeluchu"
artifactId = "jchucomponents-ui"
version = "1.6.0"
version = "1.7.0"
}
}
}
Expand Down
Loading

0 comments on commit 9cdb99d

Please sign in to comment.