Added intent to start searching

This commit is contained in:
Blatzar 2022-11-13 01:40:49 +01:00
parent 9a93b375f3
commit 2b29e8078f
5 changed files with 72 additions and 10 deletions

View file

@ -110,6 +110,17 @@
<data android:scheme="cloudstreamrepo" />
</intent-filter>
<!-- Allow searching with intents: cloudstreamsearch://Your%20Name -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="cloudstreamsearch" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />

View file

@ -16,11 +16,9 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentActivity
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.*
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavOptions
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager
@ -44,6 +42,7 @@ import com.lagradost.cloudstream3.CommonActivity.onUserLeaveHint
import com.lagradost.cloudstream3.CommonActivity.showToast
import com.lagradost.cloudstream3.CommonActivity.updateLocale
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.network.initClient
import com.lagradost.cloudstream3.plugins.PluginManager
import com.lagradost.cloudstream3.plugins.PluginManager.loadSinglePlugin
@ -52,9 +51,11 @@ import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.OAuth2A
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.accountManagers
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appString
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringRepo
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringSearch
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.inAppAuths
import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO
import com.lagradost.cloudstream3.ui.search.SearchFragment
import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
@ -88,11 +89,9 @@ import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_result_swipe.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import okhttp3.ConnectionSpec
import okhttp3.OkHttpClient
import okhttp3.internal.applyConnectionSpec
import java.io.File
import java.net.URI
import java.net.URLDecoder
import java.nio.charset.Charset
import kotlin.reflect.KClass
@ -147,7 +146,7 @@ val VLC = ResultResume(
val MPV = ResultResume(
MPV_PACKAGE,
//"is.xyz.mpv.MPVActivity.result", // resume not working :pensive:
position = "position",
position = "position",
duration = "duration",
)
@ -188,6 +187,15 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
companion object {
const val TAG = "MAINACT"
/**
* Setting this will automatically enter the query in the search
* next time the search fragment is opened.
* This variable will clear itself after one use. Null does nothing.
*
* This is a very bad solution but I was unable to find a better one.
**/
private var nextSearchQuery: String? = null
/**
* Fires every time a new batch of plugins have been loaded, no guarantee about how often this is run and on which thread
* */
@ -206,6 +214,9 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
isWebview: Boolean
): Boolean =
with(activity) {
// Invalid URIs can crash
fun safeURI(uri: String) = normalSafeApiCall { URI(uri) }
if (str != null && this != null) {
if (str.startsWith("https://cs.repo")) {
val realUrl = "https://" + str.substringAfter("?")
@ -241,10 +252,14 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
return true
}
}
} else if (URI(str).scheme == appStringRepo) {
} else if (safeURI(str)?.scheme == appStringRepo) {
val url = str.replaceFirst(appStringRepo, "https")
loadRepository(url)
return true
} else if (safeURI(str)?.scheme == appStringSearch) {
nextSearchQuery =
URLDecoder.decode(str.substringAfter("$appStringSearch://"), "UTF-8")
nav_view.selectedItemId = R.id.navigation_search
} else if (!isWebview) {
if (str.startsWith(DOWNLOAD_NAVIGATE_TO)) {
this.navigate(R.id.navigation_downloads)
@ -619,6 +634,17 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
navController.addOnDestinationChangedListener { _: NavController, navDestination: NavDestination, bundle: Bundle? ->
// Intercept search and add a query
if (navDestination.matchDestination(R.id.navigation_search) && !nextSearchQuery.isNullOrBlank()) {
bundle?.apply {
this.putString(SearchFragment.SEARCH_QUERY, nextSearchQuery)
nextSearchQuery = null
}
}
}
//val navController = findNavController(R.id.nav_host_fragment)
/*navOptions = NavOptions.Builder()

View file

@ -43,6 +43,9 @@ abstract class AccountManager(private val defIndex: Int) : AuthAPI {
const val appString = "cloudstreamapp"
const val appStringRepo = "cloudstreamrepo"
// Instantly start the search given a query
const val appStringSearch = "cloudstreamsearch"
val unixTime: Long
get() = System.currentTimeMillis() / 1000L
val unixTimeMs: Long

View file

@ -73,6 +73,14 @@ class SearchFragment : Fragment() {
}
}
}
const val SEARCH_QUERY = "search_query"
fun newInstance(query: String): Bundle {
return Bundle().apply {
putString(SEARCH_QUERY, query)
}
}
}
private val searchViewModel: SearchViewModel by activityViewModels()
@ -132,7 +140,8 @@ class SearchFragment : Fragment() {
val default = enumValues<TvType>().sorted().filter { it != TvType.NSFW }
.map { it.ordinal.toString() }.toSet()
val preferredTypes = (PreferenceManager.getDefaultSharedPreferences(ctx)
.getStringSet(this.getString(R.string.prefer_media_type_key), default)?.ifEmpty { default } ?: default)
.getStringSet(this.getString(R.string.prefer_media_type_key), default)
?.ifEmpty { default } ?: default)
.mapNotNull { it.toIntOrNull() ?: return@mapNotNull null }
val settings = ctx.getApiSettings()
@ -487,6 +496,14 @@ class SearchFragment : Fragment() {
search_master_recycler?.adapter = masterAdapter
search_master_recycler?.layoutManager = GridLayoutManager(context, 1)
// Automatically search the specified query, this allows the app search to launch from intent
arguments?.getString(SEARCH_QUERY)?.let { query ->
if (query.isBlank()) return@let
main_search?.setQuery(query, true)
// Clear the query as to not make it request the same query every time the page is opened
arguments?.putString(SEARCH_QUERY, null)
}
// SubtitlesFragment.push(activity)
//searchViewModel.search("iron man")
//(activity as AppCompatActivity).loadResult("https://shiro.is/overlord-dubbed", "overlord-dubbed", "Shiro")

View file

@ -274,7 +274,12 @@
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim"
tools:layout="@layout/fragment_search" />
tools:layout="@layout/fragment_search">
<argument
android:name="search_query"
android:defaultValue=""
app:argType="string" />
</fragment>
<fragment
android:id="@+id/navigation_downloads"