mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Added intent to start searching
This commit is contained in:
parent
9a93b375f3
commit
2b29e8078f
5 changed files with 72 additions and 10 deletions
|
@ -110,6 +110,17 @@
|
||||||
|
|
||||||
<data android:scheme="cloudstreamrepo" />
|
<data android:scheme="cloudstreamrepo" />
|
||||||
</intent-filter>
|
</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>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,9 @@ import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.*
|
||||||
import androidx.navigation.NavDestination
|
|
||||||
import androidx.navigation.NavDestination.Companion.hierarchy
|
import androidx.navigation.NavDestination.Companion.hierarchy
|
||||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||||
import androidx.navigation.NavOptions
|
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.navigation.ui.setupWithNavController
|
||||||
import androidx.preference.PreferenceManager
|
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.showToast
|
||||||
import com.lagradost.cloudstream3.CommonActivity.updateLocale
|
import com.lagradost.cloudstream3.CommonActivity.updateLocale
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
|
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||||
import com.lagradost.cloudstream3.network.initClient
|
import com.lagradost.cloudstream3.network.initClient
|
||||||
import com.lagradost.cloudstream3.plugins.PluginManager
|
import com.lagradost.cloudstream3.plugins.PluginManager
|
||||||
import com.lagradost.cloudstream3.plugins.PluginManager.loadSinglePlugin
|
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.accountManagers
|
||||||
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appString
|
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appString
|
||||||
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringRepo
|
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.syncproviders.AccountManager.Companion.inAppAuths
|
||||||
import com.lagradost.cloudstream3.ui.APIRepository
|
import com.lagradost.cloudstream3.ui.APIRepository
|
||||||
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO
|
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.search.SearchResultBuilder
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
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.android.synthetic.main.fragment_result_swipe.*
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import okhttp3.ConnectionSpec
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.internal.applyConnectionSpec
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
import java.net.URLDecoder
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
@ -147,7 +146,7 @@ val VLC = ResultResume(
|
||||||
val MPV = ResultResume(
|
val MPV = ResultResume(
|
||||||
MPV_PACKAGE,
|
MPV_PACKAGE,
|
||||||
//"is.xyz.mpv.MPVActivity.result", // resume not working :pensive:
|
//"is.xyz.mpv.MPVActivity.result", // resume not working :pensive:
|
||||||
position = "position",
|
position = "position",
|
||||||
duration = "duration",
|
duration = "duration",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -188,6 +187,15 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "MAINACT"
|
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
|
* 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
|
isWebview: Boolean
|
||||||
): Boolean =
|
): Boolean =
|
||||||
with(activity) {
|
with(activity) {
|
||||||
|
// Invalid URIs can crash
|
||||||
|
fun safeURI(uri: String) = normalSafeApiCall { URI(uri) }
|
||||||
|
|
||||||
if (str != null && this != null) {
|
if (str != null && this != null) {
|
||||||
if (str.startsWith("https://cs.repo")) {
|
if (str.startsWith("https://cs.repo")) {
|
||||||
val realUrl = "https://" + str.substringAfter("?")
|
val realUrl = "https://" + str.substringAfter("?")
|
||||||
|
@ -241,10 +252,14 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (URI(str).scheme == appStringRepo) {
|
} else if (safeURI(str)?.scheme == appStringRepo) {
|
||||||
val url = str.replaceFirst(appStringRepo, "https")
|
val url = str.replaceFirst(appStringRepo, "https")
|
||||||
loadRepository(url)
|
loadRepository(url)
|
||||||
return true
|
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) {
|
} else if (!isWebview) {
|
||||||
if (str.startsWith(DOWNLOAD_NAVIGATE_TO)) {
|
if (str.startsWith(DOWNLOAD_NAVIGATE_TO)) {
|
||||||
this.navigate(R.id.navigation_downloads)
|
this.navigate(R.id.navigation_downloads)
|
||||||
|
@ -619,6 +634,17 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
val navHostFragment =
|
val navHostFragment =
|
||||||
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
||||||
val navController = navHostFragment.navController
|
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)
|
//val navController = findNavController(R.id.nav_host_fragment)
|
||||||
|
|
||||||
/*navOptions = NavOptions.Builder()
|
/*navOptions = NavOptions.Builder()
|
||||||
|
|
|
@ -43,6 +43,9 @@ abstract class AccountManager(private val defIndex: Int) : AuthAPI {
|
||||||
const val appString = "cloudstreamapp"
|
const val appString = "cloudstreamapp"
|
||||||
const val appStringRepo = "cloudstreamrepo"
|
const val appStringRepo = "cloudstreamrepo"
|
||||||
|
|
||||||
|
// Instantly start the search given a query
|
||||||
|
const val appStringSearch = "cloudstreamsearch"
|
||||||
|
|
||||||
val unixTime: Long
|
val unixTime: Long
|
||||||
get() = System.currentTimeMillis() / 1000L
|
get() = System.currentTimeMillis() / 1000L
|
||||||
val unixTimeMs: Long
|
val unixTimeMs: Long
|
||||||
|
|
|
@ -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()
|
private val searchViewModel: SearchViewModel by activityViewModels()
|
||||||
|
@ -132,7 +140,8 @@ class SearchFragment : Fragment() {
|
||||||
val default = enumValues<TvType>().sorted().filter { it != TvType.NSFW }
|
val default = enumValues<TvType>().sorted().filter { it != TvType.NSFW }
|
||||||
.map { it.ordinal.toString() }.toSet()
|
.map { it.ordinal.toString() }.toSet()
|
||||||
val preferredTypes = (PreferenceManager.getDefaultSharedPreferences(ctx)
|
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 }
|
.mapNotNull { it.toIntOrNull() ?: return@mapNotNull null }
|
||||||
|
|
||||||
val settings = ctx.getApiSettings()
|
val settings = ctx.getApiSettings()
|
||||||
|
@ -487,6 +496,14 @@ class SearchFragment : Fragment() {
|
||||||
search_master_recycler?.adapter = masterAdapter
|
search_master_recycler?.adapter = masterAdapter
|
||||||
search_master_recycler?.layoutManager = GridLayoutManager(context, 1)
|
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)
|
// SubtitlesFragment.push(activity)
|
||||||
//searchViewModel.search("iron man")
|
//searchViewModel.search("iron man")
|
||||||
//(activity as AppCompatActivity).loadResult("https://shiro.is/overlord-dubbed", "overlord-dubbed", "Shiro")
|
//(activity as AppCompatActivity).loadResult("https://shiro.is/overlord-dubbed", "overlord-dubbed", "Shiro")
|
||||||
|
|
|
@ -274,7 +274,12 @@
|
||||||
app:exitAnim="@anim/exit_anim"
|
app:exitAnim="@anim/exit_anim"
|
||||||
app:popEnterAnim="@anim/enter_anim"
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
app:popExitAnim="@anim/exit_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
|
<fragment
|
||||||
android:id="@+id/navigation_downloads"
|
android:id="@+id/navigation_downloads"
|
||||||
|
|
Loading…
Reference in a new issue