update
This commit is contained in:
parent
55df7e9988
commit
6aea370d98
@ -81,6 +81,7 @@ dependencies {
|
|||||||
implementation("androidx.media3:media3-ui:1.3.1")
|
implementation("androidx.media3:media3-ui:1.3.1")
|
||||||
implementation("androidx.media3:media3-common:1.3.1")
|
implementation("androidx.media3:media3-common:1.3.1")
|
||||||
implementation("androidx.media3:media3-datasource-cronet:1.3.1")
|
implementation("androidx.media3:media3-datasource-cronet:1.3.1")
|
||||||
|
implementation("androidx.media3:media3-datasource-okhttp:1.3.1")
|
||||||
|
|
||||||
implementation("io.coil-kt:coil-compose:2.6.0")
|
implementation("io.coil-kt:coil-compose:2.6.0")
|
||||||
implementation("io.ktor:ktor-client-core:2.3.8")
|
implementation("io.ktor:ktor-client-core:2.3.8")
|
||||||
|
|||||||
@ -117,7 +117,7 @@ class MoLikedSongsActivity : MoBaseActivity(), LikedSongsAdapter.OnItemFavorites
|
|||||||
val id = it.favoriteBean.videoId
|
val id = it.favoriteBean.videoId
|
||||||
LogTag.LogD(TAG, "OnDownload id->${id}")
|
LogTag.LogD(TAG, "OnDownload id->${id}")
|
||||||
val currentOfflineBean = App.appOfflineDBManager.getOfflineBeanByID(id)
|
val currentOfflineBean = App.appOfflineDBManager.getOfflineBeanByID(id)
|
||||||
if (currentOfflineBean != null) {//判断当前数据库是否有这条数据。
|
if (currentOfflineBean != null && currentOfflineBean.bytesDownloaded?.let { bytes -> bytes > 0 } == true) {//判断当前数据库是否有这条数据。
|
||||||
if (currentPosition >= 0) {
|
if (currentPosition >= 0) {
|
||||||
val videoId = favoriteBeans[currentPosition].videoId
|
val videoId = favoriteBeans[currentPosition].videoId
|
||||||
showRemoveDownloadDialogHint(videoId)
|
showRemoveDownloadDialogHint(videoId)
|
||||||
@ -185,11 +185,16 @@ class MoLikedSongsActivity : MoBaseActivity(), LikedSongsAdapter.OnItemFavorites
|
|||||||
}
|
}
|
||||||
|
|
||||||
is Request.OnUpdateDownloadUi -> {
|
is Request.OnUpdateDownloadUi -> {
|
||||||
if (App.appOfflineDBManager.getOfflineBeanByID(it.id) != null) {
|
val offBean = App.appOfflineDBManager.getOfflineBeanByID(it.id)
|
||||||
|
if (offBean != null && offBean.bytesDownloaded?.let { bytes -> bytes > 0 } == true) {
|
||||||
|
binding.downloadLoading.visibility = View.GONE
|
||||||
|
binding.downloadImg.visibility = View.VISIBLE
|
||||||
binding.downloadImg.setImageResource(R.drawable.more_downloaded_icon)
|
binding.downloadImg.setImageResource(R.drawable.more_downloaded_icon)
|
||||||
binding.downloadTv.text =
|
binding.downloadTv.text =
|
||||||
getString(R.string.download_remove_offline)
|
getString(R.string.download_remove_offline)
|
||||||
} else {
|
} else {
|
||||||
|
binding.downloadLoading.visibility = View.GONE
|
||||||
|
binding.downloadImg.visibility = View.VISIBLE
|
||||||
binding.downloadImg.setImageResource(R.drawable.more_download_icon)
|
binding.downloadImg.setImageResource(R.drawable.more_download_icon)
|
||||||
binding.downloadTv.text = getString(R.string.download_save_offline)
|
binding.downloadTv.text = getString(R.string.download_save_offline)
|
||||||
}
|
}
|
||||||
@ -406,8 +411,6 @@ class MoLikedSongsActivity : MoBaseActivity(), LikedSongsAdapter.OnItemFavorites
|
|||||||
}
|
}
|
||||||
requests.trySend(Request.UpdateFavorite(bean))
|
requests.trySend(Request.UpdateFavorite(bean))
|
||||||
|
|
||||||
requests.trySend(Request.OnUpdateDownloadUi(bean.videoId))
|
|
||||||
|
|
||||||
val currentDownload = DownloadUtil.getCurrentIdDownload(bean.videoId)
|
val currentDownload = DownloadUtil.getCurrentIdDownload(bean.videoId)
|
||||||
if (currentDownload != null) {
|
if (currentDownload != null) {
|
||||||
updateDownloadUI(currentDownload)
|
updateDownloadUI(currentDownload)
|
||||||
|
|||||||
@ -28,7 +28,6 @@ import melody.offline.music.adapter.DetailsListAdapter
|
|||||||
import melody.offline.music.ads.AdPlacement
|
import melody.offline.music.ads.AdPlacement
|
||||||
import melody.offline.music.ads.LolAdWrapper
|
import melody.offline.music.ads.LolAdWrapper
|
||||||
import melody.offline.music.bean.FavoriteBean
|
import melody.offline.music.bean.FavoriteBean
|
||||||
import melody.offline.music.bean.OfflineBean
|
|
||||||
import melody.offline.music.databinding.ActivityDetailsBinding
|
import melody.offline.music.databinding.ActivityDetailsBinding
|
||||||
import melody.offline.music.innertube.Innertube
|
import melody.offline.music.innertube.Innertube
|
||||||
import melody.offline.music.innertube.requests.moPlaylistPage
|
import melody.offline.music.innertube.requests.moPlaylistPage
|
||||||
@ -36,7 +35,6 @@ import melody.offline.music.service.MyDownloadService
|
|||||||
import melody.offline.music.service.ViewModelMain
|
import melody.offline.music.service.ViewModelMain
|
||||||
import melody.offline.music.util.AnalysisUtil
|
import melody.offline.music.util.AnalysisUtil
|
||||||
import melody.offline.music.util.DownloadUtil
|
import melody.offline.music.util.DownloadUtil
|
||||||
import melody.offline.music.util.LogTag
|
|
||||||
import melody.offline.music.util.LogTag.LogD
|
import melody.offline.music.util.LogTag.LogD
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
@ -162,9 +160,8 @@ class MoListDetailsActivity : MoBaseActivity(), DetailsListAdapter.OnItemMoreCli
|
|||||||
|
|
||||||
is Request.OnDownload -> {
|
is Request.OnDownload -> {
|
||||||
val id = it.bean.videoId
|
val id = it.bean.videoId
|
||||||
val currentOfflineBean =
|
val offBean = App.appOfflineDBManager.getOfflineBeanByID(id!!)
|
||||||
App.appOfflineDBManager.getOfflineBeanByID(id!!)
|
if (offBean != null && offBean.bytesDownloaded?.let { bytes -> bytes > 0 } == true) {//判断当前数据库是否有这条数据。
|
||||||
if (currentOfflineBean != null) {//判断当前数据库是否有这条数据。
|
|
||||||
if (currentPosition >= 0) {
|
if (currentPosition >= 0) {
|
||||||
showRemoveDownloadDialogHint(id)
|
showRemoveDownloadDialogHint(id)
|
||||||
}
|
}
|
||||||
@ -244,11 +241,16 @@ class MoListDetailsActivity : MoBaseActivity(), DetailsListAdapter.OnItemMoreCli
|
|||||||
}
|
}
|
||||||
|
|
||||||
is Request.OnUpdateDownloadUi -> {
|
is Request.OnUpdateDownloadUi -> {
|
||||||
if (App.appOfflineDBManager.getOfflineBeanByID(it.id) != null) {
|
val offBean = App.appOfflineDBManager.getOfflineBeanByID(it.id)
|
||||||
|
if (offBean != null && offBean.bytesDownloaded?.let { bytes -> bytes > 0 } == true) {
|
||||||
|
binding.downloadLoading.visibility = View.GONE
|
||||||
|
binding.downloadImg.visibility = View.VISIBLE
|
||||||
binding.downloadImg.setImageResource(R.drawable.more_downloaded_icon)
|
binding.downloadImg.setImageResource(R.drawable.more_downloaded_icon)
|
||||||
binding.downloadTv.text =
|
binding.downloadTv.text =
|
||||||
getString(R.string.download_remove_offline)
|
getString(R.string.download_remove_offline)
|
||||||
} else {
|
} else {
|
||||||
|
binding.downloadLoading.visibility = View.GONE
|
||||||
|
binding.downloadImg.visibility = View.VISIBLE
|
||||||
binding.downloadImg.setImageResource(R.drawable.more_download_icon)
|
binding.downloadImg.setImageResource(R.drawable.more_download_icon)
|
||||||
binding.downloadTv.text = getString(R.string.download_save_offline)
|
binding.downloadTv.text = getString(R.string.download_save_offline)
|
||||||
}
|
}
|
||||||
@ -436,6 +438,7 @@ class MoListDetailsActivity : MoBaseActivity(), DetailsListAdapter.OnItemMoreCli
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateDownloadUI(download: Download) {
|
private fun updateDownloadUI(download: Download) {
|
||||||
|
LogD(TAG, "download.state->${download.state}")
|
||||||
when (download.state) {
|
when (download.state) {
|
||||||
Download.STATE_DOWNLOADING -> {
|
Download.STATE_DOWNLOADING -> {
|
||||||
binding.downloadLoading.visibility = View.VISIBLE
|
binding.downloadLoading.visibility = View.VISIBLE
|
||||||
@ -527,11 +530,11 @@ class MoListDetailsActivity : MoBaseActivity(), DetailsListAdapter.OnItemMoreCli
|
|||||||
}
|
}
|
||||||
requests.trySend(Request.UpdateFavorite(bean))
|
requests.trySend(Request.UpdateFavorite(bean))
|
||||||
|
|
||||||
requests.trySend(Request.OnUpdateDownloadUi(bean.videoId!!))
|
val currentDownload = DownloadUtil.getCurrentIdDownload(bean.videoId!!)
|
||||||
|
|
||||||
val currentDownload = DownloadUtil.getCurrentIdDownload(bean.videoId)
|
|
||||||
if (currentDownload != null) {
|
if (currentDownload != null) {
|
||||||
updateDownloadUI(currentDownload)
|
updateDownloadUI(currentDownload)
|
||||||
|
} else {
|
||||||
|
requests.trySend(Request.OnUpdateDownloadUi(bean.videoId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -68,6 +68,7 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
|
|||||||
const val PLAY_DETAILS_NAME = "play_details_name"
|
const val PLAY_DETAILS_NAME = "play_details_name"
|
||||||
const val PLAY_DETAILS_DESC = "play_details_desc"
|
const val PLAY_DETAILS_DESC = "play_details_desc"
|
||||||
const val PLAY_DETAILS_COME_FROM = "PLAY_DETAILS_COME_FROM"
|
const val PLAY_DETAILS_COME_FROM = "PLAY_DETAILS_COME_FROM"
|
||||||
|
const val PLAY_LIST_ID = "play_list_id"
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var binding: ActivityMoPlayDetailsBinding
|
private lateinit var binding: ActivityMoPlayDetailsBinding
|
||||||
@ -164,6 +165,34 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
|
|||||||
} else {
|
} else {
|
||||||
binding.playbackErrorLayout.visibility = View.VISIBLE
|
binding.playbackErrorLayout.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
} else if (comeFrom != null && comeFrom == MoPlaylistSongsActivity::class.java) {
|
||||||
|
LogD(TAG, "从 playlist songs 进入")
|
||||||
|
binding.nameTv.text = intent.getStringExtra(PLAY_DETAILS_NAME)
|
||||||
|
binding.descTv.text = intent.getStringExtra(PLAY_DETAILS_DESC)
|
||||||
|
|
||||||
|
val playlistID = intent.getIntExtra(PLAY_LIST_ID, -1)
|
||||||
|
val playlistItems = App.appPlaylistDBManager.getPlaylistItems(playlistID)
|
||||||
|
|
||||||
|
//找到当前点击进来的歌曲media
|
||||||
|
val findCurrentMedia = playlistItems.find { it.videoId == videoId }?.asMediaItem
|
||||||
|
if (findCurrentMedia != null) {
|
||||||
|
binding.likeAndDownloadLayout.visibility = View.VISIBLE
|
||||||
|
updateInfoUi(findCurrentMedia)
|
||||||
|
binding.playbackErrorLayout.visibility = View.GONE
|
||||||
|
binding.totalDurationTv.visibility = View.GONE
|
||||||
|
meController?.let {
|
||||||
|
it.setMediaItem(findCurrentMedia, true)
|
||||||
|
it.prepare()
|
||||||
|
it.play()
|
||||||
|
val mediaItems =
|
||||||
|
playlistItems.map { mapAll -> mapAll.asMediaItem }//转换成MediaItem
|
||||||
|
.filter { filter -> filter.mediaId != videoId }//过滤掉id相等的。
|
||||||
|
it.addMediaItems(mediaItems)
|
||||||
|
}
|
||||||
|
updatePlayListDataAndAdapter()
|
||||||
|
} else {
|
||||||
|
binding.playbackErrorLayout.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LogD(TAG, "从点击任意歌曲进入")
|
LogD(TAG, "从点击任意歌曲进入")
|
||||||
binding.nameTv.text = intent.getStringExtra(PLAY_DETAILS_NAME)
|
binding.nameTv.text = intent.getStringExtra(PLAY_DETAILS_NAME)
|
||||||
|
|||||||
@ -7,9 +7,14 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.animation.AnimationUtils
|
import android.view.animation.AnimationUtils
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.annotation.OptIn
|
import androidx.annotation.OptIn
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.net.toUri
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
|
import androidx.media3.exoplayer.offline.Download
|
||||||
|
import androidx.media3.exoplayer.offline.DownloadRequest
|
||||||
|
import androidx.media3.exoplayer.offline.DownloadService
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.gyf.immersionbar.ktx.immersionBar
|
import com.gyf.immersionbar.ktx.immersionBar
|
||||||
@ -21,8 +26,15 @@ import melody.offline.music.R
|
|||||||
import melody.offline.music.adapter.PlaylistSongsAdapter
|
import melody.offline.music.adapter.PlaylistSongsAdapter
|
||||||
import melody.offline.music.ads.AdPlacement
|
import melody.offline.music.ads.AdPlacement
|
||||||
import melody.offline.music.ads.LolAdWrapper
|
import melody.offline.music.ads.LolAdWrapper
|
||||||
|
import melody.offline.music.bean.FavoriteBean
|
||||||
import melody.offline.music.bean.PlaylistItem
|
import melody.offline.music.bean.PlaylistItem
|
||||||
import melody.offline.music.databinding.ActivityPlaylistSongsBinding
|
import melody.offline.music.databinding.ActivityPlaylistSongsBinding
|
||||||
|
import melody.offline.music.service.MyDownloadService
|
||||||
|
import melody.offline.music.service.ViewModelMain
|
||||||
|
import melody.offline.music.util.AnalysisUtil
|
||||||
|
import melody.offline.music.util.DownloadUtil
|
||||||
|
import melody.offline.music.util.LogTag
|
||||||
|
import org.json.JSONObject
|
||||||
|
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
class MoPlaylistSongsActivity : MoBaseActivity() {
|
class MoPlaylistSongsActivity : MoBaseActivity() {
|
||||||
@ -35,6 +47,22 @@ class MoPlaylistSongsActivity : MoBaseActivity() {
|
|||||||
|
|
||||||
sealed class Request {
|
sealed class Request {
|
||||||
data object TryAgain : Request()
|
data object TryAgain : Request()
|
||||||
|
data class UpdateFavorite(val bean: PlaylistItem) : Request()
|
||||||
|
|
||||||
|
data class OnFavorites(
|
||||||
|
val bean: PlaylistItem
|
||||||
|
) : Request()
|
||||||
|
|
||||||
|
data class OnDownload(
|
||||||
|
val bean: PlaylistItem
|
||||||
|
) : Request()
|
||||||
|
|
||||||
|
data class OnDownloadRemove(val id: String) : Request()
|
||||||
|
data class OnUpdateDownloadUi(val id: String) : Request()
|
||||||
|
data class OnRemovePlaylist(
|
||||||
|
val bean: PlaylistItem
|
||||||
|
) : Request()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var binding: ActivityPlaylistSongsBinding
|
private lateinit var binding: ActivityPlaylistSongsBinding
|
||||||
@ -54,6 +82,7 @@ class MoPlaylistSongsActivity : MoBaseActivity() {
|
|||||||
initView()
|
initView()
|
||||||
initAdapter()
|
initAdapter()
|
||||||
LolAdWrapper.shared.loadAdIfNotCached(this, AdPlacement.INST_ME_PAGE_LIST)
|
LolAdWrapper.shared.loadAdIfNotCached(this, AdPlacement.INST_ME_PAGE_LIST)
|
||||||
|
initDownloadFlow()
|
||||||
initData()
|
initData()
|
||||||
onReceive()
|
onReceive()
|
||||||
}
|
}
|
||||||
@ -74,6 +103,158 @@ class MoPlaylistSongsActivity : MoBaseActivity() {
|
|||||||
Request.TryAgain -> {
|
Request.TryAgain -> {
|
||||||
initData()
|
initData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is Request.UpdateFavorite -> {
|
||||||
|
val currentFavoriteBean =
|
||||||
|
App.appFavoriteDBManager.getFavoriteBeanByID(it.bean.videoId)
|
||||||
|
if (currentFavoriteBean != null) {
|
||||||
|
updateFavoriteUi(currentFavoriteBean.isFavorite)
|
||||||
|
} else {
|
||||||
|
updateFavoriteUi(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is Request.OnFavorites -> {
|
||||||
|
val jsonObject = JSONObject()
|
||||||
|
jsonObject.put(
|
||||||
|
"song_title", it.bean.title
|
||||||
|
)
|
||||||
|
val songMap = mutableMapOf(
|
||||||
|
Pair(
|
||||||
|
AnalysisUtil.PARAM_VALUE, jsonObject.toString()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val currentFavoriteBean =
|
||||||
|
App.appFavoriteDBManager.getFavoriteBeanByID(it.bean.videoId!!)
|
||||||
|
if (currentFavoriteBean != null) {
|
||||||
|
currentFavoriteBean.isFavorite = !currentFavoriteBean.isFavorite
|
||||||
|
App.appFavoriteDBManager.updateFavoriteBean(currentFavoriteBean)
|
||||||
|
if (currentFavoriteBean.isFavorite) {
|
||||||
|
AnalysisUtil.logEvent(
|
||||||
|
AnalysisUtil.PLAYER_B_LOVE_CLICK, songMap
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
AnalysisUtil.logEvent(
|
||||||
|
AnalysisUtil.PLAYER_B_UN_LOVE_CLICK, songMap
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val b = FavoriteBean(
|
||||||
|
videoId = it.bean.videoId,
|
||||||
|
title = it.bean.title,
|
||||||
|
name = it.bean.name,
|
||||||
|
thumbnail = it.bean.thumbnail,
|
||||||
|
isFavorite = true
|
||||||
|
)
|
||||||
|
App.appFavoriteDBManager.insertFavoriteBean(b)
|
||||||
|
AnalysisUtil.logEvent(AnalysisUtil.PLAYER_B_LOVE_CLICK, songMap)
|
||||||
|
}
|
||||||
|
requests.trySend(Request.UpdateFavorite(it.bean))
|
||||||
|
}
|
||||||
|
|
||||||
|
is Request.OnDownload -> {
|
||||||
|
val id = it.bean.videoId
|
||||||
|
val offBean = App.appOfflineDBManager.getOfflineBeanByID(id)
|
||||||
|
if (offBean != null && offBean.bytesDownloaded?.let { bytes -> bytes > 0 } == true) {//判断当前数据库是否有这条数据。
|
||||||
|
if (currentPosition >= 0) {
|
||||||
|
showRemoveDownloadDialogHint(id)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val isFavorite =
|
||||||
|
App.appFavoriteDBManager.getFavoriteBeanByID(it.bean.videoId.toString()) != null
|
||||||
|
//判断是否已经下载了这条数据,已经下载,就直接进行数据库数据存储,反之走下载流程。
|
||||||
|
if (DownloadUtil.downloadResourceExist(id)) {
|
||||||
|
val favoriteBean = FavoriteBean(
|
||||||
|
id,
|
||||||
|
it.bean.title,
|
||||||
|
it.bean.name,
|
||||||
|
it.bean.thumbnail,
|
||||||
|
isFavorite
|
||||||
|
)
|
||||||
|
insertOfflineData(favoriteBean)
|
||||||
|
requests.trySend(Request.OnUpdateDownloadUi(id))
|
||||||
|
} else {
|
||||||
|
val downloadRequest = DownloadRequest.Builder(id, id.toUri())
|
||||||
|
.setCustomCacheKey(id).build()
|
||||||
|
|
||||||
|
val downloadCount = DownloadUtil.getCurrentDownloads()
|
||||||
|
if (downloadCount >= 3) {
|
||||||
|
Toast.makeText(
|
||||||
|
this@MoPlaylistSongsActivity,
|
||||||
|
getString(R.string.download_tips),
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
} else {
|
||||||
|
DownloadService.sendAddDownload(
|
||||||
|
this@MoPlaylistSongsActivity,
|
||||||
|
MyDownloadService::class.java,
|
||||||
|
downloadRequest,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
LolAdWrapper.shared.showAdTiming(
|
||||||
|
this@MoPlaylistSongsActivity, AdPlacement.INST_DOWNLOAD
|
||||||
|
)
|
||||||
|
val favoriteBean = FavoriteBean(
|
||||||
|
id,
|
||||||
|
it.bean.title,
|
||||||
|
it.bean.name,
|
||||||
|
it.bean.thumbnail,
|
||||||
|
isFavorite
|
||||||
|
)
|
||||||
|
insertOfflineData(favoriteBean)
|
||||||
|
val jsonObject = JSONObject()
|
||||||
|
jsonObject.put(
|
||||||
|
"download_id", favoriteBean.videoId
|
||||||
|
)
|
||||||
|
val songMap = mutableMapOf(
|
||||||
|
Pair(
|
||||||
|
AnalysisUtil.PARAM_VALUE, jsonObject.toString()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
AnalysisUtil.logEvent(
|
||||||
|
AnalysisUtil.PLAYER_B_DOWNLOAD_CLICK, songMap
|
||||||
|
)
|
||||||
|
|
||||||
|
LolAdWrapper.shared.loadAdIfNotCached(
|
||||||
|
this@MoPlaylistSongsActivity, AdPlacement.INST_DOWNLOAD
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is Request.OnDownloadRemove -> {
|
||||||
|
val currentOfflineBean =
|
||||||
|
App.appOfflineDBManager.getOfflineBeanByID(it.id)
|
||||||
|
if (currentOfflineBean != null) {
|
||||||
|
App.appOfflineDBManager.deleteOfflineBean(currentOfflineBean)
|
||||||
|
}
|
||||||
|
|
||||||
|
requests.trySend(Request.OnUpdateDownloadUi(it.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
is Request.OnUpdateDownloadUi -> {
|
||||||
|
val offBean = App.appOfflineDBManager.getOfflineBeanByID(it.id)
|
||||||
|
if (offBean != null && offBean.bytesDownloaded?.let { bytes -> bytes > 0 } == true) {
|
||||||
|
binding.downloadLoading.visibility = View.GONE
|
||||||
|
binding.downloadImg.visibility = View.VISIBLE
|
||||||
|
binding.downloadImg.setImageResource(R.drawable.more_downloaded_icon)
|
||||||
|
binding.downloadTv.text =
|
||||||
|
getString(R.string.download_remove_offline)
|
||||||
|
} else {
|
||||||
|
binding.downloadLoading.visibility = View.GONE
|
||||||
|
binding.downloadImg.visibility = View.VISIBLE
|
||||||
|
binding.downloadImg.setImageResource(R.drawable.more_download_icon)
|
||||||
|
binding.downloadTv.text = getString(R.string.download_save_offline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is Request.OnRemovePlaylist -> {
|
||||||
|
playlistItems.remove(it.bean)
|
||||||
|
adapter?.notifyDataSetChanged()
|
||||||
|
App.appPlaylistDBManager.deletePlaylistItem(it.bean)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
events.onReceive {
|
events.onReceive {
|
||||||
@ -132,17 +313,32 @@ class MoPlaylistSongsActivity : MoBaseActivity() {
|
|||||||
binding.bottomBlankLayout.setOnClickListener {
|
binding.bottomBlankLayout.setOnClickListener {
|
||||||
hideBottomLayout()
|
hideBottomLayout()
|
||||||
}
|
}
|
||||||
|
binding.favoritesBtn.setOnClickListener {
|
||||||
|
if (currentPosition >= 0) {
|
||||||
|
requests.trySend(
|
||||||
|
Request.OnFavorites(
|
||||||
|
playlistItems[currentPosition]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
binding.moreDownloadBtn.setOnClickListener {
|
binding.moreDownloadBtn.setOnClickListener {
|
||||||
if (currentPosition >= 0) {
|
if (currentPosition >= 0) {
|
||||||
|
requests.trySend(
|
||||||
|
Request.OnDownload(
|
||||||
|
playlistItems[currentPosition]
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.moreAddPlaylistBtn.setOnClickListener {
|
binding.moreAddPlaylistBtn.setOnClickListener {
|
||||||
if (currentPosition >= 0) {
|
if (currentPosition >= 0) {
|
||||||
}
|
requests.trySend(
|
||||||
}
|
Request.OnRemovePlaylist(
|
||||||
binding.favoritesBtn.setOnClickListener {
|
playlistItems[currentPosition]
|
||||||
if (currentPosition >= 0) {
|
)
|
||||||
|
)
|
||||||
|
hideBottomLayout()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,12 +381,85 @@ class MoPlaylistSongsActivity : MoBaseActivity() {
|
|||||||
dialog.show()
|
dialog.show()
|
||||||
okBtn.setOnClickListener {
|
okBtn.setOnClickListener {
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
|
requests.trySend(Request.OnDownloadRemove(id))
|
||||||
}
|
}
|
||||||
cancelBtn.setOnClickListener {
|
cancelBtn.setOnClickListener {
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initDownloadFlow() {
|
||||||
|
ViewModelMain.modelDownloadsFlow.observe(this) { downloads ->
|
||||||
|
if (currentPosition >= 0) {
|
||||||
|
val id = playlistItems[currentPosition].videoId
|
||||||
|
val currentScreenDownloads = downloads[id]
|
||||||
|
if (currentScreenDownloads != null) {
|
||||||
|
updateDownloadUI(currentScreenDownloads)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateDownloadUI(download: Download) {
|
||||||
|
LogTag.LogD(TAG, "download.state->${download.state}")
|
||||||
|
when (download.state) {
|
||||||
|
Download.STATE_DOWNLOADING -> {
|
||||||
|
binding.downloadLoading.visibility = View.VISIBLE
|
||||||
|
binding.downloadImg.setImageResource(R.drawable.more_download_icon)
|
||||||
|
binding.downloadImg.visibility = View.GONE
|
||||||
|
|
||||||
|
binding.downloadTv.text = getString(R.string.download_saving)
|
||||||
|
|
||||||
|
binding.moreDownloadBtn.isClickable = false
|
||||||
|
binding.moreDownloadBtn.isEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
Download.STATE_COMPLETED -> {
|
||||||
|
binding.downloadLoading.visibility = View.GONE
|
||||||
|
binding.downloadImg.setImageResource(R.drawable.more_downloaded_icon)
|
||||||
|
binding.downloadImg.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
binding.downloadTv.text = getString(R.string.download_remove_offline)
|
||||||
|
|
||||||
|
binding.moreDownloadBtn.isClickable = true
|
||||||
|
binding.moreDownloadBtn.isEnabled = true
|
||||||
|
|
||||||
|
val jsonObject = JSONObject()
|
||||||
|
jsonObject.put(
|
||||||
|
"download_id", download.request.id
|
||||||
|
)
|
||||||
|
val songMap = mutableMapOf(
|
||||||
|
Pair(
|
||||||
|
AnalysisUtil.PARAM_VALUE, jsonObject.toString()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
AnalysisUtil.logEvent(AnalysisUtil.PLAYER_B_DOWNLOAD_SUCCESS_ACTION, songMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
Download.STATE_FAILED -> {
|
||||||
|
binding.downloadLoading.visibility = View.GONE
|
||||||
|
binding.downloadImg.setImageResource(R.drawable.error)
|
||||||
|
binding.downloadImg.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
binding.downloadTv.text = getString(R.string.download_save_offline)
|
||||||
|
|
||||||
|
binding.moreDownloadBtn.isClickable = true
|
||||||
|
binding.moreDownloadBtn.isEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
binding.downloadLoading.visibility = View.GONE
|
||||||
|
binding.downloadImg.setImageResource(R.drawable.more_download_icon)
|
||||||
|
binding.downloadImg.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
binding.downloadTv.text = getString(R.string.download_save_offline)
|
||||||
|
|
||||||
|
binding.moreDownloadBtn.isClickable = true
|
||||||
|
binding.moreDownloadBtn.isEnabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateFavoriteUi(b: Boolean) {
|
private fun updateFavoriteUi(b: Boolean) {
|
||||||
if (b) {
|
if (b) {
|
||||||
binding.favoritesImg.setImageResource(R.drawable.favorited_icon)
|
binding.favoritesImg.setImageResource(R.drawable.favorited_icon)
|
||||||
@ -221,6 +490,15 @@ class MoPlaylistSongsActivity : MoBaseActivity() {
|
|||||||
binding.name.visibility = View.VISIBLE
|
binding.name.visibility = View.VISIBLE
|
||||||
binding.name.text = bean.name
|
binding.name.text = bean.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requests.trySend(Request.UpdateFavorite(bean))
|
||||||
|
|
||||||
|
val currentDownload = DownloadUtil.getCurrentIdDownload(bean.videoId)
|
||||||
|
if (currentDownload != null) {
|
||||||
|
updateDownloadUI(currentDownload)
|
||||||
|
} else {
|
||||||
|
requests.trySend(Request.OnUpdateDownloadUi(bean.videoId))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hideBottomLayout() {
|
private fun hideBottomLayout() {
|
||||||
|
|||||||
@ -9,12 +9,10 @@ import android.view.ViewGroup
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import melody.offline.music.R
|
import melody.offline.music.R
|
||||||
import melody.offline.music.activity.MoOfflineSongsActivity
|
|
||||||
import melody.offline.music.activity.MoPlayDetailsActivity
|
import melody.offline.music.activity.MoPlayDetailsActivity
|
||||||
import melody.offline.music.bean.OfflineBean
|
import melody.offline.music.activity.MoPlaylistSongsActivity
|
||||||
import melody.offline.music.bean.PlaylistItem
|
import melody.offline.music.bean.PlaylistItem
|
||||||
import melody.offline.music.databinding.PlayListItemBinding
|
import melody.offline.music.databinding.PlayListItemBinding
|
||||||
import melody.offline.music.media.MediaControllerManager
|
|
||||||
|
|
||||||
class PlaylistSongsAdapter(
|
class PlaylistSongsAdapter(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
@ -43,14 +41,15 @@ class PlaylistSongsAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
holder.itemView.setOnClickListener {
|
holder.itemView.setOnClickListener {
|
||||||
// val intent = Intent(context, MoPlayDetailsActivity::class.java)
|
val intent = Intent(context, MoPlayDetailsActivity::class.java)
|
||||||
// intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_VIDEO_ID, bean.videoId)
|
intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_VIDEO_ID, bean.videoId)
|
||||||
// intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_NAME, bean.title)
|
intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_NAME, bean.title)
|
||||||
// intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_DESC, bean.name)
|
intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_DESC, bean.name)
|
||||||
// intent.putExtra(
|
intent.putExtra(
|
||||||
// MoPlayDetailsActivity.PLAY_DETAILS_COME_FROM, MoOfflineSongsActivity::class.java
|
MoPlayDetailsActivity.PLAY_DETAILS_COME_FROM, MoPlaylistSongsActivity::class.java
|
||||||
// )
|
)
|
||||||
// context.startActivity(intent)
|
intent.putExtra(MoPlayDetailsActivity.PLAY_LIST_ID, bean.playlistId)
|
||||||
|
context.startActivity(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -159,8 +159,8 @@ class MoMeFragment : MoBaseFragment<FragmentMoMeBinding>(), NewPlayListAdapter.O
|
|||||||
requireActivity(),
|
requireActivity(),
|
||||||
AdPlacement.NATIVE_ME_PAGE_LIST,
|
AdPlacement.NATIVE_ME_PAGE_LIST,
|
||||||
binding.frameAd,
|
binding.frameAd,
|
||||||
R.layout.ad_layout_admob_result,
|
R.layout.ad_layout_admob_banner,
|
||||||
R.layout.ad_layout_max_result
|
R.layout.ad_layout_max_banner
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,6 +189,7 @@ class MoMeFragment : MoBaseFragment<FragmentMoMeBinding>(), NewPlayListAdapter.O
|
|||||||
override fun onItemClick(position: Int) {
|
override fun onItemClick(position: Int) {
|
||||||
val intent = Intent(requireActivity(), MoPlaylistSongsActivity::class.java)
|
val intent = Intent(requireActivity(), MoPlaylistSongsActivity::class.java)
|
||||||
intent.putExtra(MoPlaylistSongsActivity.PLAYLIST_ID, playlist[position].id)
|
intent.putExtra(MoPlaylistSongsActivity.PLAYLIST_ID, playlist[position].id)
|
||||||
|
intent.putExtra(MoPlaylistSongsActivity.PLAYLIST_TITLE, playlist[position].title)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import androidx.media3.common.MediaMetadata
|
|||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import melody.offline.music.bean.FavoriteBean
|
import melody.offline.music.bean.FavoriteBean
|
||||||
import melody.offline.music.bean.OfflineBean
|
import melody.offline.music.bean.OfflineBean
|
||||||
|
import melody.offline.music.bean.PlaylistItem
|
||||||
import melody.offline.music.innertube.Innertube
|
import melody.offline.music.innertube.Innertube
|
||||||
import melody.offline.music.innertube.models.bodies.ContinuationBody
|
import melody.offline.music.innertube.models.bodies.ContinuationBody
|
||||||
import melody.offline.music.innertube.requests.playlistPage
|
import melody.offline.music.innertube.requests.playlistPage
|
||||||
@ -46,6 +47,21 @@ val FavoriteBean.asMediaItem: MediaItem
|
|||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
val PlaylistItem.asMediaItem: MediaItem
|
||||||
|
@OptIn(UnstableApi::class)
|
||||||
|
get() = MediaItem.Builder()
|
||||||
|
.setMediaId(videoId)
|
||||||
|
.setUri(videoId)
|
||||||
|
.setCustomCacheKey(videoId)
|
||||||
|
.setMediaMetadata(
|
||||||
|
MediaMetadata.Builder()
|
||||||
|
.setTitle(title)
|
||||||
|
.setArtist(name)
|
||||||
|
.setArtworkUri(thumbnail?.toUri())
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
|
||||||
val Innertube.SongItem.asMediaItem: MediaItem
|
val Innertube.SongItem.asMediaItem: MediaItem
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
get() = MediaItem.Builder()
|
get() = MediaItem.Builder()
|
||||||
|
|||||||
@ -383,7 +383,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="12dp"
|
||||||
android:text="@string/download"
|
android:text="@string/download_save_offline"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="14dp" />
|
android:textSize="14dp" />
|
||||||
|
|
||||||
|
|||||||
@ -57,6 +57,7 @@
|
|||||||
android:textSize="18dp" />
|
android:textSize="18dp" />
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
android:visibility="gone"
|
||||||
android:id="@+id/playlist_title_more_btn"
|
android:id="@+id/playlist_title_more_btn"
|
||||||
android:layout_width="42dp"
|
android:layout_width="42dp"
|
||||||
android:layout_height="42dp">
|
android:layout_height="42dp">
|
||||||
@ -347,7 +348,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="12dp"
|
||||||
android:text="@string/add_to_playlist"
|
android:text="@string/remove_from_playlist"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="14dp" />
|
android:textSize="14dp" />
|
||||||
|
|
||||||
|
|||||||
@ -94,7 +94,7 @@
|
|||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/downloadBtn"
|
android:id="@+id/downloadBtn"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
android:visibility="visible"
|
android:visibility="gone"
|
||||||
android:layout_height="40dp">
|
android:layout_height="40dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
|||||||
@ -119,6 +119,7 @@
|
|||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:visibility="gone"
|
||||||
android:id="@+id/downloadBtn"
|
android:id="@+id/downloadBtn"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
|
|||||||
@ -44,6 +44,7 @@
|
|||||||
<string name="play">PLAY</string>
|
<string name="play">PLAY</string>
|
||||||
<string name="download_tips">There are additional download tasks in progress, please wait a moment.</string>
|
<string name="download_tips">There are additional download tasks in progress, please wait a moment.</string>
|
||||||
<string name="add_to_playlist">Add to playlist</string>
|
<string name="add_to_playlist">Add to playlist</string>
|
||||||
|
<string name="remove_from_playlist">Remove from playlist</string>
|
||||||
<string name="download_saving">Saving</string>
|
<string name="download_saving">Saving</string>
|
||||||
<string name="download_save_offline">Save to Offline</string>
|
<string name="download_save_offline">Save to Offline</string>
|
||||||
<string name="download_remove_offline">Remove from offline</string>
|
<string name="download_remove_offline">Remove from offline</string>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user