Fixes #293: Adds about settings page
Co-authored-by: Sawyer Blatz <sblatz@mozilla.com>
This commit is contained in:
parent
2750b65cc3
commit
3ccce1b4d2
|
@ -9,10 +9,12 @@ package org.mozilla.fenix.settings
|
|||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.annotation.RawRes
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.BuildConfig.BUILD_DATE
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.replace
|
||||
import org.mozilla.fenix.settings.SettingsFragment.Companion.wordmarkPath
|
||||
import org.mozilla.geckoview.BuildConfig
|
||||
import java.io.File
|
||||
|
||||
object AboutPage {
|
||||
fun createAboutPage(context: Context): String {
|
||||
|
@ -36,10 +38,13 @@ object AboutPage {
|
|||
|
||||
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)
|
||||
.also { content ->
|
||||
substitutionMap["%about-content%"] = content
|
||||
}
|
||||
|
||||
substitutionMap["%wordmark%"] = File(context.filesDir, wordmarkPath).readText()
|
||||
|
||||
return loadResourceFile(context, R.raw.about, substitutionMap)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
package org.mozilla.fenix.settings
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.widget.Toast
|
||||
|
@ -13,19 +15,31 @@ import androidx.navigation.Navigation
|
|||
import androidx.preference.Preference
|
||||
import androidx.preference.Preference.OnPreferenceClickListener
|
||||
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.FenixApplication
|
||||
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_make_default_browser
|
||||
import org.mozilla.fenix.ext.getPreferenceKey
|
||||
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?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
job = Job()
|
||||
(activity as AppCompatActivity).supportActionBar?.show()
|
||||
}
|
||||
|
||||
|
@ -36,21 +50,70 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
generateWordmark()
|
||||
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() {
|
||||
val makeDefaultBrowserKey = context?.getPreferenceKey(pref_key_make_default_browser)
|
||||
val aboutKey = context?.getPreferenceKey(pref_key_about)
|
||||
val leakKey = context?.getPreferenceKey(pref_key_leakcanary)
|
||||
|
||||
val preferenceMakeDefaultBrowser = findPreference<Preference>(makeDefaultBrowserKey)
|
||||
val preferenceAbout = findPreference<Preference>(aboutKey)
|
||||
val preferenceLeakCanary = findPreference<Preference>(leakKey)
|
||||
|
||||
preferenceMakeDefaultBrowser.onPreferenceClickListener =
|
||||
getClickListenerForMakeDefaultBrowser()
|
||||
preferenceAbout.onPreferenceClickListener = getAboutPageListener()
|
||||
|
||||
preferenceLeakCanary.isVisible = BuildConfig.DEBUG
|
||||
if (BuildConfig.DEBUG) {
|
||||
|
@ -81,18 +144,17 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun getAboutPageListener(): OnPreferenceClickListener {
|
||||
return OnPreferenceClickListener {
|
||||
private fun navigateToSettingsArticle() {
|
||||
requireComponents.useCases.tabsUseCases.addTab.invoke(aboutURL, true)
|
||||
view?.let {
|
||||
Navigation.findNavController(it)
|
||||
.navigate(SettingsFragmentDirections.actionGlobalBrowser(null))
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val wordmarkScalingFactor = 2
|
||||
const val wordmarkPath = "wordmark.b64"
|
||||
const val aboutURL = "about:version"
|
||||
}
|
||||
}
|
||||
|
|
49
app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt
Normal file
49
app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt
Normal file
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,43 +9,45 @@
|
|||
content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
body, html {
|
||||
background: #221F1F;
|
||||
color: #FFFFFF;
|
||||
background: #f9f9fa;
|
||||
color: #0C0C0D;
|
||||
font-family: sans-serif;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
body{
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0A9AF4;
|
||||
}
|
||||
|
||||
p.subtitle {
|
||||
text-align: center;
|
||||
opacity: .7;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1#wordmark {
|
||||
img#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;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<html>
|
||||
<body
|
||||
class="about">
|
||||
<h1 id="wordmark">Fenix</h1>
|
||||
<br>
|
||||
<img src="%wordmark%" id="wordmark"/>
|
||||
<br>
|
||||
<p class="subtitle">%about-version%</p>
|
||||
%about-content%
|
||||
|
||||
<p class="subtitle">Built on: %build-date%</p>
|
||||
</body>
|
||||
</html>
|
|
@ -131,10 +131,10 @@
|
|||
<!-- 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>
|
||||
|
||||
<!-- About content -->
|
||||
<string name="about_content"><![CDATA[
|
||||
<p>%1$s puts you in control.</p>
|
||||
<p>%1$s is produced by Mozilla. Our mission is to foster a healthy, open Internet.<br/>
|
||||
<p>%1$s is made by Mozilla: a global community that makes browsers, apps, code and tools that put
|
||||
people before profit. Our mission: keep the Internet open and accessible to all.<br/>
|
||||
<a href="%2$s">Learn more</a></p>
|
||||
]]></string>
|
||||
|
||||
<!-- Sessions -->
|
||||
|
|
Loading…
Reference in New Issue
Block a user