1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 package org.mozilla.fenix.translations
7 import android.app.Dialog
8 import android.os.Bundle
9 import android.view.LayoutInflater
10 import android.view.View
11 import android.view.ViewGroup
12 import androidx.compose.foundation.layout.Column
13 import androidx.compose.runtime.getValue
14 import androidx.compose.runtime.mutableStateOf
15 import androidx.compose.runtime.remember
16 import androidx.compose.runtime.setValue
17 import androidx.compose.ui.Modifier
18 import androidx.compose.ui.layout.onGloballyPositioned
19 import androidx.compose.ui.platform.ComposeView
20 import androidx.compose.ui.platform.LocalDensity
21 import androidx.compose.ui.unit.dp
22 import androidx.navigation.fragment.findNavController
23 import androidx.navigation.fragment.navArgs
24 import com.google.android.material.bottomsheet.BottomSheetBehavior
25 import com.google.android.material.bottomsheet.BottomSheetDialogFragment
26 import org.mozilla.fenix.BrowserDirection
27 import org.mozilla.fenix.HomeActivity
28 import org.mozilla.fenix.R
29 import org.mozilla.fenix.ext.requireComponents
30 import org.mozilla.fenix.ext.settings
31 import org.mozilla.fenix.settings.SupportUtils
32 import org.mozilla.fenix.theme.FirefoxTheme
35 * The enum is to know what bottom sheet to open.
37 enum class TranslationsDialogAccessPoint {
38 Translations, TranslationsOptions,
42 * A bottom sheet fragment displaying the Firefox Translation dialog.
44 class TranslationsDialogFragment : BottomSheetDialogFragment() {
46 private var behavior: BottomSheetBehavior<View>? = null
47 private val args by navArgs<TranslationsDialogFragmentArgs>()
48 private lateinit var interactor: TranslationsInteractor
50 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
51 super.onCreateDialog(savedInstanceState).apply {
53 val bottomSheet = findViewById<View?>(R.id.design_bottom_sheet)
54 bottomSheet?.setBackgroundResource(android.R.color.transparent)
55 behavior = BottomSheetBehavior.from(bottomSheet)
56 behavior?.state = BottomSheetBehavior.STATE_EXPANDED
60 @Suppress("LongMethod")
61 override fun onCreateView(
62 inflater: LayoutInflater,
63 container: ViewGroup?,
64 savedInstanceState: Bundle?,
65 ): View = ComposeView(requireContext()).apply {
66 interactor = TranslationsInteractor(
67 translationsController = TranslationsController(
68 translationUseCase = requireComponents.useCases.sessionUseCases.translate,
69 browserStore = requireComponents.core.store,
70 tabId = args.sessionId,
76 var translationsVisibility by remember {
77 mutableStateOf(args.translationsDialogAccessPoint == TranslationsDialogAccessPoint.Translations)
80 var translationsHeightDp by remember {
84 var translationsOptionsHeightDp by remember {
88 var translationsWidthDp by remember {
92 val density = LocalDensity.current
94 TranslationDialogBottomSheet {
95 TranslationsAnimation(
96 translationsVisibility = translationsVisibility,
98 translationsOptionsHeightDp = translationsOptionsHeightDp,
100 if (translationsVisibility) {
102 modifier = Modifier.onGloballyPositioned { coordinates ->
103 translationsHeightDp = with(density) {
104 coordinates.size.height.toDp()
106 translationsWidthDp = with(density) {
107 coordinates.size.width.toDp()
111 val learnMoreUrl = SupportUtils.getSumoURLForTopic(
113 SupportUtils.SumoTopic.TRANSLATIONS,
116 learnMoreUrl = learnMoreUrl,
117 showFirstTimeTranslation = context.settings().showFirstTimeTranslation,
119 translationsVisibility = false
121 onLearnMoreClicked = {
122 (requireActivity() as HomeActivity).openToBrowserAndLoad(
123 searchTermOrURL = learnMoreUrl,
125 from = BrowserDirection.FromTranslationsDialogFragment,
128 onTranslateButtonClick = {
129 interactor.onTranslate(
130 tabId = args.sessionId,
136 onNotNowButtonClick = { dismiss() },
142 TranslationsOptionsAnimation(
143 translationsVisibility = !translationsVisibility,
145 translationsHeightDp = translationsHeightDp,
146 translationsWidthDp = translationsWidthDp,
148 if (!translationsVisibility) {
150 modifier = Modifier.onGloballyPositioned { coordinates ->
151 translationsOptionsHeightDp = with(density) {
152 coordinates.size.height.toDp()
156 TranslationsOptionsDialog(
158 translationsVisibility = true
160 onTranslationSettingsClicked = {
161 findNavController().navigate(
162 TranslationsDialogFragmentDirections
163 .actionTranslationsDialogFragmentToTranslationSettingsFragment(
164 sessionId = args.sessionId,