Merge branch 'libre-tube:master' into master

This commit is contained in:
XelXen 2022-06-18 19:05:36 +05:30 committed by GitHub
commit 3da44f5cb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 270 additions and 124 deletions

View File

@ -12,7 +12,7 @@ jobs:
- name: ktlint - name: ktlint
uses: ScaCap/action-ktlint@1.4 uses: ScaCap/action-ktlint@1.4
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.ACCESS_TOKEN }}
reporter: github-pr-check reporter: github-pr-check
android: true android: true
fail_on_error: true fail_on_error: true

View File

@ -40,7 +40,11 @@
## Contributing ## Contributing
Whether you have ideas, translations, design changes, code cleaning, or real heavy code changes, help is always welcome. The more is done the better it gets! If creating a pr, please make sure to format the code with ktlint before. Whether you have ideas, translations, design changes, code cleaning, or real heavy code changes, help is always welcome.The more is done the better it gets!
If creating a pull request, please make sure to format your code (with ktlint) before.
If opening an issue without following the issue template, we will ignore the issue and force close it.
WARNING: THIS IS A BETA VERSION, THEREFORE YOU MAY ENCOUNTER BUGS. IF YOU DO, OPEN AN ISSUE VIA OUR GITHUB REPOSITORY. WARNING: THIS IS A BETA VERSION, THEREFORE YOU MAY ENCOUNTER BUGS. IF YOU DO, OPEN AN ISSUE VIA OUR GITHUB REPOSITORY.

View File

@ -6,6 +6,7 @@ import android.content.Intent
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.content.res.Configuration import android.content.res.Configuration
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
@ -44,8 +45,9 @@ import com.google.android.material.color.DynamicColors
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
val TAG = "MainActivity" val TAG = "MainActivity"
lateinit var bottomNavigationView: BottomNavigationView lateinit var bottomNavigationView: BottomNavigationView
lateinit var toolbar: Toolbar private lateinit var toolbar: Toolbar
lateinit var navController: NavController lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -79,12 +81,8 @@ class MainActivity : AppCompatActivity() {
ThemeHelper().updateTheme(this) ThemeHelper().updateTheme(this)
LocaleHelper().updateLanguage(this) LocaleHelper().updateLanguage(this)
val connectivityManager = // show noInternet Activity if no internet available on app startup
this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager if (!isNetworkAvailable(this)) {
val networkInfo = connectivityManager.activeNetworkInfo
val isConnected = networkInfo != null && networkInfo.isConnected
if (!isConnected) {
setContentView(R.layout.activity_nointernet) setContentView(R.layout.activity_nointernet)
findViewById<Button>(R.id.retry_button).setOnClickListener { findViewById<Button>(R.id.retry_button).setOnClickListener {
recreate() recreate()
@ -101,7 +99,13 @@ class MainActivity : AppCompatActivity() {
navController = findNavController(R.id.fragment) navController = findNavController(R.id.fragment)
bottomNavigationView.setupWithNavController(navController) bottomNavigationView.setupWithNavController(navController)
when (sharedPreferences.getString("default_tab", "home")!!) { // hide the trending page if enabled
val hideTrendingPage = sharedPreferences.getBoolean("hide_trending_page", false)
if (hideTrendingPage) bottomNavigationView.menu.findItem(R.id.home2).isVisible = false
// navigate to the default start tab
val defaultTab = sharedPreferences.getString("default_tab", "home")
when (defaultTab) {
"home" -> navController.navigate(R.id.home2) "home" -> navController.navigate(R.id.home2)
"subscriptions" -> navController.navigate(R.id.subscriptions) "subscriptions" -> navController.navigate(R.id.subscriptions)
"library" -> navController.navigate(R.id.library) "library" -> navController.navigate(R.id.library)
@ -112,17 +116,14 @@ class MainActivity : AppCompatActivity() {
R.id.home2 -> { R.id.home2 -> {
navController.backQueue.clear() navController.backQueue.clear()
navController.navigate(R.id.home2) navController.navigate(R.id.home2)
true
} }
R.id.subscriptions -> { R.id.subscriptions -> {
// navController.backQueue.clear() // navController.backQueue.clear()
navController.navigate(R.id.subscriptions) navController.navigate(R.id.subscriptions)
true
} }
R.id.library -> { R.id.library -> {
// navController.backQueue.clear() // navController.backQueue.clear()
navController.navigate(R.id.library) navController.navigate(R.id.library)
true
} }
} }
false false
@ -142,14 +143,12 @@ class MainActivity : AppCompatActivity() {
// settings activity stuff // settings activity stuff
val intent = Intent(this, SettingsActivity::class.java) val intent = Intent(this, SettingsActivity::class.java)
startActivity(intent) startActivity(intent)
true
} }
toolbar.setOnMenuItemClickListener { toolbar.setOnMenuItemClickListener {
when (it.itemId) { when (it.itemId) {
R.id.action_search -> { R.id.action_search -> {
navController.navigate(R.id.searchFragment) navController.navigate(R.id.searchFragment)
true
} }
} }
false false
@ -157,6 +156,28 @@ class MainActivity : AppCompatActivity() {
} }
} }
private fun isNetworkAvailable(context: Context): Boolean {
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val nw = connectivityManager.activeNetwork ?: return false
val actNw = connectivityManager.getNetworkCapabilities(nw) ?: return false
return when {
// WiFi
actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
// Mobile
actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
// Ethernet
actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
// Bluetooth
actNw.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> true
else -> false
}
} else {
return connectivityManager.activeNetworkInfo?.isConnected ?: false
}
}
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val intentData: Uri? = intent?.data val intentData: Uri? = intent?.data
@ -184,7 +205,7 @@ class MainActivity : AppCompatActivity() {
Log.i(TAG, "URI Type: Playlist") Log.i(TAG, "URI Type: Playlist")
var playlist = data.query!! var playlist = data.query!!
if (playlist.contains("&")) { if (playlist.contains("&")) {
var playlists = playlist.split("&") val playlists = playlist.split("&")
for (v in playlists) { for (v in playlists) {
if (v.contains("list=")) { if (v.contains("list=")) {
playlist = v playlist = v
@ -216,7 +237,7 @@ class MainActivity : AppCompatActivity() {
Log.d("dafaq", data.query!!) Log.d("dafaq", data.query!!)
var watch = data.query!! var watch = data.query!!
if (watch.contains("&")) { if (watch.contains("&")) {
var watches = watch.split("&") val watches = watch.split("&")
for (v in watches) { for (v in watches) {
if (v.contains("v=")) { if (v.contains("v=")) {
watch = v watch = v
@ -224,7 +245,7 @@ class MainActivity : AppCompatActivity() {
} }
} }
} }
var bundle = Bundle() val bundle = Bundle()
bundle.putString("videoId", watch.replace("v=", "")) bundle.putString("videoId", watch.replace("v=", ""))
// for time stamped links // for time stamped links
if (data.query != null && data.query?.contains("t=")!!) { if (data.query != null && data.query?.contains("t=")!!) {
@ -233,8 +254,8 @@ class MainActivity : AppCompatActivity() {
} }
loadWatch(bundle) loadWatch(bundle)
} else { } else {
var watch = data.path!!.replace("/", "") val watch = data.path!!.replace("/", "")
var bundle = Bundle() val bundle = Bundle()
bundle.putString("videoId", watch) bundle.putString("videoId", watch)
// for time stamped links // for time stamped links
if (data.query != null && data.query?.contains("t=")!!) { if (data.query != null && data.query?.contains("t=")!!) {
@ -246,7 +267,7 @@ class MainActivity : AppCompatActivity() {
} }
private fun loadWatch(bundle: Bundle) { private fun loadWatch(bundle: Bundle) {
var frag = PlayerFragment() val frag = PlayerFragment()
frag.arguments = bundle frag.arguments = bundle
supportFragmentManager.beginTransaction() supportFragmentManager.beginTransaction()
.remove(PlayerFragment()) .remove(PlayerFragment())
@ -278,11 +299,6 @@ class MainActivity : AppCompatActivity() {
isFullScreen = false isFullScreen = false
} else { } else {
navController.popBackStack() navController.popBackStack()
if (navController.currentBackStackEntry == null &&
(parent as View).id != R.id.settings
) {
super.onBackPressed()
}
} }
} catch (e: Exception) { } catch (e: Exception) {
// try catch to prevent nointernet activity to crash // try catch to prevent nointernet activity to crash

View File

@ -2,7 +2,6 @@ package com.github.libretube.dialogs
import android.app.Dialog import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.View import android.view.View
import android.widget.Button import android.widget.Button
@ -27,6 +26,9 @@ class CustomInstanceDialog : DialogFragment() {
val instanceNameEditText = view.findViewById<TextInputEditText>(R.id.instanceName) val instanceNameEditText = view.findViewById<TextInputEditText>(R.id.instanceName)
val instanceApiUrlEditText = view.findViewById<TextInputEditText>(R.id.instanceApiUrl) val instanceApiUrlEditText = view.findViewById<TextInputEditText>(R.id.instanceApiUrl)
val instanceFrontendUrlEditText = view
.findViewById<TextInputEditText>(R.id.instanceFrontendUrl)
val addInstanceButton = view.findViewById<Button>(R.id.addInstance) val addInstanceButton = view.findViewById<Button>(R.id.addInstance)
val cancelButton = view.findViewById<Button>(R.id.cancel) val cancelButton = view.findViewById<Button>(R.id.cancel)
cancelButton.setOnClickListener { cancelButton.setOnClickListener {
@ -36,12 +38,15 @@ class CustomInstanceDialog : DialogFragment() {
addInstanceButton.setOnClickListener { addInstanceButton.setOnClickListener {
val instanceName = instanceNameEditText.text.toString() val instanceName = instanceNameEditText.text.toString()
val instanceApiUrl = instanceApiUrlEditText.text.toString() val instanceApiUrl = instanceApiUrlEditText.text.toString()
val instanceFrontendUrl = instanceFrontendUrlEditText.text.toString()
if (instanceName != "" && instanceApiUrl != "") { if (instanceName != "" && instanceApiUrl != "" && instanceFrontendUrl != "") {
try { try {
// check whether the URL is valid, otherwise catch // check whether the URL is valid, otherwise catch
val u = URL(instanceApiUrl).toURI() URL(instanceApiUrl).toURI()
saveCustomInstance(instanceName, instanceApiUrl) URL(instanceFrontendUrl).toURI()
saveCustomInstance(instanceName, instanceApiUrl, instanceFrontendUrl)
activity?.recreate() activity?.recreate()
dismiss() dismiss()
} catch (e: Exception) { } catch (e: Exception) {
@ -72,7 +77,11 @@ class CustomInstanceDialog : DialogFragment() {
} ?: throw IllegalStateException("Activity cannot be null") } ?: throw IllegalStateException("Activity cannot be null")
} }
private fun saveCustomInstance(instanceName: String, instanceApiUrl: String) { private fun saveCustomInstance(
instanceName: String,
instanceApiUrl: String,
instanceFrontendApiUrl: String
) {
val sharedPreferences = PreferenceManager val sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(requireContext()) .getDefaultSharedPreferences(requireContext())
@ -84,7 +93,7 @@ class CustomInstanceDialog : DialogFragment() {
emptyList() emptyList()
} }
// get the urls of the other custom instances // get the api urls of the other custom instances
var customInstancesUrls = try { var customInstancesUrls = try {
sharedPreferences sharedPreferences
.getStringSet("custom_instances_url", HashSet())!!.toList() .getStringSet("custom_instances_url", HashSet())!!.toList()
@ -92,15 +101,24 @@ class CustomInstanceDialog : DialogFragment() {
emptyList() emptyList()
} }
// get the frontend urls of the other custom instances
var customInstancesFrontendUrls = try {
sharedPreferences
.getStringSet("custom_instances_url", HashSet())!!.toList()
} catch (e: Exception) {
emptyList()
}
// append new instance to the list // append new instance to the list
customInstancesNames += instanceName customInstancesNames += instanceName
customInstancesUrls += instanceApiUrl customInstancesUrls += instanceApiUrl
Log.e(TAG, customInstancesNames.toString()) customInstancesFrontendUrls += instanceFrontendApiUrl
// save them to the shared preferences // save them to the shared preferences
sharedPreferences.edit() sharedPreferences.edit()
.putStringSet("custom_instances_name", HashSet(customInstancesNames)) .putStringSet("custom_instances_name", HashSet(customInstancesNames))
.putStringSet("custom_instances_url", HashSet(customInstancesUrls)) .putStringSet("custom_instances_url", HashSet(customInstancesUrls))
.putStringSet("custom_instances_frontend_url", HashSet(customInstancesFrontendUrls))
.apply() .apply()
} }
} }

View File

@ -7,24 +7,20 @@ import androidx.fragment.app.DialogFragment
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.github.libretube.R import com.github.libretube.R
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.net.URLEncoder
class ShareDialog(private val videoId: String) : DialogFragment() { class ShareDialog(private val videoId: String) : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let { return activity?.let {
val sharedPreferences = var shareOptions = arrayOf(
PreferenceManager.getDefaultSharedPreferences(requireContext()) getString(R.string.piped),
val instancePref = sharedPreferences.getString( getString(R.string.youtube)
"selectInstance",
"https://pipedapi.kavin.rocks"
)!!
val instance = "&instance=${URLEncoder.encode(instancePref, "UTF-8")}"
val shareOptions = arrayOf(
context?.getString(R.string.piped),
context?.getString(R.string.instance),
context?.getString(R.string.youtube)
) )
val instanceUrl = getCustomInstanceFrontendUrl()
// add instanceUrl option if custom instance frontend url available
if (instanceUrl != "") shareOptions += getString(R.string.instance)
MaterialAlertDialogBuilder(requireContext()) MaterialAlertDialogBuilder(requireContext())
.setTitle(context?.getString(R.string.share)) .setTitle(context?.getString(R.string.share))
.setItems( .setItems(
@ -32,8 +28,8 @@ class ShareDialog(private val videoId: String) : DialogFragment() {
) { _, id -> ) { _, id ->
val url = when (id) { val url = when (id) {
0 -> "https://piped.kavin.rocks/watch?v=$videoId" 0 -> "https://piped.kavin.rocks/watch?v=$videoId"
1 -> "https://piped.kavin.rocks/watch?v=$videoId$instance" 1 -> "https://youtu.be/$videoId"
2 -> "https://youtu.be/$videoId" 2 -> "$instanceUrl/watch?v=$videoId" // only available for custom instances
else -> "https://piped.kavin.rocks/watch?v=$videoId" else -> "https://piped.kavin.rocks/watch?v=$videoId"
} }
val intent = Intent() val intent = Intent()
@ -47,4 +43,38 @@ class ShareDialog(private val videoId: String) : DialogFragment() {
.show() .show()
} ?: throw IllegalStateException("Activity cannot be null") } ?: throw IllegalStateException("Activity cannot be null")
} }
// get the frontend url if it's a custom instance
private fun getCustomInstanceFrontendUrl(): String {
val sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(requireContext())
val instancePref = sharedPreferences.getString(
"selectInstance",
"https://pipedapi.kavin.rocks"
)
// get the api urls of the other custom instances
var customInstancesUrls = try {
sharedPreferences
.getStringSet("custom_instances_url", HashSet())!!.toList()
} catch (e: Exception) {
emptyList()
}
// get the frontend urls of the other custom instances
var customInstancesFrontendUrls = try {
sharedPreferences
.getStringSet("custom_instances_url", HashSet())!!.toList()
} catch (e: Exception) {
emptyList()
}
// return the custom instance frontend url if available
return if (customInstancesUrls.contains(instancePref)) {
val index = customInstancesUrls.indexOf(instancePref)
return customInstancesFrontendUrls[index]
} else {
""
}
}
} }

View File

@ -18,6 +18,7 @@ import com.github.libretube.R
import com.github.libretube.adapters.PlaylistsAdapter import com.github.libretube.adapters.PlaylistsAdapter
import com.github.libretube.dialogs.CreatePlaylistDialog import com.github.libretube.dialogs.CreatePlaylistDialog
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.google.android.material.floatingactionbutton.FloatingActionButton
import java.io.IOException import java.io.IOException
import retrofit2.HttpException import retrofit2.HttpException
@ -68,16 +69,7 @@ class Library : Fragment() {
} }
} else { } else {
refreshLayout.isEnabled = false refreshLayout.isEnabled = false
view.findViewById<com.google.android.material.floatingactionbutton view.findViewById<FloatingActionButton>(R.id.create_playlist).visibility = View.GONE
.FloatingActionButton>(R.id.create_playlist).visibility = View.GONE
with(view.findViewById<ImageView>(R.id.boogh2)) {
visibility = View.VISIBLE
setImageResource(R.drawable.ic_login)
}
with(view.findViewById<TextView>(R.id.textLike2)) {
visibility = View.VISIBLE
text = getString(R.string.please_login)
}
} }
} }

View File

@ -51,9 +51,9 @@ import com.github.libretube.obj.ChapterSegment
import com.github.libretube.obj.PipedStream import com.github.libretube.obj.PipedStream
import com.github.libretube.obj.Segment import com.github.libretube.obj.Segment
import com.github.libretube.obj.Segments import com.github.libretube.obj.Segments
import com.github.libretube.obj.StreamItem
import com.github.libretube.obj.Streams import com.github.libretube.obj.Streams
import com.github.libretube.obj.Subscribe import com.github.libretube.obj.Subscribe
import com.github.libretube.obj.StreamItem
import com.github.libretube.preferences.SponsorBlockSettings import com.github.libretube.preferences.SponsorBlockSettings
import com.github.libretube.util.CronetHelper import com.github.libretube.util.CronetHelper
import com.github.libretube.util.DescriptionAdapter import com.github.libretube.util.DescriptionAdapter

View File

@ -19,15 +19,16 @@ import java.io.IOException
import retrofit2.HttpException import retrofit2.HttpException
class PlaylistFragment : Fragment() { class PlaylistFragment : Fragment() {
private var playlist_id: String? = null
private val TAG = "PlaylistFragment" private val TAG = "PlaylistFragment"
private var playlistId: String? = null
var nextPage: String? = null var nextPage: String? = null
var playlistAdapter: PlaylistAdapter? = null var playlistAdapter: PlaylistAdapter? = null
var isLoading = true var isLoading = true
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
arguments?.let { arguments?.let {
playlist_id = it.getString("playlist_id") playlistId = it.getString("playlist_id")
} }
} }
@ -43,8 +44,8 @@ class PlaylistFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
playlist_id = playlist_id!!.replace("/playlist?list=", "") playlistId = playlistId!!.replace("/playlist?list=", "")
view.findViewById<TextView>(R.id.playlist_name).text = playlist_id view.findViewById<TextView>(R.id.playlist_name).text = playlistId
val recyclerView = view.findViewById<RecyclerView>(R.id.playlist_recView) val recyclerView = view.findViewById<RecyclerView>(R.id.playlist_recView)
recyclerView.layoutManager = LinearLayoutManager(context) recyclerView.layoutManager = LinearLayoutManager(context)
@ -55,7 +56,7 @@ class PlaylistFragment : Fragment() {
fun run() { fun run() {
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
val response = try { val response = try {
RetrofitInstance.api.getPlaylist(playlist_id!!) RetrofitInstance.api.getPlaylist(playlistId!!)
} catch (e: IOException) { } catch (e: IOException) {
println(e) println(e)
Log.e(TAG, "IOException, you might not have internet connection") Log.e(TAG, "IOException, you might not have internet connection")
@ -70,7 +71,7 @@ class PlaylistFragment : Fragment() {
view.findViewById<TextView>(R.id.playlist_name).text = response.name view.findViewById<TextView>(R.id.playlist_name).text = response.name
view.findViewById<TextView>(R.id.playlist_uploader).text = response.uploader view.findViewById<TextView>(R.id.playlist_uploader).text = response.uploader
view.findViewById<TextView>(R.id.playlist_totVideos).text = view.findViewById<TextView>(R.id.playlist_totVideos).text =
response.videos.toString() + " Videos" getString(R.string.videoCount, response.videos.toString())
val sharedPref2 = val sharedPref2 =
context?.getSharedPreferences("username", Context.MODE_PRIVATE) context?.getSharedPreferences("username", Context.MODE_PRIVATE)
val user = sharedPref2?.getString("username", "") val user = sharedPref2?.getString("username", "")
@ -80,7 +81,7 @@ class PlaylistFragment : Fragment() {
} }
playlistAdapter = PlaylistAdapter( playlistAdapter = PlaylistAdapter(
response.relatedStreams!!.toMutableList(), response.relatedStreams!!.toMutableList(),
playlist_id!!, playlistId!!,
isOwner, isOwner,
requireActivity(), requireActivity(),
childFragmentManager childFragmentManager
@ -112,7 +113,7 @@ class PlaylistFragment : Fragment() {
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
val response = try { val response = try {
RetrofitInstance.api.getPlaylistNextPage(playlist_id!!, nextPage!!) RetrofitInstance.api.getPlaylistNextPage(playlistId!!, nextPage!!)
} catch (e: IOException) { } catch (e: IOException) {
println(e) println(e)
Log.e(TAG, "IOException, you might not have internet connection") Log.e(TAG, "IOException, you might not have internet connection")

View File

@ -63,19 +63,19 @@ class MainSettings : PreferenceFragmentCompat() {
true true
} }
val about = findPreference<Preference>("about")
about?.setOnPreferenceClickListener {
val newFragment = AboutFragment()
navigateSettings(newFragment)
true
}
val update = findPreference<Preference>("update") val update = findPreference<Preference>("update")
update?.title = getString(R.string.version, BuildConfig.VERSION_NAME) update?.title = getString(R.string.version, BuildConfig.VERSION_NAME)
update?.setOnPreferenceClickListener { update?.setOnPreferenceClickListener {
checkUpdate(childFragmentManager) checkUpdate(childFragmentManager)
true true
} }
val about = findPreference<Preference>("about")
about?.setOnPreferenceClickListener {
val newFragment = AboutFragment()
navigateSettings(newFragment)
true
}
} }
private fun navigateSettings(newFragment: Fragment) { private fun navigateSettings(newFragment: Fragment) {

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="300"
android:viewportHeight="300"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FF000000"
android:pathData="M149.99,0C67.16,0 0,67.16 0,150c0,82.84 67.16,150 149.99,150s150,-67.16 150,-150C300,67.16 232.83,0 149.99,0zM110.97,105.36c2.08,-2.08 4.79,-3.11 7.51,-3.11c2.72,0 5.43,1.04 7.51,3.11l13.3,13.3v-3.91V62.48c0,-5.87 4.75,-10.62 10.62,-10.62s10.62,4.75 10.62,10.62v52.26v4.63l4.63,-4.63l9.39,-9.38c2.08,-2.08 4.79,-3.11 7.51,-3.11s5.44,1.04 7.51,3.11c2.55,2.55 3.52,6.08 2.93,9.38c0,0 -0,0 -0,0.01c-0.04,0.24 -0.12,0.47 -0.18,0.7c-0.09,0.37 -0.19,0.73 -0.32,1.08c-0.09,0.24 -0.19,0.47 -0.3,0.7c-0.17,0.37 -0.36,0.73 -0.57,1.08c-0.11,0.19 -0.22,0.37 -0.34,0.55c-0.36,0.52 -0.76,1.03 -1.23,1.5l-15.11,15.11l-16.59,16.59c-2.08,2.08 -4.79,3.11 -7.51,3.11c-0.03,0 -0.05,0 -0.08,0s-0.05,0 -0.08,0c-2.71,0 -5.43,-1.03 -7.51,-3.11l-16.59,-16.59l-15.11,-15.11c-0.47,-0.47 -0.86,-0.97 -1.22,-1.5c-0.13,-0.18 -0.23,-0.37 -0.34,-0.56c-0.21,-0.35 -0.4,-0.7 -0.56,-1.07c-0.11,-0.24 -0.21,-0.47 -0.3,-0.72c-0.13,-0.35 -0.22,-0.7 -0.31,-1.06c-0.06,-0.25 -0.14,-0.49 -0.19,-0.73C107.44,111.44 108.41,107.91 110.97,105.36zM231.57,209.32h-0c0,14.34 -14.06,25.57 -32.01,25.57h-99.13c-17.94,0 -32.01,-11.23 -32.01,-25.57V140.31c0,-12.12 10.06,-21.99 24,-24.76c0.6,5.98 3.22,11.53 7.53,15.83l4.11,4.11h-3.64c-7.26,0 -11.26,3.62 -11.26,4.82v69c0,1.2 3.99,4.82 11.26,4.82h99.14c7.26,0 11.26,-3.62 11.26,-4.82V140.31c0,-1.2 -3.99,-4.82 -11.26,-4.82h-3.12l4.11,-4.11c4.28,-4.28 6.89,-9.79 7.52,-15.73c13.68,2.91 23.5,12.69 23.5,24.66V209.32z" />
</vector>

View File

@ -1,11 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24"> android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
<path <path
android:fillColor="#FF000000" android:fillColor="#FF000000"
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.25,2.52 0.77,-1.28 -3.52,-2.09L13.5,8z" /> android:pathData="M12,2c5.523,0 10,4.477 10,10s-4.477,10 -10,10c-1.702,0 -3.305,-0.425 -4.708,-1.175L2,22l1.176,-5.29C2.426,15.306 2,13.703 2,12 2,6.477 6.477,2 12,2zM13,7h-2v7h6v-2h-4L13,7z"/>
</vector> </vector>

View File

@ -3,9 +3,12 @@
android:height="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24"
android:tint="?attr/colorControlNormal"> android:tint="?android:attr/colorControlNormal">
<path
<path android:pathData="M9,3h8a2,2 0,0 1,2 2v14a2,2 0,0 1,-2 2H9m6,-9 l-4,-4m4,4 l-4,4m4,-4H5"
android:fillColor="#FF000000" android:strokeLineJoin="round"
android:pathData="M9.325,16.275Q9.05,15.95 9.05,15.537Q9.05,15.125 9.325,14.85L11.175,13H4Q3.575,13 3.288,12.712Q3,12.425 3,12Q3,11.575 3.288,11.287Q3.575,11 4,11H11.175L9.325,9.15Q9.025,8.85 9.025,8.438Q9.025,8.025 9.325,7.725Q9.6,7.425 10.013,7.425Q10.425,7.425 10.7,7.7L14.3,11.3Q14.45,11.45 14.513,11.625Q14.575,11.8 14.575,12Q14.575,12.2 14.513,12.375Q14.45,12.55 14.3,12.7L10.7,16.3Q10.4,16.6 10,16.575Q9.6,16.55 9.325,16.275ZM13,21Q12.575,21 12.288,20.712Q12,20.425 12,20Q12,19.575 12.288,19.288Q12.575,19 13,19H19Q19,19 19,19Q19,19 19,19V5Q19,5 19,5Q19,5 19,5H13Q12.575,5 12.288,4.712Q12,4.425 12,4Q12,3.575 12.288,3.287Q12.575,3 13,3H19Q19.825,3 20.413,3.587Q21,4.175 21,5V19Q21,19.825 20.413,20.413Q19.825,21 19,21Z" /> android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="@android:color/black"
android:strokeLineCap="round"/>
</vector> </vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FF000000"
android:pathData="M10,11H4V3a1,1 0,0 1,1 -1h14a1,1 0,0 1,1 1v18a1,1 0,0 1,-1 1H5a1,1 0,0 1,-1 -1v-8h6v3l5,-4 -5,-4v3z"/>
</vector>

View File

@ -1,10 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportWidth="459"
android:viewportHeight="24" android:viewportHeight="459"
android:tint="?attr/colorControlNormal"> android:tint="?android:attr/colorControlNormal">
<path <path
android:fillColor="@android:color/black" android:fillColor="#FF000000"
android:pathData="M8,5v14l11,-7z" /> android:pathData="M229.5,0C102.75,0 0,102.75 0,229.5S102.75,459 229.5,459S459,356.25 459,229.5S356.25,0 229.5,0zM310.29,239.65l-111.76,76.08c-3.76,2.56 -8.63,2.83 -12.65,0.7c-4.02,-2.13 -6.54,-6.3 -6.54,-10.85V153.42c0,-4.55 2.52,-8.73 6.54,-10.85c4.02,-2.13 8.89,-1.86 12.65,0.7l111.76,76.08c3.36,2.29 5.37,6.09 5.37,10.15C315.66,233.56 313.65,237.36 310.29,239.65z" />
</vector> </vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="512"
android:viewportHeight="512"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FF000000"
android:pathData="M430.87,128.99l11.91,-11.91c6.38,-6.38 6.38,-16.73 0,-23.11c-6.38,-6.38 -16.73,-6.38 -23.11,0l-11.9,11.9c-36.81,-32.03 -83.82,-52.64 -135.43,-56.26V32.68h4.36c9.02,0 16.34,-7.32 16.34,-16.34c0,-9.02 -7.32,-16.34 -16.34,-16.34h-41.4c-9.02,0 -16.34,7.32 -16.34,16.34c0,9.02 7.32,16.34 16.34,16.34h4.36v16.92c-51.62,3.62 -98.62,24.22 -135.43,56.26L92.33,93.97c-6.38,-6.38 -16.73,-6.38 -23.11,0c-6.38,6.38 -6.38,16.73 0,23.11l11.91,11.91c-35.26,40.63 -56.62,93.63 -56.62,151.52C24.51,408.15 128.36,512 256,512s231.49,-103.85 231.49,-231.49C487.49,222.62 466.13,169.62 430.87,128.99zM256,323.54c-23.73,0 -43.03,-19.3 -43.03,-43.03c0,-17.94 11.04,-33.35 26.69,-39.8v-77.31c0,-9.02 7.32,-16.34 16.34,-16.34c9.02,0 16.34,7.32 16.34,16.34v77.31c15.65,6.45 26.69,21.85 26.69,39.8C299.03,304.24 279.73,323.54 256,323.54z" />
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="60"
android:viewportHeight="60"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FF000000"
android:pathData="M30,0.061c-16.542,0 -30,13.458 -30,30s13.458,29.879 30,29.879s30,-13.337 30,-29.879S46.542,0.061 30,0.061zM32,30.939c0,1.104 -0.896,2 -2,2H14c-1.104,0 -2,-0.896 -2,-2s0.896,-2 2,-2h14v-22c0,-1.104 0.896,-2 2,-2s2,0.896 2,2V30.939z" />
</vector>

View File

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:pathData="M16.24,7.76C15.07,6.59 13.54,6 12,6v6l-4.24,4.24c2.34,2.34 6.14,2.34 8.49,0 2.34,-2.34 2.34,-6.14 -0.01,-8.48zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" />
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="52"
android:viewportHeight="52"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FF000000"
android:pathData="M50.1,30.56a1.16,1.16 0,0 1,-2 0.82L42.73,26 30.32,36.65a3.39,3.39 0,0 1,-4.92 0l-7.49,-8.54L4.57,39.81a1.13,1.13 0,0 1,-1.64 0l-0.59,-0.59a1.13,1.13 0,0 1,0 -1.64L15.46,19.68a3.39,3.39 0,0 1,4.92 0l7.49,7.49 7.61,-8.78 -4.92,-4.45a1.26,1.26 0,0 1,0.82 -2.11H47.76A2.35,2.35 0,0 1,50 14.3Z" />
</vector>

View File

@ -1,11 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportWidth="300"
android:viewportHeight="24" android:viewportHeight="300"
android:tint="?attr/colorControlNormal"> android:tint="?android:attr/colorControlNormal">
<path <path
android:fillColor="#FF000000" android:fillColor="#FF000000"
android:pathData="M12,16Q11.575,16 11.288,15.712Q11,15.425 11,15V7.85L9.125,9.725Q8.825,10.025 8.425,10.025Q8.025,10.025 7.7,9.7Q7.4,9.4 7.413,8.987Q7.425,8.575 7.7,8.3L11.3,4.7Q11.45,4.55 11.625,4.487Q11.8,4.425 12,4.425Q12.2,4.425 12.375,4.487Q12.55,4.55 12.7,4.7L16.3,8.3Q16.6,8.6 16.587,9.012Q16.575,9.425 16.3,9.7Q16,10 15.588,10.012Q15.175,10.025 14.875,9.725L13,7.85V15Q13,15.425 12.713,15.712Q12.425,16 12,16ZM6,20Q5.175,20 4.588,19.413Q4,18.825 4,18V16Q4,15.575 4.287,15.287Q4.575,15 5,15Q5.425,15 5.713,15.287Q6,15.575 6,16V18Q6,18 6,18Q6,18 6,18H18Q18,18 18,18Q18,18 18,18V16Q18,15.575 18.288,15.287Q18.575,15 19,15Q19.425,15 19.712,15.287Q20,15.575 20,16V18Q20,18.825 19.413,19.413Q18.825,20 18,20Z" /> android:pathData="M150,0C67.16,0 0,67.16 0,150s67.16,150 150,150C232.83,300 300,232.84 300,150C300,67.16 232.83,0 150,0zM110.97,81.48l31.71,-31.71c2.08,-2.08 4.79,-3.11 7.51,-3.11c0.03,0 0.05,0 0.08,0c0.03,0 0.05,0 0.08,0c2.71,0 5.43,1.03 7.51,3.11l31.71,31.71c4.15,4.15 4.15,10.87 0,15.02c-2.07,2.08 -4.79,3.11 -7.51,3.11c-2.72,0 -5.44,-1.04 -7.51,-3.11l-14.02,-14.01v32.26v20.75v3.89c0,5.87 -4.76,10.62 -10.62,10.62c-5.87,0 -10.62,-4.75 -10.62,-10.62v-3.89v-20.75V83.21l-13.3,13.3c-2.08,2.08 -4.79,3.11 -7.51,3.11c-2.72,0 -5.44,-1.04 -7.51,-3.11C106.82,92.36 106.82,85.63 110.97,81.48zM231.58,209.32h-0c0,14.34 -14.06,25.57 -32.01,25.57h-99.13c-17.94,0 -32.01,-11.23 -32.01,-25.57V140.31c0,-14.34 14.06,-25.57 32.01,-25.57h13.39c1.52,0.27 3.08,0.43 4.66,0.43c1.57,0 3.12,-0.16 4.63,-0.43h0.61v20.75h-23.28c-7.26,0 -11.26,3.62 -11.26,4.82v69.01c0,1.2 3.99,4.82 11.26,4.82h99.14c7.26,0 11.26,-3.62 11.26,-4.82V140.31c0,-1.2 -3.99,-4.82 -11.26,-4.82h-23.49v-20.75h1.44c1.48,0.26 2.99,0.43 4.53,0.43c1.58,0 3.13,-0.16 4.66,-0.43h12.86c17.95,0 32.01,11.23 32.01,25.57V209.32z" />
</vector> </vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="512"
android:viewportHeight="512"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FF000000"
android:pathData="M395.6,69.8L325.8,0h-58.2l69.8,69.8H395.6zM23.3,0H0v69.8h93.1L23.3,0zM244.4,69.8L174.5,0h-58.2l69.8,69.8H244.4zM418.9,162.9h-93.1l69.8,-69.8h-58.2l-69.8,69.8h-93.1l69.8,-69.8h-58.2l-69.8,69.8H23.3l69.8,-69.8H0v372.4C0,491.1 20.9,512 46.5,512h418.9c25.7,0 46.5,-20.9 46.5,-46.5V93.1h-23.3L418.9,162.9zM186.2,442.2V232.7l186.2,104.7L186.2,442.2zM418.9,0l69.8,69.8H512V0H418.9z" />
</vector>

View File

@ -1,10 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?android:attr/colorControlNormal" android:viewportWidth="28"
android:viewportWidth="24" android:viewportHeight="28"
android:viewportHeight="24"> android:tint="?android:attr/colorControlNormal">
<path <path
android:fillColor="@android:color/white" android:fillColor="#212121"
android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z" /> android:pathData="M5.25,5.5C3.455,5.5 2,6.955 2,8.75V19.25C2,21.045 3.455,22.5 5.25,22.5H14.75C16.545,22.5 18,21.045 18,19.25V8.75C18,6.955 16.545,5.5 14.75,5.5H5.25Z" />
<path
android:fillColor="#212121"
android:pathData="M23.123,20.643L19.5,17.094V10.999L23.112,7.371C23.899,6.58 25.248,7.138 25.248,8.253V19.75C25.248,20.858 23.914,21.418 23.123,20.643Z" />
</vector> </vector>

View File

@ -39,6 +39,30 @@
android:padding="12dp" /> android:padding="12dp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintEnabled="false"
android:layout_marginTop="16dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="4dp"
app:boxCornerRadiusBottomStart="15dp"
app:boxCornerRadiusBottomEnd="15dp"
app:boxCornerRadiusTopEnd="15dp"
app:boxCornerRadiusTopStart="15dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/instanceFrontendUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/instance_frontend_url"
android:inputType="text"
android:padding="12dp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -52,9 +76,7 @@
app:boxCornerRadiusBottomStart="15dp" app:boxCornerRadiusBottomStart="15dp"
app:boxCornerRadiusBottomEnd="15dp" app:boxCornerRadiusBottomEnd="15dp"
app:boxCornerRadiusTopEnd="15dp" app:boxCornerRadiusTopEnd="15dp"
app:boxCornerRadiusTopStart="15dp" app:boxCornerRadiusTopStart="15dp">
>
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/instanceApiUrl" android:id="@+id/instanceApiUrl"

View File

@ -190,4 +190,6 @@
<string name="video">Video</string> <string name="video">Video</string>
<string name="downloading">Downloading</string> <string name="downloading">Downloading</string>
<string name="player_autoplay">Autoplay</string> <string name="player_autoplay">Autoplay</string>
<string name="hideTrendingPage">Hide trending page</string>
<string name="instance_frontend_url">URL to instance frontend</string>
</resources> </resources>

View File

@ -14,7 +14,7 @@
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />
<ListPreference <ListPreference
android:icon="@drawable/ic_hd" android:icon="@drawable/ic_video"
app:defaultValue="WEBM" app:defaultValue="WEBM"
app:entries="@array/playerVideoFormats" app:entries="@array/playerVideoFormats"
app:entryValues="@array/playerVideoFormats" app:entryValues="@array/playerVideoFormats"
@ -23,7 +23,7 @@
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />
<ListPreference <ListPreference
android:icon="@drawable/ic_play" android:icon="@drawable/ic_speed"
app:defaultValue="1F" app:defaultValue="1F"
app:entries="@array/playbackSpeed" app:entries="@array/playbackSpeed"
app:entryValues="@array/playbackSpeedValues" app:entryValues="@array/playbackSpeedValues"
@ -32,7 +32,7 @@
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />
<ListPreference <ListPreference
android:icon="@drawable/ic_timelapse" android:icon="@drawable/ic_time"
app:defaultValue="50" app:defaultValue="50"
app:entries="@array/bufferingGoal" app:entries="@array/bufferingGoal"
app:entryValues="@array/bufferingGoal" app:entryValues="@array/bufferingGoal"
@ -64,7 +64,7 @@
android:defaultValue="downloads" android:defaultValue="downloads"
android:entries="@array/downloadLocation" android:entries="@array/downloadLocation"
android:entryValues="@array/downloadLocationValues" android:entryValues="@array/downloadLocationValues"
app:icon="@drawable/ic_download" app:icon="@drawable/ic_download_filled"
app:key="download_location" app:key="download_location"
app:summary="@string/download_directory_summary" app:summary="@string/download_directory_summary"
app:title="@string/download_directory" /> app:title="@string/download_directory" />

View File

@ -44,6 +44,13 @@
app:title="@string/defaultTab" app:title="@string/defaultTab"
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />
<SwitchPreference
android:icon="@drawable/ic_trending"
app:defaultValue="false"
app:key="hide_trending_page"
app:title="@string/hideTrendingPage"
app:useSimpleSummaryProvider="true" />
<ListPreference <ListPreference
android:icon="@drawable/ic_grid" android:icon="@drawable/ic_grid"
app:defaultValue="@integer/grid_items" app:defaultValue="@integer/grid_items"

View File

@ -24,7 +24,7 @@
android:icon="@drawable/ic_trash" /> android:icon="@drawable/ic_trash" />
<Preference <Preference
android:icon="@drawable/ic_login" android:icon="@drawable/ic_login_filled"
android:summary="@string/notgmail" android:summary="@string/notgmail"
app:key="login_register" app:key="login_register"
app:title="@string/login_register" /> app:title="@string/login_register" />

View File

@ -54,18 +54,18 @@
<PreferenceCategory> <PreferenceCategory>
<Preference
android:icon="@drawable/ic_update"
app:key="update"
app:summary="@string/update_summary"
app:title="App version" />
<Preference <Preference
android:icon="@drawable/ic_info" android:icon="@drawable/ic_info"
app:key="about" app:key="about"
app:summary="@string/about_summary" app:summary="@string/about_summary"
app:title="@string/about" /> app:title="@string/about" />
<Preference
android:icon="@drawable/ic_update"
app:key="update"
app:summary="@string/update_summary"
app:title="App version" />
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>