mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
download headers
This commit is contained in:
parent
8a519176ca
commit
ddd722f19e
12 changed files with 295 additions and 62 deletions
|
@ -113,6 +113,7 @@ class MainActivity : AppCompatActivity() {
|
|||
val dur: Long =
|
||||
data.getLongExtra(VLC_EXTRA_DURATION_OUT, -1) //Last position in media when player exited
|
||||
val id = getKey<Int>(VLC_LAST_ID_KEY)
|
||||
println("SET KEY $id at $pos / $dur")
|
||||
if (dur > 0 && pos > 0) {
|
||||
setViewPos(id, pos, dur)
|
||||
}
|
||||
|
|
|
@ -1,31 +1,81 @@
|
|||
package com.lagradost.cloudstream3.ui.download
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
|
||||
import com.lagradost.cloudstream3.mvvm.observe
|
||||
import kotlinx.android.synthetic.main.fragment_downloads.*
|
||||
import kotlinx.android.synthetic.main.fragment_result.*
|
||||
|
||||
|
||||
class DownloadFragment : Fragment() {
|
||||
|
||||
private lateinit var notificationsViewModel: DownloadViewModel
|
||||
private lateinit var downloadsViewModel: DownloadViewModel
|
||||
|
||||
private fun getBytesAsText(bytes: Long): String {
|
||||
return "%.1f".format(bytes / 1000000000f)
|
||||
}
|
||||
|
||||
private fun View.setLayoutWidth(weight: Long) {
|
||||
val param = LinearLayout.LayoutParams(
|
||||
0,
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
maxOf((weight / 1000000000f), 0.1f) // 100mb
|
||||
)
|
||||
this.layoutParams = param
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
notificationsViewModel =
|
||||
downloadsViewModel =
|
||||
ViewModelProvider(this).get(DownloadViewModel::class.java)
|
||||
val root = inflater.inflate(R.layout.fragment_notifications, container, false)
|
||||
val textView: TextView = root.findViewById(R.id.text_notifications)
|
||||
notificationsViewModel.text.observe(viewLifecycleOwner, Observer {
|
||||
textView.text = it
|
||||
})
|
||||
return root
|
||||
observe(downloadsViewModel.noDownloadsText) {
|
||||
text_no_downloads.text = it
|
||||
}
|
||||
observe(downloadsViewModel.headerCards) {
|
||||
(download_list?.adapter as DownloadHeaderAdapter? ?: return@observe).cardList = it
|
||||
(download_list?.adapter as DownloadHeaderAdapter? ?: return@observe).notifyDataSetChanged()
|
||||
}
|
||||
observe(downloadsViewModel.availableBytes) {
|
||||
download_free_txt?.text = "Free • ${getBytesAsText(it)}GB"
|
||||
download_free?.setLayoutWidth(it)
|
||||
}
|
||||
observe(downloadsViewModel.usedBytes) {
|
||||
download_used_txt?.text = "Used • ${getBytesAsText(it)}GB"
|
||||
download_used?.setLayoutWidth(it)
|
||||
}
|
||||
observe(downloadsViewModel.downloadBytes) {
|
||||
download_app_txt?.text = "App • ${getBytesAsText(it)}GB"
|
||||
download_app?.setLayoutWidth(it)
|
||||
}
|
||||
return inflater.inflate(R.layout.fragment_downloads, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder> =
|
||||
DownloadHeaderAdapter(
|
||||
ArrayList(),
|
||||
) { click ->
|
||||
|
||||
}
|
||||
download_list.adapter = adapter
|
||||
download_list.layoutManager = GridLayoutManager(context, 1)
|
||||
downloadsViewModel.updateList(requireContext())
|
||||
|
||||
activity?.fixPaddingStatusbar(download_root)
|
||||
}
|
||||
}
|
|
@ -1,13 +1,95 @@
|
|||
package com.lagradost.cloudstream3.ui.download
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Environment
|
||||
import android.os.StatFs
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.lagradost.cloudstream3.utils.DOWNLOAD_EPISODE_CACHE
|
||||
import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE
|
||||
import com.lagradost.cloudstream3.utils.DataStore.getKey
|
||||
import com.lagradost.cloudstream3.utils.DataStore.getKeys
|
||||
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
|
||||
import com.lagradost.cloudstream3.utils.VideoDownloadManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class DownloadViewModel : ViewModel() {
|
||||
|
||||
private val _text = MutableLiveData<String>().apply {
|
||||
value = "This is notifications Fragment"
|
||||
private val _noDownloadsText = MutableLiveData<String>().apply {
|
||||
value = ""
|
||||
}
|
||||
val noDownloadsText: LiveData<String> = _noDownloadsText
|
||||
|
||||
private val _headerCards =
|
||||
MutableLiveData<List<VisualDownloadHeaderCached>>().apply { listOf<VisualDownloadHeaderCached>() }
|
||||
val headerCards: LiveData<List<VisualDownloadHeaderCached>> = _headerCards
|
||||
|
||||
private val _usedBytes = MutableLiveData<Long>()
|
||||
private val _availableBytes = MutableLiveData<Long>()
|
||||
private val _downloadBytes = MutableLiveData<Long>()
|
||||
|
||||
val usedBytes: LiveData<Long> = _usedBytes
|
||||
val availableBytes: LiveData<Long> = _availableBytes
|
||||
val downloadBytes: LiveData<Long> = _downloadBytes
|
||||
|
||||
fun updateList(context: Context) = viewModelScope.launch {
|
||||
val children = withContext(Dispatchers.IO) {
|
||||
val headers = context.getKeys(DOWNLOAD_EPISODE_CACHE)
|
||||
headers.mapNotNull { context.getKey<VideoDownloadHelper.DownloadEpisodeCached>(it) }
|
||||
}
|
||||
|
||||
// parentId : bytes
|
||||
val bytesUsedByChild = HashMap<Int, Long>()
|
||||
// parentId : downloadsCount
|
||||
val totalDownloads = HashMap<Int, Int>()
|
||||
|
||||
// Gets all children downloads
|
||||
withContext(Dispatchers.IO) {
|
||||
for (c in children) {
|
||||
val childFile = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(context, c.id)
|
||||
val len = childFile?.totalBytes ?: continue
|
||||
if (bytesUsedByChild.containsKey(c.parentId)) {
|
||||
bytesUsedByChild[c.parentId] = bytesUsedByChild[c.parentId]?.plus(len) ?: len
|
||||
} else {
|
||||
bytesUsedByChild[c.parentId] = len
|
||||
}
|
||||
|
||||
if (totalDownloads.containsKey(c.parentId)) {
|
||||
totalDownloads[c.parentId] = totalDownloads[c.parentId]?.plus(1) ?: 1
|
||||
} else {
|
||||
totalDownloads[c.parentId] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val cached = withContext(Dispatchers.IO) {
|
||||
val headers = context.getKeys(DOWNLOAD_HEADER_CACHE)
|
||||
headers.mapNotNull { context.getKey<VideoDownloadHelper.DownloadHeaderCached>(it) }
|
||||
}
|
||||
|
||||
val visual = withContext(Dispatchers.IO) {
|
||||
cached.mapNotNull { // TODO FIX
|
||||
val downloads = totalDownloads[it.id] ?: 0
|
||||
val bytes = bytesUsedByChild[it.id] ?: 0
|
||||
if(bytes <= 0 || downloads <= 0) return@mapNotNull null
|
||||
VisualDownloadHeaderCached(0, downloads, bytes, it)
|
||||
}
|
||||
}
|
||||
|
||||
val stat = StatFs(Environment.getExternalStorageDirectory().path)
|
||||
|
||||
val localBytesAvailable = stat.availableBytes//stat.blockSizeLong * stat.blockCountLong
|
||||
val localTotalBytes = stat.blockSizeLong * stat.blockCountLong
|
||||
val localDownloadedBytes = visual.sumOf { it.totalBytes }
|
||||
|
||||
_usedBytes.postValue(localTotalBytes - localBytesAvailable - localDownloadedBytes)
|
||||
_availableBytes.postValue(localBytesAvailable)
|
||||
_downloadBytes.postValue(localDownloadedBytes)
|
||||
|
||||
_headerCards.postValue(visual)
|
||||
}
|
||||
val text: LiveData<String> = _text
|
||||
}
|
|
@ -352,7 +352,7 @@ class ResultFragment : Fragment() {
|
|||
episodeClick.data.index,
|
||||
eps,
|
||||
sortUrls(currentLinks ?: return),
|
||||
currentSubs ?: return,
|
||||
currentSubs ?: ArrayList(),
|
||||
startTime = episodeClick.data.getRealPosition(),
|
||||
startIndex = startIndex
|
||||
)
|
||||
|
@ -548,7 +548,7 @@ class ResultFragment : Fragment() {
|
|||
vlcIntent.putExtra("position", position)
|
||||
|
||||
vlcIntent.component = VLC_COMPONENT
|
||||
requireContext().setKey(VLC_LAST_ID_KEY, currentId)
|
||||
requireContext().setKey(VLC_LAST_ID_KEY, episodeClick.data.id)
|
||||
activity?.startActivityForResult(vlcIntent, VLC_REQUEST_CODE)
|
||||
}
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ class SearchFragment : Fragment() {
|
|||
allApi.providersActive = requireActivity().getApiSettings()
|
||||
|
||||
//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")
|
||||
/*
|
||||
(requireActivity() as AppCompatActivity).supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.enter_anim,
|
||||
|
|
|
@ -53,11 +53,12 @@
|
|||
android:layout_height="wrap_content">
|
||||
</TextView>
|
||||
</LinearLayout>
|
||||
<!--
|
||||
android:background="?selectableItemBackgroundBorderless"-->
|
||||
<ImageView
|
||||
android:layout_marginStart="-40dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="30dp"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:src="@drawable/ic_baseline_keyboard_arrow_right_24"
|
||||
android:contentDescription="@string/download_descript"/>
|
||||
|
|
118
app/src/main/res/layout/fragment_downloads.xml
Normal file
118
app/src/main/res/layout/fragment_downloads.xml
Normal file
|
@ -0,0 +1,118 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
android:id="@+id/download_root"
|
||||
android:orientation="vertical"
|
||||
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.download.DownloadFragment">
|
||||
<LinearLayout
|
||||
android:layout_margin="10dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:layout_marginBottom="5dp"
|
||||
android:text="@string/download_storage_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
</TextView>
|
||||
<LinearLayout
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="12dp"
|
||||
android:orientation="horizontal">
|
||||
<View
|
||||
android:layout_weight="0.5"
|
||||
android:id="@+id/download_used"
|
||||
android:background="@color/usedStorageColor"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"/>
|
||||
<View
|
||||
android:id="@+id/download_app"
|
||||
android:layout_weight="0.10"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"/>
|
||||
<View
|
||||
android:id="@+id/download_free"
|
||||
android:layout_weight="0.10"
|
||||
android:background="@color/freeStorageColor"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<View
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="@color/usedStorageColor"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"/>
|
||||
<TextView
|
||||
android:id="@+id/download_used_txt"
|
||||
android:layout_gravity="center_vertical"
|
||||
tools:text="Used • 30.58GB"
|
||||
android:textSize="12sp"
|
||||
android:textColor="?attr/textColor"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<View
|
||||
android:layout_margin="5dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"/>
|
||||
<TextView
|
||||
android:id="@+id/download_app_txt"
|
||||
android:layout_gravity="center_vertical"
|
||||
tools:text="App • 30.58GB"
|
||||
android:textSize="12sp"
|
||||
android:textColor="?attr/textColor"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
<View
|
||||
android:layout_margin="5dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="@color/freeStorageColor"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"/>
|
||||
<TextView
|
||||
android:id="@+id/download_free_txt"
|
||||
android:textSize="12sp"
|
||||
android:layout_gravity="center_vertical"
|
||||
tools:text="Free • 30.58GB"
|
||||
android:textColor="?attr/textColor"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_margin="10dp"
|
||||
android:id="@+id/download_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
<TextView
|
||||
android:id="@+id/text_no_downloads"
|
||||
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"/>
|
||||
</LinearLayout>
|
|
@ -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.download.DownloadFragment">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_notifications"
|
||||
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>
|
|
@ -13,27 +13,27 @@
|
|||
android:layout_marginBottom="5dp"
|
||||
>
|
||||
<!-- IDK BUT THIS DOES NOT SEAM LIKE A GOOD WAY OF DOING IT -->
|
||||
<!--<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="horizontal">
|
||||
<View
|
||||
android:layout_weight="0.5"
|
||||
android:id="@+id/episode_view_procentage"
|
||||
android:alpha="0.2"
|
||||
android:background="@color/colorPrimary"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
</View>
|
||||
<View
|
||||
android:id="@+id/episode_view_procentage_off"
|
||||
android:layout_weight="0.10"
|
||||
android:alpha="0"
|
||||
android:background="@color/transparent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
</View>
|
||||
</LinearLayout>-->
|
||||
<!--<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="horizontal">
|
||||
<View
|
||||
android:layout_weight="0.5"
|
||||
android:id="@+id/episode_view_procentage"
|
||||
android:alpha="0.2"
|
||||
android:background="@color/colorPrimary"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
</View>
|
||||
<View
|
||||
android:id="@+id/episode_view_procentage_off"
|
||||
android:layout_weight="0.10"
|
||||
android:alpha="0"
|
||||
android:background="@color/transparent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
</View>
|
||||
</LinearLayout>-->
|
||||
<androidx.core.widget.ContentLoadingProgressBar
|
||||
android:layout_marginBottom="-1.5dp"
|
||||
android:id="@+id/episode_progress"
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
android:id="@+id/navigation_notifications"
|
||||
android:name="com.lagradost.cloudstream3.ui.download.DownloadFragment"
|
||||
android:label="@string/title_downloads"
|
||||
tools:layout="@layout/fragment_notifications"/>
|
||||
tools:layout="@layout/fragment_downloads"/>
|
||||
<fragment
|
||||
android:id="@+id/navigation_settings"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -38,4 +38,7 @@
|
|||
<color name="videoColorPrimary">@color/colorPrimary</color> <!--0e09df 617EFF 3d50fa-->
|
||||
|
||||
<color name="iconColor">#9ba0a6</color>
|
||||
|
||||
<color name="usedStorageColor">#FFF</color>
|
||||
<color name="freeStorageColor">#676767</color>
|
||||
</resources>
|
|
@ -40,4 +40,5 @@
|
|||
<string name="need_storage">Allow to download episodes</string>
|
||||
<string name="download_descript">Download</string>
|
||||
<string name="error_loading_links">Error Loading Links</string>
|
||||
<string name="download_storage_text">Internal Storage</string>
|
||||
</resources>
|
Loading…
Reference in a new issue