diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a03c893821..8c58593d8e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -86,7 +86,7 @@ diff --git a/app/src/main/java/com/ivy/wallet/ui/RootActivity.kt b/app/src/main/java/com/ivy/wallet/ui/RootActivity.kt index 3546c253ed..25e3226b7c 100644 --- a/app/src/main/java/com/ivy/wallet/ui/RootActivity.kt +++ b/app/src/main/java/com/ivy/wallet/ui/RootActivity.kt @@ -75,6 +75,8 @@ import com.ivy.wallet.ui.statistic.level2.ItemStatisticScreen import com.ivy.wallet.ui.test.TestScreen import com.ivy.wallet.ui.webView.WebViewScreen import com.ivy.wallet.ui.widget.AddTransactionWidget +import com.ivy.wallet.ui.widget.AddTransactionWidgetCompact +import com.ivy.wallet.ui.widget.WalletBalanceWidgetReceiver import com.ivy.wallet.utils.activityForResultLauncher import com.ivy.wallet.utils.convertLocalToUTC import com.ivy.wallet.utils.sendToCrashlytics @@ -140,6 +142,9 @@ class RootActivity : AppCompatActivity() { setupTimePicker() AddTransactionWidget.updateBroadcast(this) + AddTransactionWidgetCompact.updateBroadcast(this) + WalletBalanceWidgetReceiver.updateBroadcast(this) + setContent { val viewModel: RootViewModel = viewModel() diff --git a/app/src/main/java/com/ivy/wallet/ui/edit/EditTransactionViewModel.kt b/app/src/main/java/com/ivy/wallet/ui/edit/EditTransactionViewModel.kt index 1c29f61035..c156407f6f 100644 --- a/app/src/main/java/com/ivy/wallet/ui/edit/EditTransactionViewModel.kt +++ b/app/src/main/java/com/ivy/wallet/ui/edit/EditTransactionViewModel.kt @@ -15,7 +15,11 @@ import com.ivy.wallet.domain.data.TransactionType import com.ivy.wallet.domain.data.core.Account import com.ivy.wallet.domain.data.core.Category import com.ivy.wallet.domain.data.core.Transaction -import com.ivy.wallet.domain.deprecated.logic.* +import com.ivy.wallet.domain.deprecated.logic.AccountCreator +import com.ivy.wallet.domain.deprecated.logic.CategoryCreator +import com.ivy.wallet.domain.deprecated.logic.PaywallLogic +import com.ivy.wallet.domain.deprecated.logic.PlannedPaymentsLogic +import com.ivy.wallet.domain.deprecated.logic.SmartTitleSuggestionsLogic import com.ivy.wallet.domain.deprecated.logic.currency.ExchangeRatesLogic import com.ivy.wallet.domain.deprecated.logic.loantrasactions.LoanTransactionsLogic import com.ivy.wallet.domain.deprecated.logic.model.CreateAccountData @@ -23,14 +27,22 @@ import com.ivy.wallet.domain.deprecated.logic.model.CreateCategoryData import com.ivy.wallet.domain.deprecated.sync.uploader.TransactionUploader import com.ivy.wallet.domain.event.AccountsUpdatedEvent import com.ivy.wallet.io.persistence.SharedPrefs -import com.ivy.wallet.io.persistence.dao.* +import com.ivy.wallet.io.persistence.dao.AccountDao +import com.ivy.wallet.io.persistence.dao.CategoryDao +import com.ivy.wallet.io.persistence.dao.LoanDao +import com.ivy.wallet.io.persistence.dao.SettingsDao +import com.ivy.wallet.io.persistence.dao.TransactionDao import com.ivy.wallet.refreshWidget import com.ivy.wallet.ui.EditTransaction import com.ivy.wallet.ui.IvyWalletCtx import com.ivy.wallet.ui.Main import com.ivy.wallet.ui.loan.data.EditTransactionDisplayLoan -import com.ivy.wallet.ui.widget.WalletBalanceReceiver -import com.ivy.wallet.utils.* +import com.ivy.wallet.ui.widget.WalletBalanceWidgetReceiver +import com.ivy.wallet.utils.computationThread +import com.ivy.wallet.utils.ioThread +import com.ivy.wallet.utils.readOnly +import com.ivy.wallet.utils.timeNowUTC +import com.ivy.wallet.utils.uiThread import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -38,7 +50,7 @@ import kotlinx.coroutines.launch import org.greenrobot.eventbus.EventBus import java.math.BigDecimal import java.time.LocalDateTime -import java.util.* +import java.util.UUID import javax.inject.Inject @HiltViewModel @@ -538,7 +550,7 @@ class EditTransactionViewModel @Inject constructor( } transactionDao.save(loadedTransaction().toEntity()) - refreshWidget(WalletBalanceReceiver::class.java) + refreshWidget(WalletBalanceWidgetReceiver::class.java) } if (closeScreen) { diff --git a/app/src/main/java/com/ivy/wallet/ui/settings/SettingsViewModel.kt b/app/src/main/java/com/ivy/wallet/ui/settings/SettingsViewModel.kt index 68c458ae22..d5547c7392 100644 --- a/app/src/main/java/com/ivy/wallet/ui/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/ivy/wallet/ui/settings/SettingsViewModel.kt @@ -31,8 +31,14 @@ import com.ivy.wallet.refreshWidget import com.ivy.wallet.ui.IvyWalletCtx import com.ivy.wallet.ui.Main import com.ivy.wallet.ui.RootActivity -import com.ivy.wallet.ui.widget.WalletBalanceReceiver -import com.ivy.wallet.utils.* +import com.ivy.wallet.ui.widget.WalletBalanceWidgetReceiver +import com.ivy.wallet.utils.OpResult +import com.ivy.wallet.utils.asLiveData +import com.ivy.wallet.utils.formatNicelyWithTime +import com.ivy.wallet.utils.ioThread +import com.ivy.wallet.utils.sendToCrashlytics +import com.ivy.wallet.utils.timeNowUTC +import com.ivy.wallet.utils.uiThread import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -322,7 +328,7 @@ class SettingsViewModel @Inject constructor( sharedPrefs.putBoolean(SharedPrefs.APP_LOCK_ENABLED, lockApp) _lockApp.value = lockApp - refreshWidget(WalletBalanceReceiver::class.java) + refreshWidget(WalletBalanceWidgetReceiver::class.java) TestIdlingResource.decrement() } diff --git a/app/src/main/java/com/ivy/wallet/ui/widget/WalletBalanceWidget.kt b/app/src/main/java/com/ivy/wallet/ui/widget/WalletBalanceWidget.kt index 978ea4705e..4e527900ee 100644 --- a/app/src/main/java/com/ivy/wallet/ui/widget/WalletBalanceWidget.kt +++ b/app/src/main/java/com/ivy/wallet/ui/widget/WalletBalanceWidget.kt @@ -2,13 +2,14 @@ package com.ivy.wallet.ui.widget import android.appwidget.AppWidgetManager import android.content.Context -import androidx.compose.runtime.Composable import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey +import androidx.glance.GlanceId import androidx.glance.appwidget.GlanceAppWidget import androidx.glance.appwidget.GlanceAppWidgetManager import androidx.glance.appwidget.GlanceAppWidgetReceiver +import androidx.glance.appwidget.provideContent import androidx.glance.appwidget.state.updateAppWidgetState import androidx.glance.currentState import androidx.glance.state.PreferencesGlanceStateDefinition @@ -26,24 +27,31 @@ import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch import javax.inject.Inject -class WalletBalanceWidget: GlanceAppWidget() { +class WalletBalanceWidget : GlanceAppWidget() { - @Composable - override fun Content() { - val prefs = currentState() - val appLocked = prefs[booleanPreferencesKey("appLocked")] ?: false - val balance = prefs[stringPreferencesKey("balance")] ?: "0.00" - val currency = prefs[stringPreferencesKey("currency")] ?: "USD" - val income = prefs[stringPreferencesKey("income")] ?: "0.00" - val expense = prefs[stringPreferencesKey("expense")] ?: "0.00" + override suspend fun provideGlance(context: Context, id: GlanceId) { + provideContent { + val prefs = currentState() + val appLocked = prefs[booleanPreferencesKey("appLocked")] ?: false + val balance = prefs[stringPreferencesKey("balance")] ?: "0.00" + val currency = prefs[stringPreferencesKey("currency")] ?: "USD" + val income = prefs[stringPreferencesKey("income")] ?: "0.00" + val expense = prefs[stringPreferencesKey("expense")] ?: "0.00" - WalletBalanceWidgetContent(appLocked, balance, currency, income, expense) + WalletBalanceWidgetContent(appLocked, balance, currency, income, expense) + } } } @AndroidEntryPoint -class WalletBalanceReceiver : GlanceAppWidgetReceiver() { +class WalletBalanceWidgetReceiver : GlanceAppWidgetReceiver() { + companion object { + fun updateBroadcast(context: Context) { + WidgetBase.updateBroadcast(context, WalletBalanceWidgetReceiver::class.java) + } + } + override val glanceAppWidget: GlanceAppWidget = WalletBalanceWidget() private val coroutineScope = MainScope() @@ -92,15 +100,18 @@ class WalletBalanceReceiver : GlanceAppWidgetReceiver() { ) val glanceId = - GlanceAppWidgetManager(context).getGlanceIds(WalletBalanceWidget::class.java).firstOrNull() + GlanceAppWidgetManager(context).getGlanceIds(WalletBalanceWidget::class.java) + .firstOrNull() glanceId?.let { updateAppWidgetState(context, PreferencesGlanceStateDefinition, it) { pref -> pref.toMutablePreferences().apply { this[booleanPreferencesKey("appLocked")] = appLocked this[stringPreferencesKey("balance")] = shortenAmount(balance.toDouble()) this[stringPreferencesKey("currency")] = currency - this[stringPreferencesKey("income")] = shortenAmount(incomeExpense.income.toDouble()) - this[stringPreferencesKey("expense")] = shortenAmount(incomeExpense.expense.toDouble()) + this[stringPreferencesKey("income")] = + shortenAmount(incomeExpense.income.toDouble()) + this[stringPreferencesKey("expense")] = + shortenAmount(incomeExpense.expense.toDouble()) } } glanceAppWidget.update(context, it) diff --git a/app/src/main/java/com/ivy/wallet/ui/widget/WalletBalanceWidgetActions.kt b/app/src/main/java/com/ivy/wallet/ui/widget/WalletBalanceWidgetActions.kt index 0b4709c548..569e5f4cd3 100644 --- a/app/src/main/java/com/ivy/wallet/ui/widget/WalletBalanceWidgetActions.kt +++ b/app/src/main/java/com/ivy/wallet/ui/widget/WalletBalanceWidgetActions.kt @@ -1,7 +1,9 @@ package com.ivy.wallet.ui.widget +import android.annotation.SuppressLint import android.content.Context import android.content.Intent +import android.util.Log import androidx.glance.GlanceId import androidx.glance.action.ActionParameters import androidx.glance.appwidget.action.ActionCallback @@ -9,7 +11,12 @@ import com.ivy.wallet.domain.data.TransactionType import com.ivy.wallet.ui.RootActivity class WalletBalanceButtonsAction : ActionCallback { - override suspend fun onRun(context: Context, glanceId: GlanceId, parameters: ActionParameters) { + @SuppressLint("LogNotTimber") + override suspend fun onAction( + context: Context, + glanceId: GlanceId, + parameters: ActionParameters + ) { when (parameters[walletBtnActParam]) { AddTransactionWidgetClick.ACTION_ADD_INCOME -> { context.startActivity( @@ -21,6 +28,7 @@ class WalletBalanceButtonsAction : ActionCallback { } ) } + AddTransactionWidgetClick.ACTION_ADD_EXPENSE -> { context.startActivity( RootActivity.addTransactionStart( @@ -31,7 +39,9 @@ class WalletBalanceButtonsAction : ActionCallback { } ) } + AddTransactionWidgetClick.ACTION_ADD_TRANSFER -> { + Log.i("widget", "Clicked add transfer.") context.startActivity( RootActivity.addTransactionStart( context = context, @@ -41,13 +51,18 @@ class WalletBalanceButtonsAction : ActionCallback { } ) } + else -> return } } } -class WalletBalanceWidgetClickAction: ActionCallback { - override suspend fun onRun(context: Context, glanceId: GlanceId, parameters: ActionParameters) { +class WalletBalanceWidgetClickAction : ActionCallback { + override suspend fun onAction( + context: Context, + glanceId: GlanceId, + parameters: ActionParameters + ) { context.startActivity( RootActivity.getIntent( context = context diff --git a/buildSrc/src/main/java/com/ivy/wallet/buildsrc/dependencies.kt b/buildSrc/src/main/java/com/ivy/wallet/buildsrc/dependencies.kt index cab8cd3095..4714f2423f 100644 --- a/buildSrc/src/main/java/com/ivy/wallet/buildsrc/dependencies.kt +++ b/buildSrc/src/main/java/com/ivy/wallet/buildsrc/dependencies.kt @@ -129,7 +129,10 @@ fun DependencyHandler.Compose(version: String) { implementation("androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha05") // Jetpack Glance (Compose Widgets) - implementation("androidx.glance:glance-appwidget:1.0.0-alpha03") + // https://developer.android.com/jetpack/androidx/releases/glance + val glanceVersion = "1.0.0-rc01" + implementation("androidx.glance:glance-appwidget:$glanceVersion") + implementation("androidx.glance:glance-material3:$glanceVersion") Accompanist(version = "0.15.0")