Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ dependencies {
implementation(Libs.grpc_okhttp)
implementation(Libs.grpc_kotlin)
implementation(Libs.androidx_room_runtime)
implementation(Libs.androidx_room_ktx)
implementation(Libs.androidx_room_rxjava3)
implementation(Libs.okhttp)
implementation(Libs.mixpanel)
Expand Down
3 changes: 3 additions & 0 deletions api/src/main/java/com/getcode/db/PrefBoolDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import androidx.room.Query
import com.getcode.model.PrefBool
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import kotlinx.coroutines.flow.Flow

@Dao
interface PrefBoolDao {
@Query("SELECT * FROM PrefBool WHERE key = :key")
fun get(key: String): Flowable<PrefBool>
@Query("SELECT * FROM PrefBool WHERE key = :key")
fun observe(key: String): Flow<PrefBool?>

@Query("SELECT * FROM PrefBool WHERE key = :key")
fun getMaybe(key: String): Maybe<PrefBool>
Expand Down
5 changes: 5 additions & 0 deletions api/src/main/java/com/getcode/db/PrefDoubleDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.getcode.model.PrefBool
import com.getcode.model.PrefDouble
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import kotlinx.coroutines.flow.Flow

@Dao
interface PrefDoubleDao {
@Query("SELECT * FROM PrefDouble WHERE `key` = :key")
fun get(key: String): Flowable<PrefDouble>

@Query("SELECT * FROM PrefDouble WHERE key = :key")
fun observe(key: String): Flow<PrefDouble?>

@Query("SELECT * FROM PrefDouble WHERE `key` = :key")
fun getMaybe(key: String): Maybe<PrefDouble>

Expand Down
5 changes: 5 additions & 0 deletions api/src/main/java/com/getcode/db/PrefIntDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.getcode.model.PrefBool
import com.getcode.model.PrefInt
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import kotlinx.coroutines.flow.Flow

@Dao
interface PrefIntDao {
@Query("SELECT * FROM PrefInt WHERE key = :key")
fun get(key: String): Flowable<PrefInt>

@Query("SELECT * FROM PrefInt WHERE key = :key")
fun observe(key: String): Flow<PrefInt?>

@Query("SELECT * FROM PrefInt WHERE key = :key")
fun getMaybe(key: String): Maybe<PrefInt>

Expand Down
5 changes: 5 additions & 0 deletions api/src/main/java/com/getcode/db/PrefStringDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.getcode.model.PrefBool
import com.getcode.model.PrefString
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import kotlinx.coroutines.flow.Flow

@Dao
interface PrefStringDao {
@Query("SELECT * FROM PrefString WHERE key = :key")
fun get(key: String): Flowable<PrefString>

@Query("SELECT * FROM PrefString WHERE key = :key")
fun observe(key: String): Flow<PrefString?>

@Query("SELECT * FROM PrefString WHERE key = :key")
fun getMaybe(key: String): Maybe<PrefString>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.getcode.network.repository

import com.getcode.model.PrefsBool
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import javax.inject.Inject

data class AccountDebugSettings(
val isDebugBuckets: Boolean = false,
val isVibrateOnScan: Boolean = false,
val isDisplayErrors: Boolean = false,
val isRemoteSendEnabled: Boolean = false,
val isIncentivesEnabled: Boolean = false,
)

class AccountDebugRepository @Inject constructor(
private val prefRepository: PrefRepository,
) {

fun observe(): Flow<AccountDebugSettings> = combine(
prefRepository.observeOrDefault(PrefsBool.IS_DEBUG_BUCKETS, false),
prefRepository.observeOrDefault(PrefsBool.IS_DEBUG_VIBRATE_ON_SCAN, false),
prefRepository.observeOrDefault(PrefsBool.IS_DEBUG_DISPLAY_ERRORS, false),
) { buckets, vibez, errors ->
AccountDebugSettings(
isDebugBuckets = buckets,
isVibrateOnScan = vibez,
isDisplayErrors = errors
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class IdentityRepository @Inject constructor(
PrefsString.KEY_DATA_CONTAINER_ID,
user.dataContainerId.toByteArray().encodeBase64()
)
phoneRepository.phoneLinked = true
phoneRepository.phoneLinked.value = true
prefRepository.set(
PrefsBool.IS_DEBUG_ALLOWED,
user.enableDebugOptions
Expand Down Expand Up @@ -111,7 +111,7 @@ class IdentityRepository @Inject constructor(
dataContainerId = dataContainerId.decodeBase64().toList(),
enableDebugOptions = isDebugAllowed,
eligibleAirdrops = eligibleAirdrops,
isPhoneNumberLinked = isPhoneNumberLinked
isPhoneNumberLinked = isPhoneNumberLinked.value
)
}
.filter { it.userId.isNotEmpty() && it.dataContainerId.isNotEmpty() }
Expand Down Expand Up @@ -176,7 +176,7 @@ class IdentityRepository @Inject constructor(
.let { networkOracle.managedRequest(it) }
.doOnComplete {
phoneRepository.phoneNumber = ""
phoneRepository.phoneLinked = false
phoneRepository.phoneLinked.value = false
}
.firstOrError()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.getcode.network.core.NetworkOracle
import com.getcode.network.api.PhoneApi
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Single
import kotlinx.coroutines.flow.MutableStateFlow
import java.io.ByteArrayOutputStream
import javax.inject.Inject
import javax.inject.Singleton
Expand All @@ -21,7 +22,7 @@ class PhoneRepository @Inject constructor(
) {

var phoneNumber: String = ""
var phoneLinked: Boolean = false
var phoneLinked: MutableStateFlow<Boolean> = MutableStateFlow(false)

data class GetAssociatedPhoneNumberResponse(
val isSuccess: Boolean,
Expand Down Expand Up @@ -99,7 +100,7 @@ class PhoneRepository @Inject constructor(
.flatMap { response -> Database.isInit.map { response } }
.doOnNext { phone ->
phoneNumber = phone.phoneNumber
phoneLinked = phone.isLinked
phoneLinked.value = phone.isLinked
}
//.onErrorResumeNext { getAssociatedPhoneNumberLocal().map { Pair(true, it) } }
}
Expand All @@ -109,7 +110,7 @@ class PhoneRepository @Inject constructor(
Flowable.just(phoneLinked),
Flowable.just(phoneNumber)
) { v1, v2 ->
GetAssociatedPhoneNumberResponse(true, v1, false, v2)
GetAssociatedPhoneNumberResponse(true, v1.value, false, v2)
}
}
}
51 changes: 47 additions & 4 deletions api/src/main/java/com/getcode/network/repository/PrefRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,21 @@ import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject

class PrefRepository @Inject constructor() {


class PrefRepository @Inject constructor(): CoroutineScope by CoroutineScope(Dispatchers.IO) {

fun get(key: PrefsString): Flowable<String> {
val db = Database.getInstance() ?: return Flowable.empty()
return db.prefStringDao().get(key.value)
Expand All @@ -27,6 +38,38 @@ class PrefRepository @Inject constructor() {
.distinctUntilChanged()
}

fun observeOrDefault(key: PrefsBool, default: Boolean): Flow<Boolean> {
val db = Database.getInstance() ?: return flowOf(default)
return db.prefBoolDao().observe(key.value)
.flowOn(Dispatchers.IO)
.map { it?.value ?: default }
.distinctUntilChanged()
}

fun observeOrDefault(key: PrefsString, default: String): Flow<String> {
val db = Database.getInstance() ?: return flowOf(default)
return db.prefStringDao().observe(key.value)
.flowOn(Dispatchers.IO)
.map { it?.value ?: default }
.distinctUntilChanged()
}

fun observeOrDefault(key: PrefDouble, default: Double): Flow<Double> {
val db = Database.getInstance() ?: return flowOf(default)
return db.prefDoubleDao().observe(key.key)
.flowOn(Dispatchers.IO)
.map { it?.value ?: default }
.distinctUntilChanged()
}

fun observeOrDefault(key: PrefInt, default: Long): Flow<Long> {
val db = Database.getInstance() ?: return flowOf(default)
return db.prefIntDao().observe(key.key)
.flowOn(Dispatchers.IO)
.map { it?.value ?: default }
.distinctUntilChanged()
}

fun get(key: String): Flowable<Long> {
val db = Database.getInstance() ?: return Flowable.empty()
return db.prefIntDao().get(key)
Expand Down Expand Up @@ -60,7 +103,7 @@ class PrefRepository @Inject constructor() {
}

fun set(vararg list: Pair<PrefsString, String>) {
CoroutineScope(Dispatchers.IO).launch {
launch {
list.forEach { pair ->
Database.getInstance()?.prefStringDao()?.insert(PrefString(pair.first.value, pair.second))
}
Expand All @@ -74,13 +117,13 @@ class PrefRepository @Inject constructor() {
fun set(key: String, value: Int) = set(key, value.toLong())

fun set(key: String, value: Long) {
CoroutineScope(Dispatchers.IO).launch {
launch {
Database.getInstance()?.prefIntDao()?.insert(PrefInt(key, value))
}
}

fun set(key: PrefsBool, value: Boolean) {
CoroutineScope(Dispatchers.IO).launch {
launch {
Database.getInstance()?.prefBoolDao()?.insert(PrefBool(key.value, value))
}
}
Expand Down
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ dependencies {
}
androidTestImplementation(Libs.espresso_intents)
implementation(Libs.androidx_room_runtime)
implementation(Libs.androidx_room_ktx)
implementation(Libs.androidx_room_rxjava3)
kapt(Libs.androidx_room_compiler)

Expand Down
19 changes: 19 additions & 0 deletions app/src/main/java/com/getcode/inject/AppModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.getcode.inject

import android.content.Context
import com.getcode.util.AndroidResources
import com.getcode.util.resources.ResourceHelper
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent

@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
fun providesResourceHelper(
@ApplicationContext context: Context,
): ResourceHelper = AndroidResources(context)
}
2 changes: 1 addition & 1 deletion app/src/main/java/com/getcode/manager/AuthManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ class AuthManager @Inject constructor(
user.dataContainerId.toByteArray().encodeBase64()
)
)
phoneRepository.phoneLinked = phone.isLinked
phoneRepository.phoneLinked.value = phone.isLinked

prefRepository.set(
PrefsBool.IS_DEBUG_ALLOWED,
Expand Down
68 changes: 68 additions & 0 deletions app/src/main/java/com/getcode/util/AndroidResources.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.getcode.util

import android.content.Context
import androidx.annotation.RawRes
import androidx.annotation.StringRes
import com.getcode.util.resources.ResourceHelper
import dagger.hilt.android.qualifiers.ApplicationContext
import timber.log.Timber
import java.io.File
import javax.inject.Inject

class AndroidResources @Inject constructor(
@ApplicationContext private val context: Context,
) : ResourceHelper {

override fun getString(@StringRes resourceId: Int): String {
return context.getString(resourceId)
}

override fun getString(@StringRes resourceId: Int, vararg formatArgs: Any): String {
return context.getString(resourceId, *formatArgs)
}

override fun getRawResource(@RawRes resourceId: Int): String {
return try {
context.resources.openRawResource(resourceId).bufferedReader().use { it.readText() }
} catch (e: Exception) {
Timber.e(t = e, "Failed to get raw res for resource id:$resourceId")
""
}
}

override fun getQuantityString(
id: Int,
quantity: Int,
vararg formatArgs: Any,
default: String,
): String {
return try {
context.resources.getQuantityString(id, quantity, *formatArgs)
} catch (e: Exception) {
Timber.e(t = e, "Failed to get quantity string for resource id:$id")
default
}
}

override fun getDimension(dimenId: Int, default: Float): Float {
return try {
context.resources.getDimension(dimenId)
} catch (e: Exception) {
Timber.e(t = e, "Failed to get dimension for resource id:$dimenId")
default
}
}

override fun getDimensionPixelSize(dimenId: Int, default: Int): Int {
return try {
context.resources.getDimensionPixelSize(dimenId)
} catch (e: Exception) {
Timber.e(t = e, message = "Failed to get dimension for resource id:$dimenId")
default
}
}

override fun getDir(name: String, mode: Int): File? {
return context.getDir(name, mode)
}
}
Loading