Skip to content

Commit 41004fe

Browse files
gabrielluongpchevrel@mozilla.com
authored andcommitted
Bug 1998748 - Add link as a shortcut for Japan a=pascalc
Co-authored-by: Titouan Thibaud <tthibaud@mozilla.com> Original Revision: https://phabricator.services.mozilla.com/D272306 Differential Revision: https://phabricator.services.mozilla.com/D272668
1 parent 6b86eff commit 41004fe

File tree

10 files changed

+230
-33
lines changed

10 files changed

+230
-33
lines changed

mobile/android/fenix/app/nimbus.fml.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,20 @@ features:
639639
type: Boolean
640640
default: false
641641

642+
firefox-jp-guide-default-site:
643+
description: >
644+
This feature is for managing the visibility of the Firefox Japanese Guide default suggested site shortcut
645+
variables:
646+
enabled:
647+
description: >
648+
Enables the feature.
649+
type: Boolean
650+
default: false
651+
defaults:
652+
- channel: developer
653+
value:
654+
enabled: true
655+
642656
microsurveys:
643657
description: Feature for microsurveys.
644658
variables:

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/Favicon.kt

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package org.mozilla.fenix.compose
66

77
import android.content.res.Configuration
8+
import androidx.annotation.DrawableRes
89
import androidx.compose.foundation.Image
910
import androidx.compose.foundation.background
1011
import androidx.compose.foundation.layout.Box
@@ -16,6 +17,7 @@ import androidx.compose.ui.draw.clip
1617
import androidx.compose.ui.graphics.Shape
1718
import androidx.compose.ui.layout.ContentScale
1819
import androidx.compose.ui.res.dimensionResource
20+
import androidx.compose.ui.res.painterResource
1921
import androidx.compose.ui.tooling.preview.Preview
2022
import androidx.compose.ui.unit.Dp
2123
import androidx.compose.ui.unit.dp
@@ -26,6 +28,8 @@ import mozilla.components.compose.base.utils.inComposePreview
2628
import org.mozilla.fenix.components.components
2729
import org.mozilla.fenix.theme.FirefoxTheme
2830

31+
internal val FAVICON_ROUNDED_CORNER_SHAPE = RoundedCornerShape(2.dp)
32+
2933
/**
3034
* Load and display the favicon of a particular website.
3135
*
@@ -36,7 +40,7 @@ import org.mozilla.fenix.theme.FirefoxTheme
3640
* download the icon (if needed).
3741
* @param imageUrl Optional image URL to create an [IconRequest.Resource] from.
3842
* @param shape The shape used to clip the favicon. Defaults to a slightly rounded rectangle.
39-
* Use [CircleShape] for a round image.
43+
* Use [CircleShape] for a round image.
4044
*/
4145
@Composable
4246
fun Favicon(
@@ -45,15 +49,13 @@ fun Favicon(
4549
modifier: Modifier = Modifier,
4650
isPrivate: Boolean = false,
4751
imageUrl: String? = null,
48-
shape: Shape = RoundedCornerShape(2.dp),
52+
shape: Shape = FAVICON_ROUNDED_CORNER_SHAPE,
4953
) {
50-
if (inComposePreview) {
51-
FaviconPlaceholder(
52-
size = size,
53-
modifier = modifier,
54-
shape = shape,
55-
)
56-
} else {
54+
Favicon(
55+
size = size,
56+
modifier = modifier,
57+
shape = shape,
58+
) {
5759
val iconResource = imageUrl?.let {
5860
IconRequest.Resource(
5961
url = imageUrl,
@@ -89,6 +91,65 @@ fun Favicon(
8991
}
9092
}
9193

94+
/**
95+
* Load and display the favicon of a particular website.
96+
*
97+
* @param imageResource ID of a drawable resource to be shown.
98+
* @param size [Dp] height and width of the image to be displayed.
99+
* @param modifier [Modifier] to be applied to the layout.
100+
* @param shape The shape used to clip the favicon. Defaults to a slightly rounded rectangle.
101+
* Use [CircleShape] for a round image.
102+
*/
103+
@Composable
104+
fun Favicon(
105+
@DrawableRes imageResource: Int,
106+
size: Dp,
107+
modifier: Modifier = Modifier,
108+
shape: Shape = RoundedCornerShape(2.dp),
109+
) {
110+
Favicon(
111+
size = size,
112+
modifier = modifier,
113+
shape = shape,
114+
) {
115+
Image(
116+
painter = painterResource(id = imageResource),
117+
contentDescription = null,
118+
modifier = modifier
119+
.size(size)
120+
.clip(shape),
121+
contentScale = ContentScale.Crop,
122+
)
123+
}
124+
}
125+
126+
/**
127+
* Displays a favicon given a [content] slot.
128+
*
129+
* @param size [Dp] height and width of the placeholder to display.
130+
* @param modifier [Modifier] to be applied to the layout.
131+
* @param shape The shape used to clip the favicon. Defaults to a slightly rounded rectangle.
132+
* Use [CircleShape] for a round image.
133+
* @param content The content to be displayed in the favicon.
134+
*/
135+
@Composable
136+
private fun Favicon(
137+
size: Dp,
138+
modifier: Modifier = Modifier,
139+
shape: Shape = RoundedCornerShape(2.dp),
140+
content: @Composable () -> Unit,
141+
) {
142+
if (inComposePreview) {
143+
FaviconPlaceholder(
144+
size = size,
145+
modifier = modifier,
146+
shape = shape,
147+
)
148+
} else {
149+
content()
150+
}
151+
}
152+
92153
/**
93154
* Placeholder used while the Favicon image is loading.
94155
*

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/topsites/DefaultTopSitesBinding.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,16 @@ class DefaultTopSitesBinding(
7878
val notExcludedInRegions =
7979
item.excludeRegions.isEmpty() || region !in item.excludeRegions
8080

81-
includedInRegions && notExcludedInRegions
81+
val includedInExperiments =
82+
if (item.includeExperiments.isNotEmpty() &&
83+
item.includeExperiments.first() == "firefox-jp-guide-default-site"
84+
) {
85+
settings.showFirefoxJpGuideDefaultSite
86+
} else {
87+
true
88+
}
89+
90+
includedInRegions && notExcludedInRegions && includedInExperiments
8291
}.map {
8392
Pair(
8493
it.title?.takeIf(String::isNotBlank) ?: it.url.tryGetHostFromUrl(),

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/topsites/TopSites.kt

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -434,28 +434,26 @@ private fun TopSiteFaviconCard(
434434
color = backgroundColor,
435435
shape = RoundedCornerShape(4.dp),
436436
) {
437-
if (topSite is TopSite.Provided) {
438-
TopSiteFavicon(url = topSite.url, imageUrl = topSite.imageUrl)
439-
} else {
440-
TopSiteFavicon(url = topSite.url, imageUrl = getImageUrl(url = topSite.url))
441-
}
437+
TopSiteFavicon(url = topSite.url)
442438
}
443439
}
444440
}
445441
}
446442

447-
private fun getImageUrl(url: String): String? {
448-
return when (url) {
449-
"https://tenki.jp/" -> "https://tenki.jp/favicon.ico"
450-
"https://m.yahoo.co.jp/" -> "https://s.yimg.jp/c/icon/s/bsc/2.0/favicon.ico"
451-
"https://ameblo.jp/" -> "https://stat100.ameba.jp/common_style/img/favicon.ico"
452-
else -> null
453-
}
454-
}
455-
456443
@Composable
457-
private fun TopSiteFavicon(url: String, imageUrl: String? = null) {
458-
Favicon(url = url, size = TOP_SITES_FAVICON_SIZE.dp, imageUrl = imageUrl)
444+
private fun TopSiteFavicon(url: String) {
445+
when (val favicon = getTopSitesFavicon(url)) {
446+
is TopSitesFavicon.ImageUrl -> Favicon(
447+
url = url,
448+
size = TOP_SITES_FAVICON_SIZE.dp,
449+
imageUrl = favicon.url,
450+
)
451+
452+
is TopSitesFavicon.Drawable -> Favicon(
453+
size = TOP_SITES_FAVICON_SIZE.dp,
454+
imageResource = favicon.drawableResId,
455+
)
456+
}
459457
}
460458

461459
@Composable
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
package org.mozilla.fenix.home.topsites
6+
7+
import androidx.annotation.DrawableRes
8+
import org.mozilla.fenix.R
9+
10+
/**
11+
* Represents the favicon of a top site.
12+
*/
13+
sealed class TopSitesFavicon {
14+
/**
15+
* An image URL.
16+
*
17+
* @property url The URL of the image to use.
18+
*/
19+
data class ImageUrl(val url: String?) : TopSitesFavicon()
20+
21+
/**
22+
* A drawable background.
23+
*
24+
* @property drawableResId The drawable resource ID to use.
25+
*/
26+
data class Drawable(@param:DrawableRes val drawableResId: Int) : TopSitesFavicon()
27+
}
28+
29+
internal fun getTopSitesFavicon(url: String): TopSitesFavicon {
30+
return when (url) {
31+
"https://tenki.jp/" -> TopSitesFavicon.ImageUrl(url = "https://tenki.jp/favicon.ico")
32+
"https://m.yahoo.co.jp/" -> TopSitesFavicon.ImageUrl(url = "https://s.yimg.jp/c/icon/s/bsc/2.0/favicon.ico")
33+
"https://ameblo.jp/" -> TopSitesFavicon.ImageUrl(url = "https://stat100.ameba.jp/common_style/img/favicon.ico")
34+
"https://blog.mozilla.org/ja/firefox-ja/android-guide/" ->
35+
TopSitesFavicon.Drawable(R.drawable.ic_japan_onboarding_favicon)
36+
37+
else -> TopSitesFavicon.ImageUrl(url = null)
38+
}
39+
}

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,12 @@ class Settings(private val appContext: Context) : PreferencesHolder {
229229
val collections: Boolean
230230
get() = FxNimbus.features.homescreen.value().sectionsEnabled[HomeScreenSection.COLLECTIONS] == true
231231

232+
/**
233+
* Indicates whether or not the Firefox Japan Guide default site should be shown.
234+
*/
235+
val showFirefoxJpGuideDefaultSite: Boolean
236+
get() = FxNimbus.features.firefoxJpGuideDefaultSite.value().enabled
237+
232238
/**
233239
* Indicates whether or not the homepage header should be shown.
234240
*/
67.5 KB
Loading

mobile/android/fenix/app/src/main/res/raw/initial_shortcuts.json

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,26 @@
3838
"last_modified": 1
3939
},
4040
{
41-
"url": "https://tenki.jp/",
41+
"url": "https://blog.mozilla.org/ja/firefox-ja/android-guide/",
4242
"order": 1,
43+
"title": "Firefoxガイド",
44+
"schema": 1,
45+
"exclude_locales": [],
46+
"exclude_regions": [],
47+
"include_locales": [],
48+
"include_regions": [
49+
"JP"
50+
],
51+
"exclude_experiments": [],
52+
"include_experiments": [
53+
"firefox-jp-guide-default-site"
54+
],
55+
"id": "",
56+
"last_modified": 1
57+
},
58+
{
59+
"url": "https://tenki.jp/",
60+
"order": 2,
4361
"title": "tenki.jp",
4462
"schema": 1,
4563
"exclude_locales": [],
@@ -55,7 +73,7 @@
5573
},
5674
{
5775
"url": "https://m.yahoo.co.jp/",
58-
"order": 2,
76+
"order": 3,
5977
"title": "Yahoo! JAPAN",
6078
"schema": 1,
6179
"exclude_locales": [],
@@ -71,7 +89,7 @@
7189
},
7290
{
7391
"url": "https://ameblo.jp/",
74-
"order": 3,
92+
"order": 4,
7593
"title": "Amebaブログ",
7694
"schema": 1,
7795
"exclude_locales": [],
@@ -87,7 +105,7 @@
87105
},
88106
{
89107
"url": "https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8",
90-
"order": 4,
108+
"order": 5,
91109
"title": "ウィキペディア",
92110
"schema": 1,
93111
"exclude_locales": [],

0 commit comments

Comments
 (0)