parent
2750b65cc3
commit
3ccce1b4d2
|
@ -9,10 +9,12 @@ package org.mozilla.fenix.settings
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import androidx.annotation.RawRes
|
import androidx.annotation.RawRes
|
||||||
import org.mozilla.fenix.R
|
|
||||||
import org.mozilla.fenix.BuildConfig.BUILD_DATE
|
import org.mozilla.fenix.BuildConfig.BUILD_DATE
|
||||||
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.replace
|
import org.mozilla.fenix.ext.replace
|
||||||
|
import org.mozilla.fenix.settings.SettingsFragment.Companion.wordmarkPath
|
||||||
import org.mozilla.geckoview.BuildConfig
|
import org.mozilla.geckoview.BuildConfig
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
object AboutPage {
|
object AboutPage {
|
||||||
fun createAboutPage(context: Context): String {
|
fun createAboutPage(context: Context): String {
|
||||||
|
@ -36,9 +38,12 @@ object AboutPage {
|
||||||
|
|
||||||
substitutionMap["%build-date%"] = BUILD_DATE
|
substitutionMap["%build-date%"] = BUILD_DATE
|
||||||
|
|
||||||
context.resources.getString(R.string.about_content, appName).also { content ->
|
context.resources.getString(R.string.about_content, appName, SupportUtils.MOZILLA_MANIFESTO_URL)
|
||||||
substitutionMap["%about-content%"] = content
|
.also { content ->
|
||||||
}
|
substitutionMap["%about-content%"] = content
|
||||||
|
}
|
||||||
|
|
||||||
|
substitutionMap["%wordmark%"] = File(context.filesDir, wordmarkPath).readText()
|
||||||
|
|
||||||
return loadResourceFile(context, R.raw.about, substitutionMap)
|
return loadResourceFile(context, R.raw.about, substitutionMap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
package org.mozilla.fenix.settings
|
package org.mozilla.fenix.settings
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
@ -13,19 +15,31 @@ import androidx.navigation.Navigation
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.Preference.OnPreferenceClickListener
|
import androidx.preference.Preference.OnPreferenceClickListener
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import mozilla.components.support.ktx.android.graphics.toDataUri
|
||||||
import org.mozilla.fenix.BuildConfig
|
import org.mozilla.fenix.BuildConfig
|
||||||
import org.mozilla.fenix.FenixApplication
|
import org.mozilla.fenix.FenixApplication
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.R.string.pref_key_about
|
|
||||||
import org.mozilla.fenix.R.string.pref_key_leakcanary
|
import org.mozilla.fenix.R.string.pref_key_leakcanary
|
||||||
import org.mozilla.fenix.R.string.pref_key_make_default_browser
|
import org.mozilla.fenix.R.string.pref_key_make_default_browser
|
||||||
import org.mozilla.fenix.ext.getPreferenceKey
|
import org.mozilla.fenix.ext.getPreferenceKey
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class SettingsFragment : PreferenceFragmentCompat() {
|
class SettingsFragment : PreferenceFragmentCompat(), CoroutineScope {
|
||||||
|
|
||||||
|
private lateinit var job: Job
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = Dispatchers.Main + job
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
job = Job()
|
||||||
(activity as AppCompatActivity).supportActionBar?.show()
|
(activity as AppCompatActivity).supportActionBar?.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,21 +50,70 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
||||||
|
generateWordmark()
|
||||||
setupPreferences()
|
setupPreferences()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onPreferenceTreeClick(preference: Preference): Boolean {
|
||||||
|
when (preference.key) {
|
||||||
|
resources.getString(R.string.pref_key_help) -> {
|
||||||
|
requireComponents.useCases.tabsUseCases.addTab
|
||||||
|
.invoke(SupportUtils.getSumoURLForTopic(context!!, SupportUtils.SumoTopic.HELP))
|
||||||
|
navigateToSettingsArticle()
|
||||||
|
}
|
||||||
|
resources.getString(R.string.pref_key_rate) -> {
|
||||||
|
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(SupportUtils.RATE_APP_URL)))
|
||||||
|
}
|
||||||
|
resources.getString(R.string.pref_key_feedback) -> {
|
||||||
|
requireComponents.useCases.tabsUseCases.addTab.invoke(SupportUtils.FEEDBACK_URL)
|
||||||
|
navigateToSettingsArticle()
|
||||||
|
}
|
||||||
|
resources.getString(R.string.pref_key_about) -> {
|
||||||
|
requireComponents.useCases.tabsUseCases.addTab.invoke(aboutURL, true)
|
||||||
|
navigateToSettingsArticle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.onPreferenceTreeClick(preference)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shrinks the wordmark resolution on first run to ensure About Page loads quickly
|
||||||
|
*/
|
||||||
|
private fun generateWordmark() {
|
||||||
|
val path = context?.filesDir
|
||||||
|
val file = File(path, wordmarkPath)
|
||||||
|
path?.let {
|
||||||
|
if (!file.exists()) {
|
||||||
|
launch(IO) {
|
||||||
|
val options = BitmapFactory.Options().apply {
|
||||||
|
inSampleSize = wordmarkScalingFactor
|
||||||
|
inJustDecodeBounds = false
|
||||||
|
}
|
||||||
|
file.appendText(
|
||||||
|
BitmapFactory.decodeResource(
|
||||||
|
resources,
|
||||||
|
R.drawable.ic_logo_wordmark, options
|
||||||
|
).toDataUri()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupPreferences() {
|
private fun setupPreferences() {
|
||||||
val makeDefaultBrowserKey = context?.getPreferenceKey(pref_key_make_default_browser)
|
val makeDefaultBrowserKey = context?.getPreferenceKey(pref_key_make_default_browser)
|
||||||
val aboutKey = context?.getPreferenceKey(pref_key_about)
|
|
||||||
val leakKey = context?.getPreferenceKey(pref_key_leakcanary)
|
val leakKey = context?.getPreferenceKey(pref_key_leakcanary)
|
||||||
|
|
||||||
val preferenceMakeDefaultBrowser = findPreference<Preference>(makeDefaultBrowserKey)
|
val preferenceMakeDefaultBrowser = findPreference<Preference>(makeDefaultBrowserKey)
|
||||||
val preferenceAbout = findPreference<Preference>(aboutKey)
|
|
||||||
val preferenceLeakCanary = findPreference<Preference>(leakKey)
|
val preferenceLeakCanary = findPreference<Preference>(leakKey)
|
||||||
|
|
||||||
preferenceMakeDefaultBrowser.onPreferenceClickListener =
|
preferenceMakeDefaultBrowser.onPreferenceClickListener =
|
||||||
getClickListenerForMakeDefaultBrowser()
|
getClickListenerForMakeDefaultBrowser()
|
||||||
preferenceAbout.onPreferenceClickListener = getAboutPageListener()
|
|
||||||
|
|
||||||
preferenceLeakCanary.isVisible = BuildConfig.DEBUG
|
preferenceLeakCanary.isVisible = BuildConfig.DEBUG
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
|
@ -81,18 +144,17 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAboutPageListener(): OnPreferenceClickListener {
|
private fun navigateToSettingsArticle() {
|
||||||
return OnPreferenceClickListener {
|
requireComponents.useCases.tabsUseCases.addTab.invoke(aboutURL, true)
|
||||||
requireComponents.useCases.tabsUseCases.addTab.invoke(aboutURL, true)
|
view?.let {
|
||||||
view?.let {
|
Navigation.findNavController(it)
|
||||||
Navigation.findNavController(it)
|
.navigate(SettingsFragmentDirections.actionGlobalBrowser(null))
|
||||||
.navigate(SettingsFragmentDirections.actionGlobalBrowser(null))
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
const val wordmarkScalingFactor = 2
|
||||||
|
const val wordmarkPath = "wordmark.b64"
|
||||||
const val aboutURL = "about:version"
|
const val aboutURL = "about:version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.settings
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import org.mozilla.fenix.BuildConfig
|
||||||
|
import java.io.UnsupportedEncodingException
|
||||||
|
import java.net.URLEncoder
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
object SupportUtils {
|
||||||
|
const val FEEDBACK_URL = "https://input.mozilla.org"
|
||||||
|
const val RATE_APP_URL = "market://details?id=" + BuildConfig.APPLICATION_ID
|
||||||
|
const val MOZILLA_MANIFESTO_URL = "https://www.mozilla.org/en-GB/about/manifesto/"
|
||||||
|
|
||||||
|
enum class SumoTopic(
|
||||||
|
internal val topicStr: String
|
||||||
|
) {
|
||||||
|
HELP("firefox-android-help")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSumoURLForTopic(context: Context, topic: SumoTopic): String {
|
||||||
|
val escapedTopic = getEncodedTopicUTF8(topic.topicStr)
|
||||||
|
val appVersion = getAppVersion(context)
|
||||||
|
val osTarget = "Android"
|
||||||
|
val langTag = Locale.getDefault().isO3Language
|
||||||
|
return "https://support.mozilla.org/1/mobile/$appVersion/$osTarget/$langTag/$escapedTopic"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getEncodedTopicUTF8(topic: String): String {
|
||||||
|
try {
|
||||||
|
return URLEncoder.encode(topic, "UTF-8")
|
||||||
|
} catch (e: UnsupportedEncodingException) {
|
||||||
|
throw IllegalStateException("utf-8 should always be available", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAppVersion(context: Context): String {
|
||||||
|
try {
|
||||||
|
return context.packageManager.getPackageInfo(context.packageName, 0).versionName
|
||||||
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
|
// This should be impossible - we should always be able to get information about ourselves:
|
||||||
|
throw IllegalStateException("Unable find package details for Fenix", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,48 +4,50 @@
|
||||||
- You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
- You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
<head>
|
<head>
|
||||||
<meta
|
<meta
|
||||||
name="viewport"
|
name="viewport"
|
||||||
charset="utf-8"
|
charset="utf-8"
|
||||||
content="width=device-width, initial-scale=1">
|
content="width=device-width, initial-scale=1">
|
||||||
<style>
|
<style>
|
||||||
body, html {
|
body, html {
|
||||||
background: #221F1F;
|
background: #f9f9fa;
|
||||||
color: #FFFFFF;
|
color: #0C0C0D;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
body{
|
body{
|
||||||
padding-left: 24px;
|
padding-left: 24px;
|
||||||
padding-right: 24px;
|
padding-right: 24px;
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
margin-right: 0px;
|
margin-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #0A9AF4;
|
color: #0A9AF4;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.subtitle {
|
p.subtitle {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
opacity: .7;
|
opacity: .7;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
img#wordmark {
|
||||||
h1#wordmark {
|
/* We need to set the dp size here, because by default webview assumes the image is not
|
||||||
|
density specific (but since it's an android resource, we get a density specific version). */
|
||||||
|
width: 180px;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
padding-top: 24px;
|
padding-top: 24px;
|
||||||
text-align: center;
|
}
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<html>
|
<html>
|
||||||
<body
|
<body
|
||||||
class="about">
|
class="about">
|
||||||
<h1 id="wordmark">Fenix</h1>
|
<br>
|
||||||
|
<img src="%wordmark%" id="wordmark"/>
|
||||||
|
<br>
|
||||||
<p class="subtitle">%about-version%</p>
|
<p class="subtitle">%about-version%</p>
|
||||||
%about-content%
|
%about-content%
|
||||||
|
|
||||||
<p class="subtitle">Built on: %build-date%</p>
|
<p class="subtitle">Built on: %build-date%</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -131,10 +131,10 @@
|
||||||
<!-- Content description (not visible, for screen readers etc.): "Menu icon for items on a history item" -->
|
<!-- Content description (not visible, for screen readers etc.): "Menu icon for items on a history item" -->
|
||||||
<string name="content_description_history_menu">History item menu</string>
|
<string name="content_description_history_menu">History item menu</string>
|
||||||
|
|
||||||
<!-- About content -->
|
|
||||||
<string name="about_content"><![CDATA[
|
<string name="about_content"><![CDATA[
|
||||||
<p>%1$s puts you in control.</p>
|
<p>%1$s is made by Mozilla: a global community that makes browsers, apps, code and tools that put
|
||||||
<p>%1$s is produced by Mozilla. Our mission is to foster a healthy, open Internet.<br/>
|
people before profit. Our mission: keep the Internet open and accessible to all.<br/>
|
||||||
|
<a href="%2$s">Learn more</a></p>
|
||||||
]]></string>
|
]]></string>
|
||||||
|
|
||||||
<!-- Sessions -->
|
<!-- Sessions -->
|
||||||
|
|
Loading…
Reference in New Issue