mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 16:30:31 +05:30
settings refactor
This commit is contained in:
parent
60ea36c0db
commit
7ba9ecf7bd
@ -8,6 +8,7 @@
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
@ -18,14 +19,12 @@
|
||||
android:name=".MyApp"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:largeHeap="true"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
>
|
||||
android:requestLegacyExternalStorage="true">
|
||||
<activity
|
||||
android:name=".Player"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
||||
android:configChanges="orientation|screenSize"
|
||||
/>
|
||||
android:configChanges="orientation|screenSize" />
|
||||
<activity
|
||||
android:name=".SettingsActivity"
|
||||
android:label="@string/settings" />
|
||||
@ -35,8 +34,7 @@
|
||||
android:supportsPictureInPicture="true"
|
||||
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
|
||||
android:hardwareAccelerated="true"
|
||||
android:screenOrientation="userPortrait"
|
||||
>
|
||||
android:screenOrientation="userPortrait">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
@ -165,8 +163,7 @@
|
||||
<activity
|
||||
android:name=".RouterActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleInstance"
|
||||
>
|
||||
android:launchMode="singleInstance">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@ -175,8 +172,10 @@
|
||||
<!-- youtube -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
<data android:host="youtube.com" />
|
||||
@ -254,8 +253,10 @@
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
<data android:host="piped.tokhmi.xyz" />
|
||||
|
51
app/src/main/assets/gpl3.html
vendored
51
app/src/main/assets/gpl3.html
vendored
@ -6,7 +6,8 @@
|
||||
<p style="text-align: center;">Version 3, 29 June 2007</p>
|
||||
|
||||
<p>Copyright © 2007 Free Software Foundation, Inc.
|
||||
<<a href="http://fsf.org/">http://fsf.org/</a>></p><p>
|
||||
<<a href="http://fsf.org/">http://fsf.org/</a>></p>
|
||||
<p>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.</p>
|
||||
|
||||
@ -218,12 +219,14 @@
|
||||
|
||||
<ul>
|
||||
<li>a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.</li>
|
||||
it, and giving a relevant date.
|
||||
</li>
|
||||
|
||||
<li>b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
“keep intact all notices”.</li>
|
||||
“keep intact all notices”.
|
||||
</li>
|
||||
|
||||
<li>c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
@ -231,12 +234,14 @@
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.</li>
|
||||
invalidate such permission if you have separately received it.
|
||||
</li>
|
||||
|
||||
<li>d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.</li>
|
||||
work need not make them do so.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>A compilation of a covered work with other separate and independent
|
||||
@ -260,7 +265,8 @@
|
||||
<li>a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.</li>
|
||||
customarily used for software interchange.
|
||||
</li>
|
||||
|
||||
<li>b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
@ -272,13 +278,15 @@
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.</li>
|
||||
Corresponding Source from a network server at no charge.
|
||||
</li>
|
||||
|
||||
<li>c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.</li>
|
||||
with subsection 6b.
|
||||
</li>
|
||||
|
||||
<li>d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
@ -291,12 +299,14 @@
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.</li>
|
||||
available for as long as needed to satisfy these requirements.
|
||||
</li>
|
||||
|
||||
<li>e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.</li>
|
||||
charge under subsection 6d.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>A separable portion of the object code, whose source code is excluded
|
||||
@ -373,27 +383,33 @@
|
||||
|
||||
<ul>
|
||||
<li>a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or</li>
|
||||
terms of sections 15 and 16 of this License; or
|
||||
</li>
|
||||
|
||||
<li>b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or</li>
|
||||
Notices displayed by works containing it; or
|
||||
</li>
|
||||
|
||||
<li>c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or</li>
|
||||
reasonable ways as different from the original version; or
|
||||
</li>
|
||||
|
||||
<li>d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or</li>
|
||||
authors of the material; or
|
||||
</li>
|
||||
|
||||
<li>e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or</li>
|
||||
trade names, trademarks, or service marks; or
|
||||
</li>
|
||||
|
||||
<li>f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.</li>
|
||||
those licensors and authors.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>All other non-permissive additional terms are considered “further
|
||||
@ -629,4 +645,5 @@
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.</p>
|
||||
|
||||
</body></html>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -238,7 +238,8 @@ class DownloadService : Service() {
|
||||
override fun onDestroy() {
|
||||
try {
|
||||
unregisterReceiver(onDownloadComplete)
|
||||
} catch (e: Exception) { }
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
|
||||
IS_DOWNLOAD_RUNNING = false
|
||||
Log.d(TAG, "dl finished!")
|
||||
|
@ -16,8 +16,8 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.github.libretube.adapters.TrendingAdapter
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import java.io.IOException
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
class Home : Fragment() {
|
||||
|
||||
|
@ -17,8 +17,8 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.github.libretube.adapters.PlaylistsAdapter
|
||||
import com.github.libretube.dialogs.CreatePlaylistDialog
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import java.io.IOException
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
class Library : Fragment() {
|
||||
|
||||
|
@ -33,6 +33,7 @@ import androidx.navigation.ui.setupWithNavController
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.github.libretube.fragments.PlayerFragment
|
||||
import com.github.libretube.fragments.isFullScreen
|
||||
import com.github.libretube.preferences.SponsorBlockSettings
|
||||
import com.github.libretube.util.CronetHelper
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import com.github.libretube.util.updateLanguage
|
||||
|
@ -1,54 +1,20 @@
|
||||
package com.github.libretube
|
||||
|
||||
import android.Manifest
|
||||
import android.app.NotificationManager
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.github.libretube.dialogs.LoginDialog
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import com.github.libretube.util.changeIcon
|
||||
import com.github.libretube.util.checkUpdate
|
||||
import com.github.libretube.preferences.SettingsFragment
|
||||
import com.github.libretube.util.restartMainActivity
|
||||
import com.github.libretube.util.updateTheme
|
||||
import com.google.android.material.color.DynamicColors
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipInputStream
|
||||
import org.json.JSONObject
|
||||
import org.json.JSONTokener
|
||||
import retrofit2.HttpException
|
||||
|
||||
private var isCurrentViewMainSettings = true
|
||||
private var requireMainActivityRestart = false
|
||||
var isCurrentViewMainSettings = true
|
||||
var requireMainActivityRestart = false
|
||||
|
||||
class SettingsActivity :
|
||||
AppCompatActivity(),
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
class SettingsActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
DynamicColors.applyToActivityIfAvailable(this)
|
||||
@ -69,355 +35,18 @@ class SettingsActivity :
|
||||
.replace(R.id.settings, SettingsFragment())
|
||||
.commit()
|
||||
}
|
||||
|
||||
PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.registerOnSharedPreferenceChangeListener(this)
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(
|
||||
sharedPreferences: SharedPreferences?,
|
||||
rootKey: String?
|
||||
) {
|
||||
}
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat() {
|
||||
val TAG = "Settings"
|
||||
|
||||
companion object {
|
||||
lateinit var getContent: ActivityResultLauncher<String>
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
getContent =
|
||||
registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
|
||||
if (uri != null) {
|
||||
try {
|
||||
// Open a specific media item using ParcelFileDescriptor.
|
||||
val resolver: ContentResolver =
|
||||
requireActivity()
|
||||
.contentResolver
|
||||
|
||||
// "rw" for read-and-write;
|
||||
// "rwt" for truncating or overwriting existing file contents.
|
||||
// val readOnlyMode = "r"
|
||||
// uri - I have got from onActivityResult
|
||||
val type = resolver.getType(uri)
|
||||
|
||||
var inputStream: InputStream? = resolver.openInputStream(uri)
|
||||
val channels = ArrayList<String>()
|
||||
if (type == "application/json") {
|
||||
val json = inputStream?.bufferedReader()?.readLines()?.get(0)
|
||||
val jsonObject = JSONTokener(json).nextValue() as JSONObject
|
||||
Log.e(TAG, jsonObject.getJSONArray("subscriptions").toString())
|
||||
for (
|
||||
i in 0 until jsonObject.getJSONArray("subscriptions")
|
||||
.length()
|
||||
) {
|
||||
var url =
|
||||
jsonObject.getJSONArray("subscriptions").getJSONObject(i)
|
||||
.getString("url")
|
||||
url = url.replace("https://www.youtube.com/channel/", "")
|
||||
Log.e(TAG, url)
|
||||
channels.add(url)
|
||||
}
|
||||
} else {
|
||||
if (type == "application/zip") {
|
||||
val zis = ZipInputStream(inputStream)
|
||||
var entry: ZipEntry? = zis.nextEntry
|
||||
while (entry != null) {
|
||||
if (entry.name.endsWith(".csv")) {
|
||||
inputStream = zis
|
||||
break
|
||||
}
|
||||
entry = zis.nextEntry
|
||||
}
|
||||
}
|
||||
|
||||
inputStream?.bufferedReader()?.readLines()?.forEach {
|
||||
if (it.isNotBlank()) {
|
||||
val channelId = it.substringBefore(",")
|
||||
if (channelId.length == 24)
|
||||
channels.add(channelId)
|
||||
}
|
||||
}
|
||||
}
|
||||
inputStream?.close()
|
||||
|
||||
subscribe(channels)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, e.toString())
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.error,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onCreate(savedInstanceState)
|
||||
try {
|
||||
checkUpdate(childFragmentManager)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.settings, rootKey)
|
||||
|
||||
val region = findPreference<Preference>("region")
|
||||
region?.setOnPreferenceChangeListener { _, _ ->
|
||||
requireMainActivityRestart = true
|
||||
true
|
||||
}
|
||||
|
||||
val language = findPreference<ListPreference>("language")
|
||||
language?.setOnPreferenceChangeListener { _, _ ->
|
||||
restartMainActivity(requireContext())
|
||||
true
|
||||
}
|
||||
|
||||
val instance = findPreference<ListPreference>("instance")
|
||||
fetchInstance()
|
||||
instance?.setOnPreferenceChangeListener { _, newValue ->
|
||||
RetrofitInstance.url = newValue.toString()
|
||||
RetrofitInstance.lazyMgr.reset()
|
||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||
if (sharedPref?.getString("token", "") != "") {
|
||||
with(sharedPref!!.edit()) {
|
||||
putString("token", "")
|
||||
apply()
|
||||
}
|
||||
Toast.makeText(context, R.string.loggedout, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
val login = findPreference<Preference>("login_register")
|
||||
login?.setOnPreferenceClickListener {
|
||||
requireMainActivityRestart = true
|
||||
val newFragment = LoginDialog()
|
||||
newFragment.show(childFragmentManager, "Login")
|
||||
true
|
||||
}
|
||||
|
||||
val sponsorblock = findPreference<Preference>("sponsorblock")
|
||||
sponsorblock?.setOnPreferenceClickListener {
|
||||
isCurrentViewMainSettings = false
|
||||
val newFragment = SponsorBlockSettings()
|
||||
parentFragmentManager.beginTransaction()
|
||||
.replace(R.id.settings, newFragment)
|
||||
.commitNow()
|
||||
true
|
||||
}
|
||||
|
||||
val importFromYt = findPreference<Preference>("import_from_yt")
|
||||
importFromYt?.setOnPreferenceClickListener {
|
||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||
val token = sharedPref?.getString("token", "")!!
|
||||
// check StorageAccess
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
Log.d("myz", "" + Build.VERSION.SDK_INT)
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
this.requireContext(),
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
)
|
||||
!= PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
ActivityCompat.requestPermissions(
|
||||
this.requireActivity(),
|
||||
arrayOf(
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.MANAGE_EXTERNAL_STORAGE
|
||||
),
|
||||
1
|
||||
) // permission request code is just an int
|
||||
} else if (token != "") {
|
||||
getContent.launch("*/*")
|
||||
} else {
|
||||
Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
} else {
|
||||
if (ActivityCompat.checkSelfPermission(
|
||||
requireContext(),
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) != PackageManager.PERMISSION_GRANTED ||
|
||||
ActivityCompat.checkSelfPermission(
|
||||
requireContext(),
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
) != PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
ActivityCompat.requestPermissions(
|
||||
this.requireActivity(),
|
||||
arrayOf(
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
),
|
||||
1
|
||||
)
|
||||
} else if (token != "") {
|
||||
getContent.launch("*/*")
|
||||
} else {
|
||||
Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
val themeToggle = findPreference<ListPreference>("theme_togglee")
|
||||
themeToggle?.setOnPreferenceChangeListener { _, _ ->
|
||||
val refresh = Intent(context, SettingsActivity::class.java)
|
||||
startActivity(refresh)
|
||||
requireMainActivityRestart = true
|
||||
true
|
||||
}
|
||||
|
||||
val accentColor = findPreference<Preference>("accent_color")
|
||||
accentColor?.setOnPreferenceChangeListener { _, _ ->
|
||||
requireMainActivityRestart = true
|
||||
val refresh = Intent(context, SettingsActivity::class.java)
|
||||
startActivity(refresh)
|
||||
true
|
||||
}
|
||||
|
||||
val iconChange = findPreference<ListPreference>("icon_change")
|
||||
iconChange?.setOnPreferenceChangeListener { _, newValue ->
|
||||
changeIcon(requireContext(), newValue.toString())
|
||||
true
|
||||
}
|
||||
|
||||
val gridColumns = findPreference<ListPreference>("grid")
|
||||
gridColumns?.setOnPreferenceChangeListener { _, _ ->
|
||||
requireMainActivityRestart = true
|
||||
true
|
||||
}
|
||||
|
||||
val clearHistory = findPreference<Preference>("clear_history")
|
||||
clearHistory?.setOnPreferenceClickListener {
|
||||
val sharedPreferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
sharedPreferences.edit().remove("search_history").commit()
|
||||
true
|
||||
}
|
||||
|
||||
val about = findPreference<Preference>("about")
|
||||
about?.setOnPreferenceClickListener {
|
||||
val uri = Uri.parse("https://libre-tube.github.io/")
|
||||
val intent = Intent(Intent.ACTION_VIEW).setData(uri)
|
||||
startActivity(intent)
|
||||
true
|
||||
}
|
||||
|
||||
val license = findPreference<Preference>("license")
|
||||
license?.setOnPreferenceClickListener {
|
||||
val licenseString = view?.context?.assets!!.open("gpl3.html").bufferedReader().use {
|
||||
it.readText()
|
||||
}
|
||||
val licenseHtml = if (Build.VERSION.SDK_INT >= 24) {
|
||||
Html.fromHtml(licenseString, 1)
|
||||
} else {
|
||||
Html.fromHtml(licenseString)
|
||||
}
|
||||
MaterialAlertDialogBuilder(view?.context!!)
|
||||
.setPositiveButton(
|
||||
getString(R.string.okay),
|
||||
DialogInterface.OnClickListener { _, _ -> }
|
||||
)
|
||||
.setMessage(licenseHtml)
|
||||
.create()
|
||||
.show()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchInstance() {
|
||||
lifecycleScope.launchWhenCreated {
|
||||
val response = try {
|
||||
RetrofitInstance.api.getInstances("https://instances.tokhmi.xyz/")
|
||||
} catch (e: IOException) {
|
||||
println(e)
|
||||
Log.e("settings", "IOException, you might not have internet connection")
|
||||
return@launchWhenCreated
|
||||
} catch (e: HttpException) {
|
||||
Log.e("settings", "HttpException, unexpected response $e")
|
||||
return@launchWhenCreated
|
||||
} catch (e: Exception) {
|
||||
Log.e("settings", e.toString())
|
||||
return@launchWhenCreated
|
||||
}
|
||||
val listEntries: MutableList<String> = ArrayList()
|
||||
val listEntryValues: MutableList<String> = ArrayList()
|
||||
for (item in response) {
|
||||
listEntries.add(item.name!!)
|
||||
listEntryValues.add(item.api_url!!)
|
||||
}
|
||||
val entries = listEntries.toTypedArray<CharSequence>()
|
||||
val entryValues = listEntryValues.toTypedArray<CharSequence>()
|
||||
runOnUiThread {
|
||||
val instance = findPreference<ListPreference>("instance")
|
||||
instance?.entries = entries
|
||||
instance?.entryValues = entryValues
|
||||
instance?.summaryProvider =
|
||||
Preference.SummaryProvider<ListPreference> { preference ->
|
||||
val text = preference.entry
|
||||
if (TextUtils.isEmpty(text)) {
|
||||
"kavin.rocks (Official)"
|
||||
} else {
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Fragment?.runOnUiThread(action: () -> Unit) {
|
||||
this ?: return
|
||||
if (!isAdded) return // Fragment not attached to an Activity
|
||||
activity?.runOnUiThread(action)
|
||||
}
|
||||
|
||||
private fun subscribe(channels: List<String>) {
|
||||
fun run() {
|
||||
lifecycleScope.launchWhenCreated {
|
||||
val response = try {
|
||||
val sharedPref =
|
||||
context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||
RetrofitInstance.api.importSubscriptions(
|
||||
false,
|
||||
sharedPref?.getString("token", "")!!,
|
||||
channels
|
||||
)
|
||||
} catch (e: IOException) {
|
||||
Log.e(TAG, "IOException, you might not have internet connection")
|
||||
return@launchWhenCreated
|
||||
} catch (e: HttpException) {
|
||||
Log.e(TAG, "HttpException, unexpected response$e")
|
||||
return@launchWhenCreated
|
||||
}
|
||||
if (response.message == "ok") {
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.importsuccess,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
run()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (isCurrentViewMainSettings) {
|
||||
PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.unregisterOnSharedPreferenceChangeListener(this)
|
||||
if (requireMainActivityRestart) {
|
||||
requireMainActivityRestart = false
|
||||
// kill player notification
|
||||
val nManager = this.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
||||
val nManager =
|
||||
this.getSystemService(AppCompatActivity.NOTIFICATION_SERVICE) as NotificationManager
|
||||
nManager.cancelAll()
|
||||
restartMainActivity(this)
|
||||
finishAffinity()
|
||||
ActivityCompat.finishAffinity(this)
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
|
@ -26,8 +26,8 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.github.libretube.adapters.SubscriptionAdapter
|
||||
import com.github.libretube.adapters.SubscriptionChannelAdapter
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import java.io.IOException
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
class Subscriptions : Fragment() {
|
||||
val TAG = "SubFragment"
|
||||
|
@ -20,10 +20,10 @@ import com.github.libretube.obj.PlaylistId
|
||||
import com.github.libretube.obj.StreamItem
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import com.squareup.picasso.Picasso
|
||||
import java.io.IOException
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
class PlaylistAdapter(
|
||||
private val videoFeed: MutableList<StreamItem>,
|
||||
|
@ -17,10 +17,10 @@ import com.github.libretube.obj.Playlists
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.squareup.picasso.Picasso
|
||||
import java.io.IOException
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
class PlaylistsAdapter(
|
||||
private val playlists: MutableList<Playlists>,
|
||||
|
@ -15,11 +15,11 @@ import com.github.libretube.obj.Subscribe
|
||||
import com.github.libretube.obj.Subscription
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import com.squareup.picasso.Picasso
|
||||
import java.io.IOException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
class SubscriptionChannelAdapter(private val subscriptions: MutableList<Subscription>) :
|
||||
RecyclerView.Adapter<SubscriptionChannelViewHolder>() {
|
||||
|
@ -19,8 +19,8 @@ import com.github.libretube.R
|
||||
import com.github.libretube.obj.PlaylistId
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import java.io.IOException
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
class AddtoPlaylistDialog : DialogFragment() {
|
||||
private val TAG = "AddToPlaylistDialog"
|
||||
|
@ -19,8 +19,8 @@ import com.github.libretube.obj.Playlists
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import java.io.IOException
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
class CreatePlaylistDialog : DialogFragment() {
|
||||
val TAG = "CreatePlaylistDialog"
|
||||
|
@ -17,8 +17,8 @@ import com.github.libretube.R
|
||||
import com.github.libretube.obj.Login
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import java.io.IOException
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
class LoginDialog : DialogFragment() {
|
||||
private val TAG = "LoginDialog"
|
||||
|
@ -22,8 +22,8 @@ import com.github.libretube.obj.Subscribe
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.squareup.picasso.Picasso
|
||||
import java.io.IOException
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
class ChannelFragment : Fragment() {
|
||||
|
||||
|
@ -43,7 +43,6 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.IS_DOWNLOAD_RUNNING
|
||||
import com.github.libretube.MainActivity
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.SponsorBlockSettings
|
||||
import com.github.libretube.adapters.CommentsAdapter
|
||||
import com.github.libretube.adapters.TrendingAdapter
|
||||
import com.github.libretube.dialogs.AddtoPlaylistDialog
|
||||
@ -56,6 +55,7 @@ import com.github.libretube.obj.Segment
|
||||
import com.github.libretube.obj.Segments
|
||||
import com.github.libretube.obj.Streams
|
||||
import com.github.libretube.obj.Subscribe
|
||||
import com.github.libretube.preferences.SponsorBlockSettings
|
||||
import com.github.libretube.util.CronetHelper
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import com.google.android.exoplayer2.C
|
||||
@ -82,11 +82,11 @@ import com.google.android.exoplayer2.util.RepeatModeUtil
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.squareup.picasso.Picasso
|
||||
import org.chromium.net.CronetEngine
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.math.abs
|
||||
import org.chromium.net.CronetEngine
|
||||
import retrofit2.HttpException
|
||||
|
||||
var isFullScreen = false
|
||||
|
||||
|
@ -15,8 +15,8 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.adapters.PlaylistAdapter
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import java.io.IOException
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
class PlaylistFragment : Fragment() {
|
||||
private var playlist_id: String? = null
|
||||
|
@ -30,11 +30,11 @@ import com.github.libretube.adapters.SearchHistoryAdapter
|
||||
import com.github.libretube.hideKeyboard
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import java.io.IOException
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
class SearchFragment : Fragment() {
|
||||
private val TAG = "SearchFragment"
|
||||
|
@ -0,0 +1,46 @@
|
||||
package com.github.libretube.preferences
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.SettingsActivity
|
||||
import com.github.libretube.requireMainActivityRestart
|
||||
import com.github.libretube.util.changeIcon
|
||||
|
||||
class AppearanceSettings : PreferenceFragmentCompat() {
|
||||
private val TAG = "CustomizationSettings"
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.appearance_settings, rootKey)
|
||||
|
||||
val themeToggle = findPreference<ListPreference>("theme_togglee")
|
||||
themeToggle?.setOnPreferenceChangeListener { _, _ ->
|
||||
val refresh = Intent(context, SettingsActivity::class.java)
|
||||
startActivity(refresh)
|
||||
requireMainActivityRestart = true
|
||||
true
|
||||
}
|
||||
|
||||
val accentColor = findPreference<Preference>("accent_color")
|
||||
accentColor?.setOnPreferenceChangeListener { _, _ ->
|
||||
requireMainActivityRestart = true
|
||||
val refresh = Intent(context, SettingsActivity::class.java)
|
||||
startActivity(refresh)
|
||||
true
|
||||
}
|
||||
|
||||
val iconChange = findPreference<ListPreference>("icon_change")
|
||||
iconChange?.setOnPreferenceChangeListener { _, newValue ->
|
||||
changeIcon(requireContext(), newValue.toString())
|
||||
true
|
||||
}
|
||||
|
||||
val gridColumns = findPreference<ListPreference>("grid")
|
||||
gridColumns?.setOnPreferenceChangeListener { _, _ ->
|
||||
requireMainActivityRestart = true
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.github.libretube.preferences
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.github.libretube.R
|
||||
|
||||
class HistorySettings : PreferenceFragmentCompat() {
|
||||
private val TAG = "HistorySettings"
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.history_settings, rootKey)
|
||||
|
||||
val clearHistory = findPreference<Preference>("clear_history")
|
||||
clearHistory?.setOnPreferenceClickListener {
|
||||
val sharedPreferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
sharedPreferences.edit().remove("search_history").commit()
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,343 @@
|
||||
package com.github.libretube.preferences
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.dialogs.LoginDialog
|
||||
import com.github.libretube.isCurrentViewMainSettings
|
||||
import com.github.libretube.requireMainActivityRestart
|
||||
import com.github.libretube.util.RetrofitInstance
|
||||
import com.github.libretube.util.checkUpdate
|
||||
import com.github.libretube.util.restartMainActivity
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.json.JSONObject
|
||||
import org.json.JSONTokener
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipInputStream
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat() {
|
||||
val TAG = "Settings"
|
||||
|
||||
companion object {
|
||||
lateinit var getContent: ActivityResultLauncher<String>
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
getContent =
|
||||
registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
|
||||
if (uri != null) {
|
||||
try {
|
||||
// Open a specific media item using ParcelFileDescriptor.
|
||||
val resolver: ContentResolver =
|
||||
requireActivity()
|
||||
.contentResolver
|
||||
|
||||
// "rw" for read-and-write;
|
||||
// "rwt" for truncating or overwriting existing file contents.
|
||||
// val readOnlyMode = "r"
|
||||
// uri - I have got from onActivityResult
|
||||
val type = resolver.getType(uri)
|
||||
|
||||
var inputStream: InputStream? = resolver.openInputStream(uri)
|
||||
val channels = ArrayList<String>()
|
||||
if (type == "application/json") {
|
||||
val json = inputStream?.bufferedReader()?.readLines()?.get(0)
|
||||
val jsonObject = JSONTokener(json).nextValue() as JSONObject
|
||||
Log.e(TAG, jsonObject.getJSONArray("subscriptions").toString())
|
||||
for (
|
||||
i in 0 until jsonObject.getJSONArray("subscriptions")
|
||||
.length()
|
||||
) {
|
||||
var url =
|
||||
jsonObject.getJSONArray("subscriptions").getJSONObject(i)
|
||||
.getString("url")
|
||||
url = url.replace("https://www.youtube.com/channel/", "")
|
||||
Log.e(TAG, url)
|
||||
channels.add(url)
|
||||
}
|
||||
} else {
|
||||
if (type == "application/zip") {
|
||||
val zis = ZipInputStream(inputStream)
|
||||
var entry: ZipEntry? = zis.nextEntry
|
||||
while (entry != null) {
|
||||
if (entry.name.endsWith(".csv")) {
|
||||
inputStream = zis
|
||||
break
|
||||
}
|
||||
entry = zis.nextEntry
|
||||
}
|
||||
}
|
||||
|
||||
inputStream?.bufferedReader()?.readLines()?.forEach {
|
||||
if (it.isNotBlank()) {
|
||||
val channelId = it.substringBefore(",")
|
||||
if (channelId.length == 24)
|
||||
channels.add(channelId)
|
||||
}
|
||||
}
|
||||
}
|
||||
inputStream?.close()
|
||||
|
||||
subscribe(channels)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, e.toString())
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.error,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onCreate(savedInstanceState)
|
||||
try {
|
||||
checkUpdate(childFragmentManager)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.settings, rootKey)
|
||||
|
||||
val region = findPreference<Preference>("region")
|
||||
region?.setOnPreferenceChangeListener { _, _ ->
|
||||
requireMainActivityRestart = true
|
||||
true
|
||||
}
|
||||
|
||||
val language = findPreference<ListPreference>("language")
|
||||
language?.setOnPreferenceChangeListener { _, _ ->
|
||||
restartMainActivity(requireContext())
|
||||
true
|
||||
}
|
||||
|
||||
val instance = findPreference<ListPreference>("instance")
|
||||
fetchInstance()
|
||||
instance?.setOnPreferenceChangeListener { _, newValue ->
|
||||
RetrofitInstance.url = newValue.toString()
|
||||
RetrofitInstance.lazyMgr.reset()
|
||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||
if (sharedPref?.getString("token", "") != "") {
|
||||
with(sharedPref!!.edit()) {
|
||||
putString("token", "")
|
||||
apply()
|
||||
}
|
||||
Toast.makeText(context, R.string.loggedout, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
val login = findPreference<Preference>("login_register")
|
||||
login?.setOnPreferenceClickListener {
|
||||
requireMainActivityRestart = true
|
||||
val newFragment = LoginDialog()
|
||||
newFragment.show(childFragmentManager, "Login")
|
||||
true
|
||||
}
|
||||
|
||||
val sponsorblock = findPreference<Preference>("sponsorblock")
|
||||
sponsorblock?.setOnPreferenceClickListener {
|
||||
val newFragment = SponsorBlockSettings()
|
||||
navigateSettings(newFragment)
|
||||
true
|
||||
}
|
||||
|
||||
val history = findPreference<Preference>("history")
|
||||
history?.setOnPreferenceClickListener {
|
||||
val newFragment = HistorySettings()
|
||||
navigateSettings(newFragment)
|
||||
true
|
||||
}
|
||||
|
||||
val appearance = findPreference<Preference>("appearance")
|
||||
appearance?.setOnPreferenceClickListener {
|
||||
val newFragment = AppearanceSettings()
|
||||
navigateSettings(newFragment)
|
||||
true
|
||||
}
|
||||
|
||||
val importFromYt = findPreference<Preference>("import_from_yt")
|
||||
importFromYt?.setOnPreferenceClickListener {
|
||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||
val token = sharedPref?.getString("token", "")!!
|
||||
// check StorageAccess
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
Log.d("myz", "" + Build.VERSION.SDK_INT)
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
this.requireContext(),
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
)
|
||||
!= PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
ActivityCompat.requestPermissions(
|
||||
this.requireActivity(),
|
||||
arrayOf(
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.MANAGE_EXTERNAL_STORAGE
|
||||
),
|
||||
1
|
||||
) // permission request code is just an int
|
||||
} else if (token != "") {
|
||||
getContent.launch("*/*")
|
||||
} else {
|
||||
Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
} else {
|
||||
if (ActivityCompat.checkSelfPermission(
|
||||
requireContext(),
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) != PackageManager.PERMISSION_GRANTED ||
|
||||
ActivityCompat.checkSelfPermission(
|
||||
requireContext(),
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
) != PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
ActivityCompat.requestPermissions(
|
||||
this.requireActivity(),
|
||||
arrayOf(
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
),
|
||||
1
|
||||
)
|
||||
} else if (token != "") {
|
||||
getContent.launch("*/*")
|
||||
} else {
|
||||
Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
val about = findPreference<Preference>("about")
|
||||
about?.setOnPreferenceClickListener {
|
||||
val uri = Uri.parse("https://libre-tube.github.io/")
|
||||
val intent = Intent(Intent.ACTION_VIEW).setData(uri)
|
||||
startActivity(intent)
|
||||
true
|
||||
}
|
||||
|
||||
val license = findPreference<Preference>("license")
|
||||
license?.setOnPreferenceClickListener {
|
||||
val licenseString = view?.context?.assets!!
|
||||
.open("gpl3.html").bufferedReader().use {
|
||||
it.readText()
|
||||
}
|
||||
val licenseHtml = if (Build.VERSION.SDK_INT >= 24) Html.fromHtml(licenseString, 1)
|
||||
else Html.fromHtml(licenseString)
|
||||
|
||||
MaterialAlertDialogBuilder(view?.context!!)
|
||||
.setPositiveButton(getString(R.string.okay)) { _, _ -> }
|
||||
.setMessage(licenseHtml)
|
||||
.create()
|
||||
.show()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateSettings(newFragment: PreferenceFragmentCompat) {
|
||||
isCurrentViewMainSettings = false
|
||||
parentFragmentManager.beginTransaction()
|
||||
.replace(R.id.settings, newFragment)
|
||||
.commitNow()
|
||||
}
|
||||
|
||||
private fun fetchInstance() {
|
||||
lifecycleScope.launchWhenCreated {
|
||||
val response = try {
|
||||
RetrofitInstance.api.getInstances("https://instances.tokhmi.xyz/")
|
||||
} catch (e: IOException) {
|
||||
println(e)
|
||||
Log.e("settings", "IOException, you might not have internet connection")
|
||||
return@launchWhenCreated
|
||||
} catch (e: HttpException) {
|
||||
Log.e("settings", "HttpException, unexpected response $e")
|
||||
return@launchWhenCreated
|
||||
} catch (e: Exception) {
|
||||
Log.e("settings", e.toString())
|
||||
return@launchWhenCreated
|
||||
}
|
||||
val listEntries: MutableList<String> = ArrayList()
|
||||
val listEntryValues: MutableList<String> = ArrayList()
|
||||
for (item in response) {
|
||||
listEntries.add(item.name!!)
|
||||
listEntryValues.add(item.api_url!!)
|
||||
}
|
||||
val entries = listEntries.toTypedArray<CharSequence>()
|
||||
val entryValues = listEntryValues.toTypedArray<CharSequence>()
|
||||
runOnUiThread {
|
||||
val instance = findPreference<ListPreference>("instance")
|
||||
instance?.entries = entries
|
||||
instance?.entryValues = entryValues
|
||||
instance?.summaryProvider =
|
||||
Preference.SummaryProvider<ListPreference> { preference ->
|
||||
val text = preference.entry
|
||||
if (TextUtils.isEmpty(text)) {
|
||||
"kavin.rocks (Official)"
|
||||
} else {
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Fragment?.runOnUiThread(action: () -> Unit) {
|
||||
this ?: return
|
||||
if (!isAdded) return // Fragment not attached to an Activity
|
||||
activity?.runOnUiThread(action)
|
||||
}
|
||||
|
||||
private fun subscribe(channels: List<String>) {
|
||||
fun run() {
|
||||
lifecycleScope.launchWhenCreated {
|
||||
val response = try {
|
||||
val sharedPref =
|
||||
context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||
RetrofitInstance.api.importSubscriptions(
|
||||
false,
|
||||
sharedPref?.getString("token", "")!!,
|
||||
channels
|
||||
)
|
||||
} catch (e: IOException) {
|
||||
Log.e(TAG, "IOException, you might not have internet connection")
|
||||
return@launchWhenCreated
|
||||
} catch (e: HttpException) {
|
||||
Log.e(TAG, "HttpException, unexpected response$e")
|
||||
return@launchWhenCreated
|
||||
}
|
||||
if (response.message == "ok") {
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.importsuccess,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
run()
|
||||
}
|
||||
}
|
@ -1,11 +1,12 @@
|
||||
package com.github.libretube
|
||||
package com.github.libretube.preferences
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import com.github.libretube.R
|
||||
|
||||
class SponsorBlockSettings : PreferenceFragmentCompat() {
|
||||
private val TAG = "SponsorBlockDialog"
|
||||
private val TAG = "SponsorBlockSettings"
|
||||
|
||||
companion object {
|
||||
var sponsorBlockEnabled: Boolean = false
|
@ -4,12 +4,12 @@ import android.util.Log
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.github.libretube.BuildConfig
|
||||
import com.github.libretube.dialogs.UpdateAvailableDialog
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
import java.net.URL
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
fun checkUpdate(childFragmentManager: FragmentManager) {
|
||||
var updateInfo: UpdateInfo? = UpdateInfo("", "")
|
||||
|
@ -118,4 +118,6 @@
|
||||
<string name="playOnBackground">Play on background</string>
|
||||
<string name="update_available">Version %1$s is available</string>
|
||||
<string name="update_available_text">There is a new update available. Click okay to become redirected to the update page on GitHub.</string>
|
||||
<string name="appearance">Appearance</string>
|
||||
<string name="app_behavior">App Behavior</string>
|
||||
</resources>
|
63
app/src/main/res/xml/appearance_settings.xml
Normal file
63
app/src/main/res/xml/appearance_settings.xml
Normal file
@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<PreferenceCategory app:title="@string/appearance">
|
||||
|
||||
<androidx.preference.ListPreference
|
||||
app:title="@string/app_theme"
|
||||
app:key="theme_togglee"
|
||||
app:entries="@array/themes"
|
||||
app:entryValues="@array/themesValue"
|
||||
app:defaultValue="A"
|
||||
android:icon="@drawable/ic_theme" />
|
||||
|
||||
<androidx.preference.ListPreference
|
||||
app:title="@string/color_accent"
|
||||
app:key="accent_color"
|
||||
app:entries="@array/accents"
|
||||
app:entryValues="@array/accentsValue"
|
||||
app:defaultValue="red"
|
||||
android:icon="@drawable/ic_color" />
|
||||
|
||||
<androidx.preference.ListPreference
|
||||
app:title="@string/app_icon"
|
||||
app:key="icon_change"
|
||||
app:entries="@array/icons"
|
||||
app:entryValues="@array/iconsValue"
|
||||
app:defaultValue="MainActivity"
|
||||
android:icon="@drawable/ic_frame" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory app:title="@string/app_behavior">
|
||||
|
||||
<androidx.preference.ListPreference
|
||||
app:title="@string/defaultTab"
|
||||
app:key="default_tab"
|
||||
app:entries="@array/tabs"
|
||||
app:entryValues="@array/tabsValue"
|
||||
app:defaultValue="home"
|
||||
android:icon="@drawable/ic_home_outlined" />
|
||||
|
||||
<androidx.preference.ListPreference
|
||||
app:title="@string/defres"
|
||||
app:key="default_res"
|
||||
app:entries="@array/defres"
|
||||
app:entryValues="@array/defresValue"
|
||||
app:defaultValue=""
|
||||
android:icon="@drawable/ic_hd"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
|
||||
<androidx.preference.ListPreference
|
||||
app:title="@string/grid"
|
||||
app:key="grid"
|
||||
app:entries="@array/grid"
|
||||
app:entryValues="@array/grid"
|
||||
app:defaultValue="@integer/grid_items"
|
||||
android:icon="@drawable/ic_grid"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
20
app/src/main/res/xml/history_settings.xml
Normal file
20
app/src/main/res/xml/history_settings.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<PreferenceCategory app:title="@string/search_history">
|
||||
|
||||
<SwitchPreference
|
||||
app:title="@string/search_history"
|
||||
app:key="search_history_toggle"
|
||||
android:defaultValue="true"
|
||||
android:icon="@drawable/ic_history" />
|
||||
|
||||
<Preference
|
||||
app:title="@string/clear_history"
|
||||
app:key="clear_history"
|
||||
android:icon="@drawable/ic_delete" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
@ -54,80 +54,24 @@
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
<PreferenceCategory app:title="@string/customization">
|
||||
|
||||
<ListPreference
|
||||
app:title="@string/app_theme"
|
||||
app:key="theme_togglee"
|
||||
app:entries="@array/themes"
|
||||
app:entryValues="@array/themesValue"
|
||||
app:defaultValue="A"
|
||||
android:icon="@drawable/ic_theme" />
|
||||
|
||||
<ListPreference
|
||||
app:title="@string/color_accent"
|
||||
app:key="accent_color"
|
||||
app:entries="@array/accents"
|
||||
app:entryValues="@array/accentsValue"
|
||||
app:defaultValue="red"
|
||||
<Preference
|
||||
app:key="appearance"
|
||||
app:title="@string/appearance"
|
||||
android:icon="@drawable/ic_color" />
|
||||
|
||||
<ListPreference
|
||||
app:title="@string/app_icon"
|
||||
app:key="icon_change"
|
||||
app:entries="@array/icons"
|
||||
app:entryValues="@array/iconsValue"
|
||||
app:defaultValue="MainActivity"
|
||||
android:icon="@drawable/ic_frame" />
|
||||
|
||||
<androidx.preference.Preference
|
||||
app:title="@string/sponsorblock"
|
||||
app:key="sponsorblock"
|
||||
app:summary="@string/sponsorblock_summary"
|
||||
android:icon="@drawable/ic_block" />
|
||||
|
||||
<ListPreference
|
||||
app:title="@string/defaultTab"
|
||||
app:key="default_tab"
|
||||
app:entries="@array/tabs"
|
||||
app:entryValues="@array/tabsValue"
|
||||
app:defaultValue="home"
|
||||
android:icon="@drawable/ic_home_outlined" />
|
||||
|
||||
<ListPreference
|
||||
app:title="@string/defres"
|
||||
app:key="default_res"
|
||||
app:entries="@array/defres"
|
||||
app:entryValues="@array/defresValue"
|
||||
app:defaultValue=""
|
||||
android:icon="@drawable/ic_hd"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
|
||||
<ListPreference
|
||||
app:title="@string/grid"
|
||||
app:key="grid"
|
||||
app:entries="@array/grid"
|
||||
app:entryValues="@array/grid"
|
||||
app:defaultValue="@integer/grid_items"
|
||||
android:icon="@drawable/ic_grid"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory app:title="@string/history">
|
||||
|
||||
<SwitchPreference
|
||||
app:title="@string/search_history"
|
||||
app:key="search_history_toggle"
|
||||
android:defaultValue="true"
|
||||
<androidx.preference.Preference
|
||||
app:key="history"
|
||||
app:title="@string/history"
|
||||
android:icon="@drawable/ic_history" />
|
||||
|
||||
<Preference
|
||||
app:title="@string/clear_history"
|
||||
app:key="clear_history"
|
||||
android:icon="@drawable/ic_delete" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory app:title="@string/about">
|
||||
|
Loading…
x
Reference in New Issue
Block a user