diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index 8365b814..1a8fd9bb 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -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(VLC_LAST_ID_KEY) + println("SET KEY $id at $pos / $dur") if (dur > 0 && pos > 0) { setViewPos(id, pos, dur) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt index 01322d31..48f25df4 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt @@ -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 = + DownloadHeaderAdapter( + ArrayList(), + ) { click -> + + } + download_list.adapter = adapter + download_list.layoutManager = GridLayoutManager(context, 1) + downloadsViewModel.updateList(requireContext()) + + activity?.fixPaddingStatusbar(download_root) } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadViewModel.kt index 2279378a..8dc4b910 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadViewModel.kt @@ -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().apply { - value = "This is notifications Fragment" + private val _noDownloadsText = MutableLiveData().apply { + value = "" + } + val noDownloadsText: LiveData = _noDownloadsText + + private val _headerCards = + MutableLiveData>().apply { listOf() } + val headerCards: LiveData> = _headerCards + + private val _usedBytes = MutableLiveData() + private val _availableBytes = MutableLiveData() + private val _downloadBytes = MutableLiveData() + + val usedBytes: LiveData = _usedBytes + val availableBytes: LiveData = _availableBytes + val downloadBytes: LiveData = _downloadBytes + + fun updateList(context: Context) = viewModelScope.launch { + val children = withContext(Dispatchers.IO) { + val headers = context.getKeys(DOWNLOAD_EPISODE_CACHE) + headers.mapNotNull { context.getKey(it) } + } + + // parentId : bytes + val bytesUsedByChild = HashMap() + // parentId : downloadsCount + val totalDownloads = HashMap() + + // 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(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 = _text } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt index beeb5d9c..b0551eb5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt @@ -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) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt index 0c03d3b3..117110d1 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt @@ -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, diff --git a/app/src/main/res/layout/download_header_episode.xml b/app/src/main/res/layout/download_header_episode.xml index e1a85b91..4f35d0c5 100644 --- a/app/src/main/res/layout/download_header_episode.xml +++ b/app/src/main/res/layout/download_header_episode.xml @@ -53,11 +53,12 @@ android:layout_height="wrap_content"> + diff --git a/app/src/main/res/layout/fragment_downloads.xml b/app/src/main/res/layout/fragment_downloads.xml new file mode 100644 index 00000000..89aeeb17 --- /dev/null +++ b/app/src/main/res/layout/fragment_downloads.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_notifications.xml b/app/src/main/res/layout/fragment_notifications.xml deleted file mode 100644 index 733fce31..00000000 --- a/app/src/main/res/layout/fragment_notifications.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/result_episode.xml b/app/src/main/res/layout/result_episode.xml index caa1f91b..bb116643 100644 --- a/app/src/main/res/layout/result_episode.xml +++ b/app/src/main/res/layout/result_episode.xml @@ -13,27 +13,27 @@ android:layout_marginBottom="5dp" > - + + tools:layout="@layout/fragment_downloads"/> @color/colorPrimary #9ba0a6 + + #FFF + #676767 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1aa747a1..5c13e9c9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -40,4 +40,5 @@ Allow to download episodes Download Error Loading Links + Internal Storage \ No newline at end of file