From cb238a6f36957549b92c0836bcf054288c4fd73f Mon Sep 17 00:00:00 2001 From: xiaji Date: Mon, 8 Jun 2026 21:01:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9Etvcat.cc=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E6=9D=A5=E6=BA=90,=20=E8=AE=BE=E7=BD=AE=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E6=94=AF=E6=8C=81=E5=A4=9A=E6=9D=A5=E6=BA=90=E5=88=87?= =?UTF-8?q?=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/videoapp/tv/SettingsActivity.kt | 58 +++++++++++++++++- .../com/videoapp/tv/data/ConfigRepository.kt | 6 ++ .../java/com/videoapp/tv/data/SitePreset.kt | 61 +++++++++++++++++++ .../java/com/videoapp/tv/ui/SearchFragment.kt | 6 +- app/src/main/res/layout/activity_settings.xml | 18 +++++- app/src/main/res/values/strings.xml | 1 + 6 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/videoapp/tv/data/SitePreset.kt diff --git a/app/src/main/java/com/videoapp/tv/SettingsActivity.kt b/app/src/main/java/com/videoapp/tv/SettingsActivity.kt index a66c6dc..ac078f9 100644 --- a/app/src/main/java/com/videoapp/tv/SettingsActivity.kt +++ b/app/src/main/java/com/videoapp/tv/SettingsActivity.kt @@ -1,16 +1,22 @@ package com.videoapp.tv import android.os.Bundle +import android.view.View +import android.widget.AdapterView +import android.widget.ArrayAdapter import android.widget.Button import android.widget.EditText +import android.widget.Spinner import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.videoapp.tv.data.ConfigRepository import com.videoapp.tv.data.SiteConfig +import com.videoapp.tv.data.SitePreset class SettingsActivity : AppCompatActivity() { private lateinit var configRepo: ConfigRepository + private lateinit var spinnerPreset: Spinner private lateinit var editBaseUrl: EditText private lateinit var editSearchPath: EditText private lateinit var editSearchMethod: EditText @@ -24,6 +30,7 @@ class SettingsActivity : AppCompatActivity() { private lateinit var editSourceEpisodeGroupSelector: EditText private lateinit var btnSave: Button private lateinit var btnRestore: Button + private var ignoringSpinner = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -31,6 +38,7 @@ class SettingsActivity : AppCompatActivity() { configRepo = ConfigRepository(this) + spinnerPreset = findViewById(R.id.spinner_preset) editBaseUrl = findViewById(R.id.edit_base_url) editSearchPath = findViewById(R.id.edit_search_path) editSearchMethod = findViewById(R.id.edit_search_method) @@ -45,18 +53,49 @@ class SettingsActivity : AppCompatActivity() { btnSave = findViewById(R.id.btn_save) btnRestore = findViewById(R.id.btn_restore) + setupPresetSpinner() loadConfig() btnSave.setOnClickListener { saveConfig() } btnRestore.setOnClickListener { configRepo.restoreDefault() + ignoringSpinner = true + spinnerPreset.setSelection(0) + ignoringSpinner = false loadConfig() Toast.makeText(this, R.string.config_restored, Toast.LENGTH_SHORT).show() } } - private fun loadConfig() { - val config = configRepo.getConfig() + private fun setupPresetSpinner() { + val presets = configRepo.getPresets() + val presetNames = presets.map { it.name } + val adapter = ArrayAdapter( + this, + android.R.layout.simple_spinner_item, + presetNames + ) + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + spinnerPreset.adapter = adapter + + spinnerPreset.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { + if (ignoringSpinner) return + val preset = presets.getOrNull(position) ?: return + configRepo.applyPreset(preset) + loadConfigFromPreset(preset.config) + Toast.makeText( + this@SettingsActivity, + "已切换到 ${preset.name}", + Toast.LENGTH_SHORT + ).show() + } + + override fun onNothingSelected(parent: AdapterView<*>?) {} + } + } + + private fun loadConfigFromPreset(config: SiteConfig) { editBaseUrl.setText(config.baseUrl) editSearchPath.setText(config.searchPath) editSearchMethod.setText(config.searchMethod) @@ -72,6 +111,21 @@ class SettingsActivity : AppCompatActivity() { editSourceEpisodeGroupSelector.setText(config.sourceEpisodeGroupSelector) } + private fun loadConfig() { + val config = configRepo.getConfig() + loadConfigFromPreset(config) + + val presets = configRepo.getPresets() + val matchedIndex = presets.indexOfFirst { + it.config.baseUrl == config.baseUrl + } + if (matchedIndex >= 0) { + ignoringSpinner = true + spinnerPreset.setSelection(matchedIndex) + ignoringSpinner = false + } + } + private fun saveConfig() { val extraParams = parseExtraParams(editExtraParams.text.toString()) diff --git a/app/src/main/java/com/videoapp/tv/data/ConfigRepository.kt b/app/src/main/java/com/videoapp/tv/data/ConfigRepository.kt index 00606cc..e5afdc3 100644 --- a/app/src/main/java/com/videoapp/tv/data/ConfigRepository.kt +++ b/app/src/main/java/com/videoapp/tv/data/ConfigRepository.kt @@ -30,6 +30,12 @@ class ConfigRepository(context: Context) { saveConfig(SiteConfig.default()) } + fun getPresets(): List = SitePreset.PRESETS + + fun applyPreset(preset: SitePreset) { + saveConfig(preset.config) + } + companion object { private const val KEY_CONFIG = "site_config_json" } diff --git a/app/src/main/java/com/videoapp/tv/data/SitePreset.kt b/app/src/main/java/com/videoapp/tv/data/SitePreset.kt new file mode 100644 index 0000000..f6507ae --- /dev/null +++ b/app/src/main/java/com/videoapp/tv/data/SitePreset.kt @@ -0,0 +1,61 @@ +package com.videoapp.tv.data + +data class SitePreset( + val name: String, + val config: SiteConfig +) { + companion object { + val PRESETS = listOf( + SitePreset( + name = "xb6v (星辰影视)", + config = SiteConfig( + baseUrl = "https://www.xb6v.com", + searchPath = "/e/search/11index.php", + searchMethod = "POST", + keywordParam = "keyboard", + extraParams = mapOf( + "show" to "title", + "tempid" to "1", + "tbname" to "article", + "mid" to "1", + "dopost" to "search" + ), + resultSelector = "li.post", + titleSelector = "h2 a", + coverSelector = ".thumbnail img", + linkSelector = ".thumbnail a", + categorySelector = ".info_category a", + dateSelector = ".info_date", + episodeSelector = "a.lBtn", + sourceSelector = ".playfrom a, .play_source a, .source-list a", + sourceEpisodeGroupSelector = ".playlist > ul, .play_list > ul, .episode-list", + iframeSelector = ".video iframe", + videoSelector = "video source, video[src]" + ) + ), + SitePreset( + name = "tvcat (电视猫)", + config = SiteConfig( + baseUrl = "https://tvcat.cc", + searchPath = "/search", + searchMethod = "GET", + keywordParam = "q", + resultSelector = "li.col-md-2.col-sm-3.col-4", + titleSelector = "a[title]", + coverSelector = "img", + linkSelector = "a", + categorySelector = ".text-muted", + dateSelector = "", + episodeSelector = "li.list-inline-item a", + sourceSelector = "h2", + sourceEpisodeGroupSelector = "ul.list-unstyled", + iframeSelector = "iframe", + videoSelector = "video source, video[src]" + ) + ) + ) + + fun getPresetByName(name: String): SitePreset? = + PRESETS.find { it.name == name } + } +} diff --git a/app/src/main/java/com/videoapp/tv/ui/SearchFragment.kt b/app/src/main/java/com/videoapp/tv/ui/SearchFragment.kt index f4a88f5..ba1e8bd 100644 --- a/app/src/main/java/com/videoapp/tv/ui/SearchFragment.kt +++ b/app/src/main/java/com/videoapp/tv/ui/SearchFragment.kt @@ -185,7 +185,11 @@ class SearchFragment : Fragment() { val path = config.searchPath.trimStart('/') val params = "${config.keywordParam}=${java.net.URLEncoder.encode(keyword, "UTF-8")}" val extraParams = config.extraParams.entries.joinToString("&") { "${it.key}=${it.value}" } - val url = "$base/$path?$params&$extraParams" + val url = if (extraParams.isNotEmpty()) { + "$base/$path?$params&$extraParams" + } else { + "$base/$path?$params" + } fallbackWebView.visibility = View.VISIBLE resultsGrid.visibility = View.GONE diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index dd34820..6394bae 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -12,7 +12,23 @@ android:text="@string/site_config" android:textColor="@color/primary" android:textSize="24sp" - android:layout_marginBottom="24dp" /> + android:layout_marginBottom="16dp" /> + + + + 返回 配置已保存 配置已恢复默认 + 视频来源 在网页中打开