mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 14:20:30 +05:30
Merge branch 'master' into filter
This commit is contained in:
commit
ce00408baa
@ -4,8 +4,8 @@ package com.github.libretube
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.opengl.Visibility
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.text.TextUtils.substring
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -208,9 +208,11 @@ class ChannelFragment : Fragment() {
|
|||||||
refreshLayout?.isRefreshing = false;
|
refreshLayout?.isRefreshing = false;
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
view.findViewById<ScrollView>(R.id.channel_scrollView).visibility = View.VISIBLE
|
view.findViewById<ScrollView>(R.id.channel_scrollView).visibility = View.VISIBLE
|
||||||
view.findViewById<TextView>(R.id.channel_name).text=response.name
|
view.findViewById<TextView>(R.id.channel_name).text = if (response.name?.length!! > 19) response.name.toString().substring(0,16) + "..." else response.name
|
||||||
|
val channelVerified = view.findViewById<ImageView>(R.id.channel_verified)
|
||||||
|
if (response.verified) channelVerified.visibility = View.VISIBLE
|
||||||
view.findViewById<TextView>(R.id.channel_subs).text=resources.getString(R.string.subscribers, response.subscriberCount.formatShort())
|
view.findViewById<TextView>(R.id.channel_subs).text=resources.getString(R.string.subscribers, response.subscriberCount.formatShort())
|
||||||
view.findViewById<TextView>(R.id.channel_description).text=response.description
|
view.findViewById<TextView>(R.id.channel_description).text=response.description?.trim()
|
||||||
val bannerImage = view.findViewById<ImageView>(R.id.channel_banner)
|
val bannerImage = view.findViewById<ImageView>(R.id.channel_banner)
|
||||||
val channelImage = view.findViewById<ImageView>(R.id.channel_image)
|
val channelImage = view.findViewById<ImageView>(R.id.channel_image)
|
||||||
Picasso.get().load(response.bannerUrl).into(bannerImage)
|
Picasso.get().load(response.bannerUrl).into(bannerImage)
|
||||||
|
@ -18,6 +18,7 @@ import android.view.*
|
|||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.constraintlayout.motion.widget.MotionLayout
|
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||||
@ -44,6 +45,13 @@ class MainActivity : AppCompatActivity() {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
RetrofitInstance.url = sharedPreferences.getString("instance", "https://pipedapi.kavin.rocks/")!!
|
RetrofitInstance.url = sharedPreferences.getString("instance", "https://pipedapi.kavin.rocks/")!!
|
||||||
|
SponsorBlockSettings.sponsorBlockEnabled = sharedPreferences.getBoolean("sponsorblock_enabled_key", false)
|
||||||
|
SponsorBlockSettings.introEnabled = sharedPreferences.getBoolean("intro_category_key", false)
|
||||||
|
SponsorBlockSettings.selfPromoEnabled = sharedPreferences.getBoolean("selfpromo_category_key", false)
|
||||||
|
SponsorBlockSettings.interactionEnabled = sharedPreferences.getBoolean("interaction_category_key", false)
|
||||||
|
SponsorBlockSettings.sponsorsEnabled = sharedPreferences.getBoolean("sponsors_category_key", false)
|
||||||
|
SponsorBlockSettings.outroEnabled = sharedPreferences.getBoolean("outro_category_key", false)
|
||||||
|
|
||||||
DynamicColors.applyToActivitiesIfAvailable(application)
|
DynamicColors.applyToActivitiesIfAvailable(application)
|
||||||
val languageName = sharedPreferences.getString("language", "sys")
|
val languageName = sharedPreferences.getString("language", "sys")
|
||||||
if (languageName != "") {
|
if (languageName != "") {
|
||||||
@ -86,6 +94,12 @@ 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")!!) {
|
||||||
|
"home" -> navController.navigate(R.id.home2)
|
||||||
|
"subscriptions" -> navController.navigate(R.id.subscriptions)
|
||||||
|
"library" -> navController.navigate(R.id.library)
|
||||||
|
}
|
||||||
|
|
||||||
bottomNavigationView.setOnItemSelectedListener {
|
bottomNavigationView.setOnItemSelectedListener {
|
||||||
when (it.itemId) {
|
when (it.itemId) {
|
||||||
R.id.home2 -> {
|
R.id.home2 -> {
|
||||||
|
@ -13,6 +13,9 @@ interface PipedApi {
|
|||||||
@GET("comments/{videoId}")
|
@GET("comments/{videoId}")
|
||||||
suspend fun getComments(@Path("videoId") videoId: String): CommentsPage
|
suspend fun getComments(@Path("videoId") videoId: String): CommentsPage
|
||||||
|
|
||||||
|
@GET("sponsors/{videoId}")
|
||||||
|
suspend fun getSegments(@Path("videoId") videoId: String, @Query("category") category: String): Segments
|
||||||
|
|
||||||
@GET("nextpage/comments/{videoId}")
|
@GET("nextpage/comments/{videoId}")
|
||||||
suspend fun getCommentsNextPage(@Path("videoId") videoId: String, @Query("nextpage") nextPage: String): CommentsPage
|
suspend fun getCommentsNextPage(@Path("videoId") videoId: String, @Query("nextpage") nextPage: String): CommentsPage
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import android.os.Build.VERSION.SDK_INT
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
|
import android.text.TextUtils
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -35,6 +36,8 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
import com.github.libretube.adapters.CommentsAdapter
|
import com.github.libretube.adapters.CommentsAdapter
|
||||||
import com.github.libretube.adapters.TrendingAdapter
|
import com.github.libretube.adapters.TrendingAdapter
|
||||||
import com.github.libretube.obj.PipedStream
|
import com.github.libretube.obj.PipedStream
|
||||||
|
import com.github.libretube.obj.Segment
|
||||||
|
import com.github.libretube.obj.Segments
|
||||||
import com.github.libretube.obj.Subscribe
|
import com.github.libretube.obj.Subscribe
|
||||||
import com.google.android.exoplayer2.C
|
import com.google.android.exoplayer2.C
|
||||||
import com.google.android.exoplayer2.ExoPlayer
|
import com.google.android.exoplayer2.ExoPlayer
|
||||||
@ -87,6 +90,7 @@ class PlayerFragment : Fragment() {
|
|||||||
private lateinit var motionLayout: MotionLayout
|
private lateinit var motionLayout: MotionLayout
|
||||||
private lateinit var exoPlayer: ExoPlayer
|
private lateinit var exoPlayer: ExoPlayer
|
||||||
private lateinit var mediaSource: MediaSource
|
private lateinit var mediaSource: MediaSource
|
||||||
|
private lateinit var segmentData: Segments
|
||||||
|
|
||||||
private lateinit var relDownloadVideo: LinearLayout
|
private lateinit var relDownloadVideo: LinearLayout
|
||||||
|
|
||||||
@ -270,6 +274,26 @@ class PlayerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkForSegments()
|
||||||
|
{
|
||||||
|
if (!exoPlayer.isPlaying || !SponsorBlockSettings.sponsorBlockEnabled) return
|
||||||
|
|
||||||
|
exoPlayerView.postDelayed(this::checkForSegments, 100)
|
||||||
|
|
||||||
|
if(segmentData.segments.isEmpty() )
|
||||||
|
return
|
||||||
|
|
||||||
|
segmentData.segments.forEach { segment: Segment ->
|
||||||
|
val segmentStart = (segment.segment!![0] * 1000.0f).toLong()
|
||||||
|
val segmentEnd = (segment.segment!![1] * 1000.0f).toLong()
|
||||||
|
val currentPosition = exoPlayer.currentPosition
|
||||||
|
if(currentPosition in segmentStart until segmentEnd) {
|
||||||
|
Toast.makeText(context,R.string.segment_skipped, Toast.LENGTH_SHORT).show()
|
||||||
|
exoPlayer.seekTo(segmentEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun fetchJson(view: View) {
|
private fun fetchJson(view: View) {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
@ -297,6 +321,45 @@ class PlayerFragment : Fragment() {
|
|||||||
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
|
||||||
return@launchWhenCreated
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
|
if(SponsorBlockSettings.sponsorBlockEnabled) {
|
||||||
|
val categories: ArrayList<String> = arrayListOf()
|
||||||
|
if (SponsorBlockSettings.introEnabled) {
|
||||||
|
categories.add("intro")
|
||||||
|
}
|
||||||
|
if (SponsorBlockSettings.selfPromoEnabled) {
|
||||||
|
categories.add("selfpromo")
|
||||||
|
}
|
||||||
|
if (SponsorBlockSettings.interactionEnabled) {
|
||||||
|
categories.add("interaction")
|
||||||
|
}
|
||||||
|
if (SponsorBlockSettings.sponsorsEnabled) {
|
||||||
|
categories.add("sponsor")
|
||||||
|
}
|
||||||
|
if (SponsorBlockSettings.outroEnabled) {
|
||||||
|
categories.add("outro")
|
||||||
|
}
|
||||||
|
if(categories.size > 0) {
|
||||||
|
segmentData = try {
|
||||||
|
|
||||||
|
RetrofitInstance.api.getSegments(
|
||||||
|
videoId!!,
|
||||||
|
"[\"" + TextUtils.join("\",\"", categories) + "\"]"
|
||||||
|
)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
println(e)
|
||||||
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
|
Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_SHORT)
|
||||||
|
.show()
|
||||||
|
return@launchWhenCreated
|
||||||
|
} catch (e: HttpException) {
|
||||||
|
Log.e(TAG, "HttpException, unexpected response")
|
||||||
|
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT)
|
||||||
|
.show()
|
||||||
|
return@launchWhenCreated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isLoading = false
|
isLoading = false
|
||||||
var videosNameArray: Array<CharSequence> = arrayOf()
|
var videosNameArray: Array<CharSequence> = arrayOf()
|
||||||
videosNameArray += "HLS"
|
videosNameArray += "HLS"
|
||||||
@ -502,6 +565,13 @@ class PlayerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
// Listener for play and pause icon change
|
// Listener for play and pause icon change
|
||||||
exoPlayer!!.addListener(object : com.google.android.exoplayer2.Player.Listener {
|
exoPlayer!!.addListener(object : com.google.android.exoplayer2.Player.Listener {
|
||||||
|
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||||
|
if(isPlaying && SponsorBlockSettings.sponsorBlockEnabled)
|
||||||
|
{
|
||||||
|
exoPlayerView.postDelayed(this@PlayerFragment::checkForSegments, 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onPlayerStateChanged(
|
override fun onPlayerStateChanged(
|
||||||
playWhenReady: Boolean,
|
playWhenReady: Boolean,
|
||||||
playbackState: Int
|
playbackState: Int
|
||||||
@ -536,9 +606,9 @@ class PlayerFragment : Fragment() {
|
|||||||
|
|
||||||
view.findViewById<TextView>(R.id.player_description).text =
|
view.findViewById<TextView>(R.id.player_description).text =
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
Html.fromHtml(response.description, Html.FROM_HTML_MODE_COMPACT)
|
Html.fromHtml(response.description, Html.FROM_HTML_MODE_COMPACT).trim()
|
||||||
} else {
|
} else {
|
||||||
Html.fromHtml(response.description)
|
Html.fromHtml(response.description).trim()
|
||||||
}
|
}
|
||||||
view.findViewById<TextView>(R.id.player_views_info).text =
|
view.findViewById<TextView>(R.id.player_views_info).text =
|
||||||
response.views.formatShort() + " views • " + response.uploadDate
|
response.views.formatShort() + " views • " + response.uploadDate
|
||||||
|
@ -73,7 +73,7 @@ class PlaylistFragment : Fragment() {
|
|||||||
val sharedPref2 = context?.getSharedPreferences("username", Context.MODE_PRIVATE)
|
val sharedPref2 = context?.getSharedPreferences("username", Context.MODE_PRIVATE)
|
||||||
val user = sharedPref2?.getString("username","")
|
val user = sharedPref2?.getString("username","")
|
||||||
var isOwner = false
|
var isOwner = false
|
||||||
if(response.uploaderUrl == null && response.uploader == user){
|
if(response.uploaderUrl == null && response.uploader.equals(user, true)){
|
||||||
isOwner = true
|
isOwner = true
|
||||||
}
|
}
|
||||||
playlistAdapter = PlaylistAdapter(response.relatedStreams!!.toMutableList(), playlist_id!!, isOwner, requireActivity())
|
playlistAdapter = PlaylistAdapter(response.relatedStreams!!.toMutableList(), playlist_id!!, isOwner, requireActivity())
|
||||||
|
@ -39,7 +39,9 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
overridePendingTransition(50, 50);
|
overridePendingTransition(50, 50);
|
||||||
|
}
|
||||||
val view = this.findViewById<View>(android.R.id.content)
|
val view = this.findViewById<View>(android.R.id.content)
|
||||||
view.setAlpha(0F);
|
view.setAlpha(0F);
|
||||||
view.animate().alpha(1F).setDuration(300);
|
view.animate().alpha(1F).setDuration(300);
|
||||||
@ -158,6 +160,15 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val sponsorblock = findPreference<Preference>("sponsorblock")
|
||||||
|
sponsorblock?.setOnPreferenceClickListener {
|
||||||
|
val newFragment = SponsorBlockSettings()
|
||||||
|
parentFragmentManager.beginTransaction()
|
||||||
|
.replace(R.id.settings, newFragment)
|
||||||
|
.commitNow()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
val importFromYt = findPreference<Preference>("import_from_yt")
|
val importFromYt = findPreference<Preference>("import_from_yt")
|
||||||
importFromYt?.setOnPreferenceClickListener {
|
importFromYt?.setOnPreferenceClickListener {
|
||||||
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.github.libretube
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import androidx.preference.SwitchPreferenceCompat
|
||||||
|
|
||||||
|
class SponsorBlockSettings : PreferenceFragmentCompat() {
|
||||||
|
private val TAG = "SponsorBlockDialog"
|
||||||
|
companion object {
|
||||||
|
var sponsorBlockEnabled: Boolean = false
|
||||||
|
var sponsorsEnabled: Boolean = false
|
||||||
|
var selfPromoEnabled: Boolean = false
|
||||||
|
var interactionEnabled: Boolean = false
|
||||||
|
var introEnabled: Boolean = false
|
||||||
|
var outroEnabled: Boolean = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
|
setPreferencesFromResource(R.xml.sponsorblock_settings, rootKey)
|
||||||
|
val sponsorBlockToggle = findPreference<SwitchPreferenceCompat>("sponsorblock_enabled_key")
|
||||||
|
sponsorBlockToggle?.setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
sponsorBlockEnabled = newValue as Boolean
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
val sponsorToggle = findPreference<SwitchPreferenceCompat>("sponsors_category_key")
|
||||||
|
sponsorToggle?.setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
sponsorsEnabled = newValue as Boolean
|
||||||
|
true
|
||||||
|
}
|
||||||
|
val selfPromoToggle = findPreference<SwitchPreferenceCompat>("selfpromo_category_key")
|
||||||
|
selfPromoToggle?.setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
selfPromoEnabled = newValue as Boolean
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
val interactionToggle = findPreference<SwitchPreferenceCompat>("interaction_category_key")
|
||||||
|
interactionToggle?.setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
interactionEnabled = newValue as Boolean
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
val introToggle = findPreference<SwitchPreferenceCompat>("intro_category_key")
|
||||||
|
introToggle?.setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
introEnabled = newValue as Boolean
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
val outroToggle = findPreference<SwitchPreferenceCompat>("outro_category_key")
|
||||||
|
outroToggle?.setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
outroEnabled = newValue as Boolean
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
@ -16,6 +17,7 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import com.github.libretube.adapters.SubscriptionAdapter
|
import com.github.libretube.adapters.SubscriptionAdapter
|
||||||
import com.github.libretube.adapters.SubscriptionChannelAdapter
|
import com.github.libretube.adapters.SubscriptionChannelAdapter
|
||||||
|
import org.chromium.base.ThreadUtils.runOnUiThread
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
@ -52,8 +54,6 @@ class Subscriptions : Fragment() {
|
|||||||
progressBar.visibility=View.VISIBLE
|
progressBar.visibility=View.VISIBLE
|
||||||
|
|
||||||
var channelRecView = view.findViewById<RecyclerView>(R.id.sub_channels)
|
var channelRecView = view.findViewById<RecyclerView>(R.id.sub_channels)
|
||||||
channelRecView?.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
|
||||||
fetchChannels(channelRecView)
|
|
||||||
|
|
||||||
var feedRecView = view.findViewById<RecyclerView>(R.id.sub_feed)
|
var feedRecView = view.findViewById<RecyclerView>(R.id.sub_feed)
|
||||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
@ -66,6 +66,25 @@ class Subscriptions : Fragment() {
|
|||||||
fetchFeed(feedRecView, progressBar, view)
|
fetchFeed(feedRecView, progressBar, view)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var toggleSubs = view.findViewById<RelativeLayout>(R.id.toggle_subs)
|
||||||
|
toggleSubs.visibility = View.VISIBLE
|
||||||
|
var loadedSubbedChannels = false
|
||||||
|
toggleSubs.setOnClickListener {
|
||||||
|
if (!channelRecView.isVisible) {
|
||||||
|
if (!loadedSubbedChannels) {
|
||||||
|
channelRecView?.layoutManager = GridLayoutManager(context, 4)
|
||||||
|
fetchChannels(channelRecView)
|
||||||
|
loadedSubbedChannels = true
|
||||||
|
}
|
||||||
|
channelRecView.visibility = View.VISIBLE
|
||||||
|
feedRecView.visibility = View.GONE
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
channelRecView.visibility = View.GONE
|
||||||
|
feedRecView.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val scrollView = view.findViewById<ScrollView>(R.id.scrollview_sub)
|
val scrollView = view.findViewById<ScrollView>(R.id.scrollview_sub)
|
||||||
scrollView.viewTreeObserver
|
scrollView.viewTreeObserver
|
||||||
.addOnScrollChangedListener {
|
.addOnScrollChangedListener {
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
package com.github.libretube.adapters
|
package com.github.libretube.adapters
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||||
|
import androidx.core.os.bundleOf
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.github.libretube.MainActivity
|
||||||
import com.github.libretube.R
|
import com.github.libretube.R
|
||||||
import com.github.libretube.formatShort
|
import com.github.libretube.formatShort
|
||||||
import com.github.libretube.obj.Comment
|
import com.github.libretube.obj.Comment
|
||||||
@ -27,8 +31,8 @@ class CommentsAdapter(private val comments: MutableList<Comment>): RecyclerView
|
|||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
holder.v.findViewById<TextView>(R.id.comment_infos).text = comments[position].author.toString() + " • " + comments[position].commentedTime.toString()
|
holder.v.findViewById<TextView>(R.id.comment_infos).text = comments[position].author.toString() + " • " + comments[position].commentedTime.toString()
|
||||||
holder.v.findViewById<TextView>(R.id.comment_text).text = comments[position].commentText.toString()
|
holder.v.findViewById<TextView>(R.id.comment_text).text = comments[position].commentText.toString()
|
||||||
val thumbnailImage = holder.v.findViewById<ImageView>(R.id.commentor_image)
|
val channelImage = holder.v.findViewById<ImageView>(R.id.commentor_image)
|
||||||
Picasso.get().load(comments[position].thumbnail).fit().centerCrop().into(thumbnailImage)
|
Picasso.get().load(comments[position].thumbnail).fit().centerCrop().into(channelImage)
|
||||||
holder.v.findViewById<TextView>(R.id.likes_textView).text = comments[position].likeCount?.toLong().formatShort()
|
holder.v.findViewById<TextView>(R.id.likes_textView).text = comments[position].likeCount?.toLong().formatShort()
|
||||||
if (comments[position].verified == true) {
|
if (comments[position].verified == true) {
|
||||||
holder.v.findViewById<ImageView>(R.id.verified_imageView).visibility = View.VISIBLE
|
holder.v.findViewById<ImageView>(R.id.verified_imageView).visibility = View.VISIBLE
|
||||||
@ -39,6 +43,20 @@ class CommentsAdapter(private val comments: MutableList<Comment>): RecyclerView
|
|||||||
if (comments[position].hearted == true) {
|
if (comments[position].hearted == true) {
|
||||||
holder.v.findViewById<ImageView>(R.id.hearted_imageView).visibility = View.VISIBLE
|
holder.v.findViewById<ImageView>(R.id.hearted_imageView).visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
channelImage.setOnClickListener{
|
||||||
|
val activity = holder.v.context as MainActivity
|
||||||
|
val bundle = bundleOf("channel_id" to comments[position].commentorUrl)
|
||||||
|
activity.navController.navigate(R.id.channel, bundle)
|
||||||
|
try {
|
||||||
|
val mainMotionLayout = activity.findViewById<MotionLayout>(R.id.mainMotionLayout)
|
||||||
|
if (mainMotionLayout.progress == 0.toFloat()) {
|
||||||
|
mainMotionLayout.transitionToEnd()
|
||||||
|
activity.findViewById<MotionLayout>(R.id.playerMotionLayout).transitionToEnd()
|
||||||
|
}
|
||||||
|
}catch (e: Exception){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
|
12
app/src/main/java/com/github/libretube/obj/Segment.kt
Normal file
12
app/src/main/java/com/github/libretube/obj/Segment.kt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package com.github.libretube.obj
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||||
|
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
data class Segment(
|
||||||
|
val actionType: String?,
|
||||||
|
val category: String?,
|
||||||
|
val segment: List<Float>?
|
||||||
|
){
|
||||||
|
constructor(): this("", "", arrayListOf())
|
||||||
|
}
|
10
app/src/main/java/com/github/libretube/obj/Segments.kt
Normal file
10
app/src/main/java/com/github/libretube/obj/Segments.kt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package com.github.libretube.obj
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||||
|
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
data class Segments(
|
||||||
|
val segments: MutableList<Segment> = arrayListOf()
|
||||||
|
){
|
||||||
|
constructor(): this(arrayListOf())
|
||||||
|
}
|
13
app/src/main/res/drawable/ic_sponsorblock.xml
Normal file
13
app/src/main/res/drawable/ic_sponsorblock.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M12,22.7994C11.55,22.7994 11.1,22.7094 10.74,22.4394 4.89,18.8394 1.29,12.6294 1.2,5.7894 1.2,4.8894 1.65,3.9894 2.46,3.5394 8.4,0.3894 15.6,0.3894 21.54,3.6294 22.35,3.9894 22.8,4.8894 22.8,5.7894 22.71,12.6294 19.11,18.8394 13.35,22.4394 12.9,22.7094 12.45,22.7994 12,22.7994ZM12,1.9194c-3.15,0 -6.3,0.81 -9.18,2.34 -0.54,0.27 -0.9,0.9 -0.9,1.53 0.09,6.57 3.51,12.51 9.18,16.02 0.54,0.36 1.26,0.36 1.8,0C18.57,18.3894 21.9,12.3594 22.08,5.7894 22.08,5.1594 21.72,4.5294 21.18,4.2594 18.3,2.7294 15.15,1.9194 12,1.9194Z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M20.73,4.9794C15.24,2.0994 8.76,2.0994 3.27,4.9794 3,5.1594 2.82,5.4294 2.82,5.7894c0.09,6.48 3.51,12.06 8.73,15.3 0.27,0.18 0.63,0.18 0.9,0 5.13,-3.15 8.64,-8.82 8.73,-15.3C21.18,5.4294 21,5.1594 20.73,4.9794ZM9.66,15.1494L9.66,6.7794l7.29,4.23z"/>
|
||||||
|
</vector>
|
@ -9,8 +9,8 @@
|
|||||||
>
|
>
|
||||||
<de.hdodenhof.circleimageview.CircleImageView
|
<de.hdodenhof.circleimageview.CircleImageView
|
||||||
android:id="@+id/subscription_channel_image"
|
android:id="@+id/subscription_channel_image"
|
||||||
android:layout_width="60dp"
|
android:layout_width="50dp"
|
||||||
android:layout_height="60dp"
|
android:layout_height="50dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginBottom="4dp"/>
|
android:layout_marginBottom="4dp"/>
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -44,6 +44,10 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/channel_name"
|
android:id="@+id/channel_name"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -54,6 +58,16 @@
|
|||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/channel_verified"
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
android:layout_margin="7dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:src="@drawable/ic_verified" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/channel_subs"
|
android:id="@+id/channel_subs"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -81,20 +95,9 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
android:layout_marginBottom="5dp"
|
android:layout_marginBottom="15dp"
|
||||||
android:text="" />
|
android:text="" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="10dp"
|
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
android:layout_marginRight="10dp"
|
|
||||||
android:layout_marginBottom="5dp"
|
|
||||||
android:text="@string/videos"
|
|
||||||
android:textSize="17sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -54,12 +54,35 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/toggle_subs"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="12dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/subscriptions"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:src="@drawable/ic_arrow_down"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:descendantFocusability="blocksDescendants">
|
android:descendantFocusability="blocksDescendants">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:visibility="gone"
|
||||||
android:id="@+id/sub_channels"
|
android:id="@+id/sub_channels"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -470,6 +470,19 @@
|
|||||||
<item>L</item>
|
<item>L</item>
|
||||||
<item>D</item>
|
<item>D</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="tabs">
|
||||||
|
<item>@string/startpage</item>
|
||||||
|
<item>@string/subscriptions</item>
|
||||||
|
<item>@string/library</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="tabsValue">
|
||||||
|
<item>home</item>
|
||||||
|
<item>subscriptions</item>
|
||||||
|
<item>library</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="defres">
|
<string-array name="defres">
|
||||||
<item>HLS</item>
|
<item>HLS</item>
|
||||||
<item>1080p</item>
|
<item>1080p</item>
|
||||||
|
@ -84,4 +84,21 @@
|
|||||||
<string name="music_videos">Music Videos</string>
|
<string name="music_videos">Music Videos</string>
|
||||||
<string name="music_albums">Music Albums</string>
|
<string name="music_albums">Music Albums</string>
|
||||||
<string name="music_playlists">Music Playlists</string>
|
<string name="music_playlists">Music Playlists</string>
|
||||||
|
<string name="defaultTab">Default Tab</string>
|
||||||
|
<string name="sponsorblock">SponsorBlock</string>
|
||||||
|
<string name="sponsorblock_summary">Uses API from https://sponsor.ajay.app/</string>
|
||||||
|
<string name="segment_skipped">Skipped segment.</string>
|
||||||
|
<string name="category_header_title">SponsorBlock</string>
|
||||||
|
<string name="sponsorblock_state">Enabled</string>
|
||||||
|
<string name="category_segments">Segments</string>
|
||||||
|
<string name="category_sponsor">Sponsor</string>
|
||||||
|
<string name="category_sponsor_description">Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free shoutouts to causes/creators/websites/products they like.</string>
|
||||||
|
<string name="category_selfpromo">Unpaid/Self Promotion</string>
|
||||||
|
<string name="category_selfpromo_description">Similar to \"sponsor\" except for unpaid or self promotion. This includes sections about merchandise, donations, or information about who they collaborated with.</string>
|
||||||
|
<string name="category_interaction">Interaction Reminder (Subscribe)</string>
|
||||||
|
<string name="category_interaction_description">When there is a short reminder to like, subscribe or follow them in the middle of content. If it is long or about something specific, it should be under self promotion instead.</string>
|
||||||
|
<string name="category_intro">Intermission/Intro Animation</string>
|
||||||
|
<string name="category_intro_description">An interval without actual content. Could be a pause, static frame, repeating animation. This should not be used for transitions containing information.</string>
|
||||||
|
<string name="category_outro">Endcards/Credits</string>
|
||||||
|
<string name="category_outro_description">Credits or when the YouTube endcards appear. Not for conclusions with information.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -71,6 +71,22 @@
|
|||||||
android:icon="@drawable/ic_theme"
|
android:icon="@drawable/ic_theme"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<androidx.preference.Preference
|
||||||
|
app:title="@string/sponsorblock"
|
||||||
|
app:key="sponsorblock"
|
||||||
|
app:summary="@string/sponsorblock_summary"
|
||||||
|
android:icon="@drawable/ic_sponsorblock"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<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"
|
||||||
|
/>
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
app:title="@string/defres"
|
app:title="@string/defres"
|
||||||
app:key="default_res"
|
app:key="default_res"
|
||||||
|
40
app/src/main/res/xml/sponsorblock_settings.xml
Normal file
40
app/src/main/res/xml/sponsorblock_settings.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?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/category_header_title">
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
app:key="sponsorblock_enabled_key"
|
||||||
|
app:title="@string/sponsorblock_state"/>
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory app:title="@string/category_segments">
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
app:key="sponsors_category_key"
|
||||||
|
app:title="@string/category_sponsor"
|
||||||
|
app:summary="@string/category_sponsor_description"/>
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
app:key="selfpromo_category_key"
|
||||||
|
app:title="@string/category_selfpromo"
|
||||||
|
app:summary="@string/category_selfpromo_description"/>
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
app:key="interaction_category_key"
|
||||||
|
app:title="@string/category_interaction"
|
||||||
|
app:summary="@string/category_interaction_description"/>
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
app:key="intro_category_key"
|
||||||
|
app:title="@string/category_intro"
|
||||||
|
app:summary="@string/category_intro_description"/>
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
app:key="outro_category_key"
|
||||||
|
app:title="@string/category_outro"
|
||||||
|
app:summary="@string/category_outro_description"/>
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
</androidx.preference.PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user