Merge branch 'master' into nowifi

This commit is contained in:
Bnyro 2022-05-11 08:06:42 +02:00 committed by GitHub
commit b147dcbafe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 350 additions and 53 deletions

View File

@ -10,6 +10,12 @@ interface PipedApi {
@GET("streams/{videoId}") @GET("streams/{videoId}")
suspend fun getStreams(@Path("videoId") videoId: String): Streams suspend fun getStreams(@Path("videoId") videoId: String): Streams
@GET("comments/{videoId}")
suspend fun getComments(@Path("videoId") videoId: String): CommentsPage
@GET("nextpage/comments/{videoId}")
suspend fun getCommentsNextPage(@Path("videoId") videoId: String, @Query("nextpage") nextPage: String): CommentsPage
@GET("search") @GET("search")
suspend fun getSearchResults( suspend fun getSearchResults(
@Query("q") searchQuery: String, @Query("q") searchQuery: String,

View File

@ -31,7 +31,9 @@ import androidx.fragment.app.Fragment
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
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
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.Subscribe import com.github.libretube.obj.Subscribe
@ -75,6 +77,10 @@ class PlayerFragment : Fragment() {
var isSubscribed: Boolean = false var isSubscribed: Boolean = false
private lateinit var relatedRecView: RecyclerView private lateinit var relatedRecView: RecyclerView
private lateinit var commentsRecView: RecyclerView
private var commentsAdapter: CommentsAdapter? = null
private var nextPage: String? = null
private var isLoading = true
private lateinit var exoPlayerView: StyledPlayerView private lateinit var exoPlayerView: StyledPlayerView
private lateinit var motionLayout: MotionLayout private lateinit var motionLayout: MotionLayout
private lateinit var exoPlayer: ExoPlayer private lateinit var exoPlayer: ExoPlayer
@ -192,10 +198,15 @@ class PlayerFragment : Fragment() {
} }
view.findViewById<RelativeLayout>(R.id.player_title_layout).setOnClickListener { view.findViewById<RelativeLayout>(R.id.player_title_layout).setOnClickListener {
var visible = playerDescription.isVisible playerDescription.visibility =
if (playerDescription.isVisible) View.GONE else View.VISIBLE
playerDescription.visibility = if (visible) View.GONE else View.VISIBLE
} }
view.findViewById<ConstraintLayout>(R.id.comments_toggle).setOnClickListener {
commentsRecView.visibility = if (commentsRecView.isVisible) View.GONE else View.VISIBLE
relatedRecView.visibility = if (relatedRecView.isVisible) View.GONE else View.VISIBLE
}
// FullScreen button trigger // FullScreen button trigger
view.findViewById<ImageButton>(R.id.fullscreen).setOnClickListener { view.findViewById<ImageButton>(R.id.fullscreen).setOnClickListener {
// remember to hide everything when new thing added // remember to hide everything when new thing added
@ -221,6 +232,25 @@ class PlayerFragment : Fragment() {
isFullScreen = false isFullScreen = false
} }
} }
val scrollView = view.findViewById<ScrollView>(R.id.player_scrollView)
scrollView.viewTreeObserver
.addOnScrollChangedListener {
if (scrollView.getChildAt(0).bottom
== (scrollView.height + scrollView.scrollY)
) {
fetchNextComments()
}
}
commentsRecView = view.findViewById(R.id.comments_recView)
commentsRecView.layoutManager = LinearLayoutManager(view.context)
commentsRecView.setItemViewCacheSize(20)
commentsRecView.setDrawingCacheEnabled(true)
commentsRecView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH)
relatedRecView = view.findViewById(R.id.player_recView) relatedRecView = view.findViewById(R.id.player_recView)
relatedRecView.layoutManager = relatedRecView.layoutManager =
GridLayoutManager(view.context, resources.getInteger(R.integer.grid_items)) GridLayoutManager(view.context, resources.getInteger(R.integer.grid_items))
@ -253,6 +283,19 @@ 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
} }
val commentsResponse = try {
RetrofitInstance.api.getComments(videoId!!)
} 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
var videosNameArray: Array<CharSequence> = arrayOf() var videosNameArray: Array<CharSequence> = arrayOf()
videosNameArray += "HLS" videosNameArray += "HLS"
for (vid in response.videoStreams!!) { for (vid in response.videoStreams!!) {
@ -476,7 +519,11 @@ class PlayerFragment : Fragment() {
} }
} }
}) })
commentsAdapter = CommentsAdapter(commentsResponse.comments)
commentsRecView.adapter = commentsAdapter
nextPage = commentsResponse.nextpage
relatedRecView.adapter = TrendingAdapter(response.relatedStreams!!) relatedRecView.adapter = TrendingAdapter(response.relatedStreams!!)
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)
@ -736,4 +783,25 @@ class PlayerFragment : Fragment() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
} }
private fun fetchNextComments(){
lifecycleScope.launchWhenCreated {
if (!isLoading) {
isLoading = true
val response = try {
RetrofitInstance.api.getCommentsNextPage(videoId!!, nextPage!!)
} catch (e: IOException) {
println(e)
Log.e(TAG, "IOException, you might not have internet connection")
return@launchWhenCreated
} catch (e: HttpException) {
Log.e(TAG, "HttpException, unexpected response," + e.response())
return@launchWhenCreated
}
nextPage = response.nextpage
commentsAdapter?.updateItems(response.comments!!)
isLoading = false
}
}
}
} }

View File

@ -0,0 +1,53 @@
package com.github.libretube.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R
import com.github.libretube.formatShort
import com.github.libretube.obj.Comment
import com.squareup.picasso.Picasso
class CommentsAdapter(private val comments: MutableList<Comment>): RecyclerView.Adapter<ViewHolder>(){
fun updateItems(newItems: List<Comment>){
var commentsSize = comments.size
comments.addAll(newItems)
notifyItemRangeInserted(commentsSize, newItems.size)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
var commentsView = LayoutInflater.from(parent.context).inflate(R.layout.comments_row, parent, false)
return ViewHolder(commentsView)
}
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_text).text = comments[position].commentText.toString()
val thumbnailImage = holder.v.findViewById<ImageView>(R.id.commentor_image)
Picasso.get().load(comments[position].thumbnail).fit().centerCrop().into(thumbnailImage)
holder.v.findViewById<TextView>(R.id.likes_textView).text = comments[position].likeCount?.toLong().formatShort()
if (comments[position].verified == true) {
holder.v.findViewById<ImageView>(R.id.verified_imageView).visibility = View.VISIBLE
}
if (comments[position].pinned == true) {
holder.v.findViewById<ImageView>(R.id.pinned_imageView).visibility = View.VISIBLE
}
if (comments[position].hearted == true) {
holder.v.findViewById<ImageView>(R.id.hearted_imageView).visibility = View.VISIBLE
}
}
override fun getItemCount(): Int {
return comments.size
}
}
class ViewHolder(val v: View): RecyclerView.ViewHolder(v){
init {
}
}

View File

@ -1,22 +0,0 @@
package com.github.libretube.obj;
public class Comment {
public String author, thumbnail, commentId, commentText, commentedTime, commentorUrl, repliesPage;
public int likeCount;
public boolean hearted, pinned, verified;
public Comment(String author, String thumbnail, String commentId, String commentText, String commentedTime,
String commentorUrl, String repliesPage, int likeCount, boolean hearted, boolean pinned, boolean verified) {
this.author = author;
this.thumbnail = thumbnail;
this.commentId = commentId;
this.commentText = commentText;
this.commentedTime = commentedTime;
this.commentorUrl = commentorUrl;
this.repliesPage = repliesPage;
this.likeCount = likeCount;
this.hearted = hearted;
this.pinned = pinned;
this.verified = verified;
}
}

View File

@ -0,0 +1,20 @@
package com.github.libretube.obj
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)
data class Comment(
val author: String?,
val commentId: String?,
val commentText: String?,
val commentedTime: String?,
val commentorUrl: String?,
val hearted: Boolean?,
val likeCount: Int?,
val pinned: Boolean?,
val thumbnail: String?,
val verified: Boolean?
){
constructor(): this("", "","","","",null,0,null,"",null)
}

View File

@ -1,16 +0,0 @@
package com.github.libretube.obj;
import java.util.List;
public class CommentsPage {
public List<Comment> comments;
public String nextpage;
public boolean disabled;
public CommentsPage(List<Comment> comments, String nextpage, boolean disabled) {
this.comments = comments;
this.nextpage = nextpage;
this.disabled = disabled;
}
}

View File

@ -0,0 +1,12 @@
package com.github.libretube.obj
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)
data class CommentsPage(
val comments: MutableList<Comment> = arrayListOf(),
val disabled: Boolean? = null,
val nextpage: String? = "",
){
constructor(): this(arrayListOf(),null,"")
}

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="66.911dp"
android:height="66.911dp"
android:viewportWidth="66.911"
android:viewportHeight="66.911">
<path
android:pathData="M66.911,22.831c0,-10.563 -8.558,-19.122 -19.118,-19.122c-5.658,0 -10.721,2.473 -14.223,6.377c-0.037,0.043 -0.076,0.085 -0.113,0.128c-3.5,-3.98 -8.618,-6.505 -14.334,-6.505C8.561,3.709 0.005,12.268 0,22.831c0,5.834 2.629,11.059 6.758,14.565H6.751l27.104,25.806l26.308,-25.806h-0.012C64.279,33.89 66.911,28.669 66.911,22.831z"
android:fillColor="#E34326"/>
</vector>

View File

@ -0,0 +1,11 @@
<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="@android:color/white"
android:pathData="M16,9V4l1,0c0.55,0 1,-0.45 1,-1v0c0,-0.55 -0.45,-1 -1,-1H7C6.45,2 6,2.45 6,3v0c0,0.55 0.45,1 1,1l1,0v5c0,1.66 -1.34,3 -3,3h0v2h5.97v7l1,1l1,-1v-7H19v-2h0C17.34,12 16,10.66 16,9z"
android:fillType="evenOdd"/>
</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="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M1,21h4L5,9L1,9v12zM23,10c0,-1.1 -0.9,-2 -2,-2h-6.31l0.95,-4.57 0.03,-0.32c0,-0.41 -0.17,-0.79 -0.44,-1.06L14.17,1 7.59,7.59C7.22,7.95 7,8.45 7,9v10c0,1.1 0.9,2 2,2h9c0.83,0 1.54,-0.5 1.84,-1.22l3.02,-7.05c0.09,-0.23 0.14,-0.47 0.14,-0.73v-2z"/>
</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="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M23,12l-2.44,-2.79l0.34,-3.69l-3.61,-0.82L15.4,1.5L12,2.96L8.6,1.5L6.71,4.69L3.1,5.5L3.44,9.2L1,12l2.44,2.79l-0.34,3.7l3.61,0.82L8.6,22.5l3.4,-1.47l3.4,1.46l1.89,-3.19l3.61,-0.82l-0.34,-3.69L23,12zM10.09,16.72l-3.8,-3.81l1.48,-1.48l2.32,2.33l5.85,-5.87l1.48,1.48L10.09,16.72z"/>
</vector>

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="?android:attr/selectableItemBackground"
android:layout_height="wrap_content">
<LinearLayout
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="16dp"
>
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/commentor_image"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="16dp"
app:srcCompat="@mipmap/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/comment_infos"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:text="Author and Time"
android:textSize="15sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/verified_imageView"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginTop="4dp"
android:layout_marginLeft="4dp"
app:srcCompat="@drawable/ic_verified"
android:visibility="gone" />
<ImageView
android:id="@+id/pinned_imageView"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginTop="4dp"
android:layout_marginLeft="4dp"
app:srcCompat="@drawable/ic_pinned"
android:visibility="gone" />
</LinearLayout>
<TextView
android:id="@+id/comment_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:text="Comment Text" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/likes_imageView"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginRight="6dp"
android:layout_marginTop="2dp"
app:srcCompat="@drawable/ic_thumb_up" />
<TextView
android:id="@+id/likes_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LikeCount" />
<ImageView
android:id="@+id/hearted_imageView"
android:layout_width="14dp"
android:layout_height="14dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="3dp"
app:srcCompat="@drawable/ic_hearted"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -9,7 +9,7 @@
tools:context=".PlayerFragment"> tools:context=".PlayerFragment">
<ScrollView <ScrollView
android:id="@+id/scrollView2" android:id="@+id/player_scrollView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:background="?attr/colorSurface" android:background="?attr/colorSurface"
@ -250,23 +250,56 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"> android:descendantFocusability="blocksDescendants">
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/tv_suggestion" android:id="@+id/comments_toggle"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="18dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="8dp"
android:orientation="horizontal">
<TextView
android:id="@+id/commentsToggle_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/comments"
android:textSize="17sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/commentsToggle_imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:src="@drawable/ic_arrow_down"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/comments_recView"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="10dp" android:layout_marginTop="20dp"
android:layout_marginTop="10dp" android:layout_marginLeft="20dp"
android:layout_marginRight="10dp" android:layout_marginRight="20dp"
android:text="More like that" android:layout_below="@id/comments_toggle"
android:textSize="17sp" android:nestedScrollingEnabled="false"
android:visibility="gone"/> android:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/player_recView" android:id="@+id/player_recView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/tv_suggestion" android:layout_below="@id/comments_recView"
android:layout_margin="10dp" android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:nestedScrollingEnabled="false" /> android:nestedScrollingEnabled="false" />
</RelativeLayout> </RelativeLayout>

View File

@ -65,4 +65,5 @@
<string name="subscribers">%1$s subscribers</string> <string name="subscribers">%1$s subscribers</string>
<string name="noInternet">No Internet Connection</string> <string name="noInternet">No Internet Connection</string>
<string name="retry">Retry</string> <string name="retry">Retry</string>
<string name="comments">Comments</string>
</resources> </resources>