Dan Ballard pushed to branch tor-browser-140.3.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
-
3b491f90
by clairehurst at 2025-10-02T14:17:31-07:00
4 changed files:
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
- + mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorHomePage.kt
- mobile/android/fenix/app/src/main/res/layout/fragment_home.xml
- mobile/android/fenix/app/src/main/res/values/colors.xml
Changes:
| ... | ... | @@ -160,6 +160,8 @@ import org.mozilla.fenix.utils.allowUndo |
| 160 | 160 | import org.mozilla.fenix.wallpapers.Wallpaper
|
| 161 | 161 | import org.mozilla.fenix.GleanMetrics.TabStrip as TabStripMetrics
|
| 162 | 162 | |
| 163 | +import org.mozilla.fenix.components.toolbar.ToolbarPosition
|
|
| 164 | +import org.mozilla.fenix.tor.TorHomePage
|
|
| 163 | 165 | import org.mozilla.fenix.tor.UrlQuickLoadViewModel
|
| 164 | 166 | |
| 165 | 167 | @Suppress("TooManyFunctions", "LargeClass")
|
| ... | ... | @@ -301,16 +303,6 @@ class HomeFragment : Fragment(), UserInteractionHandler { |
| 301 | 303 | orientation = requireContext().resources.configuration.orientation,
|
| 302 | 304 | )
|
| 303 | 305 | |
| 304 | - // Splits by full stops or commas and puts the parts in different lines.
|
|
| 305 | - // Ignoring separators at the end of the string, it is expected
|
|
| 306 | - // that there are at most two parts (e.g. "Explore. Privately.").
|
|
| 307 | - val localBinding = binding
|
|
| 308 | - binding.exploreprivately.text = localBinding
|
|
| 309 | - .exploreprivately
|
|
| 310 | - .text
|
|
| 311 | - ?.replace(" *([.,。।]) *".toRegex(), "$1\n")
|
|
| 312 | - ?.trim()
|
|
| 313 | - |
|
| 314 | 306 | components.appStore.dispatch(AppAction.ModeChange(browsingModeManager.mode))
|
| 315 | 307 | |
| 316 | 308 | lifecycleScope.launch(IO) {
|
| ... | ... | @@ -564,19 +556,8 @@ class HomeFragment : Fragment(), UserInteractionHandler { |
| 564 | 556 | listenForMicrosurveyMessage(requireContext())
|
| 565 | 557 | }
|
| 566 | 558 | |
| 567 | - if (requireContext().settings().enableComposeHomepage) {
|
|
| 568 | - initComposeHomepage()
|
|
| 569 | - } else {
|
|
| 570 | - binding.homepageView.isVisible = false
|
|
| 571 | - binding.sessionControlRecyclerView.isVisible = true
|
|
| 572 | - sessionControlView = SessionControlView(
|
|
| 573 | - containerView = binding.sessionControlRecyclerView,
|
|
| 574 | - viewLifecycleOwner = viewLifecycleOwner,
|
|
| 575 | - interactor = sessionControlInteractor,
|
|
| 576 | - fragmentManager = parentFragmentManager,
|
|
| 577 | - )
|
|
| 578 | - |
|
| 579 | - updateSessionControlView()
|
|
| 559 | + binding.torHomepageView.setContent {
|
|
| 560 | + initComposeTorHomePageView()
|
|
| 580 | 561 | }
|
| 581 | 562 | |
| 582 | 563 | disableAppBarDragging()
|
| ... | ... | @@ -990,6 +971,17 @@ class HomeFragment : Fragment(), UserInteractionHandler { |
| 990 | 971 | )
|
| 991 | 972 | }
|
| 992 | 973 | |
| 974 | + private fun initComposeTorHomePageView() {
|
|
| 975 | + binding.torHomepageView.apply {
|
|
| 976 | + setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
|
| 977 | + setContent {
|
|
| 978 | + TorHomePage(
|
|
| 979 | + toolBarAtTop = settings().toolbarPosition == ToolbarPosition.TOP
|
|
| 980 | + )
|
|
| 981 | + }
|
|
| 982 | + }
|
|
| 983 | + }
|
|
| 984 | + |
|
| 993 | 985 | private fun initComposeHomepage() {
|
| 994 | 986 | binding.sessionControlRecyclerView.isVisible = false
|
| 995 | 987 | binding.homepageView.isVisible = true
|
| 1 | +package org.mozilla.fenix.tor
|
|
| 2 | + |
|
| 3 | +import androidx.compose.foundation.Image
|
|
| 4 | +import androidx.compose.foundation.layout.Column
|
|
| 5 | +import androidx.compose.foundation.layout.Row
|
|
| 6 | +import androidx.compose.foundation.layout.Spacer
|
|
| 7 | +import androidx.compose.foundation.layout.fillMaxSize
|
|
| 8 | +import androidx.compose.foundation.layout.fillMaxWidth
|
|
| 9 | +import androidx.compose.foundation.layout.padding
|
|
| 10 | +import androidx.compose.foundation.layout.size
|
|
| 11 | +import androidx.compose.foundation.rememberScrollState
|
|
| 12 | +import androidx.compose.foundation.verticalScroll
|
|
| 13 | +import androidx.compose.material.Text
|
|
| 14 | +import androidx.compose.runtime.Composable
|
|
| 15 | +import androidx.compose.ui.Alignment
|
|
| 16 | +import androidx.compose.ui.Modifier
|
|
| 17 | +import androidx.compose.ui.draw.paint
|
|
| 18 | +import androidx.compose.ui.geometry.Offset
|
|
| 19 | +import androidx.compose.ui.graphics.Brush
|
|
| 20 | +import androidx.compose.ui.graphics.Color
|
|
| 21 | +import androidx.compose.ui.graphics.painter.BrushPainter
|
|
| 22 | +import androidx.compose.ui.res.colorResource
|
|
| 23 | +import androidx.compose.ui.res.dimensionResource
|
|
| 24 | +import androidx.compose.ui.res.painterResource
|
|
| 25 | +import androidx.compose.ui.res.stringResource
|
|
| 26 | +import androidx.compose.ui.text.TextStyle
|
|
| 27 | +import androidx.compose.ui.text.font.FontWeight
|
|
| 28 | +import androidx.compose.ui.text.style.TextAlign
|
|
| 29 | +import androidx.compose.ui.unit.dp
|
|
| 30 | +import androidx.compose.ui.unit.sp
|
|
| 31 | +import mozilla.components.compose.base.annotation.FlexibleWindowLightDarkPreview
|
|
| 32 | +import org.mozilla.fenix.R
|
|
| 33 | + |
|
| 34 | +@Composable
|
|
| 35 | +@FlexibleWindowLightDarkPreview
|
|
| 36 | +fun TorHomePage(
|
|
| 37 | + toolBarAtTop: Boolean = true,
|
|
| 38 | +) {
|
|
| 39 | + Column(
|
|
| 40 | + modifier = Modifier
|
|
| 41 | + .fillMaxSize()
|
|
| 42 | + .padding(
|
|
| 43 | + top = if (toolBarAtTop) dimensionResource(R.dimen.tab_strip_height) else 0.dp,
|
|
| 44 | + bottom = if (!toolBarAtTop) dimensionResource(R.dimen.tab_strip_height) else 0.dp,
|
|
| 45 | + )
|
|
| 46 | + .paint(
|
|
| 47 | + BrushPainter(
|
|
| 48 | + Brush.linearGradient(
|
|
| 49 | + colors = listOf(
|
|
| 50 | + colorResource(R.color.tor_homepage_gradient_start),
|
|
| 51 | + colorResource(R.color.tor_homepage_gradient_middle),
|
|
| 52 | + colorResource(R.color.tor_homepage_gradient_end),
|
|
| 53 | + ),
|
|
| 54 | + start = Offset(0f, Float.POSITIVE_INFINITY),
|
|
| 55 | + end = Offset(Float.POSITIVE_INFINITY, 0f),
|
|
| 56 | + ),
|
|
| 57 | + ),
|
|
| 58 | + )
|
|
| 59 | + .padding(
|
|
| 60 | + start = 19.dp,
|
|
| 61 | + end = 19.dp,
|
|
| 62 | + )
|
|
| 63 | + .verticalScroll(rememberScrollState()),
|
|
| 64 | + ) {
|
|
| 65 | + Spacer(modifier = Modifier.size(17.dp))
|
|
| 66 | + Row(
|
|
| 67 | + modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically,
|
|
| 68 | + ) {
|
|
| 69 | + Image(
|
|
| 70 | + painter = painterResource(R.drawable.tor_browser_app_icon),
|
|
| 71 | + contentDescription = null,
|
|
| 72 | + Modifier.size(35.dp),
|
|
| 73 | + )
|
|
| 74 | + Spacer(modifier = Modifier.size(6.dp))
|
|
| 75 | + Text(
|
|
| 76 | + text = stringResource(R.string.app_name),
|
|
| 77 | + style = TextStyle(
|
|
| 78 | + fontSize = 20.sp,
|
|
| 79 | + color = Color(0xDEFFFFFF),
|
|
| 80 | + fontWeight = FontWeight.Bold,
|
|
| 81 | + ),
|
|
| 82 | + )
|
|
| 83 | + }
|
|
| 84 | + Spacer(Modifier.weight(1f))
|
|
| 85 | + Text(
|
|
| 86 | + // Moved from the commit 5bb3cc6b93346dabd8d46677fae7f86a8f8a4fc2
|
|
| 87 | + // "[android] Modify UI/UX", and the file HomeFragment.
|
|
| 88 | + // Splits by full stops or commas and puts the parts in different lines.
|
|
| 89 | + // Ignoring separators at the end of the string, it is expected
|
|
| 90 | + // that there are at most two parts (e.g. "Explore. Privately.").
|
|
| 91 | + text = stringResource(R.string.tor_explore_privately).replace(
|
|
| 92 | + " *([.,。।]) *".toRegex(),
|
|
| 93 | + "$1\n",
|
|
| 94 | + ).trim(),
|
|
| 95 | + style = TextStyle(
|
|
| 96 | + color = Color(color = 0xDEFFFFFF),
|
|
| 97 | + fontSize = 40.sp,
|
|
| 98 | + textAlign = TextAlign.Start,
|
|
| 99 | + ),
|
|
| 100 | + modifier = Modifier.align(Alignment.CenterHorizontally),
|
|
| 101 | + )
|
|
| 102 | + Spacer(Modifier.weight(1f))
|
|
| 103 | + Image(
|
|
| 104 | + painter = painterResource(
|
|
| 105 | + id = R.drawable.ic_onion_pattern,
|
|
| 106 | + ),
|
|
| 107 | + contentDescription = null, Modifier.fillMaxWidth(),
|
|
| 108 | + )
|
|
| 109 | + }
|
|
| 110 | + Spacer(modifier = Modifier.size(17.dp))
|
|
| 111 | +} |
| ... | ... | @@ -52,90 +52,8 @@ |
| 52 | 52 | app:layout_collapseParallaxMultiplier=".167"/>
|
| 53 | 53 | <!-- This value needs to be 1.67 * the wordmark parallax value as its 24dp vs 40 -->
|
| 54 | 54 | |
| 55 | - <androidx.constraintlayout.widget.ConstraintLayout
|
|
| 56 | - android:id="@+id/wordmark"
|
|
| 57 | - android:layout_width="wrap_content"
|
|
| 58 | - android:layout_height="wrap_content"
|
|
| 59 | - android:layout_marginStart="16dp"
|
|
| 60 | - android:layout_marginTop="18dp"
|
|
| 61 | - android:layout_marginBottom="32dp"
|
|
| 62 | - android:clickable="false"
|
|
| 63 | - android:focusable="false"
|
|
| 64 | - android:orientation="horizontal"
|
|
| 65 | - app:srcCompat="@mipmap/ic_launcher_foreground"
|
|
| 66 | - app:layout_collapseMode="parallax"
|
|
| 67 | - android:contentDescription="@string/app_name"
|
|
| 68 | - app:layout_collapseParallaxMultiplier=".1">
|
|
| 69 | - |
|
| 70 | - <ImageView
|
|
| 71 | - android:id="@+id/wordmarkLogo"
|
|
| 72 | - android:layout_width="50dp"
|
|
| 73 | - android:layout_height="50dp"
|
|
| 74 | - android:adjustViewBounds="true"
|
|
| 75 | - android:contentDescription="@null"
|
|
| 76 | - app:srcCompat="@mipmap/ic_launcher_foreground"
|
|
| 77 | - tools:ignore="ImageContrastCheck"
|
|
| 78 | - app:layout_constraintBottom_toBottomOf="parent"
|
|
| 79 | - app:layout_constraintStart_toStartOf="parent"
|
|
| 80 | - app:layout_constraintTop_toTopOf="parent"
|
|
| 81 | - app:layout_constraintEnd_toStartOf="@id/app_name"
|
|
| 82 | - android:scaleX="1.5"
|
|
| 83 | - android:scaleY="1.5" />
|
|
| 84 | - |
|
| 85 | - <!--
|
|
| 86 | - tor-browser#42590
|
|
| 87 | - <ImageView
|
|
| 88 | - android:id="@+id/wordmarkText"
|
|
| 89 | - android:layout_width="wrap_content"
|
|
| 90 | - android:layout_height="@dimen/wordmark_text_height"
|
|
| 91 | - android:adjustViewBounds="true"
|
|
| 92 | - android:contentDescription="@null"
|
|
| 93 | - android:layout_marginTop="@dimen/wordmark_text_margin_top"
|
|
| 94 | - app:srcCompat="?fenixWordmarkText" />
|
|
| 95 | - -->
|
|
| 96 | - |
|
| 97 | - <TextView
|
|
| 98 | - android:id="@+id/app_name"
|
|
| 99 | - android:layout_width="wrap_content"
|
|
| 100 | - android:layout_height="wrap_content"
|
|
| 101 | - android:clickable="false"
|
|
| 102 | - android:focusable="false"
|
|
| 103 | - android:fontFamily="Roboto-Medium"
|
|
| 104 | - android:gravity="start"
|
|
| 105 | - android:importantForAccessibility="no"
|
|
| 106 | - android:maxLines="2"
|
|
| 107 | - android:paddingStart="16dp"
|
|
| 108 | - android:paddingEnd="16dp"
|
|
| 109 | - android:text="@string/app_name"
|
|
| 110 | - android:textColor="#DEFFFFFF"
|
|
| 111 | - android:textSize="20sp"
|
|
| 112 | - app:layout_constrainedWidth="true"
|
|
| 113 | - app:layout_constraintBottom_toBottomOf="parent"
|
|
| 114 | - app:layout_constraintEnd_toEndOf="parent"
|
|
| 115 | - app:layout_constraintStart_toEndOf="@id/wordmarkLogo"
|
|
| 116 | - app:layout_constraintTop_toTopOf="parent" />
|
|
| 117 | - |
|
| 118 | - </androidx.constraintlayout.widget.ConstraintLayout>
|
|
| 119 | - |
|
| 120 | 55 | </com.google.android.material.appbar.CollapsingToolbarLayout>
|
| 121 | 56 | |
| 122 | - <TextView
|
|
| 123 | - android:id="@+id/exploreprivately"
|
|
| 124 | - android:layout_width="wrap_content"
|
|
| 125 | - android:layout_height="wrap_content"
|
|
| 126 | - android:layout_gravity="center|center_vertical"
|
|
| 127 | - android:gravity="center_horizontal"
|
|
| 128 | - android:clickable="false"
|
|
| 129 | - android:ellipsize="end"
|
|
| 130 | - android:focusable="false"
|
|
| 131 | - android:importantForAccessibility="no"
|
|
| 132 | - android:text="@string/tor_explore_privately"
|
|
| 133 | - android:fontFamily="Roboto-Medium"
|
|
| 134 | - android:textColor="#DEFFFFFF"
|
|
| 135 | - android:textSize="40sp"
|
|
| 136 | - android:lineSpacingMultiplier="1.1"
|
|
| 137 | - app:layout_scrollFlags="scroll" />
|
|
| 138 | - |
|
| 139 | 57 | </com.google.android.material.appbar.AppBarLayout>
|
| 140 | 58 | |
| 141 | 59 | <androidx.compose.ui.platform.ComposeView
|
| ... | ... | @@ -145,6 +63,11 @@ |
| 145 | 63 | android:visibility="gone"
|
| 146 | 64 | app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
| 147 | 65 | |
| 66 | + <androidx.compose.ui.platform.ComposeView
|
|
| 67 | + android:id="@+id/torHomepageView"
|
|
| 68 | + android:layout_width="match_parent"
|
|
| 69 | + android:layout_height="match_parent" />
|
|
| 70 | + |
|
| 148 | 71 | <androidx.recyclerview.widget.RecyclerView
|
| 149 | 72 | android:id="@+id/sessionControlRecyclerView"
|
| 150 | 73 | android:layout_width="match_parent"
|
| ... | ... | @@ -160,17 +83,6 @@ |
| 160 | 83 | tools:itemCount="3"
|
| 161 | 84 | app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>
|
| 162 | 85 | |
| 163 | - <ImageView
|
|
| 164 | - android:id="@+id/onion_pattern_image"
|
|
| 165 | - android:layout_width="match_parent"
|
|
| 166 | - android:layout_height="wrap_content"
|
|
| 167 | - android:layout_gravity="bottom"
|
|
| 168 | - app:srcCompat="@drawable/ic_onion_pattern"
|
|
| 169 | - tools:ignore="ContentDescription"
|
|
| 170 | - app:layout_constraintBottom_toTopOf="@id/toolbarLayout"
|
|
| 171 | - app:layout_constraintEnd_toEndOf="parent"
|
|
| 172 | - app:layout_constraintStart_toStartOf="parent" />
|
|
| 173 | - |
|
| 174 | 86 | <ViewStub
|
| 175 | 87 | android:id="@+id/toolbarLayoutStub"
|
| 176 | 88 | android:layout_width="match_parent"
|
| ... | ... | @@ -382,6 +382,11 @@ |
| 382 | 382 | |
| 383 | 383 | <!-- Private Mode mask icon circle fill colors -->
|
| 384 | 384 | <color name="mozac_ui_private_mode_circle_fill" tools:ignore="UnusedResources">@color/photonPurple60</color>
|
| 385 | +
|
|
| 386 | + <!-- TorHomepage gradient colors -->
|
|
| 387 | + <color name="tor_homepage_gradient_start">#7529A7</color>
|
|
| 388 | + <color name="tor_homepage_gradient_middle">#492E85</color>
|
|
| 389 | + <color name="tor_homepage_gradient_end">#383372</color>
|
|
| 385 | 390 | |
| 386 | 391 | <!-- Connection Assist -->
|
| 387 | 392 | <color name="connect_button_purple">#9059FF</color>
|