├── .gitattributes
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ ├── dev-request.yml
│ └── feature-request.yml
├── PULL_REQUEST_TEMPLATE.md
├── dependabot.yml
└── workflows
│ ├── apk.yml
│ ├── automatic_release.yml
│ ├── ci_actions_test.yml
│ ├── compose_stability.yml
│ ├── detekt.yml
│ ├── integration_test.yml
│ ├── internal_release.yml
│ ├── issue_assign.yml
│ ├── issue_created.yml
│ ├── lint.yml
│ ├── paparazzi_screenshot_test.yml
│ ├── pr_description.yml
│ ├── stale.yml
│ ├── test.yml
│ └── upgrade-gradle-wrapper.yml
├── .gitignore
├── .idea
├── .gitignore
├── .name
├── compiler.xml
└── migrations.xml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Gemfile
├── Gemfile.lock
├── LICENSE
├── README.md
├── all_modules.gv
├── app
├── build.gradle.kts
├── google-services.json
├── lint-baseline.xml
├── proguard-rules.pro
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ ├── ic_launcher-playstore.png
│ ├── java
│ │ └── com
│ │ │ └── ivy
│ │ │ ├── IvyNavGraph.kt
│ │ │ └── wallet
│ │ │ ├── IvyAndroidApp.kt
│ │ │ ├── IvyAppStarter.kt
│ │ │ ├── PaymentTileService.kt
│ │ │ ├── RootActivity.kt
│ │ │ ├── RootViewModel.kt
│ │ │ ├── di
│ │ │ └── AppBindingsModule.kt
│ │ │ ├── migrations
│ │ │ ├── Migration.kt
│ │ │ ├── MigrationsManager.kt
│ │ │ └── impl
│ │ │ │ └── DisableGitHubAutoBackupMigration.kt
│ │ │ └── ui
│ │ │ └── applocked
│ │ │ └── AppLockedScreen.kt
│ └── res
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_foreground.webp
│ │ ├── ic_launcher_monochrome.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_foreground.webp
│ │ ├── ic_launcher_monochrome.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_foreground.webp
│ │ ├── ic_launcher_monochrome.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_foreground.webp
│ │ ├── ic_launcher_monochrome.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_foreground.webp
│ │ ├── ic_launcher_monochrome.webp
│ │ └── ic_launcher_round.webp
│ │ ├── resources.properties
│ │ ├── values
│ │ ├── ic_launcher_background.xml
│ │ └── styles.xml
│ │ └── xml
│ │ └── shortcuts.xml
│ └── release
│ └── res
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.webp
│ ├── ic_launcher_foreground.webp
│ ├── ic_launcher_monochrome.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-mdpi
│ ├── ic_launcher.webp
│ ├── ic_launcher_foreground.webp
│ ├── ic_launcher_monochrome.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xhdpi
│ ├── ic_launcher.webp
│ ├── ic_launcher_foreground.webp
│ ├── ic_launcher_monochrome.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.webp
│ ├── ic_launcher_foreground.webp
│ ├── ic_launcher_monochrome.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.webp
│ ├── ic_launcher_foreground.webp
│ ├── ic_launcher_monochrome.webp
│ └── ic_launcher_round.webp
│ └── values
│ └── ic_launcher_background.xml
├── build.gradle.kts
├── buildSrc
├── build.gradle.kts
├── settings.gradle.kts
└── src
│ └── main
│ └── kotlin
│ ├── ivy.compose.gradle.kts
│ ├── ivy.detekt.gradle.kts
│ ├── ivy.feature.gradle.kts
│ ├── ivy.hilt.gradle.kts
│ ├── ivy.integration.testing.gradle.kts
│ ├── ivy.kotlin-android.gradle.kts
│ ├── ivy.kotlinx-serialization.gradle.kts
│ ├── ivy.module.gradle.kts
│ ├── ivy.paparazzi.gradle.kts
│ ├── ivy.room.gradle.kts
│ ├── ivy.script.gradle.kts
│ ├── ivy.widget.gradle.kts
│ └── versionCatalog.kt
├── ci-actions
├── base
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── kotlin
│ │ │ └── ivy
│ │ │ └── automate
│ │ │ └── base
│ │ │ ├── ArgsParseExt.kt
│ │ │ ├── ArrowExt.kt
│ │ │ ├── Common.kt
│ │ │ ├── Constants.kt
│ │ │ ├── ExactDsl.kt
│ │ │ ├── IvyError.kt
│ │ │ ├── github
│ │ │ ├── GitHubIssueArgs.kt
│ │ │ ├── GitHubService.kt
│ │ │ ├── GitHubServiceImpl.kt
│ │ │ └── model
│ │ │ │ ├── GitHubComment.kt
│ │ │ │ ├── GitHubIssue.kt
│ │ │ │ ├── GitHubIssueNumber.kt
│ │ │ │ ├── GitHubLabel.kt
│ │ │ │ ├── GitHubLabelName.kt
│ │ │ │ ├── GitHubPAT.kt
│ │ │ │ ├── GitHubUser.kt
│ │ │ │ ├── GitHubUsername.kt
│ │ │ │ └── NotBlankTrimmedString.kt
│ │ │ └── ktor
│ │ │ └── KtorClientScope.kt
│ │ └── test
│ │ └── kotlin
│ │ └── ivy
│ │ └── automate
│ │ └── base
│ │ ├── github
│ │ └── GitHubIssueArgsTest.kt
│ │ └── model
│ │ ├── GitHubIssueNumberTest.kt
│ │ ├── GitHubLabelNameTest.kt
│ │ ├── GitHubPATTest.kt
│ │ ├── GitHubUsernameTest.kt
│ │ └── NotBlankTrimmedStringTest.kt
├── compose-stability
│ ├── build.gradle.kts
│ ├── ivy-compose-stability-baseline.txt
│ └── src
│ │ └── main
│ │ └── kotlin
│ │ └── ivy
│ │ └── automate
│ │ └── compose
│ │ └── stability
│ │ ├── Main.kt
│ │ └── model
│ │ └── UnstableComposable.kt
├── issue-assign
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── kotlin
│ │ │ └── ivy
│ │ │ └── automate
│ │ │ └── issue
│ │ │ ├── ActionExecutor.kt
│ │ │ ├── CommentAnalyzer.kt
│ │ │ ├── DetermineAction.kt
│ │ │ └── Main.kt
│ │ └── test
│ │ └── kotlin
│ │ └── ivy
│ │ └── automate
│ │ └── issue
│ │ ├── ActionExecutorTest.kt
│ │ ├── CommentAnalyzerTest.kt
│ │ └── DetermineActionTest.kt
├── issue-create-comment
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── kotlin
│ │ │ └── ivy
│ │ │ └── automate
│ │ │ └── issue
│ │ │ └── create
│ │ │ └── Main.kt
│ │ └── test
│ │ └── kotlin
│ │ └── ivy
│ │ └── automate
│ │ └── issue
│ │ └── create
│ │ └── CommentTextTest.kt
└── pr-description-check
│ ├── build.gradle.kts
│ └── src
│ ├── main
│ └── kotlin
│ │ └── ivy
│ │ └── automate
│ │ └── pr
│ │ ├── ClosesIssueAnalyzer.kt
│ │ ├── Main.kt
│ │ └── PRDescriptionAnalyzer.kt
│ └── test
│ └── kotlin
│ └── ivy
│ └── automate
│ └── pr
│ └── ClosesIssueAnalyzerTest.kt
├── config
└── detekt
│ ├── baseline.yml
│ └── config.yml
├── debug.jks
├── docs
├── CI-Troubleshooting.md
├── Guidelines.md
├── archive
│ └── Yoda-Style-Architecture.md
├── assets
│ ├── app-layers.d2
│ ├── app-layers.svg
│ ├── architecture.d2
│ ├── architecture.svg
│ ├── data-mapping.d2
│ ├── data-mapping.svg
│ ├── modularization.d2
│ ├── modularization.svg
│ ├── modules-graph.svg
│ ├── screen-vm.d2
│ └── screen-vm.svg
├── guidelines
│ ├── Architecture.md
│ ├── Data-Modeling.md
│ ├── Error-Handling.md
│ ├── README.md
│ ├── Screen-Architecture.md
│ ├── Screenshot-Testing.md
│ └── Unit-Testing.md
└── resources
│ ├── Blog-Articles.md
│ ├── Books.md
│ ├── Docs.md
│ ├── README.md
│ └── Videos.md
├── fastlane
├── Appfile
├── Fastfile
└── metadata
│ └── android
│ └── en-GB
│ └── changelogs
│ └── default.txt
├── gradle.properties
├── gradle
├── libs.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── screen
├── accounts
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── accounts
│ │ │ ├── AccountsEvent.kt
│ │ │ ├── AccountsState.kt
│ │ │ ├── AccountsTab.kt
│ │ │ ├── AccountsViewModel.kt
│ │ │ └── IncomeExpensesRow.kt
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── ivy
│ │ │ └── accounts
│ │ │ └── AccountsTabPaparazziTest.kt
│ │ └── snapshots
│ │ └── images
│ │ ├── com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab compact composable[Dark].png
│ │ ├── com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab compact composable[Light].png
│ │ ├── com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab composable[Dark].png
│ │ ├── com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab composable[Light].png
│ │ ├── com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab nonCompact composable[Dark].png
│ │ └── com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab nonCompact composable[Light].png
├── attributions
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── attributions
│ │ │ ├── AttributionItem.kt
│ │ │ ├── AttributionsEvent.kt
│ │ │ ├── AttributionsProvider.kt
│ │ │ ├── AttributionsScreen.kt
│ │ │ ├── AttributionsState.kt
│ │ │ └── AttributionsViewModel.kt
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── ivy
│ │ │ └── attributions
│ │ │ └── AttributionsScreenPaparazziTest.kt
│ │ └── snapshots
│ │ └── images
│ │ ├── com.ivy.attributions_AttributionsScreenPaparazziTest_snapshot Attribution Screen[Dark].png
│ │ └── com.ivy.attributions_AttributionsScreenPaparazziTest_snapshot Attribution Screen[Light].png
├── balance
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── balance
│ │ │ ├── BalanceEvent.kt
│ │ │ ├── BalanceScreen.kt
│ │ │ ├── BalanceState.kt
│ │ │ └── BalanceViewModel.kt
│ │ └── test
│ │ └── snapshots
│ │ └── images
│ │ ├── com.ivy.balance_BalanceScreenPaparazziTest_snapshot Balance Screen[Dark].png
│ │ └── com.ivy.balance_BalanceScreenPaparazziTest_snapshot Balance Screen[Light].png
├── budgets
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── budgets
│ │ ├── BudgetBottomBar.kt
│ │ ├── BudgetExt.kt
│ │ ├── BudgetModal.kt
│ │ ├── BudgetScreen.kt
│ │ ├── BudgetScreenEvent.kt
│ │ ├── BudgetScreenState.kt
│ │ ├── BudgetViewModel.kt
│ │ └── model
│ │ └── DisplayBudget.kt
├── categories
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── categories
│ │ │ ├── CategoriesBottomBar.kt
│ │ │ ├── CategoriesScreen.kt
│ │ │ ├── CategoriesScreenEvent.kt
│ │ │ ├── CategoriesScreenState.kt
│ │ │ ├── CategoriesViewModel.kt
│ │ │ └── CategoryData.kt
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── ivy
│ │ │ └── categories
│ │ │ └── CategoriesScreenPaparazziTest.kt
│ │ └── snapshots
│ │ └── images
│ │ ├── com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories Screen[Dark].png
│ │ ├── com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories Screen[Light].png
│ │ ├── com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories compact Screen with search bar[Dark].png
│ │ ├── com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories compact Screen with search bar[Light].png
│ │ ├── com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories compact Screen[Dark].png
│ │ ├── com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories compact Screen[Light].png
│ │ ├── com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories nonCompact Screen with search bar[Dark].png
│ │ ├── com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories nonCompact Screen with search bar[Light].png
│ │ ├── com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories nonCompact Screen[Dark].png
│ │ └── com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories nonCompact Screen[Light].png
├── contributors
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── contributors
│ │ │ ├── Contributor.kt
│ │ │ ├── ContributorsEvent.kt
│ │ │ ├── ContributorsScreen.kt
│ │ │ ├── ContributorsState.kt
│ │ │ ├── ContributorsViewModel.kt
│ │ │ ├── IvyWalletRepositoryDataSource.kt
│ │ │ └── ProjectRepositoryInfo.kt
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── ivy
│ │ │ └── contributors
│ │ │ ├── ContributorsScreenPaparazziTest.kt
│ │ │ └── ContributorsViewModelTest.kt
│ │ └── snapshots
│ │ └── images
│ │ ├── com.ivy.contributors_ContributorsScreenPaparazziTest_snapshot Contributor Screen[Dark].png
│ │ └── com.ivy.contributors_ContributorsScreenPaparazziTest_snapshot Contributor Screen[Light].png
├── disclaimer
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── disclaimer
│ │ │ ├── DisclaimerScreen.kt
│ │ │ ├── DisclaimerViewModel.kt
│ │ │ ├── DisclaimerViewState.kt
│ │ │ └── composables
│ │ │ ├── AcceptTermsText.kt
│ │ │ ├── AgreeButton.kt
│ │ │ ├── AgreementCheckBox.kt
│ │ │ └── DisclaimerTopAppBar.kt
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── ivy
│ │ │ └── disclaimer
│ │ │ └── DisclaimerScreenPaparazziTest.kt
│ │ └── snapshots
│ │ └── images
│ │ ├── com.ivy.disclaimer_DisclaimerScreenPaparazziTest_all checked[Dark].png
│ │ ├── com.ivy.disclaimer_DisclaimerScreenPaparazziTest_all checked[Light].png
│ │ ├── com.ivy.disclaimer_DisclaimerScreenPaparazziTest_none checked[Dark].png
│ │ └── com.ivy.disclaimer_DisclaimerScreenPaparazziTest_none checked[Light].png
├── edit-transaction
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── transaction
│ │ ├── EditTransactionScreen.kt
│ │ ├── EditTransactionViewEvent.kt
│ │ └── EditTransactionViewModel.kt
├── exchange-rates
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── exchangerates
│ │ │ ├── ExchangeRateBottomBar.kt
│ │ │ ├── ExchangeRatesScreen.kt
│ │ │ ├── ExchangeRatesViewModel.kt
│ │ │ ├── RatesEvent.kt
│ │ │ ├── RatesState.kt
│ │ │ ├── component
│ │ │ └── RateItem.kt
│ │ │ ├── data
│ │ │ └── RateUi.kt
│ │ │ └── modal
│ │ │ └── AddRateModal.kt
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── ivy
│ │ │ └── exchangerates
│ │ │ └── ExchangeRatesScreenPaparazziTest.kt
│ │ └── snapshots
│ │ └── images
│ │ ├── com.ivy.exchangerates_ExchangeRatesScreenPaparazziTest_snapshot Exchange Rates Screen[Dark].png
│ │ └── com.ivy.exchangerates_ExchangeRatesScreenPaparazziTest_snapshot Exchange Rates Screen[Light].png
├── features
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── features
│ │ ├── FeaturesScreen.kt
│ │ ├── FeaturesUiEvent.kt
│ │ ├── FeaturesUiState.kt
│ │ └── FeaturesViewModel.kt
├── home
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── home
│ │ │ ├── Constants.kt
│ │ │ ├── HomeEvent.kt
│ │ │ ├── HomeHeader.kt
│ │ │ ├── HomeMoreMenu.kt
│ │ │ ├── HomeState.kt
│ │ │ ├── HomeTab.kt
│ │ │ ├── HomeViewModel.kt
│ │ │ └── customerjourney
│ │ │ ├── CustomerJourney.kt
│ │ │ ├── CustomerJourneyCardModel.kt
│ │ │ └── CustomerJourneyCardsProvider.kt
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── ivy
│ │ │ └── home
│ │ │ └── HomePaparazziTest.kt
│ │ └── snapshots
│ │ └── images
│ │ ├── com.ivy.home_HomePaparazziTest_snapshot Home Screen[Dark].png
│ │ └── com.ivy.home_HomePaparazziTest_snapshot Home Screen[Light].png
├── import-data
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── importdata
│ │ ├── csv
│ │ ├── CSVEvent.kt
│ │ ├── CSVScreen.kt
│ │ ├── CSVState.kt
│ │ ├── CSVViewModel.kt
│ │ └── domain
│ │ │ ├── CSVImporterV2.kt
│ │ │ ├── ParseFields.kt
│ │ │ └── ParseStatus.kt
│ │ └── csvimport
│ │ ├── ImportScreen.kt
│ │ ├── ImportStep.kt
│ │ ├── ImportViewModel.kt
│ │ └── flow
│ │ ├── ImportFrom.kt
│ │ ├── ImportProcessing.kt
│ │ ├── ImportResultUI.kt
│ │ ├── ImportSteps.kt
│ │ └── instructions
│ │ ├── DefaultImportSteps.kt
│ │ ├── FinancistoSteps.kt
│ │ ├── FortuneCitySteps.kt
│ │ ├── ImportInstructions.kt
│ │ ├── IvyWalletSteps.kt
│ │ ├── KTWMoneyMangerSteps.kt
│ │ ├── MonefySteps.kt
│ │ ├── MoneyManagerPraseSteps.kt
│ │ ├── OneMoneySteps.kt
│ │ ├── SpendeeSteps.kt
│ │ └── WalletByBudgetBakersSteps.kt
├── loans
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── loans
│ │ │ ├── loan
│ │ │ ├── Constants.kt
│ │ │ ├── LoanBottomBar.kt
│ │ │ ├── LoanScreenEvent.kt
│ │ │ ├── LoanScreenState.kt
│ │ │ ├── LoanTab.kt
│ │ │ ├── LoanViewModel.kt
│ │ │ ├── LoansScreen.kt
│ │ │ └── data
│ │ │ │ ├── DisplayLoan.kt
│ │ │ │ └── DisplayLoanRecord.kt
│ │ │ └── loandetails
│ │ │ ├── LoanDetailsScreen.kt
│ │ │ ├── LoanDetailsScreenState.kt
│ │ │ ├── LoanDetailsViewModel.kt
│ │ │ └── events
│ │ │ ├── DeleteLoanModalEvent.kt
│ │ │ ├── LoanDetailsScreenEvent.kt
│ │ │ ├── LoanModalEvent.kt
│ │ │ └── LoanRecordModalEvent.kt
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── ivy
│ │ │ └── loans
│ │ │ └── LoanScreenPaparazziTest.kt
│ │ └── snapshots
│ │ └── images
│ │ ├── com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen composable[Dark].png
│ │ ├── com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen composable[Light].png
│ │ ├── com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen non tabular composable[Dark].png
│ │ ├── com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen non tabular composable[Light].png
│ │ ├── com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen tabular composable[Dark].png
│ │ └── com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen tabular composable[Light].png
├── main
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── main
│ │ ├── MainBottomBar.kt
│ │ ├── MainScreen.kt
│ │ └── MainViewModel.kt
├── onboarding
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── onboarding
│ │ ├── OnboardingDetailState.kt
│ │ ├── OnboardingEvent.kt
│ │ ├── OnboardingScreen.kt
│ │ ├── OnboardingState.kt
│ │ ├── components
│ │ ├── OnboardingProgressSlider.kt
│ │ ├── OnboardingToolbar.kt
│ │ └── Suggestions.kt
│ │ ├── steps
│ │ ├── OnboardingAccounts.kt
│ │ ├── OnboardingCategories.kt
│ │ ├── OnboardingSetCurrency.kt
│ │ ├── OnboardingSplashLogin.kt
│ │ ├── OnboardingType.kt
│ │ └── archived
│ │ │ ├── OnboardingPrivacyTC.kt
│ │ │ └── OnboardingSetName.kt
│ │ └── viewmodel
│ │ ├── OnboardingRouter.kt
│ │ └── OnboardingViewModel.kt
├── piechart
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── piechart
│ │ ├── CategoryAmount.kt
│ │ ├── PieChart.kt
│ │ ├── PieChartStatisticBottomBar.kt
│ │ ├── PieChartStatisticEvent.kt
│ │ ├── PieChartStatisticScreen.kt
│ │ ├── PieChartStatisticState.kt
│ │ ├── PieChartStatisticViewModel.kt
│ │ ├── SelectedCategory.kt
│ │ └── action
│ │ └── PieChartAct.kt
├── planned-payments
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── planned
│ │ ├── edit
│ │ ├── EditPlannedScreen.kt
│ │ ├── EditPlannedScreenEvent.kt
│ │ ├── EditPlannedScreenState.kt
│ │ ├── EditPlannedViewModel.kt
│ │ └── RecurringRule.kt
│ │ └── list
│ │ ├── PlannedPaymentCard.kt
│ │ ├── PlannedPaymentsBottomBar.kt
│ │ ├── PlannedPaymentsLazyColumn.kt
│ │ ├── PlannedPaymentsScreen.kt
│ │ ├── PlannedPaymentsScreenEvent.kt
│ │ ├── PlannedPaymentsScreenState.kt
│ │ └── PlannedPaymentsViewModel.kt
├── releases
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── releases
│ │ │ ├── ReleaseInfo.kt
│ │ │ ├── ReleasesContentParser.kt
│ │ │ ├── ReleasesDataSource.kt
│ │ │ ├── ReleasesEvent.kt
│ │ │ ├── ReleasesScreen.kt
│ │ │ ├── ReleasesState.kt
│ │ │ └── ReleasesViewModel.kt
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── releases
│ │ └── ReleasesContentParserTest.kt
├── reports
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── reports
│ │ │ ├── FilterOverlay.kt
│ │ │ ├── ReportFilter.kt
│ │ │ ├── ReportScreen.kt
│ │ │ ├── ReportScreenEvent.kt
│ │ │ ├── ReportScreenState.kt
│ │ │ └── ReportViewModel.kt
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── ivy
│ │ │ └── report
│ │ │ └── ReportPaparazziTest.kt
│ │ └── snapshots
│ │ └── images
│ │ ├── com.ivy.report_ReportPaparazziTest_snapshot Report Screen no filter[Dark].png
│ │ ├── com.ivy.report_ReportPaparazziTest_snapshot Report Screen no filter[Light].png
│ │ ├── com.ivy.report_ReportPaparazziTest_snapshot Report Screen[Dark].png
│ │ └── com.ivy.report_ReportPaparazziTest_snapshot Report Screen[Light].png
├── search
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── search
│ │ │ ├── SearchEvent.kt
│ │ │ ├── SearchScreen.kt
│ │ │ ├── SearchState.kt
│ │ │ └── SearchViewModel.kt
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── ivy
│ │ │ └── search
│ │ │ └── SearchPaparazziTest.kt
│ │ └── snapshots
│ │ └── images
│ │ ├── com.ivy.search_SearchPaparazziTest_snapshot Search Screen[Dark].png
│ │ └── com.ivy.search_SearchPaparazziTest_snapshot Search Screen[Light].png
├── settings
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── settings
│ │ ├── SettingsEvent.kt
│ │ ├── SettingsScreen.kt
│ │ ├── SettingsState.kt
│ │ └── SettingsViewModel.kt
└── transactions
│ ├── build.gradle.kts
│ └── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── ivy
│ │ └── transactions
│ │ ├── TransactionsEvent.kt
│ │ ├── TransactionsScreen.kt
│ │ ├── TransactionsState.kt
│ │ └── TransactionsViewModel.kt
│ └── test
│ ├── java
│ └── com
│ │ └── ivy
│ │ └── transactions
│ │ └── TransactionsPaparazziTest.kt
│ └── snapshots
│ └── images
│ ├── com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Dark].png
│ └── com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Light].png
├── scripts
├── composeStability.sh
├── composeStabilityBaseline.sh
├── detekt.sh
├── detektBaseline.sh
├── detektFormat.sh
├── generateModulesGraph.sh
├── integrationTests.sh
├── lint.sh
├── lintBaseline.sh
├── paparazziScreenshotTests.sh
└── unitTests.sh
├── settings.gradle.kts
├── shared
├── base
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── base
│ │ │ ├── TestDispatchersProvider.kt
│ │ │ ├── Toaster.kt
│ │ │ ├── di
│ │ │ ├── BaseHiltBindings.kt
│ │ │ ├── BaseModule.kt
│ │ │ └── KotlinxSerializationModule.kt
│ │ │ ├── kotlinxserilzation
│ │ │ ├── KSerializerInstant.kt
│ │ │ ├── KSerializerLocalDateTime.kt
│ │ │ └── KSerializerUUID.kt
│ │ │ ├── legacy
│ │ │ ├── DateTimeUtil.kt
│ │ │ ├── FileUtil.kt
│ │ │ ├── GlobalUtils.kt
│ │ │ ├── LegacyTag.kt
│ │ │ ├── SharedPrefs.kt
│ │ │ ├── Theme.kt
│ │ │ ├── Transaction.kt
│ │ │ ├── TransactionHistoryItem.kt
│ │ │ └── ZipUtils.kt
│ │ │ ├── model
│ │ │ ├── IntervalType.kt
│ │ │ ├── LoanRecordType.kt
│ │ │ ├── LoanType.kt
│ │ │ └── TransactionType.kt
│ │ │ ├── resource
│ │ │ ├── AndroidResourceProvider.kt
│ │ │ ├── ResourceProvider.kt
│ │ │ └── TestResourceProvider.kt
│ │ │ ├── threading
│ │ │ ├── DispatchersProvider.kt
│ │ │ └── IvyDispatchersProvider.kt
│ │ │ └── time
│ │ │ ├── TimeConversionExt.kt
│ │ │ ├── TimeConverter.kt
│ │ │ ├── TimeProvider.kt
│ │ │ ├── TimeRange.kt
│ │ │ └── impl
│ │ │ ├── DeviceTimeProvider.kt
│ │ │ ├── StandardTimeConverter.kt
│ │ │ └── TestTimeConverter.kt
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── base
│ │ └── time
│ │ └── impl
│ │ ├── DeviceTimeProviderTest.kt
│ │ ├── StandardTimeConverterPropertyTest.kt
│ │ └── StandardTimeConverterTest.kt
├── data
│ ├── core-testing
│ │ └── build.gradle.kts
│ ├── core
│ │ ├── build.gradle.kts
│ │ ├── schemas
│ │ │ └── com.ivy.data.db.IvyRoomDatabase
│ │ │ │ ├── 101.json
│ │ │ │ ├── 102.json
│ │ │ │ ├── 103.json
│ │ │ │ ├── 104.json
│ │ │ │ ├── 105.json
│ │ │ │ ├── 106.json
│ │ │ │ ├── 107.json
│ │ │ │ ├── 108.json
│ │ │ │ ├── 109.json
│ │ │ │ ├── 110.json
│ │ │ │ ├── 111.json
│ │ │ │ ├── 112.json
│ │ │ │ ├── 113.json
│ │ │ │ ├── 114.json
│ │ │ │ ├── 115.json
│ │ │ │ ├── 116.json
│ │ │ │ ├── 117.json
│ │ │ │ ├── 118.json
│ │ │ │ ├── 119.json
│ │ │ │ ├── 120.json
│ │ │ │ ├── 121.json
│ │ │ │ ├── 122.json
│ │ │ │ ├── 123.json
│ │ │ │ ├── 124.json
│ │ │ │ ├── 125.json
│ │ │ │ ├── 126.json
│ │ │ │ ├── 127.json
│ │ │ │ ├── 128.json
│ │ │ │ ├── 129.json
│ │ │ │ └── 130.json
│ │ └── src
│ │ │ ├── androidTest
│ │ │ ├── assets
│ │ │ │ └── backups
│ │ │ │ │ ├── 450-150.json
│ │ │ │ │ └── 450-150.zip
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── ivy
│ │ │ │ └── data
│ │ │ │ ├── backup
│ │ │ │ └── BackupDataUseCaseAndroidTest.kt
│ │ │ │ └── db
│ │ │ │ ├── IvyRoomDatabaseMigrationTest.kt
│ │ │ │ └── Migration128to129Test.kt
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── ivy
│ │ │ │ └── data
│ │ │ │ ├── DataObserver.kt
│ │ │ │ ├── backup
│ │ │ │ ├── BackupDataUseCase.kt
│ │ │ │ ├── CSVRow.kt
│ │ │ │ ├── ImportResult.kt
│ │ │ │ └── IvyWalletCompleteData.kt
│ │ │ │ ├── datasource
│ │ │ │ └── LocalLegalDataSource.kt
│ │ │ │ ├── datastore
│ │ │ │ ├── Datastore.kt
│ │ │ │ └── DatastoreKeys.kt
│ │ │ │ ├── db
│ │ │ │ ├── IvyRoomDatabase.kt
│ │ │ │ ├── RoomTypeConverters.kt
│ │ │ │ ├── dao
│ │ │ │ │ ├── fake
│ │ │ │ │ │ ├── FakeAccountDao.kt
│ │ │ │ │ │ ├── FakeBudgetDao.kt
│ │ │ │ │ │ ├── FakeCategoryDao.kt
│ │ │ │ │ │ ├── FakeLoanDao.kt
│ │ │ │ │ │ ├── FakeLoanRecordDao.kt
│ │ │ │ │ │ ├── FakePlannedPaymentDao.kt
│ │ │ │ │ │ ├── FakeSettingsDao.kt
│ │ │ │ │ │ ├── FakeTagAssociationDao.kt
│ │ │ │ │ │ ├── FakeTagDao.kt
│ │ │ │ │ │ └── FakeTransactionDao.kt
│ │ │ │ │ ├── read
│ │ │ │ │ │ ├── AccountDao.kt
│ │ │ │ │ │ ├── BudgetDao.kt
│ │ │ │ │ │ ├── CategoryDao.kt
│ │ │ │ │ │ ├── ExchangeRatesDao.kt
│ │ │ │ │ │ ├── LoanDao.kt
│ │ │ │ │ │ ├── LoanRecordDao.kt
│ │ │ │ │ │ ├── PlannedPaymentRuleDao.kt
│ │ │ │ │ │ ├── SettingsDao.kt
│ │ │ │ │ │ ├── TagAssociationDao.kt
│ │ │ │ │ │ ├── TagDao.kt
│ │ │ │ │ │ ├── TransactionDao.kt
│ │ │ │ │ │ └── UserDao.kt
│ │ │ │ │ └── write
│ │ │ │ │ │ ├── WriteAccountDao.kt
│ │ │ │ │ │ ├── WriteBudgetDao.kt
│ │ │ │ │ │ ├── WriteCategoryDao.kt
│ │ │ │ │ │ ├── WriteExchangeRatesDao.kt
│ │ │ │ │ │ ├── WriteLoanDao.kt
│ │ │ │ │ │ ├── WriteLoanRecordDao.kt
│ │ │ │ │ │ ├── WritePlannedPaymentRuleDao.kt
│ │ │ │ │ │ ├── WriteSettingsDao.kt
│ │ │ │ │ │ ├── WriteTagAssociationDao.kt
│ │ │ │ │ │ ├── WriteTagDao.kt
│ │ │ │ │ │ └── WriteTransactionDao.kt
│ │ │ │ ├── entity
│ │ │ │ │ ├── AccountEntity.kt
│ │ │ │ │ ├── BudgetEntity.kt
│ │ │ │ │ ├── CategoryEntity.kt
│ │ │ │ │ ├── ExchangeRateEntity.kt
│ │ │ │ │ ├── LoanEntity.kt
│ │ │ │ │ ├── LoanRecordEntity.kt
│ │ │ │ │ ├── PlannedPaymentRuleEntity.kt
│ │ │ │ │ ├── SettingsEntity.kt
│ │ │ │ │ ├── TagAssociationEntity.kt
│ │ │ │ │ ├── TagEntity.kt
│ │ │ │ │ ├── TransactionEntity.kt
│ │ │ │ │ └── UserEntity.kt
│ │ │ │ └── migration
│ │ │ │ │ ├── Migration105to106_TrnRecurringRules.kt
│ │ │ │ │ ├── Migration106to107_Wishlist.kt
│ │ │ │ │ ├── Migration107to108_Sync.kt
│ │ │ │ │ ├── Migration108to109_Users.kt
│ │ │ │ │ ├── Migration109to110_PlannedPayments.kt
│ │ │ │ │ ├── Migration110to111_PlannedPaymentRule.kt
│ │ │ │ │ ├── Migration111to112_User_testUser.kt
│ │ │ │ │ ├── Migration112to113_ExchangeRates.kt
│ │ │ │ │ ├── Migration113to114_Multi_Currency.kt
│ │ │ │ │ ├── Migration114to115_Category_Account_Icons.kt
│ │ │ │ │ ├── Migration115to116_Account_Include_In_Balance.kt
│ │ │ │ │ ├── Migration116to117_SalteEdgeIntgration.kt
│ │ │ │ │ ├── Migration117to118_Budgets.kt
│ │ │ │ │ ├── Migration118to119_Loans.kt
│ │ │ │ │ ├── Migration119to120_LoanTransactions.kt
│ │ │ │ │ ├── Migration120to121_DropWishlistItem.kt
│ │ │ │ │ ├── Migration122to123_ExchangeRates.kt
│ │ │ │ │ ├── Migration123to124_LoanIncludeDateTime.kt
│ │ │ │ │ ├── Migration124to125_LoanEditDateTime.kt
│ │ │ │ │ ├── Migration125to126_Tags.kt
│ │ │ │ │ ├── Migration126to127_LoanRecordType.kt
│ │ │ │ │ ├── Migration127to128_PaidForDateRecord.kt
│ │ │ │ │ ├── Migration128to129_DeleteIsDeleted.kt
│ │ │ │ │ └── Migration129to130_LoanIncludeNote.kt
│ │ │ │ ├── di
│ │ │ │ ├── DatastoreModule.kt
│ │ │ │ ├── KtorClientModule.kt
│ │ │ │ ├── RemoteDataSourceModule.kt
│ │ │ │ └── RoomDbModule.kt
│ │ │ │ ├── file
│ │ │ │ └── FileSystem.kt
│ │ │ │ ├── remote
│ │ │ │ ├── RemoteExchangeRatesDataSource.kt
│ │ │ │ ├── impl
│ │ │ │ │ └── RemoteExchangeRatesDataSourceImpl.kt
│ │ │ │ └── responses
│ │ │ │ │ └── ExchangeRatesResponse.kt
│ │ │ │ ├── repository
│ │ │ │ ├── AccountRepository.kt
│ │ │ │ ├── CategoryRepository.kt
│ │ │ │ ├── CurrencyRepository.kt
│ │ │ │ ├── ExchangeRatesRepository.kt
│ │ │ │ ├── LegalRepository.kt
│ │ │ │ ├── RepositoryMemo.kt
│ │ │ │ ├── TagRepository.kt
│ │ │ │ ├── TransactionRepository.kt
│ │ │ │ ├── fake
│ │ │ │ │ └── FakeRepositoryMemo.kt
│ │ │ │ └── mapper
│ │ │ │ │ ├── AccountMapper.kt
│ │ │ │ │ ├── CategoryMapper.kt
│ │ │ │ │ ├── ExchangeRateMapper.kt
│ │ │ │ │ ├── TagMapper.kt
│ │ │ │ │ └── TransactionMapper.kt
│ │ │ │ └── temp
│ │ │ │ └── migration
│ │ │ │ └── TempMigrationUtils.kt
│ │ │ └── test
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── ivy
│ │ │ │ └── data
│ │ │ │ ├── ArbAccountEntity.kt
│ │ │ │ ├── ArbTransactionEntity.kt
│ │ │ │ ├── TestResourceUtil.kt
│ │ │ │ ├── backup
│ │ │ │ └── BackupDataUseCaseTest.kt
│ │ │ │ ├── dao
│ │ │ │ ├── FakeAccountDaoTest.kt
│ │ │ │ └── FakeCategoryDaoTest.kt
│ │ │ │ └── repository
│ │ │ │ ├── AccountRepositoryTest.kt
│ │ │ │ ├── CategoryRepositoryTest.kt
│ │ │ │ ├── ExchangeRatesRepositoryTest.kt
│ │ │ │ ├── TransactionRepositoryTest.kt
│ │ │ │ └── mapper
│ │ │ │ ├── AccountMapperPropertyTest.kt
│ │ │ │ ├── AccountMapperTest.kt
│ │ │ │ ├── CategoryMapperTest.kt
│ │ │ │ ├── ExchangeRateMapperTest.kt
│ │ │ │ ├── TransactionMapperPropertyTest.kt
│ │ │ │ └── TransactionMapperTest.kt
│ │ │ └── resources
│ │ │ └── backups
│ │ │ └── 450-150.json
│ ├── model-testing
│ │ ├── build.gradle.kts
│ │ └── src
│ │ │ ├── main
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── ivy
│ │ │ │ └── data
│ │ │ │ └── model
│ │ │ │ └── testing
│ │ │ │ ├── ArbAccount.kt
│ │ │ │ ├── ArbCategory.kt
│ │ │ │ ├── ArbTransaction.kt
│ │ │ │ ├── ArbUtils.kt
│ │ │ │ ├── ArbValue.kt
│ │ │ │ ├── DoubleApproxAssertion.kt
│ │ │ │ └── ModelFixtures.kt
│ │ │ └── test
│ │ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── data
│ │ │ └── model
│ │ │ └── testing
│ │ │ ├── ArbCategoryTest.kt
│ │ │ ├── ArbTransactionTest.kt
│ │ │ ├── ArbUtilTest.kt
│ │ │ ├── ArbValueTest.kt
│ │ │ └── DoubleApproxAssertionTest.kt
│ └── model
│ │ ├── build.gradle.kts
│ │ └── src
│ │ ├── main
│ │ └── kotlin
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── data
│ │ │ └── model
│ │ │ ├── Account.kt
│ │ │ ├── Category.kt
│ │ │ ├── ExchangeRate.kt
│ │ │ ├── Reorderable.kt
│ │ │ ├── Tag.kt
│ │ │ ├── Transaction.kt
│ │ │ ├── Value.kt
│ │ │ ├── exact
│ │ │ └── ExactDsl.kt
│ │ │ ├── primitive
│ │ │ ├── AssetCode.kt
│ │ │ ├── AssociationId.kt
│ │ │ ├── ColorInt.kt
│ │ │ ├── IconAsset.kt
│ │ │ ├── NonNegativeDouble.kt
│ │ │ ├── NonNegativeInt.kt
│ │ │ ├── NonNegativeLong.kt
│ │ │ ├── NonZeroDouble.kt
│ │ │ ├── NotBlankTrimmedString.kt
│ │ │ ├── PositiveDouble.kt
│ │ │ └── PositiveInt.kt
│ │ │ ├── sync
│ │ │ ├── Identifiable.kt
│ │ │ └── UniqueId.kt
│ │ │ └── util
│ │ │ └── ValueRounding.kt
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── data
│ │ └── model
│ │ ├── primitive
│ │ ├── AssetCodeTest.kt
│ │ ├── IconIdTest.kt
│ │ ├── NonNegativeDoubleTest.kt
│ │ ├── NonNegativeIntTest.kt
│ │ ├── NonZeroDoubleTest.kt
│ │ ├── NotBlankTrimmedStringTest.kt
│ │ ├── PositiveDoubleTest.kt
│ │ ├── PositiveIntTest.kt
│ │ └── TransactionTest.kt
│ │ └── util
│ │ └── ValueRoundingTest.kt
├── domain
│ ├── build.gradle.kts
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── domain
│ │ │ └── usecase
│ │ │ └── SyncExchangeRatesUseCaseTest.kt
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── ivy
│ │ │ └── domain
│ │ │ ├── AppStarter.kt
│ │ │ ├── RootScreen.kt
│ │ │ ├── di
│ │ │ └── IvyCoreBindingsModule.kt
│ │ │ ├── features
│ │ │ ├── BoolFeature.kt
│ │ │ ├── FeatureGroup.kt
│ │ │ ├── Features.kt
│ │ │ └── IvyFeatures.kt
│ │ │ ├── model
│ │ │ ├── StatSummary.kt
│ │ │ └── TimeRange.kt
│ │ │ └── usecase
│ │ │ ├── BalanceBuilder.kt
│ │ │ ├── StatSummaryBuilder.kt
│ │ │ ├── account
│ │ │ ├── AccountBalanceUseCase.kt
│ │ │ └── AccountStatsUseCase.kt
│ │ │ ├── category
│ │ │ └── CategoryStatsUseCase.kt
│ │ │ ├── csv
│ │ │ ├── ExportCsvUseCase.kt
│ │ │ ├── IvyCsvRow.kt
│ │ │ └── ReadCsvUseCase.kt
│ │ │ ├── exchange
│ │ │ ├── ExchangeUseCase.kt
│ │ │ └── SyncExchangeRatesUseCase.kt
│ │ │ └── wallet
│ │ │ ├── WalletBalanceUseCase.kt
│ │ │ └── WalletStatsUseCase.kt
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── domain
│ │ ├── ArbTransactionsUtil.kt
│ │ ├── ValueUtil.kt
│ │ ├── model
│ │ └── StatSummaryAssertion.kt
│ │ └── usecase
│ │ ├── balance
│ │ └── BalanceBuilderTest.kt
│ │ ├── csv
│ │ └── ExportCsvUseCasePropertyTest.kt
│ │ └── stat
│ │ ├── AccountStatsUseCasePropertyTest.kt
│ │ └── StatSummaryBuilderTest.kt
└── ui
│ ├── core
│ ├── build.gradle.kts
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── ivy
│ │ │ │ ├── design
│ │ │ │ └── system
│ │ │ │ │ ├── IvyMaterial3Theme.kt
│ │ │ │ │ └── colors
│ │ │ │ │ ├── ColorShades.kt
│ │ │ │ │ └── IvyColors.kt
│ │ │ │ └── ui
│ │ │ │ ├── ComposeViewModel.kt
│ │ │ │ ├── FormatMoneyUseCase.kt
│ │ │ │ ├── RememberScrollPosition.kt
│ │ │ │ ├── component
│ │ │ │ └── OpenSourceCard.kt
│ │ │ │ ├── di
│ │ │ │ └── IvyUiBindings.kt
│ │ │ │ └── time
│ │ │ │ ├── DevicePreferences.kt
│ │ │ │ ├── TimeFormatter.kt
│ │ │ │ └── impl
│ │ │ │ ├── AndroidDateTimePicker.kt
│ │ │ │ ├── AndroidDevicePreferences.kt
│ │ │ │ ├── DateTimePicker.kt
│ │ │ │ └── IvyTimeFormatter.kt
│ │ └── res
│ │ │ ├── drawable-nodpi
│ │ │ ├── donate_illustration.png
│ │ │ ├── ivywallet_logo.png
│ │ │ ├── monefy_logo.png
│ │ │ ├── moneymanager_logo.png
│ │ │ ├── spendee_logo.png
│ │ │ └── wallet_by_budgetbakers_logo.png
│ │ │ ├── drawable
│ │ │ ├── bluecoins.png
│ │ │ ├── didyouknow.xml
│ │ │ ├── expense_shape_widget_background.xml
│ │ │ ├── financisto_logo.png
│ │ │ ├── fortune_city_app_logo.png
│ │ │ ├── github_logo.xml
│ │ │ ├── home_more_menu_amoled_dark_mode.xml
│ │ │ ├── home_more_menu_auto_mode.xml
│ │ │ ├── home_more_menu_budgets.xml
│ │ │ ├── home_more_menu_categories.xml
│ │ │ ├── home_more_menu_dark_mode.xml
│ │ │ ├── home_more_menu_light_mode.xml
│ │ │ ├── home_more_menu_loans.xml
│ │ │ ├── home_more_menu_planned_payments.xml
│ │ │ ├── home_more_menu_reports.xml
│ │ │ ├── home_more_menu_settings.xml
│ │ │ ├── home_more_menu_share.xml
│ │ │ ├── ic_account_onboarding.xml
│ │ │ ├── ic_accounts.xml
│ │ │ ├── ic_accounts_no_padding.xml
│ │ │ ├── ic_add.xml
│ │ │ ├── ic_add_attachment.xml
│ │ │ ├── ic_add_custom_field.xml
│ │ │ ├── ic_add_due_date.xml
│ │ │ ├── ic_add_recurring.xml
│ │ │ ├── ic_add_reminder.xml
│ │ │ ├── ic_add_timetracking.xml
│ │ │ ├── ic_agreed.xml
│ │ │ ├── ic_alarm.xml
│ │ │ ├── ic_archive.xml
│ │ │ ├── ic_arrow_right.xml
│ │ │ ├── ic_attachment.xml
│ │ │ ├── ic_back.xml
│ │ │ ├── ic_back_android.xml
│ │ │ ├── ic_backspace.xml
│ │ │ ├── ic_budget_s.xml
│ │ │ ├── ic_budget_xl.xml
│ │ │ ├── ic_budget_xs.xml
│ │ │ ├── ic_buffer_exceeded.xml
│ │ │ ├── ic_buffer_ok.xml
│ │ │ ├── ic_bulb.xml
│ │ │ ├── ic_calendar.xml
│ │ │ ├── ic_categories.xml
│ │ │ ├── ic_categories_no_padding.xml
│ │ │ ├── ic_category_edit.xml
│ │ │ ├── ic_check.xml
│ │ │ ├── ic_checkbox_checked.xml
│ │ │ ├── ic_checkbox_unchecked.xml
│ │ │ ├── ic_checklist.xml
│ │ │ ├── ic_checklist_add.xml
│ │ │ ├── ic_clock.xml
│ │ │ ├── ic_currency.xml
│ │ │ ├── ic_custom_account_l.xml
│ │ │ ├── ic_custom_account_m.xml
│ │ │ ├── ic_custom_account_s.xml
│ │ │ ├── ic_custom_ada_l.xml
│ │ │ ├── ic_custom_ada_m.xml
│ │ │ ├── ic_custom_ada_s.xml
│ │ │ ├── ic_custom_atom_l.xml
│ │ │ ├── ic_custom_atom_m.xml
│ │ │ ├── ic_custom_atom_s.xml
│ │ │ ├── ic_custom_bank_l.xml
│ │ │ ├── ic_custom_bank_m.xml
│ │ │ ├── ic_custom_bank_s.xml
│ │ │ ├── ic_custom_bills_l.xml
│ │ │ ├── ic_custom_bills_m.xml
│ │ │ ├── ic_custom_bills_s.xml
│ │ │ ├── ic_custom_birthday_l.xml
│ │ │ ├── ic_custom_birthday_m.xml
│ │ │ ├── ic_custom_birthday_s.xml
│ │ │ ├── ic_custom_btc_l.xml
│ │ │ ├── ic_custom_btc_m.xml
│ │ │ ├── ic_custom_btc_s.xml
│ │ │ ├── ic_custom_calculator_l.xml
│ │ │ ├── ic_custom_calculator_m.xml
│ │ │ ├── ic_custom_calculator_s.xml
│ │ │ ├── ic_custom_calendar_l.xml
│ │ │ ├── ic_custom_calendar_m.xml
│ │ │ ├── ic_custom_calendar_s.xml
│ │ │ ├── ic_custom_camera_l.xml
│ │ │ ├── ic_custom_camera_m.xml
│ │ │ ├── ic_custom_camera_s.xml
│ │ │ ├── ic_custom_cash_l.xml
│ │ │ ├── ic_custom_cash_m.xml
│ │ │ ├── ic_custom_cash_s.xml
│ │ │ ├── ic_custom_category_l.xml
│ │ │ ├── ic_custom_category_m.xml
│ │ │ ├── ic_custom_category_s.xml
│ │ │ ├── ic_custom_chemistry_l.xml
│ │ │ ├── ic_custom_chemistry_m.xml
│ │ │ ├── ic_custom_chemistry_s.xml
│ │ │ ├── ic_custom_clothes2_l.xml
│ │ │ ├── ic_custom_clothes2_m.xml
│ │ │ ├── ic_custom_clothes2_s.xml
│ │ │ ├── ic_custom_clothes_l.xml
│ │ │ ├── ic_custom_clothes_m.xml
│ │ │ ├── ic_custom_clothes_s.xml
│ │ │ ├── ic_custom_coffee_l.xml
│ │ │ ├── ic_custom_coffee_m.xml
│ │ │ ├── ic_custom_coffee_s.xml
│ │ │ ├── ic_custom_connect_l.xml
│ │ │ ├── ic_custom_connect_m.xml
│ │ │ ├── ic_custom_connect_s.xml
│ │ │ ├── ic_custom_crown_l.xml
│ │ │ ├── ic_custom_crown_m.xml
│ │ │ ├── ic_custom_crown_s.xml
│ │ │ ├── ic_custom_diamond_l.xml
│ │ │ ├── ic_custom_diamond_m.xml
│ │ │ ├── ic_custom_diamond_s.xml
│ │ │ ├── ic_custom_dna_l.xml
│ │ │ ├── ic_custom_dna_m.xml
│ │ │ ├── ic_custom_dna_s.xml
│ │ │ ├── ic_custom_doctor_l.xml
│ │ │ ├── ic_custom_doctor_m.xml
│ │ │ ├── ic_custom_doctor_s.xml
│ │ │ ├── ic_custom_document_l.xml
│ │ │ ├── ic_custom_document_m.xml
│ │ │ ├── ic_custom_document_s.xml
│ │ │ ├── ic_custom_doge_l.xml
│ │ │ ├── ic_custom_doge_m.xml
│ │ │ ├── ic_custom_doge_s.xml
│ │ │ ├── ic_custom_drink_l.xml
│ │ │ ├── ic_custom_drink_m.xml
│ │ │ ├── ic_custom_drink_s.xml
│ │ │ ├── ic_custom_education_l.xml
│ │ │ ├── ic_custom_education_m.xml
│ │ │ ├── ic_custom_education_s.xml
│ │ │ ├── ic_custom_eth_l.xml
│ │ │ ├── ic_custom_eth_m.xml
│ │ │ ├── ic_custom_eth_s.xml
│ │ │ ├── ic_custom_family_l.xml
│ │ │ ├── ic_custom_family_m.xml
│ │ │ ├── ic_custom_family_s.xml
│ │ │ ├── ic_custom_farmacy_l.xml
│ │ │ ├── ic_custom_farmacy_m.xml
│ │ │ ├── ic_custom_farmacy_s.xml
│ │ │ ├── ic_custom_fingerprint_l.xml
│ │ │ ├── ic_custom_fingerprint_m.xml
│ │ │ ├── ic_custom_fingerprint_s.xml
│ │ │ ├── ic_custom_fishfood_l.xml
│ │ │ ├── ic_custom_fishfood_m.xml
│ │ │ ├── ic_custom_fishfood_s.xml
│ │ │ ├── ic_custom_fitness_l.xml
│ │ │ ├── ic_custom_fitness_m.xml
│ │ │ ├── ic_custom_fitness_s.xml
│ │ │ ├── ic_custom_food2_l.xml
│ │ │ ├── ic_custom_food2_m.xml
│ │ │ ├── ic_custom_food2_s.xml
│ │ │ ├── ic_custom_fooddrink_l.xml
│ │ │ ├── ic_custom_fooddrink_m.xml
│ │ │ ├── ic_custom_fooddrink_s.xml
│ │ │ ├── ic_custom_furniture_l.xml
│ │ │ ├── ic_custom_furniture_m.xml
│ │ │ ├── ic_custom_furniture_s.xml
│ │ │ ├── ic_custom_gambling_l.xml
│ │ │ ├── ic_custom_gambling_m.xml
│ │ │ ├── ic_custom_gambling_s.xml
│ │ │ ├── ic_custom_game_l.xml
│ │ │ ├── ic_custom_game_m.xml
│ │ │ ├── ic_custom_game_s.xml
│ │ │ ├── ic_custom_gears_l.xml
│ │ │ ├── ic_custom_gears_m.xml
│ │ │ ├── ic_custom_gears_s.xml
│ │ │ ├── ic_custom_gift_l.xml
│ │ │ ├── ic_custom_gift_m.xml
│ │ │ ├── ic_custom_gift_s.xml
│ │ │ ├── ic_custom_groceries_l.xml
│ │ │ ├── ic_custom_groceries_m.xml
│ │ │ ├── ic_custom_groceries_s.xml
│ │ │ ├── ic_custom_hairdresser_l.xml
│ │ │ ├── ic_custom_hairdresser_m.xml
│ │ │ ├── ic_custom_hairdresser_s.xml
│ │ │ ├── ic_custom_health_l.xml
│ │ │ ├── ic_custom_health_m.xml
│ │ │ ├── ic_custom_health_s.xml
│ │ │ ├── ic_custom_hike_l.xml
│ │ │ ├── ic_custom_hike_m.xml
│ │ │ ├── ic_custom_hike_s.xml
│ │ │ ├── ic_custom_house_l.xml
│ │ │ ├── ic_custom_house_m.xml
│ │ │ ├── ic_custom_house_s.xml
│ │ │ ├── ic_custom_insurance_l.xml
│ │ │ ├── ic_custom_insurance_m.xml
│ │ │ ├── ic_custom_insurance_s.xml
│ │ │ ├── ic_custom_label_l.xml
│ │ │ ├── ic_custom_label_m.xml
│ │ │ ├── ic_custom_label_s.xml
│ │ │ ├── ic_custom_leaf_l.xml
│ │ │ ├── ic_custom_leaf_m.xml
│ │ │ ├── ic_custom_leaf_s.xml
│ │ │ ├── ic_custom_loan_l.xml
│ │ │ ├── ic_custom_loan_m.xml
│ │ │ ├── ic_custom_loan_s.xml
│ │ │ ├── ic_custom_location_l.xml
│ │ │ ├── ic_custom_location_m.xml
│ │ │ ├── ic_custom_location_s.xml
│ │ │ ├── ic_custom_makeup_l.xml
│ │ │ ├── ic_custom_makeup_m.xml
│ │ │ ├── ic_custom_makeup_s.xml
│ │ │ ├── ic_custom_music_l.xml
│ │ │ ├── ic_custom_music_m.xml
│ │ │ ├── ic_custom_music_s.xml
│ │ │ ├── ic_custom_notice_l.xml
│ │ │ ├── ic_custom_notice_m.xml
│ │ │ ├── ic_custom_notice_s.xml
│ │ │ ├── ic_custom_orderfood2_l.xml
│ │ │ ├── ic_custom_orderfood2_m.xml
│ │ │ ├── ic_custom_orderfood2_s.xml
│ │ │ ├── ic_custom_orderfood_l.xml
│ │ │ ├── ic_custom_orderfood_m.xml
│ │ │ ├── ic_custom_orderfood_s.xml
│ │ │ ├── ic_custom_palette_l.xml
│ │ │ ├── ic_custom_palette_m.xml
│ │ │ ├── ic_custom_palette_s.xml
│ │ │ ├── ic_custom_people_l.xml
│ │ │ ├── ic_custom_people_m.xml
│ │ │ ├── ic_custom_people_s.xml
│ │ │ ├── ic_custom_pet_l.xml
│ │ │ ├── ic_custom_pet_m.xml
│ │ │ ├── ic_custom_pet_s.xml
│ │ │ ├── ic_custom_plant_l.xml
│ │ │ ├── ic_custom_plant_m.xml
│ │ │ ├── ic_custom_plant_s.xml
│ │ │ ├── ic_custom_programming_l.xml
│ │ │ ├── ic_custom_programming_m.xml
│ │ │ ├── ic_custom_programming_s.xml
│ │ │ ├── ic_custom_relationship_l.xml
│ │ │ ├── ic_custom_relationship_m.xml
│ │ │ ├── ic_custom_relationship_s.xml
│ │ │ ├── ic_custom_restaurant_l.xml
│ │ │ ├── ic_custom_restaurant_m.xml
│ │ │ ├── ic_custom_restaurant_s.xml
│ │ │ ├── ic_custom_revolut_l.xml
│ │ │ ├── ic_custom_revolut_m.xml
│ │ │ ├── ic_custom_revolut_s.xml
│ │ │ ├── ic_custom_rocket_l.xml
│ │ │ ├── ic_custom_rocket_m.xml
│ │ │ ├── ic_custom_rocket_s.xml
│ │ │ ├── ic_custom_safe_l.xml
│ │ │ ├── ic_custom_safe_m.xml
│ │ │ ├── ic_custom_safe_s.xml
│ │ │ ├── ic_custom_sail_l.xml
│ │ │ ├── ic_custom_sail_m.xml
│ │ │ ├── ic_custom_sail_s.xml
│ │ │ ├── ic_custom_selfdevelopment_l.xml
│ │ │ ├── ic_custom_selfdevelopment_m.xml
│ │ │ ├── ic_custom_selfdevelopment_s.xml
│ │ │ ├── ic_custom_server_l.xml
│ │ │ ├── ic_custom_server_m.xml
│ │ │ ├── ic_custom_server_s.xml
│ │ │ ├── ic_custom_shopping2_l.xml
│ │ │ ├── ic_custom_shopping2_m.xml
│ │ │ ├── ic_custom_shopping2_s.xml
│ │ │ ├── ic_custom_shopping_l.xml
│ │ │ ├── ic_custom_shopping_m.xml
│ │ │ ├── ic_custom_shopping_s.xml
│ │ │ ├── ic_custom_sports_l.xml
│ │ │ ├── ic_custom_sports_m.xml
│ │ │ ├── ic_custom_sports_s.xml
│ │ │ ├── ic_custom_star_l.xml
│ │ │ ├── ic_custom_star_m.xml
│ │ │ ├── ic_custom_star_s.xml
│ │ │ ├── ic_custom_stats_l.xml
│ │ │ ├── ic_custom_stats_m.xml
│ │ │ ├── ic_custom_stats_s.xml
│ │ │ ├── ic_custom_tools_l.xml
│ │ │ ├── ic_custom_tools_m.xml
│ │ │ ├── ic_custom_tools_s.xml
│ │ │ ├── ic_custom_transfer_m.xml
│ │ │ ├── ic_custom_transport_l.xml
│ │ │ ├── ic_custom_transport_m.xml
│ │ │ ├── ic_custom_transport_s.xml
│ │ │ ├── ic_custom_travel_l.xml
│ │ │ ├── ic_custom_travel_m.xml
│ │ │ ├── ic_custom_travel_s.xml
│ │ │ ├── ic_custom_trees_l.xml
│ │ │ ├── ic_custom_trees_m.xml
│ │ │ ├── ic_custom_trees_s.xml
│ │ │ ├── ic_custom_vehicle_l.xml
│ │ │ ├── ic_custom_vehicle_m.xml
│ │ │ ├── ic_custom_vehicle_s.xml
│ │ │ ├── ic_custom_work_l.xml
│ │ │ ├── ic_custom_work_m.xml
│ │ │ ├── ic_custom_work_s.xml
│ │ │ ├── ic_custom_xrp_l.xml
│ │ │ ├── ic_custom_xrp_m.xml
│ │ │ ├── ic_custom_xrp_s.xml
│ │ │ ├── ic_custom_zeus_l.xml
│ │ │ ├── ic_custom_zeus_m.xml
│ │ │ ├── ic_custom_zeus_s.xml
│ │ │ ├── ic_darkmode.xml
│ │ │ ├── ic_data_synced.xml
│ │ │ ├── ic_date.xml
│ │ │ ├── ic_delete.xml
│ │ │ ├── ic_description.xml
│ │ │ ├── ic_dismiss.xml
│ │ │ ├── ic_dismiss_close.xml
│ │ │ ├── ic_divider.xml
│ │ │ ├── ic_donate_crown.xml
│ │ │ ├── ic_donate_minus.xml
│ │ │ ├── ic_donate_plus.xml
│ │ │ ├── ic_done.xml
│ │ │ ├── ic_drag_handle.xml
│ │ │ ├── ic_due_date.xml
│ │ │ ├── ic_duedate.xml
│ │ │ ├── ic_edit.xml
│ │ │ ├── ic_email.xml
│ │ │ ├── ic_expand_less.xml
│ │ │ ├── ic_expand_more.xml
│ │ │ ├── ic_expandarrow.xml
│ │ │ ├── ic_expense.xml
│ │ │ ├── ic_export_csv.xml
│ │ │ ├── ic_export_csv_no_padding.xml
│ │ │ ├── ic_file.xml
│ │ │ ├── ic_filter_l.xml
│ │ │ ├── ic_filter_xs.xml
│ │ │ ├── ic_fingerprint.xml
│ │ │ ├── ic_format_text.xml
│ │ │ ├── ic_google.xml
│ │ │ ├── ic_hamburger.xml
│ │ │ ├── ic_hashtag.xml
│ │ │ ├── ic_hidden.xml
│ │ │ ├── ic_hide_m.xml
│ │ │ ├── ic_home.xml
│ │ │ ├── ic_import_video.xml
│ │ │ ├── ic_import_web.xml
│ │ │ ├── ic_income.xml
│ │ │ ├── ic_income_white.xml
│ │ │ ├── ic_ivy_logo.xml
│ │ │ ├── ic_label_hashtag.xml
│ │ │ ├── ic_launcher_background.xml
│ │ │ ├── ic_launcher_foreground.xml
│ │ │ ├── ic_launcher_monochrome.xml
│ │ │ ├── ic_lightmode.xml
│ │ │ ├── ic_local_account.xml
│ │ │ ├── ic_login.xml
│ │ │ ├── ic_logo.xml
│ │ │ ├── ic_logout.xml
│ │ │ ├── ic_modal_attachment_file.xml
│ │ │ ├── ic_modal_attachment_link.xml
│ │ │ ├── ic_modal_reminder.xml
│ │ │ ├── ic_monefy.xml
│ │ │ ├── ic_money_lover.xml
│ │ │ ├── ic_notes.xml
│ │ │ ├── ic_notification.xml
│ │ │ ├── ic_notification_m.xml
│ │ │ ├── ic_notransactions.xml
│ │ │ ├── ic_onboarding_next_arrow.xml
│ │ │ ├── ic_options.xml
│ │ │ ├── ic_outline_clear_24.xml
│ │ │ ├── ic_overdue.xml
│ │ │ ├── ic_planned_payments.xml
│ │ │ ├── ic_plus.xml
│ │ │ ├── ic_popup_add.xml
│ │ │ ├── ic_popup_close.xml
│ │ │ ├── ic_popup_collapse.xml
│ │ │ ├── ic_popup_expand.xml
│ │ │ ├── ic_premium_big.xml
│ │ │ ├── ic_premium_small.xml
│ │ │ ├── ic_priority_dropdown.xml
│ │ │ ├── ic_profile.xml
│ │ │ ├── ic_recurring.xml
│ │ │ ├── ic_recurring_next.xml
│ │ │ ├── ic_recurring_upcoming.xml
│ │ │ ├── ic_refresh.xml
│ │ │ ├── ic_remove.xml
│ │ │ ├── ic_remove_checklist_item.xml
│ │ │ ├── ic_reorder.xml
│ │ │ ├── ic_reset_password.xml
│ │ │ ├── ic_save.xml
│ │ │ ├── ic_search.xml
│ │ │ ├── ic_secure.xml
│ │ │ ├── ic_settings.xml
│ │ │ ├── ic_share.xml
│ │ │ ├── ic_side_menu_collapsed.xml
│ │ │ ├── ic_side_menu_expanded.xml
│ │ │ ├── ic_sort_by_alpha_24.xml
│ │ │ ├── ic_speendee.xml
│ │ │ ├── ic_statistics_s.xml
│ │ │ ├── ic_statistics_xs.xml
│ │ │ ├── ic_support.xml
│ │ │ ├── ic_swipe_horizontal.xml
│ │ │ ├── ic_swipe_up.xml
│ │ │ ├── ic_swipe_up_dark.xml
│ │ │ ├── ic_sync.xml
│ │ │ ├── ic_tasks.xml
│ │ │ ├── ic_telegram_24dp.xml
│ │ │ ├── ic_template.xml
│ │ │ ├── ic_time.xml
│ │ │ ├── ic_time_tracking_log_entry.xml
│ │ │ ├── ic_time_tracking_pause.xml
│ │ │ ├── ic_time_tracking_play.xml
│ │ │ ├── ic_timetracking.xml
│ │ │ ├── ic_toshl_finance.xml
│ │ │ ├── ic_transfer.xml
│ │ │ ├── ic_upload.xml
│ │ │ ├── ic_visible.xml
│ │ │ ├── ic_vue_brands_android.xml
│ │ │ ├── ic_vue_brands_apple.xml
│ │ │ ├── ic_vue_brands_be.xml
│ │ │ ├── ic_vue_brands_blogger.xml
│ │ │ ├── ic_vue_brands_bootsrap.xml
│ │ │ ├── ic_vue_brands_dribbble.xml
│ │ │ ├── ic_vue_brands_drive.xml
│ │ │ ├── ic_vue_brands_dropbox.xml
│ │ │ ├── ic_vue_brands_facebook.xml
│ │ │ ├── ic_vue_brands_figma.xml
│ │ │ ├── ic_vue_brands_framer.xml
│ │ │ ├── ic_vue_brands_google.xml
│ │ │ ├── ic_vue_brands_google_play.xml
│ │ │ ├── ic_vue_brands_html3.xml
│ │ │ ├── ic_vue_brands_html5.xml
│ │ │ ├── ic_vue_brands_illustrator.xml
│ │ │ ├── ic_vue_brands_js.xml
│ │ │ ├── ic_vue_brands_messenger.xml
│ │ │ ├── ic_vue_brands_ok.xml
│ │ │ ├── ic_vue_brands_paypal.xml
│ │ │ ├── ic_vue_brands_photoshop.xml
│ │ │ ├── ic_vue_brands_python.xml
│ │ │ ├── ic_vue_brands_slack.xml
│ │ │ ├── ic_vue_brands_snapchat.xml
│ │ │ ├── ic_vue_brands_spotify.xml
│ │ │ ├── ic_vue_brands_trello.xml
│ │ │ ├── ic_vue_brands_triangle.xml
│ │ │ ├── ic_vue_brands_twitch.xml
│ │ │ ├── ic_vue_brands_ui8.xml
│ │ │ ├── ic_vue_brands_vuesax.xml
│ │ │ ├── ic_vue_brands_whatsapp.xml
│ │ │ ├── ic_vue_brands_windows.xml
│ │ │ ├── ic_vue_brands_xd.xml
│ │ │ ├── ic_vue_brands_xiaomi.xml
│ │ │ ├── ic_vue_brands_youtube.xml
│ │ │ ├── ic_vue_brands_zoom.xml
│ │ │ ├── ic_vue_building_bank.xml
│ │ │ ├── ic_vue_building_building.xml
│ │ │ ├── ic_vue_building_building1.xml
│ │ │ ├── ic_vue_building_buildings.xml
│ │ │ ├── ic_vue_building_courthouse.xml
│ │ │ ├── ic_vue_building_hospital.xml
│ │ │ ├── ic_vue_building_house.xml
│ │ │ ├── ic_vue_chart_chart.xml
│ │ │ ├── ic_vue_chart_diagram.xml
│ │ │ ├── ic_vue_chart_graph.xml
│ │ │ ├── ic_vue_chart_status_up.xml
│ │ │ ├── ic_vue_chart_trend_up.xml
│ │ │ ├── ic_vue_crypto_aave.xml
│ │ │ ├── ic_vue_crypto_ankr.xml
│ │ │ ├── ic_vue_crypto_augur.xml
│ │ │ ├── ic_vue_crypto_autonio.xml
│ │ │ ├── ic_vue_crypto_avalanche.xml
│ │ │ ├── ic_vue_crypto_binance_coin.xml
│ │ │ ├── ic_vue_crypto_binance_usd.xml
│ │ │ ├── ic_vue_crypto_bitcoin.xml
│ │ │ ├── ic_vue_crypto_cardano.xml
│ │ │ ├── ic_vue_crypto_celo.xml
│ │ │ ├── ic_vue_crypto_celsius_.xml
│ │ │ ├── ic_vue_crypto_chainlink.xml
│ │ │ ├── ic_vue_crypto_civic.xml
│ │ │ ├── ic_vue_crypto_dai.xml
│ │ │ ├── ic_vue_crypto_dash.xml
│ │ │ ├── ic_vue_crypto_decred.xml
│ │ │ ├── ic_vue_crypto_dent.xml
│ │ │ ├── ic_vue_crypto_educare.xml
│ │ │ ├── ic_vue_crypto_emercoin.xml
│ │ │ ├── ic_vue_crypto_enjin_coin.xml
│ │ │ ├── ic_vue_crypto_eos.xml
│ │ │ ├── ic_vue_crypto_ethereum.xml
│ │ │ ├── ic_vue_crypto_ethereum_classic.xml
│ │ │ ├── ic_vue_crypto_ftx_token.xml
│ │ │ ├── ic_vue_crypto_graph.xml
│ │ │ ├── ic_vue_crypto_harmony.xml
│ │ │ ├── ic_vue_crypto_hedera_hashgraph.xml
│ │ │ ├── ic_vue_crypto_hex.xml
│ │ │ ├── ic_vue_crypto_huobi_token.xml
│ │ │ ├── ic_vue_crypto_icon.xml
│ │ │ ├── ic_vue_crypto_iost.xml
│ │ │ ├── ic_vue_crypto_kyber_network.xml
│ │ │ ├── ic_vue_crypto_litecoin.xml
│ │ │ ├── ic_vue_crypto_maker.xml
│ │ │ ├── ic_vue_crypto_monero.xml
│ │ │ ├── ic_vue_crypto_nebulas.xml
│ │ │ ├── ic_vue_crypto_nem.xml
│ │ │ ├── ic_vue_crypto_nexo.xml
│ │ │ ├── ic_vue_crypto_ocean_protocol.xml
│ │ │ ├── ic_vue_crypto_okb.xml
│ │ │ ├── ic_vue_crypto_ontology.xml
│ │ │ ├── ic_vue_crypto_polkadot.xml
│ │ │ ├── ic_vue_crypto_polygon.xml
│ │ │ ├── ic_vue_crypto_polyswarm.xml
│ │ │ ├── ic_vue_crypto_quant.xml
│ │ │ ├── ic_vue_crypto_siacoin.xml
│ │ │ ├── ic_vue_crypto_solana.xml
│ │ │ ├── ic_vue_crypto_stacks.xml
│ │ │ ├── ic_vue_crypto_stellar.xml
│ │ │ ├── ic_vue_crypto_tenx.xml
│ │ │ ├── ic_vue_crypto_tether.xml
│ │ │ ├── ic_vue_crypto_theta.xml
│ │ │ ├── ic_vue_crypto_thorchain.xml
│ │ │ ├── ic_vue_crypto_trontron.xml
│ │ │ ├── ic_vue_crypto_usd_coin.xml
│ │ │ ├── ic_vue_crypto_velas.xml
│ │ │ ├── ic_vue_crypto_vibe.xml
│ │ │ ├── ic_vue_crypto_wanchain.xml
│ │ │ ├── ic_vue_crypto_wing.xml
│ │ │ ├── ic_vue_crypto_xrp.xml
│ │ │ ├── ic_vue_crypto_zel.xml
│ │ │ ├── ic_vue_delivery_box.xml
│ │ │ ├── ic_vue_delivery_box1.xml
│ │ │ ├── ic_vue_delivery_package.xml
│ │ │ ├── ic_vue_delivery_receive.xml
│ │ │ ├── ic_vue_delivery_truck.xml
│ │ │ ├── ic_vue_design_bezier.xml
│ │ │ ├── ic_vue_design_brush.xml
│ │ │ ├── ic_vue_design_color_swatch.xml
│ │ │ ├── ic_vue_design_magicpen.xml
│ │ │ ├── ic_vue_design_roller.xml
│ │ │ ├── ic_vue_design_scissors.xml
│ │ │ ├── ic_vue_design_tool_pen.xml
│ │ │ ├── ic_vue_dev_arrow.xml
│ │ │ ├── ic_vue_dev_code.xml
│ │ │ ├── ic_vue_dev_data.xml
│ │ │ ├── ic_vue_dev_hashtag.xml
│ │ │ ├── ic_vue_dev_hierarchy.xml
│ │ │ ├── ic_vue_dev_relation.xml
│ │ │ ├── ic_vue_edu_award.xml
│ │ │ ├── ic_vue_edu_book.xml
│ │ │ ├── ic_vue_edu_bookmark.xml
│ │ │ ├── ic_vue_edu_briefcase.xml
│ │ │ ├── ic_vue_edu_calculator.xml
│ │ │ ├── ic_vue_edu_glass.xml
│ │ │ ├── ic_vue_edu_graduate_cap.xml
│ │ │ ├── ic_vue_edu_magazine.xml
│ │ │ ├── ic_vue_edu_note.xml
│ │ │ ├── ic_vue_edu_omega.xml
│ │ │ ├── ic_vue_edu_pen.xml
│ │ │ ├── ic_vue_edu_planer.xml
│ │ │ ├── ic_vue_edu_ruler_pen.xml
│ │ │ ├── ic_vue_edu_telescope.xml
│ │ │ ├── ic_vue_edu_todo.xml
│ │ │ ├── ic_vue_files_folder.xml
│ │ │ ├── ic_vue_files_folder_cloud.xml
│ │ │ ├── ic_vue_files_folder_favorite.xml
│ │ │ ├── ic_vue_location_discover.xml
│ │ │ ├── ic_vue_location_global.xml
│ │ │ ├── ic_vue_location_global_edit.xml
│ │ │ ├── ic_vue_location_global_search.xml
│ │ │ ├── ic_vue_location_location.xml
│ │ │ ├── ic_vue_location_map.xml
│ │ │ ├── ic_vue_location_map1.xml
│ │ │ ├── ic_vue_location_radar.xml
│ │ │ ├── ic_vue_location_routing.xml
│ │ │ ├── ic_vue_main_archive.xml
│ │ │ ├── ic_vue_main_battery_charging.xml
│ │ │ ├── ic_vue_main_battery_half.xml
│ │ │ ├── ic_vue_main_broom.xml
│ │ │ ├── ic_vue_main_cake.xml
│ │ │ ├── ic_vue_main_calendar.xml
│ │ │ ├── ic_vue_main_clock.xml
│ │ │ ├── ic_vue_main_coffee.xml
│ │ │ ├── ic_vue_main_crown.xml
│ │ │ ├── ic_vue_main_cup.xml
│ │ │ ├── ic_vue_main_emoji_happy.xml
│ │ │ ├── ic_vue_main_emoji_normal.xml
│ │ │ ├── ic_vue_main_emoji_sad.xml
│ │ │ ├── ic_vue_main_flash.xml
│ │ │ ├── ic_vue_main_gift.xml
│ │ │ ├── ic_vue_main_glass.xml
│ │ │ ├── ic_vue_main_home.xml
│ │ │ ├── ic_vue_main_home_safe.xml
│ │ │ ├── ic_vue_main_home_wifi.xml
│ │ │ ├── ic_vue_main_judge.xml
│ │ │ ├── ic_vue_main_lamp.xml
│ │ │ ├── ic_vue_main_lamp_charge.xml
│ │ │ ├── ic_vue_main_lifebuoy.xml
│ │ │ ├── ic_vue_main_milk.xml
│ │ │ ├── ic_vue_main_notification.xml
│ │ │ ├── ic_vue_main_pet.xml
│ │ │ ├── ic_vue_main_reserve.xml
│ │ │ ├── ic_vue_main_send.xml
│ │ │ ├── ic_vue_main_share.xml
│ │ │ ├── ic_vue_main_signpost.xml
│ │ │ ├── ic_vue_main_sport.xml
│ │ │ ├── ic_vue_main_timer.xml
│ │ │ ├── ic_vue_main_trash.xml
│ │ │ ├── ic_vue_main_tree.xml
│ │ │ ├── ic_vue_media_camera.xml
│ │ │ ├── ic_vue_media_film.xml
│ │ │ ├── ic_vue_media_film_play.xml
│ │ │ ├── ic_vue_media_image.xml
│ │ │ ├── ic_vue_media_microphone.xml
│ │ │ ├── ic_vue_media_mountains.xml
│ │ │ ├── ic_vue_media_music.xml
│ │ │ ├── ic_vue_media_photocamera.xml
│ │ │ ├── ic_vue_media_play.xml
│ │ │ ├── ic_vue_media_scissors.xml
│ │ │ ├── ic_vue_media_screenmirroring.xml
│ │ │ ├── ic_vue_media_setting.xml
│ │ │ ├── ic_vue_media_speaker.xml
│ │ │ ├── ic_vue_media_subtitle.xml
│ │ │ ├── ic_vue_media_voice.xml
│ │ │ ├── ic_vue_messages_device_msg.xml
│ │ │ ├── ic_vue_messages_direct.xml
│ │ │ ├── ic_vue_messages_edit.xml
│ │ │ ├── ic_vue_messages_letter.xml
│ │ │ ├── ic_vue_messages_msg.xml
│ │ │ ├── ic_vue_messages_msg_favorite.xml
│ │ │ ├── ic_vue_messages_msg_notification.xml
│ │ │ ├── ic_vue_messages_msg_search.xml
│ │ │ ├── ic_vue_messages_msg_text.xml
│ │ │ ├── ic_vue_messages_msgs.xml
│ │ │ ├── ic_vue_money_archive.xml
│ │ │ ├── ic_vue_money_bitcoin_refresh.xml
│ │ │ ├── ic_vue_money_buy_bitcoin.xml
│ │ │ ├── ic_vue_money_buy_crypto.xml
│ │ │ ├── ic_vue_money_card.xml
│ │ │ ├── ic_vue_money_card_bitcoin.xml
│ │ │ ├── ic_vue_money_card_coin.xml
│ │ │ ├── ic_vue_money_card_receive.xml
│ │ │ ├── ic_vue_money_card_send.xml
│ │ │ ├── ic_vue_money_coins.xml
│ │ │ ├── ic_vue_money_discount.xml
│ │ │ ├── ic_vue_money_dollar.xml
│ │ │ ├── ic_vue_money_math.xml
│ │ │ ├── ic_vue_money_percentage.xml
│ │ │ ├── ic_vue_money_receipt_discount.xml
│ │ │ ├── ic_vue_money_receipt_empty.xml
│ │ │ ├── ic_vue_money_receipt_items.xml
│ │ │ ├── ic_vue_money_recive.xml
│ │ │ ├── ic_vue_money_security_card.xml
│ │ │ ├── ic_vue_money_send.xml
│ │ │ ├── ic_vue_money_tag.xml
│ │ │ ├── ic_vue_money_ticket.xml
│ │ │ ├── ic_vue_money_ticket_discount.xml
│ │ │ ├── ic_vue_money_ticket_star.xml
│ │ │ ├── ic_vue_money_transfer.xml
│ │ │ ├── ic_vue_money_wallet.xml
│ │ │ ├── ic_vue_money_wallet_cards.xml
│ │ │ ├── ic_vue_money_wallet_empty.xml
│ │ │ ├── ic_vue_money_wallet_money.xml
│ │ │ ├── ic_vue_pc_bluetooth.xml
│ │ │ ├── ic_vue_pc_charging.xml
│ │ │ ├── ic_vue_pc_cpu.xml
│ │ │ ├── ic_vue_pc_game.xml
│ │ │ ├── ic_vue_pc_gameboy.xml
│ │ │ ├── ic_vue_pc_headphone.xml
│ │ │ ├── ic_vue_pc_monitor.xml
│ │ │ ├── ic_vue_pc_phone.xml
│ │ │ ├── ic_vue_pc_phone_call.xml
│ │ │ ├── ic_vue_pc_printer.xml
│ │ │ ├── ic_vue_pc_setting.xml
│ │ │ ├── ic_vue_pc_speaker.xml
│ │ │ ├── ic_vue_pc_watch.xml
│ │ │ ├── ic_vue_pc_wifi.xml
│ │ │ ├── ic_vue_people_2persons.xml
│ │ │ ├── ic_vue_people_people.xml
│ │ │ ├── ic_vue_people_person.xml
│ │ │ ├── ic_vue_people_person_search.xml
│ │ │ ├── ic_vue_people_person_tag.xml
│ │ │ ├── ic_vue_security_alarm.xml
│ │ │ ├── ic_vue_security_eye.xml
│ │ │ ├── ic_vue_security_key.xml
│ │ │ ├── ic_vue_security_lock.xml
│ │ │ ├── ic_vue_security_password.xml
│ │ │ ├── ic_vue_security_radar.xml
│ │ │ ├── ic_vue_security_shield.xml
│ │ │ ├── ic_vue_security_shield_person.xml
│ │ │ ├── ic_vue_security_shield_security.xml
│ │ │ ├── ic_vue_shop_bag.xml
│ │ │ ├── ic_vue_shop_bag1.xml
│ │ │ ├── ic_vue_shop_barcode.xml
│ │ │ ├── ic_vue_shop_cart.xml
│ │ │ ├── ic_vue_shop_shop.xml
│ │ │ ├── ic_vue_support_dislike.xml
│ │ │ ├── ic_vue_support_heart.xml
│ │ │ ├── ic_vue_support_like.xml
│ │ │ ├── ic_vue_support_like_dislike.xml
│ │ │ ├── ic_vue_support_medal.xml
│ │ │ ├── ic_vue_support_smileys.xml
│ │ │ ├── ic_vue_support_star.xml
│ │ │ ├── ic_vue_transport_airplane.xml
│ │ │ ├── ic_vue_transport_bus.xml
│ │ │ ├── ic_vue_transport_car.xml
│ │ │ ├── ic_vue_transport_car_wash.xml
│ │ │ ├── ic_vue_transport_gas.xml
│ │ │ ├── ic_vue_transport_ship.xml
│ │ │ ├── ic_vue_transport_train.xml
│ │ │ ├── ic_vue_type_link.xml
│ │ │ ├── ic_vue_type_link2.xml
│ │ │ ├── ic_vue_type_paperclip.xml
│ │ │ ├── ic_vue_type_text.xml
│ │ │ ├── ic_vue_type_textalign_center.xml
│ │ │ ├── ic_vue_type_textalign_justifycenter.xml
│ │ │ ├── ic_vue_type_textalign_left.xml
│ │ │ ├── ic_vue_type_textalign_right.xml
│ │ │ ├── ic_vue_type_translate.xml
│ │ │ ├── ic_vue_weather_cloud.xml
│ │ │ ├── ic_vue_weather_cold.xml
│ │ │ ├── ic_vue_weather_drop.xml
│ │ │ ├── ic_vue_weather_flash.xml
│ │ │ ├── ic_vue_weather_moon.xml
│ │ │ ├── ic_vue_weather_sun.xml
│ │ │ ├── ic_vue_weather_wind.xml
│ │ │ ├── ic_wallet.xml
│ │ │ ├── ic_widget_expense.xml
│ │ │ ├── ic_widget_income.xml
│ │ │ ├── ic_widget_transfer.xml
│ │ │ ├── ic_wishlist.xml
│ │ │ ├── income_shape_widget_background.xml
│ │ │ ├── ivy_wallet_logo.xml
│ │ │ ├── ktw_money_manager_logo.png
│ │ │ ├── no_account_illustration.xml
│ │ │ ├── no_account_illustration_dark.xml
│ │ │ ├── onboarding_illustration_accounts.png
│ │ │ ├── onboarding_illustration_categories.png
│ │ │ ├── onboarding_illustration_import.png
│ │ │ ├── one_money_logo.png
│ │ │ ├── preview_widget_add_trn.png
│ │ │ ├── preview_widget_add_trn_compact.png
│ │ │ ├── preview_widget_wallet_balance.png
│ │ │ ├── questions.png
│ │ │ └── shape_widget_background.xml
│ │ │ ├── font
│ │ │ ├── opensans_bold.ttf
│ │ │ ├── opensans_bolditalic.ttf
│ │ │ ├── opensans_extrabold.ttf
│ │ │ ├── opensans_extrabolditalic.ttf
│ │ │ ├── opensans_italic.ttf
│ │ │ ├── opensans_light.ttf
│ │ │ ├── opensans_lightitalic.ttf
│ │ │ ├── opensans_regular.ttf
│ │ │ ├── opensans_semibold.ttf
│ │ │ ├── opensans_semibolditalic.ttf
│ │ │ ├── raleway_black.ttf
│ │ │ ├── raleway_blackitalic.ttf
│ │ │ ├── raleway_bold.ttf
│ │ │ ├── raleway_bolditalic.ttf
│ │ │ ├── raleway_extrabold.ttf
│ │ │ ├── raleway_extrabolditalic.ttf
│ │ │ ├── raleway_extralight.ttf
│ │ │ ├── raleway_extralightitalic.ttf
│ │ │ ├── raleway_italic.ttf
│ │ │ ├── raleway_light.ttf
│ │ │ ├── raleway_lightitalic.ttf
│ │ │ ├── raleway_medium.ttf
│ │ │ ├── raleway_mediumitalic.ttf
│ │ │ ├── raleway_regular.ttf
│ │ │ ├── raleway_semibold.ttf
│ │ │ ├── raleway_semibolditalic.ttf
│ │ │ ├── raleway_thin.ttf
│ │ │ └── raleway_thinitalic.ttf
│ │ │ ├── values-ar
│ │ │ └── strings.xml
│ │ │ ├── values-bg
│ │ │ └── strings.xml
│ │ │ ├── values-de
│ │ │ └── strings.xml
│ │ │ ├── values-es
│ │ │ └── strings.xml
│ │ │ ├── values-gl
│ │ │ └── strings.xml
│ │ │ ├── values-hi
│ │ │ └── strings.xml
│ │ │ ├── values-id
│ │ │ └── strings.xml
│ │ │ ├── values-in
│ │ │ └── strings.xml
│ │ │ ├── values-it
│ │ │ └── strings.xml
│ │ │ ├── values-kn
│ │ │ └── strings.xml
│ │ │ ├── values-mn
│ │ │ └── strings.xml
│ │ │ ├── values-pl
│ │ │ └── strings.xml
│ │ │ ├── values-pt-rBR
│ │ │ └── strings.xml
│ │ │ ├── values-ru
│ │ │ └── strings.xml
│ │ │ ├── values-vi
│ │ │ └── strings.xml
│ │ │ ├── values-zh-rCN
│ │ │ └── strings.xml
│ │ │ ├── values-zh-rTW
│ │ │ └── strings.xml
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ └── strings.xml
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── ivy
│ │ │ └── ui
│ │ │ ├── FormatMoneyUseCaseTest.kt
│ │ │ ├── PaparazziScreenshotTest.kt
│ │ │ ├── component
│ │ │ └── OpenSourceCardPaparazziTest.kt
│ │ │ └── time
│ │ │ └── impl
│ │ │ └── IvyTimeFormatterTest.kt
│ │ └── snapshots
│ │ └── images
│ │ ├── com.ivy.ui.component_OpenSourceCardPaparazziTest_default state[Dark].png
│ │ └── com.ivy.ui.component_OpenSourceCardPaparazziTest_default state[Light].png
│ ├── navigation
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── navigation
│ │ ├── IvyPreview.kt
│ │ ├── Navigation.kt
│ │ ├── NavigationRoot.kt
│ │ ├── Screen.kt
│ │ └── Screens.kt
│ └── testing
│ ├── build.gradle.kts
│ └── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── ivy
│ │ └── ui
│ │ └── testing
│ │ ├── ComposeViewModelTest.kt
│ │ └── PaparazziScreenshotTest.kt
│ └── test
│ ├── java
│ └── com
│ │ └── ivy
│ │ └── ui
│ │ └── testing
│ │ ├── ComposeViewModelTestExtTest.kt
│ │ ├── DemoPaparazziTest.kt
│ │ └── FakeViewModel.kt
│ └── snapshots
│ └── images
│ ├── com.ivy.ui.testing_DemoPaparazziTest_snapshot demo composable[Dark].png
│ └── com.ivy.ui.testing_DemoPaparazziTest_snapshot demo composable[Light].png
├── temp
├── legacy-code
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── ivy
│ │ └── legacy
│ │ ├── Constants.kt
│ │ ├── IntervalTypeExt.kt
│ │ ├── IvyComposeApp.kt
│ │ ├── IvyWalletCtx.kt
│ │ ├── LoanExt.kt
│ │ ├── LogoutLogic.kt
│ │ ├── android
│ │ └── notification
│ │ │ ├── IvyNotification.kt
│ │ │ ├── IvyNotificationChannel.kt
│ │ │ └── NotificationService.kt
│ │ ├── data
│ │ ├── AppBaseData.kt
│ │ ├── BufferInfo.kt
│ │ ├── DueSection.kt
│ │ ├── EditTransactionDisplayLoan.kt
│ │ ├── datastore
│ │ │ └── IvyDataStore.kt
│ │ └── model
│ │ │ ├── AccountBalance.kt
│ │ │ ├── AccountData.kt
│ │ │ ├── FromToTimeRange.kt
│ │ │ ├── LastNTimeRange.kt
│ │ │ ├── MainTab.kt
│ │ │ ├── Month.kt
│ │ │ └── TimePeriod.kt
│ │ ├── datamodel
│ │ ├── Account.kt
│ │ ├── Budget.kt
│ │ ├── Category.kt
│ │ ├── ExchangeRate.kt
│ │ ├── Loan.kt
│ │ ├── LoanRecord.kt
│ │ ├── PlannedPaymentRule.kt
│ │ ├── Settings.kt
│ │ ├── TransactionExt.kt
│ │ └── temp
│ │ │ ├── AccountExt.kt
│ │ │ ├── BudgetExt.kt
│ │ │ ├── CategoryExt.kt
│ │ │ ├── ExchangeRateExt.kt
│ │ │ ├── LoanExt.kt
│ │ │ ├── LoanRecordExt.kt
│ │ │ ├── PlannedPaymentRuleExt.kt
│ │ │ ├── SettingsExt.kt
│ │ │ └── TransactionExt.kt
│ │ ├── domain
│ │ ├── action
│ │ │ ├── account
│ │ │ │ ├── AccTrnsAct.kt
│ │ │ │ ├── AccountByIdAct.kt
│ │ │ │ ├── AccountsAct.kt
│ │ │ │ ├── CalcAccBalanceAct.kt
│ │ │ │ └── CalcAccIncomeExpenseAct.kt
│ │ │ ├── budget
│ │ │ │ └── BudgetsAct.kt
│ │ │ ├── category
│ │ │ │ ├── CategoryIncomeWithAccountFiltersAct.kt
│ │ │ │ └── CategoryTrnsBetweenAct.kt
│ │ │ ├── exchange
│ │ │ │ └── ExchangeAct.kt
│ │ │ ├── global
│ │ │ │ ├── StartDayOfMonthAct.kt
│ │ │ │ └── UpdateStartDayOfMonthAct.kt
│ │ │ ├── loan
│ │ │ │ ├── LoanByIdAct.kt
│ │ │ │ └── LoansAct.kt
│ │ │ ├── settings
│ │ │ │ ├── BaseCurrencyAct.kt
│ │ │ │ ├── CalcBufferDiffAct.kt
│ │ │ │ ├── SettingsAct.kt
│ │ │ │ └── UpdateSettingsAct.kt
│ │ │ ├── transaction
│ │ │ │ ├── AllTrnsAct.kt
│ │ │ │ ├── CalcTrnsIncomeExpenseAct.kt
│ │ │ │ ├── DueTrnsAct.kt
│ │ │ │ ├── HistoryTrnsAct.kt
│ │ │ │ ├── HistoryWithDateDivsAct.kt
│ │ │ │ ├── TrnByIdAct.kt
│ │ │ │ ├── TrnsWithDateDivsAct.kt
│ │ │ │ └── TrnsWithRangeAndAccFiltersAct.kt
│ │ │ ├── viewmodel
│ │ │ │ ├── account
│ │ │ │ │ └── AccountDataAct.kt
│ │ │ │ ├── home
│ │ │ │ │ ├── DueTrnsInfoAct.kt
│ │ │ │ │ ├── HasTrnsAct.kt
│ │ │ │ │ ├── OverdueAct.kt
│ │ │ │ │ ├── ShouldHideBalanceAct.kt
│ │ │ │ │ ├── ShouldHideIncomeAct.kt
│ │ │ │ │ ├── UpcomingAct.kt
│ │ │ │ │ ├── UpdateAccCacheAct.kt
│ │ │ │ │ └── UpdateCategoriesCacheAct.kt
│ │ │ │ └── transaction
│ │ │ │ │ └── SaveTrnLocallyAct.kt
│ │ │ └── wallet
│ │ │ │ ├── CalcIncomeExpenseAct.kt
│ │ │ │ └── CalcWalletBalanceAct.kt
│ │ ├── data
│ │ │ ├── CustomExchangeRateState.kt
│ │ │ ├── IvyCurrency.kt
│ │ │ ├── Reorderable.kt
│ │ │ ├── SortOrder.kt
│ │ │ └── TransactionHistoryDateDivider.kt
│ │ ├── deprecated
│ │ │ └── logic
│ │ │ │ ├── AccountCreator.kt
│ │ │ │ ├── BudgetCreator.kt
│ │ │ │ ├── CategoryCreator.kt
│ │ │ │ ├── LoanCreator.kt
│ │ │ │ ├── LoanRecordCreator.kt
│ │ │ │ ├── PlannedPaymentsGenerator.kt
│ │ │ │ ├── PlannedPaymentsLogic.kt
│ │ │ │ ├── PreloadDataLogic.kt
│ │ │ │ ├── SmartTitleSuggestionsLogic.kt
│ │ │ │ ├── WalletAccountLogic.kt
│ │ │ │ ├── WalletCategoryLogic.kt
│ │ │ │ ├── csv
│ │ │ │ ├── CSVImporter.kt
│ │ │ │ ├── CSVMapper.kt
│ │ │ │ ├── CSVNormalizer.kt
│ │ │ │ └── model
│ │ │ │ │ ├── ImportType.kt
│ │ │ │ │ └── RowMapping.kt
│ │ │ │ ├── currency
│ │ │ │ └── ExchangeRatesLogic.kt
│ │ │ │ ├── loantrasactions
│ │ │ │ ├── LTLoanMapper.kt
│ │ │ │ ├── LTLoanRecordMapper.kt
│ │ │ │ ├── LoanTransactionsCore.kt
│ │ │ │ └── LoanTransactionsLogic.kt
│ │ │ │ └── model
│ │ │ │ ├── CreateAccountData.kt
│ │ │ │ ├── CreateBudgetData.kt
│ │ │ │ ├── CreateCategoryData.kt
│ │ │ │ ├── CreateLoanData.kt
│ │ │ │ ├── CreateLoanRecordData.kt
│ │ │ │ └── EditLoanRecordData.kt
│ │ └── pure
│ │ │ ├── account
│ │ │ └── AccountFunctions.kt
│ │ │ ├── data
│ │ │ ├── ClosedTimeRange.kt
│ │ │ ├── IncomeExpensePair.kt
│ │ │ ├── IncomeExpenseTransferPair.kt
│ │ │ └── WalletDAOs.kt
│ │ │ ├── exchange
│ │ │ ├── Exchange.kt
│ │ │ └── ExchangeTrns.kt
│ │ │ ├── transaction
│ │ │ ├── AccountValueFunctions.kt
│ │ │ ├── CatValueFunctions.kt
│ │ │ ├── FoldTransactions.kt
│ │ │ ├── TrnDateDividers.kt
│ │ │ ├── TrnFunctions.kt
│ │ │ └── WalletValueFunctions.kt
│ │ │ └── util
│ │ │ ├── IvyDomainUtils.kt
│ │ │ └── Utils.kt
│ │ ├── frp
│ │ ├── Annotations.kt
│ │ ├── Composition.kt
│ │ ├── Composition2.kt
│ │ ├── CompositionN.kt
│ │ ├── OnScreenStart.kt
│ │ ├── Utils.kt
│ │ ├── action
│ │ │ ├── Action.kt
│ │ │ ├── CompositionFilter.kt
│ │ │ ├── CompositionMap.kt
│ │ │ ├── CompositionSum.kt
│ │ │ └── FPAction.kt
│ │ ├── monad
│ │ │ ├── Res.kt
│ │ │ └── ResComposition.kt
│ │ ├── test
│ │ │ ├── TestIdlingResource.kt
│ │ │ └── TestingContext.kt
│ │ ├── view
│ │ │ └── FRPComposable.kt
│ │ └── viewmodel
│ │ │ ├── FRPViewModel.kt
│ │ │ └── ViewmodelUtils.kt
│ │ ├── legacy
│ │ └── ui
│ │ │ ├── IvyColorPicker.kt
│ │ │ └── theme
│ │ │ ├── IvyColors.kt
│ │ │ ├── components
│ │ │ ├── AddPrimaryAttributeButton.kt
│ │ │ ├── BackBottomBar.kt
│ │ │ ├── BalanceRow.kt
│ │ │ ├── BudgetBattery.kt
│ │ │ ├── BufferBattery.kt
│ │ │ ├── ChangeTransactionTypeModal.kt
│ │ │ ├── CircleButtons.kt
│ │ │ ├── CurrencyPicker.kt
│ │ │ ├── CustomExchangeRateCard.kt
│ │ │ ├── DateTimeRow.kt
│ │ │ ├── DeleteButton.kt
│ │ │ ├── GradientCut.kt
│ │ │ ├── IntervalPickerRow.kt
│ │ │ ├── ItemIcon.kt
│ │ │ ├── IvyBasicTextField.kt
│ │ │ ├── IvyBorderButton.kt
│ │ │ ├── IvyButton.kt
│ │ │ ├── IvyCheckbox.kt
│ │ │ ├── IvyChecklistTextField.kt
│ │ │ ├── IvyCircleButton.kt
│ │ │ ├── IvyComponents.kt
│ │ │ ├── IvyDescriptionTextField.kt
│ │ │ ├── IvyDivider.kt
│ │ │ ├── IvyDividerDot.kt
│ │ │ ├── IvyIcon.kt
│ │ │ ├── IvyNameTextFieldValue.kt
│ │ │ ├── IvyNumberTextField.kt
│ │ │ ├── IvyOutlinedButton.kt
│ │ │ ├── IvyOutlinedTextField.kt
│ │ │ ├── IvySwitch.kt
│ │ │ ├── IvyTitleTextField.kt
│ │ │ ├── IvyToolbar.kt
│ │ │ ├── ListItem.kt
│ │ │ ├── OnboardingComponents.kt
│ │ │ ├── ProgressBar.kt
│ │ │ ├── ReorderModal.kt
│ │ │ ├── WrapContentRow.kt
│ │ │ └── charts
│ │ │ │ └── linechart
│ │ │ │ └── IvyLineChart.kt
│ │ │ ├── modal
│ │ │ ├── AddKeywordModal.kt
│ │ │ ├── BufferModal.kt
│ │ │ ├── ChooseIconModal.kt
│ │ │ ├── ChoosePeriodModal.kt
│ │ │ ├── ChooseStartDateOfMonthModal.kt
│ │ │ ├── CurrencyModal.kt
│ │ │ ├── DeleteModal.kt
│ │ │ ├── IvyModal.kt
│ │ │ ├── IvyModalComponents.kt
│ │ │ ├── IvyModalDomainComponents.kt
│ │ │ ├── LegacyModals.kt
│ │ │ ├── LoanModal.kt
│ │ │ ├── LoanRecordModal.kt
│ │ │ ├── MonthPickerModal.kt
│ │ │ ├── NameModal.kt
│ │ │ ├── ProgressModal.kt
│ │ │ ├── RecurringRuleModal.kt
│ │ │ └── edit
│ │ │ │ ├── AccountModal.kt
│ │ │ │ ├── AmountModal.kt
│ │ │ │ ├── CalculatorModal.kt
│ │ │ │ ├── CategoryModal.kt
│ │ │ │ ├── ChooseCategoryModal.kt
│ │ │ │ └── DescriptionModal.kt
│ │ │ └── wallet
│ │ │ ├── AmountCurrency.kt
│ │ │ └── PeriodSelector.kt
│ │ ├── notification
│ │ ├── TransactionReminderLogic.kt
│ │ └── TransactionReminderWorker.kt
│ │ ├── ui
│ │ ├── SearchInput.kt
│ │ └── component
│ │ │ ├── IncomeExpenseCards.kt
│ │ │ ├── ItemStatisticToolbar.kt
│ │ │ ├── edit
│ │ │ ├── PrimaryAttributeColumn.kt
│ │ │ ├── TransactionDateTime.kt
│ │ │ └── core
│ │ │ │ ├── Category.kt
│ │ │ │ ├── Description.kt
│ │ │ │ ├── DueDate.kt
│ │ │ │ ├── EditBottomSheet.kt
│ │ │ │ ├── Title.kt
│ │ │ │ └── Toolbar.kt
│ │ │ ├── tags
│ │ │ ├── AddOrEditTagModal.kt
│ │ │ ├── AddTagButton.kt
│ │ │ └── ShowTagModal.kt
│ │ │ └── transaction
│ │ │ ├── HistoryDateDivider.kt
│ │ │ ├── TransactionCard.kt
│ │ │ ├── TransactionSectionDivider.kt
│ │ │ ├── Transactions.kt
│ │ │ ├── TransactionsDividerLine.kt
│ │ │ └── Utils.kt
│ │ └── utils
│ │ ├── ActivityResultExt.kt
│ │ ├── AmountFormatting.kt
│ │ ├── ComposeExt.kt
│ │ ├── DateExt.kt
│ │ ├── FirebaseExt.kt
│ │ ├── GesturesExt.kt
│ │ ├── InputError.kt
│ │ ├── IvyAnimation.kt
│ │ ├── MVVMExt.kt
│ │ ├── OpResult.kt
│ │ ├── UIExt.kt
│ │ ├── UiText.kt
│ │ ├── UtilExt.kt
│ │ ├── ValidationExt.kt
│ │ └── WalletUtil.kt
└── old-design
│ ├── build.gradle.kts
│ └── src
│ └── main
│ ├── java
│ └── com
│ │ └── ivy
│ │ └── design
│ │ ├── IvyColorPicker.kt
│ │ ├── IvyContext.kt
│ │ ├── api
│ │ ├── IvyDesign.kt
│ │ ├── IvyUI.kt
│ │ └── systems
│ │ │ └── IvyWalletDesign.kt
│ │ ├── l0_system
│ │ ├── Colors.kt
│ │ ├── IvyColors.kt
│ │ ├── IvyShapes.kt
│ │ ├── IvyTheme.kt
│ │ ├── IvyTypography.kt
│ │ └── TypographyExt.kt
│ │ ├── l1_buildingBlocks
│ │ ├── ColumnRoot.kt
│ │ ├── Dividers.kt
│ │ ├── IvyIcon.kt
│ │ ├── IvyText.kt
│ │ ├── Shapes.kt
│ │ ├── Spacers.kt
│ │ └── data
│ │ │ ├── Background.kt
│ │ │ └── IvyPadding.kt
│ │ ├── l2_components
│ │ ├── Button.kt
│ │ ├── ButtonWithIcon.kt
│ │ ├── Checkbox.kt
│ │ ├── IconButton.kt
│ │ ├── InputField.kt
│ │ └── Switch.kt
│ │ ├── l3_ivyComponents
│ │ └── ScreenTitle.kt
│ │ └── utils
│ │ ├── Android.kt
│ │ ├── Animation.kt
│ │ ├── Compose.kt
│ │ ├── Insets.kt
│ │ ├── Keyboard.kt
│ │ ├── Padding.kt
│ │ ├── Preview.kt
│ │ └── View.kt
│ └── res
│ ├── drawable
│ ├── ic_android_black_24dp.xml
│ ├── ic_baseline_add_24.xml
│ ├── ic_checkbox_checked.xml
│ └── ic_checkbox_unchecked.xml
│ ├── font
│ ├── opensans_bold.ttf
│ ├── opensans_bolditalic.ttf
│ ├── opensans_extrabold.ttf
│ ├── opensans_extrabolditalic.ttf
│ ├── opensans_italic.ttf
│ ├── opensans_light.ttf
│ ├── opensans_lightitalic.ttf
│ ├── opensans_regular.ttf
│ ├── opensans_semibold.ttf
│ ├── opensans_semibolditalic.ttf
│ ├── raleway_black.ttf
│ ├── raleway_blackitalic.ttf
│ ├── raleway_bold.ttf
│ ├── raleway_bolditalic.ttf
│ ├── raleway_extrabold.ttf
│ ├── raleway_extrabolditalic.ttf
│ ├── raleway_extralight.ttf
│ ├── raleway_extralightitalic.ttf
│ ├── raleway_italic.ttf
│ ├── raleway_light.ttf
│ ├── raleway_lightitalic.ttf
│ ├── raleway_medium.ttf
│ ├── raleway_mediumitalic.ttf
│ ├── raleway_regular.ttf
│ ├── raleway_semibold.ttf
│ ├── raleway_semibolditalic.ttf
│ ├── raleway_thin.ttf
│ └── raleway_thinitalic.ttf
│ └── values
│ └── colors.xml
└── widget
├── add-transaction
├── build.gradle.kts
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── ivy
│ │ └── widget
│ │ └── transaction
│ │ ├── AddTransactionWidget.kt
│ │ ├── AddTransactionWidgetClick.kt
│ │ └── AddTransactionWidgetCompact.kt
│ └── res
│ ├── drawable
│ └── widget_compact_divider.xml
│ ├── layout
│ ├── widget_add_transaction.xml
│ └── widget_add_transaction_compact.xml
│ └── xml
│ ├── add_transaction_widget_compact_info.xml
│ ├── add_transaction_widget_info.xml
│ └── wallet_balance_widget_info.xml
├── balance
├── build.gradle.kts
└── src
│ └── main
│ └── java
│ └── com
│ └── ivy
│ └── widget
│ └── balance
│ ├── WalletBalanceWidget.kt
│ └── WalletBalanceWidgetContent.kt
└── shared-base
├── build.gradle.kts
└── src
└── main
└── java
└── com
└── ivy
└── widget
└── WidgetBase.kt
/.gitattributes:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/.gitattributes
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @ILIYANGERMANOV
2 |
--------------------------------------------------------------------------------
/.github/workflows/paparazzi_screenshot_test.yml:
--------------------------------------------------------------------------------
1 | name: Paparazzi screenshots tests
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 |
9 | jobs:
10 | sceenshot_test:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout GIT
14 | uses: actions/checkout@v4
15 |
16 | - name: Setup Java SDK
17 | uses: actions/setup-java@v4
18 | with:
19 | distribution: 'adopt'
20 | java-version: '18'
21 |
22 | - name: Gradle cache
23 | uses: gradle/actions/setup-gradle@v4
24 |
25 | - name: Run Paparazzi screenshot tests
26 | run: ./gradlew verifyPaparazziDebug
27 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: 'Close Stale Issues and PRs'
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: '0 8 * * *'
7 |
8 | permissions:
9 | contents: write
10 | issues: write
11 | pull-requests: write
12 |
13 | jobs:
14 | stale:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - uses: actions/stale@v9
18 | with:
19 | days-before-issue-stale: 30
20 | days-before-issue-close: 7
21 | days-before-pr-stale: 2
22 | days-before-pr-close: 1
23 | exempt-issue-labels: keep,P0,bug
24 | exempt-pr-labels: keep,P0
25 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # GitHub Copilot persisted chat sessions
5 | /copilot/chatSessions
6 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | IvyWallet
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/migrations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "fastlane"
4 |
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/app/src/main/java/com/ivy/wallet/di/AppBindingsModule.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.di
2 |
3 | import com.ivy.domain.AppStarter
4 | import com.ivy.wallet.IvyAppStarter
5 | import dagger.Binds
6 | import dagger.Module
7 | import dagger.hilt.InstallIn
8 | import dagger.hilt.components.SingletonComponent
9 |
10 | @Module
11 | @InstallIn(SingletonComponent::class)
12 | abstract class AppBindingsModule {
13 | @Binds
14 | abstract fun appStarter(appStarter: IvyAppStarter): AppStarter
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/ivy/wallet/migrations/Migration.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.migrations
2 |
3 | interface Migration {
4 | val key: String
5 |
6 | suspend fun migrate()
7 | }
8 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/resources.properties:
--------------------------------------------------------------------------------
1 | unqualifiedResLocale=en-US
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-hdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-hdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-hdpi/ic_launcher_monochrome.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-hdpi/ic_launcher_monochrome.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-mdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-mdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-mdpi/ic_launcher_monochrome.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-mdpi/ic_launcher_monochrome.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-xhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-xhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-xhdpi/ic_launcher_monochrome.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-xhdpi/ic_launcher_monochrome.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-xxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-xxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-xxhdpi/ic_launcher_monochrome.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-xxhdpi/ic_launcher_monochrome.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-xxxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-xxxhdpi/ic_launcher_monochrome.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-xxxhdpi/ic_launcher_monochrome.webp
--------------------------------------------------------------------------------
/app/src/release/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/app/src/release/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/release/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #F3FFF6
4 |
--------------------------------------------------------------------------------
/buildSrc/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google()
4 | gradlePluginPortal()
5 | }
6 | }
7 |
8 | dependencyResolutionManagement {
9 | repositories {
10 | google()
11 | gradlePluginPortal()
12 | }
13 |
14 | versionCatalogs {
15 | create("libs") {
16 | from(files("../gradle/libs.versions.toml"))
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/ivy.feature.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | org.jetbrains.kotlin.plugin.compose
3 | id("ivy.module")
4 | id("ivy.compose")
5 | id("ivy.paparazzi")
6 | }
7 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/ivy.hilt.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.kotlin-android")
3 | id("dagger.hilt.android.plugin")
4 | id("com.google.devtools.ksp")
5 | }
6 |
7 | kotlin {
8 | sourceSets.all {
9 | kotlin.srcDir("build/generated/ksp/$name/kotlin")
10 | }
11 | }
12 |
13 | dependencies {
14 | implementation(libs.bundles.hilt)
15 | ksp(catalog.library("hilt-compiler"))
16 | }
17 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/ivy.integration.testing.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | defaultConfig {
7 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
8 | }
9 |
10 | packaging {
11 | resources.pickFirsts.apply {
12 | add("win32-x86-64/attach_hotspot_windows.dll")
13 | add("win32-x86/attach_hotspot_windows.dll")
14 | add("META-INF/**")
15 | add("xsd/catalog.xml")
16 | }
17 | }
18 | }
19 |
20 | dependencies {
21 | androidTestImplementation(libs.bundles.integration.testing)
22 | }
23 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/ivy.kotlinx-serialization.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.kotlin-android")
3 | id("org.jetbrains.kotlin.plugin.serialization")
4 | }
5 |
6 | dependencies {
7 | implementation(catalog.library("kotlinx-serialization-json"))
8 | }
9 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/ivy.module.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.kotlin-android")
3 | id("ivy.hilt")
4 | id("ivy.kotlinx-serialization")
5 | }
6 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/ivy.room.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.module")
3 | id("androidx.room")
4 | }
5 |
6 | dependencies {
7 | implementation(libs.bundles.room)
8 | ksp(libs.room.compiler)
9 |
10 | androidTestImplementation(libs.room.testing)
11 | }
12 |
13 | android {
14 | sourceSets {
15 | // Adds exported schema location as test app assets.
16 | getByName("androidTest").assets.srcDirs(files("$projectDir/schemas"))
17 | }
18 | }
19 |
20 | room {
21 | schemaDirectory("$projectDir/schemas")
22 | }
23 |
--------------------------------------------------------------------------------
/buildSrc/src/main/kotlin/ivy.widget.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.module")
3 | org.jetbrains.kotlin.plugin.compose
4 | }
5 |
6 | android {
7 | // Compose
8 | buildFeatures {
9 | compose = true
10 | }
11 | }
12 |
13 | dependencies {
14 | implementation(libs.bundles.glance)
15 | implementation(libs.bundles.activity)
16 | }
17 |
--------------------------------------------------------------------------------
/ci-actions/base/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.script")
3 | }
4 |
5 | dependencies {
6 | api(libs.bundles.ktor)
7 | }
8 |
--------------------------------------------------------------------------------
/ci-actions/base/src/main/kotlin/ivy/automate/base/ArrowExt.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.base
2 |
3 | import arrow.core.Either
4 |
5 | fun Either.getOrThrow(): B {
6 | return fold(
7 | ifLeft = { throw IvyError(it.toString()) },
8 | ifRight = { it }
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/ci-actions/base/src/main/kotlin/ivy/automate/base/Common.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.base
2 |
3 | import arrow.core.Either
4 | import kotlinx.coroutines.Dispatchers
5 | import kotlinx.coroutines.withContext
6 |
7 | @DslMarker
8 | annotation class IvyDsl
9 |
10 | suspend fun catchIO(
11 | block: suspend () -> A
12 | ): Either = Either.catch {
13 | withContext(Dispatchers.IO) {
14 | block()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ci-actions/base/src/main/kotlin/ivy/automate/base/Constants.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.base
2 |
3 | object Constants {
4 | const val IVY_ADMIN = "ILIYANGERMANOV"
5 | const val ARG_GITHUB_PAT = "gitHubPAT"
6 | const val ARG_ISSUE_NUMBER = "issueNumber"
7 | const val IVY_BOT_USERNAME = "ivywallet"
8 |
9 | const val ISSUES_URL = "https://github.com/Ivy-Apps/ivy-wallet/issues"
10 | const val CONTRIBUTING_URL = "https://github.com/Ivy-Apps/ivy-wallet/blob/main/CONTRIBUTING.md"
11 | }
12 |
--------------------------------------------------------------------------------
/ci-actions/base/src/main/kotlin/ivy/automate/base/IvyError.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.base
2 |
3 | class IvyError(msg: String) : Exception(msg)
4 |
--------------------------------------------------------------------------------
/ci-actions/base/src/main/kotlin/ivy/automate/base/github/model/GitHubComment.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.base.github.model
2 |
3 | data class GitHubComment(
4 | val author: GitHubUser,
5 | val text: String,
6 | )
7 |
--------------------------------------------------------------------------------
/ci-actions/base/src/main/kotlin/ivy/automate/base/github/model/GitHubIssue.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.base.github.model
2 |
3 | data class GitHubIssue(
4 | val number: GitHubIssueNumber,
5 | val creator: GitHubUser,
6 | val assignee: GitHubUser?
7 | )
8 |
--------------------------------------------------------------------------------
/ci-actions/base/src/main/kotlin/ivy/automate/base/github/model/GitHubLabel.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.base.github.model
2 |
3 | data class GitHubLabel(
4 | val name: GitHubLabelName,
5 | )
6 |
--------------------------------------------------------------------------------
/ci-actions/base/src/main/kotlin/ivy/automate/base/github/model/GitHubLabelName.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.base.github.model
2 |
3 | import arrow.core.raise.Raise
4 | import arrow.core.raise.ensure
5 | import ivy.automate.base.Exact
6 |
7 | @JvmInline
8 | value class GitHubLabelName private constructor(val value: String) {
9 | companion object : Exact {
10 | override val exactName: String = "GitHubLabelName"
11 |
12 | override fun Raise.spec(raw: String): GitHubLabelName {
13 | ensure(raw.isNotBlank()) { "Cannot be blank" }
14 | return GitHubLabelName(raw.trim())
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ci-actions/base/src/main/kotlin/ivy/automate/base/github/model/GitHubPAT.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.base.github.model
2 |
3 | import arrow.core.raise.Raise
4 | import arrow.core.raise.ensure
5 | import ivy.automate.base.Exact
6 |
7 | @JvmInline
8 | value class GitHubPAT private constructor(val value: String) {
9 | companion object : Exact {
10 | override val exactName: String = "GitHubPAT"
11 |
12 | override fun Raise.spec(raw: String): GitHubPAT {
13 | ensure(raw.isNotBlank()) { "Cannot be blank" }
14 | return GitHubPAT(raw.trim())
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ci-actions/base/src/main/kotlin/ivy/automate/base/github/model/GitHubUser.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.base.github.model
2 |
3 | data class GitHubUser(
4 | val username: GitHubUsername
5 | )
6 |
--------------------------------------------------------------------------------
/ci-actions/base/src/main/kotlin/ivy/automate/base/github/model/GitHubUsername.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.base.github.model
2 |
3 | import arrow.core.raise.Raise
4 | import arrow.core.raise.ensure
5 | import ivy.automate.base.Exact
6 |
7 | @JvmInline
8 | value class GitHubUsername private constructor(val value: String) {
9 | companion object : Exact {
10 | override val exactName: String = "GitHubUsername"
11 |
12 | override fun Raise.spec(raw: String): GitHubUsername {
13 | ensure(raw.isNotBlank()) { "Cannot be blank" }
14 | return GitHubUsername(raw.trim())
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ci-actions/compose-stability/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.script")
3 | application
4 | }
5 |
6 | application {
7 | mainClass = "ivy.automate.compose.stability.MainKt"
8 | }
9 |
10 | dependencies {
11 | implementation(projects.ciActions.base)
12 | }
13 |
--------------------------------------------------------------------------------
/ci-actions/compose-stability/src/main/kotlin/ivy/automate/compose/stability/model/UnstableComposable.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.compose.stability.model
2 |
3 | typealias FullyQualifiedName = String
4 |
5 | data class UnstableComposable(
6 | val fullyQualifiedName: FullyQualifiedName,
7 | val name: String,
8 | val skippable: Boolean,
9 | val restartable: Boolean,
10 | val unstableArguments: Set
11 | )
12 |
13 | data class ComposableArgument(
14 | val name: String,
15 | val type: String
16 | )
--------------------------------------------------------------------------------
/ci-actions/issue-assign/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.script")
3 | application
4 | }
5 |
6 | application {
7 | mainClass = "ivy.automate.issue.MainKt"
8 | }
9 |
10 | dependencies {
11 | implementation(projects.ciActions.base)
12 | }
13 |
--------------------------------------------------------------------------------
/ci-actions/issue-create-comment/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.script")
3 | application
4 | }
5 |
6 | application {
7 | mainClass = "ivy.automate.issue.create.MainKt"
8 | }
9 |
10 | dependencies {
11 | implementation(projects.ciActions.base)
12 | }
13 |
--------------------------------------------------------------------------------
/ci-actions/pr-description-check/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.script")
3 | application
4 | }
5 |
6 | application {
7 | mainClass = "ivy.automate.pr.MainKt"
8 | }
9 |
10 | dependencies {
11 | implementation(projects.ciActions.base)
12 | }
13 |
--------------------------------------------------------------------------------
/ci-actions/pr-description-check/src/main/kotlin/ivy/automate/pr/PRDescriptionAnalyzer.kt:
--------------------------------------------------------------------------------
1 | package ivy.automate.pr
2 |
3 | import arrow.core.Either
4 |
5 | interface PRDescriptionAnalyzer {
6 | fun analyze(prDescription: String): Either
7 | }
--------------------------------------------------------------------------------
/debug.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/debug.jks
--------------------------------------------------------------------------------
/docs/assets/app-layers.d2:
--------------------------------------------------------------------------------
1 | data: "Data Layer" {
2 | crud: "CRUD + Validation" {
3 | ds: "DataSource"
4 | r: "Repository"
5 | r -> ds
6 | }
7 | }
8 | domain: "Domain Layer" {
9 | "Business logic" {
10 | "Uses repositories to do smart things"
11 | }
12 | }
13 | ui: "UI Layer" {
14 | "Screens" {
15 | ui: "Compose UI"
16 | vm: "ViewModel"
17 | ui -> vm: "UiEvents"
18 | vm -> ui: "UiState"
19 | }
20 | }
21 |
22 | ui -> domain -> data
23 | ui -> data
24 |
--------------------------------------------------------------------------------
/docs/assets/data-mapping.d2:
--------------------------------------------------------------------------------
1 | direction: right
2 |
3 | raw: "Raw data models" {
4 | "DTOs"
5 | "Entities"
6 | "Bytes"
7 | }
8 | domain: "Domain models" {
9 | "ADTs"
10 | "Explicit and exact"
11 | "Validated"
12 | }
13 | uiState: "ViewState models" {
14 | "*ViewState"
15 | "UI models: formatted and ready to display"
16 | "Optimized for Compose"
17 | }
18 |
19 | repo: "Repository"
20 | vm: "ViewModel"
21 |
22 | raw -> repo: "raw"
23 | repo -> domain: "domain"
24 | domain -> vm: "domain"
25 | vm -> uiState: "viewState"
26 |
27 |
28 |
--------------------------------------------------------------------------------
/docs/assets/screen-vm.d2:
--------------------------------------------------------------------------------
1 | direction: right
2 | ui: "Compose UI" {
3 | "Draws UiState"
4 | "Sends UiEvents"
5 | }
6 | vm: "ViewModel" {
7 | "Provides UiState"
8 | "Handles UiEvents"
9 | }
10 |
11 | ui <- vm: "UiState"
12 | ui -> vm: "UiEvent"
--------------------------------------------------------------------------------
/docs/guidelines/README.md:
--------------------------------------------------------------------------------
1 | # 🏗️ Guidelines Wiki
2 |
3 | This is Ivy Wallet's Developer Guidelines wiki. We recommend the following reading order:
4 |
5 | 1. **[Data Modeling](./Data-Modeling.md)**
6 | 2. **[Error Handling](./Error-Handling.md)**
7 | 3. **[Architecture](./Architecture.md)**
8 | 4. **[Screen Architecture](./Screen-Architecture.md)**
9 | 5. **[Unit Testing](./Unit-Testing.md)**
10 | 6. **[Screenshot Testing](./Screenshot-Testing.md)**
11 |
--------------------------------------------------------------------------------
/docs/guidelines/Screenshot-Testing.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/docs/guidelines/Screenshot-Testing.md
--------------------------------------------------------------------------------
/docs/resources/Docs.md:
--------------------------------------------------------------------------------
1 | # Official Docs
2 |
3 | - [Guide to app architecture by Google](https://developer.android.com/topic/architecture)
4 | - [Jetpack Compose](https://developer.android.com/jetpack/compose)
5 | - [Room DB](https://developer.android.com/training/data-storage/room)
6 | - [DataStore](https://developer.android.com/topic/libraries/architecture/datastore)
--------------------------------------------------------------------------------
/docs/resources/README.md:
--------------------------------------------------------------------------------
1 | # Resources 📚
2 |
3 | Here you can find various programming resources that we found useful.
4 | Before you explore them we recommend checking our own **[Developer Guidelines 🏗️](../Guidelines.md)** for a quick start
5 | with core concepts and ideas. Then you can deep dive with:
6 |
7 | - [Videos](Videos.md)
8 | - [Books](Books.md)
9 | - [Blog articles](Blog-Articles.md)
10 | - [Official documentation](Docs.md)
11 |
--------------------------------------------------------------------------------
/fastlane/Appfile:
--------------------------------------------------------------------------------
1 | json_key_file("google-play-console-user.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
2 | package_name("com.ivy.wallet") # e.g. com.krausefx.app
3 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-GB/changelogs/default.txt:
--------------------------------------------------------------------------------
1 | Ivy Wallet periodic release, refer to (https://github.com/Ivy-Apps/ivy-wallet/releases) for changelog. If you find any issues, please report them in our GitHub repository.
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
5 | networkTimeout=10000
6 | validateDistributionUrl=true
7 | zipStoreBase=GRADLE_USER_HOME
8 | zipStorePath=wrapper/dists
9 |
--------------------------------------------------------------------------------
/screen/accounts/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.accounts"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 |
18 | testImplementation(projects.shared.ui.testing)
19 | }
20 |
--------------------------------------------------------------------------------
/screen/accounts/src/main/java/com/ivy/accounts/AccountsEvent.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.accounts
2 |
3 | sealed interface AccountsEvent {
4 | data class OnReorder(val reorderedList: List) :
5 | AccountsEvent
6 | data class OnReorderModalVisible(val reorderVisible: Boolean) : AccountsEvent
7 | }
8 |
--------------------------------------------------------------------------------
/screen/accounts/src/test/snapshots/images/com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab compact composable[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/accounts/src/test/snapshots/images/com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab compact composable[Dark].png
--------------------------------------------------------------------------------
/screen/accounts/src/test/snapshots/images/com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab compact composable[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/accounts/src/test/snapshots/images/com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab compact composable[Light].png
--------------------------------------------------------------------------------
/screen/accounts/src/test/snapshots/images/com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab composable[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/accounts/src/test/snapshots/images/com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab composable[Dark].png
--------------------------------------------------------------------------------
/screen/accounts/src/test/snapshots/images/com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab composable[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/accounts/src/test/snapshots/images/com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab composable[Light].png
--------------------------------------------------------------------------------
/screen/accounts/src/test/snapshots/images/com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab nonCompact composable[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/accounts/src/test/snapshots/images/com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab nonCompact composable[Dark].png
--------------------------------------------------------------------------------
/screen/accounts/src/test/snapshots/images/com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab nonCompact composable[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/accounts/src/test/snapshots/images/com.ivy.accounts_AccountsTabPaparazziTest_snapshot accountTab nonCompact composable[Light].png
--------------------------------------------------------------------------------
/screen/attributions/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.attributions"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.domain)
12 | implementation(projects.shared.ui.core)
13 | implementation(projects.shared.ui.navigation)
14 |
15 | testImplementation(projects.shared.ui.testing)
16 | }
17 |
--------------------------------------------------------------------------------
/screen/attributions/src/main/java/com/ivy/attributions/AttributionItem.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.attributions
2 |
3 | sealed interface AttributionItem {
4 | data class Attribution(val name: String, val link: String) : AttributionItem
5 | data class Divider(val sectionName: String) : AttributionItem
6 | }
7 |
--------------------------------------------------------------------------------
/screen/attributions/src/main/java/com/ivy/attributions/AttributionsEvent.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.attributions
2 |
3 | sealed interface AttributionsEvent
4 |
--------------------------------------------------------------------------------
/screen/attributions/src/main/java/com/ivy/attributions/AttributionsState.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.attributions
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | data class AttributionsState(
6 | val attributionItems: ImmutableList
7 | )
8 |
--------------------------------------------------------------------------------
/screen/attributions/src/test/snapshots/images/com.ivy.attributions_AttributionsScreenPaparazziTest_snapshot Attribution Screen[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/attributions/src/test/snapshots/images/com.ivy.attributions_AttributionsScreenPaparazziTest_snapshot Attribution Screen[Dark].png
--------------------------------------------------------------------------------
/screen/attributions/src/test/snapshots/images/com.ivy.attributions_AttributionsScreenPaparazziTest_snapshot Attribution Screen[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/attributions/src/test/snapshots/images/com.ivy.attributions_AttributionsScreenPaparazziTest_snapshot Attribution Screen[Light].png
--------------------------------------------------------------------------------
/screen/balance/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.balance"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.domain)
12 | implementation(projects.shared.ui.core)
13 | implementation(projects.shared.ui.navigation)
14 | implementation(projects.temp.legacyCode)
15 | implementation(projects.temp.oldDesign)
16 |
17 | testImplementation(projects.shared.ui.testing)
18 | }
--------------------------------------------------------------------------------
/screen/balance/src/main/java/com/ivy/balance/BalanceEvent.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.balance
2 |
3 | import com.ivy.legacy.data.model.TimePeriod
4 |
5 | sealed interface BalanceEvent {
6 | data class OnSetPeriod(val timePeriod: TimePeriod) : BalanceEvent
7 | data object OnPreviousMonth : BalanceEvent
8 | data object OnNextMonth : BalanceEvent
9 | }
10 |
--------------------------------------------------------------------------------
/screen/balance/src/main/java/com/ivy/balance/BalanceState.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.balance
2 |
3 | import androidx.compose.runtime.Immutable
4 | import com.ivy.legacy.data.model.TimePeriod
5 |
6 | @Immutable
7 | data class BalanceState(
8 | val period: TimePeriod,
9 | val baseCurrencyCode: String,
10 | val currentBalance: Double,
11 | val plannedPaymentsAmount: Double,
12 | val balanceAfterPlannedPayments: Double
13 | )
14 |
--------------------------------------------------------------------------------
/screen/balance/src/test/snapshots/images/com.ivy.balance_BalanceScreenPaparazziTest_snapshot Balance Screen[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/balance/src/test/snapshots/images/com.ivy.balance_BalanceScreenPaparazziTest_snapshot Balance Screen[Dark].png
--------------------------------------------------------------------------------
/screen/balance/src/test/snapshots/images/com.ivy.balance_BalanceScreenPaparazziTest_snapshot Balance Screen[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/balance/src/test/snapshots/images/com.ivy.balance_BalanceScreenPaparazziTest_snapshot Balance Screen[Light].png
--------------------------------------------------------------------------------
/screen/budgets/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.budgets"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 |
18 | testImplementation(projects.shared.ui.testing)
19 | }
20 |
--------------------------------------------------------------------------------
/screen/budgets/src/main/java/com/ivy/budgets/BudgetExt.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.budgets
2 |
3 | import com.ivy.base.legacy.stringRes
4 | import com.ivy.ui.R
5 |
6 | fun determineBudgetType(categoriesCount: Int): String {
7 | return when (categoriesCount) {
8 | 0 -> stringRes(R.string.total_budget)
9 | 1 -> stringRes(R.string.category_budget)
10 | else -> stringRes(R.string.multi_category_budget, categoriesCount.toString())
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/screen/categories/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.categories"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 |
18 | testImplementation(projects.shared.ui.testing)
19 | }
--------------------------------------------------------------------------------
/screen/categories/src/main/java/com/ivy/categories/CategoryData.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.categories
2 |
3 | import com.ivy.data.model.Category
4 | import com.ivy.wallet.domain.data.Reorderable
5 |
6 | data class CategoryData(
7 | val category: Category,
8 | val monthlyBalance: Double,
9 | val monthlyExpenses: Double,
10 | val monthlyIncome: Double
11 | ) : Reorderable {
12 | override fun getItemOrderNum() = category.orderNum
13 |
14 | override fun withNewOrderNum(newOrderNum: Double) = this.copy(
15 | category = category.copy(
16 | orderNum = newOrderNum
17 | )
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories Screen[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories Screen[Dark].png
--------------------------------------------------------------------------------
/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories Screen[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories Screen[Light].png
--------------------------------------------------------------------------------
/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories compact Screen with search bar[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories compact Screen with search bar[Dark].png
--------------------------------------------------------------------------------
/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories compact Screen with search bar[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories compact Screen with search bar[Light].png
--------------------------------------------------------------------------------
/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories compact Screen[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories compact Screen[Dark].png
--------------------------------------------------------------------------------
/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories compact Screen[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories compact Screen[Light].png
--------------------------------------------------------------------------------
/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories nonCompact Screen with search bar[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories nonCompact Screen with search bar[Dark].png
--------------------------------------------------------------------------------
/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories nonCompact Screen with search bar[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories nonCompact Screen with search bar[Light].png
--------------------------------------------------------------------------------
/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories nonCompact Screen[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories nonCompact Screen[Dark].png
--------------------------------------------------------------------------------
/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories nonCompact Screen[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/categories/src/test/snapshots/images/com.ivy.categories_CategoriesScreenPaparazziTest_snapshot Categories nonCompact Screen[Light].png
--------------------------------------------------------------------------------
/screen/contributors/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.contributors"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.domain)
12 | implementation(projects.shared.ui.core)
13 | implementation(projects.shared.ui.navigation)
14 |
15 | implementation(libs.bundles.ktor)
16 |
17 | testImplementation(projects.shared.ui.testing)
18 | }
19 |
--------------------------------------------------------------------------------
/screen/contributors/src/main/java/com/ivy/contributors/Contributor.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.contributors
2 |
3 | data class Contributor(
4 | val name: String,
5 | val photoUrl: String,
6 | val contributionsCount: String,
7 | val githubProfileUrl: String
8 | )
9 |
--------------------------------------------------------------------------------
/screen/contributors/src/main/java/com/ivy/contributors/ContributorsEvent.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.contributors
2 |
3 | sealed interface ContributorsEvent {
4 | data object TryAgainButtonClicked : ContributorsEvent
5 | }
6 |
--------------------------------------------------------------------------------
/screen/contributors/src/main/java/com/ivy/contributors/ProjectRepositoryInfo.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.contributors
2 |
3 | data class ProjectRepositoryInfo(
4 | val forks: String,
5 | val stars: String,
6 | val url: String
7 | )
8 |
--------------------------------------------------------------------------------
/screen/contributors/src/test/snapshots/images/com.ivy.contributors_ContributorsScreenPaparazziTest_snapshot Contributor Screen[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/contributors/src/test/snapshots/images/com.ivy.contributors_ContributorsScreenPaparazziTest_snapshot Contributor Screen[Dark].png
--------------------------------------------------------------------------------
/screen/contributors/src/test/snapshots/images/com.ivy.contributors_ContributorsScreenPaparazziTest_snapshot Contributor Screen[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/contributors/src/test/snapshots/images/com.ivy.contributors_ContributorsScreenPaparazziTest_snapshot Contributor Screen[Light].png
--------------------------------------------------------------------------------
/screen/disclaimer/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.disclaimer"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.data.core)
11 | implementation(projects.shared.ui.core)
12 | implementation(projects.shared.ui.navigation)
13 |
14 | testImplementation(projects.shared.ui.testing)
15 | }
16 |
--------------------------------------------------------------------------------
/screen/disclaimer/src/main/java/com/ivy/disclaimer/DisclaimerViewState.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.disclaimer
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | data class DisclaimerViewState(
6 | val checkboxes: ImmutableList,
7 | val agreeButtonEnabled: Boolean,
8 | )
9 |
10 | data class CheckboxViewState(
11 | val text: String,
12 | val checked: Boolean
13 | )
14 |
15 | sealed interface DisclaimerViewEvent {
16 | data class OnCheckboxClick(val index: Int) : DisclaimerViewEvent
17 | data object OnAgreeClick : DisclaimerViewEvent
18 | }
--------------------------------------------------------------------------------
/screen/disclaimer/src/main/java/com/ivy/disclaimer/composables/DisclaimerTopAppBar.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.disclaimer.composables
2 |
3 | import androidx.compose.material3.ExperimentalMaterial3Api
4 | import androidx.compose.material3.Text
5 | import androidx.compose.material3.TopAppBar
6 | import androidx.compose.runtime.Composable
7 | import androidx.compose.ui.Modifier
8 |
9 | @OptIn(ExperimentalMaterial3Api::class)
10 | @Composable
11 | fun DisclaimerTopAppBar(
12 | modifier: Modifier = Modifier,
13 | ) {
14 | TopAppBar(
15 | modifier = modifier,
16 | title = {
17 | Text(text = "Important User Agreement")
18 | }
19 | )
20 | }
--------------------------------------------------------------------------------
/screen/disclaimer/src/test/snapshots/images/com.ivy.disclaimer_DisclaimerScreenPaparazziTest_all checked[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/disclaimer/src/test/snapshots/images/com.ivy.disclaimer_DisclaimerScreenPaparazziTest_all checked[Dark].png
--------------------------------------------------------------------------------
/screen/disclaimer/src/test/snapshots/images/com.ivy.disclaimer_DisclaimerScreenPaparazziTest_all checked[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/disclaimer/src/test/snapshots/images/com.ivy.disclaimer_DisclaimerScreenPaparazziTest_all checked[Light].png
--------------------------------------------------------------------------------
/screen/disclaimer/src/test/snapshots/images/com.ivy.disclaimer_DisclaimerScreenPaparazziTest_none checked[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/disclaimer/src/test/snapshots/images/com.ivy.disclaimer_DisclaimerScreenPaparazziTest_none checked[Dark].png
--------------------------------------------------------------------------------
/screen/disclaimer/src/test/snapshots/images/com.ivy.disclaimer_DisclaimerScreenPaparazziTest_none checked[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/disclaimer/src/test/snapshots/images/com.ivy.disclaimer_DisclaimerScreenPaparazziTest_none checked[Light].png
--------------------------------------------------------------------------------
/screen/edit-transaction/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.transaction"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 | implementation(projects.widget.balance)
18 |
19 | testImplementation(projects.shared.ui.testing)
20 | }
21 |
--------------------------------------------------------------------------------
/screen/exchange-rates/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.exchangerates"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 |
18 | testImplementation(projects.shared.ui.testing)
19 | }
20 |
--------------------------------------------------------------------------------
/screen/exchange-rates/src/main/java/com/ivy/exchangerates/RatesEvent.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.exchangerates
2 |
3 | import com.ivy.exchangerates.data.RateUi
4 |
5 | sealed interface RatesEvent {
6 | data class Search(val query: String) : RatesEvent
7 | data class RemoveOverride(val rate: RateUi) : RatesEvent
8 | data class UpdateRate(val rate: RateUi, val newRate: Double) : RatesEvent
9 | data class AddRate(val rate: RateUi) : RatesEvent
10 | }
11 |
--------------------------------------------------------------------------------
/screen/exchange-rates/src/main/java/com/ivy/exchangerates/RatesState.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.exchangerates
2 |
3 | import com.ivy.exchangerates.data.RateUi
4 | import kotlinx.collections.immutable.ImmutableList
5 |
6 | data class RatesState(
7 | val baseCurrency: String,
8 | val manual: ImmutableList,
9 | val automatic: ImmutableList
10 | )
11 |
--------------------------------------------------------------------------------
/screen/exchange-rates/src/main/java/com/ivy/exchangerates/data/RateUi.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.exchangerates.data
2 |
3 | import androidx.compose.runtime.Immutable
4 |
5 | @Immutable
6 | data class RateUi(
7 | val from: String,
8 | val to: String,
9 | val rate: Double
10 | )
11 |
--------------------------------------------------------------------------------
/screen/exchange-rates/src/test/snapshots/images/com.ivy.exchangerates_ExchangeRatesScreenPaparazziTest_snapshot Exchange Rates Screen[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/exchange-rates/src/test/snapshots/images/com.ivy.exchangerates_ExchangeRatesScreenPaparazziTest_snapshot Exchange Rates Screen[Dark].png
--------------------------------------------------------------------------------
/screen/exchange-rates/src/test/snapshots/images/com.ivy.exchangerates_ExchangeRatesScreenPaparazziTest_snapshot Exchange Rates Screen[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/exchange-rates/src/test/snapshots/images/com.ivy.exchangerates_ExchangeRatesScreenPaparazziTest_snapshot Exchange Rates Screen[Light].png
--------------------------------------------------------------------------------
/screen/features/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.features"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.domain)
12 | implementation(projects.shared.ui.core)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | }
--------------------------------------------------------------------------------
/screen/features/src/main/java/com/ivy/features/FeaturesUiEvent.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.features
2 |
3 | sealed interface FeaturesUiEvent {
4 | data class ToggleFeature(val key: String) : FeaturesUiEvent
5 | }
6 |
--------------------------------------------------------------------------------
/screen/features/src/main/java/com/ivy/features/FeaturesUiState.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.features
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | data class FeaturesUiState(
6 | val featureItemViewStates: ImmutableList,
7 | )
8 |
9 | sealed interface FeatureItemViewState {
10 | data class FeatureToggleViewState(
11 | val key: String,
12 | val name: String,
13 | val enabled: Boolean,
14 | val description: String?,
15 | ) : FeatureItemViewState
16 |
17 | data class FeatureHeaderViewState(val name: String) : FeatureItemViewState
18 | }
19 |
--------------------------------------------------------------------------------
/screen/home/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.home"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 | implementation(projects.widget.addTransaction)
18 |
19 | testImplementation(projects.shared.ui.testing)
20 | }
21 |
--------------------------------------------------------------------------------
/screen/home/src/main/java/com/ivy/home/Constants.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.home
2 |
3 | object Constants {
4 | const val SWIPE_HORIZONTAL_THRESHOLD = 200
5 | const val SWIPE_DOWN_THRESHOLD_OPEN_MORE_MENU = 200
6 | }
7 |
--------------------------------------------------------------------------------
/screen/home/src/test/snapshots/images/com.ivy.home_HomePaparazziTest_snapshot Home Screen[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/home/src/test/snapshots/images/com.ivy.home_HomePaparazziTest_snapshot Home Screen[Dark].png
--------------------------------------------------------------------------------
/screen/home/src/test/snapshots/images/com.ivy.home_HomePaparazziTest_snapshot Home Screen[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/home/src/test/snapshots/images/com.ivy.home_HomePaparazziTest_snapshot Home Screen[Light].png
--------------------------------------------------------------------------------
/screen/import-data/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.importdata"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.screen.onboarding)
11 | implementation(projects.shared.base)
12 | implementation(projects.shared.data.core)
13 | implementation(projects.shared.domain)
14 | implementation(projects.shared.ui.core)
15 | implementation(projects.shared.ui.navigation)
16 | implementation(projects.temp.legacyCode)
17 | implementation(projects.temp.oldDesign)
18 |
19 | implementation(libs.bundles.opencsv)
20 | }
--------------------------------------------------------------------------------
/screen/import-data/src/main/java/com/ivy/importdata/csvimport/ImportStep.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.importdata.csvimport
2 |
3 | enum class ImportStep {
4 | IMPORT_FROM, INSTRUCTIONS, LOADING, RESULT
5 | }
6 |
--------------------------------------------------------------------------------
/screen/import-data/src/main/java/com/ivy/importdata/csvimport/flow/instructions/FortuneCitySteps.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.importdata.csvimport.flow.instructions
2 |
3 | import androidx.compose.runtime.Composable
4 |
5 | @Composable
6 | fun FortuneCitySteps(
7 | onUploadClick: () -> Unit
8 | ) {
9 | DefaultImportSteps(
10 | articleUrl = "https://fourdesire.helpshift.com/hc/en/5-fortune-city/faq/242-can-i-export-my-fortune-city-records/",
11 | onUploadClick = onUploadClick
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/screen/import-data/src/main/java/com/ivy/importdata/csvimport/flow/instructions/KTWMoneyMangerSteps.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.importdata.csvimport.flow.instructions
2 |
3 | import androidx.compose.runtime.Composable
4 |
5 | @Composable
6 | fun KTWMoneyManagerSteps(
7 | onUploadClick: () -> Unit
8 | ) {
9 | DefaultImportSteps(
10 | onUploadClick = onUploadClick
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/screen/import-data/src/main/java/com/ivy/importdata/csvimport/flow/instructions/OneMoneySteps.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.importdata.csvimport.flow.instructions
2 |
3 | import androidx.compose.runtime.Composable
4 |
5 | @Composable
6 | fun OneMoneySteps(
7 | onUploadClick: () -> Unit
8 | ) {
9 | DefaultImportSteps(
10 | onUploadClick = onUploadClick
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/screen/import-data/src/main/java/com/ivy/importdata/csvimport/flow/instructions/WalletByBudgetBakersSteps.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.importdata.csvimport.flow.instructions
2 |
3 | import androidx.compose.runtime.Composable
4 |
5 | @Composable
6 | fun WalletByBudgetBakersSteps(
7 | onUploadClick: () -> Unit
8 | ) {
9 | DefaultImportSteps(
10 | articleUrl = "https://support.budgetbakers.com/hc/en-us/articles/209753325-How-to-EXPORT-transactions-from-Wallet",
11 | onUploadClick = onUploadClick
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/screen/loans/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.loans"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 |
18 | testImplementation(projects.shared.ui.testing)
19 | }
20 |
--------------------------------------------------------------------------------
/screen/loans/src/main/java/com/ivy/loans/loan/Constants.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.loans.loan
2 |
3 | internal object Constants {
4 | const val SWIPE_HORIZONTAL_THRESHOLD = 200
5 | }
6 |
--------------------------------------------------------------------------------
/screen/loans/src/main/java/com/ivy/loans/loan/LoanTab.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.loans.loan
2 |
3 | import androidx.compose.runtime.Immutable
4 |
5 | @Immutable
6 | enum class LoanTab {
7 | PENDING, COMPLETED
8 | }
--------------------------------------------------------------------------------
/screen/loans/src/main/java/com/ivy/loans/loan/data/DisplayLoanRecord.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.loans.loan.data
2 |
3 | import com.ivy.legacy.datamodel.Account
4 | import com.ivy.legacy.datamodel.LoanRecord
5 |
6 | data class DisplayLoanRecord(
7 | val loanRecord: LoanRecord,
8 | val account: Account? = null,
9 | val loanRecordCurrencyCode: String = "",
10 | val loanCurrencyCode: String = "",
11 | val loanRecordTransaction: Boolean = false,
12 | )
13 |
--------------------------------------------------------------------------------
/screen/loans/src/main/java/com/ivy/loans/loandetails/events/DeleteLoanModalEvent.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.loans.loandetails.events
2 |
3 | sealed interface DeleteLoanModalEvent : LoanDetailsScreenEvent {
4 | data object OnDeleteLoan : DeleteLoanModalEvent
5 | data class OnDismissDeleteLoan(val isDeleteModalVisible: Boolean) : DeleteLoanModalEvent
6 | }
7 |
--------------------------------------------------------------------------------
/screen/loans/src/main/java/com/ivy/loans/loandetails/events/LoanDetailsScreenEvent.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.loans.loandetails.events
2 |
3 | import com.ivy.wallet.domain.deprecated.logic.model.CreateAccountData
4 |
5 | sealed interface LoanDetailsScreenEvent {
6 | data object OnEditLoanClick : LoanDetailsScreenEvent
7 | data object OnAmountClick : LoanDetailsScreenEvent
8 | data object OnAddRecord : LoanDetailsScreenEvent
9 | data class OnCreateAccount(val data: CreateAccountData) : LoanDetailsScreenEvent
10 | }
11 |
--------------------------------------------------------------------------------
/screen/loans/src/main/java/com/ivy/loans/loandetails/events/LoanModalEvent.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.loans.loandetails.events
2 |
3 | import com.ivy.legacy.datamodel.Loan
4 |
5 | sealed interface LoanModalEvent : LoanDetailsScreenEvent {
6 | data object OnDismissLoanModal : LoanModalEvent
7 | data class OnEditLoanModal(val loan: Loan, val createLoanTransaction: Boolean) :
8 | LoanModalEvent
9 |
10 | data object PerformCalculation : LoanModalEvent
11 | data object OnChangeDate : LoanModalEvent
12 | data object OnChangeTime : LoanModalEvent
13 | }
14 |
--------------------------------------------------------------------------------
/screen/loans/src/test/snapshots/images/com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen composable[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/loans/src/test/snapshots/images/com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen composable[Dark].png
--------------------------------------------------------------------------------
/screen/loans/src/test/snapshots/images/com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen composable[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/loans/src/test/snapshots/images/com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen composable[Light].png
--------------------------------------------------------------------------------
/screen/loans/src/test/snapshots/images/com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen non tabular composable[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/loans/src/test/snapshots/images/com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen non tabular composable[Dark].png
--------------------------------------------------------------------------------
/screen/loans/src/test/snapshots/images/com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen non tabular composable[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/loans/src/test/snapshots/images/com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen non tabular composable[Light].png
--------------------------------------------------------------------------------
/screen/loans/src/test/snapshots/images/com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen tabular composable[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/loans/src/test/snapshots/images/com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen tabular composable[Dark].png
--------------------------------------------------------------------------------
/screen/loans/src/test/snapshots/images/com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen tabular composable[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/loans/src/test/snapshots/images/com.ivy.loans_LoanScreenPaparazziTest_snapshot loanScreen tabular composable[Light].png
--------------------------------------------------------------------------------
/screen/main/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.main"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.screen.accounts)
11 | implementation(projects.screen.home)
12 | implementation(projects.shared.base)
13 | implementation(projects.shared.data.core)
14 | implementation(projects.shared.domain)
15 | implementation(projects.shared.ui.core)
16 | implementation(projects.shared.ui.navigation)
17 | implementation(projects.temp.legacyCode)
18 | implementation(projects.temp.oldDesign)
19 | }
20 |
--------------------------------------------------------------------------------
/screen/onboarding/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.onboarding"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 | }
18 |
--------------------------------------------------------------------------------
/screen/onboarding/src/main/java/com/ivy/onboarding/OnboardingState.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.onboarding
2 |
3 | import androidx.compose.runtime.Immutable
4 |
5 | @Immutable
6 | enum class OnboardingState {
7 | SPLASH,
8 | LOGIN,
9 | CHOOSE_PATH,
10 | CURRENCY,
11 | ACCOUNTS,
12 | CATEGORIES
13 | }
14 |
--------------------------------------------------------------------------------
/screen/piechart/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.piechart"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 | }
18 |
--------------------------------------------------------------------------------
/screen/piechart/src/main/java/com/ivy/piechart/CategoryAmount.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.piechart
2 |
3 | import androidx.compose.runtime.Immutable
4 | import com.ivy.base.legacy.Transaction
5 | import com.ivy.data.model.Category
6 |
7 | @Immutable
8 | data class CategoryAmount(
9 | val category: Category?,
10 | val amount: Double,
11 | val associatedTransactions: List = emptyList(),
12 | val isCategoryUnspecified: Boolean = false
13 | )
14 |
--------------------------------------------------------------------------------
/screen/piechart/src/main/java/com/ivy/piechart/SelectedCategory.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.piechart
2 |
3 | import androidx.compose.runtime.Immutable
4 | import com.ivy.data.model.Category
5 |
6 | @Immutable
7 | data class SelectedCategory(
8 | val category: Category // null - Unspecified
9 | )
10 |
--------------------------------------------------------------------------------
/screen/planned-payments/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.planned"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 | }
--------------------------------------------------------------------------------
/screen/planned-payments/src/main/java/com/ivy/planned/list/PlannedPaymentsScreenEvent.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.planned.list
2 |
3 | sealed interface PlannedPaymentsScreenEvent {
4 | data class OnOneTimePaymentsExpanded(val isExpanded: Boolean) : PlannedPaymentsScreenEvent
5 | data class OnRecurringPaymentsExpanded(val isExpanded: Boolean) : PlannedPaymentsScreenEvent
6 | }
7 |
--------------------------------------------------------------------------------
/screen/releases/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.releases"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.domain)
12 | implementation(projects.shared.ui.core)
13 | implementation(projects.shared.ui.navigation)
14 |
15 | implementation(libs.bundles.ktor)
16 | }
17 |
--------------------------------------------------------------------------------
/screen/releases/src/main/java/com/ivy/releases/ReleaseInfo.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.releases
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | data class ReleaseInfo(
6 | val releaseName: String,
7 | val releaseUrl: String,
8 | val releaseDate: String,
9 | val releaseCommits: ImmutableList
10 | )
11 |
--------------------------------------------------------------------------------
/screen/releases/src/main/java/com/ivy/releases/ReleasesEvent.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.releases
2 |
3 | sealed interface ReleasesEvent {
4 | data object OnTryAgainClick : ReleasesEvent
5 | }
6 |
--------------------------------------------------------------------------------
/screen/releases/src/main/java/com/ivy/releases/ReleasesState.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.releases
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | sealed interface ReleasesState {
6 | data class Success(val releasesInfo: ImmutableList) : ReleasesState
7 | data class Loading(val loadingMessage: String) : ReleasesState
8 | data class Error(val errorMessage: String) : ReleasesState
9 | }
10 |
--------------------------------------------------------------------------------
/screen/reports/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.reports"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 |
18 | testImplementation(projects.shared.ui.testing)
19 | }
--------------------------------------------------------------------------------
/screen/reports/src/test/snapshots/images/com.ivy.report_ReportPaparazziTest_snapshot Report Screen no filter[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/reports/src/test/snapshots/images/com.ivy.report_ReportPaparazziTest_snapshot Report Screen no filter[Dark].png
--------------------------------------------------------------------------------
/screen/reports/src/test/snapshots/images/com.ivy.report_ReportPaparazziTest_snapshot Report Screen no filter[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/reports/src/test/snapshots/images/com.ivy.report_ReportPaparazziTest_snapshot Report Screen no filter[Light].png
--------------------------------------------------------------------------------
/screen/reports/src/test/snapshots/images/com.ivy.report_ReportPaparazziTest_snapshot Report Screen[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/reports/src/test/snapshots/images/com.ivy.report_ReportPaparazziTest_snapshot Report Screen[Dark].png
--------------------------------------------------------------------------------
/screen/reports/src/test/snapshots/images/com.ivy.report_ReportPaparazziTest_snapshot Report Screen[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/reports/src/test/snapshots/images/com.ivy.report_ReportPaparazziTest_snapshot Report Screen[Light].png
--------------------------------------------------------------------------------
/screen/search/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.search"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 |
18 | testImplementation(projects.shared.ui.testing)
19 | }
20 |
--------------------------------------------------------------------------------
/screen/search/src/main/java/com/ivy/search/SearchEvent.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.search
2 |
3 | sealed interface SearchEvent {
4 | data class Search(val query: String) : SearchEvent
5 | }
6 |
--------------------------------------------------------------------------------
/screen/search/src/main/java/com/ivy/search/SearchState.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.search
2 |
3 | import com.ivy.base.legacy.TransactionHistoryItem
4 | import com.ivy.data.model.Category
5 | import com.ivy.legacy.datamodel.Account
6 | import kotlinx.collections.immutable.ImmutableList
7 |
8 | data class SearchState(
9 | val searchQuery: String,
10 | val transactions: ImmutableList,
11 | val baseCurrency: String,
12 | val accounts: ImmutableList,
13 | val categories: ImmutableList,
14 | val shouldShowAccountSpecificColorInTransactions: Boolean
15 | )
16 |
--------------------------------------------------------------------------------
/screen/search/src/test/snapshots/images/com.ivy.search_SearchPaparazziTest_snapshot Search Screen[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/search/src/test/snapshots/images/com.ivy.search_SearchPaparazziTest_snapshot Search Screen[Dark].png
--------------------------------------------------------------------------------
/screen/search/src/test/snapshots/images/com.ivy.search_SearchPaparazziTest_snapshot Search Screen[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/search/src/test/snapshots/images/com.ivy.search_SearchPaparazziTest_snapshot Search Screen[Light].png
--------------------------------------------------------------------------------
/screen/settings/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.settings"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 | implementation(projects.widget.balance)
18 |
19 | testImplementation(projects.shared.ui.testing)
20 | }
21 |
--------------------------------------------------------------------------------
/screen/settings/src/main/java/com/ivy/settings/SettingsState.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.settings
2 |
3 | import com.ivy.base.legacy.Theme
4 |
5 | data class SettingsState(
6 | val currencyCode: String,
7 | val name: String,
8 | val currentTheme: Theme,
9 | val lockApp: Boolean,
10 | val showNotifications: Boolean,
11 | val hideCurrentBalance: Boolean,
12 | val hideIncome: Boolean,
13 | val treatTransfersAsIncomeExpense: Boolean,
14 | val startDateOfMonth: String,
15 | val progressState: Boolean,
16 | val languageOptionVisible: Boolean
17 | )
18 |
--------------------------------------------------------------------------------
/screen/transactions/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.transactions"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.data.core)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 | implementation(projects.temp.legacyCode)
16 | implementation(projects.temp.oldDesign)
17 |
18 | testImplementation(projects.shared.ui.testing)
19 | }
20 |
--------------------------------------------------------------------------------
/screen/transactions/src/test/snapshots/images/com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/transactions/src/test/snapshots/images/com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Dark].png
--------------------------------------------------------------------------------
/screen/transactions/src/test/snapshots/images/com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/screen/transactions/src/test/snapshots/images/com.ivy.transactions_TransactionsPaparazziTest_snapshot Transactions Screen[Light].png
--------------------------------------------------------------------------------
/scripts/composeStability.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # -------------------
4 | # 0. ROOT DIRECTORY CHECK
5 | # -------------------
6 |
7 | # Check if the script is being run from the root directory of the repo
8 | if [ ! -f "settings.gradle.kts" ]; then
9 | echo "ERROR:"
10 | echo "Please run this script from the root directory of the repo."
11 | exit 1
12 | fi
13 |
14 | ./gradlew assembleDemo -PcomposeCompilerReports=true || exit 1
15 | ./gradlew :ci-actions:compose-stability:run || exit 1
--------------------------------------------------------------------------------
/scripts/detekt.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # -------------------
4 | # 0. ROOT DIRECTORY CHECK
5 | # -------------------
6 |
7 | # Check if the script is being run from the root directory of the repo
8 | if [ ! -f "settings.gradle.kts" ]; then
9 | echo "ERROR:"
10 | echo "Please run this script from the root directory of the repo."
11 | exit 1
12 | fi
13 |
14 |
15 | ./gradlew detekt || exit 0
--------------------------------------------------------------------------------
/scripts/detektBaseline.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # -------------------
4 | # 0. ROOT DIRECTORY CHECK
5 | # -------------------
6 |
7 | # Check if the script is being run from the root directory of the repo
8 | if [ ! -f "settings.gradle.kts" ]; then
9 | echo "ERROR:"
10 | echo "Please run this script from the root directory of the repo."
11 | exit 1
12 | fi
13 |
14 |
15 | ./gradlew detektBaseline || exit 0
16 | git add config/detekt/baseline.yml || exit 0
17 | git commit -m "Add Detekt baseline" || exit 0
18 | echo "Detekt baseline added."
19 | echo "[SUCCESS] Detekt baseline committed. Do 'git push'."
--------------------------------------------------------------------------------
/scripts/detektFormat.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Fetch changed and untracked Kotlin files
4 | CHANGED_FILES=$(git diff --name-only HEAD | grep '\.kt[s]*$' | tr '\n' ',')
5 |
6 | if [ -z "$CHANGED_FILES" ]; then
7 | echo "No Kotlin files have changed."
8 | exit 0
9 | fi
10 |
11 | # Run detektFormat only on those files
12 | ./gradlew detektFormat -Ddetekt.filesToCheck=$CHANGED_FILES
13 |
--------------------------------------------------------------------------------
/scripts/integrationTests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # -------------------
4 | # 0. ROOT DIRECTORY CHECK
5 | # -------------------
6 |
7 | # Check if the script is being run from the root directory of the repo
8 | if [ ! -f "settings.gradle.kts" ]; then
9 | echo "ERROR:"
10 | echo "Please run this script from the root directory of the repo."
11 | exit 1
12 | fi
13 |
14 | ./gradlew :shared:data:core:connectedDebugAndroidTest || exit 1
15 | ./gradlew :shared:domain:connectedDebugAndroidTest || exit 1
16 |
17 |
--------------------------------------------------------------------------------
/scripts/lint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # -------------------
4 | # 0. ROOT DIRECTORY CHECK
5 | # -------------------
6 |
7 | # Check if the script is being run from the root directory of the repo
8 | if [ ! -f "settings.gradle.kts" ]; then
9 | echo "ERROR:"
10 | echo "Please run this script from the root directory of the repo."
11 | exit 1
12 | fi
13 |
14 |
15 | ./gradlew lintR
16 | open build/reports/lint/lint.html
17 | echo "[FINISHED] Lint report opened in your default browser."
--------------------------------------------------------------------------------
/scripts/paparazziScreenshotTests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # -------------------
4 | # 0. ROOT DIRECTORY CHECK
5 | # -------------------
6 |
7 | # Check if the script is being run from the root directory of the repo
8 | if [ ! -f "settings.gradle.kts" ]; then
9 | echo "ERROR:"
10 | echo "Please run this script from the root directory of the repo."
11 | exit 1
12 | fi
13 |
14 | ./gradlew verifyPaparazziDebug || exit 1
--------------------------------------------------------------------------------
/scripts/unitTests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # -------------------
4 | # 0. ROOT DIRECTORY CHECK
5 | # -------------------
6 |
7 | # Check if the script is being run from the root directory of the repo
8 | if [ ! -f "settings.gradle.kts" ]; then
9 | echo "ERROR:"
10 | echo "Please run this script from the root directory of the repo."
11 | exit 1
12 | fi
13 |
14 |
15 | ./gradlew testDebugUnitTest || exit 0
--------------------------------------------------------------------------------
/shared/base/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.base"
7 | }
8 |
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/di/KotlinxSerializationModule.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.di
2 |
3 | import dagger.Module
4 | import dagger.Provides
5 | import dagger.hilt.InstallIn
6 | import dagger.hilt.components.SingletonComponent
7 | import kotlinx.serialization.json.Json
8 |
9 | @Module
10 | @InstallIn(SingletonComponent::class)
11 | object KotlinxSerializationModule {
12 | @Provides
13 | fun provideJson(): Json {
14 | return Json {
15 | ignoreUnknownKeys = true
16 | isLenient = true
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/legacy/LegacyTag.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.legacy
2 |
3 | import androidx.compose.runtime.Immutable
4 | import java.util.UUID
5 |
6 | @Immutable
7 | @Deprecated("Use Tag Data Model")
8 | @Suppress("DataClassTypedIDs")
9 | data class LegacyTag(val id: UUID, val name: String)
10 |
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/legacy/Theme.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.legacy
2 |
3 | import androidx.compose.runtime.Immutable
4 |
5 | @Deprecated("Old design system. Use `:ivy-design` and Material3")
6 | @Immutable
7 | enum class Theme {
8 | LIGHT, DARK, AUTO, AMOLED_DARK
9 | }
10 |
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/legacy/TransactionHistoryItem.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.legacy
2 |
3 | import androidx.compose.runtime.Immutable
4 |
5 | @Deprecated("Legacy data model. Will be deleted")
6 | @Immutable
7 | interface TransactionHistoryItem
8 |
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/model/IntervalType.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.model
2 |
3 | import androidx.annotation.Keep
4 |
5 | @Keep
6 | enum class IntervalType {
7 | DAY, WEEK, MONTH, YEAR
8 | }
9 |
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/model/LoanRecordType.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.model
2 |
3 | import androidx.annotation.Keep
4 | import androidx.compose.runtime.Immutable
5 | import kotlinx.serialization.Serializable
6 |
7 | @Immutable
8 | @Keep
9 | @Serializable
10 | enum class LoanRecordType {
11 | INCREASE, DECREASE
12 | }
13 |
14 | fun LoanRecordType.processByType(decreaseAction: () -> T, increaseAction: () -> T): T {
15 | return when (this) {
16 | LoanRecordType.DECREASE -> decreaseAction()
17 | LoanRecordType.INCREASE -> increaseAction()
18 | }
19 | }
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/model/LoanType.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.model
2 |
3 | import androidx.annotation.Keep
4 |
5 | @Keep
6 | enum class LoanType {
7 | BORROW, LEND
8 | }
9 |
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/model/TransactionType.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.model
2 |
3 | import androidx.annotation.Keep
4 | import androidx.compose.runtime.Immutable
5 | import kotlinx.serialization.Serializable
6 |
7 | @Immutable
8 | @Keep
9 | @Serializable
10 | enum class TransactionType {
11 | INCOME, EXPENSE, TRANSFER
12 | }
13 |
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/resource/ResourceProvider.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.resource
2 |
3 | import androidx.annotation.StringRes
4 |
5 | interface ResourceProvider {
6 | fun getString(@StringRes resId: Int): String
7 | fun getString(@StringRes resId: Int, vararg args: Any): String
8 | }
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/threading/DispatchersProvider.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.threading
2 |
3 | import kotlin.coroutines.CoroutineContext
4 |
5 | interface DispatchersProvider {
6 | val main: CoroutineContext
7 | val io: CoroutineContext
8 | val default: CoroutineContext
9 | }
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/threading/IvyDispatchersProvider.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.threading
2 |
3 | import kotlinx.coroutines.Dispatchers
4 | import javax.inject.Inject
5 | import kotlin.coroutines.CoroutineContext
6 |
7 | class IvyDispatchersProvider @Inject constructor() : DispatchersProvider {
8 | override val main: CoroutineContext = Dispatchers.Main
9 | override val io: CoroutineContext = Dispatchers.IO
10 | override val default: CoroutineContext = Dispatchers.Default
11 | }
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/time/TimeConversionExt.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.time
2 |
3 | import java.time.Instant
4 | import java.time.ZoneId
5 | import java.time.ZonedDateTime
6 |
7 | @Deprecated("Use the TimeConverter interface via DI")
8 | fun Instant.convertToLocal(): ZonedDateTime {
9 | return atZone(ZoneId.systemDefault())
10 | }
11 |
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/time/TimeConverter.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.time
2 |
3 | import java.time.Instant
4 | import java.time.LocalDate
5 | import java.time.LocalDateTime
6 | import java.time.LocalTime
7 |
8 | interface TimeConverter {
9 | fun Instant.toLocalDateTime(): LocalDateTime
10 | fun Instant.toLocalDate(): LocalDate
11 | fun Instant.toLocalTime(): LocalTime
12 |
13 | fun LocalDateTime.toUTC(): Instant
14 | }
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/time/TimeProvider.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.time
2 |
3 | import java.time.Instant
4 | import java.time.LocalDate
5 | import java.time.LocalDateTime
6 | import java.time.LocalTime
7 | import java.time.ZoneId
8 |
9 | interface TimeProvider {
10 | fun getZoneId(): ZoneId
11 | fun utcNow(): Instant
12 | fun localNow(): LocalDateTime
13 | fun localDateNow(): LocalDate
14 | fun localTimeNow(): LocalTime
15 | }
16 |
--------------------------------------------------------------------------------
/shared/base/src/main/java/com/ivy/base/time/TimeRange.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.time
2 |
3 | import java.time.Instant
4 | import java.util.concurrent.TimeUnit
5 |
6 | const val SafeOffsetDays = 365 * 10L
7 |
8 | val INSTANT_MIN_SAFE: Instant
9 | get() = Instant.ofEpochMilli(Long.MIN_VALUE)
10 | .plusSeconds(TimeUnit.DAYS.toSeconds(SafeOffsetDays))
11 |
12 | val INSTANT_MAX_SAFE: Instant
13 | get() = Instant.ofEpochMilli(Long.MAX_VALUE)
14 | .minusSeconds(TimeUnit.DAYS.toSeconds(SafeOffsetDays))
--------------------------------------------------------------------------------
/shared/base/src/test/java/com/ivy/base/time/impl/DeviceTimeProviderTest.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.base.time.impl
2 |
3 | import org.junit.Before
4 | import org.junit.Test
5 |
6 | class DeviceTimeProviderTest {
7 |
8 | private lateinit var timeProvider: DeviceTimeProvider
9 |
10 | @Before
11 | fun setup() {
12 | timeProvider = DeviceTimeProvider()
13 | }
14 |
15 | @Test
16 | fun `validate no crashes`() {
17 | // When
18 | timeProvider.getZoneId()
19 | timeProvider.utcNow()
20 | timeProvider.localNow()
21 |
22 | // Then
23 | // there are no crashes
24 | }
25 | }
--------------------------------------------------------------------------------
/shared/data/core-testing/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | id("ivy.room")
4 | }
5 |
6 | android {
7 | namespace = "com.ivy.data.testing"
8 | }
9 |
10 | dependencies {
11 | implementation(projects.shared.data.core)
12 | }
13 |
--------------------------------------------------------------------------------
/shared/data/core/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | id("ivy.room")
4 | id("ivy.integration.testing")
5 | }
6 |
7 | android {
8 | namespace = "com.ivy.data"
9 | }
10 |
11 | dependencies {
12 | implementation(projects.shared.base)
13 | api(projects.shared.data.model)
14 |
15 | implementation(libs.datastore)
16 | implementation(libs.bundles.ktor)
17 |
18 | testImplementation(projects.shared.data.modelTesting)
19 | androidTestImplementation(libs.bundles.integration.testing)
20 | }
21 |
--------------------------------------------------------------------------------
/shared/data/core/src/androidTest/assets/backups/450-150.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/data/core/src/androidTest/assets/backups/450-150.json
--------------------------------------------------------------------------------
/shared/data/core/src/androidTest/assets/backups/450-150.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/data/core/src/androidTest/assets/backups/450-150.zip
--------------------------------------------------------------------------------
/shared/data/core/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/backup/CSVRow.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.backup
2 |
3 | data class CSVRow(
4 | val index: Int,
5 | val content: List
6 | )
7 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/backup/ImportResult.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.backup
2 |
3 | import kotlinx.collections.immutable.ImmutableList
4 |
5 | data class ImportResult(
6 | val rowsFound: Int,
7 | val transactionsImported: Int,
8 | val accountsImported: Int,
9 | val categoriesImported: Int,
10 | val failedRows: ImmutableList,
11 | )
12 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/datastore/Datastore.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.datastore
2 |
3 | import android.content.Context
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.ui.platform.LocalContext
6 | import androidx.datastore.core.DataStore
7 | import androidx.datastore.preferences.core.Preferences
8 | import androidx.datastore.preferences.preferencesDataStore
9 |
10 | val Context.dataStore: DataStore by preferencesDataStore(
11 | name = "ivy_wallet_datastore_v1"
12 | )
13 |
14 | @Composable
15 | fun datastore(): DataStore {
16 | return LocalContext.current.dataStore
17 | }
18 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/dao/read/AccountDao.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.db.dao.read
2 |
3 | import androidx.room.Dao
4 | import androidx.room.Query
5 | import com.ivy.data.db.entity.AccountEntity
6 | import java.util.*
7 |
8 | @Dao
9 | interface AccountDao {
10 | @Query("SELECT * FROM accounts WHERE isDeleted = :deleted ORDER BY orderNum ASC")
11 | suspend fun findAll(deleted: Boolean = false): List
12 |
13 | @Query("SELECT * FROM accounts WHERE id = :id")
14 | suspend fun findById(id: UUID): AccountEntity?
15 |
16 | @Query("SELECT MAX(orderNum) FROM accounts")
17 | suspend fun findMaxOrderNum(): Double?
18 | }
19 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/dao/write/WriteAccountDao.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.db.dao.write
2 |
3 | import androidx.room.Dao
4 | import androidx.room.Query
5 | import androidx.room.Upsert
6 | import com.ivy.data.db.entity.AccountEntity
7 | import java.util.UUID
8 |
9 | @Dao
10 | interface WriteAccountDao {
11 | @Upsert
12 | suspend fun save(value: AccountEntity)
13 |
14 | @Upsert
15 | suspend fun saveMany(values: List)
16 |
17 | @Query("DELETE FROM accounts WHERE id = :id")
18 | suspend fun deleteById(id: UUID)
19 |
20 | @Query("DELETE FROM accounts")
21 | suspend fun deleteAll()
22 | }
23 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/dao/write/WriteBudgetDao.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.db.dao.write
2 |
3 | import androidx.room.Dao
4 | import androidx.room.Query
5 | import androidx.room.Upsert
6 | import com.ivy.data.db.entity.BudgetEntity
7 | import java.util.UUID
8 |
9 | @Dao
10 | interface WriteBudgetDao {
11 | @Upsert
12 | suspend fun save(value: BudgetEntity)
13 |
14 | @Upsert
15 | suspend fun saveMany(value: List)
16 |
17 | @Query("DELETE FROM budgets WHERE id = :id")
18 | suspend fun deleteById(id: UUID)
19 |
20 | @Query("DELETE FROM budgets")
21 | suspend fun deleteAll()
22 | }
23 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/dao/write/WriteCategoryDao.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.db.dao.write
2 |
3 | import androidx.room.Dao
4 | import androidx.room.Query
5 | import androidx.room.Upsert
6 | import com.ivy.data.db.entity.CategoryEntity
7 | import java.util.UUID
8 |
9 | @Dao
10 | interface WriteCategoryDao {
11 | @Upsert
12 | suspend fun save(value: CategoryEntity)
13 |
14 | @Upsert
15 | suspend fun saveMany(values: List)
16 |
17 | @Query("DELETE FROM categories WHERE id = :id")
18 | suspend fun deleteById(id: UUID)
19 |
20 | @Query("DELETE FROM categories")
21 | suspend fun deleteAll()
22 | }
23 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/dao/write/WriteLoanDao.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.db.dao.write
2 |
3 | import androidx.room.Dao
4 | import androidx.room.Query
5 | import androidx.room.Upsert
6 | import com.ivy.data.db.entity.LoanEntity
7 | import java.util.UUID
8 |
9 | @Dao
10 | interface WriteLoanDao {
11 | @Upsert
12 | suspend fun save(value: LoanEntity)
13 |
14 | @Upsert
15 | suspend fun saveMany(value: List)
16 |
17 | @Query("DELETE FROM loans WHERE id = :id")
18 | suspend fun deleteById(id: UUID)
19 |
20 | @Query("DELETE FROM loans")
21 | suspend fun deleteAll()
22 | }
23 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/dao/write/WriteSettingsDao.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.db.dao.write
2 |
3 | import androidx.room.Dao
4 | import androidx.room.Query
5 | import androidx.room.Upsert
6 | import com.ivy.data.db.entity.SettingsEntity
7 | import java.util.UUID
8 |
9 | @Dao
10 | interface WriteSettingsDao {
11 | @Upsert
12 | suspend fun save(value: SettingsEntity)
13 |
14 | @Upsert
15 | suspend fun saveMany(value: List)
16 |
17 | @Query("DELETE FROM settings WHERE id = :id")
18 | suspend fun deleteById(id: UUID)
19 |
20 | @Query("DELETE FROM settings")
21 | suspend fun deleteAll()
22 | }
23 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration108to109_Users.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.db.migration
2 |
3 | import androidx.room.migration.Migration
4 | import androidx.sqlite.db.SupportSQLiteDatabase
5 |
6 | class Migration108to109_Users : Migration(108, 109) {
7 | override fun migrate(database: SupportSQLiteDatabase) {
8 | database.execSQL(
9 | "CREATE TABLE IF NOT EXISTS `users` (`email` TEXT NOT NULL, `authProviderType` TEXT NOT NULL, `firstName` TEXT NOT NULL, `lastName` TEXT, `profilePicture` TEXT, `color` INTEGER NOT NULL, `id` TEXT NOT NULL, PRIMARY KEY(`id`))"
10 | )
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration111to112_User_testUser.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.db.migration
2 |
3 | import androidx.room.migration.Migration
4 | import androidx.sqlite.db.SupportSQLiteDatabase
5 |
6 | class Migration111to112_User_testUser : Migration(111, 112) {
7 | override fun migrate(database: SupportSQLiteDatabase) {
8 | database.execSQL("ALTER TABLE users ADD COLUMN testUser INTEGER NOT NULL DEFAULT 0")
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration112to113_ExchangeRates.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.db.migration
2 |
3 | import androidx.room.migration.Migration
4 | import androidx.sqlite.db.SupportSQLiteDatabase
5 |
6 | class Migration112to113_ExchangeRates : Migration(112, 113) {
7 | override fun migrate(database: SupportSQLiteDatabase) {
8 | database.execSQL(
9 | "CREATE TABLE IF NOT EXISTS `exchange_rates` (`baseCurrency` TEXT NOT NULL, `currency` TEXT NOT NULL, `rate` REAL NOT NULL, PRIMARY KEY(`baseCurrency`, `currency`))"
10 | )
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration113to114_Multi_Currency.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.db.migration
2 |
3 | import androidx.room.migration.Migration
4 | import androidx.sqlite.db.SupportSQLiteDatabase
5 |
6 | class Migration113to114_Multi_Currency : Migration(113, 114) {
7 | override fun migrate(database: SupportSQLiteDatabase) {
8 | database.execSQL("ALTER TABLE accounts ADD COLUMN currency TEXT")
9 | database.execSQL("ALTER TABLE transactions ADD COLUMN toAmount REAL")
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration114to115_Category_Account_Icons.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.db.migration
2 |
3 | import androidx.room.migration.Migration
4 | import androidx.sqlite.db.SupportSQLiteDatabase
5 |
6 | class Migration114to115_Category_Account_Icons : Migration(114, 115) {
7 | override fun migrate(database: SupportSQLiteDatabase) {
8 | database.execSQL("ALTER TABLE accounts ADD COLUMN icon TEXT")
9 | database.execSQL("ALTER TABLE categories ADD COLUMN icon TEXT")
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration115to116_Account_Include_In_Balance.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.db.migration
2 |
3 | import androidx.room.migration.Migration
4 | import androidx.sqlite.db.SupportSQLiteDatabase
5 |
6 | class Migration115to116_Account_Include_In_Balance : Migration(115, 116) {
7 | override fun migrate(database: SupportSQLiteDatabase) {
8 | database.execSQL("ALTER TABLE accounts ADD COLUMN includeInBalance INTEGER NOT NULL DEFAULT 1")
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration120to121_DropWishlistItem.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.db.migration
2 |
3 | import androidx.room.migration.Migration
4 | import androidx.sqlite.db.SupportSQLiteDatabase
5 |
6 | class Migration120to121_DropWishlistItem : Migration(120, 121) {
7 | override fun migrate(database: SupportSQLiteDatabase) {
8 | database.execSQL("DROP TABLE wishlist_items")
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration122to123_ExchangeRates.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.db.migration
2 |
3 | import androidx.room.migration.Migration
4 | import androidx.sqlite.db.SupportSQLiteDatabase
5 |
6 | class Migration122to123_ExchangeRates : Migration(122, 123) {
7 | override fun migrate(database: SupportSQLiteDatabase) {
8 | database.execSQL("ALTER TABLE exchange_rates ADD COLUMN manualOverride INTEGER NOT NULL DEFAULT 0")
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration123to124_LoanIncludeDateTime.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.db.migration
2 |
3 | import androidx.room.migration.Migration
4 | import androidx.sqlite.db.SupportSQLiteDatabase
5 |
6 | class Migration123to124_LoanIncludeDateTime : Migration(123, 124) {
7 | override fun migrate(db: SupportSQLiteDatabase) {
8 | db.execSQL("ALTER TABLE loans ADD COLUMN dateTime INTEGER NOT NULL DEFAULT 0")
9 | }
10 | }
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration126to127_LoanRecordType.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.db.migration
2 |
3 | import androidx.room.migration.Migration
4 | import androidx.sqlite.db.SupportSQLiteDatabase
5 |
6 | @Suppress("MagicNumber", "ClassNaming")
7 | class Migration126to127_LoanRecordType : Migration(126, 127) {
8 | override fun migrate(db: SupportSQLiteDatabase) {
9 | db.execSQL("ALTER TABLE loan_records ADD COLUMN loanRecordType TEXT NOT NULL DEFAULT 'DECREASE'")
10 | }
11 | }
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration127to128_PaidForDateRecord.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.db.migration
2 |
3 | import androidx.room.migration.Migration
4 | import androidx.sqlite.db.SupportSQLiteDatabase
5 |
6 | @Suppress("MagicNumber", "ClassNaming")
7 | class Migration127to128_PaidForDateRecord : Migration(127, 128) {
8 | override fun migrate(database: SupportSQLiteDatabase) {
9 | database.execSQL("ALTER TABLE transactions ADD COLUMN paidForDateTime INTEGER")
10 | }
11 | }
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/db/migration/Migration129to130_LoanIncludeNote.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.db.migration
2 |
3 | import androidx.room.migration.Migration
4 | import androidx.sqlite.db.SupportSQLiteDatabase
5 |
6 | class Migration129to130_LoanIncludeNote : Migration(129, 130) {
7 | override fun migrate(db: SupportSQLiteDatabase) {
8 | db.execSQL("ALTER TABLE loans ADD COLUMN note TEXT")
9 | }
10 | }
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/di/RemoteDataSourceModule.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.di
2 |
3 | import com.ivy.data.remote.RemoteExchangeRatesDataSource
4 | import com.ivy.data.remote.impl.RemoteExchangeRatesDataSourceImpl
5 | import dagger.Binds
6 | import dagger.Module
7 | import dagger.hilt.InstallIn
8 | import dagger.hilt.components.SingletonComponent
9 |
10 | @Module
11 | @InstallIn(SingletonComponent::class)
12 | abstract class RemoteDataSourceModule {
13 | @Binds
14 | abstract fun bindExchangeRatesDataSource(
15 | datasource: RemoteExchangeRatesDataSourceImpl
16 | ): RemoteExchangeRatesDataSource
17 | }
18 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/remote/RemoteExchangeRatesDataSource.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.remote
2 |
3 | import arrow.core.Either
4 | import com.ivy.data.remote.responses.ExchangeRatesResponse
5 |
6 | interface RemoteExchangeRatesDataSource {
7 | suspend fun fetchEurExchangeRates(): Either
8 | }
9 |
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/remote/responses/ExchangeRatesResponse.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.remote.responses
2 |
3 | import androidx.annotation.Keep
4 | import kotlinx.serialization.SerialName
5 | import kotlinx.serialization.Serializable
6 |
7 | @Serializable
8 | @Keep
9 | data class ExchangeRatesResponse(
10 | val date: String,
11 | @SerialName("eur")
12 | val rates: Map
13 | )
--------------------------------------------------------------------------------
/shared/data/core/src/main/java/com/ivy/data/repository/fake/FakeRepositoryMemo.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.repository.fake
2 |
3 | import com.ivy.base.TestDispatchersProvider
4 | import com.ivy.data.DataObserver
5 | import com.ivy.data.repository.RepositoryMemoFactory
6 | import org.jetbrains.annotations.VisibleForTesting
7 |
8 | @VisibleForTesting
9 | fun fakeRepositoryMemoFactory(): RepositoryMemoFactory = RepositoryMemoFactory(
10 | dataObserver = DataObserver(),
11 | dispatchers = TestDispatchersProvider
12 | )
--------------------------------------------------------------------------------
/shared/data/core/src/test/resources/backups/450-150.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/data/core/src/test/resources/backups/450-150.json
--------------------------------------------------------------------------------
/shared/data/model-testing/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.data.model.testing"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.data.model)
11 |
12 | implementation(libs.bundles.testing)
13 | }
--------------------------------------------------------------------------------
/shared/data/model-testing/src/main/java/com/ivy/data/model/testing/ModelFixtures.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.model.testing
2 |
3 | import com.ivy.data.model.AccountId
4 | import com.ivy.data.model.CategoryId
5 | import com.ivy.data.model.TransactionId
6 | import java.util.UUID
7 |
8 | object ModelFixtures {
9 | val AccountId = AccountId(UUID.randomUUID())
10 | val CategoryId = CategoryId(UUID.randomUUID())
11 | val TransactionId = TransactionId(UUID.randomUUID())
12 | }
13 |
--------------------------------------------------------------------------------
/shared/data/model/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.data.model"
7 | }
--------------------------------------------------------------------------------
/shared/data/model/src/main/kotlin/com/ivy/data/model/ExchangeRate.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.model
2 |
3 | import com.ivy.data.model.primitive.AssetCode
4 | import com.ivy.data.model.primitive.PositiveDouble
5 |
6 | data class ExchangeRate(
7 | val baseCurrency: AssetCode,
8 | val currency: AssetCode,
9 | val rate: PositiveDouble,
10 | val manualOverride: Boolean,
11 | )
12 |
--------------------------------------------------------------------------------
/shared/data/model/src/main/kotlin/com/ivy/data/model/Reorderable.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.model
2 |
3 | /**
4 | * Indicates that the item can be reordered by the user.
5 | * For the reordering to happen efficiently the item must have an [orderNum].
6 | */
7 | interface Reorderable {
8 | val orderNum: Double
9 | }
10 |
--------------------------------------------------------------------------------
/shared/data/model/src/main/kotlin/com/ivy/data/model/Value.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.model
2 |
3 | import com.ivy.data.model.primitive.AssetCode
4 | import com.ivy.data.model.primitive.NonZeroDouble
5 | import com.ivy.data.model.primitive.PositiveDouble
6 |
7 | /**
8 | * Represents monetary value. (like 10 USD, 5 EUR, 0.005 BTC, 12 GOLD_GRAM)
9 | */
10 | data class PositiveValue(
11 | val amount: PositiveDouble,
12 | val asset: AssetCode,
13 | )
14 |
15 | data class Value(
16 | val amount: NonZeroDouble,
17 | val asset: AssetCode,
18 | )
--------------------------------------------------------------------------------
/shared/data/model/src/main/kotlin/com/ivy/data/model/primitive/AssociationId.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.model.primitive
2 |
3 | import com.ivy.data.model.sync.UniqueId
4 | import java.util.UUID
5 |
6 | @JvmInline
7 | value class AssociationId(override val value: UUID) : UniqueId
--------------------------------------------------------------------------------
/shared/data/model/src/main/kotlin/com/ivy/data/model/primitive/ColorInt.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.model.primitive
2 |
3 | @JvmInline
4 | value class ColorInt(val value: Int)
5 |
--------------------------------------------------------------------------------
/shared/data/model/src/main/kotlin/com/ivy/data/model/primitive/PositiveInt.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.model.primitive
2 |
3 | import arrow.core.raise.Raise
4 | import arrow.core.raise.ensure
5 | import com.ivy.data.model.exact.Exact
6 |
7 | @JvmInline
8 | value class PositiveInt private constructor(val value: Int) {
9 | companion object : Exact {
10 | override val exactName = "PositiveInt"
11 |
12 | override fun Raise.spec(raw: Int): PositiveInt {
13 | ensure(raw > 0) { "$raw is not > 0" }
14 | return PositiveInt(raw)
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/shared/data/model/src/main/kotlin/com/ivy/data/model/sync/Identifiable.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.model.sync
2 |
3 | interface Identifiable {
4 | val id: ID
5 | }
6 |
--------------------------------------------------------------------------------
/shared/data/model/src/main/kotlin/com/ivy/data/model/sync/UniqueId.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.model.sync
2 |
3 | import java.util.UUID
4 |
5 | interface UniqueId {
6 | val value: UUID
7 | }
8 |
--------------------------------------------------------------------------------
/shared/data/model/src/main/kotlin/com/ivy/data/model/util/ValueRounding.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.data.model.util
2 |
3 | import com.ivy.data.model.PositiveValue
4 | import com.ivy.data.model.primitive.PositiveDouble
5 | import java.math.BigDecimal
6 | import java.math.RoundingMode
7 |
8 | fun PositiveValue.round(decimalPlaces: Int): PositiveValue = PositiveValue(
9 | amount = PositiveDouble.unsafe(amount.value.roundTo(decimalPlaces)),
10 | asset = asset,
11 | )
12 |
13 | fun Double.roundTo(decimalPlaces: Int): Double {
14 | return BigDecimal(this).setScale(decimalPlaces, RoundingMode.HALF_EVEN).toDouble()
15 | }
--------------------------------------------------------------------------------
/shared/domain/src/main/java/com/ivy/domain/AppStarter.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain
2 |
3 | import android.content.Intent
4 | import com.ivy.base.model.TransactionType
5 |
6 | /**
7 | * A component used to start the **RootActivity** without knowing about it.
8 | */
9 | interface AppStarter {
10 | fun getRootIntent(): Intent
11 | fun defaultStart()
12 | fun addTransactionStart(type: TransactionType)
13 | }
14 |
--------------------------------------------------------------------------------
/shared/domain/src/main/java/com/ivy/domain/features/FeatureGroup.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.features
2 |
3 | enum class FeatureGroup {
4 | Category, Account, Other
5 | }
--------------------------------------------------------------------------------
/shared/domain/src/main/java/com/ivy/domain/features/Features.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.features
2 |
3 | interface Features {
4 | val sortCategoriesAscending: BoolFeature
5 | val compactAccountsMode: BoolFeature
6 | val compactCategoriesMode: BoolFeature
7 | val showTitleSuggestions: BoolFeature
8 | val showCategorySearchBar: BoolFeature
9 | val hideTotalBalance: BoolFeature
10 | val showDecimalNumber: BoolFeature
11 | val standardKeypadLayout: BoolFeature
12 | val showAccountColorsInTransactions: BoolFeature
13 |
14 | val allFeatures: List
15 | }
16 |
--------------------------------------------------------------------------------
/shared/domain/src/main/java/com/ivy/domain/model/StatSummary.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.model
2 |
3 | import com.ivy.data.model.primitive.AssetCode
4 | import com.ivy.data.model.primitive.NonNegativeInt
5 | import com.ivy.data.model.primitive.PositiveDouble
6 |
7 | data class StatSummary(
8 | val trnCount: NonNegativeInt,
9 | val values: Map,
10 | ) {
11 | companion object {
12 | val Zero = StatSummary(
13 | values = emptyMap(),
14 | trnCount = NonNegativeInt.Zero
15 | )
16 | }
17 | }
--------------------------------------------------------------------------------
/shared/domain/src/main/java/com/ivy/domain/model/TimeRange.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.model
2 |
3 | import java.time.Instant
4 |
5 | sealed interface TimeRange {
6 | data object AllTime : TimeRange
7 |
8 | /**
9 | * @param time before this point in time (inclusive)
10 | */
11 | data class Before(val time: Instant) : TimeRange
12 |
13 | /**
14 | * @param time after this point in time (inclusive)
15 | */
16 | data class After(val time: Instant) : TimeRange
17 | }
--------------------------------------------------------------------------------
/shared/domain/src/test/java/com/ivy/domain/model/StatSummaryAssertion.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.domain.model
2 |
3 | import com.ivy.data.model.testing.shouldBeApprox
4 | import io.kotest.matchers.shouldBe
5 |
6 | infix fun StatSummary.shouldBeApprox(other: StatSummary) {
7 | trnCount shouldBe other.trnCount
8 | values.keys shouldBe other.values.keys
9 | values.keys.forEach { key ->
10 | values[key]!!.value shouldBeApprox other.values[key]!!.value
11 | }
12 | }
--------------------------------------------------------------------------------
/shared/ui/core/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.ui"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.domain)
12 | }
--------------------------------------------------------------------------------
/shared/ui/core/src/main/java/com/ivy/design/system/colors/ColorShades.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.design.system.colors
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | data class ColorShades(
6 | val extraLight: Color,
7 | val light: Color,
8 | val kindaLight: Color,
9 | val primary: Color,
10 | val kindaDark: Color,
11 | val dark: Color,
12 | val extraDark: Color,
13 | )
14 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/java/com/ivy/ui/time/DevicePreferences.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.ui.time
2 |
3 | import java.util.Locale
4 |
5 | interface DevicePreferences {
6 | fun is24HourFormat(): Boolean
7 | fun locale(): Locale
8 | }
--------------------------------------------------------------------------------
/shared/ui/core/src/main/java/com/ivy/ui/time/impl/AndroidDevicePreferences.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.ui.time.impl
2 |
3 | import android.content.Context
4 | import android.text.format.DateFormat
5 | import com.ivy.ui.time.DevicePreferences
6 | import dagger.hilt.android.qualifiers.ApplicationContext
7 | import java.util.Locale
8 | import javax.inject.Inject
9 |
10 | class AndroidDevicePreferences @Inject constructor(
11 | @ApplicationContext
12 | private val context: Context,
13 | ) : DevicePreferences {
14 | override fun is24HourFormat(): Boolean = DateFormat.is24HourFormat(context)
15 | override fun locale(): Locale = Locale.getDefault()
16 | }
--------------------------------------------------------------------------------
/shared/ui/core/src/main/java/com/ivy/ui/time/impl/DateTimePicker.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.ui.time.impl
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.Stable
5 | import java.time.Instant
6 | import java.time.LocalDate
7 | import java.time.LocalTime
8 |
9 | @Stable
10 | interface DateTimePicker {
11 | @Composable
12 | fun Content()
13 |
14 | fun pickDate(
15 | initialDate: Instant?,
16 | onDatePick: (LocalDate) -> Unit
17 | )
18 |
19 | fun pickTime(
20 | initialTime: LocalTime?,
21 | onTimePick: (LocalTime) -> Unit
22 | )
23 | }
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable-nodpi/donate_illustration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable-nodpi/donate_illustration.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable-nodpi/ivywallet_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable-nodpi/ivywallet_logo.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable-nodpi/monefy_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable-nodpi/monefy_logo.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable-nodpi/moneymanager_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable-nodpi/moneymanager_logo.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable-nodpi/spendee_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable-nodpi/spendee_logo.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable-nodpi/wallet_by_budgetbakers_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable-nodpi/wallet_by_budgetbakers_logo.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/bluecoins.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable/bluecoins.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/expense_shape_widget_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/financisto_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable/financisto_logo.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/fortune_city_app_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable/fortune_city_app_logo.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_arrow_right.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_attachment.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_category_edit.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_custom_xrp_l.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_custom_xrp_m.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_custom_xrp_s.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_done.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_expand_less.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_expand_more.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_file.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_filter_l.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_filter_xs.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_hamburger.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_outline_clear_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_popup_add.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_priority_dropdown.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_recurring_upcoming.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_refresh.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_remove.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_search.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_sort_by_alpha_24.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_statistics_s.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_statistics_xs.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_telegram_24dp.xml:
--------------------------------------------------------------------------------
1 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_time_tracking_play.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_visible.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_vue_crypto_thorchain.xml:
--------------------------------------------------------------------------------
1 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_vue_files_folder.xml:
--------------------------------------------------------------------------------
1 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_vue_main_timer.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
14 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ic_vue_weather_drop.xml:
--------------------------------------------------------------------------------
1 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/income_shape_widget_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/ktw_money_manager_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable/ktw_money_manager_logo.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/onboarding_illustration_accounts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable/onboarding_illustration_accounts.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/onboarding_illustration_categories.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable/onboarding_illustration_categories.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/onboarding_illustration_import.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable/onboarding_illustration_import.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/one_money_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable/one_money_logo.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/preview_widget_add_trn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable/preview_widget_add_trn.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/preview_widget_add_trn_compact.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable/preview_widget_add_trn_compact.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/preview_widget_wallet_balance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable/preview_widget_wallet_balance.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/questions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/drawable/questions.png
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/drawable/shape_widget_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/opensans_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/opensans_bold.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/opensans_bolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/opensans_bolditalic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/opensans_extrabold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/opensans_extrabold.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/opensans_extrabolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/opensans_extrabolditalic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/opensans_italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/opensans_italic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/opensans_light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/opensans_light.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/opensans_lightitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/opensans_lightitalic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/opensans_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/opensans_regular.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/opensans_semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/opensans_semibold.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/opensans_semibolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/opensans_semibolditalic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_black.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_blackitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_blackitalic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_bold.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_bolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_bolditalic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_extrabold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_extrabold.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_extrabolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_extrabolditalic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_extralight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_extralight.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_extralightitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_extralightitalic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_italic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_light.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_lightitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_lightitalic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_medium.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_mediumitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_mediumitalic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_regular.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_semibold.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_semibolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_semibolditalic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_thin.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/main/res/font/raleway_thinitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/main/res/font/raleway_thinitalic.ttf
--------------------------------------------------------------------------------
/shared/ui/core/src/test/snapshots/images/com.ivy.ui.component_OpenSourceCardPaparazziTest_default state[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/test/snapshots/images/com.ivy.ui.component_OpenSourceCardPaparazziTest_default state[Dark].png
--------------------------------------------------------------------------------
/shared/ui/core/src/test/snapshots/images/com.ivy.ui.component_OpenSourceCardPaparazziTest_default state[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/core/src/test/snapshots/images/com.ivy.ui.component_OpenSourceCardPaparazziTest_default state[Light].png
--------------------------------------------------------------------------------
/shared/ui/navigation/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.navigation"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.domain)
12 | implementation(projects.shared.ui.core)
13 | }
14 |
--------------------------------------------------------------------------------
/shared/ui/navigation/src/main/java/com/ivy/navigation/IvyPreview.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.navigation
2 |
3 | import androidx.compose.runtime.Composable
4 | import com.ivy.design.system.IvyMaterial3Theme
5 |
6 | @Composable
7 | fun IvyPreview(
8 | dark: Boolean = false,
9 | content: @Composable () -> Unit,
10 | ) {
11 | NavigationRoot(navigation = Navigation()) {
12 | IvyMaterial3Theme(dark = dark, isTrueBlack = false, content = content)
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/shared/ui/navigation/src/main/java/com/ivy/navigation/Screen.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.navigation
2 |
3 | /**
4 | * Marks a screen in the Ivy Wallet's navigation graph.
5 | * Extend it when creating a new screen.
6 | */
7 | sealed interface Screen {
8 | /**
9 | * Marks whether a given screen is a legacy Ivy Wallet one.
10 | * If it's a legacy screen, it automatically adds a Surface to make it work.
11 | * Do NOT mark new Material3 screens as legacy.
12 | */
13 | val isLegacy: Boolean
14 | get() = false
15 | }
16 |
--------------------------------------------------------------------------------
/shared/ui/testing/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.ui.testing"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.ui.core)
11 |
12 | // for this module we need test deps as "implementation" and not only "testImplementation"
13 | // because it'll be added as "testImplementation"
14 | implementation(libs.bundles.testing)
15 | implementation(libs.paparazzi)
16 | }
17 |
--------------------------------------------------------------------------------
/shared/ui/testing/src/test/snapshots/images/com.ivy.ui.testing_DemoPaparazziTest_snapshot demo composable[Dark].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/testing/src/test/snapshots/images/com.ivy.ui.testing_DemoPaparazziTest_snapshot demo composable[Dark].png
--------------------------------------------------------------------------------
/shared/ui/testing/src/test/snapshots/images/com.ivy.ui.testing_DemoPaparazziTest_snapshot demo composable[Light].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/shared/ui/testing/src/test/snapshots/images/com.ivy.ui.testing_DemoPaparazziTest_snapshot demo composable[Light].png
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/LoanExt.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy
2 |
3 | import com.ivy.base.legacy.stringRes
4 | import com.ivy.data.model.LoanType
5 | import com.ivy.legacy.datamodel.Loan
6 | import com.ivy.ui.R
7 |
8 | fun Loan.humanReadableType(): String {
9 | return if (type == LoanType.BORROW) {
10 | stringRes(R.string.borrowed_uppercase)
11 | } else {
12 | stringRes(R.string.lent_uppercase)
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/android/notification/IvyNotification.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.android.notification
2 |
3 | import android.content.Context
4 | import androidx.core.app.NotificationCompat
5 |
6 | class IvyNotification(
7 | context: Context,
8 | val ivyChannel: IvyNotificationChannel
9 | ) : NotificationCompat.Builder(context, ivyChannel.channelId)
10 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/data/AppBaseData.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.data
2 |
3 | import androidx.compose.runtime.Immutable
4 | import com.ivy.data.model.Category
5 | import com.ivy.legacy.datamodel.Account
6 | import kotlinx.collections.immutable.ImmutableList
7 |
8 | @Immutable
9 | data class AppBaseData(
10 | val baseCurrency: String,
11 | val accounts: ImmutableList,
12 | val categories: ImmutableList
13 | )
14 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/data/BufferInfo.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.data
2 |
3 | import androidx.compose.runtime.Immutable
4 | import java.math.BigDecimal
5 |
6 | @Immutable
7 | data class BufferInfo(
8 | val amount: BigDecimal,
9 | val bufferDiff: BigDecimal
10 | )
11 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/data/EditTransactionDisplayLoan.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.data
2 |
3 | import androidx.compose.runtime.Immutable
4 |
5 | @Immutable
6 | data class EditTransactionDisplayLoan(
7 | val isLoan: Boolean = false,
8 | val isLoanRecord: Boolean = false,
9 | val loanCaption: String? = null,
10 | val loanWarningDescription: String = ""
11 | )
12 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/data/model/AccountBalance.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.data.model
2 |
3 | import androidx.compose.runtime.Immutable
4 | import com.ivy.legacy.datamodel.Account
5 |
6 | @Immutable
7 | data class AccountBalance(
8 | val account: Account,
9 | val balance: Double
10 | )
11 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/data/model/MainTab.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.data.model
2 |
3 | import androidx.compose.runtime.Immutable
4 |
5 | @Immutable
6 | enum class MainTab {
7 | HOME, ACCOUNTS
8 | }
9 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/ExchangeRate.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.datamodel
2 |
3 | import androidx.compose.runtime.Immutable
4 | import com.ivy.data.db.entity.ExchangeRateEntity
5 |
6 | @Deprecated("Legacy data model. Will be deleted")
7 | @Immutable
8 | data class ExchangeRate(
9 | val baseCurrency: String,
10 | val currency: String,
11 | val rate: Double,
12 | ) {
13 | fun toEntity(): ExchangeRateEntity = ExchangeRateEntity(
14 | baseCurrency = baseCurrency,
15 | currency = currency,
16 | rate = rate
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/temp/AccountExt.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.datamodel.temp
2 |
3 | import com.ivy.data.db.entity.AccountEntity
4 | import com.ivy.legacy.datamodel.Account
5 |
6 | fun AccountEntity.toLegacyDomain(): Account = Account(
7 | name = name,
8 | currency = currency,
9 | color = color,
10 | icon = icon,
11 | orderNum = orderNum,
12 | includeInBalance = includeInBalance,
13 | isSynced = isSynced,
14 | isDeleted = isDeleted,
15 | id = id
16 | )
17 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/temp/CategoryExt.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.datamodel.temp
2 |
3 | import com.ivy.data.db.entity.CategoryEntity
4 | import com.ivy.legacy.datamodel.Category
5 |
6 | fun CategoryEntity.toLegacyDomain(): Category = Category(
7 | name = name,
8 | color = color,
9 | icon = icon,
10 | orderNum = orderNum,
11 | isSynced = isSynced,
12 | isDeleted = isDeleted,
13 | id = id
14 | )
15 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/temp/ExchangeRateExt.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.datamodel.temp
2 |
3 | import com.ivy.data.db.entity.ExchangeRateEntity
4 | import com.ivy.legacy.datamodel.ExchangeRate
5 |
6 | fun ExchangeRateEntity.toLegacyDomain(): ExchangeRate = ExchangeRate(
7 | baseCurrency = baseCurrency,
8 | currency = currency,
9 | rate = rate
10 | )
11 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/temp/LoanRecordExt.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.datamodel.temp
2 |
3 | import com.ivy.data.db.entity.LoanRecordEntity
4 | import com.ivy.legacy.datamodel.LoanRecord
5 |
6 | fun LoanRecordEntity.toLegacyDomain(): LoanRecord = LoanRecord(
7 | loanId = loanId,
8 | amount = amount,
9 | note = note,
10 | dateTime = dateTime,
11 | interest = interest,
12 | accountId = accountId,
13 | convertedAmount = convertedAmount,
14 | loanRecordType = loanRecordType,
15 | isSynced = isSynced,
16 | isDeleted = isDeleted,
17 | id = id
18 | )
19 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/datamodel/temp/SettingsExt.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.datamodel.temp
2 |
3 | import com.ivy.data.db.entity.SettingsEntity
4 | import com.ivy.legacy.datamodel.Settings
5 |
6 | fun SettingsEntity.toLegacyDomain(): Settings = Settings(
7 | theme = theme,
8 | baseCurrency = currency,
9 | bufferAmount = bufferAmount.toBigDecimal(),
10 | name = name,
11 | id = id
12 | )
13 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/action/loan/LoanByIdAct.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.action.loan
2 |
3 | import com.ivy.data.db.dao.read.LoanDao
4 | import com.ivy.frp.action.FPAction
5 | import com.ivy.legacy.datamodel.Loan
6 | import com.ivy.legacy.datamodel.temp.toLegacyDomain
7 | import java.util.UUID
8 | import javax.inject.Inject
9 |
10 | class LoanByIdAct @Inject constructor(
11 | private val loanDao: LoanDao
12 | ) : FPAction() {
13 | override suspend fun UUID.compose(): suspend () -> Loan? = suspend {
14 | loanDao.findById(this)?.toLegacyDomain()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/action/settings/BaseCurrencyAct.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.action.settings
2 |
3 | import com.ivy.data.db.dao.read.SettingsDao
4 | import com.ivy.frp.action.FPAction
5 | import javax.inject.Inject
6 |
7 | class BaseCurrencyAct @Inject constructor(
8 | private val settingsDao: SettingsDao
9 | ) : FPAction() {
10 | override suspend fun Unit.compose(): suspend () -> String = suspend {
11 | io { settingsDao.findFirst().currency }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/action/settings/CalcBufferDiffAct.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.action.settings
2 |
3 | import com.ivy.frp.action.FPAction
4 | import java.math.BigDecimal
5 | import javax.inject.Inject
6 |
7 | class CalcBufferDiffAct @Inject constructor() : FPAction() {
8 |
9 | override suspend fun Input.compose(): suspend () -> BigDecimal = {
10 | balance - buffer
11 | }
12 |
13 | data class Input(
14 | val balance: BigDecimal,
15 | val buffer: BigDecimal
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/action/settings/UpdateSettingsAct.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.domain.action.settings
2 |
3 | import com.ivy.data.db.dao.write.WriteSettingsDao
4 | import com.ivy.frp.action.FPAction
5 | import com.ivy.legacy.datamodel.Settings
6 | import javax.inject.Inject
7 |
8 | class UpdateSettingsAct @Inject constructor(
9 | private val writeSettingsDao: WriteSettingsDao
10 | ) : FPAction() {
11 | override suspend fun Settings.compose(): suspend () -> Settings = suspend {
12 | writeSettingsDao.save(this.toEntity())
13 | this
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/action/transaction/AllTrnsAct.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.action.transaction
2 |
3 | import com.ivy.data.model.Transaction
4 | import com.ivy.data.repository.TransactionRepository
5 | import com.ivy.frp.action.FPAction
6 | import javax.inject.Inject
7 |
8 | class AllTrnsAct @Inject constructor(
9 | private val transactionRepository: TransactionRepository
10 | ) : FPAction>() {
11 | override suspend fun Unit.compose(): suspend () -> List = suspend {
12 | transactionRepository.findAll()
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/action/viewmodel/home/HasTrnsAct.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.action.viewmodel.home
2 |
3 | import com.ivy.data.db.dao.read.TransactionDao
4 | import com.ivy.frp.action.FPAction
5 | import javax.inject.Inject
6 |
7 | class HasTrnsAct @Inject constructor(
8 | private val transactionDao: TransactionDao
9 | ) : FPAction() {
10 | override suspend fun Unit.compose(): suspend () -> Boolean = suspend {
11 | io {
12 | transactionDao.findAll_LIMIT_1().isNotEmpty()
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/action/viewmodel/home/ShouldHideBalanceAct.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.action.viewmodel.home
2 |
3 | import com.ivy.frp.action.FPAction
4 | import com.ivy.base.legacy.SharedPrefs
5 | import javax.inject.Inject
6 |
7 | class ShouldHideBalanceAct @Inject constructor(
8 | private val sharedPrefs: SharedPrefs
9 | ) : FPAction() {
10 | override suspend fun Unit.compose(): suspend () -> Boolean = {
11 | sharedPrefs.getBoolean(
12 | SharedPrefs.HIDE_CURRENT_BALANCE,
13 | false
14 | )
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/action/viewmodel/home/ShouldHideIncomeAct.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.domain.action.viewmodel.home
2 |
3 | import com.ivy.frp.action.FPAction
4 | import com.ivy.base.legacy.SharedPrefs
5 | import javax.inject.Inject
6 |
7 | class ShouldHideIncomeAct @Inject constructor(
8 | private val sharedPrefs: SharedPrefs
9 | ) : FPAction() {
10 | override suspend fun Unit.compose(): suspend () -> Boolean = {
11 | sharedPrefs.getBoolean(
12 | SharedPrefs.HIDE_INCOME,
13 | false
14 | )
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/data/CustomExchangeRateState.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.data
2 |
3 | import androidx.compose.runtime.Immutable
4 |
5 | @Immutable
6 | data class CustomExchangeRateState(
7 | val showCard: Boolean = false,
8 | val toCurrencyCode: String? = null,
9 | val fromCurrencyCode: String? = null,
10 | val exchangeRate: Double = 1.0,
11 | val convertedAmount: Double? = null
12 | )
13 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/data/Reorderable.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.data
2 |
3 | interface Reorderable {
4 | fun getItemOrderNum(): Double
5 |
6 | fun withNewOrderNum(newOrderNum: Double): Reorderable
7 | }
8 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/data/SortOrder.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.data
2 |
3 | enum class SortOrder(val orderNum: Int, val displayName: String) {
4 | DEFAULT(0, "Default"),
5 | BALANCE_AMOUNT(1, "Balance Amount"),
6 | EXPENSES(2, "Expenses"),
7 | ALPHABETICAL(3, "Alphabetical");
8 |
9 | companion object {
10 | fun from(orderNum: Int): SortOrder {
11 | return values().firstOrNull { it.orderNum == orderNum } ?: DEFAULT
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/data/TransactionHistoryDateDivider.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.data
2 |
3 | import androidx.compose.runtime.Immutable
4 | import com.ivy.base.legacy.TransactionHistoryItem
5 | import java.time.LocalDate
6 |
7 | @Immutable
8 | data class TransactionHistoryDateDivider(
9 | val date: LocalDate,
10 | val income: Double,
11 | val expenses: Double
12 | ) : TransactionHistoryItem
13 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/model/CreateAccountData.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.deprecated.logic.model
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | data class CreateAccountData(
6 | val name: String,
7 | val currency: String,
8 | val color: Color,
9 | val icon: String?,
10 | val balance: Double,
11 | val includeBalance: Boolean = true,
12 | )
13 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/model/CreateBudgetData.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.deprecated.logic.model
2 |
3 | data class CreateBudgetData(
4 | val name: String,
5 | val amount: Double,
6 | val categoryIdsSerialized: String,
7 | val accountIdsSerialized: String
8 | )
9 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/model/CreateCategoryData.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.deprecated.logic.model
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | data class CreateCategoryData(
6 | val name: String,
7 | val color: Color,
8 | val icon: String?
9 | )
10 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/model/CreateLoanData.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.deprecated.logic.model
2 |
3 | import androidx.compose.ui.graphics.Color
4 | import com.ivy.data.model.LoanType
5 | import com.ivy.legacy.datamodel.Account
6 | import java.time.LocalDateTime
7 |
8 | data class CreateLoanData(
9 | val name: String,
10 | val amount: Double,
11 | val type: LoanType,
12 | val color: Color,
13 | val icon: String?,
14 | val account: Account? = null,
15 | val note: String?,
16 | val createLoanTransaction: Boolean = false,
17 | val dateTime: LocalDateTime
18 | )
19 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/model/CreateLoanRecordData.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.deprecated.logic.model
2 |
3 | import com.ivy.base.model.LoanRecordType
4 | import com.ivy.legacy.datamodel.Account
5 | import java.time.Instant
6 |
7 | data class CreateLoanRecordData(
8 | val note: String?,
9 | val amount: Double,
10 | val dateTime: Instant,
11 | val interest: Boolean = false,
12 | val account: Account? = null,
13 | val createLoanRecordTransaction: Boolean = false,
14 | val convertedAmount: Double? = null,
15 | val loanRecordType: LoanRecordType
16 | )
17 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/deprecated/logic/model/EditLoanRecordData.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.deprecated.logic.model
2 |
3 | import com.ivy.legacy.datamodel.LoanRecord
4 |
5 | data class EditLoanRecordData(
6 | val newLoanRecord: LoanRecord,
7 | val originalLoanRecord: LoanRecord,
8 | val createLoanRecordTransaction: Boolean = false,
9 | val reCalculateLoanAmount: Boolean = false
10 | )
11 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/pure/account/AccountFunctions.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.pure.account
2 |
3 | import com.ivy.legacy.datamodel.Account
4 |
5 | fun filterExcluded(accounts: List): List =
6 | accounts.filter { it.includeInBalance }
7 |
8 | fun accountCurrency(account: Account, baseCurrency: String): String =
9 | account.currency ?: baseCurrency
10 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/pure/data/IncomeExpensePair.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.pure.data
2 |
3 | import androidx.compose.runtime.Immutable
4 | import java.math.BigDecimal
5 |
6 | @Immutable
7 | data class IncomeExpensePair(
8 | val income: BigDecimal,
9 | val expense: BigDecimal
10 | ) {
11 | companion object {
12 | fun zero(): IncomeExpensePair = IncomeExpensePair(BigDecimal.ZERO, BigDecimal.ZERO)
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/pure/data/IncomeExpenseTransferPair.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.pure.data
2 |
3 | import java.math.BigDecimal
4 |
5 | data class IncomeExpenseTransferPair(
6 | val income: BigDecimal,
7 | val expense: BigDecimal,
8 | val transferIncome: BigDecimal,
9 | val transferExpense: BigDecimal
10 | ) {
11 | companion object {
12 | fun zero(): IncomeExpenseTransferPair = IncomeExpenseTransferPair(
13 | BigDecimal.ZERO,
14 | BigDecimal.ZERO,
15 | BigDecimal.ZERO,
16 | BigDecimal.ZERO
17 | )
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/pure/data/WalletDAOs.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.pure.data
2 |
3 | import com.ivy.data.db.dao.read.AccountDao
4 | import com.ivy.data.db.dao.read.ExchangeRatesDao
5 | import com.ivy.data.db.dao.read.TransactionDao
6 | import javax.inject.Inject
7 |
8 | data class WalletDAOs @Inject constructor(
9 | val accountDao: AccountDao,
10 | val transactionDao: TransactionDao,
11 | val exchangeRatesDao: ExchangeRatesDao
12 | )
13 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/domain/pure/util/IvyDomainUtils.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.wallet.domain.pure.util
2 |
3 | fun Double?.nextOrderNum(): Double = this?.plus(1) ?: 0.0
4 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/frp/Utils.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.frp
2 |
3 | @Deprecated("Legacy code. Don't use it, please.")
4 | suspend fun List.sumOfSuspend(
5 | selector: suspend (A) -> Double
6 | ): Double {
7 | var sum = 0.0
8 | for (item in this) {
9 | sum += selector(item)
10 | }
11 | return sum
12 | }
13 |
14 | @Deprecated("Legacy code. Don't use it, please.")
15 | suspend fun Collection.filterSuspend(
16 | predicate: suspend (A) -> Boolean
17 | ): Collection {
18 | return this.filter { a ->
19 | predicate(a)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/frp/test/TestingContext.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.frp.test
2 |
3 | @Deprecated("Legacy code. Don't use it, please.")
4 | object TestingContext {
5 | var inTest = false
6 | }
7 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/frp/viewmodel/ViewmodelUtils.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.frp.viewmodel
2 |
3 | import kotlinx.coroutines.flow.MutableStateFlow
4 | import kotlinx.coroutines.flow.StateFlow
5 |
6 | @Deprecated("Legacy code. Don't use it, please.")
7 | fun MutableStateFlow.readOnly(): StateFlow {
8 | return this
9 | }
10 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/utils/InputError.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.utils
2 |
3 | open class InputError(msg: String) : Exception(msg)
4 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/utils/OpResult.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.utils
2 |
3 | sealed class OpResult {
4 | object Loading : OpResult()
5 | data class Success(val data: T) : OpResult()
6 | data class Failure(val exception: Exception) : OpResult() {
7 | fun error() = exception.message ?: exception.cause?.message ?: "unknown"
8 | }
9 |
10 | companion object {
11 | fun success(data: T) = Success(data)
12 | fun loading() = Loading
13 | fun failure(e: Exception) = Failure(e)
14 | fun faliure(errMsg: String) = Failure(Exception(errMsg))
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/temp/legacy-code/src/main/java/com/ivy/legacy/utils/ValidationExt.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.legacy.utils
2 |
3 | fun String?.isNotNullOrBlank(): Boolean {
4 | return this != null && this.isNotBlank()
5 | }
6 |
--------------------------------------------------------------------------------
/temp/old-design/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.feature")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.design"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.ui.core)
12 |
13 | implementation(projects.shared.domain)
14 | }
--------------------------------------------------------------------------------
/temp/old-design/src/main/java/com/ivy/design/l0_system/IvyTypography.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.design.l0_system
2 |
3 | import androidx.compose.ui.text.TextStyle
4 |
5 | @Deprecated("Old design system. Use `:ivy-design` and Material3")
6 | interface IvyTypography {
7 | val h1: TextStyle
8 | val h2: TextStyle
9 | val b1: TextStyle
10 | val b2: TextStyle
11 | val c: TextStyle
12 |
13 | val nH1: TextStyle
14 | val nH2: TextStyle
15 | val nB1: TextStyle
16 | val nB2: TextStyle
17 | val nC: TextStyle
18 | }
19 |
--------------------------------------------------------------------------------
/temp/old-design/src/main/java/com/ivy/design/l1_buildingBlocks/data/IvyPadding.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.design.l1_buildingBlocks.data
2 |
3 | import androidx.compose.ui.unit.Dp
4 |
5 | @Deprecated("Old design system. Use `:ivy-design` and Material3")
6 | data class IvyPadding(
7 | val top: Dp?,
8 | val bottom: Dp?,
9 | val start: Dp?,
10 | val end: Dp?
11 | )
12 |
--------------------------------------------------------------------------------
/temp/old-design/src/main/java/com/ivy/design/utils/Android.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.design.utils
2 |
3 | import android.os.Handler
4 | import android.os.Looper
5 |
6 | @Deprecated("Old design system. Use `:ivy-design` and Material3")
7 | fun postDelayed(delayMs: Long, run: () -> Unit) {
8 | Handler(Looper.getMainLooper()).postDelayed({ run() }, delayMs)
9 | }
10 |
--------------------------------------------------------------------------------
/temp/old-design/src/main/java/com/ivy/design/utils/Animation.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.design.utils
2 |
3 | import androidx.compose.animation.core.spring
4 |
5 | @Deprecated("Old design system. Use `:ivy-design` and Material3")
6 | fun springBounce(
7 | stiffness: Float = 500f,
8 | ) = spring(
9 | dampingRatio = 0.75f,
10 | stiffness = stiffness,
11 | )
12 |
--------------------------------------------------------------------------------
/temp/old-design/src/main/java/com/ivy/design/utils/View.kt:
--------------------------------------------------------------------------------
1 | package com.ivy.design.utils
2 |
3 | import android.content.Context
4 | import android.util.DisplayMetrics
5 | import kotlin.math.roundToInt
6 |
7 | @Deprecated("Old design system. Use `:ivy-design` and Material3")
8 | fun Float.dpToPx(context: Context): Float {
9 | return this * (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
10 | }
11 |
12 | @Deprecated("Old design system. Use `:ivy-design` and Material3")
13 | fun Int.dpToPx(context: Context): Int {
14 | return this.toFloat().dpToPx(context).roundToInt()
15 | }
16 |
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/drawable/ic_android_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/drawable/ic_baseline_add_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/opensans_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/opensans_bold.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/opensans_bolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/opensans_bolditalic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/opensans_extrabold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/opensans_extrabold.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/opensans_extrabolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/opensans_extrabolditalic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/opensans_italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/opensans_italic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/opensans_light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/opensans_light.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/opensans_lightitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/opensans_lightitalic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/opensans_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/opensans_regular.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/opensans_semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/opensans_semibold.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/opensans_semibolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/opensans_semibolditalic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_black.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_blackitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_blackitalic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_bold.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_bolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_bolditalic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_extrabold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_extrabold.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_extrabolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_extrabolditalic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_extralight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_extralight.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_extralightitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_extralightitalic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_italic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_light.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_lightitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_lightitalic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_medium.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_mediumitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_mediumitalic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_regular.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_semibold.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_semibolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_semibolditalic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_thin.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/font/raleway_thinitalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ivy-Apps/ivy-wallet/2c26ed1703b7308c26121f01c606e0f4cb50b7e4/temp/old-design/src/main/res/font/raleway_thinitalic.ttf
--------------------------------------------------------------------------------
/temp/old-design/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFC34CFF
4 |
--------------------------------------------------------------------------------
/widget/add-transaction/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.widget")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.widget.transaction"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.base)
12 | implementation(projects.shared.domain)
13 | implementation(projects.shared.ui.core)
14 | implementation(projects.shared.ui.navigation)
15 |
16 | implementation(projects.widget.sharedBase)
17 | }
18 |
--------------------------------------------------------------------------------
/widget/add-transaction/src/main/res/drawable/widget_compact_divider.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
--------------------------------------------------------------------------------
/widget/add-transaction/src/main/res/xml/add_transaction_widget_compact_info.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/widget/add-transaction/src/main/res/xml/add_transaction_widget_info.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/widget/add-transaction/src/main/res/xml/wallet_balance_widget_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/widget/balance/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.widget")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.widget.balance"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.domain)
12 | implementation(projects.shared.ui.core)
13 | implementation(projects.shared.ui.navigation)
14 |
15 | implementation(projects.temp.oldDesign)
16 | implementation(projects.widget.sharedBase)
17 | implementation(projects.temp.legacyCode)
18 | }
19 |
--------------------------------------------------------------------------------
/widget/shared-base/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("ivy.widget")
3 | }
4 |
5 | android {
6 | namespace = "com.ivy.widget"
7 | }
8 |
9 | dependencies {
10 | implementation(projects.shared.base)
11 | implementation(projects.shared.domain)
12 | }
13 |
--------------------------------------------------------------------------------