Skip to content

Commit

Permalink
Bug: fixed minor bugs & introduced logger
Browse files Browse the repository at this point in the history
  • Loading branch information
ferrariofilippo committed May 3, 2024
1 parent fb98fb3 commit 5fa2854
Show file tree
Hide file tree
Showing 28 changed files with 313 additions and 51 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ android {
applicationId "com.ferrariofilippo.saveapp"
minSdk 29
targetSdk 34
versionCode 4
versionName "1.05"
versionCode 5
versionName "1.06"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
Binary file modified app/release/app-release.apk
Binary file not shown.
4 changes: 2 additions & 2 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 4,
"versionName": "1.05",
"versionCode": 5,
"versionName": "1.06",
"outputFile": "app-release.apk"
}
],
Expand Down
35 changes: 26 additions & 9 deletions app/src/main/java/com/ferrariofilippo/saveapp/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package com.ferrariofilippo.saveapp

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.MenuItem
import android.widget.Button
import androidx.activity.result.ActivityResult
Expand All @@ -24,6 +23,7 @@ import com.ferrariofilippo.saveapp.util.BudgetUtil
import com.ferrariofilippo.saveapp.util.CloudStorageUtil
import com.ferrariofilippo.saveapp.util.CurrencyUtil
import com.ferrariofilippo.saveapp.util.ImportExportUtil
import com.ferrariofilippo.saveapp.util.LogUtil
import com.ferrariofilippo.saveapp.util.SettingsUtil
import com.ferrariofilippo.saveapp.util.SpacingUtil
import com.ferrariofilippo.saveapp.util.StatsUtil
Expand Down Expand Up @@ -150,18 +150,35 @@ class MainActivity : AppCompatActivity() {

val uploadBackupToDrive =
registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result: ActivityResult ->
val authResult: AuthorizationResult = Identity.getAuthorizationClient(this)
.getAuthorizationResultFromIntent(result.data)

CloudStorageUtil.enqueueUpload(application as SaveAppApplication, authResult)
try {
val authResult: AuthorizationResult = Identity.getAuthorizationClient(this)
.getAuthorizationResultFromIntent(result.data)
CloudStorageUtil.enqueueUpload(application as SaveAppApplication, authResult)
} catch (e: Exception) {
LogUtil.logException(e, javaClass.kotlin.simpleName ?: "", "uploadBackupToDrive")
}
}
val downloadBackupFromDrive =
registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result: ActivityResult ->
val authResult: AuthorizationResult = Identity.getAuthorizationClient(this)
.getAuthorizationResultFromIntent(result.data)
try {
val authResult: AuthorizationResult = Identity.getAuthorizationClient(this)
.getAuthorizationResultFromIntent(result.data)

CloudStorageUtil.enqueueDownload(application as SaveAppApplication, authResult)
} catch (e: Exception) {
LogUtil.logException(
e,
javaClass.kotlin.simpleName ?: "",
"downloadBackupFromDrive"
)
}
}

CloudStorageUtil.enqueueDownload(application as SaveAppApplication, authResult)
val exportLogFile = registerForActivityResult(CreateDocument("text/plain")) { uri ->
if (uri != null) {
LogUtil.exportLogTo(contentResolver?.openOutputStream(uri) as FileOutputStream)
}
}

// Overrides
override fun onCreate(savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -314,7 +331,7 @@ class MainActivity : AppCompatActivity() {
findNavController(R.id.containerView).navigate(R.id.action_statsFragment_to_newMovementFragment)
}
} catch (e: Exception) {
Log.e("NAV_E", e.message.toString())
LogUtil.logException(e, javaClass.kotlin.simpleName ?: "", "onAddMovementClick")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.ferrariofilippo.saveapp.data.repository.MovementRepository
import com.ferrariofilippo.saveapp.data.repository.SubscriptionRepository
import com.ferrariofilippo.saveapp.data.repository.TagRepository
import com.ferrariofilippo.saveapp.data.repository.UtilRepository
import com.ferrariofilippo.saveapp.util.LogUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob

Expand Down Expand Up @@ -49,4 +50,17 @@ class SaveAppApplication : Application() {
fun setCurrentActivity(activity: Activity?) {
currentActivity = activity
}

override fun onCreate() {
super.onCreate()
LogUtil.setLogFilePath(filesDir.absolutePath)
Thread.setDefaultUncaughtExceptionHandler { _, e ->
LogUtil.logException(
e,
javaClass.kotlin.simpleName ?: "",
"defaultUncaughtExceptionHandler"
)
Runtime.getRuntime().exit(1)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Copyright (c) 2023 Filippo Ferrario
// Copyright (c) 2024 Filippo Ferrario
// Licensed under the MIT License. See the LICENSE.

package com.ferrariofilippo.saveapp.converters

import android.view.View
import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.databinding.BindingAdapter
import com.ferrariofilippo.saveapp.R
import com.ferrariofilippo.saveapp.util.ColorUtil
import com.google.android.material.button.MaterialButton

@BindingAdapter("dynamicIcon")
Expand All @@ -34,7 +34,7 @@ fun View.setCollapsibleIcon(isCollapsed: Boolean) {
fun View.setDynamicTint(value: Int?) {
value.let {
(this as ImageView).setColorFilter(
ContextCompat.getColor(
ColorUtil.getColorOrDefault(
context,
if (value == null || value == 0) R.color.emerald_500 else value
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Copyright (c) 2023 Filippo Ferrario
// Copyright (c) 2024 Filippo Ferrario
// Licensed under the MIT License. See the LICENSE.

package com.ferrariofilippo.saveapp.model

import com.squareup.moshi.Json

data class CurrencyApiResponse(
val amount: Int,
val base: String,
val date: String,
val rates: Map<String, Double>
@Json(name="amount") val amount: Int,
@Json(name="base") val base: String,
@Json(name="date") val date: String,
@Json(name="rates") val rates: Map<String, Double>
)
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ object CloudStorageUtil {
true
)
}
LogUtil.logException(e, javaClass.kotlin.simpleName ?: "", "authorizeDownload")
}
} else {
enqueueDownload(app, result)
Expand All @@ -75,6 +76,7 @@ object CloudStorageUtil {
true
)
}
LogUtil.logException(e, javaClass.kotlin.simpleName ?: "", "authorizeUpload")
}
} else {
enqueueUpload(app, result)
Expand Down Expand Up @@ -141,6 +143,7 @@ object CloudStorageUtil {
true
)
}
LogUtil.logException(it, javaClass.kotlin.simpleName ?: "", "addOnFailureListener")
}
}
}
20 changes: 20 additions & 0 deletions app/src/main/java/com/ferrariofilippo/saveapp/util/ColorUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2024 Filippo Ferrario
// Licensed under the MIT License. See the LICENSE.

package com.ferrariofilippo.saveapp.util

import android.content.Context
import android.content.res.Resources
import androidx.core.content.ContextCompat
import com.ferrariofilippo.saveapp.R

object ColorUtil {
fun getColorOrDefault(ctx: Context, resId: Int): Int {
return try {
ContextCompat.getColor(ctx, resId)
} catch (e: Resources.NotFoundException) {
LogUtil.logException(e, javaClass.kotlin.simpleName ?: "", "getColorOrDefault")
ContextCompat.getColor(ctx, R.color.emerald_500)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// Copyright (c) 2023 Filippo Ferrario
// Copyright (c) 2024 Filippo Ferrario
// Licensed under the MIT License. See the LICENSE.

package com.ferrariofilippo.saveapp.util

import android.content.Context
import android.util.Log
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.doublePreferencesKey
Expand Down Expand Up @@ -80,7 +79,7 @@ object CurrencyUtil {
setDate(result.date)
setRates(rates)
} catch (e: Exception) {
Log.e("API", e.message ?: "")
LogUtil.logException(e, javaClass.kotlin.simpleName ?: "", "init")
rates = getRates()
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ object ImportExportUtil {
StatsUtil.addMovementToStat(app, it)
}
}
} catch (_: Exception) {
} catch (e: Exception) {
LogUtil.logException(e, javaClass.kotlin.simpleName ?: "", "importMovements")
}
}

Expand Down Expand Up @@ -239,7 +240,8 @@ object ImportExportUtil {
app.subscriptionRepository.update(it)
}
}
} catch (_: Exception) {
} catch (e: Exception) {
LogUtil.logException(e, javaClass.kotlin.simpleName ?: "", "importSubscriptions")
}
}

Expand Down Expand Up @@ -268,7 +270,8 @@ object ImportExportUtil {
app.budgetRepository.update(it)
}
}
} catch (_: Exception) {
} catch (e: Exception) {
LogUtil.logException(e, javaClass.kotlin.simpleName ?: "", "importBudgets")
}
}
}
66 changes: 66 additions & 0 deletions app/src/main/java/com/ferrariofilippo/saveapp/util/LogUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) 2024 Filippo Ferrario
// Licensed under the MIT License. See the LICENSE.

package com.ferrariofilippo.saveapp.util

import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.FileWriter
import java.io.IOException
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

object LogUtil {
private var _logFilePath = ""

fun setLogFilePath(path: String) {
_logFilePath = "$path/saveapp.log"
}

fun logException(e: Throwable, className: String, methodName: String) {
if (_logFilePath.isEmpty()) {
return
}

try {
val timeStamp = LocalDateTime
.now()
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
val formattedClassName = className.padEnd(30, ' ').substring(0, 20)
val formattedMethodName = methodName.padEnd(30, ' ').substring(0, 20)
FileWriter(_logFilePath, true).use {
it.write("$timeStamp|$formattedClassName|$formattedMethodName|${e.message}\n")
it.write(e.stackTraceToString())
it.flush()
}
} catch (_: IOException) {
}
}

fun exportLogTo(outStream: FileOutputStream?) {
if (outStream == null) {
return
}

try {
val writer = outStream.bufferedWriter()
FileInputStream(_logFilePath).use { input ->
writer.write(input.reader().readText())
}
writer.flush()
outStream.flush()
outStream.close()
} catch (_: IOException) {
}
}

fun clearLogs() {
try {
FileWriter(_logFilePath, false).use {
it.write("")
it.flush()
}
} catch (_: IOException) {
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.ferrariofilippo.saveapp.MainActivity
import com.ferrariofilippo.saveapp.R
import com.ferrariofilippo.saveapp.SaveAppApplication
import com.ferrariofilippo.saveapp.databinding.FragmentNewTagBinding
import com.ferrariofilippo.saveapp.util.ColorUtil
import com.ferrariofilippo.saveapp.view.adapters.ColorDropdownAdapter
import com.ferrariofilippo.saveapp.view.viewmodels.NewTagViewModel
import kotlinx.coroutines.runBlocking
Expand Down Expand Up @@ -64,7 +65,8 @@ class NewTagFragment : Fragment() {
viewModel.oldTag = tag
viewModel.tagName.value = tag?.name
viewModel.tagColor.value = tag?.color ?: R.color.emerald_700
viewModel.displayColor.value = application.getColor(viewModel.tagColor.value!!)
viewModel.displayColor.value =
ColorUtil.getColorOrDefault(application, viewModel.tagColor.value!!)
viewModel.isIncomeTag.value = tag?.isIncome
viewModel.isIncomeTagSwitchEnabled.value = false
}
Expand All @@ -91,7 +93,7 @@ class NewTagFragment : Fragment() {
colorAutoComplete.setOnItemClickListener { parent, _, position, _ ->
val selection = parent.adapter.getItem(position) as Int
viewModel.tagColor.value = selection
viewModel.displayColor.value = requireActivity().getColor(selection)
viewModel.displayColor.value = ColorUtil.getColorOrDefault(requireContext(), selection)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ import com.ferrariofilippo.saveapp.MainActivity
import com.ferrariofilippo.saveapp.SaveAppApplication
import com.ferrariofilippo.saveapp.databinding.FragmentSettingsBinding
import com.ferrariofilippo.saveapp.model.enums.Currencies
import com.ferrariofilippo.saveapp.util.LogUtil
import com.ferrariofilippo.saveapp.util.SettingsUtil
import com.ferrariofilippo.saveapp.view.viewmodels.SettingsViewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
Expand Down Expand Up @@ -121,5 +123,20 @@ class SettingsFragment : Fragment() {
val uri = Uri.parse("https://github.com/ferrariofilippo/SaveApp_Kotlin/issues/new")
startActivity(Intent(Intent.ACTION_VIEW, uri))
}
binding.clearLogsButton.setOnClickListener {
LogUtil.clearLogs()
Snackbar.make(
act.findViewById(com.ferrariofilippo.saveapp.R.id.containerView),
com.ferrariofilippo.saveapp.R.string.logs_cleared,
Snackbar.LENGTH_SHORT
).setAnchorView(act.findViewById(com.ferrariofilippo.saveapp.R.id.bottomAppBar)).show()
}
binding.exportLogsButton.setOnClickListener {
act.exportLogFile.launch("saveapp.log")
}
binding.privacyButton.setOnClickListener {
val uri = Uri.parse("https://saveapp.vercel.app/privacy")
startActivity(Intent(Intent.ACTION_VIEW, uri))
}
}
}
Loading

0 comments on commit 5fa2854

Please sign in to comment.