cloudstream/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt

280 lines
13 KiB
Kotlin
Raw Normal View History

2021-05-16 18:28:00 +00:00
package com.lagradost.cloudstream3.ui.result
2021-05-20 21:25:41 +00:00
import android.Manifest
2021-05-18 13:43:32 +00:00
import android.annotation.SuppressLint
2021-05-20 21:25:41 +00:00
import android.app.Activity
import android.content.ComponentName
import android.content.Intent
import android.content.Intent.*
import android.content.pm.PackageManager
2021-05-16 18:28:00 +00:00
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
2021-05-18 13:43:32 +00:00
import androidx.appcompat.app.AlertDialog
2021-05-20 21:25:41 +00:00
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.core.net.toUri
2021-05-18 13:43:32 +00:00
import androidx.core.widget.NestedScrollView
2021-05-16 18:28:00 +00:00
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
2021-05-18 13:43:32 +00:00
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.request.RequestOptions.bitmapTransform
import com.lagradost.cloudstream3.AnimeLoadResponse
import com.lagradost.cloudstream3.LoadResponse
2021-05-16 18:28:00 +00:00
import com.lagradost.cloudstream3.R
2021-05-20 21:25:41 +00:00
import com.lagradost.cloudstream3.UIHelper.checkWrite
2021-05-18 13:43:32 +00:00
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
2021-05-20 21:25:41 +00:00
import com.lagradost.cloudstream3.UIHelper.requestRW
2021-05-18 13:43:32 +00:00
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.observe
2021-05-20 15:22:28 +00:00
import com.lagradost.cloudstream3.utils.ExtractorLink
2021-05-18 13:43:32 +00:00
import jp.wasabeef.glide.transformations.BlurTransformation
import kotlinx.android.synthetic.main.fragment_result.*
2021-05-20 21:25:41 +00:00
import java.io.File
2021-05-18 13:43:32 +00:00
const val MAX_SYNO_LENGH = 600
data class ResultEpisode(
val name: String?,
val episode: Int,
val data: Any,
val apiName: String,
val id: Int,
val watchProgress: Float, // 0-1
)
2021-05-16 18:28:00 +00:00
class ResultFragment : Fragment() {
2021-05-18 13:43:32 +00:00
fun newInstance(url: String, slug: String, apiName: String) =
ResultFragment().apply {
arguments = Bundle().apply {
putString("url", url)
putString("slug", slug)
putString("apiName", apiName)
}
}
2021-05-16 18:28:00 +00:00
private lateinit var viewModel: ResultViewModel
2021-05-20 20:56:21 +00:00
private var allEpisodes: HashMap<Int, ArrayList<ExtractorLink>> = HashMap()
2021-05-16 18:28:00 +00:00
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
2021-05-18 13:43:32 +00:00
savedInstanceState: Bundle?,
2021-05-16 18:28:00 +00:00
): View? {
viewModel =
ViewModelProvider(this).get(ResultViewModel::class.java)
return inflater.inflate(R.layout.fragment_result, container, false)
}
2021-05-18 13:43:32 +00:00
@SuppressLint("SetTextI18n")
2021-05-16 18:28:00 +00:00
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
2021-05-18 13:43:32 +00:00
activity?.fixPaddingStatusbar(result_scroll)
activity?.fixPaddingStatusbar(result_barstatus)
2021-05-20 15:22:28 +00:00
// activity?.fixPaddingStatusbar(result_toolbar)
2021-05-18 13:43:32 +00:00
val url = arguments?.getString("url")
val slug = arguments?.getString("slug")
val apiName = arguments?.getString("apiName")
result_scroll.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
2021-05-20 15:22:28 +00:00
if (result_poster_blur == null) return@OnScrollChangeListener
2021-05-18 13:43:32 +00:00
result_poster_blur.alpha = maxOf(0f, (0.3f - scrollY / 1000f))
result_barstatus.alpha = scrollY / 200f
2021-05-20 15:22:28 +00:00
result_barstatus.visibility = if (scrollY > 0) View.VISIBLE else View.GONE
2021-05-18 13:43:32 +00:00
})
result_toolbar.setNavigationIcon(R.drawable.ic_baseline_arrow_back_24)
result_toolbar.setNavigationOnClickListener {
activity?.onBackPressed()
}
2021-05-20 20:56:21 +00:00
observe(viewModel.allEpisodes) {
allEpisodes = it
}
2021-05-18 13:43:32 +00:00
observe(viewModel.resultResponse) { data ->
when (data) {
is Resource.Success -> {
val d = data.value
if (d is LoadResponse) {
result_bookmark_button.text = "Watching"
if (d.year != null) {
result_year.visibility = View.VISIBLE
result_year.text = d.year.toString()
} else {
result_year.visibility = View.GONE
}
if (d.posterUrl != null) {
val glideUrl =
GlideUrl(d.posterUrl)
context!!.let {
/*
Glide.with(it)
.load(glideUrl)
.into(result_poster)*/
Glide.with(it)
.load(glideUrl)
.apply(bitmapTransform(BlurTransformation(10, 3)))
.into(result_poster_blur)
}
}
2021-05-20 20:56:21 +00:00
fun playEpisode(data: ArrayList<ExtractorLink>?) {
if (data != null) {
2021-05-20 21:25:41 +00:00
if (activity?.checkWrite() != true) {
activity?.requestRW()
if (activity?.checkWrite() == true) return
2021-05-20 20:56:21 +00:00
}
2021-05-20 21:25:41 +00:00
val outputDir = context!!.cacheDir // context being the Activity pointer
val outputFile = File.createTempFile("mirrorlist", ".m3u8", outputDir)
var text = "#EXTM3U";
for (d in data.sortedBy { -it.quality }) {
text += "\n#EXTINF:, ${d.name}\n${d.url}"
}
outputFile.writeText(text)
val VLC_PACKAGE = "org.videolan.vlc"
val VLC_INTENT_ACTION_RESULT = "org.videolan.vlc.player.result"
val VLC_COMPONENT: ComponentName =
ComponentName(VLC_PACKAGE, "org.videolan.vlc.gui.video.VideoPlayerActivity")
val REQUEST_CODE = 42
val FROM_START = -1
val FROM_PROGRESS = -2
val vlcIntent = Intent(VLC_INTENT_ACTION_RESULT)
vlcIntent.setPackage(VLC_PACKAGE)
// vlcIntent.setDataAndTypeAndNormalize(outputFile.toUri(), "video/*")
vlcIntent.addFlags(FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
vlcIntent.addFlags(FLAG_GRANT_PREFIX_URI_PERMISSION)
vlcIntent.addFlags(FLAG_GRANT_READ_URI_PERMISSION)
vlcIntent.addFlags(FLAG_GRANT_WRITE_URI_PERMISSION)
vlcIntent.setDataAndType(FileProvider.getUriForFile(activity!!,
activity!!.applicationContext.packageName + ".provider",
outputFile), "video/*")
val startId = FROM_PROGRESS
var position = startId
if (startId == FROM_START) {
position = 1
} else if (startId == FROM_PROGRESS) {
position = 0
}
vlcIntent.putExtra("position", position)
//vlcIntent.putExtra("title", episodeName)
/*
if (subFile != null) {
val sfile: Unit = Android.Net.Uri.FromFile(subFile)
vlcIntent.PutExtra("subtitles_location", sfile.Path)
//vlcIntent.PutExtra("sub_mrl", "file://" sfile.Path);
//vlcIntent.PutExtra("subtitles_location", "file:///storage/emulated/0/Download/mirrorlist.srt");
}*/
vlcIntent.setComponent(VLC_COMPONENT)
//lastId = episodeId
activity?.startActivityForResult(vlcIntent, REQUEST_CODE)
2021-05-20 20:56:21 +00:00
}
}
val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder>? = activity?.let { it ->
2021-05-18 13:43:32 +00:00
EpisodeAdapter(
it,
ArrayList(),
result_episodes,
2021-05-20 20:56:21 +00:00
) { episodeClick ->
val id = episodeClick.data.id
when (episodeClick.action) {
ACTION_PLAY_EPISODE -> {
if (allEpisodes.containsKey(id)) {
playEpisode(allEpisodes[id])
} else {
viewModel.loadEpisode(episodeClick.data) { res ->
if (res is Resource.Success) {
playEpisode(allEpisodes[id])
}
}
}
}
ACTION_RELOAD_EPISODE -> viewModel.loadEpisode(episodeClick.data) { res ->
if (res is Resource.Success) {
playEpisode(allEpisodes[id])
}
}
}
2021-05-20 15:22:28 +00:00
}
2021-05-18 13:43:32 +00:00
}
result_episodes.adapter = adapter
result_episodes.layoutManager = GridLayoutManager(context, 1)
if (d is AnimeLoadResponse) {
val preferEnglish = true
val titleName = (if (preferEnglish) d.engName else d.japName) ?: d.name
result_title.text = titleName
result_toolbar.title = titleName
if (d.plot != null) {
var syno = d.plot
if (syno.length > MAX_SYNO_LENGH) {
syno = syno.substring(0, MAX_SYNO_LENGH) + "..."
}
result_descript.setOnClickListener {
val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
builder.setMessage(d.plot).setTitle("Synopsis")
.show()
}
result_descript.text = syno
} else {
result_descript.text = "No Plot found"
}
result_tags.text = (d.tags ?: ArrayList()).joinToString(separator = " | ")
val isDub = d.dubEpisodes != null && d.dubEpisodes.size > 0
val dataList = (if (isDub) d.dubEpisodes else d.subEpisodes)
if (dataList != null && apiName != null) {
val episodes = ArrayList<ResultEpisode>()
for ((index, i) in dataList.withIndex()) {
episodes.add(ResultEpisode(
null, // TODO ADD NAMES
index + 1, //TODO MAKE ABLE TO NOT HAVE SOME EPISODE
i,
apiName,
(slug + index).hashCode(),
2021-05-20 21:25:41 +00:00
0f,//(index * 0.1f),//TODO TEST; REMOVE
2021-05-18 13:43:32 +00:00
))
}
(result_episodes.adapter as EpisodeAdapter).cardList = episodes
(result_episodes.adapter as EpisodeAdapter).notifyDataSetChanged()
}
} else {
result_title.text = d.name
}
}
}
is Resource.Failure -> {
}
}
}
if (viewModel.resultResponse.value == null && apiName != null && slug != null)
viewModel.load(slug, apiName)
2021-05-16 18:28:00 +00:00
}
}