forked from recloudstream/cloudstream
add voting system
This commit is contained in:
parent
ae137f4a34
commit
a3eef399a9
11 changed files with 560 additions and 2 deletions
|
@ -0,0 +1,86 @@
|
|||
package com.lagradost.cloudstream3.plugins
|
||||
|
||||
import android.util.Log
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||
import java.security.MessageDigest
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||
|
||||
object VotingApi { // please do not cheat the votes lol
|
||||
private const val LOGKEY = "VotingApi"
|
||||
|
||||
enum class VoteType(val value: Int) {
|
||||
UPVOTE(1),
|
||||
DOWNVOTE(-1),
|
||||
NONE(0)
|
||||
}
|
||||
|
||||
private val apiDomain = "https://api.countapi.xyz"
|
||||
|
||||
private fun transformUrl(url: String): String = // dont touch or all votes get reset
|
||||
MessageDigest
|
||||
.getInstance("SHA-1")
|
||||
.digest("${url}#funny-salt".toByteArray())
|
||||
.fold("") { str, it -> str + "%02x".format(it) }
|
||||
|
||||
suspend fun SitePlugin.getVotes(): Int {
|
||||
if (repositoryUrl == null) return 0
|
||||
return getVotes(repositoryUrl, url)
|
||||
}
|
||||
|
||||
suspend fun SitePlugin.vote(requestType: VoteType): Int {
|
||||
if (repositoryUrl == null) return 0
|
||||
return vote(repositoryUrl, url, requestType)
|
||||
}
|
||||
|
||||
fun SitePlugin.getVoteType(): VoteType {
|
||||
if (repositoryUrl == null) return VoteType.NONE
|
||||
return getVoteType(repositoryUrl, url)
|
||||
}
|
||||
|
||||
suspend fun getVotes(repositoryUrl: String, pluginUrl: String): Int {
|
||||
val url = "${apiDomain}/get/cs3-votes-${transformUrl(repositoryUrl)}/${transformUrl(pluginUrl)}"
|
||||
Log.d(LOGKEY, "Requesting: $url")
|
||||
return app.get(url).parsedSafe<Result>()?.value ?: (0.also {
|
||||
ioSafe {
|
||||
createBucket(repositoryUrl, pluginUrl)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun getVoteType(repositoryUrl: String, pluginUrl: String): VoteType {
|
||||
return getKey("cs3-votes-${transformUrl(repositoryUrl)}/${transformUrl(pluginUrl)}") ?: VoteType.NONE
|
||||
}
|
||||
|
||||
private suspend fun createBucket(repositoryUrl: String, pluginUrl: String) {
|
||||
val url = "${apiDomain}/create?namespace=cs3-votes-${transformUrl(repositoryUrl)}&key=${transformUrl(pluginUrl)}&value=0&update_lowerbound=-2&update_upperbound=2&enable_reset=0"
|
||||
Log.d(LOGKEY, "Requesting: $url")
|
||||
app.get(url)
|
||||
}
|
||||
|
||||
suspend fun vote(repositoryUrl: String, pluginUrl: String, requestType: VoteType): Int {
|
||||
val savedType: VoteType = getKey("cs3-votes-${transformUrl(repositoryUrl)}/${transformUrl(pluginUrl)}") ?: VoteType.NONE
|
||||
var newType: VoteType = requestType
|
||||
var changeValue = 0
|
||||
if (requestType == savedType) {
|
||||
newType = VoteType.NONE
|
||||
changeValue = -requestType.value
|
||||
} else if (savedType == VoteType.NONE) {
|
||||
changeValue = requestType.value
|
||||
} else if (savedType != requestType) {
|
||||
changeValue = -savedType.value + requestType.value
|
||||
}
|
||||
val url = "${apiDomain}/update/cs3-votes-${transformUrl(repositoryUrl)}/${transformUrl(pluginUrl)}?amount=${changeValue}"
|
||||
Log.d(LOGKEY, "Requesting: $url")
|
||||
val res = app.get(url).parsedSafe<Result>()?.value
|
||||
if (res != null) {
|
||||
setKey("cs3-votes-${transformUrl(repositoryUrl)}/${transformUrl(pluginUrl)}", newType)
|
||||
}
|
||||
return res ?: 0
|
||||
}
|
||||
|
||||
private data class Result(
|
||||
val value: Int?
|
||||
)
|
||||
}
|
|
@ -4,10 +4,8 @@ import android.annotation.SuppressLint
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.ContentLoadingProgressBar
|
||||
|
|
|
@ -5,17 +5,22 @@ import android.util.Log
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getActivity
|
||||
import com.lagradost.cloudstream3.PROVIDER_STATUS_DOWN
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.plugins.PluginManager
|
||||
import com.lagradost.cloudstream3.plugins.VotingApi.getVotes
|
||||
import com.lagradost.cloudstream3.ui.result.setText
|
||||
import com.lagradost.cloudstream3.ui.result.txt
|
||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.html
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||
import com.lagradost.cloudstream3.utils.GlideApp
|
||||
import com.lagradost.cloudstream3.utils.SubtitleHelper.fromTwoLettersToLanguage
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
||||
|
@ -23,6 +28,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.toPx
|
|||
import kotlinx.android.synthetic.main.repository_item.view.*
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import java.text.DecimalFormat
|
||||
|
||||
|
||||
data class PluginViewData(
|
||||
|
@ -101,6 +107,23 @@ class PluginAdapter(
|
|||
private val iconSize by lazy {
|
||||
findClosestBase2(iconSizeExact, 16, 512)
|
||||
}
|
||||
|
||||
fun prettyCount(number: Number): String? {
|
||||
val suffix = charArrayOf(' ', 'k', 'M', 'B', 'T', 'P', 'E')
|
||||
val numValue = number.toLong()
|
||||
val value = Math.floor(Math.log10(numValue.toDouble())).toInt()
|
||||
val base = value / 3
|
||||
return if (value >= 3 && base < suffix.size) {
|
||||
DecimalFormat("#0.00").format(
|
||||
numValue / Math.pow(
|
||||
10.0,
|
||||
(base * 3).toDouble()
|
||||
)
|
||||
) + suffix[base]
|
||||
} else {
|
||||
DecimalFormat().format(numValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class PluginViewHolder(itemView: View) :
|
||||
|
@ -112,6 +135,7 @@ class PluginAdapter(
|
|||
val metadata = data.plugin.second
|
||||
val disabled = metadata.status == PROVIDER_STATUS_DOWN
|
||||
val alpha = if (disabled) 0.6f else 1f
|
||||
val isLocal = data.plugin.second.repositoryUrl == null
|
||||
itemView.main_text?.alpha = alpha
|
||||
itemView.sub_text?.alpha = alpha
|
||||
|
||||
|
@ -125,6 +149,13 @@ class PluginAdapter(
|
|||
itemView.action_button?.setOnClickListener {
|
||||
iconClickCallback.invoke(data.plugin)
|
||||
}
|
||||
itemView.setOnClickListener {
|
||||
if (isLocal) return@setOnClickListener
|
||||
|
||||
val sheet = PluginDetailsFragment(data)
|
||||
val activity = itemView.context.getActivity() as AppCompatActivity
|
||||
sheet.show(activity.supportFragmentManager, "PluginDetails")
|
||||
}
|
||||
//if (itemView.context?.isTrueTvSettings() == false) {
|
||||
// val siteUrl = metadata.repositoryUrl
|
||||
// if (siteUrl != null && siteUrl.isNotBlank() && siteUrl != "NONE") {
|
||||
|
@ -185,6 +216,11 @@ class PluginAdapter(
|
|||
itemView.lang_icon.text = fromTwoLettersToLanguage(metadata.language)
|
||||
}
|
||||
|
||||
ioSafe {
|
||||
metadata.getVotes().main {
|
||||
itemView.ext_votes?.setText(txt(R.string.votes_format, prettyCount(it)))
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata.fileSize != null) {
|
||||
itemView.ext_filesize?.isVisible = true
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
package com.lagradost.cloudstream3.ui.settings.extensions
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Bundle
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.toPx
|
||||
import kotlinx.android.synthetic.main.fragment_plugin_details.*
|
||||
import android.text.format.Formatter.formatFileSize
|
||||
import com.lagradost.cloudstream3.plugins.VotingApi
|
||||
import com.lagradost.cloudstream3.plugins.VotingApi.getVoteType
|
||||
import com.lagradost.cloudstream3.plugins.VotingApi.getVotes
|
||||
import com.lagradost.cloudstream3.plugins.VotingApi.vote
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
|
||||
|
||||
|
||||
class PluginDetailsFragment(val data: PluginViewData) : BottomSheetDialogFragment() {
|
||||
|
||||
companion object {
|
||||
private tailrec fun findClosestBase2(target: Int, current: Int = 16, max: Int = 512): Int {
|
||||
if (current >= max) return max
|
||||
if (current >= target) return current
|
||||
return findClosestBase2(target, current * 2, max)
|
||||
}
|
||||
|
||||
private val iconSizeExact = 50.toPx
|
||||
private val iconSize by lazy {
|
||||
findClosestBase2(iconSizeExact, 16, 512)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.fragment_plugin_details, container, false)
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val metadata = data.plugin.second
|
||||
if (plugin_icon?.setImage(//plugin_icon?.height ?:
|
||||
metadata.iconUrl?.replace(
|
||||
"%size%",
|
||||
"$iconSize"
|
||||
)?.replace(
|
||||
"%exact_size%",
|
||||
"$iconSizeExact"
|
||||
),
|
||||
null,
|
||||
errorImageDrawable = R.drawable.ic_baseline_extension_24
|
||||
) != true
|
||||
) {
|
||||
plugin_icon?.setImageResource(R.drawable.ic_baseline_extension_24)
|
||||
}
|
||||
plugin_name?.text = metadata.name
|
||||
plugin_version?.text = metadata.version.toString()
|
||||
plugin_description?.text = metadata.description ?: getString(R.string.no_data)
|
||||
plugin_size?.text = if (metadata.fileSize == null) getString(R.string.no_data) else formatFileSize(context, metadata.fileSize)
|
||||
plugin_author?.text = if (metadata.authors.isEmpty()) getString(R.string.no_data) else metadata.authors.joinToString(", ")
|
||||
plugin_status?.text = resources.getStringArray(R.array.extension_statuses)[metadata.status]
|
||||
plugin_types?.text = if ((metadata.tvTypes == null) || metadata.tvTypes.isEmpty()) getString(R.string.no_data) else metadata.tvTypes.joinToString(", ")
|
||||
|
||||
upvote.setOnClickListener {
|
||||
ioSafe {
|
||||
metadata.vote(VotingApi.VoteType.UPVOTE).main {
|
||||
updateVoting(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
downvote.setOnClickListener {
|
||||
ioSafe {
|
||||
metadata.vote(VotingApi.VoteType.DOWNVOTE).main {
|
||||
updateVoting(it)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ioSafe {
|
||||
metadata.getVotes().main {
|
||||
updateVoting(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateVoting(value: Int) {
|
||||
val metadata = data.plugin.second
|
||||
plugin_votes.text = value.toString()
|
||||
when (metadata.getVoteType()) {
|
||||
VotingApi.VoteType.UPVOTE -> {
|
||||
upvote.imageTintList = ColorStateList.valueOf(context?.colorFromAttribute(R.attr.colorPrimary) ?: R.color.colorPrimary)
|
||||
downvote.imageTintList = ColorStateList.valueOf(context?.colorFromAttribute(R.attr.white) ?: R.color.white)
|
||||
}
|
||||
VotingApi.VoteType.DOWNVOTE -> {
|
||||
downvote.imageTintList = ColorStateList.valueOf(context?.colorFromAttribute(R.attr.colorPrimary) ?: R.color.colorPrimary)
|
||||
upvote.imageTintList = ColorStateList.valueOf(context?.colorFromAttribute(R.attr.white) ?: R.color.white)
|
||||
}
|
||||
VotingApi.VoteType.NONE -> {
|
||||
upvote.imageTintList = ColorStateList.valueOf(context?.colorFromAttribute(R.attr.white) ?: R.color.white)
|
||||
downvote.imageTintList = ColorStateList.valueOf(context?.colorFromAttribute(R.attr.white) ?: R.color.white)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
5
app/src/main/res/drawable/ic_baseline_thumb_down_24.xml
Normal file
5
app/src/main/res/drawable/ic_baseline_thumb_down_24.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="?attr/white"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M15,3L6,3c-0.83,0 -1.54,0.5 -1.84,1.22l-3.02,7.05c-0.09,0.23 -0.14,0.47 -0.14,0.73v2c0,1.1 0.9,2 2,2h6.31l-0.95,4.57 -0.03,0.32c0,0.41 0.17,0.79 0.44,1.06L9.83,23l6.59,-6.59c0.36,-0.36 0.58,-0.86 0.58,-1.41L17,5c0,-1.1 -0.9,-2 -2,-2zM19,3v12h4L23,3h-4z"/>
|
||||
</vector>
|
5
app/src/main/res/drawable/ic_baseline_thumb_up_24.xml
Normal file
5
app/src/main/res/drawable/ic_baseline_thumb_up_24.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="?attr/white"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<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>
|
275
app/src/main/res/layout/fragment_plugin_details.xml
Normal file
275
app/src/main/res/layout/fragment_plugin_details.xml
Normal file
|
@ -0,0 +1,275 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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="wrap_content"
|
||||
android:backgroundTint="?attr/primaryGrayBackground"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.settings.extensions.PluginDetailsFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:padding="20dp"
|
||||
android:visibility="visible">
|
||||
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
app:cardCornerRadius="25dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/plugin_icon"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:ignore="ContentDescription" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/plugin_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:textColor="?attr/textColor"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="normal"
|
||||
tools:text="Hello world" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:padding="8dp">
|
||||
|
||||
<!--marquee_forever-->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="@style/SmallBlackButton"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@string/extension_description" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/plugin_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
|
||||
android:ellipsize="none"
|
||||
|
||||
android:gravity="center_vertical"
|
||||
android:singleLine="false"
|
||||
android:textColor="?attr/textColor"
|
||||
tools:text="Lolem ipsum kek Lolem ipsum kek Lolem ipsum kek Lolem ipsum kek " />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:padding="8dp">
|
||||
|
||||
<!--marquee_forever-->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="@style/SmallBlackButton"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@string/extension_authors" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/plugin_author"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:ellipsize="marquee"
|
||||
|
||||
android:gravity="center_vertical"
|
||||
|
||||
android:singleLine="false"
|
||||
|
||||
android:textColor="?attr/textColor"
|
||||
tools:text="Lolem ipsum kek" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:padding="8dp">
|
||||
|
||||
<!--marquee_forever-->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="@style/SmallBlackButton"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@string/extension_version" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/plugin_version"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:ellipsize="marquee"
|
||||
|
||||
android:gravity="center_vertical"
|
||||
|
||||
android:singleLine="true"
|
||||
|
||||
android:textColor="?attr/textColor"
|
||||
tools:text="Lolem ipsum kek" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:padding="8dp">
|
||||
|
||||
<!--marquee_forever-->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="@style/SmallBlackButton"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@string/extension_status" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/plugin_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:ellipsize="marquee"
|
||||
|
||||
android:gravity="center_vertical"
|
||||
|
||||
android:singleLine="true"
|
||||
|
||||
android:textColor="?attr/textColor"
|
||||
tools:text="Lolem ipsum kek" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:padding="8dp">
|
||||
|
||||
<!--marquee_forever-->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="@style/SmallBlackButton"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@string/extension_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/plugin_size"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:ellipsize="marquee"
|
||||
|
||||
android:gravity="center_vertical"
|
||||
|
||||
android:singleLine="true"
|
||||
|
||||
android:textColor="?attr/textColor"
|
||||
tools:text="Lolem ipsum kek" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:padding="8dp">
|
||||
|
||||
<!--marquee_forever-->
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="@style/SmallBlackButton"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@string/extension_types" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/plugin_types"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:ellipsize="marquee"
|
||||
|
||||
android:gravity="center_vertical"
|
||||
|
||||
android:singleLine="false"
|
||||
|
||||
android:textColor="?attr/textColor"
|
||||
tools:text="Lolem ipsum kek" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center_horizontal|center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/downvote"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_baseline_thumb_down_24"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/plugin_votes"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/plugin_votes"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:gravity="center_horizontal|center_vertical"
|
||||
android:text="0"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/upvote"
|
||||
app:layout_constraintStart_toEndOf="@+id/downvote"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/upvote"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_baseline_thumb_up_24"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/plugin_votes"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -73,6 +73,17 @@
|
|||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ext_votes"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:text="10K"
|
||||
android:textColor="?attr/grayTextColor"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nsfw_marker"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -88,6 +99,7 @@
|
|||
android:id="@+id/sub_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textColor="?attr/grayTextColor"
|
||||
android:textSize="12sp"
|
||||
tools:text="https://github.com/..." />
|
||||
|
|
|
@ -73,6 +73,17 @@
|
|||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ext_votes"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:text="Votes: 0"
|
||||
android:textColor="?attr/grayTextColor"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nsfw_marker"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -88,9 +99,11 @@
|
|||
android:id="@+id/sub_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textColor="?attr/grayTextColor"
|
||||
android:textSize="12sp"
|
||||
tools:text="https://github.com/..." />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
|
|
|
@ -257,6 +257,14 @@
|
|||
<item>Light</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="extension_statuses">
|
||||
<item>Down</item>
|
||||
<!-- "Ok" is usually capitalized as "OK". Ok android studio 🤓-->
|
||||
<item>Ok</item>
|
||||
<item>Slow</item>
|
||||
<item>Beta</item>
|
||||
</string-array>
|
||||
|
||||
<!--https://github.com/videolan/vlc-android/blob/72ccfb93db027b49855760001d1a930fa657c5a8/application/resources/src/main/res/values/arrays.xml#L266-->
|
||||
<string-array name="subtitles_encoding_list" tools:ignore="TypographyDashes">
|
||||
<item>@string/automatic</item>
|
||||
|
|
|
@ -615,4 +615,12 @@
|
|||
<string name="safe_mode_title">Safe Mode enabled</string>
|
||||
<string name="safe_mode_description">An unrecoverable crash occurred and we\'ve automatically disabled all extensions, so you can find and remove the extension which is causing trouble.</string>
|
||||
<string name="safe_mode_crash_info">View crash info</string>
|
||||
|
||||
<string name="votes_format" formatted="true">Votes: %s</string>
|
||||
<string name="extension_description">Description</string>
|
||||
<string name="extension_version">Version</string>
|
||||
<string name="extension_status">Status</string>
|
||||
<string name="extension_size">Size</string>
|
||||
<string name="extension_authors">Authors</string>
|
||||
<string name="extension_types">Supported</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue