diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 97c49f1e5..9305f2b82 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -105,6 +105,7 @@ dependencies { implementation(libs.swisstransfer.core) implementation(libs.coil.compose) + implementation(libs.qrose) // Compose preview tools implementation(libs.compose.ui.tooling.preview) diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/components/QrCode.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/components/QrCode.kt index 37acad089..a48898f80 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/components/QrCode.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/components/QrCode.kt @@ -18,34 +18,46 @@ package com.infomaniak.swisstransfer.ui.components import android.content.res.Configuration -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.Image import androidx.compose.foundation.layout.size import androidx.compose.material3.Surface import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.infomaniak.swisstransfer.ui.theme.CustomShapes +import com.infomaniak.swisstransfer.ui.images.AppImages.AppIcons +import com.infomaniak.swisstransfer.ui.images.icons.qrInfomaniak.QrInfomaniak import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme +import io.github.alexzhirkevich.qrose.options.QrBrush +import io.github.alexzhirkevich.qrose.options.QrLogoPadding +import io.github.alexzhirkevich.qrose.options.solid +import io.github.alexzhirkevich.qrose.rememberQrCodePainter @Composable -fun QrCode() { // TODO: Add parameter containing the QR code value, and use it. - Box( - modifier = Modifier - .size(180.dp) - .clip(CustomShapes.SMALL) - .background(SwissTransferTheme.colors.qrCodeBackground), - contentAlignment = Alignment.Center, - ) { - Box( - modifier = Modifier - .size(160.dp) - .background(SwissTransferTheme.colors.qrCodeColor), // TODO: Use this color to tint the QR code. - ) +fun QrCode() { + + val url = "https://chk.me/83azQOl" // TODO: Use correct URL instead of hard-coded value. + val centralIcon = rememberVectorPainter(AppIcons.QrInfomaniak.image()) + val darkPixelsColor = QrBrush.solid(SwissTransferTheme.colors.qrCodeDarkPixels) + val lightPixelsColor = QrBrush.solid(SwissTransferTheme.colors.qrCodeLightPixels) + val painter = rememberQrCodePainter(url) { + colors { + dark = darkPixelsColor + light = lightPixelsColor + } + logo { + painter = centralIcon + size = 0.25f // 25% : Icon size in fraction relative to the QR Code size. + padding = QrLogoPadding.Natural(size = 0.08f) // 8% : Padding size in fraction relative to the Icon size. + } } + + Image( + modifier = Modifier.size(160.dp), + painter = painter, + contentDescription = null, + ) } @Preview(name = "Light mode") diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/images/icons/qrInfomaniak/QrInfomaniak.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/images/icons/qrInfomaniak/QrInfomaniak.kt new file mode 100644 index 000000000..3ac56b79a --- /dev/null +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/images/icons/qrInfomaniak/QrInfomaniak.kt @@ -0,0 +1,53 @@ +/* + * Infomaniak SwissTransfer - Android + * Copyright (C) 2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.infomaniak.swisstransfer.ui.images.icons.qrInfomaniak + +import android.content.res.Configuration +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.infomaniak.swisstransfer.ui.images.AppImages +import com.infomaniak.swisstransfer.ui.images.AppImages.AppIcons +import com.infomaniak.swisstransfer.ui.images.ThemedImage +import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme + +val AppIcons.QrInfomaniak: ThemedImage + get() = _qrInfomaniak ?: object : ThemedImage { + override val light = AppIcons.QrInfomaniakLight + override val dark = AppIcons.QrInfomaniakDark + }.also { _qrInfomaniak = it } + +private var _qrInfomaniak: ThemedImage? = null + +@Preview(name = "Light") +@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL) +@Composable +private fun Preview() { + SwissTransferTheme { + Box { + Image( + imageVector = AppIcons.QrInfomaniak.image(), + contentDescription = null, + modifier = Modifier.size(AppImages.previewSize), + ) + } + } +} diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/images/icons/qrInfomaniak/QrInfomaniakDark.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/images/icons/qrInfomaniak/QrInfomaniakDark.kt new file mode 100644 index 000000000..a70de2357 --- /dev/null +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/images/icons/qrInfomaniak/QrInfomaniakDark.kt @@ -0,0 +1,112 @@ +/* + * Infomaniak SwissTransfer - Android + * Copyright (C) 2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.infomaniak.swisstransfer.ui.images.icons.qrInfomaniak + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.PathFillType.Companion.EvenOdd +import androidx.compose.ui.graphics.PathFillType.Companion.NonZero +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.graphics.StrokeCap.Companion.Butt +import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.ImageVector.Builder +import androidx.compose.ui.graphics.vector.path +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.infomaniak.swisstransfer.ui.images.AppImages +import com.infomaniak.swisstransfer.ui.images.AppImages.AppIcons + +val AppIcons.QrInfomaniakDark: ImageVector + get() { + + if (_qrInfomaniakDark != null) return _qrInfomaniakDark!! + + _qrInfomaniakDark = Builder( + name = "QrInfomaniakDark", + defaultWidth = 41.0.dp, + defaultHeight = 44.0.dp, + viewportWidth = 41.0f, + viewportHeight = 44.0f, + ).apply { + path( + fill = SolidColor(Color(0xFFF1F1F1)), + stroke = null, + strokeLineWidth = 0.0f, + strokeLineCap = Butt, + strokeLineJoin = Miter, + strokeLineMiter = 4.0f, + pathFillType = NonZero, + ) { + moveTo(36.9f, 0.0f) + horizontalLineTo(4.1f) + curveTo(1.835f, 0.0f, -0.0f, 1.97f, -0.0f, 4.4f) + verticalLineTo(39.6f) + curveTo(-0.0f, 42.03f, 1.835f, 44.0f, 4.1f, 44.0f) + horizontalLineTo(36.9f) + curveTo(39.164f, 44.0f, 41.0f, 42.03f, 41.0f, 39.6f) + verticalLineTo(4.4f) + curveTo(41.0f, 1.97f, 39.164f, 0.0f, 36.9f, 0.0f) + close() + } + path( + fill = SolidColor(Color(0xFF152123)), + stroke = null, + strokeLineWidth = 0.0f, + strokeLineCap = Butt, + strokeLineJoin = Miter, + strokeLineMiter = 4.0f, + pathFillType = EvenOdd, + ) { + moveTo(8.552f, 36.637f) + horizontalLineTo(17.054f) + verticalLineTo(30.677f) + lineTo(20.158f, 27.469f) + lineTo(24.575f, 36.637f) + horizontalLineTo(33.976f) + lineTo(25.685f, 21.793f) + lineTo(33.486f, 13.848f) + horizontalLineTo(23.267f) + lineTo(17.054f, 21.386f) + verticalLineTo(0.0f) + horizontalLineTo(8.552f) + verticalLineTo(36.637f) + close() + } + }.build() + + return _qrInfomaniakDark!! + } + +private var _qrInfomaniakDark: ImageVector? = null + +@Preview +@Composable +private fun Preview() { + Box { + Image( + imageVector = AppIcons.QrInfomaniakDark, + contentDescription = null, + modifier = Modifier.size(AppImages.previewSize), + ) + } +} diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/images/icons/qrInfomaniak/QrInfomaniakLight.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/images/icons/qrInfomaniak/QrInfomaniakLight.kt new file mode 100644 index 000000000..0022458b2 --- /dev/null +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/images/icons/qrInfomaniak/QrInfomaniakLight.kt @@ -0,0 +1,112 @@ +/* + * Infomaniak SwissTransfer - Android + * Copyright (C) 2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.infomaniak.swisstransfer.ui.images.icons.qrInfomaniak + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.PathFillType.Companion.EvenOdd +import androidx.compose.ui.graphics.PathFillType.Companion.NonZero +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.graphics.StrokeCap.Companion.Butt +import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.ImageVector.Builder +import androidx.compose.ui.graphics.vector.path +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.infomaniak.swisstransfer.ui.images.AppImages +import com.infomaniak.swisstransfer.ui.images.AppImages.AppIcons + +val AppIcons.QrInfomaniakLight: ImageVector + get() { + + if (_qrInfomaniakLight != null) return _qrInfomaniakLight!! + + _qrInfomaniakLight = Builder( + name = "QrInfomaniakLight", + defaultWidth = 41.0.dp, + defaultHeight = 44.0.dp, + viewportWidth = 41.0f, + viewportHeight = 44.0f, + ).apply { + path( + fill = SolidColor(Color(0xFF014958)), + stroke = null, + strokeLineWidth = 0.0f, + strokeLineCap = Butt, + strokeLineJoin = Miter, + strokeLineMiter = 4.0f, + pathFillType = NonZero, + ) { + moveTo(36.9f, 0.0f) + horizontalLineTo(4.1f) + curveTo(1.835f, 0.0f, -0.0f, 1.97f, -0.0f, 4.4f) + verticalLineTo(39.6f) + curveTo(-0.0f, 42.03f, 1.835f, 44.0f, 4.1f, 44.0f) + horizontalLineTo(36.9f) + curveTo(39.164f, 44.0f, 41.0f, 42.03f, 41.0f, 39.6f) + verticalLineTo(4.4f) + curveTo(41.0f, 1.97f, 39.164f, 0.0f, 36.9f, 0.0f) + close() + } + path( + fill = SolidColor(Color(0xFFFFFFFF)), + stroke = null, + strokeLineWidth = 0.0f, + strokeLineCap = Butt, + strokeLineJoin = Miter, + strokeLineMiter = 4.0f, + pathFillType = EvenOdd, + ) { + moveTo(8.552f, 36.637f) + horizontalLineTo(17.054f) + verticalLineTo(30.677f) + lineTo(20.158f, 27.469f) + lineTo(24.575f, 36.637f) + horizontalLineTo(33.976f) + lineTo(25.685f, 21.793f) + lineTo(33.486f, 13.848f) + horizontalLineTo(23.267f) + lineTo(17.054f, 21.386f) + verticalLineTo(0.0f) + horizontalLineTo(8.552f) + verticalLineTo(36.637f) + close() + } + }.build() + + return _qrInfomaniakLight!! + } + +private var _qrInfomaniakLight: ImageVector? = null + +@Preview +@Composable +private fun Preview() { + Box { + Image( + imageVector = AppIcons.QrInfomaniakLight, + contentDescription = null, + modifier = Modifier.size(AppImages.previewSize), + ) + } +} diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorDark.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorDark.kt index 828ecdd05..3ed44cdf4 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorDark.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorDark.kt @@ -29,7 +29,6 @@ private const val dark1 = 0xFF152123 private const val dark2 = 0xFF2B383B private const val dark3 = 0xFF3C4F52 private const val shark = 0xFF9F9F9F -private const val polar_bear = 0xFFF5F5F5 private const val rabbit = 0xFFF1F1F1 private const val specific1 = 0xFF124426 @@ -87,6 +86,6 @@ val CustomDarkColorScheme = CustomColorScheme( transferTypeProximityOnContainer = Color(specific4), emailAddressChipColor = Color(green_dark), onEmailAddressChipColor = Color(green_main), - qrCodeBackground = Color(polar_bear), - qrCodeColor = Color(green_dark), + qrCodeDarkPixels = Color(rabbit), + qrCodeLightPixels = Color(dark1), ) diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorLight.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorLight.kt index 7bcefbb40..b21b57596 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorLight.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorLight.kt @@ -87,6 +87,6 @@ val CustomLightColorScheme = CustomColorScheme( transferTypeProximityOnContainer = Color(specific4), emailAddressChipColor = Color(green_contrast), onEmailAddressChipColor = Color(green_dark), - qrCodeBackground = Color(polar_bear), - qrCodeColor = Color(green_dark), + qrCodeDarkPixels = Color(green_dark), + qrCodeLightPixels = Color(white), ) diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/Theme.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/Theme.kt index 245b2d9a6..6776e893c 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/Theme.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/Theme.kt @@ -83,8 +83,8 @@ data class CustomColorScheme( val transferTypeProximityOnContainer: Color = Color.Unspecified, val emailAddressChipColor: Color = Color.Unspecified, val onEmailAddressChipColor: Color = Color.Unspecified, - val qrCodeBackground: Color = Color.Unspecified, - val qrCodeColor: Color = Color.Unspecified, + val qrCodeDarkPixels: Color = Color.Unspecified, + val qrCodeLightPixels: Color = Color.Unspecified, ) private val Shapes = Shapes( diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a94342672..dd6790877 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,7 @@ junitVersion = "1.2.1" kotlin = "2.0.20" lifecycleRuntimeKtx = "2.8.6" navigation = "2.8.1" +qrose = "1.0.1" serialization = "1.7.1" swisstransfer = "0.3.0" sentry = "4.12.0" @@ -43,6 +44,7 @@ hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", ve hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" } kotlinx-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" } navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation" } +qrose = { module = "io.github.alexzhirkevich:qrose", version.ref = "qrose" } swisstransfer-core = { module = "com.github.Infomaniak.multiplatform-SwissTransfer:STCore", version.ref = "swisstransfer" } recaptcha = { module = "com.google.android.recaptcha:recaptcha", version.ref = "recaptcha" } # Tests