diff --git a/app/src/main/java/com/github/libretube/activities/OfflinePlayerActivity.kt b/app/src/main/java/com/github/libretube/activities/OfflinePlayerActivity.kt index 1d00a3378..077e036ad 100644 --- a/app/src/main/java/com/github/libretube/activities/OfflinePlayerActivity.kt +++ b/app/src/main/java/com/github/libretube/activities/OfflinePlayerActivity.kt @@ -13,6 +13,7 @@ import com.github.libretube.constants.IntentData import com.github.libretube.databinding.ActivityOfflinePlayerBinding import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding import com.github.libretube.extensions.BaseActivity +import com.github.libretube.util.DownloadHelper import com.google.android.exoplayer2.ExoPlayer import com.google.android.exoplayer2.MediaItem import com.google.android.exoplayer2.source.MergingMediaSource @@ -69,20 +70,13 @@ class OfflinePlayerActivity : BaseActivity() { } private fun playVideo() { - val videoDownloadDir = File( - getExternalFilesDir(null), - "video" - ) - + val videoDownloadDir = DownloadHelper.getVideoDir(this) val videoFile = File( videoDownloadDir, fileName ) - val audioDownloadDir = File( - getExternalFilesDir(null), - "audio" - ) + val audioDownloadDir = DownloadHelper.getAudioDir(this) val audioFile = File( audioDownloadDir, fileName @@ -129,6 +123,7 @@ class OfflinePlayerActivity : BaseActivity() { } } + @Suppress("DEPRECATION") private fun hideSystemBars() { window?.decorView?.systemUiVisibility = ( View.SYSTEM_UI_FLAG_LAYOUT_STABLE diff --git a/app/src/main/java/com/github/libretube/adapters/DownloadsAdapter.kt b/app/src/main/java/com/github/libretube/adapters/DownloadsAdapter.kt index 2b773b819..0be4e5129 100644 --- a/app/src/main/java/com/github/libretube/adapters/DownloadsAdapter.kt +++ b/app/src/main/java/com/github/libretube/adapters/DownloadsAdapter.kt @@ -9,11 +9,12 @@ import com.github.libretube.R import com.github.libretube.activities.OfflinePlayerActivity import com.github.libretube.constants.IntentData import com.github.libretube.databinding.DownloadedMediaRowBinding +import com.github.libretube.obj.DownloadedFile import com.google.android.material.dialog.MaterialAlertDialogBuilder import java.io.File class DownloadsAdapter( - private val files: MutableList + private val files: MutableList ) : RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DownloadsViewHolder { val binding = DownloadedMediaRowBinding.inflate( @@ -29,7 +30,7 @@ class DownloadsAdapter( val file = files[position] holder.binding.apply { fileName.text = file.name - fileSize.text = "${file.length() / (1024 * 1024)} MiB" + fileSize.text = "${file.size / (1024 * 1024)} MiB" root.setOnClickListener { val intent = Intent(root.context, OfflinePlayerActivity::class.java).also { diff --git a/app/src/main/java/com/github/libretube/fragments/DownloadsFragment.kt b/app/src/main/java/com/github/libretube/fragments/DownloadsFragment.kt index 84f9baabf..cf2befe32 100644 --- a/app/src/main/java/com/github/libretube/fragments/DownloadsFragment.kt +++ b/app/src/main/java/com/github/libretube/fragments/DownloadsFragment.kt @@ -4,11 +4,13 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.size import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.github.libretube.adapters.DownloadsAdapter import com.github.libretube.databinding.FragmentDownloadsBinding import com.github.libretube.extensions.BaseFragment -import java.io.File +import com.github.libretube.util.DownloadHelper class DownloadsFragment : BaseFragment() { private lateinit var binding: FragmentDownloadsBinding @@ -25,14 +27,26 @@ class DownloadsFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val downloadDir = File( - context?.getExternalFilesDir(null), - "video" - ) + val files = DownloadHelper.getDownloadedFiles(requireContext()) + + if (files.isEmpty()) return + + binding.downloadsEmpty.visibility = View.GONE + binding.downloads.visibility = View.VISIBLE binding.downloads.layoutManager = LinearLayoutManager(context) - binding.downloads.adapter = DownloadsAdapter( - downloadDir.listFiles()?.toMutableList() ?: mutableListOf() + binding.downloads.adapter = DownloadsAdapter(files) + + binding.downloads.adapter?.registerAdapterDataObserver( + object : RecyclerView.AdapterDataObserver() { + override fun onChanged() { + if (binding.downloads.size == 0) { + binding.downloads.visibility = View.GONE + binding.downloadsEmpty.visibility = View.VISIBLE + } + super.onChanged() + } + } ) } } diff --git a/app/src/main/java/com/github/libretube/obj/DownloadedFile.kt b/app/src/main/java/com/github/libretube/obj/DownloadedFile.kt new file mode 100644 index 000000000..beb9ec185 --- /dev/null +++ b/app/src/main/java/com/github/libretube/obj/DownloadedFile.kt @@ -0,0 +1,7 @@ +package com.github.libretube.obj + +data class DownloadedFile( + val name: String, + val size: Long, + val type: Int +) diff --git a/app/src/main/java/com/github/libretube/services/DownloadService.kt b/app/src/main/java/com/github/libretube/services/DownloadService.kt index a8380883f..082fe4852 100644 --- a/app/src/main/java/com/github/libretube/services/DownloadService.kt +++ b/app/src/main/java/com/github/libretube/services/DownloadService.kt @@ -7,7 +7,6 @@ import android.content.Context import android.content.Intent import android.content.IntentFilter import android.net.Uri -import android.os.Build import android.os.IBinder import android.util.Log import androidx.core.app.NotificationCompat @@ -19,6 +18,7 @@ import com.github.libretube.constants.DOWNLOAD_FAILURE_NOTIFICATION_ID import com.github.libretube.constants.DOWNLOAD_SUCCESS_NOTIFICATION_ID import com.github.libretube.constants.DownloadType import com.github.libretube.extensions.TAG +import com.github.libretube.util.DownloadHelper import java.io.File class DownloadService : Service() { @@ -28,8 +28,6 @@ class DownloadService : Service() { private lateinit var audioUrl: String private var downloadType: Int = 3 - private lateinit var videoDownloadDir: File - private lateinit var audioDownloadDir: File private var videoDownloadId: Long? = null private var audioDownloadId: Long? = null @@ -64,19 +62,14 @@ class DownloadService : Service() { } private fun downloadManager() { - videoDownloadDir = File( - this.getExternalFilesDir(null), - "video" - ) + // initialize and create the directories to download into - if (!videoDownloadDir.exists()) videoDownloadDir.mkdirs() + val videoDownloadDir = DownloadHelper.getVideoDir(this) + val audioDownloadDir = DownloadHelper.getAudioDir(this) - audioDownloadDir = File( - this.getExternalFilesDir(null), - "audio" - ) - - if (!audioDownloadDir.exists()) audioDownloadDir.mkdirs() + listOf(videoDownloadDir, audioDownloadDir).forEach { + if (!it.exists()) it.mkdir() + } // start download try { @@ -113,9 +106,13 @@ class DownloadService : Service() { private val onDownloadComplete: BroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { // Fetching the download id received with the broadcast - val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) // Checking if the received broadcast is for our enqueued download by matching download id - when (id) { + when ( + intent.getLongExtra( + DownloadManager.EXTRA_DOWNLOAD_ID, + -1 + ) + ) { videoDownloadId -> videoDownloadId = null audioDownloadId -> audioDownloadId = null } @@ -147,13 +144,13 @@ class DownloadService : Service() { } private fun downloadFailedNotification() { - val builder = NotificationCompat.Builder(this@DownloadService, DOWNLOAD_CHANNEL_ID) + val builder = NotificationCompat.Builder(this, DOWNLOAD_CHANNEL_ID) .setSmallIcon(R.drawable.ic_download) .setContentTitle(resources.getString(R.string.downloadfailed)) .setContentText(getString(R.string.fail)) .setPriority(NotificationCompat.PRIORITY_HIGH) - with(NotificationManagerCompat.from(this@DownloadService)) { + with(NotificationManagerCompat.from(this)) { // notificationId is a unique int for each notification that you must define notify(DOWNLOAD_FAILURE_NOTIFICATION_ID, builder.build()) } @@ -161,13 +158,13 @@ class DownloadService : Service() { private fun downloadSucceededNotification() { Log.i(TAG(), "Download succeeded") - val builder = NotificationCompat.Builder(this@DownloadService, DOWNLOAD_CHANNEL_ID) + val builder = NotificationCompat.Builder(this, DOWNLOAD_CHANNEL_ID) .setSmallIcon(R.drawable.ic_download) .setContentTitle(resources.getString(R.string.success)) .setContentText(getString(R.string.downloadsucceeded)) .setPriority(NotificationCompat.PRIORITY_HIGH) - with(NotificationManagerCompat.from(this@DownloadService)) { + with(NotificationManagerCompat.from(this)) { // notificationId is a unique int for each notification that you must define notify(DOWNLOAD_SUCCESS_NOTIFICATION_ID, builder.build()) } @@ -181,14 +178,7 @@ class DownloadService : Service() { Globals.IS_DOWNLOAD_RUNNING = false - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - stopForeground(STOP_FOREGROUND_REMOVE) - } else { - @Suppress("DEPRECATION") - stopForeground(true) - } - - stopService(Intent(this@DownloadService, DownloadService::class.java)) + stopService(Intent(this, DownloadService::class.java)) super.onDestroy() } } diff --git a/app/src/main/java/com/github/libretube/util/DownloadHelper.kt b/app/src/main/java/com/github/libretube/util/DownloadHelper.kt new file mode 100644 index 000000000..397d5f77a --- /dev/null +++ b/app/src/main/java/com/github/libretube/util/DownloadHelper.kt @@ -0,0 +1,62 @@ +package com.github.libretube.util + +import android.content.Context +import com.github.libretube.constants.DownloadType +import com.github.libretube.obj.DownloadedFile +import java.io.File + +object DownloadHelper { + private fun getOfflineStorageDir(context: Context): File { + return context.getExternalFilesDir(null)!! + } + + fun getVideoDir(context: Context): File { + return File( + getOfflineStorageDir(context), + "video" + ) + } + + fun getAudioDir(context: Context): File { + return File( + getOfflineStorageDir(context), + "audio" + ) + } + + fun getDownloadedFiles(context: Context): MutableList { + val videoFiles = getVideoDir(context).listFiles() + val audioFiles = getAudioDir(context).listFiles()?.toMutableList() + + val files = mutableListOf() + + videoFiles?.forEach { + var type = DownloadType.VIDEO + audioFiles?.forEach { audioFile -> + if (audioFile.name == it.name) { + type = DownloadType.AUDIO_VIDEO + audioFiles.remove(audioFile) + } + } + files.add( + DownloadedFile( + name = it.name, + size = it.length(), + type = type + ) + ) + } + + audioFiles?.forEach { + files.add( + DownloadedFile( + name = it.name, + size = it.length(), + type = DownloadType.AUDIO + ) + ) + } + + return files + } +} diff --git a/app/src/main/res/layout/fragment_downloads.xml b/app/src/main/res/layout/fragment_downloads.xml index 676f095ff..cb921bf70 100644 --- a/app/src/main/res/layout/fragment_downloads.xml +++ b/app/src/main/res/layout/fragment_downloads.xml @@ -1,12 +1,36 @@ - + + + + + + + + android:layout_height="wrap_content" + android:visibility="gone" /> - \ No newline at end of file + \ No newline at end of file