[AboutFragment / LicenseFragment] Fix license restore after rotation

Do not restore last opened license after a rotation change when the license was closed earlier.

This commit adds onCancelListener and onDismissListener to the AlertDialogs which are used to display the licenses.
This commit is contained in:
TobiGr 2023-09-20 18:45:52 +02:00
parent 279fd2399d
commit 242e20316b
2 changed files with 60 additions and 57 deletions

View File

@ -1,15 +1,24 @@
package org.schabi.newpipe.about package org.schabi.newpipe.about
import android.os.Bundle import android.os.Bundle
import android.util.Base64
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.webkit.WebView
import androidx.appcompat.app.AlertDialog
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.databinding.FragmentLicensesBinding import org.schabi.newpipe.databinding.FragmentLicensesBinding
import org.schabi.newpipe.databinding.ItemSoftwareComponentBinding import org.schabi.newpipe.databinding.ItemSoftwareComponentBinding
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.external_communication.ShareUtils
/** /**
* Fragment containing the software licenses. * Fragment containing the software licenses.
@ -41,7 +50,7 @@ class LicenseFragment : Fragment() {
binding.licensesAppReadLicense.setOnClickListener { binding.licensesAppReadLicense.setOnClickListener {
activeLicense = StandardLicenses.GPL3 activeLicense = StandardLicenses.GPL3
compositeDisposable.add( compositeDisposable.add(
showLicense(activity, StandardLicenses.GPL3) showLicense(StandardLicenses.GPL3)
) )
} }
for (component in softwareComponents) { for (component in softwareComponents) {
@ -59,13 +68,13 @@ class LicenseFragment : Fragment() {
root.setOnClickListener { root.setOnClickListener {
activeLicense = component.license activeLicense = component.license
compositeDisposable.add( compositeDisposable.add(
showLicense(activity, component) showLicense(component)
) )
} }
binding.licensesSoftwareComponents.addView(root) binding.licensesSoftwareComponents.addView(root)
registerForContextMenu(root) registerForContextMenu(root)
} }
activeLicense?.let { compositeDisposable.add(showLicense(activity, it)) } activeLicense?.let { compositeDisposable.add(showLicense(it)) }
return binding.root return binding.root
} }
@ -74,6 +83,51 @@ class LicenseFragment : Fragment() {
activeLicense?.let { savedInstanceState.putSerializable(LICENSE_KEY, it) } activeLicense?.let { savedInstanceState.putSerializable(LICENSE_KEY, it) }
} }
private fun showLicense(component: SoftwareComponent): Disposable {
return showLicense(component.license) {
setPositiveButton(R.string.dismiss) { dialog, _ ->
dialog.dismiss()
}
setNeutralButton(R.string.open_website_license) { _, _ ->
ShareUtils.openUrlInApp(requireContext(), component.link)
}
}
}
private fun showLicense(license: License) = showLicense(license) {
setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
}
private fun showLicense(
license: License,
block: AlertDialog.Builder.() -> AlertDialog.Builder
): Disposable {
return if (context == null) {
Disposable.empty()
} else {
val context = requireContext()
Observable.fromCallable { getFormattedLicense(context, license) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { formattedLicense ->
val webViewData = Base64.encodeToString(
formattedLicense.toByteArray(), Base64.NO_PADDING
)
val webView = WebView(context)
webView.loadData(webViewData, "text/html; charset=UTF-8", "base64")
Localization.assureCorrectAppLanguage(context)
AlertDialog.Builder(requireContext())
.setTitle(license.name)
.setView(webView)
.setOnCancelListener { activeLicense = null }
.setOnDismissListener { activeLicense = null }
.block()
.show()
}
}
}
companion object { companion object {
private const val ARG_COMPONENTS = "components" private const val ARG_COMPONENTS = "components"
private const val LICENSE_KEY = "ACTIVE_LICENSE" private const val LICENSE_KEY = "ACTIVE_LICENSE"

View File

@ -1,17 +1,8 @@
package org.schabi.newpipe.about package org.schabi.newpipe.about
import android.content.Context import android.content.Context
import android.util.Base64
import android.webkit.WebView
import androidx.appcompat.app.AlertDialog
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.ThemeHelper import org.schabi.newpipe.util.ThemeHelper
import org.schabi.newpipe.util.external_communication.ShareUtils
import java.io.IOException import java.io.IOException
/** /**
@ -20,7 +11,7 @@ import java.io.IOException
* @return String which contains a HTML formatted license page * @return String which contains a HTML formatted license page
* styled according to the context's theme * styled according to the context's theme
*/ */
private fun getFormattedLicense(context: Context, license: License): String { fun getFormattedLicense(context: Context, license: License): String {
try { try {
return context.assets.open(license.filename).bufferedReader().use { it.readText() } return context.assets.open(license.filename).bufferedReader().use { it.readText() }
// split the HTML file and insert the stylesheet into the HEAD of the file // split the HTML file and insert the stylesheet into the HEAD of the file
@ -34,7 +25,7 @@ private fun getFormattedLicense(context: Context, license: License): String {
* @param context the Android context * @param context the Android context
* @return String which is a CSS stylesheet according to the context's theme * @return String which is a CSS stylesheet according to the context's theme
*/ */
private fun getLicenseStylesheet(context: Context): String { fun getLicenseStylesheet(context: Context): String {
val isLightTheme = ThemeHelper.isLightThemeSelected(context) val isLightTheme = ThemeHelper.isLightThemeSelected(context)
val licenseBackgroundColor = getHexRGBColor( val licenseBackgroundColor = getHexRGBColor(
context, if (isLightTheme) R.color.light_license_background_color else R.color.dark_license_background_color context, if (isLightTheme) R.color.light_license_background_color else R.color.dark_license_background_color
@ -56,48 +47,6 @@ private fun getLicenseStylesheet(context: Context): String {
* @param color the color number from R.color * @param color the color number from R.color
* @return a six characters long String with hexadecimal RGB values * @return a six characters long String with hexadecimal RGB values
*/ */
private fun getHexRGBColor(context: Context, color: Int): String { fun getHexRGBColor(context: Context, color: Int): String {
return context.getString(color).substring(3) return context.getString(color).substring(3)
} }
fun showLicense(context: Context?, component: SoftwareComponent): Disposable {
return showLicense(context, component.license) {
setPositiveButton(R.string.dismiss) { dialog, _ ->
dialog.dismiss()
}
setNeutralButton(R.string.open_website_license) { _, _ ->
ShareUtils.openUrlInApp(context!!, component.link)
}
}
}
fun showLicense(context: Context?, license: License) = showLicense(context, license) {
setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
}
private fun showLicense(
context: Context?,
license: License,
block: AlertDialog.Builder.() -> AlertDialog.Builder
): Disposable {
return if (context == null) {
Disposable.empty()
} else {
Observable.fromCallable { getFormattedLicense(context, license) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { formattedLicense ->
val webViewData =
Base64.encodeToString(formattedLicense.toByteArray(), Base64.NO_PADDING)
val webView = WebView(context)
webView.loadData(webViewData, "text/html; charset=UTF-8", "base64")
Localization.assureCorrectAppLanguage(context)
AlertDialog.Builder(context)
.setTitle(license.name)
.setView(webView)
.block()
.show()
}
}
}