mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 22:30:30 +05:30
Merge branch 'libre-tube:master' into master
This commit is contained in:
commit
275f304472
@ -6,7 +6,7 @@ import kotlinx.serialization.Serializable
|
||||
data class Comment(
|
||||
val author: String,
|
||||
val commentId: String,
|
||||
val commentText: String,
|
||||
val commentText: String?,
|
||||
val commentedTime: String,
|
||||
val commentorUrl: String,
|
||||
val repliesPage: String? = null,
|
||||
|
@ -18,4 +18,5 @@ object IntentData {
|
||||
const val downloading = "downloading"
|
||||
const val openAudioPlayer = "openAudioPlayer"
|
||||
const val fragmentToOpen = "fragmentToOpen"
|
||||
const val replyPage = "replyPage"
|
||||
}
|
||||
|
@ -1,42 +1,33 @@
|
||||
package com.github.libretube.ui.adapters
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.util.Log
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import android.widget.Toast
|
||||
import androidx.core.text.parseAsHtml
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.api.obj.Comment
|
||||
import com.github.libretube.api.obj.CommentsPage
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.databinding.CommentsRowBinding
|
||||
import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.extensions.formatShort
|
||||
import com.github.libretube.ui.fragments.CommentsRepliesFragment
|
||||
import com.github.libretube.ui.viewholders.CommentsViewHolder
|
||||
import com.github.libretube.util.ClipboardHelper
|
||||
import com.github.libretube.util.ImageHelper
|
||||
import com.github.libretube.util.NavigationHelper
|
||||
import com.github.libretube.util.TextUtils
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class CommentsAdapter(
|
||||
private val fragment: Fragment?,
|
||||
private val videoId: String,
|
||||
private val comments: MutableList<Comment>,
|
||||
private val isRepliesAdapter: Boolean = false,
|
||||
private val dismiss: () -> Unit
|
||||
) : RecyclerView.Adapter<CommentsViewHolder>() {
|
||||
|
||||
private var isLoading = false
|
||||
private lateinit var repliesPage: CommentsPage
|
||||
|
||||
fun clear() {
|
||||
val size: Int = comments.size
|
||||
comments.clear()
|
||||
@ -59,15 +50,8 @@ class CommentsAdapter(
|
||||
override fun onBindViewHolder(holder: CommentsViewHolder, position: Int) {
|
||||
val comment = comments[position]
|
||||
holder.binding.apply {
|
||||
if (isRepliesAdapter) {
|
||||
root.scaleX = REPLIES_ADAPTER_SCALE
|
||||
root.scaleY = REPLIES_ADAPTER_SCALE
|
||||
commentorImage.scaleX = REPLIES_ADAPTER_SCALE
|
||||
commentorImage.scaleY = REPLIES_ADAPTER_SCALE
|
||||
}
|
||||
|
||||
commentInfos.text = comment.author + TextUtils.SEPARATOR + comment.commentedTime
|
||||
commentText.text = comment.commentText.parseAsHtml()
|
||||
commentText.text = comment.commentText?.parseAsHtml()
|
||||
|
||||
ImageHelper.loadImage(comment.thumbnail, commentorImage)
|
||||
likesTextView.text = comment.likeCount.formatShort()
|
||||
@ -85,79 +69,31 @@ class CommentsAdapter(
|
||||
dismiss.invoke()
|
||||
}
|
||||
|
||||
repliesRecView.layoutManager = LinearLayoutManager(root.context)
|
||||
val repliesAdapter = CommentsAdapter(videoId, mutableListOf(), true, dismiss)
|
||||
repliesRecView.adapter = repliesAdapter
|
||||
if (!isRepliesAdapter && comment.repliesPage != null) {
|
||||
val repliesFragment = CommentsRepliesFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putString(IntentData.videoId, videoId)
|
||||
putString(IntentData.replyPage, comment.repliesPage)
|
||||
}
|
||||
}
|
||||
root.setOnClickListener {
|
||||
showMoreReplies(comment.repliesPage, showMore, repliesAdapter)
|
||||
fragment!!.parentFragmentManager
|
||||
.beginTransaction()
|
||||
.replace(R.id.commentFragContainer, repliesFragment)
|
||||
.addToBackStack(null)
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
|
||||
root.setOnLongClickListener {
|
||||
ClipboardHelper(root.context).save(comment.commentText)
|
||||
ClipboardHelper(root.context).save(comment.commentText ?: "")
|
||||
Toast.makeText(root.context, R.string.copied, Toast.LENGTH_SHORT).show()
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showMoreReplies(
|
||||
nextPage: String,
|
||||
showMoreBtn: Button,
|
||||
repliesAdapter: CommentsAdapter
|
||||
) {
|
||||
when (repliesAdapter.itemCount) {
|
||||
0 -> {
|
||||
fetchReplies(nextPage) {
|
||||
repliesAdapter.updateItems(it.comments)
|
||||
if (repliesPage.nextpage == null) {
|
||||
showMoreBtn.visibility = View.GONE
|
||||
return@fetchReplies
|
||||
}
|
||||
showMoreBtn.visibility = View.VISIBLE
|
||||
showMoreBtn.setOnClickListener { view ->
|
||||
if (repliesPage.nextpage == null) {
|
||||
view.visibility = View.GONE
|
||||
return@setOnClickListener
|
||||
}
|
||||
fetchReplies(
|
||||
repliesPage.nextpage!!
|
||||
) {
|
||||
repliesAdapter.updateItems(repliesPage.comments)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
repliesAdapter.clear()
|
||||
showMoreBtn.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return comments.size
|
||||
}
|
||||
|
||||
private fun fetchReplies(nextPage: String, onFinished: (CommentsPage) -> Unit) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (isLoading) return@launch
|
||||
isLoading = true
|
||||
repliesPage = try {
|
||||
RetrofitInstance.api.getCommentsNextPage(videoId, nextPage)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG(), "IOException, you might not have internet connection")
|
||||
return@launch
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
onFinished.invoke(repliesPage)
|
||||
}
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val REPLIES_ADAPTER_SCALE = 0.9f
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.github.libretube.ui.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.DialogFragment
|
||||
@ -24,11 +25,12 @@ class CreatePlaylistDialog(
|
||||
|
||||
binding.clonePlaylist.setOnClickListener {
|
||||
val playlistUrl = binding.playlistUrl.text.toString()
|
||||
if (!TextUtils.validateUrl(playlistUrl)) {
|
||||
val playlistId = Uri.parse(playlistUrl).getQueryParameter("list")
|
||||
if (!TextUtils.validateUrl(playlistUrl) || playlistId == null) {
|
||||
Toast.makeText(context, R.string.invalid_url, Toast.LENGTH_SHORT).show()
|
||||
return@setOnClickListener
|
||||
}
|
||||
PlaylistsHelper.clonePlaylist(requireContext().applicationContext, playlistUrl)
|
||||
PlaylistsHelper.clonePlaylist(requireContext().applicationContext, playlistId)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,76 @@
|
||||
package com.github.libretube.ui.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.databinding.FragmentCommentsBinding
|
||||
import com.github.libretube.ui.adapters.CommentsAdapter
|
||||
import com.github.libretube.ui.models.CommentsViewModel
|
||||
|
||||
class CommentsMainFragment : Fragment() {
|
||||
private lateinit var binding: FragmentCommentsBinding
|
||||
private lateinit var commentsAdapter: CommentsAdapter
|
||||
|
||||
private val viewModel: CommentsViewModel by activityViewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = FragmentCommentsBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.commentsRV.layoutManager = LinearLayoutManager(requireContext())
|
||||
binding.commentsRV.setItemViewCacheSize(20)
|
||||
|
||||
binding.commentsRV.viewTreeObserver
|
||||
.addOnScrollChangedListener {
|
||||
if (!binding.commentsRV.canScrollVertically(1)) {
|
||||
viewModel.fetchNextComments()
|
||||
}
|
||||
}
|
||||
|
||||
commentsAdapter = CommentsAdapter(
|
||||
this,
|
||||
viewModel.videoId!!,
|
||||
viewModel.commentsPage.value?.comments.orEmpty().toMutableList()
|
||||
) {
|
||||
viewModel.commentsSheetDismiss?.invoke()
|
||||
}
|
||||
binding.commentsRV.adapter = commentsAdapter
|
||||
|
||||
if (viewModel.commentsPage.value?.comments.orEmpty().isEmpty()) {
|
||||
binding.progress.visibility = View.VISIBLE
|
||||
viewModel.fetchComments()
|
||||
}
|
||||
|
||||
// listen for new comments to be loaded
|
||||
viewModel.commentsPage.observe(viewLifecycleOwner) {
|
||||
it ?: return@observe
|
||||
binding.progress.visibility = View.GONE
|
||||
if (it.disabled == true) {
|
||||
binding.errorTV.visibility = View.VISIBLE
|
||||
return@observe
|
||||
}
|
||||
if (it.comments.isEmpty()) {
|
||||
binding.errorTV.text = getString(R.string.no_comments_available)
|
||||
binding.errorTV.visibility = View.VISIBLE
|
||||
return@observe
|
||||
}
|
||||
commentsAdapter.updateItems(
|
||||
// only add the new comments to the recycler view
|
||||
it.comments.subList(commentsAdapter.itemCount, it.comments.size)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
package com.github.libretube.ui.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.api.obj.CommentsPage
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.databinding.FragmentCommentsBinding
|
||||
import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.ui.adapters.CommentsAdapter
|
||||
import com.github.libretube.ui.models.CommentsViewModel
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class CommentsRepliesFragment : Fragment() {
|
||||
private lateinit var binding: FragmentCommentsBinding
|
||||
private lateinit var repliesPage: CommentsPage
|
||||
private lateinit var repliesAdapter: CommentsAdapter
|
||||
private val viewModel: CommentsViewModel by activityViewModels()
|
||||
|
||||
private var isLoading = false
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = FragmentCommentsBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val videoId = arguments?.getString(IntentData.videoId) ?: ""
|
||||
val nextPage = arguments?.getString(IntentData.replyPage) ?: ""
|
||||
|
||||
repliesAdapter = CommentsAdapter(null, videoId, mutableListOf(), true) {
|
||||
viewModel.commentsSheetDismiss?.invoke()
|
||||
}
|
||||
|
||||
binding.commentsRV.layoutManager = LinearLayoutManager(view.context)
|
||||
binding.commentsRV.adapter = repliesAdapter
|
||||
|
||||
binding.commentsRV.viewTreeObserver
|
||||
.addOnScrollChangedListener {
|
||||
if (!binding.commentsRV.canScrollVertically(1) &&
|
||||
::repliesPage.isInitialized &&
|
||||
repliesPage.nextpage != null
|
||||
) {
|
||||
fetchReplies(videoId, repliesPage.nextpage!!) {
|
||||
repliesAdapter.updateItems(repliesPage.comments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadInitialReplies(videoId, nextPage, repliesAdapter)
|
||||
}
|
||||
|
||||
private fun loadInitialReplies(
|
||||
videoId: String,
|
||||
nextPage: String,
|
||||
repliesAdapter: CommentsAdapter
|
||||
) {
|
||||
when (repliesAdapter.itemCount) {
|
||||
0 -> {
|
||||
binding.progress.visibility = View.VISIBLE
|
||||
fetchReplies(videoId, nextPage) {
|
||||
repliesAdapter.updateItems(it.comments)
|
||||
binding.progress.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
repliesAdapter.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchReplies(
|
||||
videoId: String,
|
||||
nextPage: String,
|
||||
onFinished: (CommentsPage) -> Unit
|
||||
) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (isLoading) return@launch
|
||||
isLoading = true
|
||||
repliesPage = try {
|
||||
RetrofitInstance.api.getCommentsNextPage(videoId, nextPage)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG(), "IOException, you might not have internet connection")
|
||||
return@launch
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
onFinished.invoke(repliesPage)
|
||||
}
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ class CommentsViewModel : ViewModel() {
|
||||
|
||||
var videoId: String? = null
|
||||
var maxHeight: Int = 0
|
||||
var commentsSheetDismiss: (() -> Unit)? = null
|
||||
|
||||
fun fetchComments() {
|
||||
videoId ?: return
|
||||
|
@ -1,25 +1,24 @@
|
||||
package com.github.libretube.ui.sheets
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewTreeObserver
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import android.view.WindowManager
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.databinding.CommentsSheetBinding
|
||||
import com.github.libretube.extensions.dpToPx
|
||||
import com.github.libretube.ui.adapters.CommentsAdapter
|
||||
import com.github.libretube.ui.fragments.CommentsMainFragment
|
||||
import com.github.libretube.ui.fragments.CommentsRepliesFragment
|
||||
import com.github.libretube.ui.models.CommentsViewModel
|
||||
|
||||
class CommentsSheet : ExpandedBottomSheet() {
|
||||
private lateinit var binding: CommentsSheetBinding
|
||||
|
||||
private lateinit var commentsAdapter: CommentsAdapter
|
||||
|
||||
private val viewModel: CommentsViewModel by activityViewModels()
|
||||
private val commentsViewModel: CommentsViewModel by activityViewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@ -33,56 +32,83 @@ class CommentsSheet : ExpandedBottomSheet() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.dragHandle.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
||||
commentsViewModel.commentsSheetDismiss = this::dismiss
|
||||
|
||||
binding.apply {
|
||||
dragHandle.viewTreeObserver.addOnGlobalLayoutListener(object :
|
||||
ViewTreeObserver.OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
binding.dragHandle.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||
dragHandle.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||
|
||||
// limit the recyclerview height to not cover the video
|
||||
binding.commentsRV.updateLayoutParams {
|
||||
height = viewModel.maxHeight - (binding.dragHandle.height + 20.dpToPx().toInt())
|
||||
binding.standardBottomSheet.layoutParams =
|
||||
binding.commentFragContainer.layoutParams.apply {
|
||||
height = commentsViewModel.maxHeight
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
binding.commentsRV.layoutManager = LinearLayoutManager(requireContext())
|
||||
binding.commentsRV.setItemViewCacheSize(20)
|
||||
|
||||
binding.commentsRV.viewTreeObserver
|
||||
.addOnScrollChangedListener {
|
||||
if (!binding.commentsRV.canScrollVertically(1)) {
|
||||
viewModel.fetchNextComments()
|
||||
btnBack.setOnClickListener {
|
||||
if (childFragmentManager.backStackEntryCount > 0) {
|
||||
childFragmentManager.popBackStack()
|
||||
}
|
||||
}
|
||||
|
||||
commentsAdapter = CommentsAdapter(
|
||||
viewModel.videoId!!,
|
||||
viewModel.commentsPage.value?.comments.orEmpty().toMutableList()
|
||||
) {
|
||||
dialog?.dismiss()
|
||||
}
|
||||
binding.commentsRV.adapter = commentsAdapter
|
||||
|
||||
if (viewModel.commentsPage.value?.comments.orEmpty().isEmpty()) {
|
||||
binding.progress.visibility = View.VISIBLE
|
||||
viewModel.fetchComments()
|
||||
btnClose.setOnClickListener { dismiss() }
|
||||
}
|
||||
|
||||
// listen for new comments to be loaded
|
||||
viewModel.commentsPage.observe(viewLifecycleOwner) {
|
||||
it ?: return@observe
|
||||
binding.progress.visibility = View.GONE
|
||||
if (it.disabled == true) {
|
||||
binding.errorTV.visibility = View.VISIBLE
|
||||
return@observe
|
||||
childFragmentManager.apply {
|
||||
addOnBackStackChangedListener(this@CommentsSheet::onFragmentChanged)
|
||||
|
||||
beginTransaction()
|
||||
.replace(R.id.commentFragContainer, CommentsMainFragment())
|
||||
.runOnCommit(this@CommentsSheet::onFragmentChanged)
|
||||
.commit()
|
||||
}
|
||||
if (it.comments.isEmpty()) {
|
||||
binding.errorTV.text = getString(R.string.no_comments_available)
|
||||
binding.errorTV.visibility = View.VISIBLE
|
||||
return@observe
|
||||
}
|
||||
commentsAdapter.updateItems(
|
||||
// only add the new comments to the recycler view
|
||||
it.comments.subList(commentsAdapter.itemCount, it.comments.size)
|
||||
)
|
||||
|
||||
private fun onFragmentChanged() {
|
||||
childFragmentManager.findFragmentById(R.id.commentFragContainer)?.let {
|
||||
when (it) {
|
||||
is CommentsRepliesFragment -> {
|
||||
binding.btnBack.visibility = View.VISIBLE
|
||||
binding.commentsTitle.text = getString(R.string.replies)
|
||||
}
|
||||
else -> {
|
||||
binding.btnBack.visibility = View.GONE
|
||||
binding.commentsTitle.text = getString(R.string.comments)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface) {
|
||||
super.onDismiss(dialog)
|
||||
commentsViewModel.commentsSheetDismiss = null
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val dialog = super.onCreateDialog(savedInstanceState)
|
||||
|
||||
dialog.apply {
|
||||
setOnKeyListener { _, keyCode, _ ->
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
if (childFragmentManager.backStackEntryCount > 0) {
|
||||
childFragmentManager.popBackStack()
|
||||
return@setOnKeyListener true
|
||||
}
|
||||
}
|
||||
return@setOnKeyListener false
|
||||
}
|
||||
|
||||
window?.let {
|
||||
it.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)
|
||||
it.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
||||
}
|
||||
|
||||
setCanceledOnTouchOutside(false)
|
||||
}
|
||||
|
||||
return dialog
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/rounded_ripple">
|
||||
android:background="?selectableItemBackground">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@ -25,9 +25,10 @@
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/commentor_image"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="@android:color/darker_gray"
|
||||
app:shapeAppearance="@style/CircleImageView"
|
||||
app:srcCompat="@mipmap/ic_launcher" />
|
||||
|
||||
@ -47,8 +48,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="bold"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/text_color_secondary"
|
||||
tools:text="Author and Time" />
|
||||
|
||||
<ImageView
|
||||
@ -74,7 +75,9 @@
|
||||
android:id="@+id/comment_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:textSize="15sp"
|
||||
android:autoLink="web"
|
||||
tools:text="Comment Text" />
|
||||
|
||||
@ -120,7 +123,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
tools:text="LikeCount" />
|
||||
tools:text="ReplyCount" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -128,26 +131,5 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/replies_recView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@null"
|
||||
android:nestedScrollingEnabled="false" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/show_more"
|
||||
style="@style/Widget.Material3.Button.ElevatedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginVertical="8dp"
|
||||
android:stateListAnimator="@null"
|
||||
android:text="@string/show_more"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
app:cornerRadius="20dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?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:layout_height="match_parent">
|
||||
|
||||
@ -9,7 +10,6 @@
|
||||
style="@style/Widget.Material3.BottomSheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="20dp"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
|
||||
|
||||
<LinearLayout
|
||||
@ -20,35 +20,56 @@
|
||||
<!-- Drag handle for accessibility -->
|
||||
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
|
||||
android:id="@+id/drag_handle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="20dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="0dp"
|
||||
app:tint="@color/drag_handle_color" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:paddingHorizontal="10dp"
|
||||
android:paddingBottom="7dp"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:visibility="gone"
|
||||
android:src="?homeAsUpIndicator"
|
||||
android:padding="7dp"
|
||||
android:background="?selectableItemBackgroundBorderless" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/commentsTitle"
|
||||
style="@style/TextAppearance.Material3.ActionBar.Title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginHorizontal="10dp"
|
||||
tools:text="Title" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/btnClose"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:src="@drawable/ic_close"
|
||||
android:padding="7dp"
|
||||
android:background="?selectableItemBackgroundBorderless" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.divider.MaterialDivider
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/commentFragContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/commentsRV"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/errorTV"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginVertical="5dp"
|
||||
android:text="@string/comments_disabled"
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
29
app/src/main/res/layout/fragment_comments.xml
Normal file
29
app/src/main/res/layout/fragment_comments.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/commentsRV"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="15dp"
|
||||
android:clipToPadding="false" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/errorTV"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginVertical="5dp"
|
||||
android:text="@string/comments_disabled"
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
5
app/src/main/res/values-night/colors.xml
Normal file
5
app/src/main/res/values-night/colors.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="text_color_secondary">#BFBFBF</color>
|
||||
<color name="drag_handle_color">#3A3A3A</color>
|
||||
</resources>
|
@ -190,8 +190,8 @@
|
||||
<string name="notifications">Notificações</string>
|
||||
<string name="notify_new_streams_summary">Notificações sobre novo conteúdo de criadores que você segue.</string>
|
||||
<string name="checking_frequency">Verificando a cada…</string>
|
||||
<string name="new_streams_count">%1$s novas transmissões estão disponíveis</string>
|
||||
<string name="new_streams_by">Novas transmissôes por %1$s …</string>
|
||||
<string name="new_streams_count">%1$s novos vídeos estão disponíveis</string>
|
||||
<string name="new_streams_by">Novos vídeos de %1$s…</string>
|
||||
<string name="irreversible">Tem certeza\? Isto não pode ser desfeito!</string>
|
||||
<string name="least_views">Menos visualizações</string>
|
||||
<string name="channel_name_az">Nome do canal (A-Z)</string>
|
||||
@ -267,7 +267,7 @@
|
||||
<string name="instance_frontend_url">URL para a interface da instância</string>
|
||||
<string name="quality">Qualidade</string>
|
||||
<string name="behavior">Comportamento</string>
|
||||
<string name="seek_increment">Buscar incremento</string>
|
||||
<string name="seek_increment">Incremento de avanço/retrocesso</string>
|
||||
<string name="pauseOnScreenOff">Pausa automática</string>
|
||||
<string name="pauseOnScreenOff_summary">Pausar quando a tela é desligada.</string>
|
||||
<string name="autoplay_summary">Reproduzir o próximo vídeo assim que o atual termina.</string>
|
||||
@ -307,7 +307,7 @@
|
||||
<string name="take_a_break">Hora de tirar uma pausa</string>
|
||||
<string name="resize_mode_fill">Preencher</string>
|
||||
<string name="repeat_mode_none">Nenhum</string>
|
||||
<string name="picture_in_picture">Imagem em imagem (PIP)</string>
|
||||
<string name="picture_in_picture">Imagem em imagem (PiP)</string>
|
||||
<string name="break_reminder_time">Minutos antes de ser lembrado</string>
|
||||
<string name="yt_shorts">Vídeos curtos</string>
|
||||
<string name="no_subtitles_available">Legendas não disponíveis</string>
|
||||
@ -315,7 +315,7 @@
|
||||
<string name="backup">Cópia de segurança</string>
|
||||
<string name="resize_mode_fit">Encaixar</string>
|
||||
<string name="repeat_mode_current">Atual</string>
|
||||
<string name="push_channel_description">Exibe uma notificação quando novas transmissões estão disponíveis.</string>
|
||||
<string name="push_channel_description">Exibe uma notificação quando novos vídeos estão disponíveis.</string>
|
||||
<string name="push_channel_name">Serviço de notificações</string>
|
||||
<string name="play_next">Reproduzir a seguir</string>
|
||||
<string name="background_channel_name">Modo de segundo plano</string>
|
||||
@ -405,7 +405,7 @@
|
||||
<string name="no_comments_available">Este vídeo não tem comentários disponíveis.</string>
|
||||
<string name="comments_disabled">O autor não permite comentários.</string>
|
||||
<string name="captions_size">Tamanho das legendas</string>
|
||||
<string name="double_tap_seek">Dois toques para buscar</string>
|
||||
<string name="double_tap_seek">Dois toques para avançar/retrodeceder</string>
|
||||
<string name="all_caught_up">Você está atualizado</string>
|
||||
<string name="all_caught_up_summary">Você viu todos os vídeos novos</string>
|
||||
<string name="double_tap_seek_summary">Toque duas vezes à esquerda ou à direita para retroceder ou avançar a posição do reprodutor.</string>
|
||||
@ -435,7 +435,7 @@
|
||||
<string name="forward">Avançar</string>
|
||||
<string name="pause">Pausar</string>
|
||||
<string name="alternative_pip_controls">Controles PiP alternativos</string>
|
||||
<string name="alternative_pip_controls_summary">Mostrar opções de apenas áudio e pular no PiP em vez de avançar e retroceder</string>
|
||||
<string name="alternative_pip_controls_summary">Exibir opções de apenas áudio e pular no PiP em vez de avançar e retroceder</string>
|
||||
<string name="audio_player">Reprodutor de áudio</string>
|
||||
<string name="no_subtitle">Sem legendas</string>
|
||||
<string name="download_paused">Transferência pausada</string>
|
||||
|
@ -36,7 +36,7 @@
|
||||
<string name="empty">Морате да унесете корисничко име и лозинку.</string>
|
||||
<string name="defres">Видео резолуција</string>
|
||||
<string name="grid">Мрежне колоне</string>
|
||||
<string name="emptyList">Нема ништа овде.</string>
|
||||
<string name="emptyList">Нема ништа.</string>
|
||||
<string name="addToPlaylist">Додај на листу</string>
|
||||
<string name="createPlaylist">Направи листу</string>
|
||||
<string name="library">Библиотека</string>
|
||||
@ -88,7 +88,7 @@
|
||||
<string name="color_red">Црвена</string>
|
||||
<string name="material_you">Системска</string>
|
||||
<string name="sponsorblock_notifications">Обавештења</string>
|
||||
<string name="app_icon">Иконица</string>
|
||||
<string name="app_icon">Икона</string>
|
||||
<string name="enabled">Укључено</string>
|
||||
<string name="disabled">Искључено</string>
|
||||
<string name="piped">Пајпед</string>
|
||||
@ -127,7 +127,7 @@
|
||||
<string name="version">Верзија %1$s</string>
|
||||
<string name="about_summary">Упознајте LibreTube тим и како све то функцијонише.</string>
|
||||
<string name="related_streams">Сличан садржај</string>
|
||||
<string name="related_streams_summary">Прикажите сличне садржаје испод оног што тренутно гледате.</string>
|
||||
<string name="related_streams_summary">Прикажите сличан садржај испод тренутног гледања.</string>
|
||||
<string name="show_chapters">Прикажи поглавља</string>
|
||||
<string name="hide_chapters">Сакриј поглавља</string>
|
||||
<string name="buffering_goal">Предучитавање</string>
|
||||
@ -182,8 +182,8 @@
|
||||
<string name="pure_theme_summary">Чиста бело/црна тема</string>
|
||||
<string name="no_player_found">Није пронађен екстерни плејер. Проверите да ли имате неки инсталиран.</string>
|
||||
<string name="data_saver_mode">Режим уштеде података</string>
|
||||
<string name="search_history_summary">Запамти претраге</string>
|
||||
<string name="watch_history_summary">Чувајте историју прегледа видеа локално</string>
|
||||
<string name="search_history_summary">Памти претраге</string>
|
||||
<string name="watch_history_summary">Чувајте историју прегледа снимака локално</string>
|
||||
<string name="watch_positions_title">Запамћене позиције репродукције</string>
|
||||
<string name="reset_watch_positions">Ресетуј</string>
|
||||
<string name="captions">Наслови</string>
|
||||
@ -267,7 +267,7 @@
|
||||
<string name="notify_new_streams">Обавештења о новим стримовима</string>
|
||||
<string name="checking_frequency">Провера на сваких …</string>
|
||||
<string name="new_streams_count">%1$s нових стримова је доступно</string>
|
||||
<string name="notify_new_streams_summary">Обавештења када буду доступни нови стримови из ваших претплата.</string>
|
||||
<string name="notify_new_streams_summary">Обавештења када буду доступни нови стримови из ваших праћења.</string>
|
||||
<string name="new_streams_by">Нови стримови од %1$s…</string>
|
||||
<string name="irreversible">Да ли сте сигурни\? Ово не може бити опозвано!</string>
|
||||
<string name="required_network">Потребна веза</string>
|
||||
@ -335,13 +335,13 @@
|
||||
<string name="play_next">Пусти следеће</string>
|
||||
<string name="playback_pitch">Висина тона</string>
|
||||
<string name="default_load_interval">Аутоматски</string>
|
||||
<string name="break_reminder_time">Неколико минута пре подсећања</string>
|
||||
<string name="break_reminder_time">Минута пре подсећања</string>
|
||||
<string name="change_region">Чини се да трендови нису доступни за тренутни регион. Молимо изаберите другу у подешавањима.</string>
|
||||
<string name="limit_hls">Ограничи HLS на 1080p</string>
|
||||
<string name="filename">Назив фајла</string>
|
||||
<string name="invalid_filename">Непостојеће име фајла!</string>
|
||||
<string name="playlists_order">Редослед плејлиста</string>
|
||||
<string name="playlistNameReversed">Назив плејлисте (обрнуто)</string>
|
||||
<string name="playlists_order">Редослед листи</string>
|
||||
<string name="playlistNameReversed">Назив листе (обрнуто)</string>
|
||||
<string name="recentlyUpdated">Недавно ажуриран</string>
|
||||
<string name="recentlyUpdatedReversed">Недавно ажурирано (обрнуто)</string>
|
||||
<string name="download_channel_name">Преузми услугу</string>
|
||||
@ -380,7 +380,7 @@
|
||||
<string name="defaultIconLight">Подразумевано светло</string>
|
||||
<string name="unsupported_file_format">Неподржан формат датотеке!</string>
|
||||
<string name="hls_instead_of_dash">Користи HLS</string>
|
||||
<string name="hls_instead_of_dash_summary">Користи HLS уместо DASH (биће спорије, не препоручује се)</string>
|
||||
<string name="hls_instead_of_dash_summary">Користи HLS уместо DASH (спорије, не препоручује се)</string>
|
||||
<string name="auto_quality">Аутоматски</string>
|
||||
<string name="limit_to_runtime">Ограничење времена коришћења</string>
|
||||
<string name="open_queue_from_notification">Отвори редослед из обавештења</string>
|
||||
@ -432,7 +432,7 @@
|
||||
<string name="forward">Премотај унапред</string>
|
||||
<string name="alternative_pip_controls">Алтернативне PiP контроле</string>
|
||||
<string name="alternative_pip_controls_summary">Приказивање само звука и прескакање контрола у PiP-у уместо унапред и уназад</string>
|
||||
<string name="audio_only_mode">Режим само звука</string>
|
||||
<string name="audio_only_mode">Режим аудио плејера</string>
|
||||
<string name="audio_only_mode_summary">Претвори LibreTube у музички плејер.</string>
|
||||
<string name="concurrent_downloads_limit_reached">Максимално истовремених преузимања је достигнуто.</string>
|
||||
<string name="pinch_control_summary">Користите покрет штипања за увећавање/умањивање.</string>
|
||||
@ -446,4 +446,8 @@
|
||||
<string name="shuffle">Насумично</string>
|
||||
<string name="remove_bookmark">Обриши обележивач</string>
|
||||
<string name="add_to_bookmarks">Додај у обележиваче</string>
|
||||
<string name="sleep_timer">Аутоматско искључење</string>
|
||||
<string name="skip_silence">Прескочи тишину</string>
|
||||
<string name="help">Помоћ</string>
|
||||
<string name="faq">Често постављена питања</string>
|
||||
</resources>
|
@ -401,4 +401,8 @@
|
||||
<string name="swipe_controls">Điều khiển vuốt</string>
|
||||
<string name="swipe_controls_summary">Sử dụng thao tác vuốt để điều chỉnh độ sáng và âm lượng.</string>
|
||||
<string name="bookmark">Đánh dấu trang</string>
|
||||
<string name="download_paused">Tạm dừng tải xuống</string>
|
||||
<string name="download_completed">Tải xuống hoàn tất</string>
|
||||
<string name="concurrent_downloads">Tải xuống đồng thời tối đa</string>
|
||||
<string name="no_subtitle">Không có phụ đề</string>
|
||||
</resources>
|
@ -24,8 +24,8 @@
|
||||
<string name="registered">註冊完成。現在你可以開始訂閱頻道了。</string>
|
||||
<string name="already_logged_in">已登入。請登出現有的帳號。</string>
|
||||
<string name="login_first">請登入並再試一次。</string>
|
||||
<string name="instances">選擇實體</string>
|
||||
<string name="customInstance">自訂實體</string>
|
||||
<string name="instances">選擇實例…</string>
|
||||
<string name="customInstance">自訂實例</string>
|
||||
<string name="region">地區</string>
|
||||
<string name="login_register">登入/註冊</string>
|
||||
<string name="please_login">請先登入或到設定裡註冊。</string>
|
||||
@ -55,7 +55,7 @@
|
||||
<string name="darkTheme">深色主題</string>
|
||||
<string name="subscribers">%1$s個訂閱者</string>
|
||||
<string name="settings">設定</string>
|
||||
<string name="instance">實體</string>
|
||||
<string name="instance">實例</string>
|
||||
<string name="customization">自訂</string>
|
||||
<string name="website">網站</string>
|
||||
<string name="videoCount">%1$s部影片</string>
|
||||
@ -93,12 +93,12 @@
|
||||
<string name="license">授權</string>
|
||||
<string name="color_accent">強調色</string>
|
||||
<string name="color_red">放鬆紅</string>
|
||||
<string name="color_blue">像素藍</string>
|
||||
<string name="color_blue">幸福藍</string>
|
||||
<string name="color_yellow">活力黃</string>
|
||||
<string name="color_green">時髦綠</string>
|
||||
<string name="color_purple">愉快紫</string>
|
||||
<string name="oledTheme">黑色主題</string>
|
||||
<string name="material_you">神秘質感3</string>
|
||||
<string name="oledTheme">黑色</string>
|
||||
<string name="material_you">Material You</string>
|
||||
<string name="sponsorblock_notifications">通知</string>
|
||||
<string name="app_icon">圖示</string>
|
||||
<string name="enabled">開啟</string>
|
||||
@ -113,10 +113,10 @@
|
||||
<string name="download_directory_summary">儲存下載影音的位置。</string>
|
||||
<string name="contributing">貢獻</string>
|
||||
<string name="donate">捐贈</string>
|
||||
<string name="update_summary">按這裡檢查APP是否為最新版本。</string>
|
||||
<string name="update_summary">按這裡檢查更新</string>
|
||||
<string name="app_uptodate">現在是最新版本。</string>
|
||||
<string name="playback_speed">預設播放速度</string>
|
||||
<string name="advanced_summary">播放器,下載,歷史</string>
|
||||
<string name="playback_speed">播放速度</string>
|
||||
<string name="advanced_summary">下載和重設</string>
|
||||
<string name="live">直播</string>
|
||||
<string name="no_replies">此留言無任何回覆。</string>
|
||||
<string name="authors">作者</string>
|
||||
@ -135,19 +135,19 @@
|
||||
<string name="flameIcon">飛馳烈焰</string>
|
||||
<string name="birdIcon">加速鳥兒</string>
|
||||
<string name="instance_summary">Piped,登入,訂閱</string>
|
||||
<string name="customInstance_summary">加入自訂實體 (風險自負)</string>
|
||||
<string name="instance_name">實體名稱</string>
|
||||
<string name="instance_api_url">實體API網址</string>
|
||||
<string name="addInstance">新增實體</string>
|
||||
<string name="customInstance_summary">加入實例</string>
|
||||
<string name="instance_name">實例名稱</string>
|
||||
<string name="instance_api_url">實例API網址</string>
|
||||
<string name="addInstance">新增實例</string>
|
||||
<string name="empty_instance">請填寫名稱和API網址欄位。</string>
|
||||
<string name="clear_customInstances">清除自訂實體</string>
|
||||
<string name="clear_customInstances">清除自訂實例</string>
|
||||
<string name="invalid_url">請填入有效的網址</string>
|
||||
<string name="version">版本%1$s</string>
|
||||
<string name="about_summary">認識LibretTube團隊,以及背後緣由。</string>
|
||||
<string name="related_streams">相關串流</string>
|
||||
<string name="related_streams">相關內容</string>
|
||||
<string name="related_streams_summary">在影片中顯示相關的串流。</string>
|
||||
<string name="show_chapters">顯示章節</string>
|
||||
<string name="buffering_goal">緩衝</string>
|
||||
<string name="buffering_goal">預先載入</string>
|
||||
<string name="yes">是</string>
|
||||
<string name="subscriptions">訂閱</string>
|
||||
<string name="library">媒體庫</string>
|
||||
@ -160,7 +160,7 @@
|
||||
<string name="about">關於</string>
|
||||
<string name="changeLanguage">語言</string>
|
||||
<string name="register">註冊</string>
|
||||
<string name="server_error">伺服器出了點問題。換個實體試試?</string>
|
||||
<string name="server_error">伺服器出了點問題。換個實例試試?</string>
|
||||
<string name="dlisinprogress">有其他下載正在進行,請等待所有下載完成…</string>
|
||||
<string name="systemLanguage">系統</string>
|
||||
<string name="okay">好</string>
|
||||
@ -181,7 +181,7 @@
|
||||
<string name="reset_message">是否重置所有設定並從實例登出?</string>
|
||||
<string name="deleteAccount">刪除帳號</string>
|
||||
<string name="deleteAccount_summary">刪除您於piped實例中的帳號</string>
|
||||
<string name="playerVideoFormat">播放器所使用的視頻格式</string>
|
||||
<string name="playerVideoFormat">播放器所使用的影片格式</string>
|
||||
<string name="audio">音頻</string>
|
||||
<string name="video">視訊</string>
|
||||
<string name="downloading">下載中…</string>
|
||||
@ -206,4 +206,248 @@
|
||||
<string name="no_video">無視訊</string>
|
||||
<string name="hls">HLS</string>
|
||||
<string name="clonePlaylist">拷貝播放清單</string>
|
||||
<string name="open">開啟…</string>
|
||||
<string name="playlistCloned">已複製播放清單</string>
|
||||
<string name="confirm_unsubscribing">確認取消訂閱</string>
|
||||
<string name="default_subtitle_language">字幕語言</string>
|
||||
<string name="local_playlists">本機播放清單</string>
|
||||
<string name="color_violet">多彩紫</string>
|
||||
<string name="push_channel_description">新串流上線時顯示通知。</string>
|
||||
<string name="chapters">章節</string>
|
||||
<string name="not_enabled">選單選項尚未啟用!</string>
|
||||
<string name="select_other_start_tab">請先在另一個啟動頁籤選取!</string>
|
||||
<string name="play_all">全部播放</string>
|
||||
<string name="volume">音量</string>
|
||||
<string name="brightness">亮度</string>
|
||||
<string name="auto">自動</string>
|
||||
<string name="swipe_controls">滑動控制</string>
|
||||
<string name="swipe_controls_summary">使用滑動手勢調整亮度和音量。</string>
|
||||
<string name="background_channel_description">在通知欄顯示附有按鈕的音訊播放器。</string>
|
||||
<string name="history_empty">尚無歷史紀錄。</string>
|
||||
<string name="notifications">通知</string>
|
||||
<string name="notify_new_streams">新串流通知</string>
|
||||
<string name="notify_new_streams_summary">您跟隨的創作者最新串流的通知。</string>
|
||||
<string name="wifi">Wi-Fi</string>
|
||||
<string name="pop_up">彈出</string>
|
||||
<string name="no_comments_available">這部影片沒有留言。</string>
|
||||
<string name="required_network">需要的連線</string>
|
||||
<string name="network_all">全部</string>
|
||||
<string name="pause">暫停</string>
|
||||
<string name="rewind">後退</string>
|
||||
<string name="forward">前進</string>
|
||||
<string name="all_caught_up">沒有更多了</string>
|
||||
<string name="repeat_mode">重複模式</string>
|
||||
<string name="resize_mode_fill">填滿</string>
|
||||
<string name="resize_mode_zoom">放大</string>
|
||||
<string name="background_mode">背景模式</string>
|
||||
<string name="add_to_queue">加入佇列</string>
|
||||
<string name="skip_segment">跳過片段</string>
|
||||
<string name="sb_skip_manual">手動跳過</string>
|
||||
<string name="sb_skip_manual_summary">不要自動跳過片段,總是事先提醒。</string>
|
||||
<string name="local_subscriptions">本機訂閱列表</string>
|
||||
<string name="preferences">偏好設定</string>
|
||||
<string name="playing_queue">播放佇列</string>
|
||||
<string name="queue">佇列</string>
|
||||
<string name="time">時長</string>
|
||||
<string name="start_time">開始時間</string>
|
||||
<string name="end_time">結束時間</string>
|
||||
<string name="notification_time">通知時長</string>
|
||||
<string name="notification_time_summary">通知顯示的時長。</string>
|
||||
<string name="download_completed">下載完成</string>
|
||||
<string name="failed_fetching_instances">無法取得可用實例。</string>
|
||||
<string name="play_next">播放下一部</string>
|
||||
<string name="community">社群</string>
|
||||
<string name="require_restart">需要重新啟動APP</string>
|
||||
<string name="auth_instance_summary">授權呼叫時使用不同的實例。</string>
|
||||
<string name="views_placeholder">觀看次數</string>
|
||||
<string name="concurrent_downloads">最大並行下載數</string>
|
||||
<string name="concurrent_downloads_limit_reached">已達到最大並行下載數。</string>
|
||||
<string name="unknown">未知</string>
|
||||
<string name="resume">繼續</string>
|
||||
<string name="pauseOnScreenOff">自動暫停</string>
|
||||
<string name="portrait">肖像</string>
|
||||
<string name="discord">Discord</string>
|
||||
<string name="matrix">Matrix</string>
|
||||
<string name="telegram">Telegram</string>
|
||||
<string name="turnInternetOn">請開啟Wifi或行動數據連上網路。</string>
|
||||
<string name="never">永不</string>
|
||||
<string name="change_playback_speed">播放速度</string>
|
||||
<string name="selected">已選取</string>
|
||||
<string name="navLabelVisibility">標籤可見度</string>
|
||||
<string name="always">總是</string>
|
||||
<string name="autoRotatePlayer">自動全螢幕</string>
|
||||
<string name="pure_theme">純粹主題</string>
|
||||
<string name="autoRotatePlayer_summary">裝置旋轉後自動全螢幕。</string>
|
||||
<string name="no_player_found">找不到外部播放器。請確認已安裝外部播放器。</string>
|
||||
<string name="data_saver_mode_summary">跳過縮圖和其他圖片。</string>
|
||||
<string name="data_saver_mode">數據節省模式</string>
|
||||
<string name="search_history_summary">記住搜尋</string>
|
||||
<string name="watch_history_summary">於本機儲存影片觀看歷史</string>
|
||||
<string name="history_summary">觀看和搜尋歷史</string>
|
||||
<string name="playerAudioQuality">音訊品質</string>
|
||||
<string name="captions_size">說明文字大小</string>
|
||||
<string name="sort">排序</string>
|
||||
<string name="skip_buttons_summary">顯示按鈕,跳至上一部或下一部影片。</string>
|
||||
<string name="take_a_break">是時候休息一下了</string>
|
||||
<string name="maximum_image_cache">最大圖片快取大小</string>
|
||||
<string name="device_info">裝置資訊</string>
|
||||
<string name="delete">從下載刪除</string>
|
||||
<string name="new_videos_badge">新影片的指示器</string>
|
||||
<string name="backup_customInstances">自訂實例</string>
|
||||
<string name="default_load_interval">預設</string>
|
||||
<string name="save_feed">在背景載入訂閱列表</string>
|
||||
<string name="limit_hls">將HLS限制為1080p</string>
|
||||
<string name="save_feed_summary">在背景載入訂閱列表,並防止自動重新載入。</string>
|
||||
<string name="progressive_load_interval">載入的進度間隔</string>
|
||||
<string name="filename">檔案名稱</string>
|
||||
<string name="recentlyUpdatedReversed">最近更新 (反序)</string>
|
||||
<string name="added_to_playlist">新增至播放清單</string>
|
||||
<string name="confirm_unsubscribe">您確定要取消訂閱 %1$s 嗎?</string>
|
||||
<string name="misc">雜項</string>
|
||||
<string name="player_resize_mode">重新調整大小模式</string>
|
||||
<string name="break_reminder_time">幾分鐘前提醒</string>
|
||||
<string name="break_reminder">休息提醒</string>
|
||||
<string name="resize_mode_fit">適應</string>
|
||||
<string name="copied_to_clipboard">複製到剪貼簿</string>
|
||||
<string name="repeat_mode_none">無</string>
|
||||
<string name="new_videos_badge_summary">如果有新影片,顯示數量徽章。</string>
|
||||
<string name="hide_watched_from_feed">從訂閱列表隱藏觀看過的影片</string>
|
||||
<string name="hide_watched_from_feed_summary">不要在訂閱列表頁籤顯示觀看進度90%以上的影片。</string>
|
||||
<string name="select_at_least_one">請至少選取一個項目</string>
|
||||
<string name="download_channel_name">下載服務</string>
|
||||
<string name="confirm_unsubscribing_summary">在取消訂閱前顯示確認對話框。</string>
|
||||
<string name="livestreams">直播</string>
|
||||
<string name="progressive_load_interval_summary">數值越低,影片初始載入可能就越慢。</string>
|
||||
<string name="invalid_filename">檔案名稱無效!</string>
|
||||
<string name="playback_pitch">音高</string>
|
||||
<string name="playlists_order">播放清單順序</string>
|
||||
<string name="playlistNameReversed">播放清單名稱 (反序)</string>
|
||||
<string name="recentlyUpdated">最近更新</string>
|
||||
<string name="pure_theme_summary">純粹白/黑主題</string>
|
||||
<string name="watch_positions_title">記住播放位置</string>
|
||||
<string name="reset_watch_positions">重設</string>
|
||||
<string name="none">無</string>
|
||||
<string name="system_caption_style">系統說明文字樣式</string>
|
||||
<string name="update_now">現在安裝新版本LibreTube嗎?</string>
|
||||
<string name="playingOnBackground">在背景播放…</string>
|
||||
<string name="downloading_apk">下載APK…</string>
|
||||
<string name="playerAudioFormat">播放器的音訊格式</string>
|
||||
<string name="new_streams_count">新增 %1$s 個串流</string>
|
||||
<string name="translate">翻譯</string>
|
||||
<string name="history_size">最大歷史紀錄</string>
|
||||
<string name="unlimited">無限</string>
|
||||
<string name="already_spent_time">你已花費%1$s 在此APP上,是時候休息一下了。</string>
|
||||
<string name="yt_shorts">短影片</string>
|
||||
<string name="repeat_mode_current">目前的</string>
|
||||
<string name="backup_restore">備份 & 還原</string>
|
||||
<string name="backup">備份</string>
|
||||
<string name="picture_in_picture">畫中畫</string>
|
||||
<string name="trending_layout">另外一種熱門影片版面</string>
|
||||
<string name="renamePlaylist">重新命名播放清單</string>
|
||||
<string name="mobile_data">行動數據</string>
|
||||
<string name="navigation_bar">導航列</string>
|
||||
<string name="change_region">目前的區域似乎無法使用熱門影片。請在設定中選取其他地區。</string>
|
||||
<string name="legacy_subscriptions">舊版訂閱列表</string>
|
||||
<string name="player_summary">預設值與行為</string>
|
||||
<string name="require_restart_message">重啟APP以套用變更。</string>
|
||||
<string name="seekbar_preview">影片預覽</string>
|
||||
<string name="seekbar_preview_summary">拖動播放指示器時顯示快照。</string>
|
||||
<string name="downloadsucceeded">下載成功</string>
|
||||
<string name="share_with_time">分享時包含時間戳</string>
|
||||
<string name="pinch_control_summary">使用手勢放大縮小。</string>
|
||||
<string name="defaults">預設</string>
|
||||
<string name="general_summary">語言和地區</string>
|
||||
<string name="worst_quality">最差</string>
|
||||
<string name="caption_settings">說明文字</string>
|
||||
<string name="least_recent">最舊</string>
|
||||
<string name="network_metered">監測</string>
|
||||
<string name="captions">說明文字</string>
|
||||
<string name="network_wifi">僅限Wifi</string>
|
||||
<string name="checking_frequency">檢查頻率…</string>
|
||||
<string name="most_views">最多觀看</string>
|
||||
<string name="channel_name_az">頻道名稱 (A-Z)</string>
|
||||
<string name="most_recent">最新</string>
|
||||
<string name="no_subtitles_available">無字幕可用</string>
|
||||
<string name="channel_name_za">頻道名稱 (Z-A)</string>
|
||||
<string name="new_streams_by">%1$s 的新串流…</string>
|
||||
<string name="irreversible">您確定嗎?此操作無法撤銷!</string>
|
||||
<string name="least_views">最少觀看</string>
|
||||
<string name="audio_video_summary">品質與格式</string>
|
||||
<string name="nothing_selected">沒有選取任何項目!</string>
|
||||
<string name="double_tap_seek">按二下快轉</string>
|
||||
<string name="backup_restore_summary">匯入&匯出訂閱列表,播放清單…</string>
|
||||
<string name="export_playlists">匯出播放清單</string>
|
||||
<string name="app_backup">應用程式備份</string>
|
||||
<string name="exportsuccess">已匯出。</string>
|
||||
<string name="privacy_alert">隱私警告</string>
|
||||
<string name="username_email">使用不推薦的電子郵件繼續嗎?</string>
|
||||
<string name="proceed">繼續</string>
|
||||
<string name="sb_markers">標記</string>
|
||||
<string name="sb_markers_summary">在時間軸上標記片段。</string>
|
||||
<string name="fullscreen_orientation">全螢幕方向</string>
|
||||
<string name="aspect_ratio">影片比例</string>
|
||||
<string name="auto_rotation">自動旋轉</string>
|
||||
<string name="landscape">風景</string>
|
||||
<string name="reddit">Reddit</string>
|
||||
<string name="twitter">Twitter</string>
|
||||
<string name="pinch_control">調整音高</string>
|
||||
<string name="play_latest_videos">播放最新影片</string>
|
||||
<string name="audio_track">音訊曲目</string>
|
||||
<string name="default_audio_track">預設</string>
|
||||
<string name="export_subscriptions">匯出訂閱列表</string>
|
||||
<string name="skip_buttons">跳過按鈕</string>
|
||||
<string name="no_search_result">無結果。</string>
|
||||
<string name="error_occurred">錯誤</string>
|
||||
<string name="copied">已複製</string>
|
||||
<string name="alternative_videos_layout">另一種影片版面</string>
|
||||
<string name="defaultIconLight">預設亮色</string>
|
||||
<string name="unsupported_file_format">檔案格式不支援!</string>
|
||||
<string name="open_copied">開啟</string>
|
||||
<string name="general">一般</string>
|
||||
<string name="audio_player">音訊播放器</string>
|
||||
<string name="playlistUrl">播放清單網址</string>
|
||||
<string name="background_channel_name">背景模式</string>
|
||||
<string name="download_channel_description">在下載媒體檔案時顯示通知。</string>
|
||||
<string name="push_channel_name">通知工作器</string>
|
||||
<string name="open_queue_from_notification">從通知開啟佇列</string>
|
||||
<string name="show_more">顯示更多</string>
|
||||
<string name="time_code">時間戳 (秒)</string>
|
||||
<string name="trends">熱門影片</string>
|
||||
<string name="featured">精選影片</string>
|
||||
<string name="audio_only_mode">純音訊模式</string>
|
||||
<string name="audio_only_mode_summary">將LibreTube變成音樂播放器。</string>
|
||||
<string name="no_subtitle">無字幕</string>
|
||||
<string name="download_paused">下載暫停</string>
|
||||
<string name="alternative_trending_layout">另一種熱門影片版面</string>
|
||||
<string name="navbar_order">排序</string>
|
||||
<string name="layout">版面</string>
|
||||
<string name="alternative_player_layout">另一種播放器版面</string>
|
||||
<string name="alternative_player_layout_summary">在留言上方顯示一排相關影片,而非留言下面。</string>
|
||||
<string name="hls_instead_of_dash">使用HLS</string>
|
||||
<string name="hls_instead_of_dash_summary">使用HLS而非DASH (較慢,不推薦)</string>
|
||||
<string name="auto_quality">自動</string>
|
||||
<string name="trending">現正熱門</string>
|
||||
<string name="comments_disabled">上傳者停用了留言功能。</string>
|
||||
<string name="theme_monochrome">極簡單色</string>
|
||||
<string name="pause_on_quit">退出後暫停</string>
|
||||
<string name="queue_insert_related_videos">插入相關影片</string>
|
||||
<string name="bookmarks">書籤</string>
|
||||
<string name="bookmark">加入書籤</string>
|
||||
<string name="clear_bookmarks">清除書籤</string>
|
||||
<string name="bookmarks_empty">沒有書籤!</string>
|
||||
<string name="shuffle">隨機</string>
|
||||
<string name="add_to_bookmarks">新增至書籤</string>
|
||||
<string name="remove_bookmark">移除書籤</string>
|
||||
<string name="double_tap_seek_summary">按螢幕左邊或右邊二下快轉影片。</string>
|
||||
<string name="limit_to_runtime">限制執行時間</string>
|
||||
<string name="sleep_timer">睡眠定時器</string>
|
||||
<string name="skip_silence">跳過無聲片段</string>
|
||||
<string name="help">幫助</string>
|
||||
<string name="faq">問答</string>
|
||||
<string name="best_quality">最佳</string>
|
||||
<string name="seek_increment">快轉幅度</string>
|
||||
<string name="import_playlists">匯入播放清單</string>
|
||||
<string name="alternative_pip_controls">另一種畫中畫控制模式</string>
|
||||
<string name="alternative_pip_controls_summary">只顯示音訊,跳過畫中畫的前進後退控制</string>
|
||||
<string name="all_caught_up_summary">您已經看完了所有影片</string>
|
||||
</resources>
|
@ -3,6 +3,8 @@
|
||||
<color name="duration_background_color">#AA000000</color>
|
||||
<color name="duration_text_color">#EEFFFFFF</color>
|
||||
<color name="shortcut_color">#0061A6</color>
|
||||
<color name="text_color_secondary">#505050</color>
|
||||
<color name="drag_handle_color">#CCCCCC</color>
|
||||
|
||||
<color name="blue_md_theme_light_primary">#0058CB</color>
|
||||
<color name="blue_md_theme_light_onPrimary">#FFFFFF</color>
|
||||
|
@ -72,6 +72,7 @@
|
||||
<string name="noInternet">Connect to the Internet first.</string>
|
||||
<string name="retry">Retry</string>
|
||||
<string name="comments">Comments</string>
|
||||
<string name="replies">Replies</string>
|
||||
<string name="choose_filter">Choose search filter</string>
|
||||
<string name="channels">Channels</string>
|
||||
<string name="all">All</string>
|
||||
|
Loading…
Reference in New Issue
Block a user