tor-commits
Threads by month
- ----- 2025 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
October 2025
- 2 participants
- 192 discussions
[Git][tpo/applications/mullvad-browser][mullvad-browser-140.3.0esr-15.0-1] fixup! Base Browser's .mozconfigs.
by Pier Angelo Vendrame (@pierov) 07 Oct '25
by Pier Angelo Vendrame (@pierov) 07 Oct '25
07 Oct '25
Pier Angelo Vendrame pushed to branch mullvad-browser-140.3.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
e5c12fd6 by Pier Angelo Vendrame at 2025-10-07T13:03:21+02:00
fixup! Base Browser's .mozconfigs.
TB 44220: Stop minifying JS on Android.
Some modules break in the process.
- - - - -
2 changed files:
- browser/config/mozconfigs/base-browser-android
- mozconfig-android-all
Changes:
=====================================
browser/config/mozconfigs/base-browser-android
=====================================
@@ -37,6 +37,9 @@ ac_add_options --disable-backgroundtasks
# Disable telemetry
ac_add_options MOZ_TELEMETRY_REPORTING=
+# tor-browser#44220: the minifier produces broken files.
+ac_add_options --enable-minify=properties
+
if test -n "$LOCAL_DEV_BUILD"; then
# You must use the "default" bogus channel for dev builds
ac_add_options --enable-update-channel=default
=====================================
mozconfig-android-all
=====================================
@@ -12,6 +12,9 @@ ac_add_options --with-java-bin-path=$JAVA_HOME/bin
ac_add_options --with-android-sdk=$ANDROID_HOME
ac_add_options --with-gradle=$GRADLE_HOME/bin/gradle
+# tor-browser#44220: the minifier produces broken files.
+ac_add_options --enable-minify=properties
+
ac_add_options --disable-tests
ac_add_options --disable-debug
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/e5c…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/e5c…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][base-browser-140.3.0esr-15.0-1] fixup! Base Browser's .mozconfigs.
by Pier Angelo Vendrame (@pierov) 07 Oct '25
by Pier Angelo Vendrame (@pierov) 07 Oct '25
07 Oct '25
Pier Angelo Vendrame pushed to branch base-browser-140.3.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
b8be17cf by Pier Angelo Vendrame at 2025-10-07T13:02:55+02:00
fixup! Base Browser's .mozconfigs.
TB 44220: Stop minifying JS on Android.
Some modules break in the process.
- - - - -
2 changed files:
- browser/config/mozconfigs/base-browser-android
- mozconfig-android-all
Changes:
=====================================
browser/config/mozconfigs/base-browser-android
=====================================
@@ -37,6 +37,9 @@ ac_add_options --disable-backgroundtasks
# Disable telemetry
ac_add_options MOZ_TELEMETRY_REPORTING=
+# tor-browser#44220: the minifier produces broken files.
+ac_add_options --enable-minify=properties
+
if test -n "$LOCAL_DEV_BUILD"; then
# You must use the "default" bogus channel for dev builds
ac_add_options --enable-update-channel=default
=====================================
mozconfig-android-all
=====================================
@@ -12,6 +12,9 @@ ac_add_options --with-java-bin-path=$JAVA_HOME/bin
ac_add_options --with-android-sdk=$ANDROID_HOME
ac_add_options --with-gradle=$GRADLE_HOME/bin/gradle
+# tor-browser#44220: the minifier produces broken files.
+ac_add_options --enable-minify=properties
+
ac_add_options --disable-tests
ac_add_options --disable-debug
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/b8be17c…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/b8be17c…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser-build][main] Bug 41577: Minify JS with UglifyJS on Android x86.
by Pier Angelo Vendrame (@pierov) 07 Oct '25
by Pier Angelo Vendrame (@pierov) 07 Oct '25
07 Oct '25
Pier Angelo Vendrame pushed to branch main at The Tor Project / Applications / tor-browser-build
Commits:
c5141d16 by Pier Angelo Vendrame at 2025-10-06T22:20:12+02:00
Bug 41577: Minify JS with UglifyJS on Android x86.
Firefox's minifier does not work with some modules, so we disabled it.
However, we still need to minify them on Android x86 so to make our
files smaller and acceptable by the Play Store.
- - - - -
5 changed files:
- projects/browser/build.android
- projects/browser/config
- + projects/uglifyjs/README.md
- + projects/uglifyjs/build
- + projects/uglifyjs/config
Changes:
=====================================
projects/browser/build.android
=====================================
@@ -2,6 +2,12 @@
[% c("var/set_default_env") -%]
[% pc(c('var/compiler'), 'var/setup', { compiler_tarfile => c('input_files_by_name/' _ c('var/compiler')) }) %]
+[% IF c("var/android-x86") -%]
+ tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/node') %]
+ export PATH=/var/tmp/dist/node/bin:$PATH
+ tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/uglifyjs') %]
+[% END -%]
+
# Bundle our extension(s).
#
# NoScript will be copied over to the profile folder
@@ -58,6 +64,11 @@ function generate_apk {
[% IF c("var/tor-browser") -%]
cp -a ../moat_countries.json ../tor/pluggable_transports/pt_config.json chrome/toolkit/content/global/
[% END -%]
+ [% IF c("var/android-x86") -%]
+ find actors chrome modules moz-src \
+ -name '*.js' -or -name '*.mjs' \
+ -exec /var/tmp/dist/uglifyjs/bin/uglifyjs --in-situ {} \;
+ [% END -%]
[% c('zip', {
zip_src => [ '.' ],
zip_args => '-0 ../assets/omni.ja',
=====================================
projects/browser/config
=====================================
@@ -163,3 +163,9 @@ input_files:
# tor-browser-build#40920
- filename: sort-baseline.py
enable: '[% c("var/android") %]'
+ - project: node
+ name: node
+ enable: '[% c("var/android-x86") %]'
+ - project: uglifyjs
+ name: uglifyjs
+ enable: '[% c("var/android-x86") %]'
=====================================
projects/uglifyjs/README.md
=====================================
@@ -0,0 +1 @@
+This project fetches UglifyJS without any other changes.
=====================================
projects/uglifyjs/build
=====================================
@@ -0,0 +1,4 @@
+#!/bin/bash
+tar -xf [% project %]-[% c('version') %].tar.[% c('compress_tar') %]
+mv [% project %]-[% c('version') %] [% project %]
+tar -caf [% dest_dir %]/[% c("filename") %] [% project %]
=====================================
projects/uglifyjs/config
=====================================
@@ -0,0 +1,4 @@
+version: 3.19.3
+filename: 'uglifyjs-[% c("version") %]-[% c("var/build_id") %].tar.[% c("compress_tar") %]'
+git_hash: 3ea33afc72462a470466473208a33379b7204765
+git_url: https://github.com/mishoo/UglifyJS.git
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/c…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/c…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][tor-browser-140.3.0esr-15.0-1] fixup! Base Browser's .mozconfigs.
by Pier Angelo Vendrame (@pierov) 07 Oct '25
by Pier Angelo Vendrame (@pierov) 07 Oct '25
07 Oct '25
Pier Angelo Vendrame pushed to branch tor-browser-140.3.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
04579344 by Pier Angelo Vendrame at 2025-10-06T22:23:58+02:00
fixup! Base Browser's .mozconfigs.
TB 44220: Stop minifying JS on Android.
Some modules break in the process.
- - - - -
2 changed files:
- browser/config/mozconfigs/base-browser-android
- mozconfig-android-all
Changes:
=====================================
browser/config/mozconfigs/base-browser-android
=====================================
@@ -37,6 +37,9 @@ ac_add_options --disable-backgroundtasks
# Disable telemetry
ac_add_options MOZ_TELEMETRY_REPORTING=
+# tor-browser#44220: the minifier produces broken files.
+ac_add_options --enable-minify=properties
+
if test -n "$LOCAL_DEV_BUILD"; then
# You must use the "default" bogus channel for dev builds
ac_add_options --enable-update-channel=default
=====================================
mozconfig-android-all
=====================================
@@ -12,6 +12,9 @@ ac_add_options --with-java-bin-path=$JAVA_HOME/bin
ac_add_options --with-android-sdk=$ANDROID_HOME
ac_add_options --with-gradle=$GRADLE_HOME/bin/gradle
+# tor-browser#44220: the minifier produces broken files.
+ac_add_options --enable-minify=properties
+
ac_add_options --disable-tests
ac_add_options --disable-debug
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/0457934…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/0457934…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][tor-browser-128.14.0esr-14.5-1] 6 commits: Revert "TB 43505 [android]: Add 2025 UX Survey Campaign"
by Dan Ballard (@dan) 07 Oct '25
by Dan Ballard (@dan) 07 Oct '25
07 Oct '25
Dan Ballard pushed to branch tor-browser-128.14.0esr-14.5-1 at The Tor Project / Applications / Tor Browser
Commits:
c6b62627 by Dan Ballard at 2025-10-06T14:31:08-07:00
Revert "TB 43505 [android]: Add 2025 UX Survey Campaign"
This reverts commit f649c3d3cffa66434ae67d3eaf50fa94615d0163.
- - - - -
073a3d57 by clairehurst at 2025-10-06T19:55:05-06:00
fixup! [android] TBA strings
- - - - -
e024013c by clairehurst at 2025-10-06T19:55:06-06:00
TB 44031 [android]: Implement YEC 2025 Takeover for Android Stable
#44031 Implement strings
- - - - -
a60c837b by clairehurst at 2025-10-06T21:25:08-06:00
fixup! [android] Modify UI/UX
TB 43650 [android]: Homepage changes
- - - - -
4340c10b by clairehurst at 2025-10-06T21:25:09-06:00
TB 44031 [android]: 2025 YEC
- - - - -
9bc57028 by clairehurst at 2025-10-06T21:25:10-06:00
TB 44031 [android]: 2025 YEC preview
- - - - -
18 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/home/ui/SearchBar.kt
- + mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/CampaignCompose.kt
- − mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/CampaignStrings.kt
- + mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorCampaignViewModel.kt
- + mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorHomePage.kt
- + mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorHomePagePreview.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
- − mobile/android/fenix/app/src/main/res/drawable/campaign_hand.xml
- + mobile/android/fenix/app/src/main/res/drawable/globe_chain_burst_yec.xml
- + mobile/android/fenix/app/src/main/res/drawable/heart.xml
- + mobile/android/fenix/app/src/main/res/font/jacquard_12.ttf
- mobile/android/fenix/app/src/main/res/layout/fragment_home.xml
- mobile/android/fenix/app/src/main/res/values-ar/strings.xml
- mobile/android/fenix/app/src/main/res/values-de/strings.xml
- mobile/android/fenix/app/src/main/res/values/colors.xml
- mobile/android/fenix/app/src/main/res/values/preference_keys.xml
- mobile/android/fenix/app/src/main/res/values/torbrowser_strings.xml
Changes:
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
=====================================
@@ -12,65 +12,33 @@ import android.content.res.Configuration
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Bundle
-import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.widget.ImageView
import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.VisibleForTesting
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.background
-import androidx.compose.foundation.border
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.wrapContentHeight
-import androidx.compose.foundation.layout.wrapContentSize
-import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.foundation.verticalScroll
-import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
-import androidx.compose.material.Icon
-import androidx.compose.material.IconButton
import androidx.compose.material.Text
import androidx.compose.material.TextButton
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.draw.drawBehind
-import androidx.compose.ui.draw.scale
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.ViewCompositionStrategy
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.semantics.testTagsAsResourceId
-import androidx.compose.ui.text.TextLayoutResult
-import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
-import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.getColor
+import androidx.core.view.children
+import androidx.core.view.doOnLayout
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
@@ -140,7 +108,6 @@ import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.PrivateShortcutCreateManager
import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.appstate.AppAction
-import org.mozilla.fenix.components.components
import org.mozilla.fenix.components.menu.MenuAccessPoint
import org.mozilla.fenix.components.toolbar.IncompleteRedesignToolbarFeature
import org.mozilla.fenix.components.toolbar.ToolbarPosition
@@ -184,23 +151,23 @@ import org.mozilla.fenix.messaging.DefaultMessageController
import org.mozilla.fenix.messaging.FenixMessageSurfaceId
import org.mozilla.fenix.messaging.MessagingFeature
import org.mozilla.fenix.microsurvey.ui.MicrosurveyRequestPrompt
+import org.mozilla.fenix.nimbus.FxNimbus
import org.mozilla.fenix.perf.MarkersFragmentLifecycleCallbacks
import org.mozilla.fenix.search.toolbar.DefaultSearchSelectorController
import org.mozilla.fenix.search.toolbar.SearchSelectorMenu
import org.mozilla.fenix.tabstray.Page
import org.mozilla.fenix.tabstray.TabsTrayAccessPoint
import org.mozilla.fenix.theme.FirefoxTheme
-import org.mozilla.fenix.tor.CampaignStrings
+import org.mozilla.fenix.tor.TorCampaignViewModel
import org.mozilla.fenix.utils.Settings.Companion.TOP_SITES_PROVIDER_MAX_THRESHOLD
import org.mozilla.fenix.utils.allowUndo
import org.mozilla.fenix.wallpapers.Wallpaper
import java.lang.ref.WeakReference
import org.mozilla.fenix.GleanMetrics.TabStrip as TabStripMetrics
+import org.mozilla.fenix.tor.TorHomePage
import org.mozilla.fenix.tor.UrlQuickLoadViewModel
-import java.text.SimpleDateFormat
-import java.time.LocalDate
-import java.util.Date
+import java.util.Locale
@Suppress("TooManyFunctions", "LargeClass")
class HomeFragment : Fragment(), UserInteractionHandler {
@@ -214,6 +181,7 @@ class HomeFragment : Fragment(), UserInteractionHandler {
internal var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
+ private val torCampaignViewModel: TorCampaignViewModel by activityViewModels()
private val homeViewModel: HomeScreenViewModel by activityViewModels()
private val urlQuickLoadViewModel: UrlQuickLoadViewModel by activityViewModels()
@@ -336,16 +304,6 @@ class HomeFragment : Fragment(), UserInteractionHandler {
orientation = requireContext().resources.configuration.orientation,
)
- // Splits by full stops or commas and puts the parts in different lines.
- // Ignoring separators at the end of the string, it is expected
- // that there are at most two parts (e.g. "Explore. Privately.").
- val localBinding = binding
- binding.exploreprivately.text = localBinding
- .exploreprivately
- .text
- ?.replace(" *([.,。।]) *".toRegex(), "$1\n")
- ?.trim()
-
components.appStore.dispatch(AppAction.ModeChange(browsingModeManager.mode))
lifecycleScope.launch(IO) {
@@ -527,24 +485,12 @@ class HomeFragment : Fragment(), UserInteractionHandler {
initializeNavBar(activity)
}
- if (!shouldAddNavigationBar && shouldShowMicrosurveyPrompt()) {
- initializeMicrosurveyPrompt(requireContext())
- }
-
- sessionControlView = SessionControlView(
- containerView = binding.sessionControlRecyclerView,
- viewLifecycleOwner = viewLifecycleOwner,
- interactor = sessionControlInteractor,
- )
-
- updateSessionControlView()
+ initComposeTorHomePageView()
disableAppBarDragging()
activity.themeManager.applyStatusBarTheme(activity)
- tryShowUX2025Survey()
-
// FxNimbus.features.homescreen.recordExposure()
// DO NOT MOVE ANYTHING BELOW THIS addMarker CALL!
@@ -556,28 +502,6 @@ class HomeFragment : Fragment(), UserInteractionHandler {
return binding.root
}
- private fun tryShowUX2025Survey() {
- val dateFormat = SimpleDateFormat("yyyy-MM-dd-hh-zzz")
- val startDate = dateFormat.parse("2025-04-14-12-UTC")
-
- val endDate = dateFormat.parse("2025-04-28-00-UTC")
- val currentDate = Date()
-
- if (currentDate.before(startDate) || currentDate.after(endDate)) {
- return // comment out to test
- }
-
- if (BuildConfig.BUILD_TYPE == "release" && !requireContext().settings().hideCampaign) {
- binding.onionPatternImage.visibility = View.GONE
- binding.campaignBox.apply {
- setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
- setContent {
- CampaignBox()
- }
- }
- }
- }
-
private fun reinitializeNavBar() {
initializeNavBar(activity = requireActivity() as HomeActivity)
}
@@ -973,6 +897,28 @@ class HomeFragment : Fragment(), UserInteractionHandler {
)
}
+ private fun initComposeTorHomePageView() {
+ binding.torHomepageView.apply {
+ setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
+ setContent {
+ TorHomePage(
+ torCampaignViewModel.shouldInitiallyShowPromo,
+ onClicked = {
+ val baseUrl = "https://www.torproject.org/donate"
+ val locale = Locale.getDefault().getLanguage()
+ val donateUrl = "${baseUrl}/donate-${locale}-yec2025"
+ (requireActivity() as HomeActivity).openToBrowserAndLoad(
+ searchTermOrURL = donateUrl,
+ newTab = true,
+ from = BrowserDirection.FromHome,
+ )
+ },
+ toolBarAtTop = requireContext().settings().toolbarPosition == ToolbarPosition.TOP
+ )
+ }
+ }
+ }
+
private fun initTabStrip() {
binding.tabStripView.isVisible = true
binding.tabStripView.apply {
@@ -1456,217 +1402,4 @@ class HomeFragment : Fragment(), UserInteractionHandler {
override fun onBackPressed(): Boolean {
(requireActivity() as HomeActivity).shutDown()
}
-
- @Composable
- fun CampaignBox() {
- BoxWithConstraints(
- contentAlignment = Alignment.Center,
- modifier = Modifier
- .fillMaxWidth()
- .wrapContentHeight()
- ) {
- val alternateLayout = this.maxWidth >= 500.dp
-
- CampaignLayout(
- alternateLayout,
- maxWidth = this.maxWidth,
- modifier = Modifier
- .padding(top = if (alternateLayout) 65.dp else 55.dp, bottom = 56.dp),
- )
- }
- }
-
- @Composable
- private fun CampaignLayout(
- alternateLayout: Boolean,
- maxWidth: Dp,
- modifier: Modifier
- ) {
- Column(
- modifier = modifier
- .padding(horizontal = 24.dp)
- .verticalScroll(rememberScrollState())
- .fillMaxWidth(getVariableWidth(maxWidth)),
- horizontalAlignment = Alignment.CenterHorizontally,
- ) {
- PurpleBox(alternateLayout)
- }
- }
-
- private fun getVariableWidth(width: Dp): Float = (500.dp / width).coerceIn(0.75f, 1.0f)
-
- @Composable
- private fun PurpleBox(
- alternateLayout: Boolean,
- ) {
- Box(
- modifier = Modifier.background(PhotonColors.Violet90, shape = RoundedCornerShape(8.dp))
- ) {
- Column {
- Row(
- modifier = Modifier.fillMaxWidth().wrapContentHeight(),
- verticalAlignment = Alignment.Top,
- ) {
- Emoji()
- Spacer(Modifier.weight(1f))
- ExitIcon()
- }
- DynamicCampaignContent(alternateLayout)
- }
- }
- }
-
- @Composable
- private fun Emoji() {
- val alpha38Violet40 = Color(PhotonColors.Violet40.red, PhotonColors.Violet40.green, PhotonColors.Violet40.blue, 0.38f)
- Image(
- painter = painterResource(id = R.drawable.campaign_hand),
- contentDescription = null,
- modifier = Modifier
- .size(48.dp)
- .padding(top = (16+8).dp, start = (16+8).dp)
- .drawBehind {
- drawCircle(
- color = alpha38Violet40,
- radius = this.size.height
- )
- }
- )
- }
-
- @Composable
- private fun ExitIcon() {
- IconButton(
- modifier = Modifier.padding(8.dp),
- onClick = {
- binding.campaignBox.visibility = View.GONE
- binding.onionPatternImage.visibility = View.VISIBLE
- context?.components?.settings?.hideCampaign = true
- },
- ) {
- Icon(
- painter = painterResource(id = R.drawable.ic_close),
- tint = Color(
- getColor(
- requireContext(),
- R.color.photonWhite,
- ),
- ),
- contentDescription = CampaignStrings.get(CampaignStrings.CloseKey),
- modifier = Modifier
- .padding(0.dp)
- )
- }
- }
-
-
- @Composable
- private fun DynamicCampaignContent(
- alternateLayout: Boolean
- ) {
- Row(
- modifier = Modifier.padding(16.dp),
- verticalAlignment = Alignment.CenterVertically
- ) {
- Column(
- modifier = Modifier.fillMaxWidth(),
- horizontalAlignment = Alignment.Start,
- ) {
- TitleText()
- MainText()
-
- if (alternateLayout) {
- Row(modifier = Modifier.fillMaxWidth()) {
- Button1(alternateLayout)
- Button2()
- }
- } else {
- Button1(alternateLayout)
- Button2()
- }
-
- }
- }
- }
-
- @Composable
- private fun TitleText() {
-
- Text(text = CampaignStrings.get(CampaignStrings.HeaderKey),
- color = PhotonColors.LightGrey05,
- textAlign = TextAlign.Left,
- fontWeight = FontWeight.Bold,
- fontSize = 20.sp,
- lineHeight = 24.sp,
- modifier = Modifier.padding(bottom = 16.dp)
- )
- }
-
- @Composable
- private fun MainText() {
-
- Text(text = CampaignStrings.get(CampaignStrings.BodyKey),
- modifier = Modifier
- .fillMaxWidth()
- .padding(
- start = 0.dp,
- end = 0.dp,
- bottom = 18.dp,
- ),
- color = PhotonColors.LightGrey05,
- fontSize = 14.sp,
- textAlign = TextAlign.Left,
- )
- }
-
- @Composable
- private fun Button1(alternateLayout: Boolean) {
- TextButton(
- onClick = {
- var locale = CampaignStrings.getLocale()
- if (locale == "pt") {
- locale = "pt-BR"
- }
- (activity as HomeActivity).openToBrowserAndLoad(
- searchTermOrURL = "https://survey.torproject.org/index.php/923269?lang=${locale}",
- newTab = true,
- from = BrowserDirection.FromHome,
- )
- },
- colors = ButtonDefaults.buttonColors(
- backgroundColor = PhotonColors.Violet60),
- shape = RoundedCornerShape(4.dp),
- modifier = Modifier.padding(0.dp)
- .fillMaxWidth(fraction = if (alternateLayout) 0.5f else 1f),
-
- ) {
- Text(text = CampaignStrings.get(CampaignStrings.CTAKey),
- color = PhotonColors.LightGrey05,
- textAlign = TextAlign.Center,
- fontSize = 14.sp,
- modifier = Modifier.padding(8.dp))
- }
- }
-
- @Composable
- private fun Button2() {
- TextButton(
- onClick = {
- binding.campaignBox.visibility = View.GONE
- binding.onionPatternImage.visibility = View.VISIBLE
- context?.components?.settings?.hideCampaign = true
- },
- colors = ButtonDefaults.buttonColors(
- backgroundColor = PhotonColors.Violet90),
- shape = RoundedCornerShape(4.dp),
- modifier = Modifier.padding(0.dp)
- .fillMaxWidth()
- ) {
- Text(text = CampaignStrings.get(CampaignStrings.DismissKey),
- color = PhotonColors.Violet20,
- textAlign = TextAlign.Center,
- fontSize = 14.sp,
- modifier = Modifier.padding(8.dp))
- }
- }
}
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/ui/SearchBar.kt
=====================================
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/CampaignCompose.kt
=====================================
@@ -0,0 +1,278 @@
+package org.mozilla.fenix.tor
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.BoxWithConstraints
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.ClickableText
+import androidx.compose.material.Button
+import androidx.compose.material.ButtonDefaults
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.font.Font
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.withStyle
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import mozilla.components.ui.colors.PhotonColors
+import org.mozilla.fenix.R
+
+
+private val alternateLayoutThreshHold = 500.dp
+
+@Composable
+fun CampaignBox(shouldShowYec: MutableState<Boolean>, onDonateButtonClicked: () -> Unit) {
+ BoxWithConstraints(
+ contentAlignment = Alignment.Center,
+ modifier = Modifier
+ .fillMaxWidth()
+ .fillMaxHeight(),
+ ) {
+ val alternateLayout = this.maxWidth >= alternateLayoutThreshHold
+
+ CampaignLayout(
+ alternateLayout,
+ maxWidth = this.maxWidth,
+ shouldShowYec,
+ onDonateButtonClicked = onDonateButtonClicked,
+ )
+ }
+}
+
+@Composable
+private fun CampaignLayout(
+ alternateLayout: Boolean,
+ maxWidth: Dp,
+ shouldShowYec: MutableState<Boolean>,
+ onDonateButtonClicked: () -> Unit,
+) {
+ Column(
+ modifier = Modifier
+ .padding(horizontal = 22.dp)
+ .fillMaxWidth(getVariableWidth(maxWidth))
+ .wrapContentHeight(),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ PurpleBox(alternateLayout, shouldShowYec, onDonateButtonClicked = onDonateButtonClicked)
+ Spacer(Modifier.size(8.dp))
+ Text(
+ text = stringResource(R.string.no_donation_required_yec),
+ style = TextStyle(
+ fontSize = 12.5.sp,
+ lineHeight = 18.75.sp,
+ fontFamily = FontFamily.SansSerif,
+ fontWeight = FontWeight(400),
+ color = PhotonColors.LightGrey05,
+ textAlign = TextAlign.Center,
+ ),
+ )
+ }
+}
+
+private fun getVariableWidth(width: Dp): Float =
+ (alternateLayoutThreshHold / width).coerceIn(0.80f, 1.0f)
+
+@Composable
+private fun PurpleBox(
+ alternateLayout: Boolean,
+ shouldShowYec: MutableState<Boolean>,
+ onDonateButtonClicked: () -> Unit,
+) {
+ Box(
+ modifier = Modifier.background(
+ colorResource(R.color.yec_background), shape = RoundedCornerShape(8.dp),
+ ),
+ ) {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight(),
+ horizontalArrangement = Arrangement.End,
+ ) {
+ ExitIcon(shouldShowYec)
+ }
+ DynamicCampaignContent(alternateLayout, onDonateButtonClicked = onDonateButtonClicked)
+ }
+}
+
+@Composable
+private fun ExitIcon(shouldShowYec: MutableState<Boolean>) {
+ IconButton(
+ modifier = Modifier.padding(8.dp),
+ onClick = {
+ shouldShowYec.value = false
+ },
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.ic_close),
+ tint = PhotonColors.White,
+ contentDescription = stringResource(R.string.close_yec_button_description),
+ )
+ }
+}
+
+
+@Composable
+private fun DynamicCampaignContent(
+ alternateLayout: Boolean,
+ onDonateButtonClicked: () -> Unit,
+) {
+ @Composable
+ fun Icon(shouldShow: Boolean) {
+ if (shouldShow) {
+ Image(
+ painterResource(R.drawable.globe_chain_burst_yec),
+ contentDescription = null,
+ alignment = Alignment.Center,
+ )
+ }
+ }
+ Row(
+ modifier = Modifier
+ .padding(16.dp)
+ .fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Column(
+ modifier = Modifier.fillMaxWidth(if (alternateLayout) 0.75f else 1.0f),
+ horizontalAlignment = if (alternateLayout) Alignment.Start else Alignment.CenterHorizontally,
+ ) {
+ Icon(shouldShow = !alternateLayout)
+ TitleText(alternateLayout)
+ MainText(onDonateButtonClicked)
+ Row(
+ horizontalArrangement = if (alternateLayout) Arrangement.Start else Arrangement.Center,
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ DonateButton(onDonateButtonClicked = onDonateButtonClicked)
+ }
+ }
+ Icon(shouldShow = alternateLayout)
+ }
+}
+
+
+@Composable
+private fun TitleText(alternateLayout: Boolean) {
+ Text(
+ text = stringResource(R.string.free_the_internet_yec),
+ style = TextStyle(
+ fontSize = 56.sp,
+ lineHeight = 47.6.sp,
+ fontFamily = FontFamily(Font(R.font.jacquard_12)),
+ fontWeight = FontWeight(400),
+ color = PhotonColors.White,
+ textAlign = if (alternateLayout) TextAlign.Start else TextAlign.Center,
+ ),
+ )
+}
+
+@Composable
+private fun MainText(onDonateButtonClicked: () -> Unit) {
+ Column {
+ val linkStart: Int = stringResource((R.string.body1_yec)).indexOf("%s")
+ val annotatedText = buildAnnotatedString {
+ withStyle(
+ SpanStyle(
+ color = PhotonColors.LightGrey05,
+ fontSize = 14.sp,
+ ),
+ ) {
+ append(
+ stringResource(
+ R.string.body1_yec, stringResource(R.string.body1_link_yec),
+ ),
+ )
+ addStringAnnotation(
+ tag = "onClick",
+ annotation = "onClick",
+ start = linkStart,
+ end = linkStart + stringResource(R.string.body1_link_yec).length,
+ )
+ }
+ addStyle(
+ style = SpanStyle(colorResource(R.color.yec_green)),
+ linkStart,
+ linkStart + stringResource(R.string.body1_link_yec).length,
+ )
+ }
+ ClickableText(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(bottom = 8.dp),
+ text = annotatedText,
+ onClick = { offset ->
+ annotatedText.getStringAnnotations(
+ tag = "onClick",
+ start = offset,
+ end = offset,
+ )[0].let {
+ onDonateButtonClicked()
+ }
+ },
+ )
+ Text(
+ text = stringResource(R.string.body2_yec),
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(
+ bottom = 16.dp,
+ ),
+ color = PhotonColors.LightGrey05,
+ fontSize = 14.sp,
+ textAlign = TextAlign.Start,
+ )
+ }
+}
+
+@Composable
+private fun DonateButton(onDonateButtonClicked: () -> Unit) {
+ Button(
+ onClick = onDonateButtonClicked,
+ colors = ButtonDefaults.buttonColors(
+ backgroundColor = colorResource(R.color.yec_green),
+ ),
+ shape = RoundedCornerShape(4.dp),
+ contentPadding = PaddingValues(horizontal = 16.dp, vertical = 9.dp),
+ ) {
+ Text(
+ text = stringResource(R.string.donate_now_yec),
+ textAlign = TextAlign.Center,
+ fontSize = 16.sp,
+ fontWeight = FontWeight.SemiBold,
+ color = PhotonColors.DarkGrey80,
+ )
+ Spacer(
+ Modifier.size(4.dp),
+ )
+ Image(
+ painterResource(R.drawable.heart),
+ contentDescription = null,
+ )
+ }
+}
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/CampaignStrings.kt deleted
=====================================
@@ -1,67 +0,0 @@
-package org.mozilla.fenix.tor
-
-import java.util.Locale
-
-object CampaignStrings {
-
- val HeaderKey = "key_header"
- val BodyKey = "key_body"
- val CTAKey = "key_cta"
- val DismissKey = "key_dismiss"
- val CloseKey = "key_close"
-
- private val translations: HashMap<String, HashMap<String, String>> = hashMapOf(
- "en" to hashMapOf(
- HeaderKey to "We’d love your feedback",
- BodyKey to "Help us improve Tor Browser by completing this 10-minute survey.",
- CTAKey to "Launch the survey",
- DismissKey to "Dismiss",
- CloseKey to "Close",
- ),
- "es" to hashMapOf(
- HeaderKey to "Danos tu opinión",
- BodyKey to "Ayúdanos a mejorar el Navegador Tor completando esta encuesta de 10 minutos.",
- CTAKey to "Iniciar la encuesta",
- DismissKey to "Descartar",
- CloseKey to "Cerrar",
- ),
- "ru" to hashMapOf(
- HeaderKey to "Мы будем рады вашим отзывам",
- BodyKey to "Помогите нам улучшить браузер Tor, пройдя 10-минутный опрос.",
- CTAKey to "Начать опрос",
- DismissKey to "Отклонить",
- CloseKey to "Закрыть",
- ),
- "fr" to hashMapOf(
- HeaderKey to "Nous serions ravis d’avoir votre avis !",
- BodyKey to "Aidez-nous à améliorer le navigateur Tor en répondant à cette enquête de 10 minutes.",
- CTAKey to "Lancer l'enquête",
- DismissKey to "Ignorer",
- CloseKey to "Fermer",
- ),
- "pt" to hashMapOf(
- HeaderKey to "Adoraríamos ouvir sua opinião",
- BodyKey to "Ajude-nos a melhorar o Navegador Tor respondendo a esta pesquisa de 10 minutos.",
- CTAKey to "Iniciar a pesquisa",
- DismissKey to "Dispensar",
- CloseKey to "Fechar"
- ),
- )
-
- fun getLocale(): String {
- val locale = Locale.getDefault().getLanguage()
- if (translations.containsKey(locale)) {
- return locale
- }
- return "en"
- }
-
-
- fun get(key: String): String {
- val localeStrings = translations.get(getLocale())
- if (localeStrings == null) {
- return ""
- }
- return localeStrings.get(key) ?: ""
- }
-}
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorCampaignViewModel.kt
=====================================
@@ -0,0 +1,34 @@
+package org.mozilla.fenix.tor
+
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
+import androidx.lifecycle.ViewModel
+import java.text.SimpleDateFormat
+import java.util.Date
+import kotlin.getValue
+import org.mozilla.geckoview.BuildConfig
+
+class TorCampaignViewModel : ViewModel() {
+ val shouldInitiallyShowPromo: MutableState<Boolean> by lazy {
+ mutableStateOf(shouldInitiallyShowPromo())
+ }
+
+ fun shouldInitiallyShowPromo(): Boolean {
+// return true // uncomment to test
+
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd-hh-zzz")
+ val startDate =
+ dateFormat.parse("2025-10-14-15-UTC") // from https://gitlab.torproject.org/tpo/web/team/-/issues/66
+ val endDate =
+ dateFormat.parse("2026-01-02-00-UTC") // from https://gitlab.torproject.org/tpo/web/team/-/issues/66#note_3257224
+ val currentDate = Date()
+
+ if (currentDate.before(startDate) || currentDate.after(endDate)) {
+ return false
+ }
+ if (BuildConfig.BUILD_TYPE == "release") {
+ return true
+ }
+ return false
+ }
+}
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorHomePage.kt
=====================================
@@ -0,0 +1,124 @@
+package org.mozilla.fenix.tor
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.paint
+import androidx.compose.ui.draw.scale
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Brush
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.painter.BrushPainter
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import org.mozilla.fenix.R
+
+@Composable
+@Preview
+fun TorHomePage(
+ shouldInitiallyShowPromo: MutableState<Boolean> = mutableStateOf(false),
+ onClicked: () -> Unit = {},
+ toolBarAtTop: Boolean = true,
+) {
+ val shouldShowPromo = rememberSaveable {
+ shouldInitiallyShowPromo
+ }
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(
+ top = if (toolBarAtTop) 48.dp else 0.dp,
+ bottom = if (!toolBarAtTop) 48.dp else 0.dp,
+ )
+ .paint(
+ BrushPainter(
+ Brush.linearGradient(
+ colors = listOf(
+ colorResource(R.color.tor_homepage_gradient_start),
+ colorResource(R.color.tor_homepage_gradient_middle),
+ colorResource(R.color.tor_homepage_gradient_end),
+ ),
+ start = Offset(0f, Float.POSITIVE_INFINITY),
+ end = Offset(Float.POSITIVE_INFINITY, 0f),
+ ),
+ ),
+ )
+ .padding(
+ start = 19.dp,
+ end = 19.dp,
+ )
+ .verticalScroll(rememberScrollState()),
+ ) {
+ Spacer(modifier = Modifier.size(17.dp))
+ Row(
+ modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Image(
+ painter = painterResource(R.mipmap.ic_launcher_foreground),
+ contentDescription = null,
+ Modifier.size(35.dp).scale(2f),
+ )
+ Spacer(modifier = Modifier.size(6.dp))
+ Text(
+ text = stringResource(R.string.app_name),
+ style = TextStyle(
+ fontSize = 20.sp,
+ color = Color(0xDEFFFFFF),
+ fontWeight = FontWeight.Bold,
+ ),
+ )
+ }
+ Spacer(Modifier.weight(1f))
+ if (shouldShowPromo.value) {
+ CampaignBox(shouldShowPromo, onDonateButtonClicked = onClicked)
+ Spacer(Modifier.weight(1f))
+ } else {
+ Text(
+ // Moved from the commit 5bb3cc6b93346dabd8d46677fae7f86a8f8a4fc2
+ // "[android] Modify UI/UX", and the file HomeFragment.
+ // Splits by full stops or commas and puts the parts in different lines.
+ // Ignoring separators at the end of the string, it is expected
+ // that there are at most two parts (e.g. "Explore. Privately.").
+ text = stringResource(R.string.tor_explore_privately).replace(
+ " *([.,。।]) *".toRegex(),
+ "$1\n",
+ ).trim(),
+ style = TextStyle(
+ color = Color(color = 0xDEFFFFFF),
+ fontSize = 40.sp,
+ textAlign = TextAlign.Start,
+ ),
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ )
+ Spacer(Modifier.weight(1f))
+ Image(
+ painter = painterResource(
+ id = R.drawable.ic_onion_pattern,
+ ),
+ contentDescription = null, Modifier.fillMaxWidth(),
+ )
+ }
+ Spacer(modifier = Modifier.size(17.dp))
+ }
+}
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorHomePagePreview.kt
=====================================
@@ -0,0 +1,97 @@
+package org.mozilla.fenix.tor
+
+import android.annotation.SuppressLint
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.tooling.preview.PreviewParameterProvider
+import androidx.compose.ui.tooling.preview.Preview
+
+@SuppressLint("UnrememberedMutableState")
+@FlexibleWindowPreviewPortraitLandscapeEnglishArabicGerman
+@Composable
+/**
+ * Relevant documentation https://developer.android.com/develop/ui/compose/tooling/previews#preview-v…
+ */
+private fun TorHomePagePreview(
+ @PreviewParameter(BooleanBooleanPreviewParameterProvider::class) booleanMatrix: Pair<Boolean, Boolean>,
+) {
+ val toolbarAtTop = booleanMatrix.second
+ Box(
+ contentAlignment = if (toolbarAtTop) Alignment.Companion.TopStart else Alignment.Companion.BottomStart,
+ modifier = Modifier.Companion.fillMaxSize(),
+ ) {
+ TorHomePage(
+ shouldInitiallyShowPromo = mutableStateOf(booleanMatrix.first),
+ toolBarAtTop = toolbarAtTop,
+ )
+ }
+}
+
+private class BooleanBooleanPreviewParameterProvider :
+ PreviewParameterProvider<Pair<Boolean, Boolean>> {
+ override val values: Sequence<Pair<Boolean, Boolean>>
+ get() = sequenceOf(
+ Pair(true, true),
+ Pair(true, false),
+ Pair(false, true),
+ Pair(false, false),
+ )
+}
+
+/**
+ * A wrapper annotation for creating a preview that renders a preview for each value of portrait and landscape for english, arabic, and german.
+ */
+@Preview(
+ name = "mobile portrait",
+ group = "english",
+ widthDp = 360,
+ heightDp = 780,
+ locale = "en",
+ device = "id:pixel_5",
+)
+@Preview(
+ name = "mobile landscape",
+ group = "english",
+ widthDp = 780,
+ heightDp = 360,
+ locale = "en",
+ device = "spec:parent=pixel_5,orientation=landscape",
+)
+@Preview(
+ name = "mobile portrait",
+ group = "arabic",
+ widthDp = 360,
+ heightDp = 780,
+ locale = "ar",
+ device = "id:pixel_5",
+)
+@Preview(
+ name = "mobile landscape",
+ group = "arabic",
+ widthDp = 780,
+ heightDp = 360,
+ locale = "ar",
+ device = "spec:parent=pixel_5,orientation=landscape",
+)
+@Preview(
+ name = "mobile portrait",
+ group = "german",
+ widthDp = 360,
+ heightDp = 780,
+ locale = "de",
+ device = "id:pixel_5",
+)
+@Preview(
+ name = "mobile landscape",
+ group = "german",
+ widthDp = 780,
+ heightDp = 360,
+ locale = "de",
+ device = "spec:parent=pixel_5,orientation=landscape",
+)
+annotation class FlexibleWindowPreviewPortraitLandscapeEnglishArabicGerman
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
=====================================
@@ -43,7 +43,15 @@ import org.mozilla.fenix.components.settings.lazyFeatureFlagPreference
import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getPreferenceKey
+import org.mozilla.fenix.nimbus.CookieBannersSection
import org.mozilla.fenix.nimbus.FxNimbus
+import org.mozilla.fenix.nimbus.HomeScreenSection
+import org.mozilla.fenix.nimbus.Mr2022Section
+import org.mozilla.fenix.nimbus.QueryParameterStrippingSection
+import org.mozilla.fenix.nimbus.QueryParameterStrippingSection.QUERY_PARAMETER_STRIPPING
+import org.mozilla.fenix.nimbus.QueryParameterStrippingSection.QUERY_PARAMETER_STRIPPING_ALLOW_LIST
+import org.mozilla.fenix.nimbus.QueryParameterStrippingSection.QUERY_PARAMETER_STRIPPING_PMB
+import org.mozilla.fenix.nimbus.QueryParameterStrippingSection.QUERY_PARAMETER_STRIPPING_STRIP_LIST
import org.mozilla.fenix.settings.PhoneFeature
import org.mozilla.fenix.settings.deletebrowsingdata.DeleteBrowsingDataOnQuitType
import org.mozilla.fenix.settings.logins.SavedLoginsSortingStrategyMenu
@@ -2133,9 +2141,4 @@ class Settings(private val appContext: Context) : PreferencesHolder {
appContext.getPreferenceKey(R.string.pref_key_quick_start),
default = false,
)
-
- var hideCampaign by booleanPreference(
- appContext.getPreferenceKey(R.string.pref_key_hide_campaign_2025_ux_survey),
- default = false,
- )
}
=====================================
mobile/android/fenix/app/src/main/res/drawable/campaign_hand.xml deleted
=====================================
@@ -1,21 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
- android:viewportWidth="36"
- android:viewportHeight="36"
- android:width="36dp"
- android:height="36dp">
- <path
- android:pathData="M4.861 9.147c0.94 -0.657 2.357 -0.531 3.201 0.166l-0.968 -1.407c-0.779 -1.111 -0.5 -2.313 0.612 -3.093 1.112 -0.777 4.263 1.312 4.263 1.312 -0.786 -1.122 -0.639 -2.544 0.483 -3.331 1.122 -0.784 2.67 -0.513 3.456 0.611l10.42 14.72L25 31l-11.083 -4.042L4.25 12.625c-0.793 -1.129 -0.519 -2.686 0.611 -3.478z"
- android:fillColor="#EF9645" />
- <path
- android:pathData="M2.695 17.336s-1.132 -1.65 0.519 -2.781c1.649 -1.131 2.78 0.518 2.78 0.518l5.251 7.658c0.181 -0.302 0.379 -0.6 0.6 -0.894L4.557 11.21s-1.131 -1.649 0.519 -2.78c1.649 -1.131 2.78 0.518 2.78 0.518l6.855 9.997c0.255 -0.208 0.516 -0.417 0.785 -0.622L7.549 6.732s-1.131 -1.649 0.519 -2.78c1.649 -1.131 2.78 0.518 2.78 0.518l7.947 11.589c0.292 -0.179 0.581 -0.334 0.871 -0.498L12.238 4.729s-1.131 -1.649 0.518 -2.78c1.649 -1.131 2.78 0.518 2.78 0.518l7.854 11.454 1.194 1.742c-4.948 3.394 -5.419 9.779 -2.592 13.902 0.565 0.825 1.39 0.26 1.39 0.26 -3.393 -4.949 -2.357 -10.51 2.592 -13.903L24.515 8.62s-0.545 -1.924 1.378 -2.47c1.924 -0.545 2.47 1.379 2.47 1.379l1.685 5.004c0.668 1.984 1.379 3.961 2.32 5.831 2.657 5.28 1.07 11.842 -3.94 15.279 -5.465 3.747 -12.936 2.354 -16.684 -3.11L2.695 17.336z"
- android:fillColor="#FFDC5D" />
- <path
- android:pathData="M12 32.042C8 32.042 3.958 28 3.958 24c0 -0.553 -0.405 -1 -0.958 -1s-1.042 0.447 -1.042 1C1.958 30 6 34.042 12 34.042c0.553 0 1 -0.489 1 -1.042s-0.447 -0.958 -1 -0.958z"
- android:fillColor="#5DADEC" />
- <path
- android:pathData="M7 34c-3 0 -5 -2 -5 -5 0 -0.553 -0.447 -1 -1 -1s-1 0.447 -1 1c0 4 3 7 7 7 0.553 0 1 -0.447 1 -1s-0.447 -1 -1 -1zM24 2c-0.552 0 -1 0.448 -1 1s0.448 1 1 1c4 0 8 3.589 8 8 0 0.552 0.448 1 1 1s1 -0.448 1 -1c0 -5.514 -4 -10 -10 -10z"
- android:fillColor="#5DADEC" />
- <path
- android:pathData="M29 0.042c-0.552 0 -1 0.406 -1 0.958s0.448 1.042 1 1.042c3 0 4.958 2.225 4.958 4.958 0 0.552 0.489 1 1.042 1s0.958 -0.448 0.958 -1C35.958 3.163 33 0.042 29 0.042z"
- android:fillColor="#5DADEC" />
-</vector>
\ No newline at end of file
=====================================
mobile/android/fenix/app/src/main/res/drawable/globe_chain_burst_yec.xml
=====================================
@@ -0,0 +1,35 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="124dp" android:viewportHeight="124" android:viewportWidth="160" android:width="160dp">
+
+ <path android:fillColor="#B6E368" android:pathData="M79.97,86.16C65.19,89.07 56.28,80.34 53.67,75.61L34.02,84.97L55.14,84.24L42.62,106.51L63.16,91.39L61.15,117.92L73.64,93L84.86,111.85L79.98,86.16H79.97Z"/>
+
+ <path android:fillColor="#B6E368" android:pathData="M72.38,32.02C87.13,28.91 96.16,37.52 98.83,42.21L118.35,32.58L97.24,33.6L109.46,11.17L89.13,26.57L90.78,0L78.63,25.09L67.15,6.4L72.38,32.02Z"/>
+
+ <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:fillType="evenOdd" android:pathData="M82.86,42.77H84.19V44.18H82.79V42.84H80.14V44.18H81.46V45.52H82.79V48.27H84.19V51.09H82.79V48.34H81.4V45.59H80.06V44.18H78.74V42.84H77.34V53.77H84.19V51.09H85.59V53.77H89.58V55.18H92.31V56.59H89.51V55.18H85.6V67.44H89.58V66.1H92.38V67.44H93.71V68.85H92.38V70.26H91.05V71.67H89.65V73.01H88.25V74.35H86.99V75.76H85.6V74.35H86.86V72.94H88.25V71.6H89.65V70.26H90.98V68.85H92.31V67.51H89.58V68.85H85.6V71.67H84.2V74.42H82.8V75.76H85.6V77.17H81.4V74.35H82.8V71.6H84.19V68.85H77.34V77.17H81.4V78.43H71.88V77.17H67.76V75.76H66.43V74.35H65.1V73.01H63.7V71.67H62.38V70.26H63.78V71.6H65.1V72.94H66.5V74.35H67.83V75.76H70.56V74.42H69.16V71.67H67.83V68.85H63.7V67.51H60.98V68.85H59.58V67.44H58.25V55.18H59.65V67.44H60.98V66.1H63.78V67.44H67.83V55.18H63.78V56.59H60.98V55.18H59.65V52.36H60.98V49.61H62.38V48.27H63.78V46.93H65.1V45.59H66.43V44.18H69.23V45.59H66.5V47H65.17V48.34H63.77V49.68H62.37V52.43H61.04V55.18H63.7V53.77H67.83V51.09H69.22V53.77H75.94V42.84H74.68V44.18H73.28V42.84H70.62V44.18H69.22V42.77H70.55V41.43H82.86V42.77V42.77ZM69.22,71.59H70.55V74.34H71.95V77.16H75.94V68.84H69.23V71.59H69.22ZM77.34,67.44H84.19V55.17H77.34V67.44ZM69.22,67.44H75.94V55.17H69.22V67.44Z" android:strokeAlpha="0.8"/>
+
+ <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:pathData="M62.37,70.25H60.98V68.84H62.37V70.25Z" android:strokeAlpha="0.8"/>
+
+ <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:pathData="M95.1,67.44H93.7V55.17H95.1V67.44Z" android:strokeAlpha="0.8"/>
+
+ <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:pathData="M86.99,45.58H88.25V46.92H89.64V48.26H90.97V49.6H92.37V52.35H93.7V55.17H92.3V52.42H90.97V49.67H89.58V48.33H88.25V46.99H86.85V45.58H84.19V44.17H86.99V45.58V45.58Z" android:strokeAlpha="0.8"/>
+
+ <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:pathData="M73.28,45.58H71.95V48.33H70.62V51.08H69.22V48.26H70.55V45.51H71.88V44.17H73.28V45.58Z" android:strokeAlpha="0.8"/>
+
+ <path android:fillAlpha="0.8" android:fillColor="#00000000" android:pathData="M84.19,44.18V42.77H82.86V41.43H70.55V42.77H69.22V44.18M84.19,44.18H82.79V42.84H80.14V44.18H81.46V45.52H82.79V48.27H84.19V51.09M84.19,44.18V45.59H86.85V47H88.25V48.34H89.58V49.68H90.97V52.43H92.3V55.18M84.19,44.18H86.99V45.59H88.25V46.93H89.64V48.27H90.97V49.61H92.37V52.35H93.7V55.17M69.22,44.18H66.43V45.59H65.1V46.93H63.77V48.27H62.37V49.61H60.98V52.35H59.65V55.17M69.22,44.18V45.59H66.5V47H65.17V48.34H63.77V49.68H62.37V52.43H61.04V55.18H63.7V53.77H67.82V51.09H69.22M69.22,44.18H70.62V42.84H73.28V44.18M93.7,55.17H95.1V67.44H93.7M93.7,55.17V67.44M84.19,51.08H82.79V48.33H81.4V45.58H80.06V44.17H78.74V42.84H77.34V53.76H84.19V51.08H84.19ZM84.19,51.08H85.59V53.76H89.58V55.17H92.3M93.7,67.44H92.37V66.1H89.58V67.44H85.59V55.17H89.5V56.58H92.3V55.17H93.7M93.7,67.44V68.85H92.37V70.26H91.04V71.67H89.64V73.01H88.25V74.35H86.99V75.76H85.59M85.59,75.75V74.34H86.85V72.93H88.25V71.59H89.64V70.25H90.97V68.84H92.3V67.5H89.58V68.84H85.59V71.66H84.19V74.41H82.79V75.75H85.59V75.75ZM85.59,75.75V77.16H81.39M81.39,77.16V74.34H82.79V71.59H84.19V68.84H77.33V77.16H81.39H81.39ZM81.39,77.16V78.43H71.88V77.16H67.75V75.75H66.43V74.34H65.1V73H63.7V71.66H62.37V70.25M62.37,70.25H63.77V71.59H65.1V72.93H66.5V74.34H67.83V75.75H70.55V74.41H69.16V71.66H67.83V68.85H63.7V67.51H60.97V68.85M62.37,70.25H60.98V68.84H62.37V70.25ZM60.97,68.84H59.57V67.43H58.25V55.17H59.65M59.65,55.17V67.44H60.98V66.1H63.77V67.44H67.83V55.17H63.77V56.58H60.98V55.17H59.65ZM69.22,51.08V53.76H75.93V42.84H74.68V44.17H73.28M69.22,51.08H70.62V48.33H71.95V45.58H73.28V44.17H71.88V45.51H70.55V48.26H69.22V51.08ZM69.22,71.59H70.55V74.34H71.95V77.16H75.94V68.84H69.23V71.59H69.22ZM77.34,67.44H84.19V55.17H77.34V67.44ZM69.22,67.44H75.93V55.17H69.22V67.44Z" android:strokeAlpha="0.8" android:strokeColor="#C272FF" android:strokeWidth="0.23451"/>
+
+ <path android:fillColor="#ffffff" android:pathData="M53.84,42.78H56.64L54.84,40.42L58.14,39.7L55.15,36.24L57.62,36.17L57.73,35.5L41.11,29.32C40.64,29.14 40.17,29 39.7,28.88L31.58,7.75C29.81,3.15 25.32,0.06 20.41,0.06C18.94,0.06 17.49,0.33 16.11,0.87L7.65,4.16C1.5,6.55 -1.57,13.54 0.81,19.73L12.4,49.92C14.17,54.53 18.66,57.62 23.56,57.62C24.22,57.62 24.87,57.57 25.51,57.46C26.74,58.58 28.17,59.46 29.77,60.05L46.5,66.27L44.54,62.76H48.38L47.08,59.56H51.23L49.53,56.39L38.61,52.33C42.24,49.92 44.27,45.7 43.94,41.38L56.68,46.11L53.84,42.78ZM49.04,56.96L50.07,58.86H46.04L47.35,62.07H43.36L44.97,64.96L30.01,59.4C26.89,58.24 24.41,55.93 23.03,52.89C21.64,49.86 21.52,46.48 22.67,43.35L24.89,37.34C25.95,34.46 27.98,32.2 30.46,30.8L33.78,39.46C33.55,39.74 33.36,40.07 33.23,40.44L31.01,46.45C30.68,47.35 30.72,48.31 31.11,49.17C31.5,50.04 32.21,50.7 33.1,51.03L49.04,56.96ZM21.23,46.86C21.17,46.76 21.12,46.65 21.08,46.54L9.48,16.35C9.13,15.45 9.36,14.68 9.53,14.31C9.7,13.93 10.11,13.24 11.01,12.89L19.46,9.6C19.78,9.48 20.1,9.42 20.41,9.42C21.32,9.42 22.44,9.95 22.9,11.14L30.21,30.15C27.54,31.61 25.37,34.02 24.24,37.1L22.02,43.11C21.57,44.33 21.3,45.6 21.23,46.86ZM33.88,40.68C33.93,40.52 34,40.38 34.08,40.24L34.5,41.32C34.85,42.23 34.62,42.99 34.45,43.37H34.45C34.28,43.75 33.88,44.43 32.98,44.78L32.26,45.06L33.88,40.68ZM37.79,52.02L33.34,50.37C32.62,50.11 32.06,49.58 31.74,48.88C31.42,48.19 31.39,47.41 31.66,46.7L31.94,45.93L33.23,45.43C34.36,45 34.87,44.13 35.08,43.65C35.29,43.17 35.58,42.21 35.14,41.07L34.58,39.61V39.59L34.35,39.01L34.32,38.91L31.07,30.48L31.06,30.46L30.85,29.91L30.82,29.82L23.55,10.88C22.97,9.39 21.56,8.72 20.41,8.72C20.01,8.72 19.61,8.8 19.21,8.95L10.76,12.24C9.63,12.68 9.11,13.55 8.9,14.02C8.69,14.5 8.4,15.47 8.84,16.61L20.43,46.8C20.61,47.27 20.88,47.67 21.2,47.97C21.24,49.75 21.64,51.52 22.4,53.18C23.03,54.56 23.87,55.79 24.88,56.85C24.44,56.9 24,56.93 23.56,56.93C18.94,56.93 14.71,54.01 13.04,49.67L1.45,19.48C-0.79,13.65 2.1,7.07 7.9,4.81L16.35,1.52C17.66,1.01 19.03,0.75 20.41,0.75C25.04,0.75 29.26,3.67 30.93,8.01L38.88,28.7L38.91,28.78L39.16,29.43L39.18,29.47L42.53,38.2C42.8,38.9 42.99,39.61 43.11,40.33C43.12,40.35 43.13,40.37 43.13,40.4C43.17,40.61 43.2,40.83 43.22,41.05C43.22,41.07 43.22,41.09 43.22,41.11C43.68,45.46 41.58,49.76 37.79,52.02ZM43.86,40.6C43.74,39.71 43.51,38.81 43.18,37.94L40.01,29.69C40.29,29.77 40.58,29.86 40.87,29.97L55.81,35.53L53.67,35.59L56.85,39.27L53.63,39.97L55.24,42.09H52.33L54.41,44.53L43.86,40.6Z"/>
+
+ <path android:fillColor="#ffffff" android:pathData="M157.76,99.65L136.71,69.02C134.41,65.69 130.67,63.66 126.65,63.57C125.48,62.52 124.09,61.66 122.51,61.08L107.43,55.47L107.36,55.44L103.68,55.55L106.41,58.69L102.99,59.44L105.06,62.15H102.4L104.54,64.66L115.19,68.62L112.76,70.31C109.62,72.5 107.78,75.86 107.41,79.41L97.62,75.77L99.32,78.92H94.98L96.29,82.12H92.65L94.1,84.72L111.42,91.16C111.59,91.22 111.75,91.28 111.92,91.33L130.63,118.54C132.98,121.96 136.85,124 140.98,124C143.54,124 146.01,123.22 148.12,121.75L154.58,117.26C157.34,115.33 159.19,112.44 159.79,109.12C160.4,105.79 159.68,102.43 157.76,99.65ZM104.95,64.06L103.91,62.85H106.46L104.21,59.89L107.7,59.13L105.17,56.2L107.25,56.14L122.27,61.73C123.5,62.19 124.62,62.82 125.59,63.59C123.31,63.73 121.12,64.49 119.22,65.82L115.89,68.13L104.95,64.06ZM111.65,90.5L111.25,90.35L94.58,84.15L93.84,82.82H97.32L96.01,79.61H100.48L99.1,77.06L107.36,80.13L108.04,80.38L114.5,82.79C115.37,83.11 116.28,83.1 117.1,82.82C117.32,82.75 117.54,82.65 117.74,82.53C118.53,82.1 119.17,81.39 119.5,80.48L120.95,76.56L124.77,73.9C125.25,73.57 125.79,73.39 126.36,73.39C126.8,73.39 127.92,73.51 128.68,74.61L129.76,76.19C129.69,76.47 129.61,76.75 129.51,77.02L127.19,83.33L127.08,83.63C126.11,86.07 124.45,88.03 122.42,89.34C122.23,89.47 122.03,89.59 121.83,89.7C119.04,91.29 115.64,91.75 112.36,90.74C112.13,90.67 111.89,90.59 111.65,90.5ZM117.15,80.21C117.22,79.78 117.48,78.97 118.31,78.39L119.95,77.26L118.85,80.24C118.57,81 118.04,81.58 117.38,81.94C117.04,81.24 117.08,80.57 117.15,80.21ZM130.06,77.56L130.17,77.25C130.2,77.14 130.24,77.04 130.27,76.93L149.73,105.24C150.31,106.08 150.27,106.93 150.19,107.36C150.11,107.79 149.85,108.6 149.02,109.18L142.57,113.67C142.09,114.01 141.55,114.17 140.98,114.17C140.53,114.17 139.41,114.06 138.66,112.95L122.82,89.91C124.96,88.52 126.7,86.46 127.72,83.89L130.06,77.56ZM159.11,108.99C158.54,112.14 156.79,114.87 154.18,116.68L147.73,121.18C145.73,122.57 143.4,123.3 140.98,123.3C137.07,123.3 133.42,121.38 131.2,118.15L112.97,91.63C113.95,91.86 114.94,91.97 115.91,91.97C118.15,91.97 120.32,91.38 122.23,90.28L138.09,113.35C139.03,114.72 140.42,114.87 140.98,114.87C141.7,114.87 142.36,114.66 142.96,114.25L149.42,109.75C150.45,109.03 150.77,108.02 150.87,107.48C150.96,106.95 151.02,105.89 150.3,104.85L130.51,76.06L129.97,75.26L129.25,74.22C128.3,72.84 126.91,72.7 126.36,72.7H126.36C125.64,72.7 124.97,72.91 124.38,73.32L121.37,75.42L120.37,76.11L117.92,77.82C116.88,78.54 116.56,79.55 116.46,80.08C116.39,80.53 116.33,81.34 116.74,82.2C116.1,82.39 115.41,82.38 114.74,82.13L108.08,79.66C108.39,76.25 110.14,72.99 113.15,70.89L115.99,68.91L116.68,68.43L119.61,66.39C121.6,65 123.94,64.27 126.36,64.27H126.37C126.72,64.27 127.07,64.28 127.41,64.31C130.91,64.62 134.12,66.48 136.13,69.42L157.19,100.05C159,102.68 159.68,105.85 159.11,108.99Z"/>
+
+ <path android:fillColor="#C272FF" android:pathData="M26.73,77.81L30.91,77.83L30.91,79.04L26.73,79.03V84.32H25.51V79.03L21.2,79.02L21.2,77.8L25.51,77.81V72.54H26.73V77.81Z"/>
+
+ <path android:fillColor="#C272FF" android:pathData="M132.82,37.87L137,37.88L137,39.08L132.82,39.07V44.31H131.6V39.07L127.29,39.06L127.29,37.85L131.6,37.86V32.65H132.82V37.87Z"/>
+
+ <path android:fillColor="#C272FF" android:pathData="M20.17,99.2C20.17,98.79 19.84,98.46 19.43,98.46C19.02,98.46 18.69,98.79 18.69,99.2C18.69,99.62 19.02,99.95 19.43,99.95V101.17C18.36,101.17 17.49,100.29 17.49,99.2C17.49,98.12 18.36,97.24 19.43,97.24C20.51,97.24 21.38,98.12 21.38,99.2C21.38,100.29 20.51,101.17 19.43,101.17V99.95C19.84,99.95 20.17,99.62 20.17,99.2Z"/>
+
+ <path android:fillColor="#C272FF" android:pathData="M116.28,43.22C117.35,43.22 118.22,44.1 118.22,45.18C118.22,46.27 117.35,47.15 116.28,47.15C115.2,47.15 114.33,46.27 114.33,45.18C114.33,44.1 115.2,43.22 116.28,43.22Z"/>
+
+ <path android:fillColor="#C272FF" android:pathData="M134.74,51.08C135.81,51.08 136.68,51.96 136.68,53.04C136.68,54.12 135.81,55 134.74,55C133.66,55 132.79,54.12 132.79,53.04C132.79,51.96 133.66,51.08 134.74,51.08Z"/>
+
+ <path android:fillColor="#C272FF" android:pathData="M32.81,91.67C32.81,91.26 32.47,90.93 32.06,90.93C31.66,90.93 31.32,91.26 31.32,91.67C31.32,92.09 31.66,92.42 32.06,92.42V93.64C30.99,93.64 30.12,92.76 30.12,91.67C30.12,90.59 30.99,89.71 32.06,89.71C33.14,89.71 34.01,90.59 34.01,91.67C34.01,92.76 33.14,93.64 32.06,93.64V92.42C32.47,92.42 32.81,92.09 32.81,91.67Z"/>
+
+</vector>
=====================================
mobile/android/fenix/app/src/main/res/drawable/heart.xml
=====================================
@@ -0,0 +1,7 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="16dp" android:viewportHeight="16" android:viewportWidth="16" android:width="16dp">
+
+ <path android:fillColor="#15141A" android:pathData="M8,6C8,6 8,2 11.5,2C15,2 15,5 15,6C15,10.5 8,15 8,15V6Z"/>
+
+ <path android:fillColor="#15141A" android:pathData="M8,6C8,6 8,2 4.5,2C1,2 1,5 1,6C1,10.5 8,15 8,15L9,9L8,6Z"/>
+
+</vector>
=====================================
mobile/android/fenix/app/src/main/res/font/jacquard_12.ttf
=====================================
Binary files /dev/null and b/mobile/android/fenix/app/src/main/res/font/jacquard_12.ttf differ
=====================================
mobile/android/fenix/app/src/main/res/layout/fragment_home.xml
=====================================
@@ -47,98 +47,14 @@
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier=".167"/>
<!-- This value needs to be 1.67 * the wordmark parallax value as its 24dp vs 40 -->
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/wordmark"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginTop="18dp"
- android:layout_marginBottom="32dp"
- android:clickable="false"
- android:focusable="false"
- android:importantForAccessibility="no"
- android:orientation="horizontal"
- app:srcCompat="@mipmap/ic_launcher_foreground"
- app:layout_collapseMode="parallax"
- app:layout_collapseParallaxMultiplier=".1">
-
- <ImageView
- android:id="@+id/wordmarkLogo"
- android:layout_width="50dp"
- android:layout_height="50dp"
- android:adjustViewBounds="true"
- android:contentDescription="@null"
- app:srcCompat="@mipmap/ic_launcher_foreground"
- tools:ignore="ImageContrastCheck"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintEnd_toStartOf="@id/app_name"
- android:scaleX="1.5"
- android:scaleY="1.5" />
-
- <!--
- tor-browser#42590
- <ImageView
- android:id="@+id/wordmarkText"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/wordmark_text_height"
- android:adjustViewBounds="true"
- android:contentDescription="@null"
- android:layout_marginTop="@dimen/wordmark_text_margin_top"
- app:srcCompat="?fenixWordmarkText" />
- -->
-
- <TextView
- android:id="@+id/app_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:clickable="false"
- android:focusable="false"
- android:fontFamily="Roboto-Medium"
- android:gravity="start"
- android:importantForAccessibility="no"
- android:maxLines="2"
- android:paddingStart="16dp"
- android:paddingEnd="16dp"
- android:text="@string/app_name"
- android:textColor="#DEFFFFFF"
- android:textSize="20sp"
- app:layout_constrainedWidth="true"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toEndOf="@id/wordmarkLogo"
- app:layout_constraintTop_toTopOf="parent" />
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
</com.google.android.material.appbar.CollapsingToolbarLayout>
- <TextView
- android:id="@+id/exploreprivately"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center|center_vertical"
- android:gravity="center_horizontal"
- android:clickable="false"
- android:ellipsize="end"
- android:focusable="false"
- android:importantForAccessibility="no"
- android:text="@string/tor_explore_privately"
- android:fontFamily="Roboto-Medium"
- android:textColor="#DEFFFFFF"
- android:textSize="40sp"
- android:lineSpacingMultiplier="1.1"
- app:layout_scrollFlags="scroll" />
-
</com.google.android.material.appbar.AppBarLayout>
<androidx.compose.ui.platform.ComposeView
- android:id="@+id/campaignBox"
+ android:id="@+id/torHomepageView"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"/>
+ android:layout_height="match_parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/sessionControlRecyclerView"
@@ -155,17 +71,6 @@
tools:itemCount="3"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>
- <ImageView
- android:id="@+id/onion_pattern_image"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- app:srcCompat="@drawable/ic_onion_pattern"
- tools:ignore="ContentDescription"
- app:layout_constraintBottom_toTopOf="@id/toolbarLayout"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent" />
-
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/toolbarLayout"
android:elevation="5dp"
=====================================
mobile/android/fenix/app/src/main/res/values-ar/strings.xml
=====================================
@@ -1506,5 +1506,11 @@
<!-- Translations feature-->
-
- </resources>
+ <!-- Not meant for production. Uncomment for the compose preview in [TorHomePage] -->
+ <!-- <string name="donate_now_yec">تبرع الآن</string>-->
+ <!-- <string name="free_the_internet_yec">حرروا الإنترنت</string>-->
+ <!-- <string name="body1_yec">دعم الأدوات التي تكسر قيود الرقابة والمراقبة. %s</string>-->
+ <!-- <string name="body1_link_yec">تبرع لمشروع Tor اليوم.</string>-->
+ <!-- <string name="body2_yec">حتى 31 ديسمبر، سيتم مضاعفة تبرعك، بحد أقصى 250,000 دولار!</string>-->
+ <!-- <string name="no_donation_required_yec">سيكون متصفح Tor لنظام Android مجانيا دائما للاستخدام - لا يلزم التبرع لاستخدام هذا التطبيق.</string>-->
+</resources>
=====================================
mobile/android/fenix/app/src/main/res/values-de/strings.xml
=====================================
@@ -73,8 +73,8 @@
The first parameter is the name of the app defined in app_name (for example: Fenix) -->
<string name="private_browsing_placeholder_description_2">%1$s leert die eingegebenen Suchbegriffe und besuchten Webseiten aller privaten Tabs wenn Sie diese schließen oder die App beenden. Das macht Sie gegenüber Website-Betreibern und Internetanbietern nicht anonym, aber erleichtert es Ihnen, dass andere Nutzer dieses Geräts Ihre Aktivitäten nicht einsehen können.</string>
<string name="private_browsing_common_myths">
-
-
+
+
Häufige Missverständnisse über das Surfen im Privaten Modus</string>
<!-- True Private Browsing Mode -->
@@ -1413,7 +1413,7 @@
<string name="toast_copy_link_to_clipboard">In Zwischenablage kopiert</string>
<!-- An option from the share dialog to sign into sync -->
<string name="sync_sign_in">Bei Sync anmelden</string>
- <!-- An option from the three dot menu to sync and save data -->
+ <!-- An option from the three dot menu to sync and save data -->
<string name="sync_menu_sync_and_save_data">Daten synchronisieren und speichern</string>
<!-- An option from the share dialog to send link to all other sync devices -->
<string name="sync_send_to_all">An alle Geräte senden</string>
@@ -1800,10 +1800,10 @@
<string name="browser_toolbar_long_press_popup_paste_and_go">Einfügen & Los</string>
<!-- Paste the text in the clipboard -->
<string name="browser_toolbar_long_press_popup_paste">Einfügen</string>
-
+
<!-- Snackbar message shown after an URL has been copied to clipboard. -->
<string name="browser_toolbar_url_copied_to_clipboard_snackbar">URL in Zwischenablage kopiert</string>
-
+
<!-- Title text for the Add To Homescreen dialog -->
<string name="add_to_homescreen_title">Zum Startbildschirm hinzufügen</string>
<!-- Cancel button text for the Add to Homescreen dialog -->
@@ -2784,4 +2784,13 @@
<string name="exit_fullscreen_with_gesture">Um den Vollbildmodus zu beenden, ziehen Sie von oben und verwenden Sie die Zurück-Geste</string>
<!-- Message shown to explain how to exit fullscreen mode when using back button navigation -->
<string name="exit_fullscreen_with_back_button">Um den Vollbildmodus zu beenden, ziehen Sie von oben und drücken Sie auf „Zurück“</string>
+
+ <!-- Not meant for production. Uncomment for the compose preview in [TorHomePage] -->
+ <!-- <string name="donate_now_yec">Jetzt spenden</string>-->
+ <!-- <string name="free_the_internet_yec">Befreit das Internet</string>-->
+ <!-- <string name="body1_yec">Unterstützen Sie Tools, die die Ketten der Zensur und Überwachung sprengen. %s</string>-->
+ <!-- <string name="body1_link_yec">Spenden Sie noch heute für das Tor-Projekt.</string>-->
+ <!-- <string name="body2_yec">Bis zum 31. Dezember wird Ihre Spende bis zu einer Höhe von 250.000 Dollar verdoppelt!</string>-->
+ <!-- <string name="no_donation_required_yec">Der Tor-Browser für Android wird immer kostenlos sein – es ist keine Spende erforderlich, um diese App zu nutzen.</string>-->
+
</resources>
=====================================
mobile/android/fenix/app/src/main/res/values/colors.xml
=====================================
@@ -377,6 +377,11 @@
<!-- Private Mode mask icon circle fill colors -->
<color name="mozac_ui_private_mode_circle_fill" tools:ignore="UnusedResources">@color/photonPurple60</color>
+
+ <!-- TorHomepage gradient colors -->
+ <color name="tor_homepage_gradient_start">#7529A7</color>
+ <color name="tor_homepage_gradient_middle">#492E85</color>
+ <color name="tor_homepage_gradient_end">#383372</color>
<!-- Connection Assist -->
<color name="connect_button_purple">#9059FF</color>
@@ -385,4 +390,10 @@
<color name="configure_connection_button_white">#E1E0E7</color>
<color name="warning_yellow">#FFA436</color>
<color name="progress_background_tint">#55148C</color>
+
+ <!-- 2025 YEC -->
+ <color name="yec_green">#B6E368</color>
+ <color name="yec_purple">#C272FF</color>
+ <color name="yec_black">#15141A</color>
+ <color name="yec_background">#1D1133</color>
</resources>
=====================================
mobile/android/fenix/app/src/main/res/values/preference_keys.xml
=====================================
@@ -433,5 +433,4 @@
<string name="pref_key_tor_network_settings_bridges_enabled">pref_key_tor_network_settings_bridges_enabled</string>
<string name="pref_key_spoof_english" translatable="false">pref_key_spoof_english</string>
- <string name="pref_key_hide_campaign_2025_ux_survey" translatable="false">pref_key_hide_campaign_2025_ux_survey_test</string>
</resources>
=====================================
mobile/android/fenix/app/src/main/res/values/torbrowser_strings.xml
=====================================
@@ -134,4 +134,20 @@
<!-- Connection assist. Content Description for back button. Button will start the connection assist process again -->
<string name="connection_assist_back_button_content_description_start_again">Start again</string>
+ <!-- Year End Campaign. Text on the "Donate Now" button that takes the user to the donation page. A small black heart image will be added to the "end" of the text but within the button. Here end" means to the right of the test for LTR and to the left of the text for RTL, android handles this. -->
+ <string name="donate_now_yec">Donate Now</string>
+ <!-- Year End Campaign. White text to be shown below the purple rectangle that the rest of the content is in. -->
+ <string name="no_donation_required_yec">Tor Browser for Android will always be free to use—no donation is required to use this app.</string>
+ <!-- Year End Campaign. Here "Close" is a verb, referring to closing the banner. This is used primarily for screen readers to give the small "x" button a name. -->
+ <string name="close_yec_button_description">Close</string>
+
+ <!-- 2025 Year End Campaign. Title text that will show up bigger and in a different font -->
+ <string name="free_the_internet_yec">Free the internet</string>
+ <!-- 2025 Year End Campaign. %s will be replaced with the value for body1_link_yec -->
+ <string name="body1_yec">Support tools that break the chains of censorship and surveillance. %s</string>
+ <!-- 2025 Year End Campaign. The part to replace %s in body1_yec -->
+ <string name="body1_link_yec">Donate to the Tor Project today.</string>
+ <!-- 2025 Year End Campaign. The end date should match the end of the year 2025. The "$250,000" should be localised: it should be shown as USD (United States dollar) currency, but you may use numbers and formatting appropriate to your locale. -->
+ <string name="body2_yec">Through December 31, your gift will be matched, up to $250,000!</string>
+
</resources>
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/38f371…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/38f371…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][tor-browser-140.3.0esr-15.0-1] 2 commits: TB 44031 [android]: 2025 YEC
by Dan Ballard (@dan) 06 Oct '25
by Dan Ballard (@dan) 06 Oct '25
06 Oct '25
Dan Ballard pushed to branch tor-browser-140.3.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
d29ad567 by clairehurst at 2025-10-06T10:11:42-07:00
TB 44031 [android]: 2025 YEC
# Conflicts:
# mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorHomePage.kt
- - - - -
6a4f6241 by clairehurst at 2025-10-06T10:11:42-07:00
TB 44031 [android]: 2025 YEC preview
- - - - -
12 changed files:
- + mobile/android/android-components/components/compose/base/src/main/java/mozilla/components/compose/base/annotation/FlexibleWindowPreviewPortraitLandscapeEnglishArabicGerman.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/ui/SearchBar.kt
- + mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/CampaignCompose.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorHomePage.kt
- + mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorHomePagePreview.kt
- + mobile/android/fenix/app/src/main/res/drawable/globe_chain_burst_yec.xml
- + mobile/android/fenix/app/src/main/res/drawable/heart.xml
- + mobile/android/fenix/app/src/main/res/font/jacquard_12.ttf
- mobile/android/fenix/app/src/main/res/values-ar/strings.xml
- mobile/android/fenix/app/src/main/res/values-de/strings.xml
- mobile/android/fenix/app/src/main/res/values/colors.xml
Changes:
=====================================
mobile/android/android-components/components/compose/base/src/main/java/mozilla/components/compose/base/annotation/FlexibleWindowPreviewPortraitLandscapeEnglishArabicGerman.kt
=====================================
@@ -0,0 +1,60 @@
+/* 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 mozilla.components.compose.base.annotation
+
+import androidx.compose.ui.tooling.preview.Preview
+
+/**
+ * A wrapper annotation for creating a preview that renders a preview for each value of portrait and landscape for english, arabic, and german.
+ */
+@Preview(
+ name = "mobile portrait",
+ group = "english",
+ widthDp = 360,
+ heightDp = 780,
+ locale = "en",
+ device = "id:pixel_5",
+)
+@Preview(
+ name = "mobile landscape",
+ group = "english",
+ widthDp = 780,
+ heightDp = 360,
+ locale = "en",
+ device = "spec:parent=pixel_5,orientation=landscape",
+)
+@Preview(
+ name = "mobile portrait",
+ group = "arabic",
+ widthDp = 360,
+ heightDp = 780,
+ locale = "ar",
+ device = "id:pixel_5",
+)
+@Preview(
+ name = "mobile landscape",
+ group = "arabic",
+ widthDp = 780,
+ heightDp = 360,
+ locale = "ar",
+ device = "spec:parent=pixel_5,orientation=landscape",
+)
+@Preview(
+ name = "mobile portrait",
+ group = "german",
+ widthDp = 360,
+ heightDp = 780,
+ locale = "de",
+ device = "id:pixel_5",
+)
+@Preview(
+ name = "mobile landscape",
+ group = "german",
+ widthDp = 780,
+ heightDp = 360,
+ locale = "de",
+ device = "spec:parent=pixel_5,orientation=landscape",
+)
+annotation class FlexibleWindowPreviewPortraitLandscapeEnglishArabicGerman
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
=====================================
@@ -163,6 +163,8 @@ import org.mozilla.fenix.GleanMetrics.TabStrip as TabStripMetrics
import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.tor.TorHomePage
import org.mozilla.fenix.tor.UrlQuickLoadViewModel
+import org.mozilla.fenix.tor.shouldInitiallyShowPromo
+import java.util.Locale
@Suppress("TooManyFunctions", "LargeClass")
class HomeFragment : Fragment(), UserInteractionHandler {
@@ -976,6 +978,17 @@ class HomeFragment : Fragment(), UserInteractionHandler {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
TorHomePage(
+ shouldInitiallyShowPromo(),
+ onClicked = {
+ val baseUrl = "https://www.torproject.org/donate"
+ val locale = Locale.getDefault().getLanguage()
+ val donateUrl = "${baseUrl}/donate-${locale}-yec2025"
+ (requireActivity() as HomeActivity).openToBrowserAndLoad(
+ searchTermOrURL = donateUrl,
+ newTab = true,
+ from = BrowserDirection.FromHome,
+ )
+ },
toolBarAtTop = settings().toolbarPosition == ToolbarPosition.TOP
)
}
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/ui/SearchBar.kt
=====================================
@@ -13,6 +13,7 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark
import mozilla.components.compose.browser.toolbar.HomepageDisplayToolbar
import org.mozilla.fenix.R
import org.mozilla.fenix.theme.FirefoxTheme
+import org.mozilla.fenix.theme.Theme
/**
* Search bar.
@@ -34,8 +35,8 @@ internal fun SearchBar(
@Composable
@PreviewLightDark
-private fun SearchBarPreview() {
- FirefoxTheme {
+fun SearchBarPreview() {
+ FirefoxTheme (theme = Theme.Private) {
Column(
modifier = Modifier.background(color = FirefoxTheme.colors.layer1),
) {
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/CampaignCompose.kt
=====================================
@@ -0,0 +1,293 @@
+package org.mozilla.fenix.tor
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.BoxWithConstraints
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.BasicText
+import androidx.compose.material.Button
+import androidx.compose.material.ButtonDefaults
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.LinkAnnotation
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.TextLinkStyles
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.font.Font
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.withStyle
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import mozilla.components.ui.colors.PhotonColors
+import org.mozilla.fenix.BuildConfig
+import org.mozilla.fenix.R
+import java.text.SimpleDateFormat
+import java.util.Date
+
+
+private val alternateLayoutThreshHold = 500.dp
+
+@Composable
+fun CampaignBox(shouldShowYec: MutableState<Boolean>, onDonateButtonClicked: () -> Unit) {
+ BoxWithConstraints(
+ contentAlignment = Alignment.Center,
+ modifier = Modifier
+ .fillMaxWidth()
+ .fillMaxHeight(),
+ ) {
+ val alternateLayout = this.maxWidth >= alternateLayoutThreshHold
+
+ CampaignLayout(
+ alternateLayout,
+ maxWidth = this.maxWidth,
+ shouldShowYec,
+ onDonateButtonClicked = onDonateButtonClicked,
+ )
+ }
+}
+
+@Composable
+private fun CampaignLayout(
+ alternateLayout: Boolean,
+ maxWidth: Dp,
+ shouldShowYec: MutableState<Boolean>,
+ onDonateButtonClicked: () -> Unit,
+) {
+ Column(
+ modifier = Modifier
+ .padding(horizontal = 22.dp)
+ .fillMaxWidth(getVariableWidth(maxWidth))
+ .wrapContentHeight(),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ PurpleBox(alternateLayout, shouldShowYec, onDonateButtonClicked = onDonateButtonClicked)
+ Spacer(Modifier.size(8.dp))
+ Text(
+ text = stringResource(R.string.no_donation_required_yec),
+ style = TextStyle(
+ fontSize = 12.5.sp,
+ lineHeight = 18.75.sp,
+ fontFamily = FontFamily.SansSerif,
+ fontWeight = FontWeight(400),
+ color = PhotonColors.LightGrey05,
+ textAlign = TextAlign.Center,
+ ),
+ )
+ }
+}
+
+private fun getVariableWidth(width: Dp): Float =
+ (alternateLayoutThreshHold / width).coerceIn(0.80f, 1.0f)
+
+@Composable
+private fun PurpleBox(
+ alternateLayout: Boolean,
+ shouldShowYec: MutableState<Boolean>,
+ onDonateButtonClicked: () -> Unit,
+) {
+ Box(
+ modifier = Modifier.background(
+ colorResource(R.color.yec_background), shape = RoundedCornerShape(8.dp),
+ ),
+ ) {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight(),
+ horizontalArrangement = Arrangement.End,
+ ) {
+ ExitIcon(shouldShowYec)
+ }
+ DynamicCampaignContent(alternateLayout, onDonateButtonClicked = onDonateButtonClicked)
+ }
+}
+
+@Composable
+private fun ExitIcon(shouldShowYec: MutableState<Boolean>) {
+ IconButton(
+ modifier = Modifier.padding(8.dp),
+ onClick = {
+ shouldShowYec.value = false
+ },
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.ic_close),
+ tint = PhotonColors.White,
+ contentDescription = stringResource(R.string.close_yec_button_description),
+ )
+ }
+}
+
+
+@Composable
+private fun DynamicCampaignContent(
+ alternateLayout: Boolean,
+ onDonateButtonClicked: () -> Unit,
+) {
+ @Composable
+ fun Icon(shouldShow: Boolean) {
+ if (shouldShow) {
+ Image(
+ painterResource(R.drawable.globe_chain_burst_yec),
+ contentDescription = null,
+ alignment = Alignment.Center,
+ )
+ }
+ }
+ Row(
+ modifier = Modifier
+ .padding(16.dp)
+ .fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Column(
+ modifier = Modifier.fillMaxWidth(if (alternateLayout) 0.75f else 1.0f),
+ horizontalAlignment = if (alternateLayout) Alignment.Start else Alignment.CenterHorizontally,
+ ) {
+ Icon(shouldShow = !alternateLayout)
+ TitleText(alternateLayout)
+ MainText(onDonateButtonClicked)
+ Row(
+ horizontalArrangement = if (alternateLayout) Arrangement.Start else Arrangement.Center,
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ DonateButton(onDonateButtonClicked = onDonateButtonClicked)
+ }
+ }
+ Icon(shouldShow = alternateLayout)
+ }
+}
+
+
+@Composable
+private fun TitleText(alternateLayout: Boolean) {
+ Text(
+ text = stringResource(R.string.free_the_internet_yec),
+ style = TextStyle(
+ fontSize = 56.sp,
+ lineHeight = 47.6.sp,
+ fontFamily = FontFamily(Font(R.font.jacquard_12)),
+ fontWeight = FontWeight(400),
+ color = PhotonColors.White,
+ textAlign = if (alternateLayout) TextAlign.Start else TextAlign.Center,
+ ),
+ )
+}
+
+@Composable
+private fun MainText(onDonateButtonClicked: () -> Unit) {
+ Column {
+ BasicText(
+ text = buildAnnotatedString {
+ withStyle(
+ SpanStyle(
+ color = PhotonColors.LightGrey05,
+ fontSize = 14.sp,
+ ),
+ ) {
+ append(
+ stringResource(
+ R.string.body1_yec, stringResource(R.string.body1_link_yec),
+ ),
+ )
+ val linkStart: Int = stringResource((R.string.body1_yec)).indexOf("%s")
+ addLink(
+ url = LinkAnnotation.Url(
+ url = stringResource(R.string.body1_link_yec),
+ styles = TextLinkStyles(
+ style = SpanStyle(colorResource(R.color.yec_green)),
+ pressedStyle = SpanStyle(PhotonColors.LightGrey05),
+ ),
+ linkInteractionListener = { onDonateButtonClicked() },
+ ),
+ start = linkStart,
+ end = linkStart + stringResource(R.string.body1_link_yec).length,
+ )
+ }
+ },
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(bottom = 8.dp),
+ )
+ Text(
+ text = stringResource(R.string.body2_yec),
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(
+ bottom = 16.dp,
+ ),
+ color = PhotonColors.LightGrey05,
+ fontSize = 14.sp,
+ textAlign = TextAlign.Start,
+ )
+ }
+}
+
+@Composable
+private fun DonateButton(onDonateButtonClicked: () -> Unit) {
+ Button(
+ onClick = onDonateButtonClicked,
+ colors = ButtonDefaults.buttonColors(
+ backgroundColor = colorResource(R.color.yec_green),
+ ),
+ shape = RoundedCornerShape(4.dp),
+ contentPadding = PaddingValues(horizontal = 16.dp, vertical = 9.dp),
+ ) {
+ Text(
+ text = stringResource(R.string.donate_now_yec),
+ textAlign = TextAlign.Center,
+ fontSize = 16.sp,
+ fontWeight = FontWeight.SemiBold,
+ color = PhotonColors.DarkGrey80,
+ )
+ Spacer(
+ Modifier.size(4.dp),
+ )
+ Image(
+ painterResource(R.drawable.heart),
+ contentDescription = null,
+ )
+ }
+}
+
+
+
+fun shouldInitiallyShowPromo(): Boolean {
+// return true // uncomment to test
+
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd-hh-zzz")
+ val startDate = dateFormat.parse("2025-10-14-15-UTC") // from https://gitlab.torproject.org/tpo/web/team/-/issues/66
+ val endDate = dateFormat.parse("2026-01-02-00-UTC") // from https://gitlab.torproject.org/tpo/web/team/-/issues/66#note_3257224
+ val currentDate = Date()
+
+ if (currentDate.before(startDate) || currentDate.after(endDate)) {
+ return false
+ }
+ if (BuildConfig.BUILD_TYPE == "release") {
+ return true
+ }
+ return false
+}
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorHomePage.kt
=====================================
@@ -12,6 +12,8 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.paint
@@ -34,8 +36,13 @@ import org.mozilla.fenix.R
@Composable
@FlexibleWindowLightDarkPreview
fun TorHomePage(
+ shouldInitiallyShowPromo: Boolean = false,
+ onClicked: () -> Unit = {},
toolBarAtTop: Boolean = true,
) {
+ val shouldShowPromo = rememberSaveable {
+ mutableStateOf(shouldInitiallyShowPromo)
+ }
Column(
modifier = Modifier
.fillMaxSize()
@@ -82,30 +89,35 @@ fun TorHomePage(
)
}
Spacer(Modifier.weight(1f))
- Text(
- // Moved from the commit 5bb3cc6b93346dabd8d46677fae7f86a8f8a4fc2
- // "[android] Modify UI/UX", and the file HomeFragment.
- // Splits by full stops or commas and puts the parts in different lines.
- // Ignoring separators at the end of the string, it is expected
- // that there are at most two parts (e.g. "Explore. Privately.").
- text = stringResource(R.string.tor_explore_privately).replace(
+ if (shouldShowPromo.value) {
+ CampaignBox(shouldShowPromo, onDonateButtonClicked = onClicked)
+ Spacer(Modifier.weight(1f))
+ } else {
+ Text(
+ // Moved from the commit 5bb3cc6b93346dabd8d46677fae7f86a8f8a4fc2
+ // "[android] Modify UI/UX", and the file HomeFragment.
+ // Splits by full stops or commas and puts the parts in different lines.
+ // Ignoring separators at the end of the string, it is expected
+ // that there are at most two parts (e.g. "Explore. Privately.").
+ text = stringResource(R.string.tor_explore_privately).replace(
" *([.,。।]) *".toRegex(),
"$1\n",
).trim(),
- style = TextStyle(
- color = Color(color = 0xDEFFFFFF),
- fontSize = 40.sp,
- textAlign = TextAlign.Start,
- ),
- modifier = Modifier.align(Alignment.CenterHorizontally),
- )
- Spacer(Modifier.weight(1f))
- Image(
- painter = painterResource(
- id = R.drawable.ic_onion_pattern,
- ),
- contentDescription = null, Modifier.fillMaxWidth(),
- )
+ style = TextStyle(
+ color = Color(color = 0xDEFFFFFF),
+ fontSize = 40.sp,
+ textAlign = TextAlign.Start,
+ ),
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ )
+ Spacer(Modifier.weight(1f))
+ Image(
+ painter = painterResource(
+ id = R.drawable.ic_onion_pattern,
+ ),
+ contentDescription = null, Modifier.fillMaxWidth(),
+ )
+ }
+ Spacer(modifier = Modifier.size(17.dp))
}
- Spacer(modifier = Modifier.size(17.dp))
}
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorHomePagePreview.kt
=====================================
@@ -0,0 +1,44 @@
+package org.mozilla.fenix.tor
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.tooling.preview.PreviewParameterProvider
+import mozilla.components.compose.base.annotation.FlexibleWindowPreviewPortraitLandscapeEnglishArabicGerman
+import org.mozilla.fenix.home.ui.SearchBarPreview
+
+@FlexibleWindowPreviewPortraitLandscapeEnglishArabicGerman
+@Composable
+/**
+ * Relevant documentation https://developer.android.com/develop/ui/compose/tooling/previews#preview-v…
+ */
+private fun TorHomePagePreview(
+ @PreviewParameter(BooleanBooleanPreviewParameterProvider::class) booleanMatrix: Pair<Boolean, Boolean>,
+) {
+ val toolbarAtTop = booleanMatrix.second
+ Box(
+ contentAlignment = if (toolbarAtTop) Alignment.Companion.TopStart else Alignment.Companion.BottomStart,
+ modifier = Modifier.Companion.fillMaxSize(),
+ ) {
+ SearchBarPreview() // unrestricted vertically so will follow contentAlignment
+ TorHomePage(
+ // restricted vertically so will not follow contentAlignment
+ shouldInitiallyShowPromo = booleanMatrix.first,
+ toolBarAtTop = toolbarAtTop,
+ )
+ }
+}
+
+private class BooleanBooleanPreviewParameterProvider :
+ PreviewParameterProvider<Pair<Boolean, Boolean>> {
+ override val values: Sequence<Pair<Boolean, Boolean>>
+ get() = sequenceOf(
+ Pair(true, true),
+ Pair(true, false),
+ Pair(false, true),
+ Pair(false, false),
+ )
+}
=====================================
mobile/android/fenix/app/src/main/res/drawable/globe_chain_burst_yec.xml
=====================================
@@ -0,0 +1,35 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="124dp" android:viewportHeight="124" android:viewportWidth="160" android:width="160dp">
+
+ <path android:fillColor="#B6E368" android:pathData="M79.97,86.16C65.19,89.07 56.28,80.34 53.67,75.61L34.02,84.97L55.14,84.24L42.62,106.51L63.16,91.39L61.15,117.92L73.64,93L84.86,111.85L79.98,86.16H79.97Z"/>
+
+ <path android:fillColor="#B6E368" android:pathData="M72.38,32.02C87.13,28.91 96.16,37.52 98.83,42.21L118.35,32.58L97.24,33.6L109.46,11.17L89.13,26.57L90.78,0L78.63,25.09L67.15,6.4L72.38,32.02Z"/>
+
+ <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:fillType="evenOdd" android:pathData="M82.86,42.77H84.19V44.18H82.79V42.84H80.14V44.18H81.46V45.52H82.79V48.27H84.19V51.09H82.79V48.34H81.4V45.59H80.06V44.18H78.74V42.84H77.34V53.77H84.19V51.09H85.59V53.77H89.58V55.18H92.31V56.59H89.51V55.18H85.6V67.44H89.58V66.1H92.38V67.44H93.71V68.85H92.38V70.26H91.05V71.67H89.65V73.01H88.25V74.35H86.99V75.76H85.6V74.35H86.86V72.94H88.25V71.6H89.65V70.26H90.98V68.85H92.31V67.51H89.58V68.85H85.6V71.67H84.2V74.42H82.8V75.76H85.6V77.17H81.4V74.35H82.8V71.6H84.19V68.85H77.34V77.17H81.4V78.43H71.88V77.17H67.76V75.76H66.43V74.35H65.1V73.01H63.7V71.67H62.38V70.26H63.78V71.6H65.1V72.94H66.5V74.35H67.83V75.76H70.56V74.42H69.16V71.67H67.83V68.85H63.7V67.51H60.98V68.85H59.58V67.44H58.25V55.18H59.65V67.44H60.98V66.1H63.78V67.44H67.83V55.18H63.78V56.59H60.98V55.18H59.65V52.36H60.98V49.61H62.38V48.27H63.78V46.93H65.1V45.59H66.43V44.18H69.23V45.59H66.5V47H65.17V48.34H63.77V49.68H62.37V52.43H61.04V55.18H63.7V53.77H67.83V51.09H69.22V53.77H75.94V42.84H74.68V44.18H73.28V42.84H70.62V44.18H69.22V42.77H70.55V41.43H82.86V42.77V42.77ZM69.22,71.59H70.55V74.34H71.95V77.16H75.94V68.84H69.23V71.59H69.22ZM77.34,67.44H84.19V55.17H77.34V67.44ZM69.22,67.44H75.94V55.17H69.22V67.44Z" android:strokeAlpha="0.8"/>
+
+ <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:pathData="M62.37,70.25H60.98V68.84H62.37V70.25Z" android:strokeAlpha="0.8"/>
+
+ <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:pathData="M95.1,67.44H93.7V55.17H95.1V67.44Z" android:strokeAlpha="0.8"/>
+
+ <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:pathData="M86.99,45.58H88.25V46.92H89.64V48.26H90.97V49.6H92.37V52.35H93.7V55.17H92.3V52.42H90.97V49.67H89.58V48.33H88.25V46.99H86.85V45.58H84.19V44.17H86.99V45.58V45.58Z" android:strokeAlpha="0.8"/>
+
+ <path android:fillAlpha="0.8" android:fillColor="#C272FF" android:pathData="M73.28,45.58H71.95V48.33H70.62V51.08H69.22V48.26H70.55V45.51H71.88V44.17H73.28V45.58Z" android:strokeAlpha="0.8"/>
+
+ <path android:fillAlpha="0.8" android:fillColor="#00000000" android:pathData="M84.19,44.18V42.77H82.86V41.43H70.55V42.77H69.22V44.18M84.19,44.18H82.79V42.84H80.14V44.18H81.46V45.52H82.79V48.27H84.19V51.09M84.19,44.18V45.59H86.85V47H88.25V48.34H89.58V49.68H90.97V52.43H92.3V55.18M84.19,44.18H86.99V45.59H88.25V46.93H89.64V48.27H90.97V49.61H92.37V52.35H93.7V55.17M69.22,44.18H66.43V45.59H65.1V46.93H63.77V48.27H62.37V49.61H60.98V52.35H59.65V55.17M69.22,44.18V45.59H66.5V47H65.17V48.34H63.77V49.68H62.37V52.43H61.04V55.18H63.7V53.77H67.82V51.09H69.22M69.22,44.18H70.62V42.84H73.28V44.18M93.7,55.17H95.1V67.44H93.7M93.7,55.17V67.44M84.19,51.08H82.79V48.33H81.4V45.58H80.06V44.17H78.74V42.84H77.34V53.76H84.19V51.08H84.19ZM84.19,51.08H85.59V53.76H89.58V55.17H92.3M93.7,67.44H92.37V66.1H89.58V67.44H85.59V55.17H89.5V56.58H92.3V55.17H93.7M93.7,67.44V68.85H92.37V70.26H91.04V71.67H89.64V73.01H88.25V74.35H86.99V75.76H85.59M85.59,75.75V74.34H86.85V72.93H88.25V71.59H89.64V70.25H90.97V68.84H92.3V67.5H89.58V68.84H85.59V71.66H84.19V74.41H82.79V75.75H85.59V75.75ZM85.59,75.75V77.16H81.39M81.39,77.16V74.34H82.79V71.59H84.19V68.84H77.33V77.16H81.39H81.39ZM81.39,77.16V78.43H71.88V77.16H67.75V75.75H66.43V74.34H65.1V73H63.7V71.66H62.37V70.25M62.37,70.25H63.77V71.59H65.1V72.93H66.5V74.34H67.83V75.75H70.55V74.41H69.16V71.66H67.83V68.85H63.7V67.51H60.97V68.85M62.37,70.25H60.98V68.84H62.37V70.25ZM60.97,68.84H59.57V67.43H58.25V55.17H59.65M59.65,55.17V67.44H60.98V66.1H63.77V67.44H67.83V55.17H63.77V56.58H60.98V55.17H59.65ZM69.22,51.08V53.76H75.93V42.84H74.68V44.17H73.28M69.22,51.08H70.62V48.33H71.95V45.58H73.28V44.17H71.88V45.51H70.55V48.26H69.22V51.08ZM69.22,71.59H70.55V74.34H71.95V77.16H75.94V68.84H69.23V71.59H69.22ZM77.34,67.44H84.19V55.17H77.34V67.44ZM69.22,67.44H75.93V55.17H69.22V67.44Z" android:strokeAlpha="0.8" android:strokeColor="#C272FF" android:strokeWidth="0.23451"/>
+
+ <path android:fillColor="#ffffff" android:pathData="M53.84,42.78H56.64L54.84,40.42L58.14,39.7L55.15,36.24L57.62,36.17L57.73,35.5L41.11,29.32C40.64,29.14 40.17,29 39.7,28.88L31.58,7.75C29.81,3.15 25.32,0.06 20.41,0.06C18.94,0.06 17.49,0.33 16.11,0.87L7.65,4.16C1.5,6.55 -1.57,13.54 0.81,19.73L12.4,49.92C14.17,54.53 18.66,57.62 23.56,57.62C24.22,57.62 24.87,57.57 25.51,57.46C26.74,58.58 28.17,59.46 29.77,60.05L46.5,66.27L44.54,62.76H48.38L47.08,59.56H51.23L49.53,56.39L38.61,52.33C42.24,49.92 44.27,45.7 43.94,41.38L56.68,46.11L53.84,42.78ZM49.04,56.96L50.07,58.86H46.04L47.35,62.07H43.36L44.97,64.96L30.01,59.4C26.89,58.24 24.41,55.93 23.03,52.89C21.64,49.86 21.52,46.48 22.67,43.35L24.89,37.34C25.95,34.46 27.98,32.2 30.46,30.8L33.78,39.46C33.55,39.74 33.36,40.07 33.23,40.44L31.01,46.45C30.68,47.35 30.72,48.31 31.11,49.17C31.5,50.04 32.21,50.7 33.1,51.03L49.04,56.96ZM21.23,46.86C21.17,46.76 21.12,46.65 21.08,46.54L9.48,16.35C9.13,15.45 9.36,14.68 9.53,14.31C9.7,13.93 10.11,13.24 11.01,12.89L19.46,9.6C19.78,9.48 20.1,9.42 20.41,9.42C21.32,9.42 22.44,9.95 22.9,11.14L30.21,30.15C27.54,31.61 25.37,34.02 24.24,37.1L22.02,43.11C21.57,44.33 21.3,45.6 21.23,46.86ZM33.88,40.68C33.93,40.52 34,40.38 34.08,40.24L34.5,41.32C34.85,42.23 34.62,42.99 34.45,43.37H34.45C34.28,43.75 33.88,44.43 32.98,44.78L32.26,45.06L33.88,40.68ZM37.79,52.02L33.34,50.37C32.62,50.11 32.06,49.58 31.74,48.88C31.42,48.19 31.39,47.41 31.66,46.7L31.94,45.93L33.23,45.43C34.36,45 34.87,44.13 35.08,43.65C35.29,43.17 35.58,42.21 35.14,41.07L34.58,39.61V39.59L34.35,39.01L34.32,38.91L31.07,30.48L31.06,30.46L30.85,29.91L30.82,29.82L23.55,10.88C22.97,9.39 21.56,8.72 20.41,8.72C20.01,8.72 19.61,8.8 19.21,8.95L10.76,12.24C9.63,12.68 9.11,13.55 8.9,14.02C8.69,14.5 8.4,15.47 8.84,16.61L20.43,46.8C20.61,47.27 20.88,47.67 21.2,47.97C21.24,49.75 21.64,51.52 22.4,53.18C23.03,54.56 23.87,55.79 24.88,56.85C24.44,56.9 24,56.93 23.56,56.93C18.94,56.93 14.71,54.01 13.04,49.67L1.45,19.48C-0.79,13.65 2.1,7.07 7.9,4.81L16.35,1.52C17.66,1.01 19.03,0.75 20.41,0.75C25.04,0.75 29.26,3.67 30.93,8.01L38.88,28.7L38.91,28.78L39.16,29.43L39.18,29.47L42.53,38.2C42.8,38.9 42.99,39.61 43.11,40.33C43.12,40.35 43.13,40.37 43.13,40.4C43.17,40.61 43.2,40.83 43.22,41.05C43.22,41.07 43.22,41.09 43.22,41.11C43.68,45.46 41.58,49.76 37.79,52.02ZM43.86,40.6C43.74,39.71 43.51,38.81 43.18,37.94L40.01,29.69C40.29,29.77 40.58,29.86 40.87,29.97L55.81,35.53L53.67,35.59L56.85,39.27L53.63,39.97L55.24,42.09H52.33L54.41,44.53L43.86,40.6Z"/>
+
+ <path android:fillColor="#ffffff" android:pathData="M157.76,99.65L136.71,69.02C134.41,65.69 130.67,63.66 126.65,63.57C125.48,62.52 124.09,61.66 122.51,61.08L107.43,55.47L107.36,55.44L103.68,55.55L106.41,58.69L102.99,59.44L105.06,62.15H102.4L104.54,64.66L115.19,68.62L112.76,70.31C109.62,72.5 107.78,75.86 107.41,79.41L97.62,75.77L99.32,78.92H94.98L96.29,82.12H92.65L94.1,84.72L111.42,91.16C111.59,91.22 111.75,91.28 111.92,91.33L130.63,118.54C132.98,121.96 136.85,124 140.98,124C143.54,124 146.01,123.22 148.12,121.75L154.58,117.26C157.34,115.33 159.19,112.44 159.79,109.12C160.4,105.79 159.68,102.43 157.76,99.65ZM104.95,64.06L103.91,62.85H106.46L104.21,59.89L107.7,59.13L105.17,56.2L107.25,56.14L122.27,61.73C123.5,62.19 124.62,62.82 125.59,63.59C123.31,63.73 121.12,64.49 119.22,65.82L115.89,68.13L104.95,64.06ZM111.65,90.5L111.25,90.35L94.58,84.15L93.84,82.82H97.32L96.01,79.61H100.48L99.1,77.06L107.36,80.13L108.04,80.38L114.5,82.79C115.37,83.11 116.28,83.1 117.1,82.82C117.32,82.75 117.54,82.65 117.74,82.53C118.53,82.1 119.17,81.39 119.5,80.48L120.95,76.56L124.77,73.9C125.25,73.57 125.79,73.39 126.36,73.39C126.8,73.39 127.92,73.51 128.68,74.61L129.76,76.19C129.69,76.47 129.61,76.75 129.51,77.02L127.19,83.33L127.08,83.63C126.11,86.07 124.45,88.03 122.42,89.34C122.23,89.47 122.03,89.59 121.83,89.7C119.04,91.29 115.64,91.75 112.36,90.74C112.13,90.67 111.89,90.59 111.65,90.5ZM117.15,80.21C117.22,79.78 117.48,78.97 118.31,78.39L119.95,77.26L118.85,80.24C118.57,81 118.04,81.58 117.38,81.94C117.04,81.24 117.08,80.57 117.15,80.21ZM130.06,77.56L130.17,77.25C130.2,77.14 130.24,77.04 130.27,76.93L149.73,105.24C150.31,106.08 150.27,106.93 150.19,107.36C150.11,107.79 149.85,108.6 149.02,109.18L142.57,113.67C142.09,114.01 141.55,114.17 140.98,114.17C140.53,114.17 139.41,114.06 138.66,112.95L122.82,89.91C124.96,88.52 126.7,86.46 127.72,83.89L130.06,77.56ZM159.11,108.99C158.54,112.14 156.79,114.87 154.18,116.68L147.73,121.18C145.73,122.57 143.4,123.3 140.98,123.3C137.07,123.3 133.42,121.38 131.2,118.15L112.97,91.63C113.95,91.86 114.94,91.97 115.91,91.97C118.15,91.97 120.32,91.38 122.23,90.28L138.09,113.35C139.03,114.72 140.42,114.87 140.98,114.87C141.7,114.87 142.36,114.66 142.96,114.25L149.42,109.75C150.45,109.03 150.77,108.02 150.87,107.48C150.96,106.95 151.02,105.89 150.3,104.85L130.51,76.06L129.97,75.26L129.25,74.22C128.3,72.84 126.91,72.7 126.36,72.7H126.36C125.64,72.7 124.97,72.91 124.38,73.32L121.37,75.42L120.37,76.11L117.92,77.82C116.88,78.54 116.56,79.55 116.46,80.08C116.39,80.53 116.33,81.34 116.74,82.2C116.1,82.39 115.41,82.38 114.74,82.13L108.08,79.66C108.39,76.25 110.14,72.99 113.15,70.89L115.99,68.91L116.68,68.43L119.61,66.39C121.6,65 123.94,64.27 126.36,64.27H126.37C126.72,64.27 127.07,64.28 127.41,64.31C130.91,64.62 134.12,66.48 136.13,69.42L157.19,100.05C159,102.68 159.68,105.85 159.11,108.99Z"/>
+
+ <path android:fillColor="#C272FF" android:pathData="M26.73,77.81L30.91,77.83L30.91,79.04L26.73,79.03V84.32H25.51V79.03L21.2,79.02L21.2,77.8L25.51,77.81V72.54H26.73V77.81Z"/>
+
+ <path android:fillColor="#C272FF" android:pathData="M132.82,37.87L137,37.88L137,39.08L132.82,39.07V44.31H131.6V39.07L127.29,39.06L127.29,37.85L131.6,37.86V32.65H132.82V37.87Z"/>
+
+ <path android:fillColor="#C272FF" android:pathData="M20.17,99.2C20.17,98.79 19.84,98.46 19.43,98.46C19.02,98.46 18.69,98.79 18.69,99.2C18.69,99.62 19.02,99.95 19.43,99.95V101.17C18.36,101.17 17.49,100.29 17.49,99.2C17.49,98.12 18.36,97.24 19.43,97.24C20.51,97.24 21.38,98.12 21.38,99.2C21.38,100.29 20.51,101.17 19.43,101.17V99.95C19.84,99.95 20.17,99.62 20.17,99.2Z"/>
+
+ <path android:fillColor="#C272FF" android:pathData="M116.28,43.22C117.35,43.22 118.22,44.1 118.22,45.18C118.22,46.27 117.35,47.15 116.28,47.15C115.2,47.15 114.33,46.27 114.33,45.18C114.33,44.1 115.2,43.22 116.28,43.22Z"/>
+
+ <path android:fillColor="#C272FF" android:pathData="M134.74,51.08C135.81,51.08 136.68,51.96 136.68,53.04C136.68,54.12 135.81,55 134.74,55C133.66,55 132.79,54.12 132.79,53.04C132.79,51.96 133.66,51.08 134.74,51.08Z"/>
+
+ <path android:fillColor="#C272FF" android:pathData="M32.81,91.67C32.81,91.26 32.47,90.93 32.06,90.93C31.66,90.93 31.32,91.26 31.32,91.67C31.32,92.09 31.66,92.42 32.06,92.42V93.64C30.99,93.64 30.12,92.76 30.12,91.67C30.12,90.59 30.99,89.71 32.06,89.71C33.14,89.71 34.01,90.59 34.01,91.67C34.01,92.76 33.14,93.64 32.06,93.64V92.42C32.47,92.42 32.81,92.09 32.81,91.67Z"/>
+
+</vector>
=====================================
mobile/android/fenix/app/src/main/res/drawable/heart.xml
=====================================
@@ -0,0 +1,7 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="16dp" android:viewportHeight="16" android:viewportWidth="16" android:width="16dp">
+
+ <path android:fillColor="#15141A" android:pathData="M8,6C8,6 8,2 11.5,2C15,2 15,5 15,6C15,10.5 8,15 8,15V6Z"/>
+
+ <path android:fillColor="#15141A" android:pathData="M8,6C8,6 8,2 4.5,2C1,2 1,5 1,6C1,10.5 8,15 8,15L9,9L8,6Z"/>
+
+</vector>
=====================================
mobile/android/fenix/app/src/main/res/font/jacquard_12.ttf
=====================================
Binary files /dev/null and b/mobile/android/fenix/app/src/main/res/font/jacquard_12.ttf differ
=====================================
mobile/android/fenix/app/src/main/res/values-ar/strings.xml
=====================================
@@ -2478,4 +2478,11 @@
Text shown as a label or tag to indicate a feature or area is still undergoing active development. Note that here "Beta" should not be translated, as it is used as an icon styled element.
-->
<string name="beta_feature">النسخة التجريبية</string>
+<!-- Not meant for production. Uncomment for the compose preview in [TorHomePage] -->
+<!-- <string name="donate_now_yec">تبرع الآن</string>-->
+<!-- <string name="free_the_internet_yec">حرروا الإنترنت</string>-->
+<!-- <string name="body1_yec">دعم الأدوات التي تكسر قيود الرقابة والمراقبة. %s</string>-->
+<!-- <string name="body1_link_yec">تبرع لمشروع Tor اليوم.</string>-->
+<!-- <string name="body2_yec">حتى 31 ديسمبر، سيتم مضاعفة تبرعك، بحد أقصى 250,000 دولار!</string>-->
+<!-- <string name="no_donation_required_yec">سيكون متصفح Tor لنظام Android مجانيا دائما للاستخدام - لا يلزم التبرع لاستخدام هذا التطبيق.</string>-->
</resources>
=====================================
mobile/android/fenix/app/src/main/res/values-de/strings.xml
=====================================
@@ -3733,4 +3733,11 @@
<string name="review_prompt_feedback_header">Es tut uns leid, dass Sie Probleme haben. Sagen Sie uns, wie wir %1$s verbessern können.</string>
<!-- Label for a button opening a feedback forum -->
<string name="review_prompt_feedback_button">Feedback senden</string>
+ <!-- Not meant for production. Uncomment for the compose preview in [TorHomePage] -->
+<!-- <string name="donate_now_yec">Jetzt spenden</string>-->
+<!-- <string name="free_the_internet_yec">Befreit das Internet</string>-->
+<!-- <string name="body1_yec">Unterstützen Sie Tools, die die Ketten der Zensur und Überwachung sprengen. %s</string>-->
+<!-- <string name="body1_link_yec">Spenden Sie noch heute für das Tor-Projekt.</string>-->
+<!-- <string name="body2_yec">Bis zum 31. Dezember wird Ihre Spende bis zu einer Höhe von 250.000 Dollar verdoppelt!</string>-->
+<!-- <string name="no_donation_required_yec">Der Tor-Browser für Android wird immer kostenlos sein – es ist keine Spende erforderlich, um diese App zu nutzen.</string>-->
</resources>
=====================================
mobile/android/fenix/app/src/main/res/values/colors.xml
=====================================
@@ -395,4 +395,10 @@
<color name="configure_connection_button_white">#E1E0E7</color>
<color name="warning_yellow">#FFA436</color>
<color name="progress_background_tint">#55148C</color>
+
+ <!-- 2025 YEC -->
+ <color name="yec_green">#B6E368</color>
+ <color name="yec_purple">#C272FF</color>
+ <color name="yec_black">#15141A</color>
+ <color name="yec_background">#1D1133</color>
</resources>
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/4c7a34…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/4c7a34…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser-build][main] Bug 41572: Prepare Tor VPN 1.2.0Beta
by boklm (@boklm) 06 Oct '25
by boklm (@boklm) 06 Oct '25
06 Oct '25
boklm pushed to branch main at The Tor Project / Applications / tor-browser-build
Commits:
bd70bd63 by Nicolas Vigier at 2025-10-06T17:32:18+02:00
Bug 41572: Prepare Tor VPN 1.2.0Beta
- - - - -
1 changed file:
- rbm.conf
Changes:
=====================================
rbm.conf
=====================================
@@ -331,9 +331,9 @@ targets:
torvpn:
var:
tor-vpn: 1
- torbrowser_version: '1.0.0Beta'
+ torbrowser_version: '1.2.0Beta'
torbrowser_build: 'build1'
- browser_release_date: '2025/08/28 15:33:44'
+ browser_release_date: '2025/09/25 19:00:00'
project-name: tor-vpn
projectname: torvpn
Project_Name: 'Tor VPN'
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/b…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/b…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser-build][main] Bug 41576: Do not build expert bundles in containers.
by Pier Angelo Vendrame (@pierov) 06 Oct '25
by Pier Angelo Vendrame (@pierov) 06 Oct '25
06 Oct '25
Pier Angelo Vendrame pushed to branch main at The Tor Project / Applications / tor-browser-build
Commits:
eb372d59 by Pier Angelo Vendrame at 2025-10-06T16:23:35+02:00
Bug 41576: Do not build expert bundles in containers.
- - - - -
5 changed files:
- projects/tor-expert-bundle-aar/build
- projects/tor-expert-bundle-aar/config
- + projects/tor-expert-bundle/MANIFEST.MF
- projects/tor-expert-bundle/build
- projects/tor-expert-bundle/config
Changes:
=====================================
projects/tor-expert-bundle-aar/build
=====================================
@@ -2,17 +2,21 @@
[% c("var/set_default_env") -%]
distdir=[% dest_dir %]/[% c('filename') %]
-mkdir -p /var/tmp/build $distdir
-
-mkdir tor-expert-bundle-aar
-cd tor-expert-bundle-aar
+mkdir -p $distdir
[% IF c("var/android_single_arch") -%]
- unzip -o $rootdir/[% c('input_files_by_name/tor-expert-bundle') %]/tor-expert-bundle-[% c("arch") %].aar
+ mv $rootdir/[% c('input_files_by_name/tor-expert-bundle') %]/tor-expert-bundle-[% c("arch") %].aar $distdir/tor-expert-bundle.aar
[% ELSE -%]
+ mkdir aar
+ cd aar
+
+ # We take for granted that we can take the manifests from any of the bundles
+ # without having to change it.
[% FOREACH arch = ['armv7', 'aarch64', 'x86', 'x86_64'] -%]
unzip -o $rootdir/[% c('input_files_by_name/tor-expert-bundle-' _ arch) %]/tor-expert-bundle-[% arch %].aar
[% END -%]
+ [% c('zip', {
+ zip_src => [ '*' ],
+ zip_args => '$distdir/tor-expert-bundle.aar'
+ }) %]
[% END -%]
-
-jar -cvf $distdir/tor-expert-bundle.aar *
=====================================
projects/tor-expert-bundle-aar/config
=====================================
@@ -1,13 +1,10 @@
# vim: filetype=yaml sw=2
version: '[% c("var/torbrowser_version") %]'
filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %]'
-container:
- use_container: 1
var:
input_files:
- - project: container-image
- project: tor-expert-bundle
name: tor-expert-bundle-armv7
target_replace:
=====================================
projects/tor-expert-bundle/MANIFEST.MF
=====================================
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
=====================================
projects/tor-expert-bundle/build
=====================================
@@ -1,6 +1,6 @@
#!/bin/bash
[% c("var/set_default_env") -%]
-distdir=/var/tmp/dist/[% project %]
+distdir=$rootdir/[% project %]
mkdir -p $distdir
output_dir=[% dest_dir %]/[% c('filename') %]
@@ -41,11 +41,9 @@ cd $distdir
# package a .aar on android
[% IF c("var/android") -%]
- aar_file=torExpertBundle-[% c('arch') %].aar
-
abi=[% c('var/abi') %]
- mkdir aar
+ mkdir -p aar/META-INF
mkdir -p aar/jni/$abi
mkdir -p aar/assets/common
@@ -61,10 +59,15 @@ cd $distdir
cp -a tor/pluggable_transports/pt_config.json aar/assets/common/
- cp -a $rootdir/AndroidManifest.xml aar/
+ cp $rootdir/AndroidManifest.xml aar/
+ cp $rootdir/MANIFEST.MF aar/META-INF/
+ [% c("touch") %] aar/AndroidManifest.xml aar/META-INF/MANIFEST.MF
cd aar
- jar -cvf $output_dir/tor-expert-bundle-[% c('arch') %].aar *
+ [% c('zip', {
+ zip_src => [ '*' ],
+ zip_args => '$output_dir/tor-expert-bundle-' _ c('arch') _ '.aar'
+ }) %]
cd ..
[% END %]
=====================================
projects/tor-expert-bundle/config
=====================================
@@ -2,16 +2,12 @@
filename: '[% project %]-[% c("var/osname") %]-[% c("version") %]-[% c("var/build_id") %]'
version: '[% c("var/torbrowser_version") %]'
-container:
- use_container: 1
-
targets:
windows:
var:
pt_extension: .exe
input_files:
- - project: container-image
- name: tor
project: tor
- name: lyrebird
@@ -22,3 +18,5 @@ input_files:
- filename: pt_config.json
- filename: AndroidManifest.xml
enable: '[% c("var/android") %]'
+ - filename: MANIFEST.MF
+ enable: '[% c("var/android") %]'
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/e…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/e…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/mullvad-browser][mullvad-browser-128.14.0esr-14.5-1] fixup! Firefox preference overrides.
by Pier Angelo Vendrame (@pierov) 06 Oct '25
by Pier Angelo Vendrame (@pierov) 06 Oct '25
06 Oct '25
Pier Angelo Vendrame pushed to branch mullvad-browser-128.14.0esr-14.5-1 at The Tor Project / Applications / Mullvad Browser
Commits:
bd08301e by Pier Angelo Vendrame at 2025-10-06T16:20:52+02:00
fixup! Firefox preference overrides.
BB 44240: Fix a typo in a pref.
- - - - -
1 changed file:
- browser/app/profile/001-base-profile.js
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -129,7 +129,7 @@ pref("dom.security.https_only_mode", true);
// but set it anyway only as a defense-in-depth.
pref("dom.security.https_only_mode_pbm", true);
// tor-browser#43197, defense in depth if ever https-only got disabled
-pref("dom.security.https_first_add_exception_on_failiure", false);
+pref("dom.security.https_first_add_exception_on_failure", false);
// tor-browser#22320: Hide referer when coming from a .onion address
// We enable this here (rather than in Tor Browser) in case users of other
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/bd0…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/bd0…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][base-browser-128.14.0esr-14.5-1] fixup! Firefox preference overrides.
by Pier Angelo Vendrame (@pierov) 06 Oct '25
by Pier Angelo Vendrame (@pierov) 06 Oct '25
06 Oct '25
Pier Angelo Vendrame pushed to branch base-browser-128.14.0esr-14.5-1 at The Tor Project / Applications / Tor Browser
Commits:
dcd9d767 by Pier Angelo Vendrame at 2025-10-06T16:20:26+02:00
fixup! Firefox preference overrides.
BB 44240: Fix a typo in a pref.
- - - - -
1 changed file:
- browser/app/profile/001-base-profile.js
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -129,7 +129,7 @@ pref("dom.security.https_only_mode", true);
// but set it anyway only as a defense-in-depth.
pref("dom.security.https_only_mode_pbm", true);
// tor-browser#43197, defense in depth if ever https-only got disabled
-pref("dom.security.https_first_add_exception_on_failiure", false);
+pref("dom.security.https_first_add_exception_on_failure", false);
// tor-browser#22320: Hide referer when coming from a .onion address
// We enable this here (rather than in Tor Browser) in case users of other
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/dcd9d76…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/dcd9d76…
You're receiving this email because of your account on gitlab.torproject.org.
1
0