Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into t2
Browse files Browse the repository at this point in the history
# Conflicts:
#	app/src/main/res/values-de/strings.xml
#	app/src/main/res/values-es/strings.xml
#	app/src/main/res/values-fr/strings.xml
#	app/src/main/res/values-it/strings.xml
#	app/src/main/res/values/strings.xml
  • Loading branch information
LunarX committed Dec 16, 2024
2 parents 0bcbc2d + 8f94b90 commit b9cff14
Show file tree
Hide file tree
Showing 55 changed files with 7,044 additions and 233 deletions.
47 changes: 47 additions & 0 deletions Core2/Compose/Core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.compose.compiler)
}

val sharedCompileSdk: Int by rootProject.extra
val sharedMinSdk: Int by rootProject.extra
val sharedJavaVersion: JavaVersion by rootProject.extra

android {
namespace = "com.infomaniak.core2.compose.core"
compileSdk = sharedCompileSdk

defaultConfig {
minSdk = sharedMinSdk

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = sharedJavaVersion
targetCompatibility = sharedJavaVersion
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.14"
}
kotlinOptions {
jvmTarget = sharedJavaVersion.toString()
}
}

dependencies {
implementation(platform(core2.compose.bom))
implementation(core2.compose.runtime)
implementation(core2.compose.ui.tooling)
}
Empty file.
21 changes: 21 additions & 0 deletions Core2/Compose/Core/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.infomaniak.core2.compose.core

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.content.pm.ActivityInfo
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.platform.LocalContext

@Composable
fun LockScreenOrientation(isLocked: Boolean) {
if (!isLocked) return

val context = LocalContext.current
LaunchedEffect(Unit) {
val activity = context.findActivity() ?: return@LaunchedEffect

@SuppressLint("SourceLockedOrientationActivity")
activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
}

private tailrec fun Context.findActivity(): Activity? = when (this) {
is Activity -> this
is ContextWrapper -> baseContext.findActivity()
else -> null
}
52 changes: 52 additions & 0 deletions Core2/Onboarding/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.compose.compiler)
}

val sharedCompileSdk: Int by rootProject.extra
val sharedMinSdk: Int by rootProject.extra
val sharedJavaVersion: JavaVersion by rootProject.extra

android {
namespace = "com.infomaniak.library.onboarding"
compileSdk = sharedCompileSdk

defaultConfig {
minSdk = sharedMinSdk

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = sharedJavaVersion
targetCompatibility = sharedJavaVersion
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.14"
}
kotlinOptions {
jvmTarget = sharedJavaVersion.toString()
}
}

dependencies {
implementation(platform(core2.compose.bom))
implementation(core2.androidx.core.ktx)
implementation(core2.compose.foundation)
implementation(core2.compose.material3)
implementation(core2.compose.runtime)
implementation(core2.compose.ui.tooling.preview)

debugImplementation(core2.compose.ui.tooling)
}
Empty file.
21 changes: 21 additions & 0 deletions Core2/Onboarding/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.infomaniak.library.onboarding

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.lerp
import kotlin.math.abs

@Composable
fun HorizontalPagerIndicator(
modifier: Modifier = Modifier,
pagerState: PagerState,
indicatorStyle: IndicatorStyle,
) {
Row(modifier, horizontalArrangement = Arrangement.Center) {
repeat(pagerState.pageCount) { index ->
val (indicatorWidth, indicatorColor: Color) = computeIndicatorProperties(index, pagerState, indicatorStyle)

Box(
modifier = Modifier
.clip(CircleShape)
.background(indicatorColor)
.size(height = indicatorStyle.inactiveSize, width = indicatorWidth)
)

if (index < pagerState.pageCount - 1) Spacer(modifier = Modifier.width(indicatorStyle.indicatorSpacing))
}
}
}

private fun computeIndicatorProperties(
index: Int,
pagerState: PagerState,
indicatorStyle: IndicatorStyle,
): Pair<Dp, Color> = with(indicatorStyle) {
val (extendedCurrentPageOffsetFraction, pageVisibilityProgress) = computePageProgresses(index, pagerState)

val indicatorWidth = lerp(inactiveSize, activeWidth, pageVisibilityProgress)

val isTransitioningToSelected = extendedCurrentPageOffsetFraction < 0
val indicatorColor: Color = when {
index == pagerState.currentPage && isTransitioningToSelected -> {
lerp(inactiveColor, activeColor, pageVisibilityProgress)
}
index == pagerState.currentPage + 1 && isTransitioningToSelected -> {
lerp(inactiveColor, activeColor, pageVisibilityProgress)
}
index <= pagerState.currentPage -> activeColor
else -> inactiveColor
}

return indicatorWidth to indicatorColor
}

private fun computePageProgresses(index: Int, pagerState: PagerState): Pair<Float, Float> {
// Extended offset fraction of the current page relative to the screen. It's as if pagerState.currentPageOffsetFraction went
// beyond -0.5 up to -1 and beyond 0.5 up to 1
//
// Range: [-1, 1]
// 0: Page is centered on the screen
// -1: Page is completely off-screen to the left
// 1: Page is completely off-screen to the right
val extendedCurrentPageOffsetFraction = when {
// Page is one step behind the current page and partially visible on the left
index == pagerState.currentPage - 1 && pagerState.currentPageOffsetFraction < 0 -> {
1 + pagerState.currentPageOffsetFraction
}
// Current page itself (centered or partially moved)
index == pagerState.currentPage -> pagerState.currentPageOffsetFraction
// Page is one step ahead of the current page and partially visible on the right
index == pagerState.currentPage + 1 && pagerState.currentPageOffsetFraction >= 0 -> {
-1 + pagerState.currentPageOffsetFraction
}
// Completely off-screen
else -> 1f
}

// Progress of the page visibility i.e. what fraction of the page is currently visible
// Range: [0, 1]
// 0: Page is completely off-screen
// 1: Page is fully centered on the screen and therefore fully visible
val pageVisibilityProgress = 1 - abs(extendedCurrentPageOffsetFraction)

return extendedCurrentPageOffsetFraction to pageVisibilityProgress
}

data class IndicatorStyle(
val inactiveColor: Color,
val activeColor: Color,
val inactiveSize: Dp,
val activeWidth: Dp,
val indicatorSpacing: Dp,
)

@Preview
@Composable
private fun Preview() {
HorizontalPagerIndicator(
pagerState = rememberPagerState(pageCount = { 3 }, initialPage = 1),
indicatorStyle = IndicatorStyle(
inactiveColor = Color.LightGray,
activeColor = Color.DarkGray,
inactiveSize = 8.dp,
activeWidth = 16.dp,
indicatorSpacing = 8.dp,
),
)
}
Loading

0 comments on commit b9cff14

Please sign in to comment.