Skip to content

Commit

Permalink
Merge branch 'release/3.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
benoitletondor committed Mar 21, 2024
2 parents f983cb5 + 75ddeba commit b697f6d
Show file tree
Hide file tree
Showing 27 changed files with 773 additions and 152 deletions.
6 changes: 4 additions & 2 deletions Android/EasyBudget/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ android {
compileSdk = 34
minSdk = 23
targetSdk = 34
versionCode = 131
versionName = "3.1.11"
versionCode = 133
versionName = "3.2.0"
vectorDrawables.useSupportLibrary = true
}

Expand Down Expand Up @@ -187,4 +187,6 @@ dependencies {
implementation("net.sf.biweekly:biweekly:0.6.8")

implementation("net.lingala.zip4j:zip4j:2.11.5")

implementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.9.3")
}
39 changes: 28 additions & 11 deletions Android/EasyBudget/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
android:configChanges="locale|keyboardHidden|orientation|screenSize"
android:launchMode="singleTask"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"
tools:ignore="DiscouragedApi,LockedOrientationActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand All @@ -96,66 +96,83 @@
android:configChanges="locale|keyboardHidden|orientation|screenSize"
android:label="@string/title_activity_monthly_report"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"
tools:ignore="DiscouragedApi,LockedOrientationActivity"
android:exported="false"/>
<activity
android:name=".view.expenseedit.ExpenseEditActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize"
android:label="@string/title_activity_add_expense"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"
tools:ignore="DiscouragedApi,LockedOrientationActivity"
android:exported="false"/>
<activity
android:name=".view.recurringexpenseadd.RecurringExpenseEditActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize"
android:label="@string/title_activity_recurring_expense_add"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"
tools:ignore="DiscouragedApi,LockedOrientationActivity"
android:exported="false"/>
<activity
android:name=".view.settings.SettingsActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize"
android:label="@string/title_activity_settings"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"/>
tools:ignore="DiscouragedApi,LockedOrientationActivity"/>
<activity
android:name=".view.welcome.WelcomeActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize"
android:label="@string/title_activity_welcome"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"
tools:ignore="DiscouragedApi,LockedOrientationActivity"
android:exported="false"/>
<activity
android:name=".view.premium.PremiumActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize"
android:label="@string/title_activity_premium"
android:screenOrientation="portrait"
android:exported="false"
tools:ignore="LockedOrientationActivity"/>
tools:ignore="DiscouragedApi,LockedOrientationActivity"/>
<activity
android:name=".view.main.login.LoginActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize"
android:label="@string/title_activity_login"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"/>
tools:ignore="DiscouragedApi,LockedOrientationActivity"/>
<activity
android:name=".view.main.createaccount.CreateAccountActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize"
android:label="@string/title_activity_create_account"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"/>
tools:ignore="DiscouragedApi,LockedOrientationActivity"/>
<activity
android:name=".view.main.manageaccount.ManageAccountActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize"
android:label="@string/title_activity_manage_account"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"/>
tools:ignore="DiscouragedApi,LockedOrientationActivity"/>
<activity
android:name=".view.settings.backup.BackupSettingsActivity"
android:label="@string/backup_settings_activity_title"
android:screenOrientation="portrait"
android:exported="false"
tools:ignore="LockedOrientationActivity" />
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".view.report.export.ExportReportActivity"
android:label="@string/title_activity_monthly_report_export"
android:screenOrientation="portrait"
android:exported="false"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />

<!-- Provider used for exporting CSVs to other apps -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>

<!-- Push -->
<service
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,34 +390,39 @@ class EasyBudget : Application(), Configuration.Provider {
private fun onUpdate(previousVersion: Int, @Suppress("SameParameterValue") newVersion: Int) {
Logger.debug("Update detected, from $previousVersion to $newVersion")

if (previousVersion < 90) {
try {
if (Build.VERSION.SDK_INT >= 33 && ActivityCompat.checkSelfPermission(this@EasyBudget, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
return
}
if (previousVersion < 132) {
GlobalScope.launch {
try {
if (Build.VERSION.SDK_INT >= 33 && ActivityCompat.checkSelfPermission(this@EasyBudget, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
return@launch
}

val intent = Intent(this, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
putExtra(MainActivity.INTENT_OPEN_ACCOUNTS_TRAY_EXTRA, true)
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)

val builder = NotificationCompat.Builder(this, CHANNEL_NEW_FEATURES)
.setSmallIcon(R.drawable.ic_push)
.setContentTitle(getString(R.string.update_three_dot_zero_notification_title))
.setContentText(getString(R.string.update_three_dot_zero_notification_message))
.setStyle(NotificationCompat.BigTextStyle().bigText(getString(R.string.update_three_dot_zero_notification_message)))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.addAction(R.drawable.ic_baseline_new_releases, getString(R.string.update_three_dot_zero_notification_cta), pendingIntent)

with(NotificationManagerCompat.from(this)) {
// notificationId is a unique int for each notification that you must define
notify(100001, builder.build())
if (!iab.isUserPro()) {
return@launch
}

val intent = Intent(this@EasyBudget, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(this@EasyBudget, 0, intent, PendingIntent.FLAG_IMMUTABLE)

val builder = NotificationCompat.Builder(this@EasyBudget, CHANNEL_NEW_FEATURES)
.setSmallIcon(R.drawable.ic_push)
.setContentTitle(getString(R.string.update_three_dot_two_notification_title))
.setContentText(getString(R.string.update_three_dot_two_notification_message))
.setStyle(NotificationCompat.BigTextStyle().bigText(getString(R.string.update_three_dot_two_notification_message)))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.addAction(R.drawable.ic_baseline_new_releases, getString(R.string.update_three_dot_two_notification_cta), pendingIntent)

with(NotificationManagerCompat.from(this@EasyBudget)) {
// notificationId is a unique int for each notification that you must define
notify(100001, builder.build())
}
} catch (e: Exception) {
Logger.error("Error while showing update notification", e)
}
} catch (e: Exception) {
Logger.error("Error while showing update notification", e)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import com.google.firebase.firestore.FieldValue
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.Query
import com.google.firebase.firestore.QuerySnapshot
import com.google.firebase.firestore.ktx.firestoreSettings
import com.google.firebase.firestore.firestoreSettings
import com.google.firebase.firestore.ktx.memoryCacheSettings
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.trySendBlocking
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import io.realm.kotlin.ext.query
import io.realm.kotlin.log.LogLevel
import io.realm.kotlin.log.RealmLogger
import io.realm.kotlin.mongodb.App
import io.realm.kotlin.mongodb.AppConfiguration
import io.realm.kotlin.mongodb.Credentials
import io.realm.kotlin.mongodb.subscriptions
import io.realm.kotlin.mongodb.sync.SyncConfiguration
Expand Down Expand Up @@ -81,7 +82,6 @@ class OnlineDBImpl(
}

private val onChangeMutableFlow = MutableSharedFlow<Unit>()

override val onChangeFlow: Flow<Unit> = onChangeMutableFlow

override fun ensureDBCreated() { /* No-op */ }
Expand Down Expand Up @@ -526,6 +526,7 @@ class OnlineDBImpl(
realm.close()
app.close()
cancel()
recurringExpensesLoadingStateMutableFlow.value = RecurringExpenseLoadingState.NotLoaded
}

private fun generateQueryForDateRange(from: LocalDate, to: LocalDate): String
Expand Down Expand Up @@ -557,7 +558,11 @@ class OnlineDBImpl(
accountId: String,
accountSecret: String,
): OnlineDBImpl {
val app = App.create(atlasAppId)
val app = App.create(
AppConfiguration.Builder(atlasAppId)
.enableSessionMultiplexing(true)
.build()
)

val user = withContext(Dispatchers.IO) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,32 @@ package com.benoitletondor.easybudgetapp.helper

import com.benoitletondor.easybudgetapp.parameters.Parameters
import com.benoitletondor.easybudgetapp.parameters.getInitDate
import com.kizitonwose.calendar.core.yearMonth

import java.time.LocalDate
import java.time.YearMonth
import java.util.ArrayList

/**
* Get the list of months available for the user for the monthly report view.
*
* @return a list of Date object set at the 1st day of the month 00:00:00:000
* Get the list of months available in the monthly report view.
*/
fun Parameters.getListOfMonthsAvailableForUser(): List<LocalDate> {
val initDate = getInitDate() ?: return emptyList()
val today = LocalDate.now()
fun Parameters.getListOfMonthsAvailableForUser(): List<YearMonth> {
val initMonth = getInitDate()?.yearMonth ?: YearMonth.now()

// End 12 months in the future (13 because we are comparing with "isBefore")
val endRange = LocalDate.now().yearMonth.plusMonths(13)

val months = ArrayList<LocalDate>()
var currentDate = LocalDate.of(initDate.year, initDate.month, 1)
// Start at least 12 months ago
var currentMonth = if (initMonth.isAfter(YearMonth.now().minusMonths(12))) {
YearMonth.now().minusMonths(12)
} else {
initMonth
}

while (currentDate.isBefore(today) || currentDate == today) {
months.add(currentDate)
currentDate = currentDate.plusMonths(1)
val months = ArrayList<YearMonth>()
while (currentMonth.isBefore(endRange)) {
months.add(currentMonth)
currentMonth = currentMonth.plusMonths(1)
}

return months
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

package com.benoitletondor.easybudgetapp.helper

import android.content.Context
import biweekly.util.Frequency
import biweekly.util.Recurrence
import com.benoitletondor.easybudgetapp.R
import com.benoitletondor.easybudgetapp.model.RecurringExpenseType

fun Recurrence.toRecurringExpenseType(): RecurringExpenseType {
Expand Down Expand Up @@ -62,4 +64,17 @@ fun RecurringExpenseType.toRecurrence(): Recurrence {
}

return Recurrence.Builder(frequency).interval(interval).build()
}

fun RecurringExpenseType.toFormattedString(context: Context): String = when(this) {
RecurringExpenseType.DAILY -> context.getString(R.string.daily)
RecurringExpenseType.WEEKLY -> context.getString(R.string.weekly)
RecurringExpenseType.BI_WEEKLY -> context.getString(R.string.bi_weekly)
RecurringExpenseType.TER_WEEKLY -> context.getString(R.string.ter_weekly)
RecurringExpenseType.FOUR_WEEKLY -> context.getString(R.string.four_weekly)
RecurringExpenseType.MONTHLY -> context.getString(R.string.monthly)
RecurringExpenseType.BI_MONTHLY -> context.getString(R.string.bi_monthly)
RecurringExpenseType.TER_MONTHLY -> context.getString(R.string.ter_monthly)
RecurringExpenseType.SIX_MONTHLY ->context.getString(R.string.six_monthly)
RecurringExpenseType.YEARLY -> context.getString(R.string.yearly)
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import androidx.core.view.ViewCompat
import androidx.core.view.updateLayoutParams
import com.benoitletondor.easybudgetapp.R
import java.time.LocalDate
import java.time.YearMonth
import java.time.format.DateTimeFormatter
import java.util.Locale

Expand Down Expand Up @@ -178,7 +179,7 @@ fun AlertDialog.centerButtons() {
* @param context non null context
* @return a formatted string like "January 2016"
*/
fun LocalDate.getMonthTitle(context: Context): String {
fun YearMonth.getMonthTitle(context: Context): String {
val format = DateTimeFormatter.ofPattern(context.resources.getString(R.string.monthly_report_month_title_format), Locale.getDefault())
return format.format(this)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.recyclerview.widget.RecyclerView
import com.benoitletondor.easybudgetapp.R
import com.benoitletondor.easybudgetapp.helper.CurrencyHelper
import com.benoitletondor.easybudgetapp.helper.toFormattedString
import com.benoitletondor.easybudgetapp.model.Expense
import com.benoitletondor.easybudgetapp.model.RecurringExpenseDeleteType
import com.benoitletondor.easybudgetapp.model.RecurringExpenseType
import com.benoitletondor.easybudgetapp.parameters.Parameters
import com.benoitletondor.easybudgetapp.view.expenseedit.ExpenseEditActivity
import com.benoitletondor.easybudgetapp.view.main.MainActivity
Expand Down Expand Up @@ -97,18 +97,7 @@ class ExpensesRecyclerViewAdapter(
viewHolder.checkedCheckBox.isChecked = expense.checked

if (expense.isRecurring()) {
when (expense.associatedRecurringExpense!!.recurringExpense.type) {
RecurringExpenseType.DAILY -> viewHolder.recurringIndicatorTextview.text = viewHolder.view.context.getString(R.string.daily)
RecurringExpenseType.WEEKLY -> viewHolder.recurringIndicatorTextview.text = viewHolder.view.context.getString(R.string.weekly)
RecurringExpenseType.BI_WEEKLY -> viewHolder.recurringIndicatorTextview.text = viewHolder.view.context.getString(R.string.bi_weekly)
RecurringExpenseType.TER_WEEKLY -> viewHolder.recurringIndicatorTextview.text = viewHolder.view.context.getString(R.string.ter_weekly)
RecurringExpenseType.FOUR_WEEKLY -> viewHolder.recurringIndicatorTextview.text = viewHolder.view.context.getString(R.string.four_weekly)
RecurringExpenseType.MONTHLY -> viewHolder.recurringIndicatorTextview.text = viewHolder.view.context.getString(R.string.monthly)
RecurringExpenseType.BI_MONTHLY -> viewHolder.recurringIndicatorTextview.text = viewHolder.view.context.getString(R.string.bi_monthly)
RecurringExpenseType.TER_MONTHLY -> viewHolder.recurringIndicatorTextview.text = viewHolder.view.context.getString(R.string.ter_monthly)
RecurringExpenseType.SIX_MONTHLY -> viewHolder.recurringIndicatorTextview.text = viewHolder.view.context.getString(R.string.six_monthly)
RecurringExpenseType.YEARLY -> viewHolder.recurringIndicatorTextview.text = viewHolder.view.context.getString(R.string.yearly)
}
viewHolder.recurringIndicatorTextview.text = expense.associatedRecurringExpense!!.recurringExpense.type.toFormattedString(viewHolder.view.context)
}

val onClickListener = View.OnClickListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,31 +455,19 @@ private fun ColumnScope.ProSubscriptionView(proSubscribed: Boolean) {
modifier = Modifier.align(Alignment.CenterHorizontally),
)

Spacer(modifier = Modifier.height(30.dp))

Text(
modifier = Modifier
.padding(bottom = 10.dp)
.fillMaxWidth(),
text = stringResource(R.string.premium_settings_coming_soon),
color = Color.White,
fontSize = 20.sp,
textAlign = TextAlign.Center,
)
Spacer(modifier = Modifier.height(20.dp))

Text(
modifier = Modifier.padding(bottom = 10.dp),
text = stringResource(R.string.premium_popup_not_pro_feature3_title),
color = Color.White.copy(alpha = 0.9f),
color = Color.White,
fontSize = 20.sp,
fontStyle = FontStyle.Italic,
)

Text(
text = stringResource(R.string.premium_popup_not_pro_feature3_message),
color = Color.White.copy(alpha = 0.9f),
color = Color.White,
fontSize = 16.sp,
fontStyle = FontStyle.Italic,
)

}
Expand Down
Loading

0 comments on commit b697f6d

Please sign in to comment.