├── debug.keystore
├── .gitmodules
├── gradle
├── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
└── libs.versions.toml
├── app
├── src
│ ├── main
│ │ ├── ic_launcher-playstore.png
│ │ ├── res
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── raw
│ │ │ │ ├── mascot_searching.lottie
│ │ │ │ ├── mountain_gondola.lottie
│ │ │ │ ├── swiss_with_flag.lottie
│ │ │ │ ├── storage_cardboard_box_pile.lottie
│ │ │ │ ├── three_cards_transfer_type.lottie
│ │ │ │ └── two_locks_intertwined_stars.lottie
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── raw-night
│ │ │ │ ├── mascot_searching.lottie
│ │ │ │ ├── mountain_gondola.lottie
│ │ │ │ ├── swiss_with_flag.lottie
│ │ │ │ ├── storage_cardboard_box_pile.lottie
│ │ │ │ ├── three_cards_transfer_type.lottie
│ │ │ │ └── two_locks_intertwined_stars.lottie
│ │ │ ├── drawable-hdpi
│ │ │ │ ├── splashscreen_icon_legacy.webp
│ │ │ │ └── splashscreen_branding_image_legacy.webp
│ │ │ ├── drawable-mdpi
│ │ │ │ ├── splashscreen_icon_legacy.webp
│ │ │ │ └── splashscreen_branding_image_legacy.webp
│ │ │ ├── drawable-xhdpi
│ │ │ │ ├── splashscreen_icon_legacy.webp
│ │ │ │ └── splashscreen_branding_image_legacy.webp
│ │ │ ├── drawable-xxhdpi
│ │ │ │ ├── splashscreen_icon_legacy.webp
│ │ │ │ └── splashscreen_branding_image_legacy.webp
│ │ │ ├── drawable-xxxhdpi
│ │ │ │ ├── splashscreen_icon_legacy.webp
│ │ │ │ └── splashscreen_branding_image_legacy.webp
│ │ │ ├── resources.properties
│ │ │ ├── values-night
│ │ │ │ └── colors.xml
│ │ │ ├── xml
│ │ │ │ ├── locales_config.xml
│ │ │ │ ├── network_security_config.xml
│ │ │ │ ├── backup_rules.xml
│ │ │ │ └── data_extraction_rules.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── drawable
│ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ ├── splashscreen_legacy.xml
│ │ │ │ ├── flag_ge.xml
│ │ │ │ ├── flag_it.xml
│ │ │ │ ├── flag_fr.xml
│ │ │ │ ├── ic_launcher_monochrome.xml
│ │ │ │ ├── splashscreen_gradient_legacy.xml
│ │ │ │ └── ic_logo_notification.xml
│ │ │ ├── values
│ │ │ │ ├── colors.xml
│ │ │ │ └── themes.xml
│ │ │ └── values-v31
│ │ │ │ └── themes.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── infomaniak
│ │ │ └── swisstransfer
│ │ │ ├── ui
│ │ │ ├── screen
│ │ │ │ ├── newtransfer
│ │ │ │ │ ├── NewTransferOpenManager.kt
│ │ │ │ │ ├── PickedFile.kt
│ │ │ │ │ ├── NewTransferViewModel.kt
│ │ │ │ │ ├── upload
│ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ └── WeightOneSpacer.kt
│ │ │ │ │ │ └── UploadProgressAdType.kt
│ │ │ │ │ ├── NewTransferScreen.kt
│ │ │ │ │ ├── AlreadyUsedFileNamesSet.kt
│ │ │ │ │ └── validateemail
│ │ │ │ │ │ └── HideSelectAllTextToolbar.kt
│ │ │ │ └── main
│ │ │ │ │ ├── transferdetails
│ │ │ │ │ ├── TransferDownloadUi.kt
│ │ │ │ │ └── emptystate
│ │ │ │ │ │ ├── VirusCheckContent.kt
│ │ │ │ │ │ ├── UnknownTransferErrorContent.kt
│ │ │ │ │ │ └── VirusDetectedContent.kt
│ │ │ │ │ ├── components
│ │ │ │ │ └── SwissTransferScaffold.kt
│ │ │ │ │ ├── settings
│ │ │ │ │ ├── components
│ │ │ │ │ │ └── SettingDivider.kt
│ │ │ │ │ ├── SettingsSentryViewModel.kt
│ │ │ │ │ └── SettingsViewModel.kt
│ │ │ │ │ ├── transfers
│ │ │ │ │ ├── DeleteTransferUseCase.kt
│ │ │ │ │ └── components
│ │ │ │ │ │ └── DeleteTransferDialog.kt
│ │ │ │ │ └── DeeplinkViewModel.kt
│ │ │ ├── images
│ │ │ │ ├── AppImages.kt
│ │ │ │ ├── ThemedImage.kt
│ │ │ │ ├── illus
│ │ │ │ │ ├── beers
│ │ │ │ │ │ └── Beers.kt
│ │ │ │ │ ├── matomo
│ │ │ │ │ │ └── Matomo.kt
│ │ │ │ │ ├── sentry
│ │ │ │ │ │ └── Sentry.kt
│ │ │ │ │ ├── mascotDead
│ │ │ │ │ │ └── MascotDead.kt
│ │ │ │ │ ├── dataProtection
│ │ │ │ │ │ └── DataProtection.kt
│ │ │ │ │ ├── mascotSearching
│ │ │ │ │ │ └── MascotSearching.kt
│ │ │ │ │ ├── mascotWithMagnifyingGlass
│ │ │ │ │ │ └── MascotWithMagnifyingGlass.kt
│ │ │ │ │ ├── uploadCancelBottomSheet
│ │ │ │ │ │ └── RedCrossPaperPlanes.kt
│ │ │ │ │ ├── onboarding
│ │ │ │ │ │ ├── RadialGradientCornerTopLeft.kt
│ │ │ │ │ │ └── RadialGradientCornerTopRight.kt
│ │ │ │ │ ├── uploadError
│ │ │ │ │ │ └── GhostMagnifyingGlassQuestionMark.kt
│ │ │ │ │ ├── ghostPointingReport
│ │ │ │ │ │ └── GhostPointingReport.kt
│ │ │ │ │ ├── ghostScanningSquare
│ │ │ │ │ │ └── GhostScanningSquare.kt
│ │ │ │ │ └── appIntegrity
│ │ │ │ │ │ └── GhostScrollCrossPointing.kt
│ │ │ │ └── icons
│ │ │ │ │ ├── matomo
│ │ │ │ │ └── Matomo.kt
│ │ │ │ │ ├── sentry
│ │ │ │ │ └── Sentry.kt
│ │ │ │ │ └── qrInfomaniak
│ │ │ │ │ └── QrInfomaniak.kt
│ │ │ ├── utils
│ │ │ │ ├── GetSetCallbacks.kt
│ │ │ │ ├── ThemeUtils.kt
│ │ │ │ ├── FileUiExt.kt
│ │ │ │ ├── LastTransferPreferences.kt
│ │ │ │ ├── DataManagementPreferences.kt
│ │ │ │ ├── ScreenWrapperUtils.kt
│ │ │ │ ├── DeeplinkExt.kt
│ │ │ │ ├── TextUtils.kt
│ │ │ │ ├── NotificationPermissionUtils.kt
│ │ │ │ ├── DataStoreUtils.kt
│ │ │ │ ├── AccountUtils.kt
│ │ │ │ └── PermissionsUtils.kt
│ │ │ ├── AppUpdateManageable.kt
│ │ │ ├── previewparameter
│ │ │ │ ├── TransferUiListPreviewParameterProvider.kt
│ │ │ │ └── EmailsPreviewParameterProvider.kt
│ │ │ ├── navigation
│ │ │ │ ├── ExternalNavigation.kt
│ │ │ │ └── NavigationItem.kt
│ │ │ ├── theme
│ │ │ │ ├── CustomShapes.kt
│ │ │ │ └── Dimens.kt
│ │ │ ├── AppReviewManageable.kt
│ │ │ └── components
│ │ │ │ ├── SmallWindowScreenTitle.kt
│ │ │ │ ├── ReviewAlertDialog.kt
│ │ │ │ ├── TextDotText.kt
│ │ │ │ ├── SharpRippleButton.kt
│ │ │ │ ├── EmailsFlowRow.kt
│ │ │ │ └── NewTransferFab.kt
│ │ │ ├── di
│ │ │ ├── ClientQualifiers.kt
│ │ │ ├── CoroutinesQualifiers.kt
│ │ │ ├── CoroutinesDispatchersModule.kt
│ │ │ └── ApplicationModule.kt
│ │ │ └── upload
│ │ │ ├── StartUploadRequest.kt
│ │ │ ├── PickedFileExt.kt
│ │ │ ├── PickedFilesExtractor.kt
│ │ │ ├── NewTransferParams.kt
│ │ │ ├── NewTransferParamsExt.kt
│ │ │ └── InputStreamCounter.kt
│ ├── preprod
│ │ └── res
│ │ │ ├── mipmap
│ │ │ ├── ic_launcher.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ │ └── drawable
│ │ │ ├── ic_launcher_background.xml
│ │ │ └── ic_launcher_monochrome.xml
│ ├── prod
│ │ └── src
│ │ │ └── res
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ └── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.webp
│ │ │ └── ic_launcher_round.webp
│ ├── androidTest
│ │ └── java
│ │ │ └── com
│ │ │ └── infomaniak
│ │ │ └── swisstransfer
│ │ │ └── ExampleInstrumentedTest.kt
│ └── test
│ │ └── java
│ │ └── com
│ │ └── infomaniak
│ │ └── swisstransfer
│ │ ├── NavigationDestinationUnitTest.kt
│ │ └── TransferDatesUnitTest.kt
└── proguard-rules.pro
├── .idea
├── codeStyles
│ └── codeStyleConfig.xml
├── copyright
│ ├── profiles_settings.xml
│ └── Infomaniak_Open_Source.xml
└── icon.svg
├── .github
├── workflows
│ ├── auto-author-assign.yml
│ ├── dependent-issues.yml
│ ├── semantic-commit.yml
│ ├── android.yml
│ ├── translations-validation.yml
│ └── rebase-default-branch.yml
└── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── .gitignore
├── env.example.properties
├── gradle.properties
└── settings.gradle.kts
/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/debug.keystore
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "Core"]
2 | path = Core
3 | url = git@github.com:Infomaniak/android-core.git
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/raw/mascot_searching.lottie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/raw/mascot_searching.lottie
--------------------------------------------------------------------------------
/app/src/main/res/raw/mountain_gondola.lottie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/raw/mountain_gondola.lottie
--------------------------------------------------------------------------------
/app/src/main/res/raw/swiss_with_flag.lottie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/raw/swiss_with_flag.lottie
--------------------------------------------------------------------------------
/app/src/preprod/res/mipmap/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/preprod/res/mipmap/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/raw-night/mascot_searching.lottie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/raw-night/mascot_searching.lottie
--------------------------------------------------------------------------------
/app/src/main/res/raw-night/mountain_gondola.lottie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/raw-night/mountain_gondola.lottie
--------------------------------------------------------------------------------
/app/src/main/res/raw-night/swiss_with_flag.lottie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/raw-night/swiss_with_flag.lottie
--------------------------------------------------------------------------------
/app/src/preprod/res/mipmap/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/preprod/res/mipmap/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/prod/src/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/prod/src/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/prod/src/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/prod/src/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/prod/src/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/prod/src/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/prod/src/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/prod/src/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/prod/src/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/prod/src/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/raw/storage_cardboard_box_pile.lottie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/raw/storage_cardboard_box_pile.lottie
--------------------------------------------------------------------------------
/app/src/main/res/raw/three_cards_transfer_type.lottie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/raw/three_cards_transfer_type.lottie
--------------------------------------------------------------------------------
/app/src/main/res/raw/two_locks_intertwined_stars.lottie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/raw/two_locks_intertwined_stars.lottie
--------------------------------------------------------------------------------
/app/src/prod/src/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/prod/src/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/prod/src/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/prod/src/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/prod/src/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/prod/src/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/prod/src/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/prod/src/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/splashscreen_icon_legacy.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/drawable-hdpi/splashscreen_icon_legacy.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/splashscreen_icon_legacy.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/drawable-mdpi/splashscreen_icon_legacy.webp
--------------------------------------------------------------------------------
/app/src/main/res/raw-night/storage_cardboard_box_pile.lottie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/raw-night/storage_cardboard_box_pile.lottie
--------------------------------------------------------------------------------
/app/src/main/res/raw-night/three_cards_transfer_type.lottie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/raw-night/three_cards_transfer_type.lottie
--------------------------------------------------------------------------------
/app/src/prod/src/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/prod/src/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/splashscreen_icon_legacy.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/drawable-xhdpi/splashscreen_icon_legacy.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/splashscreen_icon_legacy.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/drawable-xxhdpi/splashscreen_icon_legacy.webp
--------------------------------------------------------------------------------
/app/src/main/res/raw-night/two_locks_intertwined_stars.lottie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/raw-night/two_locks_intertwined_stars.lottie
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/splashscreen_icon_legacy.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/drawable-xxxhdpi/splashscreen_icon_legacy.webp
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/splashscreen_branding_image_legacy.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/drawable-hdpi/splashscreen_branding_image_legacy.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/splashscreen_branding_image_legacy.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/drawable-mdpi/splashscreen_branding_image_legacy.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/splashscreen_branding_image_legacy.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/drawable-xhdpi/splashscreen_branding_image_legacy.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/splashscreen_branding_image_legacy.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/drawable-xxhdpi/splashscreen_branding_image_legacy.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/splashscreen_branding_image_legacy.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infomaniak/android-SwissTransfer/HEAD/app/src/main/res/drawable-xxxhdpi/splashscreen_branding_image_legacy.webp
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jul 17 16:05:07 CEST 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/.github/workflows/auto-author-assign.yml:
--------------------------------------------------------------------------------
1 | name: Auto Author Assign
2 |
3 | on:
4 | pull_request_target:
5 | types: [ opened, reopened ]
6 |
7 | concurrency:
8 | group: ${{ github.workflow }}-${{ github.ref }}
9 | cancel-in-progress: true
10 |
11 | permissions:
12 | pull-requests: write
13 |
14 | jobs:
15 | assign-author:
16 | runs-on: ubuntu-latest
17 | steps:
18 | - uses: toshimaru/auto-author-assign@v2.1.1
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.aab
2 | *.apk
3 | /app/release/baselineProfiles
4 | /app/src/androidTest/java/com/infomaniak/drive/utils/Env.kt
5 | /app/src/standard/java/com/infomaniak/drive/GeniusScanEnv.kt
6 | **/build
7 | **/captures
8 | .cxx
9 | .DS_Store
10 | env.properties
11 | uitest-env.properties
12 | .externalNativeBuild
13 | .gradle
14 | **/.idea
15 | !.idea/icon.svg
16 | /.idea/navEditor.xml
17 | *.iml
18 | .kotlin/errors
19 | .kotlin/sessions
20 | **/local.properties
21 | *.realm
22 | *.realm.lock
23 | *.mx
24 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | *Note: Please write your issue only in english*
11 |
12 | **Is your feature request related to a problem? Please describe.**
13 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
14 |
15 | **Describe the solution you'd like**
16 | A clear and concise description of what you want to happen.
17 |
18 | **Describe alternatives you've considered**
19 | A clear and concise description of any alternative solutions or features you've considered.
20 |
21 | **Additional context**
22 | Add any other context or screenshots about the feature request here.
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/NewTransferOpenManager.kt:
--------------------------------------------------------------------------------
1 | package com.infomaniak.swisstransfer.ui.screen.newtransfer
2 |
3 | import android.net.Uri
4 | import kotlinx.coroutines.channels.Channel
5 | import javax.inject.Inject
6 | import javax.inject.Singleton
7 |
8 | @Singleton
9 | class NewTransferOpenManager @Inject constructor() {
10 | sealed interface Reason {
11 | data class ExternalShareIncoming(val uris: List) : Reason
12 | data object Other : Reason
13 | }
14 |
15 | suspend fun readOpenReason(): Reason = reasonChannel.receive()
16 |
17 | fun setOpenReason(reason: Reason) {
18 | reasonChannel.trySend(reason)
19 | }
20 |
21 | private val reasonChannel = Channel(capacity = 1)
22 | }
23 |
--------------------------------------------------------------------------------
/.github/workflows/dependent-issues.yml:
--------------------------------------------------------------------------------
1 | name: Dependent Issues
2 |
3 | on:
4 | issues:
5 | types:
6 | - opened
7 | - edited
8 | - closed
9 | - reopened
10 | pull_request_target:
11 | types:
12 | - opened
13 | - edited
14 | - closed
15 | - reopened
16 | # Makes sure we always add status check for PRs. Useful only if
17 | # this action is required to pass before merging. Otherwise, it
18 | # can be removed.
19 | - synchronize
20 |
21 | concurrency:
22 | group: ${{ github.workflow }}-${{ github.ref }}
23 | cancel-in-progress: true
24 |
25 | jobs:
26 | check:
27 | runs-on: ubuntu-latest
28 | steps:
29 | - uses: z0al/dependent-issues@v1.5.2
30 | env:
31 | # (Required) The token to use to make API calls to GitHub.
32 | GITHUB_TOKEN: ${{ github.token }}
33 |
--------------------------------------------------------------------------------
/app/src/main/res/resources.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Infomaniak SwissTransfer - Android
3 | # Copyright (C) 2024 Infomaniak Network SA
4 | #
5 | # This program is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # This program is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with this program. If not, see .
17 | #
18 | #
19 | # Set default locale
20 | unqualifiedResLocale=en
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | *Note: Please write your issue only in english*
11 |
12 | **Description**
13 | A clear and concise description of what the bug is.
14 |
15 | **Steps to reproduce**
16 | Steps to reproduce the behavior:
17 |
18 | 1. Go to '...'
19 | 2. Click on '....'
20 | 3. Scroll down to '....'
21 | 4. See error
22 |
23 | **Expected behavior**
24 | A clear and concise description of what you expected to happen.
25 |
26 | **Screenshots**
27 | If applicable, add screenshots to help explain your problem.
28 |
29 | **Smartphone (please complete the following information):**
30 |
31 | - Device: [e.g. Samsung S20 Ultra 5G]
32 | - Android version: [e.g. Android 11]
33 | - App version: [e.g. 1.0.1]
34 |
35 | **Additional context**
36 | Add any other context about the problem here.
37 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 | #156E61
20 |
21 |
--------------------------------------------------------------------------------
/.github/workflows/semantic-commit.yml:
--------------------------------------------------------------------------------
1 | name: 'PR and Commit Message Check'
2 | on:
3 | pull_request_target:
4 | types:
5 | - opened
6 | - edited
7 | - reopened
8 | - synchronize
9 |
10 | concurrency:
11 | group: ${{ github.workflow }}-${{ github.ref }}
12 | cancel-in-progress: true
13 |
14 | jobs:
15 | check-commit-message:
16 | name: Check Commit Message
17 | runs-on: ubuntu-latest
18 | steps:
19 | - name: Check Commit Message
20 | uses: gsactions/commit-message-checker@v2
21 | with:
22 | pattern: '^Merge .+|(^(feat|fix|chore|docs|style|refactor|perf|ci|test)(\(.+\))?: [A-Z0-9].+)'
23 | error: 'Commit messages and PR title should match conventional commit convention and start with an uppercase.'
24 | excludeDescription: 'true'
25 | excludeTitle: 'false'
26 | checkAllCommitMessages: 'true'
27 | accessToken: ${{ secrets.GITHUB_TOKEN }}
28 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/env.example.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Infomaniak SwissTransfer - Android
3 | # Copyright (C) 2024 Infomaniak Network SA
4 | #
5 | # This program is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # This program is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with this program. If not, see .
17 | #
18 | #
19 | # This is a sample file, create your own, named `env.properties`.
20 | # You can create your token here: https://sentry-mobile.infomaniak.com/settings/sentry/auth-tokens
21 | sentryAuthToken=YOUR_SENTRY_AUTH_TOKEN_HERE
22 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
23 | # The TransferTypeUi class is removed when minifying, we don't want that.
24 | -keep class com.infomaniak.swisstransfer.ui.screen.newtransfer.pickfiles.components.TransferTypeUi{*;}
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/di/ClientQualifiers.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.di
19 |
20 | import javax.inject.Qualifier
21 |
22 | @Retention(AnnotationRetention.BINARY)
23 | @Qualifier
24 | annotation class UserAgent
25 |
--------------------------------------------------------------------------------
/.idea/copyright/Infomaniak_Open_Source.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/AppImages.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images
19 |
20 | import androidx.compose.ui.unit.dp
21 |
22 | object AppImages {
23 | object AppIcons
24 | object AppIllus
25 |
26 | val previewSize = 250.dp
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/GetSetCallbacks.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.utils
19 |
20 | import androidx.compose.runtime.Immutable
21 |
22 | @Immutable
23 | class GetSetCallbacks(
24 | val get: () -> T,
25 | val set: (T) -> Unit,
26 | )
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/PickedFile.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.newtransfer
19 |
20 | import android.net.Uri
21 |
22 | data class PickedFile(
23 | val uri: Uri,
24 | val name: String,
25 | val mimeType: String,
26 | val size: Long,
27 | )
28 |
--------------------------------------------------------------------------------
/.github/workflows/android.yml:
--------------------------------------------------------------------------------
1 | name: Android CI
2 |
3 | on:
4 | pull_request:
5 |
6 | concurrency:
7 | group: ${{ github.workflow }}-${{ github.ref }}
8 | cancel-in-progress: true
9 |
10 | jobs:
11 | instrumentation-tests:
12 | if: github.event.pull_request.draft == false
13 | runs-on: [ self-hosted, Android ]
14 |
15 | steps:
16 | - name: Checkout the code
17 | uses: actions/checkout@v5.0.0
18 | with:
19 | token: ${{ github.token }}
20 | submodules: recursive
21 |
22 | - name: Create test env.properties
23 | run: |
24 | touch env.properties
25 | echo "sentryAuthToken=DummyToken" > env.properties
26 |
27 | # Setup Gradle and Run tests
28 | - name: Grant execute permission for gradlew
29 | run: chmod +x gradlew
30 |
31 | - name: Clean gradle cache
32 | run: ./gradlew clean
33 |
34 | # Making sure the app compiles
35 | - name: Build app
36 | run: ./gradlew assembleDebug
37 |
38 | - name: Run unit tests
39 | run: ./gradlew testProdDebugUnitTest --stacktrace
40 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/locales_config.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/upload/StartUploadRequest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.upload
19 |
20 | import com.infomaniak.swisstransfer.ui.screen.newtransfer.PickedFile
21 |
22 | data class StartUploadRequest(
23 | val params: NewTransferParams,
24 | val files: List,
25 | val info: UploadState.Ongoing.TransferInfo
26 | )
27 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/preprod/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
18 |
23 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/preprod/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/preprod/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
18 |
23 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/AppUpdateManageable.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui
19 |
20 | import com.infomaniak.core.inappupdate.updatemanagers.InAppUpdateManager
21 |
22 | interface AppUpdateManageable {
23 |
24 | val inAppUpdateManager: InAppUpdateManager
25 |
26 | fun initAppUpdateManager(isUpdateRequired: Boolean) = inAppUpdateManager.init(
27 | isUpdateRequired = isUpdateRequired,
28 | )
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/upload/PickedFileExt.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.upload
19 |
20 | import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.FileToUploadMetadata
21 | import com.infomaniak.swisstransfer.ui.screen.newtransfer.PickedFile
22 |
23 | fun PickedFile.toFileUploadMetaData(): FileToUploadMetadata {
24 | return FileToUploadMetadata(
25 | name = name,
26 | size = size,
27 | mimeType = mimeType
28 | )
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 | #FFBB86FC
20 | #FF6200EE
21 | #FF3700B3
22 | #FF03DAC5
23 | #FF018786
24 | #FF000000
25 | #FFFFFFFF
26 |
27 | #3CB572
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/di/CoroutinesQualifiers.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.di
19 |
20 | import javax.inject.Qualifier
21 |
22 | //region Globals qualifiers
23 | @Retention(AnnotationRetention.BINARY)
24 | @Qualifier
25 | annotation class DefaultDispatcher
26 |
27 | @Retention(AnnotationRetention.BINARY)
28 | @Qualifier
29 | annotation class IoDispatcher
30 |
31 | @Retention(AnnotationRetention.BINARY)
32 | @Qualifier
33 | annotation class MainDispatcher
34 | //endregion
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/ThemedImage.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images
19 |
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.graphics.vector.ImageVector
22 | import com.infomaniak.swisstransfer.ui.theme.LocalIsDarkMode
23 |
24 | interface ThemedImage {
25 | val light: ImageVector
26 | val dark: ImageVector
27 |
28 | @Composable
29 | fun image(): ImageVector = if (LocalIsDarkMode.current) dark else light
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/previewparameter/TransferUiListPreviewParameterProvider.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.previewparameter
19 |
20 | import androidx.compose.ui.tooling.preview.PreviewParameterProvider
21 | import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.TransferUi
22 |
23 | class TransferUiListPreviewParameter : PreviewParameterProvider> {
24 | override val values: Sequence> = sequenceOf(transfersPreviewData)
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/ThemeUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.utils
19 |
20 | import androidx.compose.foundation.isSystemInDarkTheme
21 | import androidx.compose.runtime.Composable
22 | import com.infomaniak.multiplatform_swisstransfer.common.models.Theme
23 |
24 | @Composable
25 | fun isDarkTheme(getTheme: () -> Theme?): Boolean {
26 | return getTheme()?.let {
27 | if (it == Theme.SYSTEM) isSystemInDarkTheme() else it == Theme.DARK
28 | } ?: isSystemInDarkTheme()
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/upload/PickedFilesExtractor.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.upload
19 |
20 | import android.net.Uri
21 | import com.infomaniak.swisstransfer.ui.screen.newtransfer.PickedFile
22 | import kotlinx.coroutines.flow.StateFlow
23 |
24 | interface PickedFilesExtractor {
25 |
26 | val pickedFilesFlow: StateFlow>
27 | val isHandlingUrisFlow: StateFlow
28 |
29 | fun addUris(uris: List)
30 | fun removeUris(uris: List)
31 | fun clear()
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
26 |
27 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/navigation/ExternalNavigation.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.navigation
19 |
20 | const val EXTERNAL_NAVIGATION_KEY = "externalNavigationKey"
21 | const val TRANSFER_UUID_KEY = "transferUuidKey"
22 | const val TRANSFER_TYPE_KEY = "transferTypeKey"
23 | const val TRANSFER_TOTAL_SIZE_KEY = "transferTotalSizeKey"
24 | const val TRANSFER_URL_KEY = "transferUrlKey"
25 | const val TRANSFER_AUTHOR_EMAIL_KEY = "transferAuthorEmailKey"
26 |
27 | enum class ExternalNavigation { UploadOngoing, UploadSuccess }
28 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v31/themes.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/CustomShapes.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.theme
19 |
20 | import androidx.compose.foundation.shape.CircleShape
21 | import androidx.compose.foundation.shape.RoundedCornerShape
22 | import androidx.compose.ui.unit.dp
23 |
24 | object CustomShapes {
25 | val NONE = RoundedCornerShape(0)
26 | val ROUNDED = CircleShape
27 | val EXTRA_SMALL = RoundedCornerShape(4.dp)
28 | val SMALL = RoundedCornerShape(8.dp)
29 | val MEDIUM = RoundedCornerShape(16.dp)
30 | val LARGE = RoundedCornerShape(24.dp)
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/splashscreen_legacy.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. For more details, visit
12 | # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library's R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library's dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/transferdetails/TransferDownloadUi.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.main.transferdetails
19 |
20 | import androidx.lifecycle.Lifecycle
21 | import com.infomaniak.core.DownloadStatus
22 | import kotlinx.coroutines.flow.StateFlow
23 |
24 | interface TransferDownloadUi {
25 |
26 | val lifecycle: Lifecycle
27 |
28 | suspend fun awaitDownloadRequest()
29 |
30 | suspend fun showStatusAndAwaitRemovalRequest(
31 | statusFlow: StateFlow,
32 | supportsPreview: Boolean
33 | )
34 |
35 | suspend fun awaitOpenRequest()
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/FileUiExt.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.utils
19 |
20 | import com.infomaniak.core.filetypes.FileType
21 | import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.FileUi
22 |
23 | val FileUi.fileType: FileType
24 | get() = if (isFolder) {
25 | FileType.FOLDER
26 | } else {
27 | mimeType?.let { FileType.guessFromMimeType(it) } ?: FileType.guessFromFileName(fileName)
28 | }
29 |
30 | val FileUi.hasPreview: Boolean
31 | get() = when (fileType) {
32 | FileType.IMAGE, FileType.VIDEO -> true
33 | else -> false
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/NewTransferViewModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.newtransfer
19 |
20 | import androidx.lifecycle.ViewModel
21 | import com.infomaniak.swisstransfer.ui.utils.NotificationsUtils
22 | import dagger.hilt.android.lifecycle.HiltViewModel
23 | import javax.inject.Inject
24 |
25 | @HiltViewModel
26 | class NewTransferViewModel @Inject constructor(
27 | private val notificationsUtils: NotificationsUtils,
28 | ) : ViewModel() {
29 |
30 | fun cancelUploadNotification() {
31 | notificationsUtils.cancelNotification(NotificationsUtils.Ids.LastUpload)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
24 |
25 |
26 |
30 |
31 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/LastTransferPreferences.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.utils
19 |
20 | import android.content.Context
21 | import androidx.datastore.core.DataStore
22 | import androidx.datastore.preferences.core.Preferences
23 | import androidx.datastore.preferences.core.stringPreferencesKey
24 | import androidx.datastore.preferences.preferencesDataStore
25 |
26 | val Context.lastTransferDataStore: DataStore by preferencesDataStore(name = "LastTransferPreferences")
27 |
28 | object LastTransferPreferences {
29 | data object lastTransferUuid : DataStorePreference(stringPreferencesKey("LastTransferUuid"), "")
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/DataManagementPreferences.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.utils
19 |
20 | import android.content.Context
21 | import androidx.datastore.core.DataStore
22 | import androidx.datastore.preferences.core.Preferences
23 | import androidx.datastore.preferences.core.booleanPreferencesKey
24 | import androidx.datastore.preferences.preferencesDataStore
25 |
26 | val Context.dataManagementDataStore: DataStore by preferencesDataStore(name = "DataManagementPreferences")
27 |
28 | object DataManagementPreferences {
29 | data object IsSentryAuthorized : DataStorePreference(booleanPreferencesKey("IsSentryAuthorized"), true)
30 | }
31 |
--------------------------------------------------------------------------------
/.github/workflows/translations-validation.yml:
--------------------------------------------------------------------------------
1 | name: Validate translations
2 |
3 | on:
4 | pull_request:
5 |
6 | concurrency:
7 | group: ${{ github.workflow }}-${{ github.ref }}
8 | cancel-in-progress: true
9 |
10 | jobs:
11 | validate-strings:
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - name: Checkout PR branch
16 | uses: actions/checkout@v5.0.0
17 |
18 | - name: Clone Ink repository
19 | uses: actions/checkout@v5.0.0
20 | with:
21 | repository: infomaniak/ink_utils
22 | ref: main
23 | submodules: true
24 | path: ink_utils
25 |
26 | - name: Set up Python
27 | uses: actions/setup-python@v5.6.0
28 | with:
29 | python-version: '3.11'
30 |
31 | - name: Create venv and install requirements
32 | run: |
33 | cd ink_utils
34 | python -m venv venv
35 | source venv/bin/activate
36 | pip install --upgrade pip
37 | pip install -r requirements.txt
38 |
39 | - name: Create Ink config YAML
40 | run: |
41 | PR_PATH=$(pwd)
42 | cat < ink_utils/settings.yml
43 | app:
44 | global:
45 | project_root: "${PR_PATH}/app"
46 | EOF
47 |
48 | - name: Run Ink validation for app
49 | run: |
50 | source ink_utils/venv/bin/activate
51 | python ink_utils/main.py project app
52 | python ink_utils/main.py loco --check --verbose
53 |
--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 | accompanistPermissions = "0.37.3"
3 | agp = "8.13.1"
4 | constraintlayoutCompose = "1.1.1"
5 | coreSplashscreen = "1.2.0"
6 | desugarJDK = "2.1.5"
7 | qrose = "1.0.1"
8 | room = "2.8.4"
9 | swisstransfer = "6.0.0"
10 |
11 | [libraries]
12 | accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanistPermissions" }
13 | androidx-constraintlayout-compose = { module = "androidx.constraintlayout:constraintlayout-compose", version.ref = "constraintlayoutCompose" }
14 | androidx-core-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "coreSplashscreen" }
15 | compose-material3-adaptative-navigation = { module = "androidx.compose.material3:material3-adaptive-navigation-suite" }
16 | compose-ui-graphics = { module = "androidx.compose.ui:ui-graphics" }
17 | desugar-jdk = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugarJDK" }
18 | qrose = { module = "io.github.alexzhirkevich:qrose", version.ref = "qrose" }
19 | room-processing = { module = "androidx.room:room-compiler-processing", version.ref = "room" }
20 | swisstransfer-core = { module = "com.github.Infomaniak.multiplatform-SwissTransfer:STCore", version.ref = "swisstransfer" }
21 | swisstransfer-network = { module = "com.github.Infomaniak.multiplatform-SwissTransfer:STNetwork", version.ref = "swisstransfer" }
22 |
23 | [plugins]
24 | android-application = { id = "com.android.application", version.ref = "agp" }
25 | android-library = { id = "com.android.library", version.ref = "agp" }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/AppReviewManageable.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui
19 |
20 | import com.infomaniak.core.inappreview.BaseInAppReviewManager.Behavior
21 | import com.infomaniak.core.inappreview.reviewmanagers.InAppReviewManager
22 |
23 | interface AppReviewManageable {
24 |
25 | val inAppReviewManager: InAppReviewManager
26 |
27 | fun initAppReviewManager() = inAppReviewManager.init(
28 | countdownBehavior = Behavior.Manual,
29 | appReviewThreshold = APP_REVIEW_THRESHOLD,
30 | maxAppReviewThreshold = MAX_APP_REVIEW_THRESHOLD,
31 | )
32 |
33 | companion object {
34 | private const val APP_REVIEW_THRESHOLD = 2
35 | private const val MAX_APP_REVIEW_THRESHOLD = 10
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/Dimens.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.theme
19 |
20 | import androidx.compose.ui.unit.dp
21 | import com.infomaniak.core.ui.compose.margin.Margin
22 |
23 | object Dimens {
24 | val MaxSinglePaneScreenWidth = 800.dp
25 | val SettingHorizontalMargin = Margin.Medium
26 | val SettingVerticalMargin = Margin.Small
27 | val DescriptionWidth = 300.dp
28 | val LargeButtonHeight = 56.dp
29 | val SingleButtonMaxWidth = MaxSinglePaneScreenWidth / 2
30 | val MicroIconSize = 8.dp
31 | val MiniIconSize = 12.dp
32 | val SmallIconSize = 16.dp
33 | val IconSize = 24.dp
34 | val BorderWidth = 1.dp
35 | val ButtonComboVerticalPadding = Margin.Small
36 | val InputChipMinWidth = 88.dp
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/upload/NewTransferParams.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.upload
19 |
20 | import com.infomaniak.multiplatform_swisstransfer.common.models.DownloadLimit
21 | import com.infomaniak.multiplatform_swisstransfer.common.models.EmailLanguage
22 | import com.infomaniak.multiplatform_swisstransfer.common.models.ValidityPeriod
23 | import com.infomaniak.swisstransfer.ui.screen.newtransfer.pickfiles.components.TransferTypeUi
24 |
25 | data class NewTransferParams(
26 | val validityPeriod: ValidityPeriod,
27 | val authorEmail: String,
28 | val password: String,
29 | val message: String,
30 | val downloadCountLimit: DownloadLimit,
31 | val languageCode: EmailLanguage,
32 | val recipientsEmails: Set,
33 | val type: TransferTypeUi,
34 | )
35 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/infomaniak/swisstransfer/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer
19 |
20 | import androidx.test.ext.junit.runners.AndroidJUnit4
21 | import androidx.test.platform.app.InstrumentationRegistry
22 | import org.junit.Assert.assertEquals
23 | import org.junit.Test
24 | import org.junit.runner.RunWith
25 |
26 | /**
27 | * Instrumented test, which will execute on an Android device.
28 | *
29 | * See [testing documentation](http://d.android.com/tools/testing).
30 | */
31 | @RunWith(AndroidJUnit4::class)
32 | class ExampleInstrumentedTest {
33 | @Test
34 | fun useAppContext() {
35 | // Context of the app under test.
36 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
37 | assertEquals("com.infomaniak.swisstransfer", appContext.packageName)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/components/SmallWindowScreenTitle.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.components
19 |
20 | import androidx.compose.material3.Text
21 | import androidx.compose.runtime.Composable
22 | import androidx.compose.ui.Modifier
23 | import com.infomaniak.swisstransfer.ui.theme.LocalWindowAdaptiveInfo
24 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
25 | import com.infomaniak.swisstransfer.ui.utils.isWindowSmall
26 |
27 | @Composable
28 | fun SmallWindowScreenTitle(title: String, modifier: Modifier = Modifier) {
29 | val windowAdaptiveInfo = LocalWindowAdaptiveInfo.current
30 | if (windowAdaptiveInfo.isWindowSmall()) {
31 | Text(
32 | text = title,
33 | style = SwissTransferTheme.typography.h1,
34 | modifier = modifier,
35 | )
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/ScreenWrapperUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.utils
19 |
20 | import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
21 | import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator
22 | import com.infomaniak.swisstransfer.ui.components.canPopBackStack
23 | import com.infomaniak.swisstransfer.ui.components.popBackStack
24 |
25 | object ScreenWrapperUtils {
26 |
27 | @OptIn(ExperimentalMaterial3AdaptiveApi::class)
28 | fun getBackNavigation(navigator: ThreePaneScaffoldNavigator<*>): (suspend () -> Unit)? {
29 | val navigateBackCallback: suspend () -> Unit = { navigator.popBackStack() }
30 | val navigateBack: (suspend () -> Unit)? = if (navigator.canPopBackStack()) navigateBackCallback else null
31 | return navigateBack
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/upload/NewTransferParamsExt.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.upload
19 |
20 | import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.FileToUploadMetadata
21 | import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.UploadSessionRequest
22 |
23 | fun NewTransferParams.toUploadSessionRequest(
24 | filesMetadata: List
25 | ): UploadSessionRequest = UploadSessionRequest(
26 | validityPeriod = validityPeriod,
27 | authorEmail = authorEmail,
28 | password = password,
29 | message = message,
30 | sizeOfUpload = filesMetadata.sumOf { it.size },
31 | downloadCountLimit = downloadCountLimit,
32 | filesCount = filesMetadata.size,
33 | languageCode = languageCode,
34 | filesMetadata = filesMetadata,
35 | recipientsEmails = recipientsEmails
36 | )
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/upload/components/WeightOneSpacer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.newtransfer.upload.components
19 |
20 | import androidx.compose.foundation.layout.ColumnScope
21 | import androidx.compose.foundation.layout.RowScope
22 | import androidx.compose.foundation.layout.Spacer
23 | import androidx.compose.foundation.layout.height
24 | import androidx.compose.foundation.layout.width
25 | import androidx.compose.runtime.Composable
26 | import androidx.compose.ui.Modifier
27 | import androidx.compose.ui.unit.Dp
28 |
29 | @Composable
30 | fun ColumnScope.WeightOneSpacer(minHeight: Dp) {
31 | Spacer(Modifier.height(minHeight))
32 | Spacer(Modifier.weight(1.0f))
33 | }
34 |
35 | @Composable
36 | fun RowScope.WeightOneSpacer(minWidth: Dp) {
37 | Spacer(Modifier.width(minWidth))
38 | Spacer(Modifier.weight(1.0f))
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/components/SwissTransferScaffold.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.main.components
19 |
20 | import androidx.compose.foundation.layout.Box
21 | import androidx.compose.foundation.layout.padding
22 | import androidx.compose.material3.Scaffold
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 |
26 | @Composable
27 | fun SwissTransferScaffold(
28 | topBar: @Composable () -> Unit = {},
29 | snackbarHost: @Composable () -> Unit = {},
30 | floatingActionButton: @Composable () -> Unit = {},
31 | content: @Composable () -> Unit,
32 | ) {
33 | Scaffold(
34 | topBar = { topBar() },
35 | snackbarHost = snackbarHost,
36 | floatingActionButton = floatingActionButton,
37 | ) { contentPadding ->
38 | Box(modifier = Modifier.padding(contentPadding)) {
39 | content()
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/test/java/com/infomaniak/swisstransfer/NavigationDestinationUnitTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer
19 |
20 | import com.infomaniak.swisstransfer.ui.navigation.MainNavigation
21 | import org.junit.Assert.assertNotNull
22 | import org.junit.Test
23 |
24 | class NavigationDestinationUnitTest {
25 |
26 | /**
27 | * Make sure that NavigationDestination names are not changed without changing the `entries` list, because of minification issue.
28 | */
29 | @Test
30 | fun check_destinations_names_are_correct() {
31 | val destinationsNames = MainNavigation.Companion.destinationsNames
32 | assertNotNull(destinationsNames.find { it == MainNavigation.SentDestination::class.simpleName })
33 | assertNotNull(destinationsNames.find { it == MainNavigation.ReceivedDestination::class.simpleName })
34 | assertNotNull(destinationsNames.find { it == MainNavigation.SettingsDestination::class.simpleName })
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/flag_ge.xml:
--------------------------------------------------------------------------------
1 |
18 |
23 |
24 |
25 |
28 |
31 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/DeeplinkExt.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.utils
19 |
20 | import androidx.activity.ComponentActivity
21 |
22 | private val TRANSFER_DEEPLINK_REGEX = "https://.+/d/([^?]+)(?:\\?delete=(.+))?".toRegex()
23 |
24 | fun ComponentActivity.hasValidTransferDeeplink(): Boolean {
25 | val deeplink = intent?.data?.toString()
26 | return deeplink?.matches(TRANSFER_DEEPLINK_REGEX) == true
27 | }
28 |
29 | fun ComponentActivity.getDeeplinkTransferData(): DeeplinkTransferData? {
30 | return intent?.data?.let { deeplinkUri ->
31 | val deeplinkGroupValues = TRANSFER_DEEPLINK_REGEX.find(deeplinkUri.toString())?.groupValues
32 | val transferUuid = deeplinkGroupValues?.get(1)
33 | val deleteToken = deeplinkGroupValues?.get(2)
34 | DeeplinkTransferData(uuid = transferUuid, deleteToken = deleteToken)
35 | }
36 | }
37 |
38 | data class DeeplinkTransferData(val uuid: String?, val deleteToken: String?)
39 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/flag_it.xml:
--------------------------------------------------------------------------------
1 |
18 |
23 |
24 |
25 |
28 |
31 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/SettingDivider.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.main.settings.components
19 |
20 | import androidx.compose.foundation.layout.padding
21 | import androidx.compose.material3.HorizontalDivider
22 | import androidx.compose.material3.Surface
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
26 | import com.infomaniak.swisstransfer.ui.theme.Dimens
27 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
28 |
29 | @Composable
30 | fun SettingDivider() {
31 | HorizontalDivider(
32 | modifier = Modifier.padding(
33 | horizontal = Dimens.SettingHorizontalMargin,
34 | vertical = Dimens.SettingVerticalMargin,
35 | ),
36 | )
37 | }
38 |
39 | @PreviewLightAndDark
40 | @Composable
41 | private fun Preview() {
42 | SwissTransferTheme {
43 | Surface {
44 | SettingDivider()
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/previewparameter/EmailsPreviewParameterProvider.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.previewparameter
19 |
20 | import androidx.compose.ui.tooling.preview.PreviewParameterProvider
21 |
22 | class EmailsPreviewParameter : PreviewParameterProvider> {
23 | override val values: Sequence> = sequenceOf(emailsPreviewData)
24 | }
25 |
26 | val emailsPreviewData = listOf(
27 | "a.b@c.de",
28 | "f.g@h.ij",
29 | "email@example.com",
30 | "firstname.lastname@example.com",
31 | "email@subdomain.example.com",
32 | "firstname+lastname@example.com",
33 | "email@123.123.123.123",
34 | "email@[123.123.123.123]",
35 | "sdiofhcdqsklmjvbnfdkjlsdbnfkdgflghhwfiudmsklwhdxfbvhlsdjkbwnxcjkvdxhjgwhxdjlxkchwbdvxfhbdqshjkdhjd@mail.com",
36 | "\"email\"@example.com",
37 | "1234567890@example.com",
38 | "email@example-one.com",
39 | "_______@example.com",
40 | "email@example.name",
41 | "email@example.museum",
42 | "email@example.co.jp",
43 | "firstname-lastname@example.com",
44 | )
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/NewTransferScreen.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.newtransfer
19 |
20 | import androidx.compose.runtime.Composable
21 | import androidx.hilt.navigation.compose.hiltViewModel
22 | import androidx.navigation.compose.rememberNavController
23 | import com.infomaniak.core.inappreview.reviewmanagers.InAppReviewManager
24 | import com.infomaniak.swisstransfer.ui.navigation.NewTransferNavigation
25 |
26 | @Composable
27 | fun NewTransferScreen(
28 | startDestination: NewTransferNavigation,
29 | inAppReviewManager: InAppReviewManager,
30 | closeActivity: (startMainActivityIfTaskIsEmpty: Boolean) -> Unit,
31 | newTransferViewModel: NewTransferViewModel = hiltViewModel(),
32 | ) {
33 | NewTransferNavHost(
34 | navController = rememberNavController(),
35 | startDestination = startDestination,
36 | inAppReviewManager = inAppReviewManager,
37 | closeActivity = closeActivity,
38 | cancelUploadNotification = { newTransferViewModel.cancelUploadNotification() }
39 | )
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/TextUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.utils
19 |
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.text.AnnotatedString
22 | import androidx.compose.ui.text.SpanStyle
23 | import androidx.compose.ui.text.buildAnnotatedString
24 | import androidx.compose.ui.text.font.FontWeight
25 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
26 |
27 | object TextUtils {
28 | @Composable
29 | fun assembleWithBoldArgument(template: String, argument: String): AnnotatedString {
30 | val description = String.format(template, argument)
31 |
32 | val startIndex = description.indexOf(argument)
33 | val endIndex = startIndex + argument.length
34 |
35 | return buildAnnotatedString {
36 | append(description)
37 | addStyle(
38 | style = SpanStyle(fontWeight = FontWeight.Bold, color = SwissTransferTheme.colors.primaryTextColor),
39 | start = startIndex,
40 | end = endIndex,
41 | )
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/di/CoroutinesDispatchersModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.di
19 |
20 | import dagger.Module
21 | import dagger.Provides
22 | import dagger.hilt.InstallIn
23 | import dagger.hilt.components.SingletonComponent
24 | import kotlinx.coroutines.CoroutineDispatcher
25 | import kotlinx.coroutines.CoroutineScope
26 | import kotlinx.coroutines.Dispatchers
27 | import javax.inject.Singleton
28 |
29 | @Module
30 | @InstallIn(SingletonComponent::class)
31 | object CoroutinesDispatchersModule {
32 |
33 | @DefaultDispatcher
34 | @Provides
35 | fun providesDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default
36 |
37 | @IoDispatcher
38 | @Provides
39 | fun providesIoDispatcher(): CoroutineDispatcher = Dispatchers.IO
40 |
41 | @MainDispatcher
42 | @Provides
43 | fun providesMainDispatcher(): CoroutineDispatcher = Dispatchers.Main
44 |
45 | @Provides
46 | @Singleton
47 | fun providesGlobalCoroutineScope(@DefaultDispatcher defaultDispatcher: CoroutineDispatcher): CoroutineScope {
48 | return CoroutineScope(defaultDispatcher)
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/components/ReviewAlertDialog.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.components
19 |
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.ui.res.stringResource
22 | import com.infomaniak.swisstransfer.R
23 | import com.infomaniak.core.R as RCore
24 |
25 | @Composable
26 | fun ReviewAlertDialog(onUserWantsToReview: () -> Unit, onUserWantsToGiveFeedback: () -> Unit, onDismiss: () -> Unit) {
27 | SwissTransferAlertDialog(
28 | title = stringResource(RCore.string.reviewAlertTitle, stringResource(R.string.appName)),
29 | positiveButton = {
30 | SmallButton(
31 | style = ButtonType.Tertiary,
32 | title = stringResource(RCore.string.buttonYes),
33 | onClick = onUserWantsToReview,
34 | )
35 | },
36 | negativeButton = {
37 | SmallButton(
38 | style = ButtonType.Tertiary,
39 | title = stringResource(RCore.string.buttonNo),
40 | onClick = onUserWantsToGiveFeedback,
41 | )
42 | },
43 | onDismiss = onDismiss,
44 | )
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/NotificationPermissionUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.utils
19 |
20 | import android.Manifest
21 | import android.content.Context
22 | import android.content.pm.PackageManager
23 | import android.os.Build.VERSION.SDK_INT
24 | import androidx.activity.compose.ManagedActivityResultLauncher
25 | import androidx.annotation.RequiresApi
26 | import androidx.core.content.ContextCompat
27 |
28 | object NotificationPermissionUtils {
29 |
30 | @RequiresApi(33)
31 | private val permission = Manifest.permission.POST_NOTIFICATIONS
32 |
33 | fun hasNotificationPermission(context: Context): Boolean {
34 | return when {
35 | SDK_INT < 33 -> true
36 | ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED -> true
37 | else -> false
38 | }
39 | }
40 |
41 | fun askNotificationPermission(launcher: ManagedActivityResultLauncher) {
42 | if (SDK_INT >= 33) {
43 | // TODO: Manage with a custom dialog if not handled by the system
44 | launcher.launch(permission)
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/DataStoreUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.utils
19 |
20 | import androidx.datastore.core.DataStore
21 | import androidx.datastore.preferences.core.MutablePreferences
22 | import androidx.datastore.preferences.core.Preferences
23 | import kotlinx.coroutines.flow.Flow
24 | import kotlinx.coroutines.flow.first
25 | import kotlinx.coroutines.flow.map
26 | import kotlinx.coroutines.runBlocking
27 |
28 | open class DataStorePreference(val dataStoreKey: Preferences.Key, val defaultValue: T)
29 |
30 | fun DataStore.getPreference(preference: DataStorePreference): T {
31 | return runBlocking { flowOf(preference).first() }
32 | }
33 |
34 | operator fun Preferences.get(preference: DataStorePreference): T {
35 | return get(preference.dataStoreKey) ?: preference.defaultValue
36 | }
37 |
38 | operator fun MutablePreferences.set(preference: DataStorePreference, value: T) {
39 | set(preference.dataStoreKey, value)
40 | }
41 |
42 | private fun DataStore.flowOf(preference: DataStorePreference): Flow {
43 | return data.map { it[preference] }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/AccountUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.utils
19 |
20 | import com.infomaniak.multiplatform_swisstransfer.managers.AccountManager
21 | import javax.inject.Inject
22 | import javax.inject.Singleton
23 |
24 | @Singleton
25 | class AccountUtils @Inject constructor(
26 | private val accountManager: AccountManager,
27 | private val accountPreferences: AccountPreferences,
28 | ) {
29 |
30 | suspend fun init() {
31 | accountPreferences.currentUserId?.let {
32 | accountManager.loadUser(it)
33 | }
34 | }
35 |
36 | suspend fun login(userId: Int = DEFAULT_USER_ID) {
37 | accountPreferences.currentUserId = userId
38 | accountManager.loadUser(userId)
39 | }
40 |
41 | suspend fun logout(userId: Int) {
42 | accountManager.removeUser(userId)
43 | // TODO: Handle logging as the next available connected user or the DEFAULT_USER_ID
44 | accountPreferences.currentUserId = DEFAULT_USER_ID
45 | }
46 |
47 | fun isUserConnected(): Boolean = accountPreferences.currentUserId != null
48 |
49 | companion object {
50 | const val DEFAULT_USER_ID = 0
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/AlreadyUsedFileNamesSet.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.newtransfer
19 |
20 | import kotlinx.coroutines.sync.Mutex
21 | import kotlinx.coroutines.sync.withLock
22 |
23 | class AlreadyUsedFileNamesSet {
24 | private val alreadyUsedFileNames = mutableSetOf()
25 | private val mutex = Mutex()
26 |
27 | suspend fun addUniqueFileName(computeUniqueFileName: (AlreadyUsedStrategy) -> String): String {
28 | val uniqueFileName: String
29 |
30 | mutex.withLock {
31 | val alreadyUsedStrategy = AlreadyUsedStrategy { alreadyUsedFileNames.contains(it) }
32 | uniqueFileName = computeUniqueFileName(alreadyUsedStrategy)
33 | alreadyUsedFileNames.add(uniqueFileName)
34 | }
35 |
36 | return uniqueFileName
37 | }
38 |
39 | suspend fun addAll(filesNames: List): Boolean = mutex.withLock { alreadyUsedFileNames.addAll(filesNames) }
40 | suspend fun remove(filesName: String): Boolean = mutex.withLock { alreadyUsedFileNames.remove(filesName) }
41 |
42 | fun interface AlreadyUsedStrategy {
43 | fun isAlreadyUsed(fileName: String): Boolean
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/transfers/DeleteTransferUseCase.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.main.transfers
19 |
20 | import com.infomaniak.core.cancellable
21 | import com.infomaniak.core.sentry.SentryLog
22 | import com.infomaniak.multiplatform_swisstransfer.managers.TransferManager
23 | import com.infomaniak.swisstransfer.di.IoDispatcher
24 | import kotlinx.coroutines.CoroutineDispatcher
25 | import kotlinx.coroutines.CoroutineScope
26 | import kotlinx.coroutines.launch
27 | import javax.inject.Inject
28 |
29 | class DeleteTransferUseCase @Inject constructor(
30 | private val transferManager: TransferManager,
31 | @IoDispatcher private val ioDispatcher: CoroutineDispatcher,
32 | ) {
33 | operator fun invoke(transferUuid: String, coroutineScope: CoroutineScope) {
34 | coroutineScope.launch(ioDispatcher) {
35 | runCatching {
36 | transferManager.deleteTransfer(transferUuid)
37 | }.cancellable().onFailure {
38 | SentryLog.e(TAG, "Failure for deleteTransfer", it)
39 | }
40 | }
41 | }
42 |
43 | companion object {
44 | private val TAG = DeleteTransferUseCase::class.java.simpleName
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/DeeplinkViewModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.main
19 |
20 | import androidx.lifecycle.SavedStateHandle
21 | import androidx.lifecycle.ViewModel
22 | import com.infomaniak.multiplatform_swisstransfer.common.models.TransferDirection
23 | import com.infomaniak.multiplatform_swisstransfer.managers.TransferManager
24 | import dagger.hilt.android.lifecycle.HiltViewModel
25 | import javax.inject.Inject
26 |
27 | @HiltViewModel
28 | class DeeplinkViewModel @Inject constructor(
29 | private val savedStateHandle: SavedStateHandle,
30 | private val transferManager: TransferManager,
31 | ) : ViewModel() {
32 |
33 | val isDeeplinkConsumed = savedStateHandle.getStateFlow(IS_DEEPLINK_CONSUMED_KEY, false)
34 |
35 | fun consumeDeepLink() {
36 | if (!isDeeplinkConsumed.value) savedStateHandle[IS_DEEPLINK_CONSUMED_KEY] = true
37 | }
38 |
39 | suspend fun getDeeplinkTransferDirection(transferUuid: String): TransferDirection? {
40 | return transferManager.getTransferByUUID(transferUuid)?.direction
41 | }
42 |
43 | companion object {
44 |
45 | const val SENT_DEEPLINK_SUFFIX = "/sent"
46 |
47 | private const val IS_DEEPLINK_CONSUMED_KEY = "isDeepLinkConsumed"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/.idea/icon.svg:
--------------------------------------------------------------------------------
1 |
18 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/flag_fr.xml:
--------------------------------------------------------------------------------
1 |
18 |
23 |
24 |
25 |
28 |
31 |
34 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/upload/UploadProgressAdType.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.newtransfer.upload
19 |
20 | import androidx.annotation.RawRes
21 | import androidx.annotation.StringRes
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.ui.res.stringResource
24 | import androidx.compose.ui.text.AnnotatedString
25 | import com.infomaniak.swisstransfer.R
26 | import com.infomaniak.swisstransfer.ui.utils.TextUtils
27 |
28 | enum class UploadProgressAdType(
29 | @StringRes private val descriptionTemplate: Int,
30 | @StringRes private val descriptionAccentuatedPart: Int,
31 | @RawRes val illustration: Int,
32 | ) {
33 | INDEPENDENCE(
34 | R.string.uploadProgressDescriptionTemplateIndependence,
35 | R.string.uploadProgressDescriptionArgumentIndependence,
36 | R.raw.swiss_with_flag,
37 | ),
38 | ENERGY(
39 | R.string.uploadProgressDescriptionTemplateEnergy,
40 | R.string.uploadProgressDescriptionArgumentEnergy,
41 | R.raw.mountain_gondola,
42 | );
43 |
44 | @Composable
45 | fun description(): AnnotatedString {
46 | return TextUtils.assembleWithBoldArgument(stringResource(descriptionTemplate), stringResource(descriptionAccentuatedPart))
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/PermissionsUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.utils
19 |
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.runtime.LaunchedEffect
22 | import androidx.compose.runtime.remember
23 | import androidx.compose.runtime.snapshotFlow
24 | import com.google.accompanist.permissions.ExperimentalPermissionsApi
25 | import com.google.accompanist.permissions.PermissionState
26 | import com.google.accompanist.permissions.isGranted
27 | import kotlinx.coroutines.CompletableJob
28 | import kotlinx.coroutines.Job
29 | import kotlinx.coroutines.flow.first
30 |
31 | @OptIn(ExperimentalPermissionsApi::class)
32 | @Composable
33 | fun PermissionState?.guardedCallback(action: () -> Unit): () -> Unit {
34 | if (this == null) return action
35 |
36 | val isGrantedFlow = remember(permission) { snapshotFlow { status.isGranted } }
37 | val actionFired: CompletableJob = remember(permission) { Job() }
38 |
39 | LaunchedEffect(permission) {
40 | actionFired.join()
41 | isGrantedFlow.first { it }
42 | action()
43 | }
44 |
45 | return {
46 | if (status.isGranted) {
47 | action()
48 | } else {
49 | launchPermissionRequest()
50 | actionFired.complete()
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/beers/Beers.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.beers
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.size
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
26 | import com.infomaniak.swisstransfer.ui.images.AppImages
27 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
28 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
29 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
30 |
31 | val AppIllus.Beers: ThemedImage
32 | get() = _beers ?: object : ThemedImage {
33 | override val light = AppIllus.BeersLight
34 | override val dark = AppIllus.BeersDark
35 | }.also { _beers = it }
36 |
37 | private var _beers: ThemedImage? = null
38 |
39 | @PreviewLightAndDark
40 | @Composable
41 | private fun Preview() {
42 | SwissTransferTheme {
43 | Box {
44 | Image(
45 | imageVector = AppIllus.Beers.image(),
46 | contentDescription = null,
47 | modifier = Modifier.size(AppImages.previewSize),
48 | )
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/icons/matomo/Matomo.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.icons.matomo
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.size
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
26 | import com.infomaniak.swisstransfer.ui.images.AppImages
27 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIcons
28 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
29 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
30 |
31 | val AppIcons.Matomo: ThemedImage
32 | get() = _matomo ?: object : ThemedImage {
33 | override val light = AppIcons.MatomoLight
34 | override val dark = AppIcons.MatomoDark
35 | }.also { _matomo = it }
36 |
37 | private var _matomo: ThemedImage? = null
38 |
39 | @PreviewLightAndDark
40 | @Composable
41 | private fun Preview() {
42 | SwissTransferTheme {
43 | Box {
44 | Image(
45 | imageVector = AppIcons.Matomo.image(),
46 | contentDescription = null,
47 | modifier = Modifier.size(AppImages.previewSize),
48 | )
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/icons/sentry/Sentry.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.icons.sentry
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.size
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
26 | import com.infomaniak.swisstransfer.ui.images.AppImages
27 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIcons
28 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
29 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
30 |
31 | val AppIcons.Sentry: ThemedImage
32 | get() = _sentry ?: object : ThemedImage {
33 | override val light = AppIcons.SentryLight
34 | override val dark = AppIcons.SentryDark
35 | }.also { _sentry = it }
36 |
37 | private var _sentry: ThemedImage? = null
38 |
39 | @PreviewLightAndDark
40 | @Composable
41 | private fun Preview() {
42 | SwissTransferTheme {
43 | Box {
44 | Image(
45 | imageVector = AppIcons.Sentry.image(),
46 | contentDescription = null,
47 | modifier = Modifier.size(AppImages.previewSize),
48 | )
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/matomo/Matomo.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.matomo
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.size
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
26 | import com.infomaniak.swisstransfer.ui.images.AppImages
27 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
28 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
29 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
30 |
31 | val AppIllus.Matomo: ThemedImage
32 | get() = _matomo ?: object : ThemedImage {
33 | override val light = AppIllus.MatomoLight
34 | override val dark = AppIllus.MatomoDark
35 | }.also { _matomo = it }
36 |
37 | private var _matomo: ThemedImage? = null
38 |
39 | @PreviewLightAndDark
40 | @Composable
41 | private fun Preview() {
42 | SwissTransferTheme {
43 | Box {
44 | Image(
45 | imageVector = AppIllus.Matomo.image(),
46 | contentDescription = null,
47 | modifier = Modifier.size(AppImages.previewSize),
48 | )
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/sentry/Sentry.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.sentry
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.size
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
26 | import com.infomaniak.swisstransfer.ui.images.AppImages
27 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
28 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
29 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
30 |
31 | val AppIllus.Sentry: ThemedImage
32 | get() = _sentry ?: object : ThemedImage {
33 | override val light = AppIllus.SentryLight
34 | override val dark = AppIllus.SentryDark
35 | }.also { _sentry = it }
36 |
37 | private var _sentry: ThemedImage? = null
38 |
39 | @PreviewLightAndDark
40 | @Composable
41 | private fun Preview() {
42 | SwissTransferTheme {
43 | Box {
44 | Image(
45 | imageVector = AppIllus.Sentry.image(),
46 | contentDescription = null,
47 | modifier = Modifier.size(AppImages.previewSize),
48 | )
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/mascotDead/MascotDead.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.mascotDead
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.size
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
26 | import com.infomaniak.swisstransfer.ui.images.AppImages
27 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
28 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
29 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
30 |
31 | val AppIllus.MascotDead: ThemedImage
32 | get() = _mascotDead ?: object : ThemedImage {
33 | override val light = AppIllus.MascotDeadLight
34 | override val dark = AppIllus.MascotDeadDark
35 | }.also { _mascotDead = it }
36 |
37 | private var _mascotDead: ThemedImage? = null
38 |
39 | @PreviewLightAndDark
40 | @Composable
41 | private fun Preview() {
42 | SwissTransferTheme {
43 | Box {
44 | Image(
45 | imageVector = AppIllus.MascotDead.image(),
46 | contentDescription = null,
47 | modifier = Modifier.size(AppImages.previewSize),
48 | )
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/icons/qrInfomaniak/QrInfomaniak.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.icons.qrInfomaniak
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.size
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
26 | import com.infomaniak.swisstransfer.ui.images.AppImages
27 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIcons
28 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
29 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
30 |
31 | val AppIcons.QrInfomaniak: ThemedImage
32 | get() = _qrInfomaniak ?: object : ThemedImage {
33 | override val light = AppIcons.QrInfomaniakLight
34 | override val dark = AppIcons.QrInfomaniakDark
35 | }.also { _qrInfomaniak = it }
36 |
37 | private var _qrInfomaniak: ThemedImage? = null
38 |
39 | @PreviewLightAndDark
40 | @Composable
41 | private fun Preview() {
42 | SwissTransferTheme {
43 | Box {
44 | Image(
45 | imageVector = AppIcons.QrInfomaniak.image(),
46 | contentDescription = null,
47 | modifier = Modifier.size(AppImages.previewSize),
48 | )
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/dataProtection/DataProtection.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.dataProtection
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.size
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
26 | import com.infomaniak.swisstransfer.ui.images.AppImages
27 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
28 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
29 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
30 |
31 | val AppIllus.DataProtection: ThemedImage
32 | get() = _dataProtection ?: object : ThemedImage {
33 | override val light = AppIllus.DataProtectionLight
34 | override val dark = AppIllus.DataProtectionDark
35 | }.also { _dataProtection = it }
36 |
37 | private var _dataProtection: ThemedImage? = null
38 |
39 | @PreviewLightAndDark
40 | @Composable
41 | private fun Preview() {
42 | SwissTransferTheme {
43 | Box {
44 | Image(
45 | imageVector = AppIllus.DataProtection.image(),
46 | contentDescription = null,
47 | modifier = Modifier.size(AppImages.previewSize),
48 | )
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/mascotSearching/MascotSearching.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.mascotSearching
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.size
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
26 | import com.infomaniak.swisstransfer.ui.images.AppImages
27 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
28 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
29 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
30 |
31 | val AppIllus.MascotSearching: ThemedImage
32 | get() = _mascotSearching ?: object : ThemedImage {
33 | override val light = AppIllus.MascotSearchingLight
34 | override val dark = AppIllus.MascotSearchingDark
35 | }.also { _mascotSearching = it }
36 |
37 | private var _mascotSearching: ThemedImage? = null
38 |
39 | @PreviewLightAndDark
40 | @Composable
41 | private fun Preview() {
42 | SwissTransferTheme {
43 | Box {
44 | Image(
45 | imageVector = AppIllus.MascotSearching.image(),
46 | contentDescription = null,
47 | modifier = Modifier.size(AppImages.previewSize),
48 | )
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/upload/InputStreamCounter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.upload
19 |
20 | import android.net.Uri
21 | import splitties.init.appCtx
22 |
23 | internal class InputStreamCounter(
24 | bufferSize: Int = DEFAULT_BUFFER_SIZE // 8kiB only
25 | ) {
26 |
27 | private val sharedByteArrayForCountingBytes = ByteArray(bufferSize)
28 |
29 | /**
30 | * [android.provider.OpenableColumns.SIZE] is declarative, and could therefore have an inaccurate value,
31 | * so we're counting the bytes from the stream instead.
32 | */
33 | inline fun fileSizeFor(
34 | uri: Uri,
35 | onTotalBytesUpdate: (skippedBytes: Int, totalBytes: Long) -> Unit,
36 | ): Long = appCtx.contentResolver.openInputStream(uri)!!.buffered(sharedByteArrayForCountingBytes.size).use { stream ->
37 | var totalBytes = 0L
38 | while (true) {
39 | // The skip() method might skip beyond EOF. From FileInputStream's JavaDoc:
40 | // "This method may skip more bytes than what are remaining in the backing file."
41 | // (from https://docs.oracle.com/javase/8/docs/api/java/io/FileInputStream.html#skip-long-)
42 | // That's why we're using read instead.
43 | val skippedBytes = stream.read(sharedByteArrayForCountingBytes)
44 | if (skippedBytes == -1) break
45 | totalBytes += skippedBytes
46 | onTotalBytesUpdate(skippedBytes, totalBytes)
47 | }
48 | totalBytes
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_monochrome.xml:
--------------------------------------------------------------------------------
1 |
18 |
23 |
26 |
29 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/mascotWithMagnifyingGlass/MascotWithMagnifyingGlass.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024-2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.mascotWithMagnifyingGlass
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.size
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
26 | import com.infomaniak.swisstransfer.ui.images.AppImages
27 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
28 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
29 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
30 |
31 | val AppIllus.MascotWithMagnifyingGlass: ThemedImage
32 | get() = _mascotWithMagnifyingGlass ?: object : ThemedImage {
33 | override val light = AppIllus.MascotWithMagnifyingGlassLight
34 | override val dark = AppIllus.MascotWithMagnifyingGlassDark
35 | }.also { _mascotWithMagnifyingGlass = it }
36 |
37 | private var _mascotWithMagnifyingGlass: ThemedImage? = null
38 |
39 | @PreviewLightAndDark
40 | @Composable
41 | private fun Preview() {
42 | SwissTransferTheme {
43 | Box {
44 | Image(
45 | imageVector = AppIllus.MascotWithMagnifyingGlass.image(),
46 | contentDescription = null,
47 | modifier = Modifier.size(AppImages.previewSize),
48 | )
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/preprod/res/drawable/ic_launcher_monochrome.xml:
--------------------------------------------------------------------------------
1 |
18 |
23 |
26 |
29 |
33 |
34 |
--------------------------------------------------------------------------------
/.github/workflows/rebase-default-branch.yml:
--------------------------------------------------------------------------------
1 | # Rebases a pull request on the repo's default branch when the "rebase" label is added
2 | # Link: https://github.com/Infomaniak/.github/blob/main/workflow-templates/rebase-default-branch.yml
3 |
4 | name: Rebase Pull Request
5 |
6 | on:
7 | pull_request:
8 | types: [ labeled ]
9 |
10 | concurrency:
11 | group: ${{ github.workflow }}-${{ github.ref }}
12 | cancel-in-progress: true
13 |
14 | env:
15 | DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
16 |
17 | jobs:
18 | main:
19 | if: ${{ contains(github.event.*.labels.*.name, 'rebase') }}
20 | name: Rebase
21 | runs-on: ubuntu-latest
22 | steps:
23 | - name: Checkout
24 | uses: actions/checkout@v5.0.0
25 | with:
26 | ref: ${{ github.event.pull_request.head.ref }}
27 | fetch-depth: 0
28 |
29 | # Context: https://httgp.com/signing-commits-in-github-actions
30 | # Link: https://github.com/crazy-max/ghaction-import-gpg/releases
31 | - name: Import bot's GPG key for signing commits
32 | id: import-gpg
33 | uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0
34 | with:
35 | gpg_private_key: ${{ secrets.BOT_MOBILE_GPG_PRIVATE_KEY }}
36 | passphrase: ${{ secrets.BOT_MOBILE_GPG_PASSPHRASE }}
37 | git_config_global: true
38 | git_user_signingkey: true
39 | git_commit_gpgsign: true
40 |
41 | - name: perform rebase
42 | run: |
43 | git config --global user.name "dev-mobile-bot"
44 | git config --global user.email "mobile+github-bot@infomaniak-dev.ch"
45 | git status
46 | git pull
47 | git checkout "$DEFAULT_BRANCH"
48 | git status
49 | git pull
50 | git checkout "$GITHUB_HEAD_REF"
51 | git rebase "$DEFAULT_BRANCH"
52 | git push --force-with-lease
53 | git status
54 |
55 | # Context: https://github.com/marketplace/actions/actions-ecosystem-remove-labels
56 | # Link: https://github.com/actions-ecosystem/action-remove-labels/releases
57 | - name: remove label
58 | if: always()
59 | uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 # v1.3.0
60 | with:
61 | labels: rebase
62 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsSentryViewModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.main.settings
19 |
20 | import android.content.Context
21 | import androidx.datastore.preferences.core.edit
22 | import androidx.lifecycle.ViewModel
23 | import androidx.lifecycle.viewModelScope
24 | import com.infomaniak.swisstransfer.ui.utils.DataManagementPreferences
25 | import com.infomaniak.swisstransfer.ui.utils.dataManagementDataStore
26 | import com.infomaniak.swisstransfer.ui.utils.get
27 | import com.infomaniak.swisstransfer.ui.utils.set
28 | import dagger.hilt.android.lifecycle.HiltViewModel
29 | import dagger.hilt.android.qualifiers.ApplicationContext
30 | import kotlinx.coroutines.flow.SharingStarted
31 | import kotlinx.coroutines.flow.map
32 | import kotlinx.coroutines.flow.stateIn
33 | import kotlinx.coroutines.launch
34 | import javax.inject.Inject
35 |
36 | @HiltViewModel
37 | class SettingsSentryViewModel @Inject constructor(
38 | @ApplicationContext private val appContext: Context,
39 | ) : ViewModel() {
40 | val isSentryAuthorized = appContext.dataManagementDataStore.data
41 | .map { it[DataManagementPreferences.IsSentryAuthorized] }
42 | .stateIn(viewModelScope, SharingStarted.Lazily, false)
43 |
44 | fun setSentryAuthorization(isAuthorized: Boolean) {
45 | viewModelScope.launch {
46 | appContext.dataManagementDataStore.edit {
47 | it[DataManagementPreferences.IsSentryAuthorized] = isAuthorized
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/navigation/NavigationItem.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.navigation
19 |
20 | import androidx.annotation.StringRes
21 | import androidx.compose.material3.BottomAppBar
22 | import androidx.compose.material3.NavigationRail
23 | import androidx.compose.ui.graphics.vector.ImageVector
24 | import com.infomaniak.swisstransfer.R
25 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIcons
26 | import com.infomaniak.swisstransfer.ui.images.icons.ArrowDownCircle
27 | import com.infomaniak.swisstransfer.ui.images.icons.ArrowUpCircle
28 | import com.infomaniak.swisstransfer.ui.images.icons.Settings
29 | import com.infomaniak.swisstransfer.ui.navigation.MainNavigation.ReceivedDestination
30 | import com.infomaniak.swisstransfer.ui.navigation.MainNavigation.SentDestination
31 | import com.infomaniak.swisstransfer.ui.navigation.MainNavigation.SettingsDestination
32 |
33 | /**
34 | * Enum class representing the different destinations in the app's [BottomAppBar] or [NavigationRail].
35 | *
36 | * @property label The resource ID of the string label for the destination.
37 | * @property icon The icon to be displayed for the destination.
38 | */
39 | enum class NavigationItem(
40 | @StringRes val label: Int,
41 | val icon: ImageVector,
42 | val destination: MainNavigation,
43 | ) {
44 | SENT(R.string.sentTitle, AppIcons.ArrowUpCircle, SentDestination()),
45 | RECEIVED(R.string.receivedTitle, AppIcons.ArrowDownCircle, ReceivedDestination()),
46 | SETTINGS(R.string.settingsTitle, AppIcons.Settings, SettingsDestination),
47 | }
48 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | pluginManagement {
19 | repositories {
20 | google {
21 | content {
22 | includeGroupByRegex("com\\.android.*")
23 | includeGroupByRegex("com\\.google.*")
24 | includeGroupByRegex("androidx.*")
25 | }
26 | }
27 | mavenCentral()
28 | gradlePluginPortal()
29 | }
30 | }
31 | dependencyResolutionManagement {
32 | @Suppress("UnstableApiUsage")
33 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
34 | @Suppress("UnstableApiUsage")
35 | repositories {
36 | google()
37 | // mavenLocal() // Do not put this in production
38 | mavenCentral()
39 | maven { url = uri("https://jitpack.io") }
40 | }
41 | versionCatalogs {
42 | create("core") { from(files("Core/gradle/core.versions.toml")) }
43 | }
44 | }
45 |
46 | rootProject.name = "android-SwissTransfer"
47 | include(
48 | ":app",
49 | ":Core",
50 | ":Core:AppIntegrity",
51 | ":Core:AppVersionChecker",
52 | ":Core:FileTypes",
53 | ":Core:InAppReview",
54 | ":Core:InAppUpdate",
55 | ":Core:Matomo",
56 | ":Core:Network",
57 | ":Core:Network:Models",
58 | ":Core:Notifications",
59 | ":Core:Onboarding",
60 | ":Core:Sentry",
61 | ":Core:Thumbnails",
62 | ":Core:Ui:View",
63 | ":Core:Ui:Compose:BasicButton",
64 | ":Core:Ui:Compose:Basics",
65 | ":Core:Ui:Compose:BottomStickyButtonScaffolds",
66 | ":Core:Ui:Compose:Margin",
67 | ":Core:Ui:Compose:Preview",
68 | ":Core:WebView",
69 | )
70 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/uploadCancelBottomSheet/RedCrossPaperPlanes.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.uploadCancelBottomSheet
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.size
23 | import androidx.compose.material3.Surface
24 | import androidx.compose.runtime.Composable
25 | import androidx.compose.ui.Modifier
26 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
27 | import com.infomaniak.swisstransfer.ui.images.AppImages
28 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
29 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
30 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
31 |
32 | val AppIllus.RedCrossPaperPlanes: ThemedImage
33 | get() = _redCrossPaperPlanes ?: object : ThemedImage {
34 | override val light = AppIllus.RedCrossPaperPlanesLight
35 | override val dark = AppIllus.RedCrossPaperPlanesDark
36 | }.also { _redCrossPaperPlanes = it }
37 |
38 | private var _redCrossPaperPlanes: ThemedImage? = null
39 |
40 | @PreviewLightAndDark
41 | @Composable
42 | private fun Preview() {
43 | SwissTransferTheme {
44 | Surface {
45 | Box {
46 | Image(
47 | imageVector = AppIllus.RedCrossPaperPlanes.image(),
48 | contentDescription = null,
49 | modifier = Modifier.size(AppImages.previewSize),
50 | )
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/splashscreen_gradient_legacy.xml:
--------------------------------------------------------------------------------
1 |
18 |
24 |
25 |
26 |
32 |
35 |
38 |
39 |
40 |
41 |
42 |
43 |
48 |
51 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/transferdetails/emptystate/VirusCheckContent.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.main.transferdetails.emptystate
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.material3.Surface
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.runtime.LaunchedEffect
24 | import androidx.compose.ui.res.stringResource
25 | import com.infomaniak.core.ui.compose.preview.PreviewSmallWindow
26 | import com.infomaniak.multiplatform_swisstransfer.common.matomo.MatomoScreen
27 | import com.infomaniak.swisstransfer.R
28 | import com.infomaniak.swisstransfer.ui.MatomoSwissTransfer
29 | import com.infomaniak.swisstransfer.ui.components.EmptyState
30 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
31 | import com.infomaniak.swisstransfer.ui.images.illus.ghostScanningSquare.GhostScanningSquare
32 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
33 |
34 | @Composable
35 | fun VirusCheckContent() {
36 | LaunchedEffect(Unit) { MatomoSwissTransfer.trackScreen(MatomoScreen.VirusCheck) }
37 |
38 | EmptyState(
39 | content = { Image(imageVector = AppIllus.GhostScanningSquare.image(), contentDescription = null) },
40 | title = stringResource(R.string.transferVirusCheckTitle),
41 | description = stringResource(R.string.transferVirusCheckDescription),
42 | )
43 | }
44 |
45 |
46 | @PreviewSmallWindow
47 | @Composable
48 | private fun Preview() {
49 | SwissTransferTheme {
50 | Surface {
51 | VirusCheckContent()
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/components/TextDotText.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | @file:OptIn(ExperimentalTypeInference::class)
19 |
20 | package com.infomaniak.swisstransfer.ui.components
21 |
22 | import androidx.compose.foundation.layout.Row
23 | import androidx.compose.foundation.layout.Spacer
24 | import androidx.compose.foundation.layout.width
25 | import androidx.compose.material3.ProvideTextStyle
26 | import androidx.compose.material3.Text
27 | import androidx.compose.runtime.Composable
28 | import androidx.compose.ui.Modifier
29 | import androidx.compose.ui.graphics.Color
30 | import androidx.compose.ui.semantics.hideFromAccessibility
31 | import androidx.compose.ui.semantics.semantics
32 | import androidx.compose.ui.text.TextStyle
33 | import com.infomaniak.core.ui.compose.margin.Margin
34 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
35 | import kotlin.experimental.ExperimentalTypeInference
36 |
37 | @Composable
38 | fun TextDotText(
39 | firstText: @Composable () -> Unit,
40 | secondText: (@Composable () -> Unit)? = null,
41 | modifier: Modifier = Modifier,
42 | color: Color = SwissTransferTheme.colors.secondaryTextColor,
43 | style: TextStyle = SwissTransferTheme.typography.bodySmallRegular,
44 | ) = Row(modifier) {
45 | ProvideTextStyle(style.copy(color = color)) {
46 | firstText()
47 | secondText?.let { secondText ->
48 | Spacer(Modifier.width(Margin.Mini))
49 | Text(text = "•", modifier = Modifier.semantics { hideFromAccessibility() })
50 | Spacer(Modifier.width(Margin.Mini))
51 | secondText()
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/onboarding/RadialGradientCornerTopLeft.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.onboarding
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.width
23 | import androidx.compose.material3.Surface
24 | import androidx.compose.runtime.Composable
25 | import androidx.compose.ui.Modifier
26 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
27 | import com.infomaniak.swisstransfer.ui.images.AppImages
28 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
29 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
30 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
31 |
32 | val AppIllus.RadialGradientCornerTopLeft: ThemedImage
33 | get() = _radialGradientCornerTopLeft ?: object : ThemedImage {
34 | override val light = AppIllus.RadialGradientCornerTopLeftLight
35 | override val dark = AppIllus.RadialGradientCornerTopLeftDark
36 | }.also { _radialGradientCornerTopLeft = it }
37 |
38 | private var _radialGradientCornerTopLeft: ThemedImage? = null
39 |
40 | @PreviewLightAndDark
41 | @Composable
42 | private fun Preview() {
43 | SwissTransferTheme {
44 | Surface {
45 | Box {
46 | Image(
47 | imageVector = AppIllus.RadialGradientCornerTopLeft.image(),
48 | contentDescription = null,
49 | modifier = Modifier.width(AppImages.previewSize),
50 | )
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/transferdetails/emptystate/UnknownTransferErrorContent.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.main.transferdetails.emptystate
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.material3.Surface
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.runtime.LaunchedEffect
24 | import androidx.compose.ui.res.stringResource
25 | import androidx.compose.ui.tooling.preview.Preview
26 | import com.infomaniak.multiplatform_swisstransfer.common.matomo.MatomoScreen
27 | import com.infomaniak.swisstransfer.R
28 | import com.infomaniak.swisstransfer.ui.MatomoSwissTransfer
29 | import com.infomaniak.swisstransfer.ui.components.EmptyState
30 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
31 | import com.infomaniak.swisstransfer.ui.images.illus.uploadError.GhostMagnifyingGlassQuestionMark
32 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
33 |
34 | @Composable
35 | fun UnknownTransferErrorContent() {
36 | LaunchedEffect(Unit) { MatomoSwissTransfer.trackScreen(MatomoScreen.UnknownTransferError) }
37 |
38 | EmptyState(
39 | content = { Image(imageVector = AppIllus.GhostMagnifyingGlassQuestionMark.image(), contentDescription = null) },
40 | title = stringResource(R.string.uploadErrorTitle),
41 | description = stringResource(R.string.validateMailUnknownError),
42 | )
43 | }
44 |
45 | @Preview
46 | @Composable
47 | private fun Preview() {
48 | SwissTransferTheme {
49 | Surface {
50 | UnknownTransferErrorContent()
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/transferdetails/emptystate/VirusDetectedContent.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.main.transferdetails.emptystate
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.material3.Surface
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.runtime.LaunchedEffect
24 | import androidx.compose.ui.res.stringResource
25 | import com.infomaniak.core.ui.compose.preview.PreviewSmallWindow
26 | import com.infomaniak.multiplatform_swisstransfer.common.matomo.MatomoScreen
27 | import com.infomaniak.swisstransfer.R
28 | import com.infomaniak.swisstransfer.ui.MatomoSwissTransfer
29 | import com.infomaniak.swisstransfer.ui.components.EmptyState
30 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
31 | import com.infomaniak.swisstransfer.ui.images.illus.ghostPointingReport.GhostPointingReport
32 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
33 |
34 | @Composable
35 | fun VirusDetectedContent() {
36 | LaunchedEffect(Unit) { MatomoSwissTransfer.trackScreen(MatomoScreen.VirusDetected) }
37 |
38 | EmptyState(
39 | content = { Image(imageVector = AppIllus.GhostPointingReport.image(), contentDescription = null) },
40 | title = stringResource(R.string.transferVirusDetectedTitle),
41 | description = stringResource(R.string.transferVirusDetectedDescription),
42 | )
43 | }
44 |
45 |
46 | @PreviewSmallWindow
47 | @Composable
48 | private fun Preview() {
49 | SwissTransferTheme {
50 | Surface {
51 | VirusDetectedContent()
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/onboarding/RadialGradientCornerTopRight.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.onboarding
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.width
23 | import androidx.compose.material3.Surface
24 | import androidx.compose.runtime.Composable
25 | import androidx.compose.ui.Modifier
26 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
27 | import com.infomaniak.swisstransfer.ui.images.AppImages
28 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
29 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
30 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
31 |
32 | val AppIllus.RadialGradientCornerTopRight: ThemedImage
33 | get() = _radialGradientCornerTopRight ?: object : ThemedImage {
34 | override val light = AppIllus.RadialGradientCornerTopRightLight
35 | override val dark = AppIllus.RadialGradientCornerTopRightDark
36 | }.also { _radialGradientCornerTopRight = it }
37 |
38 | private var _radialGradientCornerTopRight: ThemedImage? = null
39 |
40 | @PreviewLightAndDark
41 | @Composable
42 | private fun Preview() {
43 | SwissTransferTheme {
44 | Surface {
45 | Box {
46 | Image(
47 | imageVector = AppIllus.RadialGradientCornerTopRight.image(),
48 | contentDescription = null,
49 | modifier = Modifier.width(AppImages.previewSize),
50 | )
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_logo_notification.xml:
--------------------------------------------------------------------------------
1 |
18 |
23 |
26 |
29 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/validateemail/HideSelectAllTextToolbar.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.newtransfer.validateemail
19 |
20 | import androidx.compose.ui.geometry.Rect
21 | import androidx.compose.ui.platform.TextToolbar
22 | import androidx.compose.ui.platform.TextToolbarStatus
23 |
24 | class HideSelectAllTextToolbar(private val previousToolbar: TextToolbar) : TextToolbar {
25 | override val status: TextToolbarStatus get() = previousToolbar.status
26 |
27 | override fun showMenu(
28 | rect: Rect,
29 | onCopyRequested: (() -> Unit)?,
30 | onPasteRequested: (() -> Unit)?,
31 | onCutRequested: (() -> Unit)?,
32 | onSelectAllRequested: (() -> Unit)?,
33 | onAutofillRequested: (() -> Unit)?,
34 | ) {
35 | previousToolbar.showMenu(
36 | rect,
37 | onCopyRequested,
38 | onPasteRequested,
39 | onCutRequested,
40 | null, // Disable "Select All"
41 | onAutofillRequested,
42 | )
43 | }
44 |
45 | override fun showMenu(
46 | rect: Rect,
47 | onCopyRequested: (() -> Unit)?,
48 | onPasteRequested: (() -> Unit)?,
49 | onCutRequested: (() -> Unit)?,
50 | onSelectAllRequested: (() -> Unit)?
51 | ) {
52 | previousToolbar.showMenu(
53 | rect,
54 | onCopyRequested,
55 | onPasteRequested,
56 | onCutRequested,
57 | null, // Disable "Select All"
58 | )
59 | }
60 |
61 | override fun hide() {
62 | previousToolbar.hide()
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/components/SharpRippleButton.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.components
19 |
20 | import androidx.compose.foundation.layout.PaddingValues
21 | import androidx.compose.foundation.layout.RowScope
22 | import androidx.compose.foundation.selection.selectable
23 | import androidx.compose.material3.Button
24 | import androidx.compose.material3.ButtonDefaults
25 | import androidx.compose.runtime.Composable
26 | import androidx.compose.ui.Modifier
27 | import androidx.compose.ui.unit.dp
28 | import com.infomaniak.swisstransfer.ui.theme.CustomShapes
29 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
30 |
31 | @Composable
32 | fun SharpRippleButton(
33 | modifier: Modifier = Modifier,
34 | isSelected: () -> Boolean = { false },
35 | onClick: () -> Unit,
36 | contentPadding: PaddingValues = PaddingValues(0.dp),
37 | content: @Composable RowScope.() -> Unit,
38 | ) {
39 | val colors = if (isSelected()) {
40 | ButtonDefaults.textButtonColors(
41 | contentColor = SwissTransferTheme.colors.primaryTextColor,
42 | containerColor = SwissTransferTheme.colors.selectedSettingItem,
43 | )
44 | } else {
45 | ButtonDefaults.textButtonColors(contentColor = SwissTransferTheme.colors.primaryTextColor)
46 | }
47 | Button(
48 | modifier = modifier.selectable(
49 | selected = isSelected(),
50 | onClick = onClick,
51 | ),
52 | colors = colors,
53 | shape = CustomShapes.NONE,
54 | onClick = onClick,
55 | content = content,
56 | contentPadding = contentPadding,
57 | )
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/uploadError/GhostMagnifyingGlassQuestionMark.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.uploadError
19 |
20 | import androidx.compose.foundation.Image
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.size
23 | import androidx.compose.material3.Surface
24 | import androidx.compose.runtime.Composable
25 | import androidx.compose.ui.Modifier
26 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
27 | import com.infomaniak.swisstransfer.ui.images.AppImages
28 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
29 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
30 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
31 |
32 | val AppIllus.GhostMagnifyingGlassQuestionMark: ThemedImage
33 | get() = _ghostMagnifyingGlassQuestionMark ?: object : ThemedImage {
34 | override val light = AppIllus.GhostMagnifyingGlassQuestionMarkLight
35 | override val dark = AppIllus.GhostMagnifyingGlassQuestionMarkDark
36 | }.also { _ghostMagnifyingGlassQuestionMark = it }
37 |
38 | private var _ghostMagnifyingGlassQuestionMark: ThemedImage? = null
39 |
40 | @PreviewLightAndDark
41 | @Composable
42 | private fun Preview() {
43 | SwissTransferTheme {
44 | Surface {
45 | Box {
46 | Image(
47 | imageVector = AppIllus.GhostMagnifyingGlassQuestionMark.image(),
48 | contentDescription = null,
49 | modifier = Modifier.size(AppImages.previewSize),
50 | )
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/components/EmailsFlowRow.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.components
19 |
20 | import androidx.compose.foundation.layout.Arrangement
21 | import androidx.compose.foundation.layout.ExperimentalLayoutApi
22 | import androidx.compose.foundation.layout.FlowRow
23 | import androidx.compose.foundation.layout.padding
24 | import androidx.compose.material3.Surface
25 | import androidx.compose.runtime.Composable
26 | import androidx.compose.ui.Modifier
27 | import androidx.compose.ui.tooling.preview.PreviewParameter
28 | import com.infomaniak.core.ui.compose.margin.Margin
29 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
30 | import com.infomaniak.swisstransfer.ui.previewparameter.EmailsPreviewParameter
31 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
32 |
33 | @OptIn(ExperimentalLayoutApi::class)
34 | @Composable
35 | fun EmailsFlowRow(
36 | emails: List,
37 | modifier: Modifier = Modifier,
38 | horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
39 | ) {
40 | FlowRow(
41 | modifier = modifier,
42 | horizontalArrangement = horizontalArrangement,
43 | ) {
44 | emails.forEach {
45 | SwissTransferSuggestionChip(
46 | text = it,
47 | modifier = Modifier.padding(horizontal = Margin.Micro),
48 | )
49 | }
50 | }
51 | }
52 |
53 | @PreviewLightAndDark
54 | @Composable
55 | private fun Preview(@PreviewParameter(EmailsPreviewParameter::class) emails: List) {
56 | SwissTransferTheme {
57 | Surface {
58 | EmailsFlowRow(emails)
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/ghostPointingReport/GhostPointingReport.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.ghostPointingReport
19 |
20 | import android.content.res.Configuration
21 | import androidx.compose.foundation.Image
22 | import androidx.compose.foundation.layout.Box
23 | import androidx.compose.foundation.layout.size
24 | import androidx.compose.material3.Surface
25 | import androidx.compose.runtime.Composable
26 | import androidx.compose.ui.Modifier
27 | import androidx.compose.ui.tooling.preview.Preview
28 | import com.infomaniak.swisstransfer.ui.images.AppImages
29 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
30 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
31 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
32 |
33 | val AppIllus.GhostPointingReport: ThemedImage
34 | get() = _ghostPointingReport ?: object : ThemedImage {
35 | override val light = AppIllus.GhostPointingReportLight
36 | override val dark = AppIllus.GhostPointingReportDark
37 | }.also { _ghostPointingReport = it }
38 |
39 | private var _ghostPointingReport: ThemedImage? = null
40 |
41 | @Preview(name = "Light")
42 | @Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL)
43 | @Composable
44 | private fun Preview() {
45 | SwissTransferTheme {
46 | Surface {
47 | Box {
48 | Image(
49 | imageVector = AppIllus.GhostPointingReport.image(),
50 | contentDescription = null,
51 | modifier = Modifier.size(AppImages.previewSize),
52 | )
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/ghostScanningSquare/GhostScanningSquare.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.ghostScanningSquare
19 |
20 | import android.content.res.Configuration
21 | import androidx.compose.foundation.Image
22 | import androidx.compose.foundation.layout.Box
23 | import androidx.compose.foundation.layout.size
24 | import androidx.compose.material3.Surface
25 | import androidx.compose.runtime.Composable
26 | import androidx.compose.ui.Modifier
27 | import androidx.compose.ui.tooling.preview.Preview
28 | import com.infomaniak.swisstransfer.ui.images.AppImages
29 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
30 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
31 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
32 |
33 | val AppIllus.GhostScanningSquare: ThemedImage
34 | get() = _ghostScanningSquare ?: object : ThemedImage {
35 | override val light = AppIllus.GhostScanningSquareLight
36 | override val dark = AppIllus.GhostScanningSquareDark
37 | }.also { _ghostScanningSquare = it }
38 |
39 | private var _ghostScanningSquare: ThemedImage? = null
40 |
41 | @Preview(name = "Light")
42 | @Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL)
43 | @Composable
44 | private fun Preview() {
45 | SwissTransferTheme {
46 | Surface {
47 | Box {
48 | Image(
49 | imageVector = AppIllus.GhostScanningSquare.image(),
50 | contentDescription = null,
51 | modifier = Modifier.size(AppImages.previewSize),
52 | )
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/images/illus/appIntegrity/GhostScrollCrossPointing.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.images.illus.appIntegrity
19 |
20 | import android.content.res.Configuration
21 | import androidx.compose.foundation.Image
22 | import androidx.compose.foundation.layout.Box
23 | import androidx.compose.foundation.layout.size
24 | import androidx.compose.material3.Surface
25 | import androidx.compose.runtime.Composable
26 | import androidx.compose.ui.Modifier
27 | import androidx.compose.ui.tooling.preview.Preview
28 | import com.infomaniak.swisstransfer.ui.images.AppImages
29 | import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus
30 | import com.infomaniak.swisstransfer.ui.images.ThemedImage
31 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
32 |
33 | val AppIllus.GhostScrollCrossPointing: ThemedImage
34 | get() = _ghostScrollCrossPointing ?: object : ThemedImage {
35 | override val light = AppIllus.GhostScrollCrossPointingLight
36 | override val dark = AppIllus.GhostScrollCrossPointingDark
37 | }.also { _ghostScrollCrossPointing = it }
38 |
39 | private var _ghostScrollCrossPointing: ThemedImage? = null
40 |
41 | @Preview(name = "Light")
42 | @Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL)
43 | @Composable
44 | private fun Preview() {
45 | SwissTransferTheme {
46 | Surface {
47 | Box {
48 | Image(
49 | imageVector = AppIllus.GhostScrollCrossPointing.image(),
50 | contentDescription = null,
51 | modifier = Modifier.size(AppImages.previewSize),
52 | )
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/components/NewTransferFab.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.components
19 |
20 | import androidx.compose.foundation.layout.Row
21 | import androidx.compose.foundation.layout.Spacer
22 | import androidx.compose.foundation.layout.width
23 | import androidx.compose.material3.Surface
24 | import androidx.compose.runtime.Composable
25 | import androidx.compose.ui.Modifier
26 | import androidx.compose.ui.platform.LocalContext
27 | import com.infomaniak.core.ui.compose.margin.Margin
28 | import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
29 | import com.infomaniak.swisstransfer.ui.NewTransferActivity
30 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
31 | import com.infomaniak.swisstransfer.ui.utils.launchActivity
32 |
33 | @Composable
34 | fun NewTransferFab(
35 | modifier: Modifier = Modifier,
36 | newTransferFabType: NewTransferFabType
37 | ) {
38 | val context = LocalContext.current
39 |
40 | SwissTransferFab(
41 | modifier = modifier,
42 | fabType = newTransferFabType.fabType,
43 | onClick = { context.launchActivity(NewTransferActivity::class) },
44 | )
45 | }
46 |
47 | enum class NewTransferFabType(val fabType: FabType) {
48 | BOTTOM_BAR(FabType.NORMAL),
49 | EMPTY_STATE(FabType.BIG);
50 | }
51 |
52 | @PreviewLightAndDark
53 | @Composable
54 | private fun NewTransferFabPreview() {
55 | SwissTransferTheme {
56 | Surface {
57 | Row {
58 | NewTransferFab(newTransferFabType = NewTransferFabType.BOTTOM_BAR)
59 | Spacer(Modifier.width(Margin.Large))
60 | NewTransferFab(newTransferFabType = NewTransferFabType.EMPTY_STATE)
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/transfers/components/DeleteTransferDialog.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2025 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.main.transfers.components
19 |
20 | import androidx.compose.material3.Surface
21 | import androidx.compose.runtime.Composable
22 | import androidx.compose.ui.res.stringResource
23 | import androidx.compose.ui.tooling.preview.PreviewLightDark
24 | import com.infomaniak.swisstransfer.R
25 | import com.infomaniak.swisstransfer.ui.components.ButtonType
26 | import com.infomaniak.swisstransfer.ui.components.SmallButton
27 | import com.infomaniak.swisstransfer.ui.components.SwissTransferAlertDialog
28 | import com.infomaniak.swisstransfer.ui.components.SwissTransferAlertDialogDefaults
29 | import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
30 |
31 | @Composable
32 | fun DeleteTransferDialog(
33 | closeAlertDialog: () -> Unit,
34 | onConfirmation: () -> Unit,
35 | ) {
36 | SwissTransferAlertDialog(
37 | title = stringResource(R.string.deleteThisTransferTitle),
38 | description = stringResource(R.string.deleteThisTransferDescription),
39 | onDismiss = closeAlertDialog,
40 | positiveButton = {
41 | SmallButton(
42 | stringResource(R.string.buttonDeleteYes),
43 | onClick = { onConfirmation() },
44 | style = ButtonType.Destructive,
45 | )
46 | },
47 | negativeButton = { SwissTransferAlertDialogDefaults.CancelButton(onClick = closeAlertDialog) },
48 | )
49 | }
50 |
51 | @PreviewLightDark
52 | @Composable
53 | private fun Preview() {
54 | SwissTransferTheme {
55 | Surface {
56 | DeleteTransferDialog(
57 | closeAlertDialog = {},
58 | onConfirmation = {},
59 | )
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsViewModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.ui.screen.main.settings
19 |
20 | import androidx.lifecycle.ViewModel
21 | import androidx.lifecycle.viewModelScope
22 | import com.infomaniak.multiplatform_swisstransfer.common.models.DownloadLimit
23 | import com.infomaniak.multiplatform_swisstransfer.common.models.EmailLanguage
24 | import com.infomaniak.multiplatform_swisstransfer.common.models.Theme
25 | import com.infomaniak.multiplatform_swisstransfer.common.models.ValidityPeriod
26 | import com.infomaniak.multiplatform_swisstransfer.managers.AppSettingsManager
27 | import com.infomaniak.swisstransfer.di.IoDispatcher
28 | import dagger.hilt.android.lifecycle.HiltViewModel
29 | import kotlinx.coroutines.CoroutineDispatcher
30 | import kotlinx.coroutines.launch
31 | import javax.inject.Inject
32 |
33 | @HiltViewModel
34 | class SettingsViewModel @Inject constructor(
35 | private val appSettingsManager: AppSettingsManager,
36 | @IoDispatcher private val ioDispatcher: CoroutineDispatcher,
37 | ) : ViewModel() {
38 |
39 | val appSettingsFlow = appSettingsManager.appSettings
40 |
41 | fun setTheme(theme: Theme) = viewModelScope.launch(ioDispatcher) {
42 | appSettingsManager.setTheme(theme)
43 | }
44 |
45 | fun setValidityPeriod(validityPeriod: ValidityPeriod) = viewModelScope.launch(ioDispatcher) {
46 | appSettingsManager.setValidityPeriod(validityPeriod)
47 | }
48 |
49 | fun setDownloadLimit(downloadLimit: DownloadLimit) = viewModelScope.launch(ioDispatcher) {
50 | appSettingsManager.setDownloadLimit(downloadLimit)
51 | }
52 |
53 | fun setEmailLanguage(emailLanguage: EmailLanguage) = viewModelScope.launch(ioDispatcher) {
54 | appSettingsManager.setEmailLanguage(emailLanguage)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/test/java/com/infomaniak/swisstransfer/TransferDatesUnitTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer
19 |
20 | import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.TransferUi
21 | import com.infomaniak.swisstransfer.dataset.DummyTransfer
22 | import com.infomaniak.swisstransfer.ui.utils.ExpiryStatus
23 | import com.infomaniak.swisstransfer.ui.utils.daysBeforeExpiry
24 | import com.infomaniak.swisstransfer.ui.utils.expiryStatus
25 | import com.infomaniak.swisstransfer.ui.utils.isExpired
26 | import org.junit.Test
27 |
28 | class TransferDatesUnitTest {
29 |
30 | @Test
31 | fun check_expiryStatus_are_correct() {
32 | assert(TransferUi(DummyTransfer.expired).expiryStatus() == ExpiryStatus.EXPIRED)
33 | assert(TransferUi(DummyTransfer.expiresToday).expiryStatus() == ExpiryStatus.EXPIRES_TODAY)
34 | assert(TransferUi(DummyTransfer.expiresTomorrow).expiryStatus() == ExpiryStatus.EXPIRES_TOMORROW)
35 | assert(TransferUi(DummyTransfer.notExpired).expiryStatus() == ExpiryStatus.NOT_EXPIRED)
36 | }
37 |
38 | @Test
39 | fun check_daysBeforeExpiry_are_correct() {
40 | assert(TransferUi(DummyTransfer.expired).daysBeforeExpiry == -5)
41 | assert(TransferUi(DummyTransfer.expiresToday).daysBeforeExpiry == 0)
42 | assert(TransferUi(DummyTransfer.expiresTomorrow).daysBeforeExpiry == 1)
43 | assert(TransferUi(DummyTransfer.notExpired).daysBeforeExpiry == 5)
44 | }
45 |
46 | @Test
47 | fun check_isExpired_are_correct() {
48 | assert(TransferUi(DummyTransfer.expired).isExpired)
49 | assert(TransferUi(DummyTransfer.expiresToday).isExpired.not())
50 | assert(TransferUi(DummyTransfer.expiresTomorrow).isExpired.not())
51 | assert(TransferUi(DummyTransfer.notExpired).isExpired.not())
52 | assert(TransferUi(DummyTransfer.downloaded).isExpired)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/infomaniak/swisstransfer/di/ApplicationModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Infomaniak SwissTransfer - Android
3 | * Copyright (C) 2024 Infomaniak Network SA
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.infomaniak.swisstransfer.di
19 |
20 | import android.app.Application
21 | import android.content.Context
22 | import androidx.core.app.NotificationManagerCompat
23 | import androidx.work.WorkManager
24 | import com.infomaniak.core.appintegrity.AppIntegrityManager
25 | import com.infomaniak.core.utils.buildUserAgent
26 | import com.infomaniak.swisstransfer.BuildConfig
27 | import com.infomaniak.swisstransfer.ui.MainApplication
28 | import dagger.Module
29 | import dagger.Provides
30 | import dagger.hilt.InstallIn
31 | import dagger.hilt.android.qualifiers.ApplicationContext
32 | import dagger.hilt.components.SingletonComponent
33 | import javax.inject.Singleton
34 |
35 | @Module
36 | @InstallIn(SingletonComponent::class)
37 | object ApplicationModule {
38 |
39 | @Provides
40 | fun providesMainApplication(application: Application) = application as MainApplication
41 |
42 | @Provides
43 | @Singleton
44 | fun providesWorkManager(@ApplicationContext appContext: Context) = WorkManager.getInstance(appContext)
45 |
46 | @UserAgent
47 | @Provides
48 | @Singleton
49 | fun providesUserAgent(): String {
50 | return buildUserAgent(
51 | appId = BuildConfig.APPLICATION_ID,
52 | appVersionCode = BuildConfig.VERSION_CODE,
53 | appVersionName = BuildConfig.VERSION_NAME,
54 | )
55 | }
56 |
57 | @Provides
58 | @Singleton
59 | fun providesAppIntegrityManager(application: Application, @UserAgent userAgent: String): AppIntegrityManager {
60 | return AppIntegrityManager(application, userAgent)
61 | }
62 |
63 | @Provides
64 | @Singleton
65 | fun providesNotificationManagerCompat(@ApplicationContext appContext: Context): NotificationManagerCompat {
66 | return NotificationManagerCompat.from(appContext)
67 | }
68 | }
69 |
--------------------------------------------------------------------------------