init
This commit is contained in:
parent
65f848987d
commit
1549f67cd7
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
|
|
|
@ -40,19 +40,23 @@ dependencies {
|
|||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation 'androidx.core:core-ktx:1.3.2'
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'com.google.android.material:material:1.1.0'
|
||||
implementation 'com.google.android.material:material:1.3.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation 'androidx.navigation:navigation-fragment:2.3.5'
|
||||
implementation 'androidx.navigation:navigation-ui:2.3.5'
|
||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
|
||||
testImplementation 'junit:junit:4.+'
|
||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
|
||||
implementation "io.karn:khttp-android:0.1.2"
|
||||
implementation 'org.jsoup:jsoup:1.13.1'
|
||||
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.11.3"
|
||||
|
||||
implementation("com.google.android.material:material:1.3.0")
|
||||
|
||||
implementation "androidx.preference:preference-ktx:1.1.1"
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.lagradost.cloudstream3
|
|||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||
import com.lagradost.cloudstream3.animeproviders.ShiroProvider
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
|
@ -11,7 +12,14 @@ val baseHeader = mapOf("User-Agent" to USER_AGENT)
|
|||
val mapper = JsonMapper.builder().addModule(KotlinModule())
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()!!
|
||||
|
||||
open class MainAPI {
|
||||
object APIHolder {
|
||||
val apis = arrayListOf<MainAPI>(
|
||||
ShiroProvider()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
abstract class MainAPI {
|
||||
open val name = "NONE"
|
||||
open val mainUrl = "NONE"
|
||||
open fun search(query: String): ArrayList<Any>? { // SearchResponse
|
||||
|
@ -29,14 +37,14 @@ open class MainAPI {
|
|||
|
||||
data class Link(
|
||||
val name: String,
|
||||
val url : String,
|
||||
val url: String,
|
||||
val quality: Int?,
|
||||
val referer : String?,
|
||||
val referer: String?,
|
||||
)
|
||||
|
||||
interface LinkExtractor {
|
||||
val linkStart : String // THIS IS USED TO AUTO-EXTRACT LINKS FROM URL
|
||||
fun extract(link : String, referer : String) : ArrayList<Link>
|
||||
val linkStart: String // THIS IS USED TO AUTO-EXTRACT LINKS FROM URL
|
||||
fun extract(link: String, referer: String): ArrayList<Link>
|
||||
}
|
||||
|
||||
enum class ShowStatus {
|
||||
|
|
|
@ -5,7 +5,6 @@ import com.google.android.material.bottomnavigation.BottomNavigationView
|
|||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
import androidx.navigation.ui.setupActionBarWithNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
@ -19,7 +18,7 @@ class MainActivity : AppCompatActivity() {
|
|||
// Passing each menu ID as a set of Ids because each
|
||||
// menu should be considered as top level destinations.
|
||||
val appBarConfiguration = AppBarConfiguration(setOf(
|
||||
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications))
|
||||
R.id.navigation_home, R.id.navigation_search, R.id.navigation_notifications))
|
||||
//setupActionBarWithNavController(navController, appBarConfiguration)
|
||||
navView.setupWithNavController(navController)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package com.lagradost.cloudstream3
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.View
|
||||
|
||||
object UIHelper {
|
||||
fun Activity.getStatusBarHeight(): Int {
|
||||
var result = 0
|
||||
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
|
||||
if (resourceId > 0) {
|
||||
result = resources.getDimensionPixelSize(resourceId)
|
||||
}
|
||||
return result
|
||||
|
||||
}
|
||||
|
||||
fun Activity.fixPaddingStatusbar(v: View) {
|
||||
v.setPadding(v.paddingLeft, v.paddingTop + getStatusBarHeight(), v.paddingRight, v.paddingBottom)
|
||||
}
|
||||
}
|
|
@ -43,44 +43,40 @@ class ShiroProvider : MainAPI() {
|
|||
@JsonProperty("slug") val slug: String,
|
||||
@JsonProperty("name") val name: String,
|
||||
)
|
||||
|
||||
data class ShiroSearchResponse(
|
||||
@JsonProperty("data") val data: List<ShiroSearchResponseShow>,
|
||||
@JsonProperty("status") val status: String
|
||||
@JsonProperty("status") val status: String,
|
||||
)
|
||||
|
||||
data class ShiroFullSearchResponseCurrentPage(
|
||||
@JsonProperty("items") val items: List<ShiroSearchResponseShow>
|
||||
@JsonProperty("items") val items: List<ShiroSearchResponseShow>,
|
||||
)
|
||||
|
||||
data class ShiroFullSearchResponseNavItems(
|
||||
@JsonProperty("currentPage") val currentPage: ShiroFullSearchResponseCurrentPage
|
||||
@JsonProperty("currentPage") val currentPage: ShiroFullSearchResponseCurrentPage,
|
||||
)
|
||||
|
||||
data class ShiroFullSearchResponseNav(
|
||||
@JsonProperty("nav") val nav: ShiroFullSearchResponseNavItems
|
||||
@JsonProperty("nav") val nav: ShiroFullSearchResponseNavItems,
|
||||
)
|
||||
|
||||
data class ShiroFullSearchResponse(
|
||||
@JsonProperty("data") val data: ShiroFullSearchResponseNav,
|
||||
@JsonProperty("status") val status: String
|
||||
@JsonProperty("status") val status: String,
|
||||
)
|
||||
|
||||
override fun search(query: String): ArrayList<Any>? {
|
||||
if(!autoLoadToken()) return null
|
||||
try {
|
||||
val returnValue: ArrayList<Any> = ArrayList()
|
||||
val response = khttp.get("https://tapi.shiro.is/advanced?search=${
|
||||
URLEncoder.encode(
|
||||
query,
|
||||
"UTF-8"
|
||||
)
|
||||
}&token=$token")
|
||||
val mapped = response.let { mapper.readValue<ShiroSearchResponse>(it.text) }
|
||||
if (!autoLoadToken()) return null
|
||||
val returnValue: ArrayList<Any> = ArrayList()
|
||||
val response = khttp.get("https://tapi.shiro.is/advanced?search=${
|
||||
URLEncoder.encode(
|
||||
query,
|
||||
"UTF-8"
|
||||
)
|
||||
}&token=$token")
|
||||
val mapped = response.let { mapper.readValue<ShiroSearchResponse>(it.text) }
|
||||
|
||||
|
||||
|
||||
return returnValue
|
||||
}
|
||||
catch (e : Exception) {
|
||||
return null
|
||||
}
|
||||
return returnValue
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.lagradost.cloudstream3.mvvm
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
fun <T> LifecycleOwner.observe(liveData: LiveData<T>, action: (t: T) -> Unit) {
|
||||
liveData.observe(this, Observer { it?.let { t -> action(t) } })
|
||||
}
|
||||
|
||||
sealed class Resource<out T> {
|
||||
data class Success<out T>(val value: T) : Resource<T>()
|
||||
data class Failure(
|
||||
val isNetworkError: Boolean,
|
||||
val errorCode: Int?,
|
||||
val errorResponse: Any?, //ResponseBody
|
||||
val errorString: String,
|
||||
) : Resource<Nothing>()
|
||||
}
|
||||
|
||||
suspend fun <T> safeApiCall(
|
||||
apiCall: suspend () -> T,
|
||||
): Resource<T> {
|
||||
return withContext(Dispatchers.IO) {
|
||||
try {
|
||||
Resource.Success(apiCall.invoke())
|
||||
} catch (throwable: Throwable) {
|
||||
Log.d("ApiError", "-------------------------------------------------------------------")
|
||||
Log.d("ApiError", "safeApiCall: " + throwable.localizedMessage)
|
||||
Log.d("ApiError", "safeApiCall: " + throwable.message)
|
||||
Log.d("ApiError", "-------------------------------------------------------------------")
|
||||
when (throwable) {
|
||||
/*is HttpException -> {
|
||||
Resource.Failure(false, throwable.code(), throwable.response()?.errorBody(), throwable.localizedMessage)
|
||||
}
|
||||
is SocketTimeoutException -> {
|
||||
Resource.Failure(true,null,null,"Please try again later.")
|
||||
}
|
||||
is UnknownHostException ->{
|
||||
Resource.Failure(true,null,null,"Cannot connect to server, try again later.")
|
||||
}*/
|
||||
else -> {
|
||||
Resource.Failure(true, null, null, throwable.localizedMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
package com.lagradost.cloudstream3.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import kotlin.math.abs
|
||||
|
||||
class GrdLayoutManager(val context: Context, val spanCoun: Int) : GridLayoutManager(context, spanCoun) {
|
||||
override fun onFocusSearchFailed(
|
||||
focused: View,
|
||||
focusDirection: Int,
|
||||
recycler: RecyclerView.Recycler,
|
||||
state: RecyclerView.State
|
||||
): View? {
|
||||
return try {
|
||||
val fromPos = getPosition(focused)
|
||||
println("Search failed $fromPos")
|
||||
val nextPos = getNextViewPos(fromPos, focusDirection)
|
||||
findViewByPosition(nextPos)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRequestChildFocus(
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State,
|
||||
child: View,
|
||||
focused: View?
|
||||
): Boolean {
|
||||
// android.widget.FrameLayout$LayoutParams cannot be cast to androidx.recyclerview.widget.RecyclerView$LayoutParams
|
||||
return try {
|
||||
val pos = maxOf(0, getPosition(focused!!) - 2)
|
||||
parent.scrollToPosition(pos)
|
||||
super.onRequestChildFocus(parent, state, child, focused)
|
||||
} catch (e: Exception){
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// Allows moving right and left with focus https://gist.github.com/vganin/8930b41f55820ec49e4d
|
||||
override fun onInterceptFocusSearch(focused: View, direction: Int): View? {
|
||||
return try {
|
||||
val fromPos = getPosition(focused)
|
||||
val nextPos = getNextViewPos(fromPos, direction)
|
||||
findViewByPosition(nextPos)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNextViewPos(fromPos: Int, direction: Int): Int {
|
||||
val offset = calcOffsetToNextView(direction)
|
||||
|
||||
if (hitBorder(fromPos, offset)) {
|
||||
return fromPos
|
||||
}
|
||||
|
||||
return fromPos + offset
|
||||
}
|
||||
|
||||
private fun calcOffsetToNextView(direction: Int): Int {
|
||||
println("calc")
|
||||
|
||||
val spanCount = this.spanCoun
|
||||
val orientation = this.orientation
|
||||
|
||||
if (orientation == VERTICAL) {
|
||||
when (direction) {
|
||||
View.FOCUS_DOWN -> {
|
||||
return spanCount
|
||||
}
|
||||
View.FOCUS_UP -> {
|
||||
return -spanCount
|
||||
}
|
||||
View.FOCUS_RIGHT -> {
|
||||
return 1
|
||||
}
|
||||
View.FOCUS_LEFT -> {
|
||||
return -1
|
||||
}
|
||||
|
||||
}
|
||||
} else if (orientation == HORIZONTAL) {
|
||||
when (direction) {
|
||||
View.FOCUS_DOWN -> {
|
||||
return 1
|
||||
}
|
||||
View.FOCUS_UP -> {
|
||||
return -1
|
||||
}
|
||||
View.FOCUS_RIGHT -> {
|
||||
return spanCount
|
||||
}
|
||||
View.FOCUS_LEFT -> {
|
||||
return -spanCount
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
private fun hitBorder(from: Int, offset: Int): Boolean {
|
||||
val spanCount = spanCount
|
||||
|
||||
return if (abs(offset) == 1) {
|
||||
val spanIndex = from % spanCount
|
||||
val newSpanIndex = spanIndex + offset
|
||||
newSpanIndex < 0 || newSpanIndex >= spanCount
|
||||
} else {
|
||||
val newPos = from + offset
|
||||
newPos in spanCount..-1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
RecyclerView(context, attrs) {
|
||||
|
||||
private val manager = GrdLayoutManager(context, 2) // THIS CONTROLS SPANS
|
||||
|
||||
private var columnWidth = -1
|
||||
|
||||
var spanCount = 0
|
||||
set(value) {
|
||||
field = value
|
||||
if (value > 0) {
|
||||
manager.spanCount = value
|
||||
}
|
||||
}
|
||||
|
||||
val itemWidth: Int
|
||||
get() = measuredWidth / manager.spanCount
|
||||
|
||||
init {
|
||||
if (attrs != null) {
|
||||
val attrsArray = intArrayOf(android.R.attr.columnWidth)
|
||||
val array = context.obtainStyledAttributes(attrs, attrsArray)
|
||||
columnWidth = array.getDimensionPixelSize(0, -1)
|
||||
array.recycle()
|
||||
}
|
||||
|
||||
layoutManager = manager
|
||||
}
|
||||
|
||||
|
||||
/*override fun onMeasure(widthSpec: Int, heightSpec: Int) {
|
||||
super.onMeasure(widthSpec, heightSpec)
|
||||
if (spanCount == 0 && columnWidth > 0) {
|
||||
val count = max(1, measuredWidth / columnWidth)
|
||||
spanCount = count
|
||||
}
|
||||
}*/
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package com.lagradost.cloudstream3.ui.dashboard
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.lagradost.cloudstream3.R
|
||||
|
||||
class DashboardFragment : Fragment() {
|
||||
|
||||
private lateinit var dashboardViewModel: DashboardViewModel
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
dashboardViewModel =
|
||||
ViewModelProvider(this).get(DashboardViewModel::class.java)
|
||||
val root = inflater.inflate(R.layout.fragment_dashboard, container, false)
|
||||
val textView: TextView = root.findViewById(R.id.text_dashboard)
|
||||
dashboardViewModel.text.observe(viewLifecycleOwner, Observer {
|
||||
textView.text = it
|
||||
})
|
||||
return root
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package com.lagradost.cloudstream3.ui.dashboard
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
class DashboardViewModel : ViewModel() {
|
||||
|
||||
private val _text = MutableLiveData<String>().apply {
|
||||
value = "This is dashboard Fragment"
|
||||
}
|
||||
val text: LiveData<String> = _text
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.lagradost.cloudstream3.ui.search
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
|
||||
|
||||
class SearchFragment : Fragment() {
|
||||
|
||||
private lateinit var searchViewModel: SearchViewModel
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
searchViewModel =
|
||||
ViewModelProvider(this).get(SearchViewModel::class.java)
|
||||
|
||||
return inflater.inflate(R.layout.fragment_search, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// activity?.fixPaddingStatusbar(searchRoot)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.lagradost.cloudstream3.ui.search
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.lagradost.cloudstream3.APIHolder.apis
|
||||
import com.lagradost.cloudstream3.MainAPI
|
||||
import com.lagradost.cloudstream3.mvvm.safeApiCall
|
||||
|
||||
class SearchViewModel : ViewModel() {
|
||||
|
||||
private val _text = MutableLiveData<String>().apply {
|
||||
value = "This is dashboard Fragment"
|
||||
}
|
||||
val text: LiveData<String> = _text
|
||||
|
||||
val api : MainAPI = apis[0]
|
||||
|
||||
suspend fun search(query: String) = safeApiCall {
|
||||
api.search(query)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="10dp" />
|
||||
<solid android:color="@color/darkBackground" />
|
||||
</shape>
|
||||
</inset>
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
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="M3,17v2h6v-2L3,17zM3,5v2h10L13,5L3,5zM13,21v-2h8v-2h-8v-2h-2v6h2zM7,9v2L3,11v2h4v2h2L9,9L7,9zM21,13v-2L11,11v2h10zM15,9h2L17,7h4L21,5h-4L17,3h-2v6z"/>
|
||||
</vector>
|
|
@ -0,0 +1,14 @@
|
|||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:name="vector"
|
||||
android:width="850dp"
|
||||
android:height="850dp"
|
||||
android:viewportWidth="850"
|
||||
android:viewportHeight="850">
|
||||
<path
|
||||
android:name="path_2"
|
||||
android:pathData="M 233.86 666.14 L 616.54 666.14 M 425.2 539.08 L 425.2 159.6 M 410.14 554.17 L 581.98 454.96 M 268.41 454.96 L 440.25 554.17"
|
||||
android:strokeColor="#ffffff"
|
||||
android:strokeWidth="60"
|
||||
android:strokeMiterLimit="10"/>
|
||||
</vector>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/grayBackground"/>
|
||||
<corners android:topLeftRadius="16dp"
|
||||
android:topRightRadius="16dp"/>
|
||||
|
||||
</shape>
|
|
@ -0,0 +1,5 @@
|
|||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
||||
<corners android:radius="5dp" />
|
||||
<solid android:color="@color/colorSearch"/>
|
||||
<!--<stroke android:width="0.5dp" android:color="@color/searchColorTransparent" />-->
|
||||
</shape>
|
|
@ -0,0 +1,20 @@
|
|||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:name="vector"
|
||||
android:width="850dp"
|
||||
android:height="850dp"
|
||||
android:viewportWidth="850"
|
||||
android:viewportHeight="850">
|
||||
<path
|
||||
android:name="path"
|
||||
android:pathData="M 425.2 172.91 C 363.2 172.91 303.676 197.566 259.836 241.406 C 215.996 285.246 191.34 344.77 191.34 406.77 C 191.34 468.77 215.996 528.294 259.836 572.134 C 303.676 615.974 363.2 640.63 425.2 640.63 C 487.2 640.63 546.724 615.974 590.564 572.134 C 634.404 528.294 659.06 468.77 659.06 406.77 C 659.06 344.77 634.404 285.246 590.564 241.406 C 546.724 197.566 487.2 172.91 425.2 172.91 Z"
|
||||
android:strokeColor="#ffffff"
|
||||
android:strokeWidth="60"
|
||||
android:strokeMiterLimit="10"/>
|
||||
<path
|
||||
android:name="path_1"
|
||||
android:pathData="M 599.86 562.28 L 719.87 682.29"
|
||||
android:strokeColor="#ffffff"
|
||||
android:strokeWidth="60"
|
||||
android:strokeMiterLimit="10"/>
|
||||
</vector>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/colorPrimary"/>
|
||||
<corners android:topLeftRadius="5dp" android:topRightRadius="5dp"/>
|
||||
</shape>
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<font-family xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<font
|
||||
app:fontStyle="normal"
|
||||
app:fontWeight="100"
|
||||
app:font="@font/productsans_thin" />
|
||||
<font
|
||||
app:fontStyle="italic"
|
||||
app:fontWeight="100"
|
||||
app:font="@font/productsans_thinitalic" />
|
||||
|
||||
<font
|
||||
app:fontStyle="normal"
|
||||
app:fontWeight="300"
|
||||
app:font="@font/productsans_light" />
|
||||
|
||||
<font
|
||||
app:fontStyle="italic"
|
||||
app:fontWeight="300"
|
||||
app:font="@font/productsans_lightitalic" />
|
||||
|
||||
<font
|
||||
app:fontStyle="normal"
|
||||
app:fontWeight="400"
|
||||
app:font="@font/productsans_regular" />
|
||||
|
||||
<font
|
||||
app:fontStyle="italic"
|
||||
app:fontWeight="400"
|
||||
app:font="@font/productsans_italic" />
|
||||
|
||||
<font
|
||||
app:fontStyle="normal"
|
||||
app:fontWeight="500"
|
||||
app:font="@font/productsans_medium" />
|
||||
<font
|
||||
app:fontStyle="italic"
|
||||
app:fontWeight="500"
|
||||
app:font="@font/productsans_mediumitalic" />
|
||||
|
||||
<font
|
||||
app:fontStyle="normal"
|
||||
app:fontWeight="700"
|
||||
app:font="@font/productsans_bold" />
|
||||
<font
|
||||
app:fontStyle="italic"
|
||||
app:fontWeight="700"
|
||||
app:font="@font/productsans_bolditalic" />
|
||||
|
||||
<font
|
||||
app:fontStyle="normal"
|
||||
app:fontWeight="900"
|
||||
app:font="@font/productsans_black" />
|
||||
<font
|
||||
app:fontStyle="italic"
|
||||
app:fontWeight="900"
|
||||
app:font="@font/productsans_blackitalic" />
|
||||
</font-family>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
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=".ui.dashboard.DashboardFragment">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_dashboard"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:textAlignment="center"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,74 @@
|
|||
<?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="match_parent"
|
||||
android:id="@+id/searchRoot"
|
||||
tools:context=".ui.search.SearchFragment"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="@dimen/navbarHeight"
|
||||
|
||||
android:background="@color/grayBackground">
|
||||
|
||||
<FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp" android:background="@drawable/search_background"
|
||||
>
|
||||
<FrameLayout android:layout_width="match_parent" android:layout_marginEnd="30dp"
|
||||
android:layout_height="wrap_content">
|
||||
<androidx.appcompat.widget.SearchView
|
||||
|
||||
android:animateLayoutChanges="true"
|
||||
android:id="@+id/main_search"
|
||||
app:queryBackground="@color/transparent"
|
||||
app:searchIcon="@drawable/search_icon"
|
||||
android:paddingStart="-10dp"
|
||||
android:iconifiedByDefault="false"
|
||||
app:queryHint="@string/search_hint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:layout_margin="10dp"
|
||||
app:iconifiedByDefault="false"
|
||||
tools:ignore="RtlSymmetry">
|
||||
<androidx.core.widget.ContentLoadingProgressBar
|
||||
android:id="@+id/search_loading_bar"
|
||||
android:layout_width="20dp" android:layout_height="20dp"
|
||||
android:layout_marginStart="-35dp"
|
||||
style="@style/Widget.AppCompat.ProgressBar"
|
||||
android:foregroundTint="@color/white"
|
||||
android:progressTint="@color/white"
|
||||
android:layout_gravity="center">
|
||||
|
||||
</androidx.core.widget.ContentLoadingProgressBar>
|
||||
<!--app:queryHint="@string/search_hint"
|
||||
android:background="@color/grayBackground" @color/itemBackground
|
||||
app:searchHintIcon="@drawable/search_white"
|
||||
-->
|
||||
</androidx.appcompat.widget.SearchView>
|
||||
</FrameLayout>
|
||||
<ImageView
|
||||
android:id="@+id/search_filter"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_baseline_tune_24"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
app:tint="@color/textColor"
|
||||
android:contentDescription="@string/change_providers_descript">
|
||||
</ImageView>
|
||||
</FrameLayout>
|
||||
<com.lagradost.cloudstream3.ui.AutofitRecyclerView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingTop="5dp"
|
||||
app:spanCount="3"
|
||||
android:paddingEnd="8dp"
|
||||
android:id="@+id/cardSpace"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
</com.lagradost.cloudstream3.ui.AutofitRecyclerView>
|
||||
</LinearLayout>
|
|
@ -7,13 +7,13 @@
|
|||
android:title="@string/title_home"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/navigation_dashboard"
|
||||
android:icon="@drawable/ic_dashboard_black_24dp"
|
||||
android:title="@string/title_dashboard"/>
|
||||
android:id="@+id/navigation_search"
|
||||
android:icon="@drawable/search_icon"
|
||||
android:title="@string/title_search"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/navigation_notifications"
|
||||
android:icon="@drawable/ic_notifications_black_24dp"
|
||||
android:title="@string/title_notifications"/>
|
||||
android:icon="@drawable/netflix_download"
|
||||
android:title="@string/title_downloads"/>
|
||||
|
||||
</menu>
|
|
@ -3,23 +3,23 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/mobile_navigation"
|
||||
app:startDestination="@+id/navigation_home">
|
||||
app:startDestination="@+id/navigation_search">
|
||||
|
||||
<fragment
|
||||
<!-- <fragment
|
||||
android:id="@+id/navigation_home"
|
||||
android:name="com.lagradost.cloudstream3.ui.home.HomeFragment"
|
||||
android:label="@string/title_home"
|
||||
tools:layout="@layout/fragment_home"/>
|
||||
|
||||
-->
|
||||
<fragment
|
||||
android:id="@+id/navigation_dashboard"
|
||||
android:name="com.lagradost.cloudstream3.ui.dashboard.DashboardFragment"
|
||||
android:label="@string/title_dashboard"
|
||||
tools:layout="@layout/fragment_dashboard"/>
|
||||
android:id="@+id/navigation_search"
|
||||
android:name="com.lagradost.cloudstream3.ui.search.SearchFragment"
|
||||
android:label="@string/title_search"
|
||||
tools:layout="@layout/fragment_search"/>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/navigation_notifications"
|
||||
android:name="com.lagradost.cloudstream3.ui.notifications.NotificationsFragment"
|
||||
android:label="@string/title_notifications"
|
||||
android:label="@string/title_downloads"
|
||||
tools:layout="@layout/fragment_notifications"/>
|
||||
</navigation>
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#3d50fa</color>
|
||||
<color name="colorSearch">#3444D1</color> <!--#3444D1-->
|
||||
<color name="colorRipple">#1A3D50FA</color>
|
||||
<color name="colorSearch">@color/itemBackground</color> <!--#3444D1-->
|
||||
<color name="colorItemSeen">#1E1E32</color>
|
||||
<color name="colorOngoing">#F53B66</color> <!--FF8181-->
|
||||
<color name="colorPrimaryDark">#3700B3</color>
|
||||
|
@ -20,9 +21,4 @@
|
|||
<color name="transparent">#00000000</color>
|
||||
|
||||
<color name="white">#FFF</color>
|
||||
<color name="readerBackground">#292832</color> <!--3c3c3c-->
|
||||
<color name="readerTextColor">#cccccc</color>
|
||||
<color name="readerHightlightedTextColor">#206f96</color>
|
||||
<color name="readerHightlightedMetaInfo">#0D000000</color>
|
||||
<color name="roundedTextBorder">#DD0277BD</color>
|
||||
</resources>
|
|
@ -2,4 +2,6 @@
|
|||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
<dimen name="roundedImageRadius">4dp</dimen>
|
||||
<dimen name="navbarHeight">0dp</dimen>
|
||||
</resources>
|
|
@ -1,6 +1,8 @@
|
|||
<resources>
|
||||
<string name="app_name">CloudStream</string>
|
||||
<string name="title_home">Home</string>
|
||||
<string name="title_dashboard">Dashboard</string>
|
||||
<string name="title_notifications">Notifications</string>
|
||||
<string name="title_search">Search</string>
|
||||
<string name="title_downloads">Downloads</string>
|
||||
<string name="search_hint">Search...</string>
|
||||
<string name="change_providers_descript">Change Providers</string>
|
||||
</resources>
|
|
@ -16,21 +16,41 @@
|
|||
<item name="android:scrollbarThumbVertical">@null</item>
|
||||
<item name="android:scrollbarThumbHorizontal">@null</item>
|
||||
|
||||
<item name="android:windowTranslucentStatus">true</item>
|
||||
<item name="android:windowTranslucentStatus">true</item> <!--true-->
|
||||
<item name="android:windowTranslucentNavigation">false</item>
|
||||
<!--
|
||||
<item name="alertDialogTheme">@style/Theme.AlertDialog</item>
|
||||
|
||||
<item name="android:textViewStyle">@style/RobotoTextViewStyle</item>
|
||||
<item name="android:buttonStyle">@style/RobotoButtonStyle</item>
|
||||
<item name="materialButtonStyle">@style/RobotoMaterialButtonStyle</item>
|
||||
<item name="preferenceFragmentCompatStyle">@style/PreferenceTheme</item>-->
|
||||
<item name="android:textViewStyle">@style/AppTextViewStyle</item>
|
||||
<item name="android:buttonStyle">@style/AppButtonStyle</item>
|
||||
<item name="materialButtonStyle">@style/AppMaterialButtonStyle</item>
|
||||
<item name="preferenceFragmentCompatStyle">@style/PreferenceTheme</item>
|
||||
<item name="bottomSheetDialogTheme">@style/AppBottomSheetDialogTheme</item>
|
||||
<item name="searchViewStyle">@style/AppSearchViewStyle</item>
|
||||
<item name="tabStyle">@style/Theme.Widget.Tabs</item>
|
||||
</style>
|
||||
|
||||
<style name="AppSearchViewStyle"
|
||||
parent="Theme.MaterialComponents.NoActionBar">
|
||||
<item name="android:searchIcon">@drawable/search_icon</item>
|
||||
<item name="android:queryHint">@string/search_hint</item>
|
||||
<item name="android:background">@color/transparent</item>
|
||||
<item name="android:fontFamily">@font/google_sans</item>
|
||||
</style>
|
||||
<style name="AppBottomSheetDialogTheme"
|
||||
parent="Theme.Design.Light.BottomSheetDialog">
|
||||
<item name="bottomSheetStyle">@style/AppModalStyle</item>
|
||||
</style>
|
||||
|
||||
<style name="AppModalStyle"
|
||||
parent="Widget.Design.BottomSheet.Modal">
|
||||
<item name="android:background">@drawable/rounded_dialog</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="PreferenceTheme" parent="@style/AppTheme">
|
||||
</style>
|
||||
|
||||
<!--
|
||||
|
||||
<style name="Theme.AlertDialog" parent="ThemeOverlay.MaterialComponents.Dialog.Alert">
|
||||
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
|
||||
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
|
||||
|
@ -38,24 +58,28 @@
|
|||
<item name="textAllCaps">false</item>
|
||||
</style>
|
||||
|
||||
<style name="RoundedBgTextView" parent="@android:style/Widget.TextView">
|
||||
<item name="roundedTextHorizontalPadding">2dp</item>
|
||||
<item name="roundedTextVerticalPadding">2dp</item>
|
||||
<item name="roundedTextDrawable">@drawable/rounded_text_bg</item>
|
||||
<item name="roundedTextDrawableLeft">@drawable/rounded_text_bg_left</item>
|
||||
<item name="roundedTextDrawableMid">@drawable/rounded_text_bg_mid</item>
|
||||
<item name="roundedTextDrawableRight">@drawable/rounded_text_bg_right</item>
|
||||
</style>
|
||||
|
||||
<style name="RobotoTextViewStyle" parent="android:Widget.TextView">
|
||||
<style name="AppTextViewStyle" parent="android:Widget.TextView">
|
||||
<item name="android:fontFamily">@font/google_sans</item>
|
||||
</style>
|
||||
|
||||
<style name="RobotoButtonStyle" parent="android:Widget.Holo.Button">
|
||||
<style name="AppButtonStyle" parent="android:Widget.Holo.Button">
|
||||
<item name="android:fontFamily">@font/google_sans</item>
|
||||
</style>
|
||||
|
||||
<style name="RobotoMaterialButtonStyle" parent="Widget.MaterialComponents.Button">
|
||||
<style name="AppMaterialButtonStyle" parent="Widget.MaterialComponents.Button">
|
||||
<item name="android:fontFamily">@font/google_sans</item>
|
||||
</style>-->
|
||||
</style>
|
||||
|
||||
<style name="Theme.Widget.Tabs" parent="Widget.MaterialComponents.TabLayout.Colored">
|
||||
<item name="tabGravity">center</item>
|
||||
<item name="backgroundTint">@color/transparent</item>
|
||||
<item name="tabIndicator">@drawable/tab_selector</item>
|
||||
<item name="tabIndicatorColor">@color/colorPrimary</item>
|
||||
<item name="tabTextColor">@color/colorPrimary</item>
|
||||
<item name="tabIndicatorFullWidth">false</item>
|
||||
<item name="tabIndicatorHeight">3dp</item>
|
||||
<item name="tabInlineLabel">true</item>
|
||||
<item name="tabMinWidth">75dp</item>
|
||||
<item name="tabMode">scrollable</item>
|
||||
</style>
|
||||
</resources>
|
Loading…
Reference in New Issue