11package org.schabi.newpipe.about
22
33import android.os.Bundle
4+ import android.util.Base64
45import android.view.LayoutInflater
56import android.view.View
67import android.view.ViewGroup
8+ import android.webkit.WebView
9+ import androidx.appcompat.app.AlertDialog
710import androidx.core.os.bundleOf
811import androidx.fragment.app.Fragment
12+ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
13+ import io.reactivex.rxjava3.core.Observable
914import io.reactivex.rxjava3.disposables.CompositeDisposable
15+ import io.reactivex.rxjava3.disposables.Disposable
16+ import io.reactivex.rxjava3.schedulers.Schedulers
17+ import org.schabi.newpipe.BuildConfig
1018import org.schabi.newpipe.R
1119import org.schabi.newpipe.databinding.FragmentLicensesBinding
1220import org.schabi.newpipe.databinding.ItemSoftwareComponentBinding
21+ import org.schabi.newpipe.util.Localization
22+ import org.schabi.newpipe.util.external_communication.ShareUtils
1323
1424/* *
1525 * Fragment containing the software licenses.
1626 */
1727class LicenseFragment : Fragment () {
1828 private lateinit var softwareComponents: Array <SoftwareComponent >
19- private var activeLicense : License ? = null
29+ private var activeSoftwareComponent : SoftwareComponent ? = null
2030 private val compositeDisposable = CompositeDisposable ()
2131
2232 override fun onCreate (savedInstanceState : Bundle ? ) {
2333 super .onCreate(savedInstanceState)
2434 softwareComponents = arguments?.getParcelableArray(ARG_COMPONENTS ) as Array <SoftwareComponent >
25- activeLicense = savedInstanceState?.getSerializable(LICENSE_KEY ) as ? License
35+ activeSoftwareComponent = savedInstanceState?.getSerializable(SOFTWARE_COMPONENT_KEY ) as ? SoftwareComponent
2636 // Sort components by name
2737 softwareComponents.sortBy { it.name }
2838 }
@@ -39,9 +49,8 @@ class LicenseFragment : Fragment() {
3949 ): View {
4050 val binding = FragmentLicensesBinding .inflate(inflater, container, false )
4151 binding.licensesAppReadLicense.setOnClickListener {
42- activeLicense = StandardLicenses .GPL3
4352 compositeDisposable.add(
44- showLicense(activity, StandardLicenses . GPL3 )
53+ showLicense(NEWPIPE_SOFTWARE_COMPONENT )
4554 )
4655 }
4756 for (component in softwareComponents) {
@@ -57,26 +66,70 @@ class LicenseFragment : Fragment() {
5766 val root: View = componentBinding.root
5867 root.tag = component
5968 root.setOnClickListener {
60- activeLicense = component.license
6169 compositeDisposable.add(
62- showLicense(activity, component)
70+ showLicense(component)
6371 )
6472 }
6573 binding.licensesSoftwareComponents.addView(root)
6674 registerForContextMenu(root)
6775 }
68- activeLicense ?.let { compositeDisposable.add(showLicense(activity, it)) }
76+ activeSoftwareComponent ?.let { compositeDisposable.add(showLicense(it)) }
6977 return binding.root
7078 }
7179
7280 override fun onSaveInstanceState (savedInstanceState : Bundle ) {
7381 super .onSaveInstanceState(savedInstanceState)
74- activeLicense?.let { savedInstanceState.putSerializable(LICENSE_KEY , it) }
82+ activeSoftwareComponent?.let { savedInstanceState.putSerializable(SOFTWARE_COMPONENT_KEY , it) }
83+ }
84+
85+ private fun showLicense (
86+ softwareComponent : SoftwareComponent
87+ ): Disposable {
88+ return if (context == null ) {
89+ Disposable .empty()
90+ } else {
91+ val context = requireContext()
92+ activeSoftwareComponent = softwareComponent
93+ Observable .fromCallable { getFormattedLicense(context, softwareComponent.license) }
94+ .subscribeOn(Schedulers .io())
95+ .observeOn(AndroidSchedulers .mainThread())
96+ .subscribe { formattedLicense ->
97+ val webViewData = Base64 .encodeToString(
98+ formattedLicense.toByteArray(), Base64 .NO_PADDING
99+ )
100+ val webView = WebView (context)
101+ webView.loadData(webViewData, " text/html; charset=UTF-8" , " base64" )
102+
103+ Localization .assureCorrectAppLanguage(context)
104+ val builder = AlertDialog .Builder (requireContext())
105+ .setTitle(softwareComponent.name)
106+ .setView(webView)
107+ .setOnCancelListener { activeSoftwareComponent = null }
108+ .setOnDismissListener { activeSoftwareComponent = null }
109+ .setPositiveButton(R .string.done) { dialog, _ -> dialog.dismiss() }
110+
111+ if (softwareComponent != NEWPIPE_SOFTWARE_COMPONENT ) {
112+ builder.setNeutralButton(R .string.open_website_license) { _, _ ->
113+ ShareUtils .openUrlInApp(requireContext(), softwareComponent.link)
114+ }
115+ }
116+
117+ builder.show()
118+ }
119+ }
75120 }
76121
77122 companion object {
78123 private const val ARG_COMPONENTS = " components"
79- private const val LICENSE_KEY = " ACTIVE_LICENSE"
124+ private const val SOFTWARE_COMPONENT_KEY = " ACTIVE_SOFTWARE_COMPONENT"
125+ private val NEWPIPE_SOFTWARE_COMPONENT = SoftwareComponent (
126+ " NewPipe" ,
127+ " 2014-2023" ,
128+ " Team NewPipe" ,
129+ " https://newpipe.net/" ,
130+ StandardLicenses .GPL3 ,
131+ BuildConfig .VERSION_NAME
132+ )
80133 fun newInstance (softwareComponents : Array <SoftwareComponent >): LicenseFragment {
81134 val fragment = LicenseFragment ()
82135 fragment.arguments = bundleOf(ARG_COMPONENTS to softwareComponents)
0 commit comments