Merge branch 'master' into filter

This commit is contained in:
Bnyro 2022-05-16 18:17:19 +02:00 committed by GitHub
commit ce00408baa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 364 additions and 25 deletions

View File

@ -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)

View File

@ -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 -> {

View File

@ -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

View File

@ -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

View File

@ -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())

View File

@ -39,7 +39,9 @@ class SettingsActivity : AppCompatActivity(),
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
overridePendingTransition(50, 50); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
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)

View File

@ -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
}
}
}

View File

@ -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 {

View File

@ -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 {

View 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())
}

View 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())
}

View 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>

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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>

View File

@ -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>

View File

@ -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"

View 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>