Bug 1856957 - Translations UI Download Cycle Spinner.
parent
e8eb5de884
commit
6894cee460
@ -0,0 +1,157 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.translations
|
||||||
|
|
||||||
|
import androidx.compose.animation.core.LinearEasing
|
||||||
|
import androidx.compose.animation.core.RepeatMode
|
||||||
|
import androidx.compose.animation.core.animateFloat
|
||||||
|
import androidx.compose.animation.core.infiniteRepeatable
|
||||||
|
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.rotate
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.semantics.Role
|
||||||
|
import androidx.compose.ui.semantics.clearAndSetSemantics
|
||||||
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
|
import androidx.compose.ui.semantics.disabled
|
||||||
|
import androidx.compose.ui.semantics.role
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.compose.annotation.LightDarkPreview
|
||||||
|
import org.mozilla.fenix.compose.button.PrimaryButton
|
||||||
|
import org.mozilla.fenix.theme.FirefoxTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animation duration in milliseconds.
|
||||||
|
* If it is set to a low number, the speed of the rotation will be higher.
|
||||||
|
*/
|
||||||
|
private const val ANIMATION_DURATION_MS = 2000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icon for Download indicator.
|
||||||
|
*
|
||||||
|
* @param icon [Painter] used to be displayed.
|
||||||
|
* @param modifier [Modifier] to be applied to the icon layout.
|
||||||
|
* @param tint Tint [Color] to be applied to the icon.
|
||||||
|
* @param contentDescription Optional content description for the icon.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun DownloadIconIndicator(
|
||||||
|
icon: Painter,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
tint: Color = FirefoxTheme.colors.iconPrimary,
|
||||||
|
contentDescription: String? = null,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = icon,
|
||||||
|
modifier = modifier.then(
|
||||||
|
Modifier
|
||||||
|
.rotate(rotationAnimation()),
|
||||||
|
),
|
||||||
|
contentDescription = contentDescription,
|
||||||
|
tint = tint,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download indicator for translations screens.
|
||||||
|
* It indicates that the download of the language file is in progress.
|
||||||
|
*
|
||||||
|
* @param text The button text to be displayed.
|
||||||
|
* @param modifier [Modifier] to be applied to the layout.
|
||||||
|
* @param contentDescription Content description to be applied to the button.
|
||||||
|
* @param icon Optional [Painter] used to display an [Icon] before the button text.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun DownloadIndicator(
|
||||||
|
text: String,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
contentDescription: String? = null,
|
||||||
|
icon: Painter? = null,
|
||||||
|
) {
|
||||||
|
PrimaryButton(
|
||||||
|
text = text,
|
||||||
|
modifier = modifier.then(
|
||||||
|
Modifier
|
||||||
|
.clearAndSetSemantics {
|
||||||
|
disabled()
|
||||||
|
role = Role.Button
|
||||||
|
contentDescription?.let { this.contentDescription = contentDescription }
|
||||||
|
},
|
||||||
|
),
|
||||||
|
enabled = false,
|
||||||
|
icon = icon,
|
||||||
|
iconModifier = Modifier
|
||||||
|
.rotate(rotationAnimation()),
|
||||||
|
onClick = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun rotationAnimation(): Float {
|
||||||
|
val infiniteTransition = rememberInfiniteTransition()
|
||||||
|
val angle by infiniteTransition.animateFloat(
|
||||||
|
initialValue = 0f,
|
||||||
|
targetValue = 360f,
|
||||||
|
animationSpec = infiniteRepeatable(
|
||||||
|
animation = tween(ANIMATION_DURATION_MS, easing = LinearEasing),
|
||||||
|
repeatMode = RepeatMode.Restart,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return angle
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@LightDarkPreview
|
||||||
|
private fun DownloadIconIndicatorPreview() {
|
||||||
|
FirefoxTheme {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(FirefoxTheme.colors.layer1)
|
||||||
|
.padding(16.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
|
) {
|
||||||
|
DownloadIconIndicator(
|
||||||
|
icon = painterResource(id = R.drawable.mozac_ic_sync_24),
|
||||||
|
contentDescription = stringResource(
|
||||||
|
id = R.string.translations_bottom_sheet_translating_in_progress,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@LightDarkPreview
|
||||||
|
private fun DownloadIndicatorPreview() {
|
||||||
|
FirefoxTheme {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(FirefoxTheme.colors.layer1)
|
||||||
|
.padding(16.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
|
) {
|
||||||
|
DownloadIndicator(
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||||
|
text = stringResource(id = R.string.translations_bottom_sheet_translating_in_progress),
|
||||||
|
contentDescription = stringResource(
|
||||||
|
id = R.string.translations_bottom_sheet_translating_in_progress_content_description,
|
||||||
|
),
|
||||||
|
icon = painterResource(id = R.drawable.mozac_ic_sync_24),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue