From c93871430587a42cabc33c5461e32fa6a0430973 Mon Sep 17 00:00:00 2001 From: ILIYANGERMANOV Date: Sun, 27 Aug 2023 02:09:28 +0300 Subject: [PATCH] GitHub backups + Material3 migration (#2507) - GitHub backups MVP - Note: Auto-backups are NOT implemented, yet! - Migrate Material2 components to Material3. (verify that the UI still works and looks okay) --- .idea/.gitignore | 2 + app/build.gradle.kts | 17 +- .../main/java/com/ivy/wallet/AppModuleDI.kt | 26 - .../backup/github/GitHubAutoBackupManager.kt | 9 + .../ivy/wallet/backup/github/GitHubBackup.kt | 113 ++++ .../ivy/wallet/backup/github/GitHubClient.kt | 104 +++ .../wallet/backup/github/GitHubCredentials.kt | 7 + .../backup/github/GitHubCredentialsManager.kt | 89 +++ .../backup/github/ui/GitHubBackupCard.kt | 213 +++++++ .../backup/github/ui/GitHubBackupScreen.kt | 147 +++++ .../backup/github/ui/GitHubBackupViewModel.kt | 82 +++ .../kotlinxserilzation/UUIDSerializer.kt | 20 + .../com/ivy/wallet/backup/ktor/KtorClient.kt | 28 + .../wallet/backup/ktor/KtorClientModule.kt | 18 + .../ivy/wallet/data/EncryptedSharedPrefs.kt | 38 ++ .../com/ivy/wallet/data/IvyWalletDatastore.kt | 19 + .../com/ivy/wallet/datetime/DateTimeUtil.kt | 15 + .../domain/action/charts/PieChartAct.kt | 4 +- .../wallet/domain/data/core/Transaction.kt | 2 +- ...ExportZipLogic.kt => ExportBackupLogic.kt} | 7 +- .../com/ivy/wallet/domain/pure/util/Utils.kt | 11 +- .../io/persistence/datastore/IvyDataStore.kt | 1 + .../java/com/ivy/wallet/ui/RootActivity.kt | 2 + .../com/ivy/wallet/ui/accounts/AccountsTab.kt | 31 +- .../wallet/ui/accounts/IncomeExpensesRow.kt | 11 +- .../ui/analytics/AnalyticsReportScreen.kt | 15 +- .../com/ivy/wallet/ui/analytics/DataCircle.kt | 2 +- .../wallet/ui/applocked/AppLockedScreen.kt | 13 +- .../ivy/wallet/ui/balance/BalanceScreen.kt | 25 +- .../com/ivy/wallet/ui/budget/BudgetScreen.kt | 21 +- .../wallet/ui/category/CategoriesScreen.kt | 45 +- .../com/ivy/wallet/ui/charts/ChartsScreen.kt | 19 +- .../wallet/ui/charts/charts/CategoryCharts.kt | 8 +- .../wallet/ui/charts/charts/WalletCharts.kt | 14 +- .../transaction/HistoryDateDivider.kt | 9 +- .../component/transaction/TransactionCard.kt | 34 +- .../transaction/TransactionSectionDivider.kt | 9 +- .../ui/component/transaction/Transactions.kt | 15 +- .../transaction/TransactionsDividerLine.kt | 2 +- .../java/com/ivy/wallet/ui/csv/CSVScreen.kt | 27 +- .../wallet/ui/csvimport/ImportViewModel.kt | 6 +- .../wallet/ui/csvimport/flow/ImportFrom.kt | 18 +- .../ui/csvimport/flow/ImportProcessing.kt | 17 +- .../ui/csvimport/flow/ImportResultUI.kt | 19 +- .../flow/instructions/ImportInstructions.kt | 17 +- .../com/ivy/wallet/ui/donate/DonateModal.kt | 2 +- .../com/ivy/wallet/ui/donate/DonateScreen.kt | 9 +- .../wallet/ui/edit/EditTransactionScreen.kt | 50 +- .../wallet/ui/edit/PrimaryAttributeColumn.kt | 12 +- .../ivy/wallet/ui/edit/TransactionDateTime.kt | 9 +- .../ivy/wallet/ui/edit/core/Description.kt | 2 +- .../com/ivy/wallet/ui/edit/core/DueDate.kt | 8 +- .../wallet/ui/edit/core/EditBottomSheet.kt | 55 +- .../java/com/ivy/wallet/ui/edit/core/Title.kt | 4 +- .../ui/exchangerates/ExchangeRatesScreen.kt | 20 +- .../ui/exchangerates/component/RateItem.kt | 2 +- .../ui/exchangerates/modal/AddRateModal.kt | 12 +- .../com/ivy/wallet/ui/home/CustomerJourney.kt | 10 +- .../java/com/ivy/wallet/ui/home/HomeHeader.kt | 27 +- .../com/ivy/wallet/ui/home/HomeMoreMenu.kt | 56 +- .../java/com/ivy/wallet/ui/home/HomeTab.kt | 24 +- .../com/ivy/wallet/ui/loan/LoansScreen.kt | 36 +- .../ui/loandetails/LoanDetailsScreen.kt | 79 ++- .../com/ivy/wallet/ui/main/MainBottomBar.kt | 44 +- .../components/OnboardingToolbar.kt | 2 +- .../ui/onboarding/components/Suggestions.kt | 8 +- .../ui/onboarding/steps/OnboardingAccounts.kt | 39 +- .../onboarding/steps/OnboardingCategories.kt | 34 +- .../onboarding/steps/OnboardingSetCurrency.kt | 20 +- .../onboarding/steps/OnboardingSplashLogin.kt | 33 +- .../ui/onboarding/steps/OnboardingType.kt | 19 +- .../steps/archived/OnboardingPrivacyTC.kt | 24 +- .../steps/archived/OnboardingSetName.kt | 27 +- .../ivy/wallet/ui/paywall/PaywallScreen.kt | 29 +- .../com/ivy/wallet/ui/paywall/PlansSheet.kt | 47 +- .../ui/planned/edit/EditPlannedScreen.kt | 29 +- .../wallet/ui/planned/edit/RecurringRule.kt | 10 +- .../ui/planned/list/PlannedPaymentCard.kt | 17 +- .../planned/list/PlannedPaymentsLazyColumn.kt | 25 +- .../ui/planned/list/PlannedPaymentsScreen.kt | 2 +- .../ivy/wallet/ui/reports/FilterOverlay.kt | 49 +- .../com/ivy/wallet/ui/reports/ReportScreen.kt | 33 +- .../com/ivy/wallet/ui/search/SearchScreen.kt | 25 +- .../wallet/ui/serverstop/ServerStopScreen.kt | 2 +- .../ui/serverstop/ServerStopViewModel.kt | 6 +- .../ivy/wallet/ui/settings/SettingsScreen.kt | 74 ++- .../wallet/ui/settings/SettingsViewModel.kt | 6 +- .../level1/PieChartStatisticScreen.kt | 53 +- .../statistic/level2/ItemStatisticScreen.kt | 63 +- .../java/com/ivy/wallet/ui/test/TestScreen.kt | 4 +- .../com/ivy/wallet/ui/test/TestViewModel.kt | 4 +- .../components/AddPrimaryAttributeButton.kt | 9 +- .../wallet/ui/theme/components/BalanceRow.kt | 2 +- .../ui/theme/components/BudgetBattery.kt | 21 +- .../ui/theme/components/BufferBattery.kt | 21 +- .../components/ChangeTransactionTypeModal.kt | 18 +- .../ui/theme/components/CircleButtons.kt | 2 +- .../ui/theme/components/CurrencyPicker.kt | 26 +- .../components/CustomExchangeRateCard.kt | 11 +- .../ui/theme/components/IntervalPickerRow.kt | 15 +- .../ui/theme/components/IvyBasicTextField.kt | 8 +- .../ui/theme/components/IvyBorderButton.kt | 4 +- .../wallet/ui/theme/components/IvyButton.kt | 11 +- .../wallet/ui/theme/components/IvyCheckbox.kt | 10 +- .../theme/components/IvyChecklistTextField.kt | 8 +- .../ui/theme/components/IvyColorPicker.kt | 65 +- .../components/IvyDescriptionTextField.kt | 8 +- .../ivy/wallet/ui/theme/components/IvyIcon.kt | 2 +- .../theme/components/IvyNameTextFieldValue.kt | 15 +- .../ui/theme/components/IvyNumberTextField.kt | 8 +- .../ui/theme/components/IvyOutlinedButton.kt | 8 +- .../theme/components/IvyOutlinedTextField.kt | 2 +- .../ui/theme/components/IvyTitleTextField.kt | 17 +- .../theme/components/OnboardingComponents.kt | 2 +- .../ui/theme/components/ReorderModal.kt | 2 +- .../ui/theme/components/WrapContentRow.kt | 2 +- .../wallet/ui/theme/modal/AddKeywordModal.kt | 10 +- .../ivy/wallet/ui/theme/modal/BudgetModal.kt | 19 +- .../ui/theme/modal/ChoosePeriodModal.kt | 37 +- .../modal/ChooseStartDateOfMonthModal.kt | 13 +- .../wallet/ui/theme/modal/CurrencyModal.kt | 16 +- .../ivy/wallet/ui/theme/modal/DeleteModal.kt | 5 +- .../com/ivy/wallet/ui/theme/modal/IvyModal.kt | 39 +- .../ui/theme/modal/IvyModalComponents.kt | 2 +- .../theme/modal/IvyModalDomainComponents.kt | 2 +- .../ivy/wallet/ui/theme/modal/LoanModal.kt | 34 +- .../wallet/ui/theme/modal/LoanRecordModal.kt | 29 +- .../wallet/ui/theme/modal/MonthPickerModal.kt | 16 +- .../ivy/wallet/ui/theme/modal/NameModal.kt | 10 +- .../wallet/ui/theme/modal/ProgressModal.kt | 12 +- .../ui/theme/modal/RecurringRuleModal.kt | 33 +- .../ui/theme/modal/edit/AccountModal.kt | 30 +- .../wallet/ui/theme/modal/edit/AmountModal.kt | 31 +- .../ui/theme/modal/edit/CalculatorModal.kt | 23 +- .../theme/modal/edit/ChooseCategoryModal.kt | 25 +- .../ui/theme/modal/edit/DescriptionModal.kt | 16 +- .../wallet/ui/theme/wallet/AmountCurrency.kt | 2 +- .../wallet/ui/theme/wallet/PeriodSelector.kt | 12 +- .../ivy/wallet/ui/webView/WebViewScreen.kt | 2 +- buildSrc/build.gradle.kts | 8 +- .../com/ivy/wallet/buildsrc/dependencies.kt | 168 +---- docs/Business-Model.md | 75 --- docs/Developer-Guidelines.md | 599 ------------------ docs/Ivy-Dao.md | 35 - docs/modularization.md | 83 --- gradle/libs.versions.toml | 105 +++ ivy-design/build.gradle.kts | 6 +- .../src/main/java/com/ivy/design/api/IvyUI.kt | 36 +- .../java/com/ivy/design/l0_system/IvyTheme.kt | 55 +- .../design/l1_buildingBlocks/ColumnRoot.kt | 4 +- .../ivy/design/l1_buildingBlocks/IvyIcon.kt | 4 +- .../ivy/design/l1_buildingBlocks/IvyText.kt | 2 +- .../com/ivy/design/l2_components/Button.kt | 2 +- .../design/l2_components/ButtonWithIcon.kt | 2 +- .../com/ivy/design/l2_components/Checkbox.kt | 2 +- .../design/l3_ivyComponents/ScreenTitle.kt | 2 +- .../java/com/ivy/design/ExampleUnitTest.kt | 16 - settings.gradle.kts | 3 +- 158 files changed, 2904 insertions(+), 1514 deletions(-) create mode 100644 app/src/main/java/com/ivy/wallet/backup/github/GitHubAutoBackupManager.kt create mode 100644 app/src/main/java/com/ivy/wallet/backup/github/GitHubBackup.kt create mode 100644 app/src/main/java/com/ivy/wallet/backup/github/GitHubClient.kt create mode 100644 app/src/main/java/com/ivy/wallet/backup/github/GitHubCredentials.kt create mode 100644 app/src/main/java/com/ivy/wallet/backup/github/GitHubCredentialsManager.kt create mode 100644 app/src/main/java/com/ivy/wallet/backup/github/ui/GitHubBackupCard.kt create mode 100644 app/src/main/java/com/ivy/wallet/backup/github/ui/GitHubBackupScreen.kt create mode 100644 app/src/main/java/com/ivy/wallet/backup/github/ui/GitHubBackupViewModel.kt create mode 100644 app/src/main/java/com/ivy/wallet/backup/kotlinxserilzation/UUIDSerializer.kt create mode 100644 app/src/main/java/com/ivy/wallet/backup/ktor/KtorClient.kt create mode 100644 app/src/main/java/com/ivy/wallet/backup/ktor/KtorClientModule.kt create mode 100644 app/src/main/java/com/ivy/wallet/data/EncryptedSharedPrefs.kt create mode 100644 app/src/main/java/com/ivy/wallet/data/IvyWalletDatastore.kt create mode 100644 app/src/main/java/com/ivy/wallet/datetime/DateTimeUtil.kt rename app/src/main/java/com/ivy/wallet/domain/deprecated/logic/zip/{ExportZipLogic.kt => ExportBackupLogic.kt} (98%) delete mode 100644 docs/Business-Model.md delete mode 100644 docs/Developer-Guidelines.md delete mode 100644 docs/Ivy-Dao.md delete mode 100644 docs/modularization.md create mode 100644 gradle/libs.versions.toml delete mode 100644 ivy-design/src/test/java/com/ivy/design/ExampleUnitTest.kt diff --git a/.idea/.gitignore b/.idea/.gitignore index 26d33521af..8353b4cd73 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -1,3 +1,5 @@ # Default ignored files /shelf/ /workspace.xml +/deploymentTargetDropDown.xml +/migrations.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 37dfdde195..01aaa31c44 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -9,6 +9,8 @@ plugins { id("com.google.firebase.crashlytics") id("org.jetbrains.kotlin.android") id("dagger.hilt.android.plugin") + + alias(libs.plugins.kotlinx.serialization) } android { @@ -114,7 +116,7 @@ android { } composeOptions { - kotlinCompilerExtensionVersion = com.ivy.wallet.buildsrc.GlobalVersions.compose + kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get() } lint { @@ -139,4 +141,17 @@ android { dependencies { appModuleDependencies() + implementation(project(":ivy-design")) + + implementation(libs.ivy.frp.temp) + implementation(libs.bundles.kotlin) + implementation(libs.bundles.ktor) + implementation(libs.bundles.arrow) + implementation(libs.bundles.compose) + implementation(libs.bundles.glance) + implementation(libs.datastore) + implementation(libs.androidx.security) + + testImplementation(libs.bundles.kotest) + testImplementation(libs.bundles.kotlin.test) } diff --git a/app/src/main/java/com/ivy/wallet/AppModuleDI.kt b/app/src/main/java/com/ivy/wallet/AppModuleDI.kt index 206c16516a..d4f4f0c2f6 100644 --- a/app/src/main/java/com/ivy/wallet/AppModuleDI.kt +++ b/app/src/main/java/com/ivy/wallet/AppModuleDI.kt @@ -14,7 +14,6 @@ import com.ivy.wallet.domain.deprecated.logic.loantrasactions.LTLoanRecordMapper import com.ivy.wallet.domain.deprecated.logic.loantrasactions.LoanTransactionsCore import com.ivy.wallet.domain.deprecated.logic.loantrasactions.LoanTransactionsLogic import com.ivy.wallet.domain.deprecated.logic.notification.TransactionReminderLogic -import com.ivy.wallet.domain.deprecated.logic.zip.ExportZipLogic import com.ivy.wallet.domain.deprecated.sync.IvySync import com.ivy.wallet.domain.deprecated.sync.item.* import com.ivy.wallet.domain.deprecated.sync.uploader.* @@ -715,31 +714,6 @@ object AppModuleDI { ) } - @Provides - fun providesExportZipLogic( - accountDao: AccountDao, - budgetDao: BudgetDao, - categoryDao: CategoryDao, - loanRecordDao: LoanRecordDao, - loanDao: LoanDao, - plannedPaymentRuleDao: PlannedPaymentRuleDao, - settingsDao: SettingsDao, - transactionDao: TransactionDao, - sharedPrefs: SharedPrefs - ): ExportZipLogic { - return ExportZipLogic( - accountDao, - budgetDao, - categoryDao, - loanRecordDao, - loanDao, - plannedPaymentRuleDao, - settingsDao, - transactionDao, - sharedPrefs - ) - } - @Provides fun provideExpImagesService(): ExpImagesService = object : ExpImagesService { override suspend fun fetchImages(): List { diff --git a/app/src/main/java/com/ivy/wallet/backup/github/GitHubAutoBackupManager.kt b/app/src/main/java/com/ivy/wallet/backup/github/GitHubAutoBackupManager.kt new file mode 100644 index 0000000000..7bc95b872e --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/backup/github/GitHubAutoBackupManager.kt @@ -0,0 +1,9 @@ +package com.ivy.wallet.backup.github + +import javax.inject.Inject + +class GitHubAutoBackupManager @Inject constructor() { + fun scheduleAutoBackups() { + // TODO: + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/backup/github/GitHubBackup.kt b/app/src/main/java/com/ivy/wallet/backup/github/GitHubBackup.kt new file mode 100644 index 0000000000..c9e7237c28 --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/backup/github/GitHubBackup.kt @@ -0,0 +1,113 @@ +package com.ivy.wallet.backup.github + +import android.content.Context +import androidx.datastore.preferences.core.edit +import arrow.core.Either +import arrow.core.raise.either +import arrow.core.raise.ensureNotNull +import com.ivy.wallet.data.DatastoreKeys +import com.ivy.wallet.data.dataStore +import com.ivy.wallet.domain.deprecated.logic.zip.ExportBackupLogic +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.withContext +import java.time.Instant +import javax.inject.Inject + +class GitHubBackup @Inject constructor( + private val client: GitHubClient, + private val credentialsManager: GitHubCredentialsManager, + private val exportBackupLogic: ExportBackupLogic, + @ApplicationContext + private val appContext: Context +) { + private val enabledInternalState = MutableStateFlow(null) + private val lastBackupTimeState = MutableStateFlow(null) + + val enabled: Flow = enabledInternalState.map { state -> + state ?: credentialsManager.getCredentials().isRight().also { + enabledInternalState.value = it + } + }.distinctUntilChanged() + + val lastBackupTime: Flow = lastBackupTimeState.map { state -> + val epochSeconds = state ?: appContext.dataStore.data + .firstOrNull()?.let { it[DatastoreKeys.GITHUB_LAST_BACKUP_EPOCH_SEC] } + + epochSeconds?.let(Instant::ofEpochSecond) + } + + suspend fun enable( + gitHubUrl: String, + gitHubPAT: String, + ): Either = either { + val regex = """https?://(?:www\.)?github\.com/([^/]+)/([^/]+)""".toRegex() + val matchResult = regex.find(gitHubUrl) + + val owner = matchResult?.groups?.get(1)?.value + ensureNotNull(owner) { + "Couldn't parse 'owner' from \"$gitHubUrl.\"" + } + val repo = matchResult.groups[2]?.value + ensureNotNull(repo) { + "Couldn't parse 'repo' from \"$gitHubUrl.\"" + } + + credentialsManager.saveCredentials( + owner = owner, + repo = repo, + gitHubPAT = gitHubPAT, + ).bind() + enabledInternalState.value = true + } + + suspend fun disable() { + credentialsManager.removeSaved() + enabledInternalState.value = false + } + + suspend fun repoUrl(): String? { + return credentialsManager.getCredentials() + .map { "https://github.com/${it.owner}/${it.repo}" } + .getOrNull() + } + + suspend fun backupData(): Either = withContext(Dispatchers.IO) { + either { + val credentials = credentialsManager.getCredentials() + .mapLeft(Error::MissingCredentials).bind() + + val json = exportBackupLogic.generateJsonBackup() + client.commit( + credentials = credentials, + path = "Ivy-Wallet-backup.json", + content = json, + ).mapLeft(Error::Commit).bind() + + appContext.dataStore.edit { + val epochSecondsNow = Instant.now().epochSecond + it[DatastoreKeys.GITHUB_LAST_BACKUP_EPOCH_SEC] = epochSecondsNow + lastBackupTimeState.value = epochSecondsNow + } + } + } + + sealed interface Error { + val humanReadable: String + + data class MissingCredentials(val error: String) : Error { + override val humanReadable: String + get() = "Missing credentials: $error." + } + + data class Commit(val error: String) : Error { + override val humanReadable: String + get() = "Failed to commit: $error." + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/backup/github/GitHubClient.kt b/app/src/main/java/com/ivy/wallet/backup/github/GitHubClient.kt new file mode 100644 index 0000000000..8dc71c64e3 --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/backup/github/GitHubClient.kt @@ -0,0 +1,104 @@ +package com.ivy.wallet.backup.github + +import androidx.annotation.Keep +import arrow.core.Either +import arrow.core.raise.catch +import arrow.core.raise.either +import arrow.core.raise.ensure +import dagger.Lazy +import io.ktor.client.HttpClient +import io.ktor.client.call.body +import io.ktor.client.request.get +import io.ktor.client.request.headers +import io.ktor.client.request.put +import io.ktor.client.request.setBody +import io.ktor.http.ContentType +import io.ktor.http.HeadersBuilder +import io.ktor.http.contentType +import io.ktor.http.isSuccess +import io.ktor.util.encodeBase64 +import kotlinx.serialization.Serializable +import javax.inject.Inject + + +class GitHubClient @Inject constructor( + private val httpClient: Lazy, +) { + @Keep + @Serializable + data class GitHubFileContent( + val content: String, + val message: String, + val committer: Committer, + val sha: String?, + ) + + @Keep + @Serializable + data class Committer(val name: String, val email: String) + + @Keep + @Serializable + data class GitHubFileResponse(val sha: String) + + suspend fun commit( + credentials: GitHubCredentials, + path: String, + content: String, + ): Either = either { + val url = repoUrl(credentials, path) + val sha = getExistingFileSha(credentials, url) + + val encodedContent = content.toByteArray(Charsets.UTF_16).encodeBase64() + + val requestBody = GitHubFileContent( + content = encodedContent, + message = "Committing from Ktor", + committer = Committer(name = "Ivy Wallet", email = "ivywalelt@ivy-bot.com"), + sha = sha, + ) + + val response = httpClient.get().put(url) { + headers { + githubToken(credentials) + contentType(ContentType.Application.Json) + acceptsUtf16() + } + setBody(requestBody) + } + ensure(response.status.isSuccess()) { + "Unsuccessful response: ${response.status}" + } + return Either.Right(Unit) + } + + private suspend fun getExistingFileSha( + credentials: GitHubCredentials, + url: String + ): String? = catch({ + // Fetch the current file to get its SHA + httpClient.get().get(url) { + headers { + githubToken(credentials) + } + }.body().sha + + }) { + null + } + + private fun HeadersBuilder.githubToken(credentials: GitHubCredentials) { + append("Authorization", "token ${credentials.accessToken}") + } + + private fun HeadersBuilder.acceptsUtf16() { + append("Accept-Charset", "UTF-16") + } + + private fun repoUrl( + credentials: GitHubCredentials, + path: String + ): String { + return "https://api.github.com/repos/${credentials.owner}/${credentials.repo}/contents/$path" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/backup/github/GitHubCredentials.kt b/app/src/main/java/com/ivy/wallet/backup/github/GitHubCredentials.kt new file mode 100644 index 0000000000..6aefe8e598 --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/backup/github/GitHubCredentials.kt @@ -0,0 +1,7 @@ +package com.ivy.wallet.backup.github + +data class GitHubCredentials( + val owner: String, + val repo: String, + val accessToken: String, +) \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/backup/github/GitHubCredentialsManager.kt b/app/src/main/java/com/ivy/wallet/backup/github/GitHubCredentialsManager.kt new file mode 100644 index 0000000000..577ebe6095 --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/backup/github/GitHubCredentialsManager.kt @@ -0,0 +1,89 @@ +package com.ivy.wallet.backup.github + +import android.content.Context +import android.content.SharedPreferences +import androidx.datastore.preferences.core.edit +import arrow.core.Either +import arrow.core.raise.either +import arrow.core.raise.ensureNotNull +import com.ivy.wallet.data.DatastoreKeys +import com.ivy.wallet.data.EncryptedPrefsKeys +import com.ivy.wallet.data.EncryptedSharedPrefs +import com.ivy.wallet.data.dataStore +import dagger.Lazy +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.withContext +import javax.inject.Inject + +class GitHubCredentialsManager @Inject constructor( + @EncryptedSharedPrefs + private val encryptedSharedPrefs: Lazy, + @ApplicationContext + private val appContext: Context, +) { + + suspend fun getCredentials(): Either = withContext(Dispatchers.IO) { + either { + val token = getGitHubPAT() + ensureNotNull(token) { + "GitHub PAT (Personal Access Token) isn't configured." + } + val data = appContext.dataStore.data.firstOrNull() + ensureNotNull(data) { + "Error: Datastore data is null!" + } + val owner = data[DatastoreKeys.GITHUB_OWNER] + ensureNotNull(owner) { + "GitHub owner isn't configured." + } + val repo = data[DatastoreKeys.GITHUB_REPO] + ensureNotNull(repo) { + "GitHub repo isn't configured." + } + + GitHubCredentials( + owner = owner, + repo = repo, + accessToken = token, + ) + } + } + + suspend fun saveCredentials( + owner: String, + repo: String, + gitHubPAT: String, + ): Either = withContext(Dispatchers.IO) { + either { + appContext.dataStore.edit { + it[DatastoreKeys.GITHUB_OWNER] = owner + it[DatastoreKeys.GITHUB_REPO] = repo + } + encryptedSharedPrefs.get().edit() + .putString(EncryptedPrefsKeys.BACKUP_GITHUB_PAT, gitHubPAT) + .apply() + } + } + + suspend fun removeSaved(): Unit = withContext(Dispatchers.IO) { + encryptedSharedPrefs.get().edit().remove(EncryptedPrefsKeys.BACKUP_GITHUB_PAT).apply() + appContext.dataStore.edit { + it.remove(DatastoreKeys.GITHUB_OWNER) + it.remove(DatastoreKeys.GITHUB_REPO) + } + } + + + private fun getGitHubPAT(): String? { + return encryptedSharedPrefs.get() + .getString(EncryptedPrefsKeys.BACKUP_GITHUB_PAT, null) + } + + private data class ParsedUrl( + val owner: String, + val repo: String, + ) +} + diff --git a/app/src/main/java/com/ivy/wallet/backup/github/ui/GitHubBackupCard.kt b/app/src/main/java/com/ivy/wallet/backup/github/ui/GitHubBackupCard.kt new file mode 100644 index 0000000000..66c2b9e8f5 --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/backup/github/ui/GitHubBackupCard.kt @@ -0,0 +1,213 @@ +package com.ivy.wallet.backup.github.ui + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.ElevatedButton +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalUriHandler +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import com.ivy.design.l0_system.UI +import com.ivy.frp.view.navigation.navigation +import com.ivy.wallet.R +import com.ivy.wallet.ui.theme.Orange + +@Composable +fun GitHubBackupCard( + modifier: Modifier = Modifier, +) { + val viewModel = viewModel() + val enabled by viewModel.enabled.collectAsState(initial = false) + + if (enabled) { + BackupEnabled( + modifier = modifier, + viewModel = viewModel + ) + } else { + BackupDisabled( + modifier = modifier, + ) + } +} + +@Composable +private fun BackupEnabled( + viewModel: GitHubBackupViewModel, + modifier: Modifier = Modifier, +) { + Card( + modifier = modifier, + shape = RoundedCornerShape(12.dp), + colors = CardDefaults.cardColors( + containerColor = UI.colors.medium, + contentColor = UI.colors.mediumInverse, + ) + ) { + Column( + modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), + ) { + Text( + modifier = Modifier, + text = "GitHub auto-backups", + style = MaterialTheme.typography.bodyLarge, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Start, + ) + GitHubBackupStatus(viewModel) + LastBackup(viewModel) + Spacer(modifier = Modifier.height(8.dp)) + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + ElevatedButton( + onClick = viewModel::backupData + ) { + Text(text = "Backup now") + } + Spacer(modifier = Modifier.width(16.dp)) + OutlinedButton( + onClick = viewModel::disableBackups, + colors = ButtonDefaults.outlinedButtonColors( + containerColor = MaterialTheme.colorScheme.error, + contentColor = MaterialTheme.colorScheme.onError, + ) + ) { + Text("Disable") + } + } + } + } +} + +@Composable +private fun GitHubBackupStatus( + viewModel: GitHubBackupViewModel, +) { + val status by viewModel.backupStatus.collectAsState() + if (status == null) return + + + when (val stat = status) { + is GitHubBackupStatus.Error -> { + Spacer(modifier = Modifier.height(8.dp)) + Text( + modifier = Modifier, + text = stat.error, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.error, + textAlign = TextAlign.Start, + ) + } + + GitHubBackupStatus.Loading -> { + Spacer(modifier = Modifier.height(8.dp)) + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + CircularProgressIndicator( + modifier = Modifier, + color = Orange, + ) + Spacer(modifier = Modifier.width(12.dp)) + Text( + modifier = Modifier, + text = "Backing up...", + color = Orange, + style = MaterialTheme.typography.bodyMedium, + textAlign = TextAlign.Start, + ) + } + } + + GitHubBackupStatus.Success -> { + Spacer(modifier = Modifier.height(8.dp)) + Text( + modifier = Modifier, + text = "Hurray! Backup successful!", + style = MaterialTheme.typography.bodyMedium, + color = UI.colors.green, + textAlign = TextAlign.Start, + ) + } + + null -> {} + } +} + +@Composable +private fun LastBackup( + viewModel: GitHubBackupViewModel, +) { + val lastBackupTime by viewModel.lastBackupTime.collectAsState(initial = null) + if (lastBackupTime != null) { + Spacer(modifier = Modifier.height(8.dp)) + Text( + modifier = Modifier, + text = "Last backup at $lastBackupTime", + color = UI.colors.gray, + style = MaterialTheme.typography.labelMedium, + textAlign = TextAlign.Start, + ) + Spacer(modifier = Modifier.height(8.dp)) + val uriHandler = LocalUriHandler.current + OutlinedButton( + onClick = { + viewModel.viewBackup(uriHandler::openUri) + } + ) { + Text("View backup") + } + } +} + +@Composable +private fun BackupDisabled( + modifier: Modifier = Modifier, +) { + val nav = navigation() + Button( + modifier = modifier, + onClick = { + nav.navigateTo(GitHubBackupScreen) + }, + shape = RoundedCornerShape(12.dp), + contentPadding = PaddingValues(horizontal = 16.dp, vertical = 12.dp) + ) { + Spacer(modifier = Modifier.width(4.dp)) + Image( + painter = painterResource(id = R.drawable.github_logo), + contentDescription = null, + contentScale = ContentScale.Fit, + colorFilter = ColorFilter.tint(LocalContentColor.current) + ) + Spacer(modifier = Modifier.width(16.dp)) + Text("Enable GitHub auto backups") + Spacer(modifier = Modifier.weight(1f)) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/backup/github/ui/GitHubBackupScreen.kt b/app/src/main/java/com/ivy/wallet/backup/github/ui/GitHubBackupScreen.kt new file mode 100644 index 0000000000..412c4bc205 --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/backup/github/ui/GitHubBackupScreen.kt @@ -0,0 +1,147 @@ +package com.ivy.wallet.backup.github.ui + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.outlined.Info +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.ElevatedButton +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FilledIconButton +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalUriHandler +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import com.ivy.frp.view.navigation.Screen +import com.ivy.frp.view.navigation.navigation + +private const val GITHUB_REPO_INFO_URL = + "https://docs.github.com/en/get-started/quickstart/create-a-repo" + +private const val GITHUB_PAT_INFO_URL = + "https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token" + +object GitHubBackupScreen : Screen + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun GitHubBackupScreen() { + val nav = navigation() + + Scaffold( + topBar = { + CenterAlignedTopAppBar( + title = { + Text( + text = "GitHub Backups", + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + }, + navigationIcon = { + IconButton(onClick = { + nav.back() + }) { + Icon( + imageVector = Icons.Filled.ArrowBack, + contentDescription = "Back" + ) + } + }, + ) + }, + content = { innerPadding -> + Content( + modifier = Modifier.padding(innerPadding) + ) + } + ) +} + +@Composable +private fun Content( + modifier: Modifier = Modifier, +) { + val viewModel = viewModel() + + Column( + modifier = modifier.padding(horizontal = 16.dp), + ) { + Spacer(modifier = Modifier.height(24.dp)) + + var repoUrl by rememberSaveable { mutableStateOf("") } + var accessToken by rememberSaveable { mutableStateOf("") } + + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + OutlinedTextField( + value = repoUrl, + onValueChange = { repoUrl = it }, + label = { Text("GitHub repo url") }, + ) + Spacer(modifier = Modifier.width(12.dp)) + InfoButton(infoUrl = GITHUB_REPO_INFO_URL) + } + + Spacer(modifier = Modifier.height(12.dp)) + + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + OutlinedTextField( + value = accessToken, + onValueChange = { accessToken = it }, + label = { Text("GitHub PAT") } + ) + Spacer(modifier = Modifier.width(12.dp)) + InfoButton(infoUrl = GITHUB_PAT_INFO_URL) + } + + Spacer(modifier = Modifier.height(24.dp)) + ElevatedButton( + onClick = { + viewModel.enableBackups(repoUrl, accessToken) + }, + enabled = repoUrl.isNotBlank() && accessToken.isNotBlank() + ) { + Text(text = "Connect") + } + } +} + +@Composable +private fun InfoButton( + infoUrl: String, + modifier: Modifier = Modifier, +) { + val uriHandler = LocalUriHandler.current + FilledIconButton( + modifier = modifier, + onClick = { + uriHandler.openUri(infoUrl) + } + ) { + Icon( + imageVector = Icons.Outlined.Info, + contentDescription = "Info" + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/backup/github/ui/GitHubBackupViewModel.kt b/app/src/main/java/com/ivy/wallet/backup/github/ui/GitHubBackupViewModel.kt new file mode 100644 index 0000000000..4decc4bb8b --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/backup/github/ui/GitHubBackupViewModel.kt @@ -0,0 +1,82 @@ +package com.ivy.wallet.backup.github.ui + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.ivy.frp.view.navigation.Navigation +import com.ivy.wallet.backup.github.GitHubAutoBackupManager +import com.ivy.wallet.backup.github.GitHubBackup +import com.ivy.wallet.datetime.format +import com.ivy.wallet.datetime.toLocal +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch +import java.time.format.FormatStyle +import javax.inject.Inject + +@HiltViewModel +class GitHubBackupViewModel @Inject constructor( + private val gitHubBackup: GitHubBackup, + private val navigation: Navigation, + private val gitHubAutoBackupManager: GitHubAutoBackupManager, +) : ViewModel() { + + val enabled = gitHubBackup.enabled + + val lastBackupTime: Flow = gitHubBackup.lastBackupTime.map { instant -> + instant?.toLocal()?.format(FormatStyle.MEDIUM) + } + + val backupStatus = MutableStateFlow(null) + + fun backupData() { + viewModelScope.launch { + backupStatus.value = GitHubBackupStatus.Loading + backupStatus.value = gitHubBackup.backupData().fold( + ifLeft = { GitHubBackupStatus.Error(it.humanReadable) }, + ifRight = { GitHubBackupStatus.Success } + ) + if (backupStatus.value == GitHubBackupStatus.Success) { + delay(2_000L) + backupStatus.value = null + } + } + } + + fun enableBackups( + gitHubUrl: String, + gitHubPAT: String, + ) { + viewModelScope.launch { + gitHubBackup.enable( + gitHubUrl = gitHubUrl.trim(), + gitHubPAT = gitHubPAT.trim(), + ).onRight { + gitHubAutoBackupManager.scheduleAutoBackups() + navigation.back() + } + } + } + + fun disableBackups() { + viewModelScope.launch { + gitHubBackup.disable() + } + } + + fun viewBackup(onOpenUrl: (String) -> Unit) { + viewModelScope.launch { + gitHubBackup.repoUrl()?.let { + onOpenUrl(it) + } + } + } +} + +sealed interface GitHubBackupStatus { + object Loading : GitHubBackupStatus + data class Error(val error: String) : GitHubBackupStatus + data object Success : GitHubBackupStatus +} \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/backup/kotlinxserilzation/UUIDSerializer.kt b/app/src/main/java/com/ivy/wallet/backup/kotlinxserilzation/UUIDSerializer.kt new file mode 100644 index 0000000000..ef51eecd19 --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/backup/kotlinxserilzation/UUIDSerializer.kt @@ -0,0 +1,20 @@ +package com.ivy.wallet.backup.kotlinxserilzation + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import java.util.UUID + +object UUIDSerializer : KSerializer { + override val descriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING) + + override fun deserialize(decoder: Decoder): UUID { + return UUID.fromString(decoder.decodeString()) + } + + override fun serialize(encoder: Encoder, value: UUID) { + encoder.encodeString(value.toString()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/backup/ktor/KtorClient.kt b/app/src/main/java/com/ivy/wallet/backup/ktor/KtorClient.kt new file mode 100644 index 0000000000..b7b34b6ea6 --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/backup/ktor/KtorClient.kt @@ -0,0 +1,28 @@ +package com.ivy.wallet.backup.ktor + +import io.ktor.client.HttpClient +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.plugins.logging.Logger +import io.ktor.client.plugins.logging.Logging +import io.ktor.serialization.kotlinx.json.json +import kotlinx.serialization.json.Json +import timber.log.Timber + +fun newKtorClient(): HttpClient { + return HttpClient { + install(ContentNegotiation) { + json(json = Json { + ignoreUnknownKeys = true + isLenient = true + }) + } + + install(Logging) { + logger = object : Logger { + override fun log(message: String) { + Timber.d(message) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/backup/ktor/KtorClientModule.kt b/app/src/main/java/com/ivy/wallet/backup/ktor/KtorClientModule.kt new file mode 100644 index 0000000000..e7964f552b --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/backup/ktor/KtorClientModule.kt @@ -0,0 +1,18 @@ +package com.ivy.wallet.backup.ktor + +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import io.ktor.client.HttpClient +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object KtorClientModule { + @Provides + @Singleton + fun provideKtorClient(): HttpClient { + return newKtorClient() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/data/EncryptedSharedPrefs.kt b/app/src/main/java/com/ivy/wallet/data/EncryptedSharedPrefs.kt new file mode 100644 index 0000000000..e32d968b1e --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/data/EncryptedSharedPrefs.kt @@ -0,0 +1,38 @@ +package com.ivy.wallet.data + +import android.content.Context +import android.content.SharedPreferences +import androidx.security.crypto.EncryptedSharedPreferences +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import javax.inject.Qualifier + +@Qualifier +@Retention(AnnotationRetention.RUNTIME) +annotation class EncryptedSharedPrefs + +@Module +@InstallIn(SingletonComponent::class) +object EncryptedSharedPrefsModule { + @EncryptedSharedPrefs + @Provides + fun provideEncryptedSharedPrefs( + @ApplicationContext + appContext: Context + ): SharedPreferences { + return EncryptedSharedPreferences.create( + "ivy_secure_shared_prefs_v1", + "ivy_master_key_v1", + appContext, + EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, + EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM + ) + } +} + +object EncryptedPrefsKeys { + const val BACKUP_GITHUB_PAT = "github_backup_pat" +} \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/data/IvyWalletDatastore.kt b/app/src/main/java/com/ivy/wallet/data/IvyWalletDatastore.kt new file mode 100644 index 0000000000..080f46927e --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/data/IvyWalletDatastore.kt @@ -0,0 +1,19 @@ +package com.ivy.wallet.data + +import android.content.Context +import androidx.datastore.core.DataStore +import androidx.datastore.preferences.core.Preferences +import androidx.datastore.preferences.core.longPreferencesKey +import androidx.datastore.preferences.core.stringPreferencesKey +import androidx.datastore.preferences.preferencesDataStore + +val Context.dataStore: DataStore by preferencesDataStore( + name = "ivy_wallet_datastore_v1" +) + +object DatastoreKeys { + val GITHUB_OWNER = stringPreferencesKey("github_backup_owner") + val GITHUB_REPO = stringPreferencesKey("github_backup_repo") + val GITHUB_LAST_BACKUP_EPOCH_SEC = + longPreferencesKey("github_backup_last_backup_time_epoch_sec") +} \ No newline at end of file diff --git a/app/src/main/java/com/ivy/wallet/datetime/DateTimeUtil.kt b/app/src/main/java/com/ivy/wallet/datetime/DateTimeUtil.kt new file mode 100644 index 0000000000..54b6fcb2d7 --- /dev/null +++ b/app/src/main/java/com/ivy/wallet/datetime/DateTimeUtil.kt @@ -0,0 +1,15 @@ +package com.ivy.wallet.datetime + +import java.time.Instant +import java.time.ZoneId +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter +import java.time.format.FormatStyle + +fun Instant.toLocal(): ZonedDateTime { + return ZonedDateTime.ofInstant(this, ZoneId.systemDefault()) +} + +fun ZonedDateTime.format(style: FormatStyle = FormatStyle.LONG): String { + return format(DateTimeFormatter.ofLocalizedDateTime(style)) +} diff --git a/app/src/main/java/com/ivy/wallet/domain/action/charts/PieChartAct.kt b/app/src/main/java/com/ivy/wallet/domain/action/charts/PieChartAct.kt index e20e682625..eac301f128 100644 --- a/app/src/main/java/com/ivy/wallet/domain/action/charts/PieChartAct.kt +++ b/app/src/main/java/com/ivy/wallet/domain/action/charts/PieChartAct.kt @@ -24,7 +24,7 @@ import com.ivy.wallet.ui.onboarding.model.FromToTimeRange import com.ivy.wallet.ui.statistic.level1.CategoryAmount import com.ivy.wallet.ui.theme.RedLight import java.math.BigDecimal -import java.util.* +import java.util.UUID import javax.inject.Inject class PieChartAct @Inject constructor( @@ -201,6 +201,7 @@ class PieChartAct @Inject constructor( else BigDecimal.ZERO } + TransactionType.EXPENSE -> { incExpQuad.expense + if (treatTransferAsIncExp) @@ -208,6 +209,7 @@ class PieChartAct @Inject constructor( else BigDecimal.ZERO } + else -> BigDecimal.ZERO } } diff --git a/app/src/main/java/com/ivy/wallet/domain/data/core/Transaction.kt b/app/src/main/java/com/ivy/wallet/domain/data/core/Transaction.kt index 28b810756c..73d937f149 100644 --- a/app/src/main/java/com/ivy/wallet/domain/data/core/Transaction.kt +++ b/app/src/main/java/com/ivy/wallet/domain/data/core/Transaction.kt @@ -6,7 +6,7 @@ import com.ivy.wallet.io.network.data.TransactionDTO import com.ivy.wallet.io.persistence.data.TransactionEntity import java.math.BigDecimal import java.time.LocalDateTime -import java.util.* +import java.util.UUID data class Transaction( //TODO: Remove default values & introduce Transaction#dummy() method diff --git a/app/src/main/java/com/ivy/wallet/domain/deprecated/logic/zip/ExportZipLogic.kt b/app/src/main/java/com/ivy/wallet/domain/deprecated/logic/zip/ExportBackupLogic.kt similarity index 98% rename from app/src/main/java/com/ivy/wallet/domain/deprecated/logic/zip/ExportZipLogic.kt rename to app/src/main/java/com/ivy/wallet/domain/deprecated/logic/zip/ExportBackupLogic.kt index 6776ba4cc8..307c31e4ca 100644 --- a/app/src/main/java/com/ivy/wallet/domain/deprecated/logic/zip/ExportZipLogic.kt +++ b/app/src/main/java/com/ivy/wallet/domain/deprecated/logic/zip/ExportBackupLogic.kt @@ -21,9 +21,10 @@ import java.time.Instant import java.time.LocalDateTime import java.time.ZoneOffset import java.util.* +import javax.inject.Inject -class ExportZipLogic( +class ExportBackupLogic @Inject constructor( private val accountDao: AccountDao, private val budgetDao: BudgetDao, private val categoryDao: CategoryDao, @@ -38,7 +39,7 @@ class ExportZipLogic( context: Context, zipFileUri: Uri ) { - val jsonString = generateJsonString() + val jsonString = generateJsonBackup() val file = createJsonDataFile(context, jsonString) zip(context = context, zipFileUri, listOf(file)) clearCacheDir(context) @@ -55,7 +56,7 @@ class ExportZipLogic( return file } - private suspend fun generateJsonString(): String { + suspend fun generateJsonBackup(): String { return scopedIOThread { val accounts = it.async { accountDao.findAll() } val budgets = it.async { budgetDao.findAll() } diff --git a/app/src/main/java/com/ivy/wallet/domain/pure/util/Utils.kt b/app/src/main/java/com/ivy/wallet/domain/pure/util/Utils.kt index 71c53d3627..bec0a01b90 100644 --- a/app/src/main/java/com/ivy/wallet/domain/pure/util/Utils.kt +++ b/app/src/main/java/com/ivy/wallet/domain/pure/util/Utils.kt @@ -2,6 +2,7 @@ package com.ivy.wallet.domain.pure.util import arrow.core.NonEmptyList import arrow.core.Option +import arrow.core.toNonEmptyListOrNull import java.math.BigDecimal fun NonEmptyList.mapIndexedNel( @@ -15,11 +16,11 @@ fun NonEmptyList.mapIndexedNel( suspend fun NonEmptyList.mapIndexedNelSuspend( f: suspend (Int, T) -> T ): NonEmptyList { - return NonEmptyList.fromListUnsafe( - this.mapIndexed { index, value -> - f(index, value) - } - ) + val result = mutableListOf() + for ((index, elem) in this.withIndex()) { + result.add(f(index, elem)) + } + return requireNotNull(result.toNonEmptyListOrNull()) } fun nonEmptyListOfZeros(n: Int): NonEmptyList { diff --git a/app/src/main/java/com/ivy/wallet/io/persistence/datastore/IvyDataStore.kt b/app/src/main/java/com/ivy/wallet/io/persistence/datastore/IvyDataStore.kt index 48556ae11d..1d16b6c631 100644 --- a/app/src/main/java/com/ivy/wallet/io/persistence/datastore/IvyDataStore.kt +++ b/app/src/main/java/com/ivy/wallet/io/persistence/datastore/IvyDataStore.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.map import javax.inject.Inject import javax.inject.Singleton +@Deprecated("legacy") @Singleton class IvyDataStore @Inject constructor( @ApplicationContext private val appContext: Context 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 25e3226b7c..acc3590740 100644 --- a/app/src/main/java/com/ivy/wallet/ui/RootActivity.kt +++ b/app/src/main/java/com/ivy/wallet/ui/RootActivity.kt @@ -46,6 +46,7 @@ import com.ivy.wallet.BuildConfig import com.ivy.wallet.Constants import com.ivy.wallet.Constants.SUPPORT_EMAIL import com.ivy.wallet.R +import com.ivy.wallet.backup.github.ui.GitHubBackupScreen import com.ivy.wallet.domain.data.TransactionType import com.ivy.wallet.domain.deprecated.logic.CustomerJourneyLogic import com.ivy.wallet.ui.analytics.AnalyticsReport @@ -229,6 +230,7 @@ class RootActivity : AppCompatActivity() { is IvyWebView -> WebViewScreen(screen = screen) is DonateScreen -> DonateScreen(screen = screen) is CSVScreen -> CSVScreen(screen = screen) + is GitHubBackupScreen -> GitHubBackupScreen() null -> { } } diff --git a/app/src/main/java/com/ivy/wallet/ui/accounts/AccountsTab.kt b/app/src/main/java/com/ivy/wallet/ui/accounts/AccountsTab.kt index 95e54695c7..14fedaf194 100644 --- a/app/src/main/java/com/ivy/wallet/ui/accounts/AccountsTab.kt +++ b/app/src/main/java/com/ivy/wallet/ui/accounts/AccountsTab.kt @@ -3,10 +3,20 @@ package com.ivy.wallet.ui.accounts import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -22,8 +32,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation @@ -34,8 +42,19 @@ import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.Main import com.ivy.wallet.ui.ivyWalletCtx import com.ivy.wallet.ui.main.MainTab -import com.ivy.wallet.ui.theme.* -import com.ivy.wallet.ui.theme.components.* +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.GreenDark +import com.ivy.wallet.ui.theme.GreenLight +import com.ivy.wallet.ui.theme.IvyDark +import com.ivy.wallet.ui.theme.components.BalanceRow +import com.ivy.wallet.ui.theme.components.BalanceRowMini +import com.ivy.wallet.ui.theme.components.ItemIconSDefaultIcon +import com.ivy.wallet.ui.theme.components.ReorderButton +import com.ivy.wallet.ui.theme.components.ReorderModalSingleType +import com.ivy.wallet.ui.theme.dynamicContrast +import com.ivy.wallet.ui.theme.findContrastTextColor +import com.ivy.wallet.ui.theme.toComposeColor import com.ivy.wallet.utils.UiText import com.ivy.wallet.utils.clickableNoIndication import com.ivy.wallet.utils.horizontalSwipeListener diff --git a/app/src/main/java/com/ivy/wallet/ui/accounts/IncomeExpensesRow.kt b/app/src/main/java/com/ivy/wallet/ui/accounts/IncomeExpensesRow.kt index 619e637076..bc62bfb4d5 100644 --- a/app/src/main/java/com/ivy/wallet/ui/accounts/IncomeExpensesRow.kt +++ b/app/src/main/java/com/ivy/wallet/ui/accounts/IncomeExpensesRow.kt @@ -1,8 +1,13 @@ package com.ivy.wallet.ui.accounts import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -11,9 +16,9 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import com.ivy.wallet.R import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style +import com.ivy.wallet.R import com.ivy.wallet.ui.theme.wallet.AmountCurrencyB1 @Composable diff --git a/app/src/main/java/com/ivy/wallet/ui/analytics/AnalyticsReportScreen.kt b/app/src/main/java/com/ivy/wallet/ui/analytics/AnalyticsReportScreen.kt index 1be89bcf0b..3a38ce9dd1 100644 --- a/app/src/main/java/com/ivy/wallet/ui/analytics/AnalyticsReportScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/analytics/AnalyticsReportScreen.kt @@ -1,9 +1,19 @@ package com.ivy.wallet.ui.analytics import androidx.compose.foundation.horizontalScroll -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState @@ -12,7 +22,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.colorAs import com.ivy.wallet.R diff --git a/app/src/main/java/com/ivy/wallet/ui/analytics/DataCircle.kt b/app/src/main/java/com/ivy/wallet/ui/analytics/DataCircle.kt index 880c7db50d..83dca8a44c 100644 --- a/app/src/main/java/com/ivy/wallet/ui/analytics/DataCircle.kt +++ b/app/src/main/java/com/ivy/wallet/ui/analytics/DataCircle.kt @@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/applocked/AppLockedScreen.kt b/app/src/main/java/com/ivy/wallet/ui/applocked/AppLockedScreen.kt index 6b040f1fb0..47083ad59c 100644 --- a/app/src/main/java/com/ivy/wallet/ui/applocked/AppLockedScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/applocked/AppLockedScreen.kt @@ -4,8 +4,16 @@ package com.ivy.wallet.ui.applocked import android.content.Context import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment @@ -19,7 +27,6 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.wallet.R diff --git a/app/src/main/java/com/ivy/wallet/ui/balance/BalanceScreen.kt b/app/src/main/java/com/ivy/wallet/ui/balance/BalanceScreen.kt index e7a7ddceaf..14e4d6a914 100644 --- a/app/src/main/java/com/ivy/wallet/ui/balance/BalanceScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/balance/BalanceScreen.kt @@ -1,8 +1,25 @@ package com.ivy.wallet.ui.balance -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.rotate @@ -13,8 +30,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.zIndex import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation diff --git a/app/src/main/java/com/ivy/wallet/ui/budget/BudgetScreen.kt b/app/src/main/java/com/ivy/wallet/ui/budget/BudgetScreen.kt index aae0b53b16..b22656047b 100644 --- a/app/src/main/java/com/ivy/wallet/ui/budget/BudgetScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/budget/BudgetScreen.kt @@ -1,10 +1,24 @@ package com.ivy.wallet.ui.budget -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag @@ -14,7 +28,6 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation diff --git a/app/src/main/java/com/ivy/wallet/ui/category/CategoriesScreen.kt b/app/src/main/java/com/ivy/wallet/ui/category/CategoriesScreen.kt index e8f6c3e8a6..e5a38c0c58 100644 --- a/app/src/main/java/com/ivy/wallet/ui/category/CategoriesScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/category/CategoriesScreen.kt @@ -4,11 +4,28 @@ import androidx.annotation.DrawableRes import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -23,8 +40,6 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation @@ -34,17 +49,31 @@ import com.ivy.wallet.domain.data.core.Category import com.ivy.wallet.ui.Categories import com.ivy.wallet.ui.ItemStatistic import com.ivy.wallet.ui.IvyWalletPreview -import com.ivy.wallet.ui.theme.* -import com.ivy.wallet.ui.theme.components.* +import com.ivy.wallet.ui.theme.Gradient +import com.ivy.wallet.ui.theme.GradientGreen +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.GreenDark +import com.ivy.wallet.ui.theme.GreenLight +import com.ivy.wallet.ui.theme.IvyDark +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.White +import com.ivy.wallet.ui.theme.components.BalanceRow +import com.ivy.wallet.ui.theme.components.CircleButtonFilled +import com.ivy.wallet.ui.theme.components.ItemIconSDefaultIcon +import com.ivy.wallet.ui.theme.components.IvyIcon +import com.ivy.wallet.ui.theme.components.ReorderButton +import com.ivy.wallet.ui.theme.components.ReorderModalSingleType +import com.ivy.wallet.ui.theme.findContrastTextColor import com.ivy.wallet.ui.theme.modal.IvyModal import com.ivy.wallet.ui.theme.modal.ModalSet import com.ivy.wallet.ui.theme.modal.ModalTitle import com.ivy.wallet.ui.theme.modal.edit.CategoryModal import com.ivy.wallet.ui.theme.modal.edit.CategoryModalData +import com.ivy.wallet.ui.theme.toComposeColor import com.ivy.wallet.ui.theme.wallet.AmountCurrencyB1 import com.ivy.wallet.utils.balancePrefix import com.ivy.wallet.utils.onScreenStart -import java.util.* +import java.util.UUID @Composable fun BoxWithConstraintsScope.CategoriesScreen(screen: Categories) { diff --git a/app/src/main/java/com/ivy/wallet/ui/charts/ChartsScreen.kt b/app/src/main/java/com/ivy/wallet/ui/charts/ChartsScreen.kt index 97b9b6ce3a..612d4cce7e 100644 --- a/app/src/main/java/com/ivy/wallet/ui/charts/ChartsScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/charts/ChartsScreen.kt @@ -3,10 +3,22 @@ package com.ivy.wallet.ui.charts import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -16,7 +28,6 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation diff --git a/app/src/main/java/com/ivy/wallet/ui/charts/charts/CategoryCharts.kt b/app/src/main/java/com/ivy/wallet/ui/charts/charts/CategoryCharts.kt index 637886d048..da22663d5e 100644 --- a/app/src/main/java/com/ivy/wallet/ui/charts/charts/CategoryCharts.kt +++ b/app/src/main/java/com/ivy/wallet/ui/charts/charts/CategoryCharts.kt @@ -7,8 +7,12 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag diff --git a/app/src/main/java/com/ivy/wallet/ui/charts/charts/WalletCharts.kt b/app/src/main/java/com/ivy/wallet/ui/charts/charts/WalletCharts.kt index 30b6e2f712..892d173da5 100644 --- a/app/src/main/java/com/ivy/wallet/ui/charts/charts/WalletCharts.kt +++ b/app/src/main/java/com/ivy/wallet/ui/charts/charts/WalletCharts.kt @@ -1,10 +1,18 @@ package com.ivy.wallet.ui.charts.charts import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color diff --git a/app/src/main/java/com/ivy/wallet/ui/component/transaction/HistoryDateDivider.kt b/app/src/main/java/com/ivy/wallet/ui/component/transaction/HistoryDateDivider.kt index 5a08d5a2cf..27bc6a2ed0 100644 --- a/app/src/main/java/com/ivy/wallet/ui/component/transaction/HistoryDateDivider.kt +++ b/app/src/main/java/com/ivy/wallet/ui/component/transaction/HistoryDateDivider.kt @@ -1,7 +1,12 @@ package com.ivy.wallet.ui.component.transaction -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/component/transaction/TransactionCard.kt b/app/src/main/java/com/ivy/wallet/ui/component/transaction/TransactionCard.kt index d17ed04af3..20cf2647dc 100644 --- a/app/src/main/java/com/ivy/wallet/ui/component/transaction/TransactionCard.kt +++ b/app/src/main/java/com/ivy/wallet/ui/component/transaction/TransactionCard.kt @@ -3,10 +3,17 @@ package com.ivy.wallet.ui.component.transaction import androidx.annotation.DrawableRes import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -32,12 +39,31 @@ import com.ivy.wallet.domain.data.core.Transaction import com.ivy.wallet.ui.ItemStatistic import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.data.AppBaseData -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.Gradient +import com.ivy.wallet.ui.theme.GradientGreen +import com.ivy.wallet.ui.theme.GradientIvy +import com.ivy.wallet.ui.theme.GradientOrangeRevert +import com.ivy.wallet.ui.theme.GradientRed +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.GreenDark +import com.ivy.wallet.ui.theme.Ivy +import com.ivy.wallet.ui.theme.IvyDark +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.ItemIconSDefaultIcon import com.ivy.wallet.ui.theme.components.IvyButton import com.ivy.wallet.ui.theme.components.IvyIcon +import com.ivy.wallet.ui.theme.findContrastTextColor +import com.ivy.wallet.ui.theme.gradientExpenses +import com.ivy.wallet.ui.theme.toComposeColor import com.ivy.wallet.ui.theme.wallet.AmountCurrencyB1 -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.dateNowUTC +import com.ivy.wallet.utils.format +import com.ivy.wallet.utils.formatNicely +import com.ivy.wallet.utils.isNotNullOrBlank +import com.ivy.wallet.utils.timeNowUTC import java.time.LocalDateTime diff --git a/app/src/main/java/com/ivy/wallet/ui/component/transaction/TransactionSectionDivider.kt b/app/src/main/java/com/ivy/wallet/ui/component/transaction/TransactionSectionDivider.kt index 02c6501ca3..4d1b66d16f 100644 --- a/app/src/main/java/com/ivy/wallet/ui/component/transaction/TransactionSectionDivider.kt +++ b/app/src/main/java/com/ivy/wallet/ui/component/transaction/TransactionSectionDivider.kt @@ -1,8 +1,13 @@ package com.ivy.wallet.ui.component.transaction import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment diff --git a/app/src/main/java/com/ivy/wallet/ui/component/transaction/Transactions.kt b/app/src/main/java/com/ivy/wallet/ui/component/transaction/Transactions.kt index 64db8e3433..f01be48c46 100644 --- a/app/src/main/java/com/ivy/wallet/ui/component/transaction/Transactions.kt +++ b/app/src/main/java/com/ivy/wallet/ui/component/transaction/Transactions.kt @@ -1,10 +1,14 @@ package com.ivy.wallet.ui.component.transaction -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.items -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -24,7 +28,12 @@ import com.ivy.wallet.stringRes import com.ivy.wallet.ui.EditTransaction import com.ivy.wallet.ui.data.AppBaseData import com.ivy.wallet.ui.data.DueSection -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.Black +import com.ivy.wallet.ui.theme.Gradient +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.IvyButton import com.ivy.wallet.ui.theme.components.IvyIcon diff --git a/app/src/main/java/com/ivy/wallet/ui/component/transaction/TransactionsDividerLine.kt b/app/src/main/java/com/ivy/wallet/ui/component/transaction/TransactionsDividerLine.kt index 1e0c00c449..b16aa4fd51 100644 --- a/app/src/main/java/com/ivy/wallet/ui/component/transaction/TransactionsDividerLine.kt +++ b/app/src/main/java/com/ivy/wallet/ui/component/transaction/TransactionsDividerLine.kt @@ -2,7 +2,7 @@ package com.ivy.wallet.ui.component.transaction import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.Divider +import androidx.compose.material3.Divider import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.Dp diff --git a/app/src/main/java/com/ivy/wallet/ui/csv/CSVScreen.kt b/app/src/main/java/com/ivy/wallet/ui/csv/CSVScreen.kt index a1bed8a8ca..abe9ddc1e6 100644 --- a/app/src/main/java/com/ivy/wallet/ui/csv/CSVScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/csv/CSVScreen.kt @@ -4,16 +4,29 @@ import android.net.Uri import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.horizontalScroll -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Button -import androidx.compose.material.ButtonDefaults -import androidx.compose.material.Text -import androidx.compose.material.TextField -import androidx.compose.runtime.* +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.TextRange @@ -22,7 +35,6 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.colorAs import com.ivy.wallet.ui.CSVScreen @@ -47,6 +59,7 @@ fun CSVScreen( launchedFromOnboarding = screen.launchedFromOnboarding, onEvent = viewModel::onEvent ) + is UIState.Processing -> ImportProcessing(progressPercent = ui.percent) is UIState.Result -> ImportResultUI( result = ui.importResult, diff --git a/app/src/main/java/com/ivy/wallet/ui/csvimport/ImportViewModel.kt b/app/src/main/java/com/ivy/wallet/ui/csvimport/ImportViewModel.kt index 118d07f32a..9e4c6c0615 100644 --- a/app/src/main/java/com/ivy/wallet/ui/csvimport/ImportViewModel.kt +++ b/app/src/main/java/com/ivy/wallet/ui/csvimport/ImportViewModel.kt @@ -13,7 +13,7 @@ import com.ivy.wallet.domain.deprecated.logic.csv.CSVNormalizer import com.ivy.wallet.domain.deprecated.logic.csv.IvyFileReader import com.ivy.wallet.domain.deprecated.logic.csv.model.ImportResult import com.ivy.wallet.domain.deprecated.logic.csv.model.ImportType -import com.ivy.wallet.domain.deprecated.logic.zip.ExportZipLogic +import com.ivy.wallet.domain.deprecated.logic.zip.ExportBackupLogic import com.ivy.wallet.ui.Import import com.ivy.wallet.ui.IvyWalletCtx import com.ivy.wallet.ui.onboarding.viewmodel.OnboardingViewModel @@ -35,7 +35,7 @@ class ImportViewModel @Inject constructor( private val csvNormalizer: CSVNormalizer, private val csvMapper: CSVMapper, private val csvImporter: CSVImporter, - private val exportZipLogic: ExportZipLogic + private val exportBackupLogic: ExportBackupLogic ) : ViewModel() { private val _importStep = MutableLiveData() val importStep = _importStep.asLiveData() @@ -83,7 +83,7 @@ class ImportViewModel @Inject constructor( _importResult.value = if (hasCSVExtension(context, fileUri)) restoreCSVFile(fileUri = fileUri, importType = importType) else { - exportZipLogic.import( + exportBackupLogic.import( context = context, zipFileUri = fileUri, onProgress = { progressPercent -> diff --git a/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/ImportFrom.kt b/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/ImportFrom.kt index 0fe55b1f47..b97a17f70d 100644 --- a/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/ImportFrom.kt +++ b/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/ImportFrom.kt @@ -4,11 +4,21 @@ package com.ivy.wallet.ui.csvimport.flow import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.Button -import androidx.compose.material.Text +import androidx.compose.material3.Button +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -18,8 +28,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation diff --git a/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/ImportProcessing.kt b/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/ImportProcessing.kt index 5bd807090e..fc06534c26 100644 --- a/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/ImportProcessing.kt +++ b/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/ImportProcessing.kt @@ -1,8 +1,16 @@ package com.ivy.wallet.ui.csvimport.flow + import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -10,15 +18,12 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style +import com.ivy.wallet.R import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.theme.GradientGreen import com.ivy.wallet.ui.theme.Gray -import com.ivy.wallet.R - - import com.ivy.wallet.ui.theme.components.IvyDividerLine @Composable diff --git a/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/ImportResultUI.kt b/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/ImportResultUI.kt index b8382c268e..0a4f838ff7 100644 --- a/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/ImportResultUI.kt +++ b/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/ImportResultUI.kt @@ -1,15 +1,20 @@ package com.ivy.wallet.ui.csvimport.flow -import androidx.compose.foundation.layout.* -import androidx.compose.material.Button -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.material3.Button +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation @@ -17,7 +22,11 @@ import com.ivy.wallet.R import com.ivy.wallet.domain.deprecated.logic.csv.model.ImportResult import com.ivy.wallet.ui.CSVScreen import com.ivy.wallet.ui.IvyWalletPreview -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.GradientIvy +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.BackButton import com.ivy.wallet.ui.theme.components.IvyDividerLine import com.ivy.wallet.ui.theme.components.OnboardingButton diff --git a/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/instructions/ImportInstructions.kt b/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/instructions/ImportInstructions.kt index 4e1e7a1312..a91c7fe8fc 100644 --- a/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/instructions/ImportInstructions.kt +++ b/app/src/main/java/com/ivy/wallet/ui/csvimport/flow/instructions/ImportInstructions.kt @@ -4,10 +4,21 @@ import androidx.annotation.DrawableRes import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -20,8 +31,6 @@ import androidx.compose.ui.text.font.FontWeight.Companion.Bold import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation diff --git a/app/src/main/java/com/ivy/wallet/ui/donate/DonateModal.kt b/app/src/main/java/com/ivy/wallet/ui/donate/DonateModal.kt index 148bef6052..b793f77714 100644 --- a/app/src/main/java/com/ivy/wallet/ui/donate/DonateModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/donate/DonateModal.kt @@ -3,7 +3,7 @@ package com.ivy.wallet.ui.donate import androidx.compose.foundation.layout.BoxWithConstraintsScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign diff --git a/app/src/main/java/com/ivy/wallet/ui/donate/DonateScreen.kt b/app/src/main/java/com/ivy/wallet/ui/donate/DonateScreen.kt index eeccee6af2..f2cc80e974 100644 --- a/app/src/main/java/com/ivy/wallet/ui/donate/DonateScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/donate/DonateScreen.kt @@ -8,12 +8,12 @@ import androidx.compose.foundation.layout.BoxWithConstraintsScope import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -30,7 +30,6 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.navigationBarsPadding import com.ivy.design.l0_system.Black import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.White @@ -282,9 +281,7 @@ private fun BoxWithConstraintsScope.DonateButton( modifier = Modifier .align(Alignment.BottomCenter) .fillMaxWidth() - .navigationBarsPadding( - bottom = true, start = false, end = false - ) + .navigationBarsPadding() .padding(horizontal = 20.dp) .padding(bottom = 16.dp) .testTag("btn_donate"), diff --git a/app/src/main/java/com/ivy/wallet/ui/edit/EditTransactionScreen.kt b/app/src/main/java/com/ivy/wallet/ui/edit/EditTransactionScreen.kt index 6b0c409cea..c29d559fb2 100644 --- a/app/src/main/java/com/ivy/wallet/ui/edit/EditTransactionScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/edit/EditTransactionScreen.kt @@ -1,12 +1,25 @@ package com.ivy.wallet.ui.edit import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.layout.onGloballyPositioned @@ -17,8 +30,6 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.design.utils.hideKeyboard @@ -30,20 +41,39 @@ import com.ivy.wallet.domain.data.core.Account import com.ivy.wallet.domain.data.core.Category import com.ivy.wallet.domain.deprecated.logic.model.CreateAccountData import com.ivy.wallet.domain.deprecated.logic.model.CreateCategoryData -import com.ivy.wallet.ui.* -import com.ivy.wallet.ui.edit.core.* +import com.ivy.wallet.ui.EditPlanned +import com.ivy.wallet.ui.EditTransaction +import com.ivy.wallet.ui.IvyWalletPreview +import com.ivy.wallet.ui.edit.core.Category +import com.ivy.wallet.ui.edit.core.Description +import com.ivy.wallet.ui.edit.core.DueDate +import com.ivy.wallet.ui.edit.core.EditBottomSheet +import com.ivy.wallet.ui.edit.core.Title +import com.ivy.wallet.ui.edit.core.Toolbar +import com.ivy.wallet.ui.ivyWalletCtx import com.ivy.wallet.ui.loan.data.EditTransactionDisplayLoan +import com.ivy.wallet.ui.rootView import com.ivy.wallet.ui.theme.components.AddPrimaryAttributeButton import com.ivy.wallet.ui.theme.components.ChangeTransactionTypeModal import com.ivy.wallet.ui.theme.components.CustomExchangeRateCard -import com.ivy.wallet.ui.theme.modal.* -import com.ivy.wallet.ui.theme.modal.edit.* +import com.ivy.wallet.ui.theme.modal.DeleteModal +import com.ivy.wallet.ui.theme.modal.ModalAdd +import com.ivy.wallet.ui.theme.modal.ModalCheck +import com.ivy.wallet.ui.theme.modal.ModalSave +import com.ivy.wallet.ui.theme.modal.ProgressModal +import com.ivy.wallet.ui.theme.modal.edit.AccountModal +import com.ivy.wallet.ui.theme.modal.edit.AccountModalData +import com.ivy.wallet.ui.theme.modal.edit.AmountModal +import com.ivy.wallet.ui.theme.modal.edit.CategoryModal +import com.ivy.wallet.ui.theme.modal.edit.CategoryModalData +import com.ivy.wallet.ui.theme.modal.edit.ChooseCategoryModal +import com.ivy.wallet.ui.theme.modal.edit.DescriptionModal import com.ivy.wallet.utils.convertUTCtoLocal import com.ivy.wallet.utils.getTrueDate import com.ivy.wallet.utils.onScreenStart import com.ivy.wallet.utils.timeNowLocal import java.time.LocalDateTime -import java.util.* +import java.util.UUID import kotlin.math.roundToInt @ExperimentalFoundationApi diff --git a/app/src/main/java/com/ivy/wallet/ui/edit/PrimaryAttributeColumn.kt b/app/src/main/java/com/ivy/wallet/ui/edit/PrimaryAttributeColumn.kt index 13d046949a..c975a0b2c8 100644 --- a/app/src/main/java/com/ivy/wallet/ui/edit/PrimaryAttributeColumn.kt +++ b/app/src/main/java/com/ivy/wallet/ui/edit/PrimaryAttributeColumn.kt @@ -3,8 +3,16 @@ package com.ivy.wallet.ui.edit import androidx.annotation.DrawableRes import androidx.compose.foundation.border -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/edit/TransactionDateTime.kt b/app/src/main/java/com/ivy/wallet/ui/edit/TransactionDateTime.kt index dd7ac93b27..44fd7ba49f 100644 --- a/app/src/main/java/com/ivy/wallet/ui/edit/TransactionDateTime.kt +++ b/app/src/main/java/com/ivy/wallet/ui/edit/TransactionDateTime.kt @@ -3,8 +3,13 @@ package com.ivy.wallet.ui.edit import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/edit/core/Description.kt b/app/src/main/java/com/ivy/wallet/ui/edit/core/Description.kt index 45c7d68226..2142637d53 100644 --- a/app/src/main/java/com/ivy/wallet/ui/edit/core/Description.kt +++ b/app/src/main/java/com/ivy/wallet/ui/edit/core/Description.kt @@ -4,7 +4,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag diff --git a/app/src/main/java/com/ivy/wallet/ui/edit/core/DueDate.kt b/app/src/main/java/com/ivy/wallet/ui/edit/core/DueDate.kt index 340ef8db74..4db41849ad 100644 --- a/app/src/main/java/com/ivy/wallet/ui/edit/core/DueDate.kt +++ b/app/src/main/java/com/ivy/wallet/ui/edit/core/DueDate.kt @@ -3,8 +3,12 @@ package com.ivy.wallet.ui.edit.core import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/edit/core/EditBottomSheet.kt b/app/src/main/java/com/ivy/wallet/ui/edit/core/EditBottomSheet.kt index 7ee5b5e58b..3d97305515 100644 --- a/app/src/main/java/com/ivy/wallet/ui/edit/core/EditBottomSheet.kt +++ b/app/src/main/java/com/ivy/wallet/ui/edit/core/EditBottomSheet.kt @@ -6,12 +6,27 @@ import androidx.compose.animation.core.tween import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -28,7 +43,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.test.TestingContext @@ -38,15 +52,40 @@ import com.ivy.wallet.domain.data.TransactionType import com.ivy.wallet.domain.data.core.Account import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.ivyWalletCtx -import com.ivy.wallet.ui.theme.* -import com.ivy.wallet.ui.theme.components.* +import com.ivy.wallet.ui.theme.Gradient +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.GreenDark +import com.ivy.wallet.ui.theme.GreenLight +import com.ivy.wallet.ui.theme.Ivy +import com.ivy.wallet.ui.theme.IvyDark +import com.ivy.wallet.ui.theme.components.ActionsRow +import com.ivy.wallet.ui.theme.components.BalanceRow +import com.ivy.wallet.ui.theme.components.CircleButton +import com.ivy.wallet.ui.theme.components.ItemIconSDefaultIcon +import com.ivy.wallet.ui.theme.components.IvyButton +import com.ivy.wallet.ui.theme.components.IvyIcon +import com.ivy.wallet.ui.theme.findContrastTextColor import com.ivy.wallet.ui.theme.modal.DURATION_MODAL_ANIM import com.ivy.wallet.ui.theme.modal.ModalSave import com.ivy.wallet.ui.theme.modal.ModalSet import com.ivy.wallet.ui.theme.modal.edit.AmountModal -import com.ivy.wallet.utils.* +import com.ivy.wallet.ui.theme.toComposeColor +import com.ivy.wallet.utils.addKeyboardListener +import com.ivy.wallet.utils.clickableNoIndication +import com.ivy.wallet.utils.consumeClicks +import com.ivy.wallet.utils.densityScope +import com.ivy.wallet.utils.format +import com.ivy.wallet.utils.hideKeyboard +import com.ivy.wallet.utils.keyboardOnlyWindowInsets +import com.ivy.wallet.utils.lerp +import com.ivy.wallet.utils.navigationBarInsets +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.springBounce +import com.ivy.wallet.utils.thenIf +import com.ivy.wallet.utils.verticalSwipeListener import kotlinx.coroutines.launch -import java.util.* +import java.util.Locale +import java.util.UUID import kotlin.math.roundToInt @Composable diff --git a/app/src/main/java/com/ivy/wallet/ui/edit/core/Title.kt b/app/src/main/java/com/ivy/wallet/ui/edit/core/Title.kt index a2d17635fe..7b86e918ef 100644 --- a/app/src/main/java/com/ivy/wallet/ui/edit/core/Title.kt +++ b/app/src/main/java/com/ivy/wallet/ui/edit/core/Title.kt @@ -8,7 +8,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope @@ -32,7 +32,7 @@ import com.ivy.wallet.ui.theme.components.IvyTitleTextField import com.ivy.wallet.utils.keyboardVisibleState import com.ivy.wallet.utils.selectEndTextFieldValue import kotlinx.coroutines.launch -import java.util.* +import java.util.UUID const val SUGGESTIONS_LIMIT = 10 diff --git a/app/src/main/java/com/ivy/wallet/ui/exchangerates/ExchangeRatesScreen.kt b/app/src/main/java/com/ivy/wallet/ui/exchangerates/ExchangeRatesScreen.kt index fc9f233fd1..b9f842568e 100644 --- a/app/src/main/java/com/ivy/wallet/ui/exchangerates/ExchangeRatesScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/exchangerates/ExchangeRatesScreen.kt @@ -4,20 +4,25 @@ import androidx.compose.foundation.layout.BoxWithConstraintsScope import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.items -import androidx.compose.material.Button -import androidx.compose.material.ButtonDefaults -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.White import com.ivy.design.l0_system.style @@ -33,7 +38,7 @@ import com.ivy.wallet.ui.exchangerates.modal.AddRateModal import com.ivy.wallet.ui.search.SearchInput import com.ivy.wallet.ui.theme.modal.edit.AmountModal import com.ivy.wallet.utils.selectEndTextFieldValue -import java.util.* +import java.util.UUID object ExchangeRatesScreen : Screen @@ -106,7 +111,8 @@ private fun BoxWithConstraintsScope.UI( .align(Alignment.BottomCenter) .padding(bottom = 24.dp), colors = ButtonDefaults.buttonColors( - backgroundColor = UI.colors.primary + containerColor = UI.colors.primary, + contentColor = White, ), onClick = { addRateModalVisible = true diff --git a/app/src/main/java/com/ivy/wallet/ui/exchangerates/component/RateItem.kt b/app/src/main/java/com/ivy/wallet/ui/exchangerates/component/RateItem.kt index b0ab4c03d8..203b747adf 100644 --- a/app/src/main/java/com/ivy/wallet/ui/exchangerates/component/RateItem.kt +++ b/app/src/main/java/com/ivy/wallet/ui/exchangerates/component/RateItem.kt @@ -5,7 +5,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/exchangerates/modal/AddRateModal.kt b/app/src/main/java/com/ivy/wallet/ui/exchangerates/modal/AddRateModal.kt index 4b5bbb2d3d..4b88d7c7fc 100644 --- a/app/src/main/java/com/ivy/wallet/ui/exchangerates/modal/AddRateModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/exchangerates/modal/AddRateModal.kt @@ -4,9 +4,13 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.BoxWithConstraintsScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.OutlinedTextField -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview @@ -22,7 +26,7 @@ import com.ivy.wallet.ui.theme.modal.IvyModal import com.ivy.wallet.ui.theme.modal.ModalAdd import com.ivy.wallet.ui.theme.modal.ModalTitle import com.ivy.wallet.ui.theme.modal.edit.AmountModal -import java.util.* +import java.util.UUID @Composable fun BoxWithConstraintsScope.AddRateModal( diff --git a/app/src/main/java/com/ivy/wallet/ui/home/CustomerJourney.kt b/app/src/main/java/com/ivy/wallet/ui/home/CustomerJourney.kt index 3a416bce1b..c44017577f 100644 --- a/app/src/main/java/com/ivy/wallet/ui/home/CustomerJourney.kt +++ b/app/src/main/java/com/ivy/wallet/ui/home/CustomerJourney.kt @@ -2,8 +2,14 @@ package com.ivy.wallet.ui.home import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/home/HomeHeader.kt b/app/src/main/java/com/ivy/wallet/ui/home/HomeHeader.kt index fb0c6ac3de..254456b252 100644 --- a/app/src/main/java/com/ivy/wallet/ui/home/HomeHeader.kt +++ b/app/src/main/java/com/ivy/wallet/ui/home/HomeHeader.kt @@ -6,8 +6,16 @@ import androidx.compose.animation.core.Spring import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment @@ -29,13 +37,24 @@ import com.ivy.wallet.ui.PieChartStatistic import com.ivy.wallet.ui.component.transaction.TransactionsDividerLine import com.ivy.wallet.ui.ivyWalletCtx import com.ivy.wallet.ui.onboarding.model.TimePeriod -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.Gradient +import com.ivy.wallet.ui.theme.GradientGreen +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.BalanceRow import com.ivy.wallet.ui.theme.components.BalanceRowMini import com.ivy.wallet.ui.theme.components.IvyIcon import com.ivy.wallet.ui.theme.components.IvyOutlinedButton import com.ivy.wallet.ui.theme.wallet.AmountCurrencyB1 -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.clickableNoIndication +import com.ivy.wallet.utils.drawColoredShadow +import com.ivy.wallet.utils.format +import com.ivy.wallet.utils.horizontalSwipeListener +import com.ivy.wallet.utils.isNotNullOrBlank +import com.ivy.wallet.utils.springBounce +import com.ivy.wallet.utils.thenIf +import com.ivy.wallet.utils.verticalSwipeListener import kotlin.math.absoluteValue diff --git a/app/src/main/java/com/ivy/wallet/ui/home/HomeMoreMenu.kt b/app/src/main/java/com/ivy/wallet/ui/home/HomeMoreMenu.kt index dd87930332..b0c09b762e 100644 --- a/app/src/main/java/com/ivy/wallet/ui/home/HomeMoreMenu.kt +++ b/app/src/main/java/com/ivy/wallet/ui/home/HomeMoreMenu.kt @@ -3,10 +3,32 @@ package com.ivy.wallet.ui.home import androidx.annotation.DrawableRes import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -25,8 +47,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.SunsetNight import com.ivy.design.l0_system.Theme import com.ivy.design.l0_system.UI @@ -34,8 +54,17 @@ import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation import com.ivy.wallet.Constants import com.ivy.wallet.R -import com.ivy.wallet.ui.* +import com.ivy.wallet.ui.BudgetScreen +import com.ivy.wallet.ui.Categories +import com.ivy.wallet.ui.IvyWalletPreview +import com.ivy.wallet.ui.Loans +import com.ivy.wallet.ui.PlannedPayments +import com.ivy.wallet.ui.Report +import com.ivy.wallet.ui.RootActivity +import com.ivy.wallet.ui.Search +import com.ivy.wallet.ui.Settings import com.ivy.wallet.ui.donate.DonateScreen +import com.ivy.wallet.ui.ivyWalletCtx import com.ivy.wallet.ui.theme.Blue import com.ivy.wallet.ui.theme.Gradient import com.ivy.wallet.ui.theme.Gray @@ -45,8 +74,17 @@ import com.ivy.wallet.ui.theme.components.IvyButton import com.ivy.wallet.ui.theme.components.IvyIcon import com.ivy.wallet.ui.theme.modal.AddModalBackHandling import com.ivy.wallet.ui.theme.wallet.AmountCurrencyB1 -import com.ivy.wallet.utils.* -import java.util.* +import com.ivy.wallet.utils.clickableNoIndication +import com.ivy.wallet.utils.colorLerp +import com.ivy.wallet.utils.lerp +import com.ivy.wallet.utils.navigationBarInset +import com.ivy.wallet.utils.openUrl +import com.ivy.wallet.utils.springBounce +import com.ivy.wallet.utils.statusBarInset +import com.ivy.wallet.utils.thenIf +import com.ivy.wallet.utils.toDensityPx +import com.ivy.wallet.utils.verticalSwipeListener +import java.util.UUID import kotlin.math.roundToInt private const val SWIPE_UP_THRESHOLD_CLOSE_MORE_MENU = 300 diff --git a/app/src/main/java/com/ivy/wallet/ui/home/HomeTab.kt b/app/src/main/java/com/ivy/wallet/ui/home/HomeTab.kt index 3efe5178a8..1ffab84dd7 100644 --- a/app/src/main/java/com/ivy/wallet/ui/home/HomeTab.kt +++ b/app/src/main/java/com/ivy/wallet/ui/home/HomeTab.kt @@ -2,11 +2,22 @@ package com.ivy.wallet.ui.home import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollConnection @@ -17,11 +28,9 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.systemBarsPadding import com.ivy.frp.asParamTo2 import com.ivy.frp.forward import com.ivy.frp.then2 -import com.ivy.frp.view.FRP import com.ivy.frp.view.navigation.navigation import com.ivy.frp.view.navigation.onScreenStart import com.ivy.wallet.Constants @@ -42,7 +51,12 @@ import com.ivy.wallet.ui.data.DueSection import com.ivy.wallet.ui.ivyWalletCtx import com.ivy.wallet.ui.main.MainTab import com.ivy.wallet.ui.onboarding.model.TimePeriod -import com.ivy.wallet.ui.theme.modal.* +import com.ivy.wallet.ui.theme.modal.BufferModal +import com.ivy.wallet.ui.theme.modal.BufferModalData +import com.ivy.wallet.ui.theme.modal.ChoosePeriodModal +import com.ivy.wallet.ui.theme.modal.ChoosePeriodModalData +import com.ivy.wallet.ui.theme.modal.CurrencyModal +import com.ivy.wallet.ui.theme.modal.DeleteModal import com.ivy.wallet.utils.horizontalSwipeListener import com.ivy.wallet.utils.verticalSwipeListener import java.math.BigDecimal diff --git a/app/src/main/java/com/ivy/wallet/ui/loan/LoansScreen.kt b/app/src/main/java/com/ivy/wallet/ui/loan/LoansScreen.kt index 26b4fe6eeb..b43a1b044a 100644 --- a/app/src/main/java/com/ivy/wallet/ui/loan/LoansScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/loan/LoansScreen.kt @@ -1,8 +1,22 @@ package com.ivy.wallet.ui.loan -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -19,7 +33,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation @@ -30,9 +43,20 @@ import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.LoanDetails import com.ivy.wallet.ui.Loans import com.ivy.wallet.ui.loan.data.DisplayLoan -import com.ivy.wallet.ui.theme.* -import com.ivy.wallet.ui.theme.components.* +import com.ivy.wallet.ui.theme.Blue +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.components.BalanceRow +import com.ivy.wallet.ui.theme.components.ItemIconSDefaultIcon +import com.ivy.wallet.ui.theme.components.IvyIcon +import com.ivy.wallet.ui.theme.components.ProgressBar +import com.ivy.wallet.ui.theme.components.ReorderButton +import com.ivy.wallet.ui.theme.components.ReorderModalSingleType +import com.ivy.wallet.ui.theme.dynamicContrast +import com.ivy.wallet.ui.theme.findContrastTextColor import com.ivy.wallet.ui.theme.modal.LoanModal +import com.ivy.wallet.ui.theme.toComposeColor import com.ivy.wallet.utils.getDefaultFIATCurrency import com.ivy.wallet.utils.onScreenStart diff --git a/app/src/main/java/com/ivy/wallet/ui/loandetails/LoanDetailsScreen.kt b/app/src/main/java/com/ivy/wallet/ui/loandetails/LoanDetailsScreen.kt index cad4302f2d..11711d1c0a 100644 --- a/app/src/main/java/com/ivy/wallet/ui/loandetails/LoanDetailsScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/loandetails/LoanDetailsScreen.kt @@ -2,14 +2,29 @@ package com.ivy.wallet.ui.loandetails import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material.Divider -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Divider +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -22,7 +37,6 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.statusBarsHeight import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation @@ -42,11 +56,36 @@ import com.ivy.wallet.ui.LoanDetails import com.ivy.wallet.ui.component.transaction.TypeAmountCurrency import com.ivy.wallet.ui.loan.data.DisplayLoanRecord import com.ivy.wallet.ui.statistic.level2.ItemStatisticToolbar -import com.ivy.wallet.ui.theme.* -import com.ivy.wallet.ui.theme.components.* -import com.ivy.wallet.ui.theme.modal.* -import com.ivy.wallet.utils.* -import java.util.* +import com.ivy.wallet.ui.theme.Gradient +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.MediumBlack +import com.ivy.wallet.ui.theme.MediumWhite +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.components.BalanceRow +import com.ivy.wallet.ui.theme.components.ItemIconMDefaultIcon +import com.ivy.wallet.ui.theme.components.IvyButton +import com.ivy.wallet.ui.theme.components.IvyIcon +import com.ivy.wallet.ui.theme.components.ProgressBar +import com.ivy.wallet.ui.theme.components.getCustomIconIdS +import com.ivy.wallet.ui.theme.dynamicContrast +import com.ivy.wallet.ui.theme.findContrastTextColor +import com.ivy.wallet.ui.theme.isDarkColor +import com.ivy.wallet.ui.theme.modal.DeleteModal +import com.ivy.wallet.ui.theme.modal.LoanModal +import com.ivy.wallet.ui.theme.modal.LoanModalData +import com.ivy.wallet.ui.theme.modal.LoanRecordModal +import com.ivy.wallet.ui.theme.modal.LoanRecordModalData +import com.ivy.wallet.ui.theme.modal.ProgressModal +import com.ivy.wallet.ui.theme.toComposeColor +import com.ivy.wallet.utils.clickableNoIndication +import com.ivy.wallet.utils.drawColoredShadow +import com.ivy.wallet.utils.format +import com.ivy.wallet.utils.formatNicelyWithTime +import com.ivy.wallet.utils.isNotNullOrBlank +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.setStatusBarDarkTextCompat +import com.ivy.wallet.utils.timeNowUTC +import java.util.UUID @Composable fun BoxWithConstraintsScope.LoanDetailsScreen(screen: LoanDetails) { @@ -120,11 +159,11 @@ private fun BoxWithConstraintsScope.UI( ) { val listState = rememberLazyListState() - Spacer(Modifier.statusBarsHeight()) LazyColumn( modifier = Modifier .fillMaxSize() + .statusBarsPadding() .padding(top = 16.dp) .clip(UI.shapes.r1Top) .background(UI.colors.pure), @@ -485,7 +524,11 @@ private fun LoanInfoCard( Text( modifier = Modifier .testTag("left_to_pay"), - text = stringResource(R.string.left_to_pay, leftToPay.format(baseCurrency), baseCurrency), + text = stringResource( + R.string.left_to_pay, + leftToPay.format(baseCurrency), + baseCurrency + ), style = UI.typo.nB2.style( color = Gray, fontWeight = FontWeight.ExtraBold @@ -509,9 +552,9 @@ private fun LoanInfoCard( Divider( modifier = Modifier .padding(horizontal = 24.dp, vertical = 16.dp) - .height(1.dp) - .fillMaxWidth() - .background(contrastColor) + .fillMaxWidth(), + thickness = 1.dp, + color = contrastColor ) Text( @@ -546,7 +589,11 @@ private fun LoanInfoCard( Text( modifier = Modifier .testTag("interest_paid"), - text = stringResource(R.string.interest_paid, loanAmountPaid.format(baseCurrency), baseCurrency), + text = stringResource( + R.string.interest_paid, + loanAmountPaid.format(baseCurrency), + baseCurrency + ), style = UI.typo.nB2.style( color = Gray, fontWeight = FontWeight.ExtraBold diff --git a/app/src/main/java/com/ivy/wallet/ui/main/MainBottomBar.kt b/app/src/main/java/com/ivy/wallet/ui/main/MainBottomBar.kt index df946ad9eb..b08f8d8446 100644 --- a/app/src/main/java/com/ivy/wallet/ui/main/MainBottomBar.kt +++ b/app/src/main/java/com/ivy/wallet/ui/main/MainBottomBar.kt @@ -6,9 +6,24 @@ import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.detectDragGestures -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -24,18 +39,31 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex -import com.google.accompanist.insets.navigationBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.wallet.R import com.ivy.wallet.ui.ivyWalletCtx -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.Gradient +import com.ivy.wallet.ui.theme.GradientGreen +import com.ivy.wallet.ui.theme.GradientIvy +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.Ivy +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.IvyCircleButton import com.ivy.wallet.ui.theme.components.IvyIcon import com.ivy.wallet.ui.theme.components.IvyOutlinedButton +import com.ivy.wallet.ui.theme.gradientExpenses import com.ivy.wallet.ui.theme.modal.AddModalBackHandling -import com.ivy.wallet.utils.* -import java.util.* +import com.ivy.wallet.ui.theme.pureBlur +import com.ivy.wallet.utils.clickableNoIndication +import com.ivy.wallet.utils.densityScope +import com.ivy.wallet.utils.lerp +import com.ivy.wallet.utils.navigationBarInset +import com.ivy.wallet.utils.springBounceFast +import com.ivy.wallet.utils.thenIf +import com.ivy.wallet.utils.toDensityDp +import com.ivy.wallet.utils.toDensityPx +import java.util.UUID import kotlin.math.abs import kotlin.math.roundToInt @@ -187,12 +215,14 @@ fun BoxWithConstraintsScope.BottomBar( dragOffset = Offset.Zero //prevent double open of the screen onAddExpense() } + dragOffset.x < -horizontalThreshold && dragOffset.y < -verticalThreshold -> { //swipe up left dragOffset = Offset.Zero //prevent double open of the screen onAddIncome() } + dragOffset.x > horizontalThreshold && dragOffset.y < -verticalThreshold -> { //swipe up right diff --git a/app/src/main/java/com/ivy/wallet/ui/onboarding/components/OnboardingToolbar.kt b/app/src/main/java/com/ivy/wallet/ui/onboarding/components/OnboardingToolbar.kt index 0971f3c9f1..c6ef916b01 100644 --- a/app/src/main/java/com/ivy/wallet/ui/onboarding/components/OnboardingToolbar.kt +++ b/app/src/main/java/com/ivy/wallet/ui/onboarding/components/OnboardingToolbar.kt @@ -4,7 +4,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip diff --git a/app/src/main/java/com/ivy/wallet/ui/onboarding/components/Suggestions.kt b/app/src/main/java/com/ivy/wallet/ui/onboarding/components/Suggestions.kt index 01239cf54b..1df7cdcef3 100644 --- a/app/src/main/java/com/ivy/wallet/ui/onboarding/components/Suggestions.kt +++ b/app/src/main/java/com/ivy/wallet/ui/onboarding/components/Suggestions.kt @@ -3,8 +3,12 @@ package com.ivy.wallet.ui.onboarding.components import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingAccounts.kt b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingAccounts.kt index 4cbeac7cd1..c9b8684e14 100644 --- a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingAccounts.kt +++ b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingAccounts.kt @@ -1,11 +1,29 @@ package com.ivy.wallet.ui.onboarding.steps -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -16,8 +34,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation @@ -32,13 +48,22 @@ import com.ivy.wallet.ui.onboarding.components.OnboardingToolbar import com.ivy.wallet.ui.onboarding.components.Suggestions import com.ivy.wallet.ui.onboarding.model.AccountBalance import com.ivy.wallet.ui.paywall.PaywallReason -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.GradientIvy +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.Ivy +import com.ivy.wallet.ui.theme.IvyDark +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.GradientCutBottom import com.ivy.wallet.ui.theme.components.ItemIconMDefaultIcon import com.ivy.wallet.ui.theme.components.IvyIcon import com.ivy.wallet.ui.theme.components.OnboardingButton +import com.ivy.wallet.ui.theme.dynamicContrast +import com.ivy.wallet.ui.theme.findContrastTextColor import com.ivy.wallet.ui.theme.modal.edit.AccountModal import com.ivy.wallet.ui.theme.modal.edit.AccountModalData +import com.ivy.wallet.ui.theme.toComposeColor import com.ivy.wallet.ui.theme.wallet.AmountCurrencyB1Row import com.ivy.wallet.utils.toLowerCaseLocal diff --git a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingCategories.kt b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingCategories.kt index 18ff81364c..10e84e3686 100644 --- a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingCategories.kt +++ b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingCategories.kt @@ -4,11 +4,25 @@ import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -19,8 +33,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation @@ -31,12 +43,22 @@ import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.onboarding.components.OnboardingProgressSlider import com.ivy.wallet.ui.onboarding.components.OnboardingToolbar import com.ivy.wallet.ui.onboarding.components.Suggestions -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.GradientIvy +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.Ivy +import com.ivy.wallet.ui.theme.IvyDark +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.OrangeLight +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.RedLight +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.GradientCutBottom import com.ivy.wallet.ui.theme.components.ItemIconSDefaultIcon import com.ivy.wallet.ui.theme.components.OnboardingButton +import com.ivy.wallet.ui.theme.findContrastTextColor import com.ivy.wallet.ui.theme.modal.edit.CategoryModal import com.ivy.wallet.ui.theme.modal.edit.CategoryModalData +import com.ivy.wallet.ui.theme.toComposeColor import com.ivy.wallet.utils.toLowerCaseLocal @ExperimentalFoundationApi diff --git a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingSetCurrency.kt b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingSetCurrency.kt index c6cab78ea3..b4f59b9e08 100644 --- a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingSetCurrency.kt +++ b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingSetCurrency.kt @@ -1,16 +1,26 @@ package com.ivy.wallet.ui.onboarding.steps -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation diff --git a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingSplashLogin.kt b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingSplashLogin.kt index de3c33aac2..e2089ca09d 100644 --- a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingSplashLogin.kt +++ b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingSplashLogin.kt @@ -7,10 +7,25 @@ import androidx.compose.animation.core.updateTransition import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.text.ClickableText -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -28,8 +43,6 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.wallet.Constants @@ -42,7 +55,15 @@ import com.ivy.wallet.ui.theme.Gradient import com.ivy.wallet.ui.theme.Gray import com.ivy.wallet.ui.theme.Green import com.ivy.wallet.ui.theme.components.IvyIcon -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.OpResult +import com.ivy.wallet.utils.clickableNoIndication +import com.ivy.wallet.utils.drawColoredShadow +import com.ivy.wallet.utils.lerp +import com.ivy.wallet.utils.openUrl +import com.ivy.wallet.utils.springBounceSlow +import com.ivy.wallet.utils.thenIf +import com.ivy.wallet.utils.toDensityDp +import com.ivy.wallet.utils.toDensityPx import kotlin.math.roundToInt @Composable diff --git a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingType.kt b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingType.kt index 432828b2a6..e28bdd361b 100644 --- a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingType.kt +++ b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/OnboardingType.kt @@ -1,8 +1,15 @@ package com.ivy.wallet.ui.onboarding.steps import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -11,15 +18,17 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation import com.ivy.wallet.R import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.onboarding.components.OnboardingProgressSlider -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.GradientIvy +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.CloseButton import com.ivy.wallet.ui.theme.components.IvyOutlinedButtonFillMaxWidth import com.ivy.wallet.ui.theme.components.OnboardingButton diff --git a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/archived/OnboardingPrivacyTC.kt b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/archived/OnboardingPrivacyTC.kt index 2a88e58e3f..2a63d0d4b0 100644 --- a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/archived/OnboardingPrivacyTC.kt +++ b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/archived/OnboardingPrivacyTC.kt @@ -5,9 +5,25 @@ import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.detectHorizontalDragGestures -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawBehind @@ -21,8 +37,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.wallet.Constants diff --git a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/archived/OnboardingSetName.kt b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/archived/OnboardingSetName.kt index eeb41e6449..864860715d 100644 --- a/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/archived/OnboardingSetName.kt +++ b/app/src/main/java/com/ivy/wallet/ui/onboarding/steps/archived/OnboardingSetName.kt @@ -2,11 +2,23 @@ package com.ivy.wallet.ui.onboarding.steps.archived import androidx.compose.animation.core.animateDpAsState import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester @@ -21,8 +33,6 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.wallet.R @@ -31,7 +41,12 @@ import com.ivy.wallet.ui.theme.GradientIvy import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.IvyOutlinedTextField import com.ivy.wallet.ui.theme.components.OnboardingButton -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.addKeyboardListener +import com.ivy.wallet.utils.densityScope +import com.ivy.wallet.utils.isNotNullOrBlank +import com.ivy.wallet.utils.keyboardOnlyWindowInsets +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.springBounceSlow @Composable fun OnboardingSetName( diff --git a/app/src/main/java/com/ivy/wallet/ui/paywall/PaywallScreen.kt b/app/src/main/java/com/ivy/wallet/ui/paywall/PaywallScreen.kt index 8654ee5c0b..42266a8260 100644 --- a/app/src/main/java/com/ivy/wallet/ui/paywall/PaywallScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/paywall/PaywallScreen.kt @@ -2,13 +2,27 @@ package com.ivy.wallet.ui.paywall import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight @@ -16,8 +30,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.android.billingclient.api.SkuDetails -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation @@ -33,7 +45,12 @@ import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.Paywall import com.ivy.wallet.ui.RootActivity import com.ivy.wallet.ui.ivyWalletCtx -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.GradientIvy +import com.ivy.wallet.ui.theme.GradientOrange +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.BackButtonType import com.ivy.wallet.ui.theme.components.IvyIcon import com.ivy.wallet.ui.theme.components.IvyToolbar diff --git a/app/src/main/java/com/ivy/wallet/ui/paywall/PlansSheet.kt b/app/src/main/java/com/ivy/wallet/ui/paywall/PlansSheet.kt index 781c6f6bd2..78054b549b 100644 --- a/app/src/main/java/com/ivy/wallet/ui/paywall/PlansSheet.kt +++ b/app/src/main/java/com/ivy/wallet/ui/paywall/PlansSheet.kt @@ -1,10 +1,31 @@ package com.ivy.wallet.ui.paywall import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -17,22 +38,30 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import com.android.billingclient.api.SkuDetails -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.wallet.R import com.ivy.wallet.android.billing.Plan import com.ivy.wallet.android.billing.PlanType import com.ivy.wallet.ui.IvyWalletPreview -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.GradientGreen +import com.ivy.wallet.ui.theme.GradientIvy +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.ActionsRow import com.ivy.wallet.ui.theme.components.CloseButton import com.ivy.wallet.ui.theme.components.IvyButton +import com.ivy.wallet.ui.theme.gradientCutBackgroundTop import com.ivy.wallet.ui.theme.modal.AddModalBackHandling import com.ivy.wallet.ui.theme.modal.ModalTitle -import com.ivy.wallet.utils.* -import java.util.* +import com.ivy.wallet.ui.theme.pureBlur +import com.ivy.wallet.utils.consumeClicks +import com.ivy.wallet.utils.drawColoredShadow +import com.ivy.wallet.utils.springBounce +import com.ivy.wallet.utils.thenIf +import com.ivy.wallet.utils.toUpperCaseLocal +import java.util.UUID import kotlin.math.roundToInt @Composable diff --git a/app/src/main/java/com/ivy/wallet/ui/planned/edit/EditPlannedScreen.kt b/app/src/main/java/com/ivy/wallet/ui/planned/edit/EditPlannedScreen.kt index 5c59e1b4d1..6488fc8bb9 100644 --- a/app/src/main/java/com/ivy/wallet/ui/planned/edit/EditPlannedScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/planned/edit/EditPlannedScreen.kt @@ -1,11 +1,21 @@ package com.ivy.wallet.ui.planned.edit import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.platform.testTag @@ -14,8 +24,6 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.wallet.R import com.ivy.wallet.domain.data.IntervalType import com.ivy.wallet.domain.data.TransactionType @@ -25,13 +33,22 @@ import com.ivy.wallet.domain.deprecated.logic.model.CreateAccountData import com.ivy.wallet.domain.deprecated.logic.model.CreateCategoryData import com.ivy.wallet.ui.EditPlanned import com.ivy.wallet.ui.IvyWalletPreview -import com.ivy.wallet.ui.edit.core.* +import com.ivy.wallet.ui.edit.core.Category +import com.ivy.wallet.ui.edit.core.Description +import com.ivy.wallet.ui.edit.core.EditBottomSheet +import com.ivy.wallet.ui.edit.core.Title +import com.ivy.wallet.ui.edit.core.Toolbar import com.ivy.wallet.ui.theme.components.ChangeTransactionTypeModal import com.ivy.wallet.ui.theme.modal.DeleteModal import com.ivy.wallet.ui.theme.modal.ModalSet import com.ivy.wallet.ui.theme.modal.RecurringRuleModal import com.ivy.wallet.ui.theme.modal.RecurringRuleModalData -import com.ivy.wallet.ui.theme.modal.edit.* +import com.ivy.wallet.ui.theme.modal.edit.AccountModal +import com.ivy.wallet.ui.theme.modal.edit.AccountModalData +import com.ivy.wallet.ui.theme.modal.edit.CategoryModal +import com.ivy.wallet.ui.theme.modal.edit.CategoryModalData +import com.ivy.wallet.ui.theme.modal.edit.ChooseCategoryModal +import com.ivy.wallet.ui.theme.modal.edit.DescriptionModal import com.ivy.wallet.utils.onScreenStart import java.time.LocalDateTime diff --git a/app/src/main/java/com/ivy/wallet/ui/planned/edit/RecurringRule.kt b/app/src/main/java/com/ivy/wallet/ui/planned/edit/RecurringRule.kt index f8fe902beb..608171f4ec 100644 --- a/app/src/main/java/com/ivy/wallet/ui/planned/edit/RecurringRule.kt +++ b/app/src/main/java/com/ivy/wallet/ui/planned/edit/RecurringRule.kt @@ -2,8 +2,14 @@ package com.ivy.wallet.ui.planned.edit import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/planned/list/PlannedPaymentCard.kt b/app/src/main/java/com/ivy/wallet/ui/planned/list/PlannedPaymentCard.kt index 12d9d78053..e92472ec42 100644 --- a/app/src/main/java/com/ivy/wallet/ui/planned/list/PlannedPaymentCard.kt +++ b/app/src/main/java/com/ivy/wallet/ui/planned/list/PlannedPaymentCard.kt @@ -2,11 +2,18 @@ package com.ivy.wallet.ui.planned.list import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -36,7 +43,11 @@ import com.ivy.wallet.ui.theme.components.IvyIcon import com.ivy.wallet.ui.theme.components.getCustomIconIdS import com.ivy.wallet.ui.theme.findContrastTextColor import com.ivy.wallet.ui.theme.toComposeColor -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.formatDateOnly +import com.ivy.wallet.utils.formatDateOnlyWithYear +import com.ivy.wallet.utils.isNotNullOrBlank +import com.ivy.wallet.utils.timeNowUTC +import com.ivy.wallet.utils.uppercaseLocal import java.time.LocalDateTime @Composable diff --git a/app/src/main/java/com/ivy/wallet/ui/planned/list/PlannedPaymentsLazyColumn.kt b/app/src/main/java/com/ivy/wallet/ui/planned/list/PlannedPaymentsLazyColumn.kt index fa26d1a9af..3df9242028 100644 --- a/app/src/main/java/com/ivy/wallet/ui/planned/list/PlannedPaymentsLazyColumn.kt +++ b/app/src/main/java/com/ivy/wallet/ui/planned/list/PlannedPaymentsLazyColumn.kt @@ -1,17 +1,30 @@ package com.ivy.wallet.ui.planned.list -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.* -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyItemScope +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.Navigation diff --git a/app/src/main/java/com/ivy/wallet/ui/planned/list/PlannedPaymentsScreen.kt b/app/src/main/java/com/ivy/wallet/ui/planned/list/PlannedPaymentsScreen.kt index f1800be9b1..a5e2aa2dea 100644 --- a/app/src/main/java/com/ivy/wallet/ui/planned/list/PlannedPaymentsScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/planned/list/PlannedPaymentsScreen.kt @@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.BoxWithConstraintsScope import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState diff --git a/app/src/main/java/com/ivy/wallet/ui/reports/FilterOverlay.kt b/app/src/main/java/com/ivy/wallet/ui/reports/FilterOverlay.kt index cb4b771085..acf5c56d32 100644 --- a/app/src/main/java/com/ivy/wallet/ui/reports/FilterOverlay.kt +++ b/app/src/main/java/com/ivy/wallet/ui/reports/FilterOverlay.kt @@ -2,12 +2,29 @@ package com.ivy.wallet.ui.reports import androidx.annotation.DrawableRes import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -20,7 +37,6 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.wallet.R @@ -29,18 +45,35 @@ import com.ivy.wallet.domain.data.core.Account import com.ivy.wallet.domain.data.core.Category import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.ivyWalletCtx -import com.ivy.wallet.ui.theme.* -import com.ivy.wallet.ui.theme.components.* +import com.ivy.wallet.ui.theme.GradientGreen +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.GreenDark +import com.ivy.wallet.ui.theme.GreenLight +import com.ivy.wallet.ui.theme.IvyDark +import com.ivy.wallet.ui.theme.Purple1Dark +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.Red3Light +import com.ivy.wallet.ui.theme.components.CloseButton +import com.ivy.wallet.ui.theme.components.GradientCutBottom +import com.ivy.wallet.ui.theme.components.ItemIconSDefaultIcon +import com.ivy.wallet.ui.theme.components.IvyButton +import com.ivy.wallet.ui.theme.components.IvyCheckboxWithText +import com.ivy.wallet.ui.theme.components.IvyDividerLine +import com.ivy.wallet.ui.theme.components.IvyOutlinedButton +import com.ivy.wallet.ui.theme.components.IvyOutlinedButtonFillMaxWidth +import com.ivy.wallet.ui.theme.components.WrapContentRow +import com.ivy.wallet.ui.theme.findContrastTextColor import com.ivy.wallet.ui.theme.modal.AddKeywordModal import com.ivy.wallet.ui.theme.modal.AddModalBackHandling import com.ivy.wallet.ui.theme.modal.ChoosePeriodModal import com.ivy.wallet.ui.theme.modal.ChoosePeriodModalData import com.ivy.wallet.ui.theme.modal.edit.AmountModal +import com.ivy.wallet.ui.theme.toComposeColor import com.ivy.wallet.ui.theme.wallet.AmountCurrencyB1Row import com.ivy.wallet.utils.capitalizeLocal import com.ivy.wallet.utils.springBounce import com.ivy.wallet.utils.thenIf -import java.util.* +import java.util.UUID import kotlin.math.roundToInt @Composable diff --git a/app/src/main/java/com/ivy/wallet/ui/reports/ReportScreen.kt b/app/src/main/java/com/ivy/wallet/ui/reports/ReportScreen.kt index e01db9e358..d89a8a485b 100644 --- a/app/src/main/java/com/ivy/wallet/ui/reports/ReportScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/reports/ReportScreen.kt @@ -2,10 +2,19 @@ package com.ivy.wallet.ui.reports import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -20,7 +29,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation @@ -39,8 +47,23 @@ import com.ivy.wallet.ui.data.AppBaseData import com.ivy.wallet.ui.data.DueSection import com.ivy.wallet.ui.ivyWalletCtx import com.ivy.wallet.ui.statistic.level2.IncomeExpensesCards -import com.ivy.wallet.ui.theme.* -import com.ivy.wallet.ui.theme.components.* +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.GreenDark +import com.ivy.wallet.ui.theme.GreenLight +import com.ivy.wallet.ui.theme.IvyDark +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.Purple1Dark +import com.ivy.wallet.ui.theme.Red3Light +import com.ivy.wallet.ui.theme.components.BackButtonType +import com.ivy.wallet.ui.theme.components.BalanceRow +import com.ivy.wallet.ui.theme.components.CircleButtonFilled +import com.ivy.wallet.ui.theme.components.IvyButton +import com.ivy.wallet.ui.theme.components.IvyCheckboxWithText +import com.ivy.wallet.ui.theme.components.IvyIcon +import com.ivy.wallet.ui.theme.components.IvyOutlinedButton +import com.ivy.wallet.ui.theme.components.IvyToolbar +import com.ivy.wallet.ui.theme.pureBlur import com.ivy.wallet.utils.clickableNoIndication import com.ivy.wallet.utils.onScreenStart diff --git a/app/src/main/java/com/ivy/wallet/ui/search/SearchScreen.kt b/app/src/main/java/com/ivy/wallet/ui/search/SearchScreen.kt index 8b9a5bf3d6..389f52c052 100644 --- a/app/src/main/java/com/ivy/wallet/ui/search/SearchScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/search/SearchScreen.kt @@ -5,10 +5,24 @@ import androidx.compose.animation.core.tween import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -19,7 +33,6 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.UI import com.ivy.frp.view.navigation.navigation import com.ivy.wallet.R @@ -36,7 +49,11 @@ import com.ivy.wallet.ui.theme.Gray import com.ivy.wallet.ui.theme.components.IvyBasicTextField import com.ivy.wallet.ui.theme.components.IvyIcon import com.ivy.wallet.ui.theme.modal.DURATION_MODAL_ANIM -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.densityScope +import com.ivy.wallet.utils.keyboardOnlyWindowInsets +import com.ivy.wallet.utils.keyboardVisibleState +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.selectEndTextFieldValue @Composable fun SearchScreen(screen: Search) { diff --git a/app/src/main/java/com/ivy/wallet/ui/serverstop/ServerStopScreen.kt b/app/src/main/java/com/ivy/wallet/ui/serverstop/ServerStopScreen.kt index 7899146040..c17cd913e7 100644 --- a/app/src/main/java/com/ivy/wallet/ui/serverstop/ServerStopScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/serverstop/ServerStopScreen.kt @@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue diff --git a/app/src/main/java/com/ivy/wallet/ui/serverstop/ServerStopViewModel.kt b/app/src/main/java/com/ivy/wallet/ui/serverstop/ServerStopViewModel.kt index 76c422f447..ef130a1b97 100644 --- a/app/src/main/java/com/ivy/wallet/ui/serverstop/ServerStopViewModel.kt +++ b/app/src/main/java/com/ivy/wallet/ui/serverstop/ServerStopViewModel.kt @@ -5,7 +5,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.ivy.frp.test.TestIdlingResource import com.ivy.frp.view.navigation.Navigation -import com.ivy.wallet.domain.deprecated.logic.zip.ExportZipLogic +import com.ivy.wallet.domain.deprecated.logic.zip.ExportBackupLogic import com.ivy.wallet.io.persistence.SharedPrefs import com.ivy.wallet.ui.IvyWalletCtx import com.ivy.wallet.ui.RootActivity @@ -23,7 +23,7 @@ import javax.inject.Inject class ServerStopViewModel @Inject constructor( private val ivyContext: IvyWalletCtx, private val sharedPrefs: SharedPrefs, - private val exportZipLogic: ExportZipLogic, + private val exportBackupLogic: ExportBackupLogic, private val navigation: Navigation, ) : ViewModel() { private val exportInProgress = MutableStateFlow(false) @@ -48,7 +48,7 @@ class ServerStopViewModel @Inject constructor( TestIdlingResource.increment() exportInProgress.value = true - exportZipLogic.exportToFile(context = context, zipFileUri = fileUri) + exportBackupLogic.exportToFile(context = context, zipFileUri = fileUri) exportInProgress.value = false sharedPrefs.putBoolean(SharedPrefs.DATA_BACKUP_COMPLETED, true) diff --git a/app/src/main/java/com/ivy/wallet/ui/settings/SettingsScreen.kt b/app/src/main/java/com/ivy/wallet/ui/settings/SettingsScreen.kt index bc4ff84eb1..7b309d9234 100644 --- a/app/src/main/java/com/ivy/wallet/ui/settings/SettingsScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/settings/SettingsScreen.kt @@ -5,12 +5,29 @@ import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -28,8 +45,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel import coil.compose.AsyncImage -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.SunsetNight import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style @@ -40,19 +55,48 @@ import com.ivy.wallet.BuildConfig import com.ivy.wallet.Constants import com.ivy.wallet.Constants.URL_IVY_CONTRIBUTORS import com.ivy.wallet.R +import com.ivy.wallet.backup.github.ui.GitHubBackupCard import com.ivy.wallet.domain.data.AuthProviderType import com.ivy.wallet.domain.data.IvyCurrency import com.ivy.wallet.domain.data.core.User -import com.ivy.wallet.ui.* +import com.ivy.wallet.ui.Import +import com.ivy.wallet.ui.IvyWalletPreview +import com.ivy.wallet.ui.Paywall +import com.ivy.wallet.ui.RootActivity +import com.ivy.wallet.ui.Settings +import com.ivy.wallet.ui.Test import com.ivy.wallet.ui.donate.DonateScreen import com.ivy.wallet.ui.exchangerates.ExchangeRatesScreen -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.ivyWalletCtx +import com.ivy.wallet.ui.rootActivity +import com.ivy.wallet.ui.theme.Blue +import com.ivy.wallet.ui.theme.Gradient +import com.ivy.wallet.ui.theme.GradientGreen +import com.ivy.wallet.ui.theme.GradientIvy +import com.ivy.wallet.ui.theme.GradientOrange +import com.ivy.wallet.ui.theme.GradientRed +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.Red3 +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.IvyButton import com.ivy.wallet.ui.theme.components.IvySwitch import com.ivy.wallet.ui.theme.components.IvyToolbar -import com.ivy.wallet.ui.theme.modal.* -import com.ivy.wallet.utils.* -import java.util.* +import com.ivy.wallet.ui.theme.findContrastTextColor +import com.ivy.wallet.ui.theme.modal.ChooseStartDateOfMonthModal +import com.ivy.wallet.ui.theme.modal.CurrencyModal +import com.ivy.wallet.ui.theme.modal.DeleteModal +import com.ivy.wallet.ui.theme.modal.NameModal +import com.ivy.wallet.ui.theme.modal.ProgressModal +import com.ivy.wallet.ui.theme.modal.RequestFeatureModal +import com.ivy.wallet.utils.OpResult +import com.ivy.wallet.utils.clickableNoIndication +import com.ivy.wallet.utils.drawColoredShadow +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.thenIf +import java.util.UUID @ExperimentalFoundationApi @Composable @@ -267,6 +311,14 @@ private fun BoxWithConstraintsScope.UI( ) ) } + + Spacer(Modifier.height(12.dp)) + + GitHubBackupCard( + modifier = Modifier + .padding(horizontal = 16.dp) + .fillMaxWidth() + ) } item { @@ -874,6 +926,7 @@ private fun AccountCardUser( Spacer(Modifier.width(24.dp)) } } + is OpResult.Success -> { if (opSync.data) { //synced @@ -913,6 +966,7 @@ private fun AccountCardUser( } } } + is OpResult.Failure -> { IvyButton( modifier = Modifier.padding(horizontal = 24.dp), 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 d5547c7392..f5151a65d6 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 @@ -16,7 +16,7 @@ import com.ivy.wallet.domain.data.core.User import com.ivy.wallet.domain.deprecated.logic.LogoutLogic import com.ivy.wallet.domain.deprecated.logic.csv.ExportCSVLogic import com.ivy.wallet.domain.deprecated.logic.currency.ExchangeRatesLogic -import com.ivy.wallet.domain.deprecated.logic.zip.ExportZipLogic +import com.ivy.wallet.domain.deprecated.logic.zip.ExportBackupLogic import com.ivy.wallet.domain.deprecated.sync.IvySync import com.ivy.wallet.io.network.FCMClient import com.ivy.wallet.io.network.IvyAnalytics @@ -61,7 +61,7 @@ class SettingsViewModel @Inject constructor( private val exchangeRatesLogic: ExchangeRatesLogic, private val logoutLogic: LogoutLogic, private val sharedPrefs: SharedPrefs, - private val exportZipLogic: ExportZipLogic, + private val exportBackupLogic: ExportBackupLogic, private val startDayOfMonthAct: StartDayOfMonthAct, private val updateStartDayOfMonthAct: UpdateStartDayOfMonthAct, private val fetchAllTrnsFromServerAct: FetchAllTrnsFromServerAct, @@ -223,7 +223,7 @@ class SettingsViewModel @Inject constructor( TestIdlingResource.increment() _progressState.value = true - exportZipLogic.exportToFile(context = context, zipFileUri = fileUri) + exportBackupLogic.exportToFile(context = context, zipFileUri = fileUri) _progressState.value = false sharedPrefs.putBoolean(SharedPrefs.DATA_BACKUP_COMPLETED, true) diff --git a/app/src/main/java/com/ivy/wallet/ui/statistic/level1/PieChartStatisticScreen.kt b/app/src/main/java/com/ivy/wallet/ui/statistic/level1/PieChartStatisticScreen.kt index d86ab1dc68..3387afff02 100644 --- a/app/src/main/java/com/ivy/wallet/ui/statistic/level1/PieChartStatisticScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/statistic/level1/PieChartStatisticScreen.kt @@ -4,12 +4,23 @@ import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -28,21 +39,47 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.frp.view.navigation.navigation import com.ivy.wallet.R import com.ivy.wallet.domain.data.TransactionType import com.ivy.wallet.domain.data.core.Category -import com.ivy.wallet.ui.* +import com.ivy.wallet.ui.EditTransaction +import com.ivy.wallet.ui.ItemStatistic +import com.ivy.wallet.ui.IvyWalletPreview +import com.ivy.wallet.ui.PieChartStatistic +import com.ivy.wallet.ui.ivyWalletCtx import com.ivy.wallet.ui.onboarding.model.TimePeriod -import com.ivy.wallet.ui.theme.* -import com.ivy.wallet.ui.theme.components.* +import com.ivy.wallet.ui.theme.GradientGreen +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.IvyDark +import com.ivy.wallet.ui.theme.IvyLight +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.RedLight +import com.ivy.wallet.ui.theme.White +import com.ivy.wallet.ui.theme.components.BalanceRow +import com.ivy.wallet.ui.theme.components.BalanceRowMini +import com.ivy.wallet.ui.theme.components.CircleButtonFilledGradient +import com.ivy.wallet.ui.theme.components.CloseButton +import com.ivy.wallet.ui.theme.components.ItemIconM +import com.ivy.wallet.ui.theme.components.ItemIconMDefaultIcon +import com.ivy.wallet.ui.theme.components.IvyOutlinedButton +import com.ivy.wallet.ui.theme.findContrastTextColor +import com.ivy.wallet.ui.theme.gradientExpenses import com.ivy.wallet.ui.theme.modal.ChoosePeriodModal +import com.ivy.wallet.ui.theme.pureBlur +import com.ivy.wallet.ui.theme.toComposeColor import com.ivy.wallet.ui.theme.wallet.AmountCurrencyB1Row -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.drawColoredShadow +import com.ivy.wallet.utils.format +import com.ivy.wallet.utils.horizontalSwipeListener +import com.ivy.wallet.utils.lerp +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.springBounce +import com.ivy.wallet.utils.thenIf @ExperimentalFoundationApi @Composable diff --git a/app/src/main/java/com/ivy/wallet/ui/statistic/level2/ItemStatisticScreen.kt b/app/src/main/java/com/ivy/wallet/ui/statistic/level2/ItemStatisticScreen.kt index 632ed2fe3e..4dce37ae79 100644 --- a/app/src/main/java/com/ivy/wallet/ui/statistic/level2/ItemStatisticScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/statistic/level2/ItemStatisticScreen.kt @@ -2,11 +2,27 @@ package com.ivy.wallet.ui.statistic.level2 import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -20,7 +36,6 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import com.google.accompanist.insets.statusBarsHeight import com.ivy.design.l0_system.Theme import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style @@ -35,13 +50,32 @@ import com.ivy.wallet.domain.data.core.Category import com.ivy.wallet.domain.data.core.Transaction import com.ivy.wallet.domain.pure.data.IncomeExpensePair import com.ivy.wallet.stringRes -import com.ivy.wallet.ui.* +import com.ivy.wallet.ui.EditTransaction +import com.ivy.wallet.ui.ItemStatistic +import com.ivy.wallet.ui.IvyWalletPreview +import com.ivy.wallet.ui.PieChartStatistic import com.ivy.wallet.ui.component.transaction.transactions import com.ivy.wallet.ui.data.AppBaseData import com.ivy.wallet.ui.data.DueSection +import com.ivy.wallet.ui.ivyWalletCtx import com.ivy.wallet.ui.onboarding.model.TimePeriod -import com.ivy.wallet.ui.theme.* -import com.ivy.wallet.ui.theme.components.* +import com.ivy.wallet.ui.theme.Gradient +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.GreenDark +import com.ivy.wallet.ui.theme.MediumBlack +import com.ivy.wallet.ui.theme.MediumWhite +import com.ivy.wallet.ui.theme.Transparent +import com.ivy.wallet.ui.theme.components.BalanceRow +import com.ivy.wallet.ui.theme.components.BalanceRowMedium +import com.ivy.wallet.ui.theme.components.CircleButton +import com.ivy.wallet.ui.theme.components.DeleteButton +import com.ivy.wallet.ui.theme.components.ItemIconMDefaultIcon +import com.ivy.wallet.ui.theme.components.IvyButton +import com.ivy.wallet.ui.theme.components.IvyOutlinedButton +import com.ivy.wallet.ui.theme.dynamicContrast +import com.ivy.wallet.ui.theme.findContrastTextColor +import com.ivy.wallet.ui.theme.isDarkColor import com.ivy.wallet.ui.theme.modal.ChoosePeriodModal import com.ivy.wallet.ui.theme.modal.ChoosePeriodModalData import com.ivy.wallet.ui.theme.modal.DeleteModal @@ -49,10 +83,18 @@ import com.ivy.wallet.ui.theme.modal.edit.AccountModal import com.ivy.wallet.ui.theme.modal.edit.AccountModalData import com.ivy.wallet.ui.theme.modal.edit.CategoryModal import com.ivy.wallet.ui.theme.modal.edit.CategoryModalData +import com.ivy.wallet.ui.theme.toComposeColor import com.ivy.wallet.ui.theme.wallet.PeriodSelector -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.balancePrefix +import com.ivy.wallet.utils.clickableNoIndication +import com.ivy.wallet.utils.drawColoredShadow +import com.ivy.wallet.utils.format +import com.ivy.wallet.utils.horizontalSwipeListener +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.setStatusBarDarkTextCompat +import com.ivy.wallet.utils.thenIf import java.math.BigDecimal -import java.util.* +import java.util.UUID @Composable @@ -246,11 +288,11 @@ private fun BoxWithConstraintsScope.UI( val listState = rememberLazyListState() val density = LocalDensity.current - Spacer(Modifier.statusBarsHeight()) LazyColumn( modifier = Modifier .fillMaxSize() + .systemBarsPadding() .padding(top = 16.dp) .clip(UI.shapes.r1Top) .background(UI.colors.pure) @@ -802,6 +844,7 @@ private fun Item( account != null -> { showAccountModal() } + category != null -> { showCategoryModal() } diff --git a/app/src/main/java/com/ivy/wallet/ui/test/TestScreen.kt b/app/src/main/java/com/ivy/wallet/ui/test/TestScreen.kt index f677f7a025..c1096c0533 100644 --- a/app/src/main/java/com/ivy/wallet/ui/test/TestScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/test/TestScreen.kt @@ -41,7 +41,7 @@ fun BoxWithConstraintsScope.TestScreen(screen: Test) { user = user, onSyncCategories = viewModel::syncCategories, - onTestWorker = viewModel::testWorker + onTestWorker = viewModel::testWorker, ) } @@ -50,7 +50,7 @@ private fun BoxWithConstraintsScope.UI( user: User?, onSyncCategories: () -> Unit, - onTestWorker: () -> Unit + onTestWorker: () -> Unit, ) { var chooseIconModalVisible by remember { mutableStateOf(false) diff --git a/app/src/main/java/com/ivy/wallet/ui/test/TestViewModel.kt b/app/src/main/java/com/ivy/wallet/ui/test/TestViewModel.kt index cb9052a539..9ffc67ce67 100644 --- a/app/src/main/java/com/ivy/wallet/ui/test/TestViewModel.kt +++ b/app/src/main/java/com/ivy/wallet/ui/test/TestViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.ivy.frp.test.TestIdlingResource +import com.ivy.wallet.backup.github.GitHubClient import com.ivy.wallet.domain.data.core.User import com.ivy.wallet.domain.deprecated.logic.notification.TransactionReminderLogic import com.ivy.wallet.domain.deprecated.sync.item.CategorySync @@ -20,7 +21,8 @@ class TestViewModel @Inject constructor( private val categorySync: CategorySync, private val userDao: UserDao, private val ivySession: IvySession, - private val transactionReminderLogic: TransactionReminderLogic + private val transactionReminderLogic: TransactionReminderLogic, + private val gitHubClient: GitHubClient, ) : ViewModel() { private val _user = MutableLiveData() diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/AddPrimaryAttributeButton.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/AddPrimaryAttributeButton.kt index 1b138211a6..4f40517989 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/AddPrimaryAttributeButton.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/AddPrimaryAttributeButton.kt @@ -3,8 +3,12 @@ package com.ivy.wallet.ui.theme.components import androidx.annotation.DrawableRes import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -18,7 +22,6 @@ import com.ivy.wallet.R import com.ivy.wallet.ui.IvyWalletComponentPreview - @Composable fun AddPrimaryAttributeButton( @DrawableRes icon: Int, diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/BalanceRow.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/BalanceRow.kt index 616d27b42d..1d373933ac 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/BalanceRow.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/BalanceRow.kt @@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/BudgetBattery.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/BudgetBattery.kt index c19ea00785..28bf02eda7 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/BudgetBattery.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/BudgetBattery.kt @@ -2,8 +2,16 @@ package com.ivy.wallet.ui.theme.components import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -18,7 +26,11 @@ import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.wallet.R import com.ivy.wallet.ui.IvyWalletComponentPreview -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.Ivy +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.wallet.AmountCurrencyB2Row import com.ivy.wallet.utils.format import com.ivy.wallet.utils.thenIf @@ -73,12 +85,15 @@ fun BudgetBattery( percentSpent <= 0.25 -> { Green } + percentSpent <= 0.50 -> { Ivy } + percentSpent <= 0.75 -> { Orange } + else -> Red }, size = size.copy( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/BufferBattery.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/BufferBattery.kt index b1dec93850..5631574bfd 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/BufferBattery.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/BufferBattery.kt @@ -2,8 +2,16 @@ package com.ivy.wallet.ui.theme.components import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -18,7 +26,11 @@ import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.wallet.R import com.ivy.wallet.ui.IvyWalletComponentPreview -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.Ivy +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.wallet.AmountCurrencyB2Row import com.ivy.wallet.utils.thenIf import kotlin.math.abs @@ -65,12 +77,15 @@ fun BufferBattery( bufferExceededPercent <= 0.25 -> { Green } + bufferExceededPercent <= 0.50 -> { Ivy } + bufferExceededPercent <= 0.75 -> { Orange } + else -> Red }, size = size.copy( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/ChangeTransactionTypeModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/ChangeTransactionTypeModal.kt index 8a68ae951e..b1a2f41c8b 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/ChangeTransactionTypeModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/ChangeTransactionTypeModal.kt @@ -2,9 +2,19 @@ package com.ivy.wallet.ui.theme.components import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -27,7 +37,7 @@ import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.modal.IvyModal import com.ivy.wallet.ui.theme.modal.ModalSet import com.ivy.wallet.ui.theme.modal.ModalTitle -import java.util.* +import java.util.UUID @Composable fun BoxWithConstraintsScope.ChangeTransactionTypeModal( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/CircleButtons.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/CircleButtons.kt index c8bf8aa069..c1c54974da 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/CircleButtons.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/CircleButtons.kt @@ -6,7 +6,7 @@ import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Icon +import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/CurrencyPicker.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/CurrencyPicker.kt index 18d84b97d3..4f8d97aae8 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/CurrencyPicker.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/CurrencyPicker.kt @@ -5,15 +5,26 @@ import androidx.compose.animation.core.tween import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -42,8 +53,13 @@ import com.ivy.wallet.ui.theme.GradientIvy import com.ivy.wallet.ui.theme.Ivy import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.modal.DURATION_MODAL_ANIM -import com.ivy.wallet.utils.* -import java.util.* +import com.ivy.wallet.utils.addKeyboardListener +import com.ivy.wallet.utils.densityScope +import com.ivy.wallet.utils.hideKeyboard +import com.ivy.wallet.utils.keyboardOnlyWindowInsets +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.toLowerCaseLocal +import java.util.Locale @Composable fun CurrencyPicker( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/CustomExchangeRateCard.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/CustomExchangeRateCard.kt index 3c6f1e53de..4b271ad991 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/CustomExchangeRateCard.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/CustomExchangeRateCard.kt @@ -2,8 +2,15 @@ package com.ivy.wallet.ui.theme.components import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IntervalPickerRow.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IntervalPickerRow.kt index 32960a5952..a6d270d68c 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IntervalPickerRow.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IntervalPickerRow.kt @@ -3,10 +3,19 @@ package com.ivy.wallet.ui.theme.components import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyBasicTextField.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyBasicTextField.kt index 700695706d..1de80ca9f1 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyBasicTextField.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyBasicTextField.kt @@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -13,7 +13,11 @@ import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.* +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardCapitalization +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import com.ivy.design.l0_system.UI diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyBorderButton.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyBorderButton.kt index 9ccaa6fba2..94b1d0ca92 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyBorderButton.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyBorderButton.kt @@ -7,8 +7,8 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width -import androidx.compose.material.Icon -import androidx.compose.material.Text +import androidx.compose.material3.Icon +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyButton.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyButton.kt index 79e4ed5921..28ea9133f4 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyButton.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyButton.kt @@ -3,9 +3,14 @@ package com.ivy.wallet.ui.theme.components import androidx.annotation.DrawableRes import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Icon -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.material3.Icon +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyCheckbox.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyCheckbox.kt index 71cbe331ee..8e2806cf07 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyCheckbox.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyCheckbox.kt @@ -1,10 +1,14 @@ package com.ivy.wallet.ui.theme.components import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Icon -import androidx.compose.material.Text +import androidx.compose.material3.Icon +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyChecklistTextField.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyChecklistTextField.kt index cf0d053b0f..a40d81f0dd 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyChecklistTextField.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyChecklistTextField.kt @@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -16,7 +16,11 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.platform.LocalView import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.* +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardCapitalization +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyColorPicker.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyColorPicker.kt index d0f891adcc..77423d8bd4 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyColorPicker.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyColorPicker.kt @@ -3,11 +3,19 @@ package com.ivy.wallet.ui.theme.components import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment @@ -27,7 +35,58 @@ import com.ivy.wallet.R import com.ivy.wallet.ui.IvyWalletComponentPreview import com.ivy.wallet.ui.ivyWalletCtx import com.ivy.wallet.ui.paywall.PaywallReason -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.Blue +import com.ivy.wallet.ui.theme.Blue2 +import com.ivy.wallet.ui.theme.Blue2Dark +import com.ivy.wallet.ui.theme.Blue2Light +import com.ivy.wallet.ui.theme.Blue3 +import com.ivy.wallet.ui.theme.Blue3Dark +import com.ivy.wallet.ui.theme.Blue3Light +import com.ivy.wallet.ui.theme.BlueDark +import com.ivy.wallet.ui.theme.BlueLight +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.Green2 +import com.ivy.wallet.ui.theme.Green2Dark +import com.ivy.wallet.ui.theme.Green2Light +import com.ivy.wallet.ui.theme.Green3 +import com.ivy.wallet.ui.theme.Green3Dark +import com.ivy.wallet.ui.theme.Green3Light +import com.ivy.wallet.ui.theme.Green4 +import com.ivy.wallet.ui.theme.Green4Dark +import com.ivy.wallet.ui.theme.Green4Light +import com.ivy.wallet.ui.theme.GreenDark +import com.ivy.wallet.ui.theme.GreenLight +import com.ivy.wallet.ui.theme.Ivy +import com.ivy.wallet.ui.theme.IvyDark +import com.ivy.wallet.ui.theme.IvyLight +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.Orange2 +import com.ivy.wallet.ui.theme.Orange2Dark +import com.ivy.wallet.ui.theme.Orange2Light +import com.ivy.wallet.ui.theme.Orange3 +import com.ivy.wallet.ui.theme.Orange3Dark +import com.ivy.wallet.ui.theme.Orange3Light +import com.ivy.wallet.ui.theme.OrangeDark +import com.ivy.wallet.ui.theme.OrangeLight +import com.ivy.wallet.ui.theme.Purple1 +import com.ivy.wallet.ui.theme.Purple1Dark +import com.ivy.wallet.ui.theme.Purple1Light +import com.ivy.wallet.ui.theme.Purple2 +import com.ivy.wallet.ui.theme.Purple2Dark +import com.ivy.wallet.ui.theme.Purple2Light +import com.ivy.wallet.ui.theme.Red +import com.ivy.wallet.ui.theme.Red2 +import com.ivy.wallet.ui.theme.Red2Dark +import com.ivy.wallet.ui.theme.Red2Light +import com.ivy.wallet.ui.theme.Red3 +import com.ivy.wallet.ui.theme.Red3Dark +import com.ivy.wallet.ui.theme.Red3Light +import com.ivy.wallet.ui.theme.RedDark +import com.ivy.wallet.ui.theme.RedLight +import com.ivy.wallet.ui.theme.Yellow +import com.ivy.wallet.ui.theme.YellowDark +import com.ivy.wallet.ui.theme.YellowLight +import com.ivy.wallet.ui.theme.dynamicContrast import com.ivy.wallet.utils.densityScope import com.ivy.wallet.utils.onScreenStart import com.ivy.wallet.utils.thenIf diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyDescriptionTextField.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyDescriptionTextField.kt index 466f5b0c0d..d637d2386f 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyDescriptionTextField.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyDescriptionTextField.kt @@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -15,7 +15,11 @@ import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.* +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardCapitalization +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyIcon.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyIcon.kt index 9631bf8a54..a2df5fe06b 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyIcon.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyIcon.kt @@ -1,7 +1,7 @@ package com.ivy.wallet.ui.theme.components import androidx.annotation.DrawableRes -import androidx.compose.material.Icon +import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyNameTextFieldValue.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyNameTextFieldValue.kt index 2cad0a3266..a818330de1 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyNameTextFieldValue.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyNameTextFieldValue.kt @@ -1,10 +1,15 @@ package com.ivy.wallet.ui.theme.components -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -13,7 +18,11 @@ import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.* +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardCapitalization +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyNumberTextField.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyNumberTextField.kt index e97dd4cbba..02c15af0ea 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyNumberTextField.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyNumberTextField.kt @@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -13,7 +13,11 @@ import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.* +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardCapitalization +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import com.ivy.design.l0_system.UI diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyOutlinedButton.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyOutlinedButton.kt index e31a539b17..6200b6c0c8 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyOutlinedButton.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyOutlinedButton.kt @@ -4,8 +4,12 @@ import androidx.annotation.DrawableRes import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyOutlinedTextField.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyOutlinedTextField.kt index 4438db50fa..08be9754bd 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyOutlinedTextField.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyOutlinedTextField.kt @@ -9,7 +9,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyTitleTextField.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyTitleTextField.kt index 0e78609f7e..93945c1b35 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyTitleTextField.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/IvyTitleTextField.kt @@ -1,11 +1,18 @@ package com.ivy.wallet.ui.theme.components import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -14,7 +21,11 @@ import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.* +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardCapitalization +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/OnboardingComponents.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/OnboardingComponents.kt index 3dce0ed889..4e43bbea00 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/OnboardingComponents.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/OnboardingComponents.kt @@ -7,7 +7,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/ReorderModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/ReorderModal.kt index 777e87249a..665b57b5a8 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/ReorderModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/ReorderModal.kt @@ -5,7 +5,7 @@ import android.view.View import android.view.ViewGroup import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.* -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/components/WrapContentRow.kt b/app/src/main/java/com/ivy/wallet/ui/theme/components/WrapContentRow.kt index 22baf4a433..8f1fab3d02 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/components/WrapContentRow.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/components/WrapContentRow.kt @@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/AddKeywordModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/AddKeywordModal.kt index 53201f37da..78fd5a33df 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/AddKeywordModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/AddKeywordModal.kt @@ -4,8 +4,12 @@ import androidx.compose.foundation.layout.BoxWithConstraintsScope import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester @@ -20,7 +24,7 @@ import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.theme.components.IvyTitleTextField import com.ivy.wallet.utils.onScreenStart import com.ivy.wallet.utils.selectEndTextFieldValue -import java.util.* +import java.util.UUID @Composable fun BoxWithConstraintsScope.AddKeywordModal( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/BudgetModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/BudgetModal.kt index b2096f4ab2..d184678236 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/BudgetModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/BudgetModal.kt @@ -1,12 +1,21 @@ package com.ivy.wallet.ui.theme.modal -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester @@ -14,6 +23,7 @@ import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardCapitalization @@ -21,7 +31,6 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.compose.ui.res.stringResource import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.wallet.R @@ -41,7 +50,7 @@ import com.ivy.wallet.utils.hideKeyboard import com.ivy.wallet.utils.isNotNullOrBlank import com.ivy.wallet.utils.onScreenStart import com.ivy.wallet.utils.selectEndTextFieldValue -import java.util.* +import java.util.UUID data class BudgetModalData( val budget: Budget?, diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/ChoosePeriodModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/ChoosePeriodModal.kt index be9ba2e340..f004dea3e4 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/ChoosePeriodModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/ChoosePeriodModal.kt @@ -1,12 +1,27 @@ package com.ivy.wallet.ui.theme.modal -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.rememberScrollState +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -24,18 +39,26 @@ import com.ivy.wallet.ui.ivyWalletCtx import com.ivy.wallet.ui.onboarding.model.FromToTimeRange import com.ivy.wallet.ui.onboarding.model.LastNTimeRange import com.ivy.wallet.ui.onboarding.model.TimePeriod -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.Gradient +import com.ivy.wallet.ui.theme.GradientIvy +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Green +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.CircleButtonFilled import com.ivy.wallet.ui.theme.components.IntervalPickerRow import com.ivy.wallet.ui.theme.components.IvyDividerLine import com.ivy.wallet.ui.theme.modal.model.Month import com.ivy.wallet.ui.theme.modal.model.Month.Companion.fromMonthValue import com.ivy.wallet.ui.theme.modal.model.Month.Companion.monthsList -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.addKeyboardListener +import com.ivy.wallet.utils.dateNowUTC +import com.ivy.wallet.utils.formatDateOnlyWithYear +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.timeNowUTC import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.time.LocalDateTime -import java.util.* +import java.util.UUID data class ChoosePeriodModalData( val id: UUID = UUID.randomUUID(), diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/ChooseStartDateOfMonthModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/ChooseStartDateOfMonthModal.kt index 0f520f7d0f..7084093e1c 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/ChooseStartDateOfMonthModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/ChooseStartDateOfMonthModal.kt @@ -3,9 +3,16 @@ package com.ivy.wallet.ui.theme.modal import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -22,7 +29,7 @@ import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.theme.Ivy import com.ivy.wallet.ui.theme.White import com.ivy.wallet.utils.thenIf -import java.util.* +import java.util.UUID @Composable fun BoxWithConstraintsScope.ChooseStartDateOfMonthModal( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/CurrencyModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/CurrencyModal.kt index 3bd894de98..f7a127db97 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/CurrencyModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/CurrencyModal.kt @@ -1,8 +1,16 @@ package com.ivy.wallet.ui.theme.modal -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag @@ -17,7 +25,7 @@ import com.ivy.wallet.domain.data.IvyCurrency import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.theme.Gray import com.ivy.wallet.ui.theme.components.CurrencyPicker -import java.util.* +import java.util.UUID @Composable fun BoxWithConstraintsScope.CurrencyModal( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/DeleteModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/DeleteModal.kt index 2334dc47e3..b8ab5e8c9c 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/DeleteModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/DeleteModal.kt @@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.BoxWithConstraintsScope import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -13,9 +13,8 @@ import androidx.compose.ui.unit.dp import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.wallet.R - import com.ivy.wallet.ui.theme.Red -import java.util.* +import java.util.UUID @Composable fun BoxWithConstraintsScope.DeleteModal( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/IvyModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/IvyModal.kt index 7be9215c70..2ea4323a62 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/IvyModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/IvyModal.kt @@ -3,10 +3,29 @@ package com.ivy.wallet.ui.theme.modal import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.tween -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -18,7 +37,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.l0_system.UI import com.ivy.frp.view.navigation.Navigation import com.ivy.frp.view.navigation.navigation @@ -28,8 +46,15 @@ import com.ivy.wallet.ui.theme.components.ActionsRow import com.ivy.wallet.ui.theme.components.CloseButton import com.ivy.wallet.ui.theme.gradientCutBackgroundTop import com.ivy.wallet.ui.theme.mediumBlur -import com.ivy.wallet.utils.* -import java.util.* +import com.ivy.wallet.utils.addKeyboardListener +import com.ivy.wallet.utils.consumeClicks +import com.ivy.wallet.utils.densityScope +import com.ivy.wallet.utils.hideKeyboard +import com.ivy.wallet.utils.keyboardOnlyWindowInsets +import com.ivy.wallet.utils.navigationBarInsets +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.thenIf +import java.util.UUID import kotlin.math.roundToInt diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/IvyModalComponents.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/IvyModalComponents.kt index 5e1f18d2bf..6ec05ebbe4 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/IvyModalComponents.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/IvyModalComponents.kt @@ -3,7 +3,7 @@ package com.ivy.wallet.ui.theme.modal import androidx.annotation.DrawableRes import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/IvyModalDomainComponents.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/IvyModalDomainComponents.kt index ab8160b2ba..7079af66b3 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/IvyModalDomainComponents.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/IvyModalDomainComponents.kt @@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/LoanModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/LoanModal.kt index bb4350e5a9..302cc28425 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/LoanModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/LoanModal.kt @@ -3,12 +3,25 @@ package com.ivy.wallet.ui.theme.modal import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -32,18 +45,27 @@ import com.ivy.wallet.domain.data.core.Loan import com.ivy.wallet.domain.deprecated.logic.model.CreateAccountData import com.ivy.wallet.domain.deprecated.logic.model.CreateLoanData import com.ivy.wallet.ui.IvyWalletPreview -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.GradientIvy +import com.ivy.wallet.ui.theme.Gray +import com.ivy.wallet.ui.theme.Ivy +import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.ItemIconSDefaultIcon import com.ivy.wallet.ui.theme.components.IvyCheckboxWithText import com.ivy.wallet.ui.theme.components.IvyColorPicker import com.ivy.wallet.ui.theme.components.IvyIcon +import com.ivy.wallet.ui.theme.findContrastTextColor import com.ivy.wallet.ui.theme.modal.edit.AccountModal import com.ivy.wallet.ui.theme.modal.edit.AccountModalData import com.ivy.wallet.ui.theme.modal.edit.AmountModal import com.ivy.wallet.ui.theme.modal.edit.IconNameRow -import com.ivy.wallet.utils.* +import com.ivy.wallet.ui.theme.toComposeColor +import com.ivy.wallet.utils.getDefaultFIATCurrency +import com.ivy.wallet.utils.isNotNullOrBlank +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.selectEndTextFieldValue +import com.ivy.wallet.utils.thenIf import kotlinx.coroutines.launch -import java.util.* +import java.util.UUID data class LoanModalData( val loan: Loan?, diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/LoanRecordModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/LoanRecordModal.kt index 096462c7a4..51766ccf6e 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/LoanRecordModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/LoanRecordModal.kt @@ -3,12 +3,23 @@ package com.ivy.wallet.ui.theme.modal import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -38,10 +49,18 @@ import com.ivy.wallet.ui.theme.modal.edit.AccountModal import com.ivy.wallet.ui.theme.modal.edit.AccountModalData import com.ivy.wallet.ui.theme.modal.edit.AmountModal import com.ivy.wallet.ui.theme.toComposeColor -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.convertUTCtoLocal +import com.ivy.wallet.utils.formatLocalTime +import com.ivy.wallet.utils.formatNicely +import com.ivy.wallet.utils.getDefaultFIATCurrency +import com.ivy.wallet.utils.getTrueDate +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.selectEndTextFieldValue +import com.ivy.wallet.utils.thenIf +import com.ivy.wallet.utils.timeNowUTC import kotlinx.coroutines.launch import java.time.LocalDateTime -import java.util.* +import java.util.UUID data class LoanRecordModalData( val loanRecord: LoanRecord?, diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/MonthPickerModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/MonthPickerModal.kt index edaec94eba..0432a05e50 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/MonthPickerModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/MonthPickerModal.kt @@ -7,8 +7,12 @@ import androidx.compose.foundation.layout.BoxWithConstraintsScope import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalView @@ -26,9 +30,13 @@ import com.ivy.wallet.ui.theme.components.WrapContentRow import com.ivy.wallet.ui.theme.findContrastTextColor import com.ivy.wallet.ui.theme.modal.model.Month import com.ivy.wallet.ui.theme.modal.model.Month.Companion.monthsList -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.dateNowUTC +import com.ivy.wallet.utils.drawColoredShadow +import com.ivy.wallet.utils.hideKeyboard +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.thenIf import java.time.LocalDate -import java.util.* +import java.util.UUID @Composable fun BoxWithConstraintsScope.MonthPickerModal( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/NameModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/NameModal.kt index 2f6cec0666..a51d64b5f7 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/NameModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/NameModal.kt @@ -4,8 +4,12 @@ import androidx.compose.foundation.layout.BoxWithConstraintsScope import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight @@ -17,7 +21,7 @@ import com.ivy.wallet.R import com.ivy.wallet.ui.IvyWalletPreview import com.ivy.wallet.ui.theme.components.IvyTitleTextField import com.ivy.wallet.utils.selectEndTextFieldValue -import java.util.* +import java.util.UUID @Composable fun BoxWithConstraintsScope.NameModal( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/ProgressModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/ProgressModal.kt index 5f95c3cae2..b5e6e89a02 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/ProgressModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/ProgressModal.kt @@ -1,8 +1,12 @@ package com.ivy.wallet.ui.theme.modal -import androidx.compose.foundation.layout.* -import androidx.compose.material.LinearProgressIndicator -import androidx.compose.material.Text +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.LinearProgressIndicator +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -12,7 +16,7 @@ import androidx.compose.ui.unit.dp import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.wallet.ui.theme.Red -import java.util.* +import java.util.UUID @Composable fun BoxWithConstraintsScope.ProgressModal( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/RecurringRuleModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/RecurringRuleModal.kt index 70fca87e0e..3bc4235f37 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/RecurringRuleModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/RecurringRuleModal.kt @@ -3,10 +3,25 @@ package com.ivy.wallet.ui.theme.modal import androidx.compose.foundation.ScrollState import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -31,12 +46,20 @@ import com.ivy.wallet.ui.theme.White import com.ivy.wallet.ui.theme.components.IntervalPickerRow import com.ivy.wallet.ui.theme.components.IvyCircleButton import com.ivy.wallet.ui.theme.components.IvyDividerLine -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.addKeyboardListener +import com.ivy.wallet.utils.clickableNoIndication +import com.ivy.wallet.utils.closeDay +import com.ivy.wallet.utils.formatDateWeekDayLong +import com.ivy.wallet.utils.formatNicely +import com.ivy.wallet.utils.hideKeyboard +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.thenIf +import com.ivy.wallet.utils.timeNowUTC import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.time.LocalDate import java.time.LocalDateTime -import java.util.* +import java.util.UUID data class RecurringRuleModalData( val initialStartDate: LocalDateTime?, diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/AccountModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/AccountModal.kt index a62f4d9656..e61f0c1bdf 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/AccountModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/AccountModal.kt @@ -2,9 +2,18 @@ package com.ivy.wallet.ui.theme.modal.edit import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -28,9 +37,18 @@ import com.ivy.wallet.ui.theme.Gray import com.ivy.wallet.ui.theme.Ivy import com.ivy.wallet.ui.theme.components.IvyCheckboxWithText import com.ivy.wallet.ui.theme.components.IvyColorPicker -import com.ivy.wallet.ui.theme.modal.* -import com.ivy.wallet.utils.* -import java.util.* +import com.ivy.wallet.ui.theme.modal.ChooseIconModal +import com.ivy.wallet.ui.theme.modal.CurrencyModal +import com.ivy.wallet.ui.theme.modal.IvyModal +import com.ivy.wallet.ui.theme.modal.ModalAddSave +import com.ivy.wallet.ui.theme.modal.ModalAmountSection +import com.ivy.wallet.ui.theme.modal.ModalTitle +import com.ivy.wallet.utils.isNotNullOrBlank +import com.ivy.wallet.utils.onScreenStart +import com.ivy.wallet.utils.selectEndTextFieldValue +import com.ivy.wallet.utils.toLowerCaseLocal +import com.ivy.wallet.utils.toUpperCaseLocal +import java.util.UUID data class AccountModalData( val account: Account?, diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/AmountModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/AmountModal.kt index 9a09ca9d5d..edb19d4195 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/AmountModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/AmountModal.kt @@ -4,10 +4,24 @@ import android.annotation.SuppressLint import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -29,8 +43,15 @@ import com.ivy.wallet.ui.theme.components.IvyIcon import com.ivy.wallet.ui.theme.modal.IvyModal import com.ivy.wallet.ui.theme.modal.ModalPositiveButton import com.ivy.wallet.ui.theme.modal.modalPreviewActionRowHeight -import com.ivy.wallet.utils.* -import java.util.* +import com.ivy.wallet.utils.amountToDouble +import com.ivy.wallet.utils.amountToDoubleOrNull +import com.ivy.wallet.utils.format +import com.ivy.wallet.utils.formatInputAmount +import com.ivy.wallet.utils.formatInt +import com.ivy.wallet.utils.hideKeyboard +import com.ivy.wallet.utils.localDecimalSeparator +import com.ivy.wallet.utils.onScreenStart +import java.util.UUID import kotlin.math.truncate @Composable diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/CalculatorModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/CalculatorModal.kt index 32751c898f..6c15fde7ae 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/CalculatorModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/CalculatorModal.kt @@ -1,8 +1,17 @@ package com.ivy.wallet.ui.theme.modal.edit -import androidx.compose.foundation.layout.* -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource @@ -19,9 +28,13 @@ import com.ivy.wallet.ui.theme.Red import com.ivy.wallet.ui.theme.modal.IvyModal import com.ivy.wallet.ui.theme.modal.ModalSet import com.ivy.wallet.ui.theme.modal.ModalTitle -import com.ivy.wallet.utils.* +import com.ivy.wallet.utils.amountToDoubleOrNull +import com.ivy.wallet.utils.format +import com.ivy.wallet.utils.formatInputAmount +import com.ivy.wallet.utils.localDecimalSeparator +import com.ivy.wallet.utils.normalizeExpression import com.notkamui.keval.Keval -import java.util.* +import java.util.UUID @Composable fun BoxWithConstraintsScope.CalculatorModal( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/ChooseCategoryModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/ChooseCategoryModal.kt index 07d3d2ada2..54bf305142 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/ChooseCategoryModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/ChooseCategoryModal.kt @@ -4,10 +4,20 @@ import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -23,19 +33,24 @@ import com.ivy.design.l0_system.style import com.ivy.wallet.R import com.ivy.wallet.domain.data.core.Category import com.ivy.wallet.ui.IvyWalletPreview -import com.ivy.wallet.ui.theme.* +import com.ivy.wallet.ui.theme.Gradient +import com.ivy.wallet.ui.theme.Ivy +import com.ivy.wallet.ui.theme.Orange +import com.ivy.wallet.ui.theme.Red import com.ivy.wallet.ui.theme.components.ItemIconSDefaultIcon import com.ivy.wallet.ui.theme.components.IvyBorderButton import com.ivy.wallet.ui.theme.components.IvyCircleButton import com.ivy.wallet.ui.theme.components.WrapContentRow +import com.ivy.wallet.ui.theme.findContrastTextColor import com.ivy.wallet.ui.theme.modal.IvyModal import com.ivy.wallet.ui.theme.modal.ModalSkip import com.ivy.wallet.ui.theme.modal.ModalTitle +import com.ivy.wallet.ui.theme.toComposeColor import com.ivy.wallet.utils.drawColoredShadow import com.ivy.wallet.utils.hideKeyboard import com.ivy.wallet.utils.onScreenStart import com.ivy.wallet.utils.thenIf -import java.util.* +import java.util.UUID @ExperimentalFoundationApi @Composable diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/DescriptionModal.kt b/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/DescriptionModal.kt index d1429f14f2..7d44d20ec4 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/DescriptionModal.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/modal/edit/DescriptionModal.kt @@ -1,10 +1,18 @@ package com.ivy.wallet.ui.theme.modal.edit -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.BoxWithConstraintsScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester @@ -28,7 +36,7 @@ import com.ivy.wallet.ui.theme.modal.ModalDynamicPrimaryAction import com.ivy.wallet.utils.clickableNoIndication import com.ivy.wallet.utils.onScreenStart import com.ivy.wallet.utils.selectEndTextFieldValue -import java.util.* +import java.util.UUID @Composable fun BoxWithConstraintsScope.DescriptionModal( diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/wallet/AmountCurrency.kt b/app/src/main/java/com/ivy/wallet/ui/theme/wallet/AmountCurrency.kt index 9a34133580..104a88a9d4 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/wallet/AmountCurrency.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/wallet/AmountCurrency.kt @@ -3,7 +3,7 @@ package com.ivy.wallet.ui.theme.wallet import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.width -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/theme/wallet/PeriodSelector.kt b/app/src/main/java/com/ivy/wallet/ui/theme/wallet/PeriodSelector.kt index 500aecb633..7d27e350ad 100644 --- a/app/src/main/java/com/ivy/wallet/ui/theme/wallet/PeriodSelector.kt +++ b/app/src/main/java/com/ivy/wallet/ui/theme/wallet/PeriodSelector.kt @@ -3,9 +3,17 @@ package com.ivy.wallet.ui.theme.wallet import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/ivy/wallet/ui/webView/WebViewScreen.kt b/app/src/main/java/com/ivy/wallet/ui/webView/WebViewScreen.kt index 80ad2f2275..20cce14744 100644 --- a/app/src/main/java/com/ivy/wallet/ui/webView/WebViewScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/webView/WebViewScreen.kt @@ -7,13 +7,13 @@ import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.BoxWithConstraintsScope import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.webkit.WebSettingsCompat import androidx.webkit.WebViewFeature -import com.google.accompanist.insets.systemBarsPadding import com.ivy.design.l0_system.Theme import com.ivy.frp.view.navigation.navigation import com.ivy.wallet.ui.IvyWebView diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index ca021f8eb5..b6e1232cc3 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -3,12 +3,8 @@ plugins { id("org.gradle.test-retry") version "1.2.0" } -tasks.test { - retry { - maxRetries.set(2) - maxFailures.set(10) - failOnPassedAfterRetry.set(false) - } +tasks.withType().configureEach { + useJUnitPlatform() } repositories { 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 f095d22ad5..52381d1928 100644 --- a/buildSrc/src/main/java/com/ivy/wallet/buildsrc/dependencies.kt +++ b/buildSrc/src/main/java/com/ivy/wallet/buildsrc/dependencies.kt @@ -17,7 +17,6 @@ package com.ivy.wallet.buildsrc import org.gradle.api.artifacts.dsl.DependencyHandler -import org.gradle.kotlin.dsl.project object Project { @@ -46,26 +45,25 @@ object GlobalVersions { fun DependencyHandler.appModuleDependencies( kotlinVersion: String = GlobalVersions.kotlinVersion ) { - implementation(project(":ivy-design")) +// implementation(project(":ivy-design")) - implementation("com.github.ILIYANGERMANOV:ivy-frp:0.9.5") +// implementation("com.github.ILIYANGERMANOV:ivy-frp:0.9.5") - Kotlin(version = kotlinVersion) - Coroutines(version = "1.5.0") - FunctionalProgramming( - arrowVersion = "1.0.1", - kotestVersion = "5.1.0", - kotlinVersion = kotlinVersion - ) +// Coroutines(version = "1.5.0") +// FunctionalProgramming( +// arrowVersion = "1.0.1", +// kotestVersion = "5.1.0", +// kotlinVersion = kotlinVersion +// ) - Compose(version = GlobalVersions.compose) +// Compose(version = GlobalVersions.compose) Google() Firebase() Hilt( - hiltVersion = "2.47", - versionX = "1.0.0" + hiltVersion = "2.47", + versionX = "1.0.0" ) RoomDB() @@ -74,23 +72,20 @@ fun DependencyHandler.appModuleDependencies( Lifecycle(version = "2.3.1") AndroidX() - DataStore() - ThirdParty() } fun DependencyHandler.ivyDesignModuleDependencies( kotlinVersion: String = GlobalVersions.kotlinVersion ) { - Kotlin(version = kotlinVersion) - Coroutines(version = "1.5.0") - FunctionalProgramming( - arrowVersion = "1.0.1", - kotestVersion = "5.1.0", - kotlinVersion = kotlinVersion - ) +// Coroutines(version = "1.5.0") +// FunctionalProgramming( +// arrowVersion = "1.0.1", +// kotestVersion = "5.1.0", +// kotlinVersion = kotlinVersion +// ) - Compose(version = GlobalVersions.compose) +// Compose(version = GlobalVersions.compose) AndroidX() Lifecycle(version = "2.3.1") @@ -101,73 +96,6 @@ fun DependencyHandler.DataStore() { implementation("androidx.datastore:datastore-preferences:1.0.0") } -/** - * Kotlin STD lib - * https://kotlinlang.org/docs/releases.html#release-details - */ -fun DependencyHandler.Kotlin(version: String) { - //URL: https://kotlinlang.org/docs/releases.html#release-details - //WARNING: Version is also updated from buildSrc - implementation("org.jetbrains.kotlin:kotlin-stdlib:$version") -} - -fun DependencyHandler.Compose(version: String) { - val foundation = GlobalVersions.composeFoundation - //URL: https://developer.android.com/jetpack/androidx/releases/compose - implementation("androidx.compose.ui:ui:$foundation") - implementation("androidx.compose.foundation:foundation:$foundation") - implementation("androidx.compose.animation:animation:$foundation") - implementation("androidx.compose.material:material:$foundation") - implementation("androidx.compose.material:material-icons-extended:$foundation") - implementation("androidx.compose.runtime:runtime-livedata:$foundation") - implementation("androidx.compose.ui:ui-tooling:$foundation") - - //URL: https://developer.android.com/jetpack/androidx/releases/activity - implementation("androidx.activity:activity-compose:1.4.0") - - //URL: https://developer.android.com/jetpack/androidx/releases/lifecycle - implementation("androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha05") - - // Jetpack Glance (Compose Widgets) - // 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") - - Coil() - - ComposeTesting(version = version) -} - -/** - * Compose Window Insets + extras - * https://github.com/google/accompanist - */ -fun DependencyHandler.Accompanist(version: String) { - implementation("com.google.accompanist:accompanist-coil:$version") - implementation("com.google.accompanist:accompanist-insets:$version") - implementation("com.google.accompanist:accompanist-systemuicontroller:0.24.4-alpha") -} - -fun DependencyHandler.Coil() { - implementation("io.coil-kt:coil-compose:2.0.0") -} - -/** - * Required for running Compose UI tests - * https://developer.android.com/jetpack/compose/testing#setup - */ -fun DependencyHandler.ComposeTesting(version: String) { - //THIS IS NOT RIGHT: Implementation for IdlingResource access on both Debug & Release - //Without having this dependency "lintRelease" fails - implementation("androidx.compose.ui:ui-test-junit4:${GlobalVersions.composeFoundation}") - - // Needed for createComposeRule, but not createAndroidComposeRule: - androidTestImplementation("androidx.compose.ui:ui-test-manifest:${GlobalVersions.composeFoundation}") -} - fun DependencyHandler.Google() { //URL: https://mvnrepository.com/artifact/com.google.android.gms/play-services-auth implementation("com.google.android.gms:play-services-auth:19.2.0") @@ -279,19 +207,6 @@ fun DependencyHandler.AndroidX() { implementation("androidx.webkit:webkit:1.4.0") } -fun DependencyHandler.Coroutines( - version: String = "1.7.3" -) { - //URL: https://github.com/Kotlin/kotlinx.coroutines - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$version") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$version") - - //URL: https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-play-services - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$version") - - //URL: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/ - androidTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$version") -} fun DependencyHandler.ThirdParty() { //URL: https://github.com/airbnb/lottie-android @@ -311,51 +226,4 @@ fun DependencyHandler.ThirdParty() { implementation("com.opencsv:opencsv:5.5") implementation("org.apache.commons:commons-lang3:3.12.0") -} - -fun DependencyHandler.FunctionalProgramming( - arrowVersion: String = "1.0.1", - kotestVersion: String = "5.1.0", - kotlinVersion: String -) { - Arrow(version = arrowVersion) - - Kotest( - version = kotestVersion, - arrowVersion = arrowVersion, - kotlinVersion = kotlinVersion - ) -} - -/** - * Functional Programming with Kotlin - */ -fun DependencyHandler.Arrow( - version: String -) { - implementation(platform("io.arrow-kt:arrow-stack:$version")) - implementation("io.arrow-kt:arrow-core") - implementation("io.arrow-kt:arrow-fx-coroutines") - implementation("io.arrow-kt:arrow-fx-stm") -} - -/** - * Kotlin Property-based testing - */ -fun DependencyHandler.Kotest( - version: String, - arrowVersion: String, - kotlinVersion: String -) { - //junit5 is required! - testImplementation("org.junit.jupiter:junit-jupiter:5.8.2") - testImplementation("io.kotest:kotest-runner-junit5:$version") - testImplementation("io.kotest:kotest-assertions-core:$version") - testImplementation("io.kotest:kotest-property:$version") - - //otherwise Kotest doesn't work... - testImplementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion") - - - testImplementation("io.kotest.extensions:kotest-property-arrow:$arrowVersion") } \ No newline at end of file diff --git a/docs/Business-Model.md b/docs/Business-Model.md deleted file mode 100644 index d181f7d377..0000000000 --- a/docs/Business-Model.md +++ /dev/null @@ -1,75 +0,0 @@ -# Business Model - -[![PRs are welcome!](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/ILIYANGERMANOV/ivy-wallet/blob/main/CONTRIBUTING.md) -[![Feedback is welcome!](https://img.shields.io/badge/feedback-welcome-brightgreen)](https://t.me/+ETavgioAvWg4NThk) -[![Proposals are highly appreciated!](https://img.shields.io/badge/proposals-highly%20appreciated-brightgreen)](https://t.me/+ETavgioAvWg4NThk) - -**:warning: Disclaimer: This business model isn't eternal and might evolve over time. So... We need your honest opinion to make it better!** - -## Non-profit - -For now, the model behind Ivy Wallet would be non-profit. A place to develop cool tech, use it to manage your money and also build a solid public portfolio on GitHub. - -> In the near future, we might create an option in the app for PayPal donations. Donations will be used to pay the servers, Ivy's legal entity expenses and then distributed between founders and contributors. - -### Goals -- Build a cool app to use ourselves. -- More users to become contributors and supporters to the project. -- Learn, design and develop cutting-edge Android technologies while doing something meaningful, not sample projects. -- Create a public portfolio that you can proudly present. -- Earn your place in the "Hall of Fame" and make Ivy Wallet better. -- The more Ivy Wallet grows, the more what we do here will matter! -- _Hoping that one day: the Ivy Wallet app would gain enough downloads so big companies (Google, Apple, Amazon) can notice us and then we can connect our top contributors (devs, designers, marketing, product) with top job opportunities! :rocket:_ - -### We want people to proudly say.... - -- "I develop this app!" -- "I designed this feature of the app!" -- "I improved this and that!" -- "I manage this amazing product!" -- "I made this project successful and famous!" -- ... -- We want you to fill part of the project and use your skills and talents to determine its ultimate destiny! - -### Model - -```mermaid -graph TD; - -contribs(Contributors) -app(Ivy Wallet app) -reviews(Reviews) -hall("Hall of Fame") -github(GitHub repo) - -contribs -- Develop --> app -contribs -- Promote --> app -contribs -- Use --> app -contribs -- Maintain --> app - -app -- Generates --> reviews -reviews -- Traffic --> app - -app -- Displays --> hall -hall -- Portfolio --> contribs -hall -- Promote --> contribs -hall -- Respect --> contribs - -github -- Displays --> hall -``` - -### Hall of Fame -_Disclaimer: WIP... :construction:_ - -The `Hall of Fame` would be a special screen in the app to honor Ivy Wallet's contributors. - -There is a `Hall of Fame` page in our GitHub repository and right now it's called [Contributors Wall](https://github.com/ILIYANGERMANOV/ivy-wallet#contributors-wall). - -Non-technical people who promoted, designed or helped Ivy Wallet in any way can include themselves by submitting a PR following a template. _(which will be provided here :construction:)_ - - ---- - -_Version 1.0.1_ - -_Feedback, proposals, and PRs are highly appreciated! Let's spark discussion and make Ivy Wallet and the world a better place! :rocket:_ \ No newline at end of file diff --git a/docs/Developer-Guidelines.md b/docs/Developer-Guidelines.md deleted file mode 100644 index 32a98b9396..0000000000 --- a/docs/Developer-Guidelines.md +++ /dev/null @@ -1,599 +0,0 @@ -# Ivy Developer Guidelines - -A short guide _(that'll evolve with time)_ with one and only goal - to **make us better developers.** - -[![PRs are welcome!](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/ILIYANGERMANOV/ivy-wallet/blob/main/CONTRIBUTING.md) -[![Feedback is welcome!](https://img.shields.io/badge/feedback-welcome-brightgreen)](https://t.me/+ETavgioAvWg4NThk) -[![Proposals are highly appreciated!](https://img.shields.io/badge/proposals-highly%20appreciated-brightgreen)](https://t.me/+ETavgioAvWg4NThk) - -> PRs and proposals for typos, better wording, better examples or minor edits are very welcome! - -## Ivy Architecture (FRP) - -The Ivy Architecture follows the Functional Reactive Programming (FRP) principles. A good example for them is [The Elm Architecture.](https://guide.elm-lang.org/architecture/) - -### Motivation - -- Organize code _(Scalability)_ -- Reduce complexity _(Separation of responsibility)_ -- Reuse code (Composability) -- Limit side-effects _(Less bugs)_ -- Easier testing _(Pure, Controlled Effects, UI)_ -- Easier refactoring _(Strongly Typed)_ - -### Architecture graph - -```mermaid -graph TD; - -android(Android System) -user(User) -view(UI) -event(Event) -viewmodel(ViewModel) -action(Action) -pure(Pure) - -event -- Propagated --> viewmodel -viewmodel -- Triggers --> action -viewmodel -- "UI State (Flow)" --> view -action -- "Abstacts IO" --> pure -action -- "Composition" --> action -pure -- "Composition" --> pure -pure -- "Computes" --> action -action -- "Data" --> viewmodel - -user -- Interracts --> view -view -- Produces --> event -android -- Produces --> event -``` - -### Resources _(further learning)_ - -- [The Android Architecture](https://www.youtube.com/watch?v=TPWmfJq16rA&list=PLWz5rJ2EKKc8GZWCbUm3tBXKeqIi3rcVX) -- [Clean Code](https://www.oreilly.com/library/view/clean-code-a/9780136083238/) -- [Jetpack Compose Docs](https://developer.android.com/jetpack/compose/documentation) -- [Functional Programming](https://en.wikipedia.org/wiki/Functional_programming) -- [Category Theory for Programmers](https://github.com/hmemcpy/milewski-ctfp-pdf) -- [Functional Reactive Programming](https://www.youtube.com/watch?v=Agu6jipKfYw&t=1518s) -- [The Elm Architecture](https://guide.elm-lang.org/architecture/) -- [Maintainable Software Architecture with Haskell](https://www.youtube.com/watch?v=kIwd1D9m1gE) -- [The Dao of FP](https://github.com/BartoszMilewski/Publications/blob/master/TheDaoOfFP/DaoFP.pdf) -- [Don't walk away from complexity, run!](https://www.youtube.com/watch?v=4MEKu2TcEHM) -- [Lambda Calculus](https://www.youtube.com/watch?v=eis11j_iGMs) - -### 0. Data Model - -The Data Model in Ivy drives clear separation between `domain` pure data required for business logic w/o added complexity, `entity` database data, `dto` _(data transfer object)_ JSON representation for network requests and `ui` data which we'll displayed. - -Learn more at [Android Developers Architecture: Entity](https://www.youtube.com/watch?v=cfak1jDKM_4). - -#### Motivation - -- Reduce complexity _(JSON, DB specifics are isolated)_ -- Flexibility _(allows editing of Data object on different levels w/o breaking existing code)_ -- Easier domain logic _(unnecessary fields are removed)_ - -#### Data Model - -```mermaid -graph TD; - -data(Data) -entity(Entity) -dto(DTO) -ui_data(UI Data) - -ui(UI) -network(Network) -db(Database) -viewmodel(ViewModel) -domain("Domain (Action, Pure)") - -network -- Fetch --> dto -- Send --> network -dto --> data - -db -- Retrieve --> entity -- Persist --> db -entity --> data - -data --> entity -data --> dto - -data -- Computation input --> domain -domain -- Computation output --> viewmodel -viewmodel -- Transform --> ui_data -ui_data -- "UI State (Flow)" --> ui - -``` - -#### Example - -- `DisplayTransaction` - - UI specific fields -- `Transaction` - - domain data -- `TransactionEntity` - - has `isSynced`, `isDeletedFlags` db specific fields (Room DB annotations) -- `TransactionDTO` - - exactly what the API expects/returns (JSON) - -> Motivation: This separation **reduces complexity** and **provides flexibility** for changes. - -### 1. Event (UI interaction or system) - -The `Event` encapsulates outside world signals in an excepted format and abstracts user input and system events. - -An `Event` is generated from either user interaction with the UI or a system subscription _(e.g. Screen start, Time, Random, Battery level)_. - -#### Motivation - -- Simplifies domain logic. _(Abstracts Input)_ -- Makes ViewModel & Domain logic independent of Android & UI specifics. _(Dependency Inversion)_ - -#### Event Graph - -```mermaid -graph TD; - -user(User) -world(Outside World) -system(System Event) -ui(UI) -event(Event) - -user -- Interracts --> ui -world -- Triggers --> system - -ui -- Produces --> event -system -- Produces --> event -``` - -> Note: There are infinite user inputs and outside world signals. - -### 2. ViewModel (mediator) - -Triggers `Action` for incoming `Event`, transforms the result to `UI State` and propagates it to the UI via `Flow`. - -#### Motivation - -- Domain logic & UI independent of each other. _(Dependency Inversion)_ -- Defines the behavior for each UI and connects it with the corresponding domain logic. - -#### ViewModel - -```mermaid -graph TD; - -event(Event) -viewmodel(ViewModel) -action(Actions) -ui(UI) - -event -- Incoming --> viewmodel -viewmodel -- "Action Input" --> action -action -- "Action Output" --> viewmodel -viewmodel -- "UI State (Flow)" --> ui -``` - -### 3. Action (domain logic with side-effects) - -Actions accept `Action Input`, handles `threading`, abstract `side-effects` (IO) and executes specific domain logic by **composing** `pure` functions or other `actions`. - -#### Motivation - -- Encapsulates domain logic. -- Make business operations (actions) re-usable. _(Composability)_ -- Handles threading. _(Reduces Complexity)_ -- Simplifies the ViewModel. -- Independent of UI State. _(Dependency Inversion)_ -- Provide side-effects for the `pure` layer via Dependency Injection. _(DAOs, Retrofit, etc)_ - -#### Action Types - -- `FPAction()`: declarative FP style _(preferable)_ -- `Action()`: imperative OOP style - -#### Action Graph - -```mermaid -graph TD; - -input(Action Input) -output(Action Output) -pure(Pure Functions) -action(Action) - -io(IO) -dao(Database) -network(Network) -side-effect(Side-Effect) - -side-effect -- any --> io -dao -- DAOs --> io -network -- Retrofit --> io -io -- DI --> action - -action -- Composition --> action -action -- Threading --> action - -input --> action -action -- abstracted IO --> pure -- Result --> action -action -- Final Result --> output -``` - -#### Action Composition Examples - -##### Calculate Balance - -```Kotlin -//Example 1: Calculates Ivy's balance -class CalcWalletBalanceAct @Inject constructor( - private val accountsAct: AccountsAct, - private val calcAccBalanceAct: CalcAccBalanceAct, - private val exchangeAct: ExchangeAct, -) : FPAction() { - - override suspend fun Input.compose(): suspend () -> BigDecimal = recipe().fixUnit() - - private suspend fun Input.recipe(): suspend (Unit) -> BigDecimal = - accountsAct thenFilter { - withExcluded || it.includeInBalance - } thenMap { - calcAccBalanceAct( - CalcAccBalanceAct.Input( - account = it, - range = range - ) - ) - } thenMap { - exchangeAct( - ExchangeAct.Input( - data = ExchangeData( - baseCurrency = baseCurrency, - fromCurrency = (it.account.currency ?: baseCurrency).toOption(), - toCurrency = balanceCurrency - ), - amount = it.balance - ) - ) - } thenSum { - it.orNull() ?: BigDecimal.ZERO - } - - data class Input( - val baseCurrency: String, - val balanceCurrency: String = baseCurrency, - val range: ClosedTimeRange = ClosedTimeRange.allTimeIvy(), - val withExcluded: Boolean = false - ) -} -``` - -##### Overdue Transactions - -```Kotlin -//Example 2: Due transtions + due income/expense for a given filter -class DueTrnsInfoAct @Inject constructor( - private val dueTrnsAct: DueTrnsAct, - private val accountByIdAct: AccountByIdAct, - private val exchangeAct: ExchangeAct -) : FPAction() { - - override suspend fun Input.compose(): suspend () -> Output = - suspend { - range - } then dueTrnsAct then { trns -> - val dateNow = dateNowUTC() - trns.filter { - this.dueFilter(it, dateNow) - } - } then { dueTrns -> - //We have due transactions in different currencies - val exchangeArg = ExchangeTrnArgument( - baseCurrency = baseCurrency, - exchange = ::actInput then exchangeAct, - getAccount = accountByIdAct.lambda() - ) - - Output( - dueIncomeExpense = IncomeExpensePair( - income = sumTrns( - incomes(dueTrns), - ::exchangeInBaseCurrency, - exchangeArg - ), - expense = sumTrns( - expenses(dueTrns), - ::exchangeInBaseCurrency, - exchangeArg - ) - ), - dueTrns = dueTrns - ) - } - - data class Input( - val range: ClosedTimeRange, - val baseCurrency: String, - val dueFilter: (Transaction, LocalDate) -> Boolean - ) - - data class Output( - val dueIncomeExpense: IncomeExpensePair, - val dueTrns: List - ) -} - - -//Example 3: Overdue transactions + their income/expense -class OverdueAct @Inject constructor( - private val dueTrnsInfoAct: DueTrnsInfoAct -) : FPAction() { - - override suspend fun Input.compose(): suspend () -> Output = suspend { - DueTrnsInfoAct.Input( - range = ClosedTimeRange( - from = beginningOfIvyTime(), - to = toRange - ), - baseCurrency = baseCurrency, - dueFilter = ::isOverdue - ) - } then dueTrnsInfoAct then { - Output( - overdue = it.dueIncomeExpense, - overdueTrns = it.dueTrns - ) - } - - data class Input( - val toRange: LocalDateTime, - val baseCurrency: String - ) - - data class Output( - val overdue: IncomeExpensePair, - val overdueTrns: List - ) -} -``` - -> `Actions` are very similar to the "use-cases" from the standard "Clean Code" architecture. - -> Tip: You can compose actions and pure functions by using `then`, `thenMap`, `thenFilter`, `thenSum`. - -> Tip: When creating an `Action` make it as **atomic** as possible. The goal of each `Action` is to do one thing **efficiently** and to be **composable** with other actions like LEGO. - -### 4. Pure (domain logic, pure code) - -The `pure` layer must consist of only pure functions without side-effects. If the business logic requires, **side-effects must be abstracted**. - -#### Motivation - -- Avoid code duplication in `Action(s)`. _(Composability)_ -- Reduce complexity by abstracting domain logic from side-effects (DB, Network, etc) _(Effect-Based system)_ -- Easier Unit Testing for the core domain logic. -- Enables Property-based Testing. - -#### Function types - -- **Partial**: not defined for all input values - - ```Kotlin - @Partial(inCaseOf="b=0, produces ArithmeticException::class") - fun divide(a: Int, b: Int) = a / b - ``` - -- **Total**: defined for all input values but for the same input there is no guarantee to always return the same output (has side-effects) - - ```Kotlin - //It's defined in all cases but with each call returns a different output - @Total - fun timeNowUTC(): LocalDateTime = LocalDateTime.now(ZoneOffset.UTC) - - //Produces logging side-effect which can be seen in Logcat - @Total - fun logMessage( - msg: String - ) { - Log.d("DEBUG", msg) //SIDE-EFFECT! - } - ``` - -- **Pure**: defined for all input values and for the same input always returns the same result (has NO side-effects) - - ```Kotlin - @Pure - fun sum(a: Int, b: Int) = a + b - - @Pure - fun logMessage( - msg: String, - - @SideEffect - log: (String) -> Unit - ) { - log("DEBUG: $msg") - } - ``` - -Each `@Pure` function must be **total** and its `@SideEffect`(s) if any abstracted. - -> Rule: If a pure function is called with the **same input** and mocked side-effects it must always produce the **same output**. - -#### Pure Graph - -```mermaid -graph TD; - -input(Input) -pure(Pure) -side-effect(IO / Side-Effect) -lambda("@SideEffect Lambda") -output(Output) - -side-effect -- Implements --> lambda - -input -- Data --> pure -lambda -- Abstracted Effects --> pure - -pure -- Calculates --> output -``` - -#### Code Example - -```Kotlin -//domain.action (NOT PURE) -class ExchangeAct @Inject constructor( - private val exchangeRateDao: ExchangeRateDao, -) : FPAction>() { - override suspend fun Input.compose(): suspend () -> Option = suspend { - exchange( - data = data, - amount = amount, - getExchangeRate = exchangeRateDao::findByBaseCurrencyAndCurrency then { - it?.toDomain() - } - ) - } - - data class Input( - val data: ExchangeData, - val amount: BigDecimal - ) -} - - -//domain.pure (PURE) -@Pure -suspend fun exchange( - data: ExchangeData, - amount: BigDecimal, - - @SideEffect - getExchangeRate: suspend (baseCurrency: String, toCurrency: String) -> ExchangeRate?, -): Option { - //PURE IMPLEMENTATION - //.... -} -``` - -> Tip: Make `pure` functions small, atomic and composable. - -### 5. UI (@Composable) - -Renders the `UI State` that the user sees, handles `user input` and transforms it to `events` which are propagated to the `ViewModel`. **Do NOT perform any business logic or computations.** - -#### Motivation - -- UI independent of logic. -- Transform UI State into UI on the screen. -- Abstracts the ViewModel from UI specifics. - -```mermaid -graph TD; - -user(User) -uiState("UI State (Flow)") -ui("UI (@Composable)") -event(Event) -viewmodel(ViewModel) - -user -- Interracts --> ui -ui -- Produces --> event -event -- "onEvent()" --> viewmodel -viewmodel -- "Action(s)" --> uiState -uiState -- "Flow#collectAsState()" --> ui -``` - -> Exception: The UI layer may perform in-app `navigation().navigate(..)` to reduce boiler-plate and complexity. - -### 6. IO (side-effects) - -Responsible for the implementation of IO operations like persistence, network requests, randomness, date & time, etc. - -#### Motivation - -- Encapsulate IO effects. _(Reduce Complexity)_ -- Abstracts `Action(s)` from IO implementation. -- Re-usable IO. _(Composability)_ - -#### Side-Effects - -- **Room DB**, local persistence -- **Shared Preferences**, local persistence - - key-value pairs persistence - - _migrated to DataStore_ -- **Retrofit**, Network Requests (REST) - - send requests - - parse response JSON with GSON - - transform network errors to `NetworkException` -- **Randomness** - - `UUID` generation -- **Date & Time** - - current Date & Time (`timeNowUtc`, `dateNowUtc`) - - Date & Time formatting using user's `Locale` - -### 7. Android System (side-effects) - -Responsible for the interaction with the Android System like launching `Intent`, sending `notification`, receiving `push messages`, `biometrics`, etc. - -#### Motivation - -- Abstracts `Action(s)` and `UI` from the Android System and its specifics. _(Reduce Complexity)_ -- Re-usable Android System effects. _(Composability)_ - ---- - -## Testing - -One of the reasons for the Ivy Architecture is to support painless, effective and efficient testing of the code base. - -### Motivation - -- Verifies whether the code works as expected before reaching manual QA. _(Stability)_ -- Easier refactoring. _(Tests will protect us)_ -- Faster and more reliable QA. _(Tests will ensure that the core functionality is working)_ -- Instant feedback for Pull Requests. _(CI/CD)_ - -### Unit Testing - -Tests whether the code is working correctly in the expected cases. _(hard-coded cases)_ - -#### Layers - -- `Data Model` -- `Pure` - -### Property-Based Testing - -Tests correctness in unexpected cases by randomly generated test cases in a given range of possible input. _(auto-generated tests cases)_ - -#### Layers - -- `Data Model` -- `Pure` - -### End-to-end Android Tests - -Tests the integration and correctness with the Android SDK & System on specific Android API version. _(end-to-end for logic)_ - -#### Layers - -- `Action` -- `IO` -- `Android System` - -### UI Android Tests - -Tests everything from the perspective of a user using the UI. Imagine it like an automated QA going through pre-defined scenarios. _(end-to-end for everything)_ - -#### Layers - -- `UI` (Compose) - ---- - -_Version 1.3.2_ - -_Feedback and proposals are highly appreciated! Let's spark technical discussion and make Ivy and the Android World better! :rocket:_ diff --git a/docs/Ivy-Dao.md b/docs/Ivy-Dao.md deleted file mode 100644 index 8798a7d560..0000000000 --- a/docs/Ivy-Dao.md +++ /dev/null @@ -1,35 +0,0 @@ -# Ivy DAO - -## :warning: WARNING: This business model is deprecated! :warning: - -## High-level picture -```mermaid -graph TD; - contribs(Contributors) - users(Users) - dao(Ivy DAO) - product(Ivy Wallet App) - - dao_dev_fund(R&D Fund) - dao_proposals(Proposals) - - tickets(GitHub Issues) - - contribs -- Develop --> product - contribs -- Design --> product - contribs -- Promote --> product - contribs -- Vote with IVY --> dao_proposals - - product -- Acquire --> users - - users -- Reviews --> product - users -- Donate crypto --> dao - - dao -- Store Donations --> dao_dev_fund - dao -- Smart Contract --> dao_proposals - dao_dev_fund -- Bounty --> dao_proposals - - dao_proposals -- If passed voting --> tickets - tickets -- Earn: Bounty + IVY --> contribs - -``` \ No newline at end of file diff --git a/docs/modularization.md b/docs/modularization.md deleted file mode 100644 index 63ef333e92..0000000000 --- a/docs/modularization.md +++ /dev/null @@ -1,83 +0,0 @@ -# Modularization - -The goal of this file is to outline how we'll migrate Ivy Wallet from `app` monolith to `modularized` one. - -**Motivation:** -- faster builds (only modules with changes will re-build) -- scaleability (create new features w/o affecting existing code) -- easier testing - -## Modules Graph - -_⚠️ WIP ⚠️_ - -```mermaid -graph TD; -app(:app) - - -export-csv(:export-csv) -export-zip(:export-zip) -import-csv(:import:csv) -import-zip(:import-zip) - -import-csv-app-ivy(:import-csv-app-ivy) -import-csv-app-budgetbakers(:import-csv-app-budgetbakers) - -ui-component-trn-card(:ui-component-trn-card) - -ui-import(:ui-import) -ui-export(:ui-export) - -ui-reports(:ui-reports) -ui-transaction-details(:ui-transaction-details) -ui-home(:ui-home) -ui-pie-chart(:ui-pie-chart) -ui-categories(:ui-categories) -ui-accounts(:ui-accounts) -ui-budgets(:ui-budgets) -ui-loans(:ui-loans) -ui-more-menu(:ui-more-menu) -ui-settings(:ui-settings) -ui-onboarding(:ui-onboarding) -ui-customer-journey(:ui-customer-journey) -ui-planned-payments(:ui-planned-payments) - -ui-balance-transactions(:ui-balance-transactions) - -ui-home --> app -ui-balance-transactions --> app - -ui-onboarding --> app -ui-settings --> app - -ui-transaction-details --> app -ui-accounts --> app -ui-categories --> app -ui-pie-chart --> app -ui-more-menu --> app -ui-budgets --> app -ui-loans --> app -ui-reports --> app -ui-planned-payments --> app - - -ui-customer-journey --> ui-home - -ui-component-trn-card --> ui-home -ui-component-trn-card --> ui-balance-transactions - -import-csv-app-ivy --> import-csv -import-csv-app-budgetbakers --> import-csv -import-csv --> ui-import -import-zip --> ui-import - -export-zip --> ui-export -export-csv --> ui-export - -ui-import --> ui-settings -ui-import --> ui-onboarding -ui-export --> ui-settings - - -``` diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000000..79536562df --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,105 @@ +[versions] +kotlin = "1.9.0" +kotlin-coroutines = "1.7.3" +ktor = "2.3.3" +kotlinx-serialization = "1.6.0" +arrow = "1.2.0" +kotest = "5.6.2" +compose = "1.5.0" +compose-compiler = "1.5.2" +compose-material3 = "1.1.1" +compose-activity = "1.7.2" +compose-viewmodel = "2.6.1" +coil = "2.4.0" +glance = "1.0.0-rc01" +datastore = "1.0.0" +androidx-security = "1.0.0" + +[libraries] +kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } +kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" } +kotlin-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlin-coroutines" } +kotlin-coroutines-googleplay-temp = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-play-services", version.ref = "kotlin-coroutines" } +kotlin-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlin-coroutines" } +kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } +ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" } +ktor-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } +ktor-serialization = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } +ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } +ktor-client-serialization = { module = "io.ktor:ktor-client-serialization", version.ref = "ktor" } +ktor-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" } +arrowkt-core = { module = "io.arrow-kt:arrow-core", version.ref = "arrow" } +kotest-junit5 = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest" } +kotest-assertions = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest" } +kotest-property = { module = "io.kotest:kotest-property", version.ref = "kotest" } +kotest-property-arrow = { module = "io.kotest.extensions:kotest-property-arrow", version.ref = "arrow" } +kotest-datatest = { module = "io.kotest:kotest-framework-datatest", version.ref = "kotest" } +ivy-frp-temp = { module = "com.github.ILIYANGERMANOV:ivy-frp", version = "0.9.5" } +compose-animation = { module = "androidx.compose.animation:animation", version.ref = "compose" } +#compose-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "compose-compiler" } +compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" } +compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "compose-material3" } +compose-material3-windowsize = { module = "androidx.compose.material3:material3-window-size-class", version.ref = "compose-material3" } +compose-runtime = { module = "androidx.compose.runtime:runtime", version.ref = "compose" } +compose-runtime-livedate-temp = { module = "androidx.compose.runtime:runtime-livedata", version.ref = "compose" } +compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" } +compose-activity = { module = "androidx.activity:activity-compose", version.ref = "compose-activity" } +compose-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "compose-viewmodel" } +compose-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" } +compose-coil = { module = "io.coil-kt:coil-compose", version.ref = "coil" } +glance = { module = "androidx.glance:glance", version.ref = "glance" } +glance-appwidget = { module = "androidx.glance:glance-appwidget", version.ref = "glance" } +glance-material3 = { module = "androidx.glance:glance-material3", version.ref = "glance" } +datastore = { module = "androidx.datastore:datastore-preferences", version.ref = "datastore" } +androidx-security = { module = "androidx.security:security-crypto", version.ref = "androidx-security" } + +[bundles] +kotlin = [ + "kotlin-stdlib", + "kotlin-coroutines-core", + "kotlin-coroutines-android", + "kotlin-coroutines-googleplay-temp" +] +kotlin-test = [ + "kotlin-coroutines-test" +] +arrow = [ + "arrowkt-core" +] +ktor = [ + "kotlinx-serialization-json", + "ktor-client-okhttp", + "ktor-content-negotiation", + "ktor-serialization", + "ktor-client-core", + "ktor-client-serialization", + "ktor-logging" +] +kotest = [ + "kotest-junit5", + "kotest-assertions", + "kotest-property", + "kotest-property-arrow", + "kotest-datatest" +] +compose = [ + "compose-animation", + "compose-foundation", + "compose-material3", + "compose-material3-windowsize", + "compose-runtime", + "compose-ui", + "compose-activity", + "compose-viewmodel", + "compose-tooling", + "compose-runtime-livedate-temp", + "compose-coil" +] +glance = [ + "glance", + "glance-appwidget", + "glance-material3" +] + +[plugins] +kotlinx-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } diff --git a/ivy-design/build.gradle.kts b/ivy-design/build.gradle.kts index 591b247c24..ba5f63cb8c 100644 --- a/ivy-design/build.gradle.kts +++ b/ivy-design/build.gradle.kts @@ -45,7 +45,7 @@ android { } composeOptions { - kotlinCompilerExtensionVersion = com.ivy.wallet.buildsrc.GlobalVersions.compose + kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get() } packagingOptions { @@ -58,4 +58,8 @@ android { dependencies { ivyDesignModuleDependencies() + + implementation(libs.bundles.arrow) + implementation(libs.bundles.kotlin) + implementation(libs.bundles.compose) } \ No newline at end of file diff --git a/ivy-design/src/main/java/com/ivy/design/api/IvyUI.kt b/ivy-design/src/main/java/com/ivy/design/api/IvyUI.kt index 571ceb3b2b..466e2049d8 100644 --- a/ivy-design/src/main/java/com/ivy/design/api/IvyUI.kt +++ b/ivy-design/src/main/java/com/ivy/design/api/IvyUI.kt @@ -3,17 +3,12 @@ package com.ivy.design.api import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.BoxWithConstraintsScope import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Surface +import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity -import com.google.accompanist.insets.ProvideWindowInsets -import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.ivy.design.IvyContext import com.ivy.design.l0_system.IvyTheme @@ -33,30 +28,17 @@ fun IvyUI( theme = ivyContext.theme, design = design ) { - - val systemUiController = rememberSystemUiController() - val useDarkIcons = MaterialTheme.colors.isLight - - SideEffect { - systemUiController.setSystemBarsColor( - color = Color.Transparent, - darkIcons = useDarkIcons - ) - } - Surface(modifier = Modifier.fillMaxSize()) { - ProvideWindowInsets { - BoxWithConstraints { - ivyContext.screenWidth = with(LocalDensity.current) { - maxWidth.roundToPx() - } - ivyContext.screenHeight = with(LocalDensity.current) { - maxHeight.roundToPx() - } + BoxWithConstraints { + ivyContext.screenWidth = with(LocalDensity.current) { + maxWidth.roundToPx() + } + ivyContext.screenHeight = with(LocalDensity.current) { + maxHeight.roundToPx() + } - Content() - } + Content() } } } diff --git a/ivy-design/src/main/java/com/ivy/design/l0_system/IvyTheme.kt b/ivy-design/src/main/java/com/ivy/design/l0_system/IvyTheme.kt index 8916d703ee..88bdc414fc 100644 --- a/ivy-design/src/main/java/com/ivy/design/l0_system/IvyTheme.kt +++ b/ivy-design/src/main/java/com/ivy/design/l0_system/IvyTheme.kt @@ -1,14 +1,21 @@ package com.ivy.design.l0_system +import android.app.Activity import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material.Colors -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Shapes -import androidx.compose.material.Typography +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Shapes +import androidx.compose.material3.Typography +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.runtime.SideEffect import androidx.compose.runtime.compositionLocalOf +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat import com.ivy.design.api.IvyDesign val LocalIvyColors = compositionLocalOf { error("No IvyColors") } @@ -48,8 +55,20 @@ fun IvyTheme( LocalIvyTypography provides typography, LocalIvyShapes provides shapes ) { + val colorScheme = adaptColors(colors) + + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colors.pure.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = + colors.isLight + } + } + MaterialTheme( - colors = adaptColors(colors), + colorScheme = colorScheme, typography = adaptTypography(typography), shapes = adaptShapes(shapes), content = content @@ -57,31 +76,31 @@ fun IvyTheme( } } -fun adaptColors(colors: IvyColors): Colors { - return Colors( +fun adaptColors(colors: IvyColors): ColorScheme { + val colorScheme = if (colors.isLight) + lightColorScheme() else darkColorScheme() + return colorScheme.copy( primary = colors.primary, - primaryVariant = colors.primary1, + onPrimary = White, secondary = colors.primary, - secondaryVariant = colors.primary1, + onSecondary = White, background = colors.pure, + onBackground = colors.pureInverse, surface = colors.pure, onSurface = colors.pureInverse, error = colors.red, - onPrimary = White, - onSecondary = White, - onBackground = colors.pureInverse, onError = White, - isLight = colors.isLight + scrim = colors.gray, ) } fun adaptTypography(typography: IvyTypography): Typography { return Typography( - h1 = typography.h1, - h2 = typography.h2, - body1 = typography.b1, - body2 = typography.b2, - caption = typography.c + headlineLarge = typography.h1, + headlineMedium = typography.h2, + bodyLarge = typography.b1, + bodyMedium = typography.b2, + bodySmall = typography.c ) } diff --git a/ivy-design/src/main/java/com/ivy/design/l1_buildingBlocks/ColumnRoot.kt b/ivy-design/src/main/java/com/ivy/design/l1_buildingBlocks/ColumnRoot.kt index d93be4debb..8979d93be9 100644 --- a/ivy-design/src/main/java/com/ivy/design/l1_buildingBlocks/ColumnRoot.kt +++ b/ivy-design/src/main/java/com/ivy/design/l1_buildingBlocks/ColumnRoot.kt @@ -4,11 +4,11 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.ivy.design.utils.thenIf @Composable diff --git a/ivy-design/src/main/java/com/ivy/design/l1_buildingBlocks/IvyIcon.kt b/ivy-design/src/main/java/com/ivy/design/l1_buildingBlocks/IvyIcon.kt index 51998f315e..d408d16312 100644 --- a/ivy-design/src/main/java/com/ivy/design/l1_buildingBlocks/IvyIcon.kt +++ b/ivy-design/src/main/java/com/ivy/design/l1_buildingBlocks/IvyIcon.kt @@ -4,7 +4,7 @@ import androidx.annotation.DrawableRes import androidx.compose.foundation.Image import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.material.Icon +import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -51,8 +51,10 @@ fun IvyIconScaled( when (iconScale) { IconScale.L -> this.size(64.dp) + IconScale.M -> this.size(48.dp) + IconScale.S -> this.size(32.dp) } diff --git a/ivy-design/src/main/java/com/ivy/design/l1_buildingBlocks/IvyText.kt b/ivy-design/src/main/java/com/ivy/design/l1_buildingBlocks/IvyText.kt index e70b623045..0004d5cc99 100644 --- a/ivy-design/src/main/java/com/ivy/design/l1_buildingBlocks/IvyText.kt +++ b/ivy-design/src/main/java/com/ivy/design/l1_buildingBlocks/IvyText.kt @@ -1,6 +1,6 @@ package com.ivy.design.l1_buildingBlocks -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.TextStyle diff --git a/ivy-design/src/main/java/com/ivy/design/l2_components/Button.kt b/ivy-design/src/main/java/com/ivy/design/l2_components/Button.kt index 3a22fe6056..fef4afeebd 100644 --- a/ivy-design/src/main/java/com/ivy/design/l2_components/Button.kt +++ b/ivy-design/src/main/java/com/ivy/design/l2_components/Button.kt @@ -3,7 +3,7 @@ package com.ivy.design.l2_components import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.TextStyle diff --git a/ivy-design/src/main/java/com/ivy/design/l2_components/ButtonWithIcon.kt b/ivy-design/src/main/java/com/ivy/design/l2_components/ButtonWithIcon.kt index a54a9c3c1b..2db74f531d 100644 --- a/ivy-design/src/main/java/com/ivy/design/l2_components/ButtonWithIcon.kt +++ b/ivy-design/src/main/java/com/ivy/design/l2_components/ButtonWithIcon.kt @@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/ivy-design/src/main/java/com/ivy/design/l2_components/Checkbox.kt b/ivy-design/src/main/java/com/ivy/design/l2_components/Checkbox.kt index e9070b584b..00ab252149 100644 --- a/ivy-design/src/main/java/com/ivy/design/l2_components/Checkbox.kt +++ b/ivy-design/src/main/java/com/ivy/design/l2_components/Checkbox.kt @@ -5,7 +5,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/ivy-design/src/main/java/com/ivy/design/l3_ivyComponents/ScreenTitle.kt b/ivy-design/src/main/java/com/ivy/design/l3_ivyComponents/ScreenTitle.kt index 5d28e8d282..e9179d2ce9 100644 --- a/ivy-design/src/main/java/com/ivy/design/l3_ivyComponents/ScreenTitle.kt +++ b/ivy-design/src/main/java/com/ivy/design/l3_ivyComponents/ScreenTitle.kt @@ -1,7 +1,7 @@ package com.ivy.design.l3_ivyComponents import androidx.compose.foundation.layout.padding -import androidx.compose.material.Text +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color diff --git a/ivy-design/src/test/java/com/ivy/design/ExampleUnitTest.kt b/ivy-design/src/test/java/com/ivy/design/ExampleUnitTest.kt deleted file mode 100644 index 08ade6083f..0000000000 --- a/ivy-design/src/test/java/com/ivy/design/ExampleUnitTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.ivy.design - -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 579afebd63..0897f48e44 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,5 +8,4 @@ dependencyResolutionManagement { } rootProject.name = "Ivy Wallet" include(":app") -include(":ivy-design") - \ No newline at end of file +include(":ivy-design") \ No newline at end of file