343 lines
13 KiB
Kotlin
343 lines
13 KiB
Kotlin
package melody.offline.music.activity
|
||
|
||
import android.annotation.SuppressLint
|
||
import android.graphics.Color
|
||
import android.graphics.drawable.ColorDrawable
|
||
import android.view.LayoutInflater
|
||
import android.view.View
|
||
import android.widget.TextView
|
||
import androidx.annotation.OptIn
|
||
import androidx.appcompat.app.AlertDialog
|
||
import androidx.media3.common.util.UnstableApi
|
||
import androidx.media3.exoplayer.offline.Download
|
||
import androidx.recyclerview.widget.LinearLayoutManager
|
||
import com.gyf.immersionbar.ktx.immersionBar
|
||
import kotlinx.coroutines.channels.Channel
|
||
import kotlinx.coroutines.isActive
|
||
import kotlinx.coroutines.selects.select
|
||
import melody.offline.music.App
|
||
import melody.offline.music.R
|
||
import melody.offline.music.adapter.OfflineSongsAdapter
|
||
import melody.offline.music.ads.AdPlacement
|
||
import melody.offline.music.ads.LolAdWrapper
|
||
import melody.offline.music.bean.FavoriteBean
|
||
import melody.offline.music.bean.OfflineBean
|
||
import melody.offline.music.bean.PlaylistItem
|
||
import melody.offline.music.databinding.ActivityOfflineSongsBinding
|
||
import melody.offline.music.util.AnalysisUtil
|
||
import melody.offline.music.util.LogTag
|
||
import melody.offline.music.view.ListMoreBottomSheetDialog
|
||
import org.json.JSONObject
|
||
|
||
@OptIn(UnstableApi::class)
|
||
class MoOfflineSongsActivity : MoBaseActivity(), ListMoreBottomSheetDialog.ListMoreViewListener,
|
||
ListMoreBottomSheetDialog.UpdateAdapterListener {
|
||
private val requests: Channel<Request> = Channel(Channel.UNLIMITED)
|
||
|
||
sealed class Request {
|
||
data object TryAgain : Request()
|
||
data class OnFavorites(val bean: PlaylistItem) : Request()
|
||
data class OnDownloadRemove(val bean: PlaylistItem) : Request()
|
||
data class UpdateFavorite(val bean: PlaylistItem) : Request()
|
||
data class OnAddPlaylist(val bean: PlaylistItem) : Request()
|
||
data class OnUpdateCurrentListItem(val bean: PlaylistItem) : Request()
|
||
}
|
||
|
||
private lateinit var binding: ActivityOfflineSongsBinding
|
||
private var adapter: OfflineSongsAdapter? = null
|
||
|
||
private var myList: MutableList<PlaylistItem> = mutableListOf()
|
||
private var moreDialog: ListMoreBottomSheetDialog? = null
|
||
private var currentPosition = -1
|
||
|
||
override suspend fun main() {
|
||
binding = ActivityOfflineSongsBinding.inflate(layoutInflater)
|
||
setContentView(binding.root)
|
||
LolAdWrapper.shared.showAdTiming(this, AdPlacement.INST_ME_PAGE_LIST)
|
||
initImmersionBar()
|
||
initView()
|
||
initAdapter()
|
||
LolAdWrapper.shared.loadAdIfNotCached(this, AdPlacement.INST_ME_PAGE_LIST)
|
||
initData()
|
||
onReceive()
|
||
}
|
||
|
||
private fun initImmersionBar() {
|
||
immersionBar {
|
||
statusBarDarkFont(false)
|
||
statusBarView(binding.view)
|
||
}
|
||
}
|
||
|
||
@SuppressLint("NotifyDataSetChanged")
|
||
private suspend fun onReceive() {
|
||
while (isActive) {
|
||
select<Unit> {
|
||
requests.onReceive {
|
||
when (it) {
|
||
Request.TryAgain -> {
|
||
initData()
|
||
}
|
||
|
||
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 {
|
||
|
||
insertFavoriteData(OfflineBean(
|
||
videoId = it.bean.videoId,
|
||
title = it.bean.title,
|
||
name = it.bean.name,
|
||
thumbnail = it.bean.thumbnail,
|
||
bytesDownloaded = it.bean.bytesDownloaded,
|
||
size = it.bean.size,
|
||
isOffline = it.bean.isOffline,
|
||
isFavorite = it.bean.isFavorite
|
||
))
|
||
AnalysisUtil.logEvent(AnalysisUtil.PLAYER_B_LOVE_CLICK, songMap)
|
||
}
|
||
requests.trySend(Request.UpdateFavorite(it.bean))
|
||
}
|
||
|
||
is Request.UpdateFavorite -> {
|
||
val currentFavoriteBean = App.appFavoriteDBManager.getFavoriteBeanByID(it.bean.videoId)
|
||
if (currentFavoriteBean != null) {
|
||
updateFavoriteUi(currentFavoriteBean.isFavorite)
|
||
} else {
|
||
updateFavoriteUi(false)
|
||
}
|
||
|
||
requests.trySend(Request.OnUpdateCurrentListItem(it.bean))
|
||
}
|
||
|
||
is Request.OnDownloadRemove -> {
|
||
val currentOfflineBean =
|
||
App.appOfflineDBManager.getOfflineBeanByID(it.bean.videoId)
|
||
if (currentOfflineBean != null) {
|
||
App.appOfflineDBManager.deleteOfflineBean(currentOfflineBean)
|
||
}
|
||
|
||
if (currentPosition >= 0) {
|
||
myList.remove(myList[currentPosition])
|
||
}
|
||
adapter?.notifyDataSetChanged()
|
||
moreDialog?.dismiss()
|
||
|
||
requests.trySend(Request.OnUpdateCurrentListItem(it.bean))
|
||
}
|
||
|
||
is Request.OnAddPlaylist -> {
|
||
showAddPlaylistBottomDialog(
|
||
FavoriteBean(
|
||
videoId = it.bean.videoId,
|
||
title = it.bean.title,
|
||
name = it.bean.name,
|
||
thumbnail = it.bean.thumbnail,
|
||
isFavorite = it.bean.isFavorite
|
||
)
|
||
)
|
||
}
|
||
|
||
is Request.OnUpdateCurrentListItem -> {
|
||
updateCurrentItem(it.bean.videoId)
|
||
}
|
||
}
|
||
}
|
||
events.onReceive {
|
||
when (it) {
|
||
Event.ActivityOnResume -> {
|
||
activityOnResume()
|
||
}
|
||
|
||
Event.AutomaticallySwitchSongs -> {
|
||
if (adapter != null) {
|
||
adapter?.notifyDataSetChanged()
|
||
}
|
||
}
|
||
|
||
else -> {}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
@SuppressLint("NotifyDataSetChanged")
|
||
private fun activityOnResume() {
|
||
addMusicPlayerViewToLayout(binding.playMusicLayout)
|
||
|
||
if (adapter != null) {
|
||
adapter?.notifyDataSetChanged()
|
||
}
|
||
|
||
LolAdWrapper.shared.loadAdShowNativeAd(
|
||
this,
|
||
AdPlacement.NATIVE_ME_PAGE_LIST,
|
||
binding.frameAd,
|
||
R.layout.ad_layout_admob_banner,
|
||
R.layout.ad_layout_max_banner
|
||
)
|
||
}
|
||
|
||
private fun initView() {
|
||
binding.backBtn.setOnClickListener {
|
||
finish()
|
||
}
|
||
binding.tryAgainBtn.setOnClickListener {
|
||
requests.trySend(Request.TryAgain)
|
||
}
|
||
}
|
||
|
||
private fun initAdapter() {
|
||
adapter = OfflineSongsAdapter(this, myList)
|
||
adapter?.setOnMoreClickListener(object : OfflineSongsAdapter.OnMoreClickListener {
|
||
override fun onMoreClick(position: Int) {
|
||
currentPosition = position
|
||
moreDialog = ListMoreBottomSheetDialog(
|
||
this@MoOfflineSongsActivity,
|
||
myList[position],
|
||
this@MoOfflineSongsActivity,
|
||
this@MoOfflineSongsActivity
|
||
)
|
||
moreDialog?.setListMoreViewListener(this@MoOfflineSongsActivity)
|
||
moreDialog?.show()
|
||
}
|
||
})
|
||
binding.rv.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
|
||
binding.rv.adapter = adapter
|
||
}
|
||
|
||
@SuppressLint("NotifyDataSetChanged")
|
||
private suspend fun initData() {
|
||
showLoadingUi()
|
||
val offlineBeans = App.appOfflineDBManager.getAllOfflineBeans()
|
||
if (offlineBeans.isNotEmpty()) {
|
||
myList.clear()
|
||
offlineBeans.forEach { offlineBean ->
|
||
val favoriteItem = App.appFavoriteDBManager.getFavoriteBeanByID(offlineBean.videoId)
|
||
if (offlineBean.bytesDownloaded?.let { bytes -> bytes > 0 } == true) {
|
||
myList.add(
|
||
PlaylistItem(
|
||
videoId = offlineBean.videoId,
|
||
title = offlineBean.title,
|
||
name = offlineBean.name,
|
||
thumbnail = offlineBean.thumbnail,
|
||
isOffline = offlineBean.isOffline,
|
||
isFavorite = favoriteItem?.isFavorite ?: false,
|
||
bytesDownloaded = offlineBean.bytesDownloaded,
|
||
size = offlineBean.size
|
||
)
|
||
)
|
||
|
||
}
|
||
}
|
||
if (myList.size > 0) {
|
||
showDataUi()
|
||
} else {
|
||
showNoContentUi()
|
||
}
|
||
} else {
|
||
showNoContentUi()
|
||
}
|
||
|
||
if (adapter != null) {
|
||
adapter?.notifyDataSetChanged()
|
||
}
|
||
}
|
||
|
||
private fun updateFavoriteUi(b: Boolean) {
|
||
if (moreDialog != null) {
|
||
moreDialog?.updateFavoriteUi(b)
|
||
}
|
||
}
|
||
|
||
private suspend fun updateCurrentItem(id: String) {
|
||
//更新当前界面的数据集合
|
||
myList.forEach { item ->
|
||
if (item.videoId == id) {
|
||
val favoriteBean = App.appFavoriteDBManager.getFavoriteBeanByID(item.videoId)
|
||
val offlineBean = App.appOfflineDBManager.getOfflineBeanByID(item.videoId)
|
||
item.isFavorite = favoriteBean?.isFavorite ?: false
|
||
item.isOffline = offlineBean?.isOffline ?: false
|
||
item.bytesDownloaded = offlineBean?.bytesDownloaded
|
||
item.size = offlineBean?.size
|
||
}
|
||
}
|
||
myList.forEach { item ->
|
||
if (item.videoId == id) {
|
||
LogTag.LogD(TAG, "updateCurrentItem -> $item")
|
||
}
|
||
}
|
||
}
|
||
|
||
override fun onFavoritesClicked(playlistItem: PlaylistItem) {
|
||
requests.trySend(Request.OnFavorites(playlistItem))
|
||
}
|
||
|
||
override fun onDownloadClicked(playlistItem: PlaylistItem) {
|
||
//下载列表只有删除,删除后更新adapter
|
||
showRemoveDownloadDialogHint(playlistItem)
|
||
}
|
||
|
||
override fun onAddToPlaylistClicked(playlistItem: PlaylistItem) {
|
||
requests.trySend(Request.OnAddPlaylist(playlistItem))
|
||
}
|
||
|
||
override fun onUpdateAdapterListener(download: Download, playlistItem: PlaylistItem) {
|
||
|
||
}
|
||
|
||
private fun showRemoveDownloadDialogHint(bean: PlaylistItem) {
|
||
val inflater = LayoutInflater.from(this)
|
||
val dialogView = inflater.inflate(R.layout.dialog_hint, null)
|
||
val okBtn = dialogView.findViewById<TextView>(R.id.dialog_ok_btn)
|
||
val cancelBtn = dialogView.findViewById<TextView>(R.id.dialog_cancel_btn)
|
||
val dialogBuilder = AlertDialog.Builder(this).setView(dialogView)
|
||
val dialog = dialogBuilder.create()
|
||
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||
dialog.show()
|
||
okBtn.setOnClickListener {
|
||
dialog.dismiss()
|
||
requests.trySend(Request.OnDownloadRemove(bean))
|
||
}
|
||
cancelBtn.setOnClickListener {
|
||
dialog.dismiss()
|
||
}
|
||
}
|
||
|
||
private fun showDataUi() {
|
||
binding.loadingLayout.visibility = View.GONE
|
||
binding.noContentLayout.visibility = View.GONE
|
||
}
|
||
|
||
private fun showLoadingUi() {
|
||
binding.loadingLayout.visibility = View.VISIBLE
|
||
binding.noContentLayout.visibility = View.GONE
|
||
}
|
||
|
||
private fun showNoContentUi() {
|
||
binding.loadingLayout.visibility = View.GONE
|
||
binding.noContentLayout.visibility = View.VISIBLE
|
||
}
|
||
} |