Skip to content

Commit

Permalink
Merge branch 'release/3.0.7'
Browse files Browse the repository at this point in the history
  • Loading branch information
benoitletondor committed Oct 29, 2023
2 parents b5fe8c6 + 6ae4303 commit e74a6b4
Show file tree
Hide file tree
Showing 30 changed files with 167 additions and 132 deletions.
1 change: 1 addition & 0 deletions Android/EasyBudget/.idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

73 changes: 39 additions & 34 deletions Android/EasyBudget/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-kapt")
id("com.google.firebase.crashlytics")
id("dagger.hilt.android.plugin")
id("com.google.devtools.ksp")
Expand All @@ -36,11 +35,11 @@ android {

defaultConfig {
applicationId = "com.benoitletondor.easybudgetapp"
compileSdk = 33
compileSdk = 34
minSdk = 21
targetSdk = 33
versionCode = 105
versionName = "3.0.6"
targetSdk = 34
versionCode = 107
versionName = "3.0.7"
vectorDrawables.useSupportLibrary = true

javaCompileOptions {
Expand Down Expand Up @@ -94,19 +93,13 @@ android {
keyPassword = "uFdRPMWz69R28t6m9zV53jmw9hJVK3"
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11

compileOptions {
isCoreLibraryDesugaringEnabled = true
}

kotlinOptions {
jvmTarget = "11"
}

composeOptions {
kotlinCompilerExtensionVersion = "1.4.8"
kotlinCompilerExtensionVersion = "1.5.3"
}

buildFeatures {
Expand All @@ -116,9 +109,21 @@ android {
}
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
// Remove this when https://github.com/google/dagger/issues/4049 is merged
androidComponents {
onVariants(selector().all()) { variant ->
afterEvaluate {
// This is a workaround for https://issuetracker.google.com/301245705 which depends on internal
// implementations of the android gradle plugin and the ksp gradle plugin which might change in the future
// in an unpredictable way.
project.tasks.getByName("ksp" + variant.name.capitalize() + "Kotlin") {
val dataBindingTask = project.tasks.getByName ("dataBindingGenBaseClasses" + variant.name.capitalize()) as com.android.build.gradle.internal.tasks.databinding.DataBindingGenBaseClassesTask

(this as org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool<*>).setSource(
dataBindingTask.sourceOutFolder
)
}
}
}
}

Expand All @@ -132,40 +137,40 @@ dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")

implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.core:core-ktx:1.10.1")
implementation("com.google.android.material:material:1.9.0")
implementation("androidx.recyclerview:recyclerview:1.3.1")
implementation("androidx.core:core-ktx:1.12.0")
implementation("com.google.android.material:material:1.10.0")
implementation("androidx.recyclerview:recyclerview:1.3.2")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.preference:preference-ktx:1.2.1")
implementation("androidx.activity:activity-ktx:1.7.2")
implementation("androidx.activity:activity-ktx:1.8.0")
implementation("androidx.fragment:fragment-ktx:1.6.1")
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.work:work-runtime-ktx:2.8.1")
implementation("androidx.work:work-gcm:2.8.1")
implementation("com.google.android.play:core:1.10.3")

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")

implementation(platform("com.google.firebase:firebase-bom:32.2.2"))
implementation(platform("com.google.firebase:firebase-bom:32.4.1"))
implementation("com.google.firebase:firebase-messaging-ktx")
implementation("com.google.firebase:firebase-storage")
implementation("com.google.firebase:firebase-crashlytics")
implementation("com.google.firebase:firebase-analytics-ktx")
implementation("com.google.firebase:firebase-firestore-ktx")
implementation("com.firebaseui:firebase-ui-auth:8.0.2")

val composeBom = platform("androidx.compose:compose-bom:2023.06.01")
val composeBom = platform("androidx.compose:compose-bom:2023.10.01")
implementation(composeBom)
androidTestImplementation(composeBom)
debugImplementation("androidx.compose.ui:ui-tooling")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui")
implementation("androidx.activity:activity-compose:1.7.2")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")
implementation("androidx.activity:activity-compose:1.8.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
implementation("com.google.accompanist:accompanist-themeadapter-material3:0.31.5-beta")

implementation("com.android.billingclient:billing-ktx:6.0.1")
Expand All @@ -175,13 +180,13 @@ dependencies {
implementation("com.batch.android:batch-sdk:1.19.4")

implementation("com.google.dagger:hilt-android:$hiltVersion")
implementation("androidx.hilt:hilt-work:1.0.0")
kapt("androidx.hilt:hilt-compiler:1.0.0")
kapt("com.google.dagger:hilt-compiler:$hiltVersion")
implementation("androidx.hilt:hilt-work:1.1.0-rc01")
ksp("androidx.hilt:hilt-compiler:1.1.0-rc01")
ksp("com.google.dagger:hilt-compiler:$hiltVersion")

ksp("androidx.room:room-compiler:2.5.2")
implementation("androidx.room:room-runtime:2.5.2")
implementation("androidx.room:room-ktx:2.5.2")
ksp("androidx.room:room-compiler:2.6.0")
implementation("androidx.room:room-runtime:2.6.0")
implementation("androidx.room:room-ktx:2.6.0")

implementation("io.realm.kotlin:library-sync:$realmVersion")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,10 @@ class FirebaseAccounts(
.await()
}

override suspend fun leaveAccount(currentUser: CurrentUser, accountCredentials: AccountCredentials,) {
override suspend fun leaveAccount(
currentUser: CurrentUser,
accountCredentials: AccountCredentials,
) {
val accountRef = db.collection(ACCOUNTS_COLLECTION).document(accountCredentials.id)

val invitationQuery = db.collection(INVITATIONS_COLLECTION)
Expand Down Expand Up @@ -374,7 +377,7 @@ class FirebaseAccounts(
private const val INVITATION_DOCUMENT_ACCOUNT_ID = "accountId"
private const val INVITATION_DOCUMENT_SENDER_ID = "senderId"
private const val INVITATION_DOCUMENT_SENDER_EMAIL = "senderEmail"
private const val INVITATION_DOCUMENT_SENDER_LOCALE = "senderLocale";
private const val INVITATION_DOCUMENT_SENDER_LOCALE = "senderLocale"

private const val ACCOUNTS_COLLECTION = "accounts"
private const val ACCOUNT_DOCUMENT_SECRET = "secret"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ interface Auth {
fun startAuthentication(activity: Activity)
fun handleActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
fun logout()
suspend fun refreshUserTokens()
}

sealed class AuthState {
object NotAuthenticated : AuthState()
object Authenticating : AuthState()
data object NotAuthenticated : AuthState()
data object Authenticating : AuthState()
data class Authenticated(val currentUser: CurrentUser) : AuthState()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,26 @@ class FirebaseAuth(
updateAuthState()
}

override suspend fun refreshUserTokens() {
currentState.value = getAuthState(forceRefreshToken = true)
}

private fun updateAuthState() {
launch {
currentState.value = getAuthState()
currentState.value = getAuthState(forceRefreshToken = false)
}
}

private suspend fun getAuthState(): AuthState {
private suspend fun getAuthState(forceRefreshToken: Boolean): AuthState {
val firebaseUser = auth.currentUser
return if( firebaseUser == null ) {
AuthState.NotAuthenticated
} else {
try {
val token = firebaseUser.getIdToken(false).await().token!!
AuthState.Authenticated(firebaseUser.toCurrentUser(token))
val token = firebaseUser.getIdToken(forceRefreshToken).await().token!!
AuthState.Authenticated(
currentUser = firebaseUser.toCurrentUser(token),
)
} catch (e: Exception) {
Logger.error("Error while getting firebase token", e)
AuthState.NotAuthenticated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package com.benoitletondor.easybudgetapp.db
import com.benoitletondor.easybudgetapp.model.Expense
import com.benoitletondor.easybudgetapp.model.RecurringExpense
import kotlinx.coroutines.flow.Flow
import java.io.Closeable
import java.time.LocalDate

interface DB {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -522,15 +522,15 @@ class OnlineDBImpl(
= "date == ${day.toEpochDay()}"

sealed class SyncSessionState {
object NotStarted : SyncSessionState()
object Started : SyncSessionState()
object Done : SyncSessionState()
data object NotStarted : SyncSessionState()
data object Started : SyncSessionState()
data object Done : SyncSessionState()
class Error(val exception: Throwable) : SyncSessionState()
}

private sealed class RecurringExpenseLoadingState {
object NotLoaded : RecurringExpenseLoadingState()
object Loading : RecurringExpenseLoadingState()
data object NotLoaded : RecurringExpenseLoadingState()
data object Loading : RecurringExpenseLoadingState()
data class Loaded(val expenses: List<RecurringExpenseEntity>) : RecurringExpenseLoadingState()
class Error(val exception: Throwable) : RecurringExpenseLoadingState()
}
Expand Down Expand Up @@ -568,7 +568,7 @@ class OnlineDBImpl(
user = user,
schema = setOf(ExpenseEntity::class, RecurringExpenseEntity::class),
)
.name("${account.id}.realm")
.name("${account.id}_v2.realm") // v2 == with indexes on properties
.initialSubscriptions(rerunOnOpen = true) { realm ->
add(
query = realm.query<ExpenseEntity>(account.generateQuery()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.benoitletondor.easybudgetapp.model.AssociatedRecurringExpense
import com.benoitletondor.easybudgetapp.model.Expense
import com.benoitletondor.easybudgetapp.model.RecurringExpense
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.Index
import io.realm.kotlin.types.annotations.PrimaryKey
import java.security.SecureRandom
import java.time.LocalDate
Expand All @@ -32,9 +33,13 @@ class ExpenseEntity() : RealmObject {
var _id: Long = SecureRandom().nextLong()
var title: String = ""
var amount: Long = 0
@Index
var date: Long = 0
@Index
var checked: Boolean = false
@Index
var accountId: String = ""
@Index
var accountSecret: String = ""

constructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import biweekly.ICalendar
import biweekly.component.VEvent
import biweekly.property.DateEnd
import biweekly.property.DateStart
import biweekly.property.ProductId
import biweekly.property.RecurrenceId
import biweekly.property.RecurrenceRule
import biweekly.property.Status
Expand All @@ -38,9 +37,8 @@ import com.benoitletondor.easybudgetapp.model.AssociatedRecurringExpense
import com.benoitletondor.easybudgetapp.model.Expense
import com.benoitletondor.easybudgetapp.model.RecurringExpense
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.Index
import io.realm.kotlin.types.annotations.PrimaryKey
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.security.SecureRandom
import java.time.LocalDate
import java.util.Date
Expand All @@ -53,7 +51,9 @@ class RecurringExpenseEntity() : RealmObject {
@PrimaryKey
var _id: Long = SecureRandom().nextLong()
var iCalRepresentation: String = ""
@Index
var accountId: String = ""
@Index
var accountSecret: String = ""

constructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,21 @@ private const val BACKUP_VERSION = 1
private const val BACKUP_VERSION_FILENAME = "version"
private const val BACKUP_DB_FILENAME = "db_backup"

class BackupException(message: String) : Exception("Backup: $message")

suspend fun backupDB(context: Context,
cloudStorage: CloudStorage,
auth: Auth,
parameters: Parameters,
iab: Iab): ListenableWorker.Result {
Logger.debug("BackupJob", "Starting backup")

val currentUser = (auth.state.value as? AuthState.Authenticated)?.currentUser
if( currentUser == null ) {
Logger.error(
"BackupJob",
"Not authenticated"
"Not authenticated",
BackupException("Not authenticated"),
)

return ListenableWorker.Result.failure()
Expand All @@ -66,7 +71,8 @@ suspend fun backupDB(context: Context,
if( !iab.isUserPremium() ) {
Logger.error(
"BackupJob",
"Not premium"
"Not premium",
BackupException("Not premium"),
)

return ListenableWorker.Result.failure()
Expand Down Expand Up @@ -134,6 +140,8 @@ suspend fun backupDB(context: Context,
}
}

Logger.debug("BackupJob", "Backup complete")

return ListenableWorker.Result.success()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ package com.benoitletondor.easybudgetapp.helper

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.annotation.TargetApi
import android.app.Activity
import android.content.Context
import android.os.Build
import android.text.Editable
import android.text.TextWatcher
import android.view.*
import android.view.Gravity
import android.view.View
import android.view.ViewAnimationUtils
import android.view.ViewTreeObserver
import android.view.WindowManager
import android.view.animation.AccelerateInterpolator
import android.view.inputmethod.InputMethodManager
import android.widget.Button
Expand All @@ -39,7 +42,7 @@ import com.benoitletondor.easybudgetapp.R
import com.benoitletondor.easybudgetapp.view.main.MainActivity
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.*
import java.util.Locale
import kotlin.math.max

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ interface Iab {
}

sealed class PurchaseFlowResult {
object Cancelled : PurchaseFlowResult()
data object Cancelled : PurchaseFlowResult()
data class Success(val purchaseType: PurchaseType) : PurchaseFlowResult()
data class Error(val reason: String): PurchaseFlowResult()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private const val SHOULD_SHOW_CHECKED_BALANCE = "should_show_checked_balance"
/**
* Id of the last selected online account
*/
private const val SELECTED_ACCOUNT_ID_KEY = "selectedAccountId";
private const val SELECTED_ACCOUNT_ID_KEY = "selectedAccountId"

fun Parameters.getInitDate(): LocalDate? {
val timestamp = getLong(INIT_TIMESTAMP_PARAMETERS_KEY, 0L)
Expand Down
Loading

0 comments on commit e74a6b4

Please sign in to comment.