mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue