Bug 1861058 - Translations UI Make navigating from one bottom sheet to another more smooth.
parent
d0c7c9f92c
commit
6289aef354
@ -1,63 +0,0 @@
|
||||
/* 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 android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.browser.BrowserFragmentDirections
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
|
||||
/**
|
||||
* A bottom sheet fragment displaying the Firefox Translation Options dialog.
|
||||
*/
|
||||
class TranslationOptionsDialogFragment : BottomSheetDialogFragment() {
|
||||
|
||||
private var behavior: BottomSheetBehavior<View>? = null
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
|
||||
super.onCreateDialog(savedInstanceState).apply {
|
||||
setOnShowListener {
|
||||
val bottomSheet =
|
||||
findViewById<View?>(R.id.design_bottom_sheet)
|
||||
bottomSheet?.setBackgroundResource(android.R.color.transparent)
|
||||
behavior = BottomSheetBehavior.from(bottomSheet)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?,
|
||||
): View = ComposeView(requireContext()).apply {
|
||||
setContent {
|
||||
FirefoxTheme {
|
||||
TranslationOptionsDialogBottomSheet(
|
||||
translationOptionsList = getTranslationOptionsList(),
|
||||
onBackClicked = {
|
||||
findNavController().popBackStack()
|
||||
findNavController().navigate(
|
||||
BrowserFragmentDirections.actionBrowserFragmentToTranslationsDialogFragment(),
|
||||
)
|
||||
},
|
||||
onTranslationSettingsClicked = {
|
||||
findNavController().popBackStack()
|
||||
findNavController().navigate(
|
||||
TranslationSettingsFragmentDirections.actionGlobalToTranslationSettingsFragment(),
|
||||
)
|
||||
},
|
||||
aboutTranslationClicked = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
/* 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.AnimatedVisibility
|
||||
import androidx.compose.animation.AnimatedVisibilityScope
|
||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.expandIn
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.slideInHorizontally
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Divider
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
|
||||
private const val BOTTOM_SHEET_HANDLE_WIDTH_PERCENT = 0.1f
|
||||
|
||||
@Composable
|
||||
internal fun TranslationDialogBottomSheet(content: @Composable () -> Unit) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(
|
||||
color = FirefoxTheme.colors.layer2,
|
||||
shape = RoundedCornerShape(topStart = 8.dp, topEnd = 8.dp),
|
||||
)
|
||||
.nestedScroll(rememberNestedScrollInteropConnection()),
|
||||
) {
|
||||
Divider(
|
||||
Modifier
|
||||
.padding(top = 16.dp)
|
||||
.fillMaxWidth(BOTTOM_SHEET_HANDLE_WIDTH_PERCENT)
|
||||
.align(alignment = Alignment.CenterHorizontally),
|
||||
color = FirefoxTheme.colors.borderInverted,
|
||||
thickness = 3.dp,
|
||||
)
|
||||
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun TranslationsAnimation(
|
||||
translationsVisibility: Boolean,
|
||||
density: Density,
|
||||
translationsOptionsHeightDp: Dp,
|
||||
content: @Composable AnimatedVisibilityScope.() -> Unit,
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = translationsVisibility,
|
||||
enter = expandIn(
|
||||
animationSpec = tween(
|
||||
easing = FastOutSlowInEasing,
|
||||
),
|
||||
initialSize = {
|
||||
with(density) {
|
||||
IntSize(
|
||||
0,
|
||||
translationsOptionsHeightDp.roundToPx(),
|
||||
)
|
||||
}
|
||||
},
|
||||
) + fadeIn(
|
||||
animationSpec = tween(
|
||||
easing = FastOutSlowInEasing,
|
||||
),
|
||||
) + slideInHorizontally(
|
||||
animationSpec = tween(
|
||||
easing = FastOutSlowInEasing,
|
||||
),
|
||||
),
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun TranslationsOptionsAnimation(
|
||||
translationsVisibility: Boolean,
|
||||
density: Density,
|
||||
translationsHeightDp: Dp,
|
||||
translationsWidthDp: Dp,
|
||||
content: @Composable AnimatedVisibilityScope.() -> Unit,
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = translationsVisibility,
|
||||
enter = expandIn(
|
||||
animationSpec = tween(
|
||||
easing = FastOutSlowInEasing,
|
||||
),
|
||||
initialSize = {
|
||||
with(density) {
|
||||
IntSize(
|
||||
0,
|
||||
translationsHeightDp.roundToPx(),
|
||||
)
|
||||
}
|
||||
},
|
||||
) + fadeIn(
|
||||
animationSpec = tween(
|
||||
easing = FastOutSlowInEasing,
|
||||
),
|
||||
) + slideInHorizontally(
|
||||
initialOffsetX = { with(density) { translationsWidthDp.roundToPx() } },
|
||||
animationSpec = tween(
|
||||
easing = FastOutSlowInEasing,
|
||||
),
|
||||
),
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun TranslationsDialog(onSettingClicked: () -> Unit) {
|
||||
TranslationsDialogBottomSheet(
|
||||
onSettingClicked = onSettingClicked,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun TranslationsOptionsDialog(
|
||||
onBackClicked: () -> Unit,
|
||||
onTranslationSettingsClicked: () -> Unit,
|
||||
) {
|
||||
TranslationOptionsDialog(
|
||||
translationOptionsList = getTranslationOptionsList(),
|
||||
onBackClicked = onBackClicked,
|
||||
onTranslationSettingsClicked = onTranslationSettingsClicked,
|
||||
aboutTranslationClicked = {},
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue