feat: extension testing
This commit is contained in:
parent
949bcc418a
commit
ab360b3a75
15 changed files with 1103 additions and 4 deletions
|
@ -200,6 +200,7 @@
|
|||
android:parentActivityName=".MainActivity" />
|
||||
<activity
|
||||
android:name=".util.MarkdownCreatorActivity"/>
|
||||
<activity android:name=".parsers.ParserTestActivity" />
|
||||
<activity
|
||||
android:name=".media.ReviewActivity"
|
||||
android:parentActivityName=".media.MediaDetailsActivity" />
|
||||
|
|
|
@ -53,8 +53,11 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
|
|||
|
||||
override val name = extension.name
|
||||
override val saveName = extension.name
|
||||
override val hostUrl = extension.sources.first().name
|
||||
override val hostUrl =
|
||||
(extension.sources.first() as? AnimeHttpSource)?.baseUrl ?: extension.sources.first().name
|
||||
override val isNSFW = extension.isNsfw
|
||||
override val icon = extension.icon
|
||||
|
||||
override var selectDub: Boolean
|
||||
get() = getDub()
|
||||
set(value) {
|
||||
|
@ -324,8 +327,10 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
|||
|
||||
override val name = extension.name
|
||||
override val saveName = extension.name
|
||||
override val hostUrl = extension.sources.first().name
|
||||
override val hostUrl =
|
||||
(extension.sources.first() as? HttpSource)?.baseUrl ?: extension.sources.first().name
|
||||
override val isNSFW = extension.isNsfw
|
||||
override val icon = extension.icon
|
||||
|
||||
override suspend fun loadChapters(
|
||||
mangaLink: String,
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
package ani.dantotsu.parsers
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import ani.dantotsu.FileUrl
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.currContext
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.okHttpClient
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import me.xdrop.fuzzywuzzy.FuzzySearch
|
||||
import okhttp3.Request
|
||||
import java.io.Serializable
|
||||
import java.net.URLDecoder
|
||||
import java.net.URLEncoder
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
|
||||
abstract class BaseParser {
|
||||
|
@ -41,6 +45,11 @@ abstract class BaseParser {
|
|||
* **/
|
||||
open val language = "English"
|
||||
|
||||
/**
|
||||
* Icon of the site, can be null
|
||||
*/
|
||||
open val icon: Drawable? = null
|
||||
|
||||
/**
|
||||
* Search for Anime/Manga/Novel, returns a List of Responses
|
||||
*
|
||||
|
@ -133,10 +142,39 @@ abstract class BaseParser {
|
|||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
* ping the site to check if it's working or not.
|
||||
* @return Triple<Int, Int?, String> : First Int is the status code, Second Int is the response time in milliseconds, Third String is the response message.
|
||||
*/
|
||||
fun ping(): Triple<Int, Int?, String> {
|
||||
val client = okHttpClient
|
||||
var statusCode = 0
|
||||
var responseTime: Int? = null
|
||||
var responseMessage = ""
|
||||
try {
|
||||
val request = Request.Builder()
|
||||
.url(hostUrl)
|
||||
.build()
|
||||
responseTime = measureTimeMillis {
|
||||
client.newCall(request).execute().use { response ->
|
||||
statusCode = response.code
|
||||
responseMessage = response.message
|
||||
}
|
||||
}.toInt()
|
||||
} catch (e: Exception) {
|
||||
Logger.log("Failed to ping $name")
|
||||
statusCode = -1
|
||||
responseMessage = if (e.message.isNullOrEmpty()) "None" else e.message!!
|
||||
Logger.log(e)
|
||||
}
|
||||
return Triple(statusCode, responseTime, responseMessage)
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get an existing Search Response which was selected by the user.
|
||||
* **/
|
||||
* @param mediaId : The mediaId of the Media object.
|
||||
* @return ShowResponse? : The ShowResponse object if found, else null.
|
||||
*/
|
||||
open suspend fun loadSavedShowResponse(mediaId: Int): ShowResponse? {
|
||||
checkIfVariablesAreEmpty()
|
||||
return PrefManager.getNullableCustomVal(
|
||||
|
@ -148,7 +186,10 @@ abstract class BaseParser {
|
|||
|
||||
/**
|
||||
* Used to save Shows Response using `saveName`.
|
||||
* **/
|
||||
* @param mediaId : The mediaId of the Media object.
|
||||
* @param response : The ShowResponse object to save.
|
||||
* @param selected : Boolean : If the ShowResponse was selected by the user or not.
|
||||
*/
|
||||
open fun saveShowResponse(mediaId: Int, response: ShowResponse?, selected: Boolean = false) {
|
||||
if (response != null) {
|
||||
checkIfVariablesAreEmpty()
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package ani.dantotsu.parsers
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.ItemExtensionSelectBinding
|
||||
import com.xwray.groupie.viewbinding.BindableItem
|
||||
|
||||
class ExtensionSelectItem(
|
||||
private val name: String,
|
||||
private val image: Drawable?,
|
||||
private var isSelected: Boolean,
|
||||
val selectCallback: (String, Boolean) -> Unit
|
||||
) : BindableItem<ItemExtensionSelectBinding>() {
|
||||
private lateinit var binding: ItemExtensionSelectBinding
|
||||
|
||||
override fun bind(viewBinding: ItemExtensionSelectBinding, position: Int) {
|
||||
binding = viewBinding
|
||||
binding.extensionNameTextView.text = name
|
||||
image?.let {
|
||||
binding.extensionIconImageView.setImageDrawable(it)
|
||||
}
|
||||
binding.extensionCheckBox.setOnCheckedChangeListener(null)
|
||||
binding.extensionCheckBox.isChecked = isSelected
|
||||
binding.extensionCheckBox.setOnCheckedChangeListener { _, isChecked ->
|
||||
isSelected = isChecked
|
||||
selectCallback(name, isChecked)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLayout(): Int {
|
||||
return R.layout.item_extension_select
|
||||
}
|
||||
|
||||
override fun initializeViewBinding(view: View): ItemExtensionSelectBinding {
|
||||
return ItemExtensionSelectBinding.bind(view)
|
||||
}
|
||||
}
|
367
app/src/main/java/ani/dantotsu/parsers/ExtensionTestItem.kt
Normal file
367
app/src/main/java/ani/dantotsu/parsers/ExtensionTestItem.kt
Normal file
|
@ -0,0 +1,367 @@
|
|||
package ani.dantotsu.parsers
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import androidx.core.view.isVisible
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.ItemExtensionTestBinding
|
||||
import ani.dantotsu.getThemeColor
|
||||
import com.xwray.groupie.viewbinding.BindableItem
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class ExtensionTestItem(
|
||||
private var extensionType: String,
|
||||
private var testType: String,
|
||||
private var extension: BaseParser,
|
||||
private var searchString: String = "Chainsaw Man"
|
||||
) : BindableItem<ItemExtensionTestBinding>() {
|
||||
private lateinit var binding: ItemExtensionTestBinding
|
||||
private lateinit var context: Context
|
||||
private var job: Job? = null
|
||||
private var isRunning = false
|
||||
private var pingResult: Triple<Int, Int?, String>? = null
|
||||
private var searchResultSize: Int? = null
|
||||
private var episodeResultSize: Int? = null
|
||||
private var serverResultSize: Int? = null
|
||||
|
||||
override fun bind(viewBinding: ItemExtensionTestBinding, position: Int) {
|
||||
binding = viewBinding
|
||||
context = binding.root.context
|
||||
binding.extensionIconImageView.setImageDrawable(extension.icon)
|
||||
binding.extensionNameTextView.text = extension.name
|
||||
binding.extensionLoading.isVisible = isRunning
|
||||
hideAllResults()
|
||||
|
||||
pingResult()
|
||||
searchResult()
|
||||
episodeResult()
|
||||
serverResult()
|
||||
}
|
||||
|
||||
override fun getLayout(): Int {
|
||||
return R.layout.item_extension_test
|
||||
}
|
||||
|
||||
override fun initializeViewBinding(view: View): ItemExtensionTestBinding {
|
||||
return ItemExtensionTestBinding.bind(view)
|
||||
}
|
||||
|
||||
private fun hideAllResults() {
|
||||
if (::binding.isInitialized.not()) return
|
||||
binding.searchResultText.isVisible = false
|
||||
binding.episodeResultText.isVisible = false
|
||||
binding.serverResultText.isVisible = false
|
||||
}
|
||||
|
||||
fun cancelJob() {
|
||||
job?.cancel()
|
||||
job = null
|
||||
binding.extensionLoading.isVisible = false
|
||||
}
|
||||
|
||||
fun startTest() {
|
||||
pingResult = null
|
||||
searchResultSize = null
|
||||
episodeResultSize = null
|
||||
serverResultSize = null
|
||||
isRunning = true
|
||||
hideAllResults()
|
||||
job?.cancel()
|
||||
job = Job()
|
||||
CoroutineScope(Dispatchers.IO + job!!).launch {
|
||||
when (extensionType) {
|
||||
"anime" -> {
|
||||
val extension = extension as AnimeParser
|
||||
runAnimeTest(extension)
|
||||
}
|
||||
|
||||
"manga" -> {
|
||||
val extension = extension as MangaParser
|
||||
runMangaTest(extension)
|
||||
}
|
||||
|
||||
"novel" -> {
|
||||
val extension = extension as NovelParser
|
||||
runNovelTest(extension)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun runAnimeTest(extension: AnimeParser) {
|
||||
pingResult = extension.ping()
|
||||
withContext(Dispatchers.Main) {
|
||||
pingResult()
|
||||
}
|
||||
if (testType == "ping") {
|
||||
done()
|
||||
return
|
||||
}
|
||||
val searchResult = extension.search(searchString)
|
||||
searchResultSize = searchResult.size
|
||||
withContext(Dispatchers.Main) {
|
||||
searchResult()
|
||||
}
|
||||
if (searchResultSize == 0 || testType == "basic") {
|
||||
done()
|
||||
return
|
||||
}
|
||||
val episodeResult = extension.loadEpisodes("", null, searchResult.first().sAnime!!)
|
||||
episodeResultSize = episodeResult.size
|
||||
withContext(Dispatchers.Main) {
|
||||
episodeResult()
|
||||
}
|
||||
if (episodeResultSize == 0) {
|
||||
done()
|
||||
return
|
||||
}
|
||||
val serverResult = extension.loadVideoServers("", null, episodeResult.first().sEpisode!!)
|
||||
serverResultSize = serverResult.size
|
||||
withContext(Dispatchers.Main) {
|
||||
serverResult()
|
||||
}
|
||||
|
||||
done()
|
||||
}
|
||||
|
||||
private suspend fun runMangaTest(extension: MangaParser) {
|
||||
pingResult = extension.ping()
|
||||
withContext(Dispatchers.Main) {
|
||||
pingResult()
|
||||
}
|
||||
if (testType == "ping") {
|
||||
done()
|
||||
return
|
||||
}
|
||||
val searchResult = extension.search(searchString)
|
||||
searchResultSize = searchResult.size
|
||||
withContext(Dispatchers.Main) {
|
||||
searchResult()
|
||||
}
|
||||
if (searchResultSize == 0 || testType == "basic") {
|
||||
done()
|
||||
return
|
||||
}
|
||||
val chapterResult = extension.loadChapters("", null, searchResult.first().sManga!!)
|
||||
episodeResultSize = chapterResult.size
|
||||
withContext(Dispatchers.Main) {
|
||||
episodeResult()
|
||||
}
|
||||
if (episodeResultSize == 0) {
|
||||
done()
|
||||
return
|
||||
}
|
||||
val serverResult = extension.loadImages("", chapterResult.first().sChapter)
|
||||
serverResultSize = serverResult.size
|
||||
withContext(Dispatchers.Main) {
|
||||
serverResult()
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
if (::binding.isInitialized )
|
||||
binding.extensionLoading.isVisible = false
|
||||
isRunning = false
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun runNovelTest(extension: NovelParser) {
|
||||
withContext(Dispatchers.Main) {
|
||||
pingResult()
|
||||
}
|
||||
if (testType == "ping") {
|
||||
done()
|
||||
return
|
||||
}
|
||||
val searchResult = extension.search(searchString)
|
||||
searchResultSize = searchResult.size
|
||||
withContext(Dispatchers.Main) {
|
||||
searchResult()
|
||||
}
|
||||
if (searchResultSize == 0 || testType == "basic") {
|
||||
done()
|
||||
return
|
||||
}
|
||||
val chapterResult = extension.loadBook(searchResult.first().link, null)
|
||||
episodeResultSize = chapterResult.links.size
|
||||
withContext(Dispatchers.Main) {
|
||||
episodeResult()
|
||||
serverResult()
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
if (::binding.isInitialized )
|
||||
binding.extensionLoading.isVisible = false
|
||||
isRunning = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun done() {
|
||||
if (::binding.isInitialized.not()) return
|
||||
binding.extensionLoading.isVisible = false
|
||||
isRunning = false
|
||||
}
|
||||
|
||||
private fun pingResult() {
|
||||
if (::binding.isInitialized.not()) return
|
||||
if (extensionType == "novel") {
|
||||
binding.pingResultText.isVisible = true
|
||||
binding.pingResultText.text = context.getString(R.string.test_not_supported)
|
||||
binding.pingResultText.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_round_info_24, 0, 0, 0
|
||||
)
|
||||
return
|
||||
}
|
||||
if (pingResult == null) {
|
||||
binding.pingResultText.isVisible = false
|
||||
return
|
||||
} else {
|
||||
binding.pingResultText.isVisible = true
|
||||
}
|
||||
binding.pingResultText.setTextColor(
|
||||
context.getThemeColor(com.google.android.material.R.attr.colorPrimary)
|
||||
)
|
||||
val (code, time, message) = pingResult!!
|
||||
if (code == 200) {
|
||||
binding.pingResultText.text = context.getString(R.string.ping_success, time.toString())
|
||||
binding.pingResultText.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_circle_check, 0, 0, 0
|
||||
)
|
||||
return
|
||||
}
|
||||
binding.pingResultText.text =
|
||||
context.getString(R.string.ping_error, code.toString(), message)
|
||||
binding.pingResultText.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_circle_cancel, 0, 0, 0
|
||||
)
|
||||
binding.pingResultText.setTextColor(
|
||||
context.getThemeColor(com.google.android.material.R.attr.colorError)
|
||||
)
|
||||
}
|
||||
|
||||
private fun searchResult() {
|
||||
if (::binding.isInitialized.not()) return
|
||||
if (searchResultSize == null) {
|
||||
binding.searchResultText.isVisible = false
|
||||
return
|
||||
}
|
||||
binding.searchResultText.setTextColor(
|
||||
context.getThemeColor(com.google.android.material.R.attr.colorPrimary)
|
||||
)
|
||||
binding.searchResultText.isVisible = true
|
||||
if (searchResultSize == 0) {
|
||||
val text = context.getString(R.string.title_search_test,
|
||||
context.getString(R.string.no_results_found))
|
||||
binding.searchResultText.text = text
|
||||
binding.searchResultText.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_circle_cancel, 0, 0, 0
|
||||
)
|
||||
binding.searchResultText.setTextColor(
|
||||
context.getThemeColor(com.google.android.material.R.attr.colorError)
|
||||
)
|
||||
return
|
||||
}
|
||||
val text = context.getString(R.string.title_search_test,
|
||||
context.getString(R.string.results_found, searchResultSize.toString()))
|
||||
binding.searchResultText.text = text
|
||||
binding.searchResultText.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_circle_check, 0, 0, 0
|
||||
)
|
||||
}
|
||||
|
||||
private fun episodeResult() {
|
||||
if (::binding.isInitialized.not()) return
|
||||
if (episodeResultSize == null) {
|
||||
binding.episodeResultText.isVisible = false
|
||||
return
|
||||
}
|
||||
binding.episodeResultText.setTextColor(
|
||||
context.getThemeColor(com.google.android.material.R.attr.colorPrimary)
|
||||
)
|
||||
binding.episodeResultText.isVisible = true
|
||||
if (episodeResultSize == 0) {
|
||||
val text = when(extensionType) {
|
||||
"anime" -> context.getString(R.string.episode_search_test,
|
||||
context.getString(R.string.no_results_found))
|
||||
"manga" -> context.getString(R.string.chapter_search_test,
|
||||
context.getString(R.string.no_results_found))
|
||||
else -> context.getString(R.string.book_search_test,
|
||||
context.getString(R.string.no_results_found))
|
||||
}
|
||||
binding.episodeResultText.text = text
|
||||
binding.episodeResultText.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_circle_cancel, 0, 0, 0
|
||||
)
|
||||
binding.episodeResultText.setTextColor(
|
||||
context.getThemeColor(com.google.android.material.R.attr.colorError)
|
||||
)
|
||||
return
|
||||
}
|
||||
val text = when(extensionType) {
|
||||
"anime" -> context.getString(R.string.episode_search_test,
|
||||
context.getString(R.string.results_found, episodeResultSize.toString()))
|
||||
"manga" -> context.getString(R.string.chapter_search_test,
|
||||
context.getString(R.string.results_found, episodeResultSize.toString()))
|
||||
else -> context.getString(R.string.book_search_test,
|
||||
context.getString(R.string.results_found, episodeResultSize.toString()))
|
||||
}
|
||||
binding.episodeResultText.text = text
|
||||
binding.episodeResultText.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_circle_check, 0, 0, 0
|
||||
)
|
||||
}
|
||||
|
||||
private fun serverResult() {
|
||||
if (::binding.isInitialized.not()) return
|
||||
if (extensionType == "novel") {
|
||||
binding.pingResultText.isVisible = true
|
||||
binding.pingResultText.text = context.getString(R.string.test_not_supported)
|
||||
binding.pingResultText.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_round_info_24, 0, 0, 0
|
||||
)
|
||||
return
|
||||
}
|
||||
if (serverResultSize == null) {
|
||||
binding.serverResultText.isVisible = false
|
||||
return
|
||||
}
|
||||
binding.serverResultText.setTextColor(
|
||||
context.getThemeColor(com.google.android.material.R.attr.colorPrimary)
|
||||
)
|
||||
binding.serverResultText.isVisible = true
|
||||
if (serverResultSize == 0) {
|
||||
val text = when(extensionType) {
|
||||
"anime" -> context.getString(R.string.video_search_test,
|
||||
context.getString(R.string.no_results_found))
|
||||
"manga" -> context.getString(R.string.image_search_test,
|
||||
context.getString(R.string.no_results_found))
|
||||
else -> context.getString(R.string.book_search_test,
|
||||
context.getString(R.string.no_results_found))
|
||||
}
|
||||
binding.serverResultText.text = text
|
||||
binding.serverResultText.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_circle_cancel, 0, 0, 0
|
||||
)
|
||||
binding.serverResultText.setTextColor(
|
||||
context.getThemeColor(com.google.android.material.R.attr.colorError)
|
||||
)
|
||||
return
|
||||
}
|
||||
val text = when(extensionType) {
|
||||
"anime" -> context.getString(R.string.video_search_test,
|
||||
context.getString(R.string.results_found, serverResultSize.toString()))
|
||||
"manga" -> context.getString(R.string.image_search_test,
|
||||
context.getString(R.string.results_found, serverResultSize.toString()))
|
||||
else -> context.getString(R.string.book_search_test,
|
||||
context.getString(R.string.results_found, serverResultSize.toString()))
|
||||
}
|
||||
binding.serverResultText.text = text
|
||||
binding.serverResultText.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.ic_circle_check, 0, 0, 0
|
||||
)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package ani.dantotsu.parsers
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import ani.dantotsu.BottomSheetDialogFragment
|
||||
import ani.dantotsu.databinding.BottomSheetExtensionTestSettingsBinding
|
||||
import ani.dantotsu.parsers.novel.NovelExtensionManager
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class ExtensionTestSettingsBottomDialog : BottomSheetDialogFragment() {
|
||||
private var _binding: BottomSheetExtensionTestSettingsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val adapter: GroupieAdapter = GroupieAdapter()
|
||||
private val animeExtension: AnimeExtensionManager = Injekt.get()
|
||||
private val mangaExtensions: MangaExtensionManager = Injekt.get()
|
||||
private val novelExtensions: NovelExtensionManager = Injekt.get()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = BottomSheetExtensionTestSettingsBinding.inflate(inflater, container, false)
|
||||
return _binding?.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.extensionSelectionRecyclerView.adapter = adapter
|
||||
binding.extensionSelectionRecyclerView.layoutManager = LinearLayoutManager(
|
||||
context,
|
||||
LinearLayoutManager.VERTICAL,
|
||||
false
|
||||
)
|
||||
binding.animeRadioButton.setOnCheckedChangeListener { _, b ->
|
||||
if (b) {
|
||||
extensionType = "anime"
|
||||
extensionsToTest.clear()
|
||||
setupAdapter()
|
||||
}
|
||||
}
|
||||
binding.mangaRadioButton.setOnCheckedChangeListener { _, b ->
|
||||
if (b) {
|
||||
extensionType = "manga"
|
||||
extensionsToTest.clear()
|
||||
setupAdapter()
|
||||
}
|
||||
}
|
||||
binding.novelsRadioButton.setOnCheckedChangeListener { _, b ->
|
||||
if (b) {
|
||||
extensionType = "novel"
|
||||
extensionsToTest.clear()
|
||||
setupAdapter()
|
||||
}
|
||||
}
|
||||
binding.pingRadioButton.setOnCheckedChangeListener { _, b ->
|
||||
if (b) {
|
||||
testType = "ping"
|
||||
}
|
||||
}
|
||||
binding.basicRadioButton.setOnCheckedChangeListener { _, b ->
|
||||
if (b) {
|
||||
testType = "basic"
|
||||
}
|
||||
}
|
||||
binding.fullRadioButton.setOnCheckedChangeListener { _, b ->
|
||||
if (b) {
|
||||
testType = "full"
|
||||
}
|
||||
}
|
||||
setupAdapter()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupAdapter() {
|
||||
val namesAndUrls: Map<String,Drawable?> = when (extensionType) {
|
||||
"anime" -> animeExtension.installedExtensionsFlow.value.associate { it.name to it.icon }
|
||||
"manga" -> mangaExtensions.installedExtensionsFlow.value.associate { it.name to it.icon }
|
||||
"novel" -> novelExtensions.installedExtensionsFlow.value.associate { it.name to it.icon }
|
||||
else -> emptyMap()
|
||||
}
|
||||
adapter.clear()
|
||||
namesAndUrls.forEach { (name, icon) ->
|
||||
val isSelected = extensionsToTest.contains(name)
|
||||
adapter.add(ExtensionSelectItem(name, icon, isSelected, ::selectedCallback))
|
||||
}
|
||||
}
|
||||
|
||||
private fun selectedCallback(name: String, isSelected: Boolean) {
|
||||
if (isSelected) {
|
||||
extensionsToTest.add(name)
|
||||
} else {
|
||||
extensionsToTest.remove(name)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(): ExtensionTestSettingsBottomDialog {
|
||||
return ExtensionTestSettingsBottomDialog()
|
||||
}
|
||||
|
||||
var extensionType = "anime"
|
||||
var testType = "ping"
|
||||
var extensionsToTest: MutableList<String> = mutableListOf()
|
||||
}
|
||||
}
|
112
app/src/main/java/ani/dantotsu/parsers/ParserTestActivity.kt
Normal file
112
app/src/main/java/ani/dantotsu/parsers/ParserTestActivity.kt
Normal file
|
@ -0,0 +1,112 @@
|
|||
package ani.dantotsu.parsers
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.ActivityParserTestBinding
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import ani.dantotsu.toast
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
|
||||
class ParserTestActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityParserTestBinding
|
||||
val adapter = GroupieAdapter()
|
||||
val extensionsToTest: MutableList<ExtensionTestItem> = mutableListOf()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
initActivity(this)
|
||||
binding = ActivityParserTestBinding.inflate(layoutInflater)
|
||||
binding.toolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = statusBarHeight
|
||||
}
|
||||
binding.extensionResultsRecyclerView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin = navBarHeight
|
||||
}
|
||||
setContentView(binding.root)
|
||||
|
||||
binding.extensionResultsRecyclerView.adapter = adapter
|
||||
binding.extensionResultsRecyclerView.layoutManager = LinearLayoutManager(
|
||||
this,
|
||||
LinearLayoutManager.VERTICAL,
|
||||
false
|
||||
)
|
||||
binding.backButton.setOnClickListener {
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
binding.optionsLayout.setOnClickListener {
|
||||
ExtensionTestSettingsBottomDialog.newInstance()
|
||||
.show(supportFragmentManager, "extension_test_settings")
|
||||
}
|
||||
|
||||
binding.startButton.setOnClickListener {
|
||||
if (ExtensionTestSettingsBottomDialog.extensionsToTest.isEmpty()) {
|
||||
toast(R.string.no_extensions_selected)
|
||||
return@setOnClickListener
|
||||
}
|
||||
extensionsToTest.forEach {
|
||||
it.cancelJob()
|
||||
}
|
||||
extensionsToTest.clear()
|
||||
adapter.clear()
|
||||
when (ExtensionTestSettingsBottomDialog.extensionType) {
|
||||
"anime" -> {
|
||||
ExtensionTestSettingsBottomDialog.extensionsToTest.forEach { name ->
|
||||
val extension =
|
||||
AnimeSources.list.find { source -> source.name == name }?.get?.value
|
||||
extension?.let {
|
||||
extensionsToTest.add(
|
||||
ExtensionTestItem(
|
||||
"anime",
|
||||
ExtensionTestSettingsBottomDialog.testType,
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
"manga" -> {
|
||||
ExtensionTestSettingsBottomDialog.extensionsToTest.forEach { name ->
|
||||
val extension =
|
||||
MangaSources.list.find { source -> source.name == name }?.get?.value
|
||||
extension?.let {
|
||||
extensionsToTest.add(
|
||||
ExtensionTestItem(
|
||||
"manga",
|
||||
ExtensionTestSettingsBottomDialog.testType,
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
"novel" -> {
|
||||
ExtensionTestSettingsBottomDialog.extensionsToTest.forEach { name ->
|
||||
val extension =
|
||||
NovelSources.list.find { source -> source.name == name }?.get?.value
|
||||
extension?.let {
|
||||
extensionsToTest.add(
|
||||
ExtensionTestItem(
|
||||
"novel",
|
||||
ExtensionTestSettingsBottomDialog.testType,
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
extensionsToTest.forEach {
|
||||
adapter.add(it)
|
||||
it.startTest()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package ani.dantotsu.settings
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
|
@ -13,6 +14,7 @@ import android.view.inputmethod.EditorInfo
|
|||
import android.widget.AutoCompleteTextView
|
||||
import android.widget.EditText
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
|
@ -28,6 +30,7 @@ import ani.dantotsu.media.MediaType
|
|||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.others.AndroidBug5497Workaround
|
||||
import ani.dantotsu.others.LanguageMapper
|
||||
import ani.dantotsu.parsers.ParserTestActivity
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.statusBarHeight
|
||||
|
@ -70,6 +73,14 @@ class ExtensionsActivity : AppCompatActivity() {
|
|||
bottomMargin = statusBarHeight + navBarHeight
|
||||
}
|
||||
|
||||
binding.testButton.setOnClickListener {
|
||||
ContextCompat.startActivity(
|
||||
this,
|
||||
Intent(this, ParserTestActivity::class.java),
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
val tabLayout = findViewById<TabLayout>(R.id.tabLayout)
|
||||
val viewPager = findViewById<ViewPager2>(R.id.viewPager)
|
||||
viewPager.offscreenPageLimit = 1
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ani.dantotsu.settings
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.HapticFeedbackConstants
|
||||
import android.view.KeyEvent
|
||||
|
@ -9,6 +10,7 @@ import android.view.ViewGroup
|
|||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.EditText
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
|
@ -20,6 +22,7 @@ import ani.dantotsu.databinding.ItemRepositoryBinding
|
|||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.media.MediaType
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.parsers.ParserTestActivity
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.statusBarHeight
|
||||
|
@ -232,6 +235,20 @@ class SettingsExtensionsActivity : AppCompatActivity() {
|
|||
setExtensionOutput(it.attachView, MediaType.MANGA)
|
||||
}
|
||||
),
|
||||
Settings(
|
||||
type = 1,
|
||||
name = getString(R.string.extension_test),
|
||||
desc = getString(R.string.extension_test_desc),
|
||||
icon = R.drawable.ic_round_search_sources_24,
|
||||
isActivity = true,
|
||||
onClick = {
|
||||
ContextCompat.startActivity(
|
||||
context,
|
||||
Intent(context, ParserTestActivity::class.java),
|
||||
null
|
||||
)
|
||||
}
|
||||
),
|
||||
Settings(
|
||||
type = 1,
|
||||
name = getString(R.string.user_agent),
|
||||
|
|
|
@ -41,6 +41,15 @@
|
|||
android:layout_marginHorizontal="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/testButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/sort_by"
|
||||
app:srcCompat="@drawable/ic_round_search_sources_24"
|
||||
app:tint="?attr/colorOnBackground" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/openSettingsButton"
|
||||
android:layout_width="48dp"
|
||||
|
|
109
app/src/main/res/layout/activity_parser_test.xml
Normal file
109
app/src/main/res/layout/activity_parser_test.xml
Normal file
|
@ -0,0 +1,109 @@
|
|||
<androidx.core.widget.NestedScrollView 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"
|
||||
tools:context=".settings.SettingsNotificationActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/backButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="12dp"
|
||||
android:src="@drawable/ic_round_arrow_back_ios_new_24"
|
||||
app:tint="?attr/colorOnBackground"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="44dp"
|
||||
android:ellipsize="end"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:gravity="center|start"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"
|
||||
android:textColor="?attr/colorOnBackground"
|
||||
android:textSize="18sp"
|
||||
android:text="@string/extension_test" />
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/optionsLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginVertical="16dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
app:srcCompat="@drawable/ic_round_filter_24"
|
||||
app:tint="?attr/colorPrimary"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:text="@string/view_options"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginVertical="16dp"
|
||||
android:rotation="180"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@drawable/ic_round_arrow_back_ios_new_24"
|
||||
app:tint="?attr/colorPrimary"
|
||||
tools:ignore="ContentDescription"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="50dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginVertical="16dp"
|
||||
android:backgroundTint="?attr/colorPrimaryContainer"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:text="@string/start_test"
|
||||
android:textColor="?attr/colorOnPrimaryContainer"
|
||||
app:cornerRadius="12dp"
|
||||
app:iconTint="?attr/colorOnPrimaryContainer" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/extensionResultsRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:nestedScrollingEnabled="false"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingBottom="16dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
100
app/src/main/res/layout/bottom_sheet_extension_test_settings.xml
Normal file
100
app/src/main/res/layout/bottom_sheet_extension_test_settings.xml
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_marginVertical="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:text="@string/extension_type"
|
||||
android:textAlignment="center"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<RadioGroup
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||
android:id="@+id/animeRadioButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:checked="true"
|
||||
android:text="@string/anime"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||
android:id="@+id/mangaRadioButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/manga"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||
android:id="@+id/novelsRadioButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/novels"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:layout_marginTop="16dp"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:text="@string/test_type"
|
||||
android:textAlignment="center"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<RadioGroup
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||
android:id="@+id/pingRadioButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:checked="true"
|
||||
android:text="@string/ping"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||
android:id="@+id/basicRadioButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/basic"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||
android:id="@+id/fullRadioButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/full"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/extensionSelectionRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingBottom="16dp"
|
||||
tools:listitem="@layout/item_extension_select"/>
|
||||
|
||||
</LinearLayout>
|
40
app/src/main/res/layout/item_extension_select.xml
Normal file
40
app/src/main/res/layout/item_extension_select.xml
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/extensionCardView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorSurface"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/extensionIconImageView"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="3dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/extensionNameTextView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:fontFamily="@font/poppins_semi_bold"
|
||||
android:text="@string/extension_name"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<com.google.android.material.checkbox.MaterialCheckBox
|
||||
android:id="@+id/extensionCheckBox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp" />
|
||||
|
||||
</LinearLayout>
|
111
app/src/main/res/layout/item_extension_test.xml
Normal file
111
app/src/main/res/layout/item_extension_test.xml
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?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:id="@+id/extensionCardView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorSurface"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/extensionIconImageView"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="3dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/extensionNameTextView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/poppins_semi_bold"
|
||||
android:text="@string/extension_name"
|
||||
android:textSize="15sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/resultLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pingResultText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="10dp"
|
||||
android:fontFamily="@font/poppins_semi_bold"
|
||||
android:text="@string/placeholder"
|
||||
android:textSize="13sp"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
app:drawableStartCompat="@drawable/ic_round_help_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/searchResultText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="10dp"
|
||||
android:fontFamily="@font/poppins_semi_bold"
|
||||
android:text="@string/placeholder"
|
||||
android:textSize="13sp"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
app:drawableStartCompat="@drawable/ic_round_help_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/episodeResultText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="10dp"
|
||||
android:fontFamily="@font/poppins_semi_bold"
|
||||
android:text="@string/placeholder"
|
||||
android:textSize="13sp"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
app:drawableStartCompat="@drawable/ic_round_help_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/serverResultText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="10dp"
|
||||
android:fontFamily="@font/poppins_semi_bold"
|
||||
android:text="@string/placeholder"
|
||||
android:textSize="13sp"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
app:drawableStartCompat="@drawable/ic_round_help_24" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/extensionLoading"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
|
@ -996,4 +996,25 @@ Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exerc
|
|||
<string name="subscriptions">Subscriptions</string>
|
||||
<string name="subscription_deleted">Subscription Deleted</string>
|
||||
<string name="foreground_service_not_allowed">Cannot install when app is in background</string>
|
||||
<string name="ping">Ping</string>
|
||||
<string name="basic">Basic</string>
|
||||
<string name="full">Full</string>
|
||||
<string name="test_type">Test Type</string>
|
||||
<string name="extension_type">Extension Type</string>
|
||||
<string name="view_options">View Options</string>
|
||||
<string name="extension_test">Extension Test</string>
|
||||
<string name="extension_test_desc">Test if the extensions are working</string>
|
||||
<string name="start_test">Start Test</string>
|
||||
<string name="no_extensions_selected">No extensions selected</string>
|
||||
<string name="ping_success">Ping successful: %1$s ms</string>
|
||||
<string name="ping_error">Ping failed. Code: %1$s, Message: %2$s</string>
|
||||
<string name="test_not_supported">Test not supported for this extension</string>
|
||||
<string name="no_results_found">No results found. Extension may be broken</string>
|
||||
<string name="results_found">%1$s results found</string>
|
||||
<string name="title_search_test">Title Search Test: %1$s</string>
|
||||
<string name="episode_search_test">Episode Search Test: %1$s</string>
|
||||
<string name="chapter_search_test">Chapter Search Test: %1$s</string>
|
||||
<string name="video_search_test">Video Search Test: %1$s</string>
|
||||
<string name="image_search_test">Image Search Test: %1$s</string>
|
||||
<string name="book_search_test">Book Search Test: %1$s</string>
|
||||
</resources>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue