update
This commit is contained in:
parent
eb81f9bda7
commit
b49547cb9b
@ -13,6 +13,7 @@ import melody.offline.music.databinding.MusicResponsiveItemBinding
|
||||
import melody.offline.music.innertube.models.MusicCarouselShelfRenderer
|
||||
import melody.offline.music.media.MediaControllerManager
|
||||
import melody.offline.music.util.AnalysisUtil
|
||||
import melody.offline.music.util.LogTag
|
||||
|
||||
class ResponsiveListAdapter(
|
||||
private val context: Context,
|
||||
@ -83,15 +84,20 @@ class ResponsiveListAdapter(
|
||||
intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_DESC, desc)
|
||||
context.startActivity(intent)
|
||||
|
||||
if(itemClickListener!=null){
|
||||
if (itemClickListener != null) {
|
||||
itemClickListener?.onItemClick(position)
|
||||
}
|
||||
}
|
||||
holder.binding.moreBtn.setOnClickListener {
|
||||
if (itemMoreClickListener != null) {
|
||||
itemMoreClickListener?.onItemMoreClick(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = list.size
|
||||
|
||||
inner class ViewHolder(private val binding: MusicResponsiveItemBinding) :
|
||||
inner class ViewHolder(val binding: MusicResponsiveItemBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun bind(url: String?, name: String?, desc: String?, videoID: String?) {
|
||||
@ -129,4 +135,14 @@ class ResponsiveListAdapter(
|
||||
interface OnItemClickListener {
|
||||
fun onItemClick(position: Int)
|
||||
}
|
||||
|
||||
private var itemMoreClickListener: OnItemMoreClickListener? = null
|
||||
|
||||
fun setOnItemMoreClickListener(listener: OnItemMoreClickListener) {
|
||||
itemMoreClickListener = listener
|
||||
}
|
||||
|
||||
interface OnItemMoreClickListener {
|
||||
fun onItemMoreClick(position: Int)
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,27 @@
|
||||
package melody.offline.music.fragment
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.net.toUri
|
||||
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.RecyclerView
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.gyf.immersionbar.ktx.immersionBar
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import melody.offline.music.databinding.FragmentMoHomeBinding
|
||||
import melody.offline.music.innertube.Innertube
|
||||
import melody.offline.music.innertube.models.MusicCarouselShelfRenderer
|
||||
@ -14,12 +32,32 @@ import melody.offline.music.view.MusicResponsiveListView
|
||||
import melody.offline.music.view.MusicTowRowListView
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.selects.select
|
||||
import kotlinx.coroutines.withContext
|
||||
import melody.offline.music.App
|
||||
import melody.offline.music.R
|
||||
import melody.offline.music.activity.MoListDetailsActivity
|
||||
import melody.offline.music.adapter.NewPlayListAdapter
|
||||
import melody.offline.music.ads.AdPlacement
|
||||
import melody.offline.music.ads.AnalysisAdState
|
||||
import melody.offline.music.ads.LolAdWrapper
|
||||
import melody.offline.music.bean.FavoriteBean
|
||||
import melody.offline.music.bean.OfflineBean
|
||||
import melody.offline.music.bean.Playlist
|
||||
import melody.offline.music.bean.PlaylistItem
|
||||
import melody.offline.music.service.MyDownloadService
|
||||
import melody.offline.music.util.AnalysisUtil
|
||||
import melody.offline.music.util.DownloadUtil
|
||||
import melody.offline.music.util.FileSizeConverter
|
||||
import melody.offline.music.util.asPlaylistItem
|
||||
import melody.offline.music.view.ListMoreBottomSheetDialog
|
||||
import org.json.JSONObject
|
||||
|
||||
class MoHomeFragment : MoBaseFragment<FragmentMoHomeBinding>() {
|
||||
@OptIn(UnstableApi::class)
|
||||
class MoHomeFragment : MoBaseFragment<FragmentMoHomeBinding>(),
|
||||
MusicResponsiveListView.OnMoreClickListener, ListMoreBottomSheetDialog.ListMoreViewListener,
|
||||
ListMoreBottomSheetDialog.UpdateAdapterListener {
|
||||
|
||||
|
||||
interface MoHomeFragmentToSearchClickListener {
|
||||
@ -31,12 +69,18 @@ class MoHomeFragment : MoBaseFragment<FragmentMoHomeBinding>() {
|
||||
}
|
||||
|
||||
private var toSearchClickListener: MoHomeFragmentToSearchClickListener? = null
|
||||
|
||||
|
||||
private var moreDialog: ListMoreBottomSheetDialog? = null
|
||||
private val requests: Channel<Request> = Channel(Channel.UNLIMITED)
|
||||
|
||||
enum class Request {
|
||||
TryAgain,
|
||||
sealed class Request {
|
||||
data object TryAgain : Request()
|
||||
data class ShowDialog(val bean: MusicCarouselShelfRenderer.Content) : 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 bean: PlaylistItem) : Request()
|
||||
data class OnUpdateDownloadUi(val bean: PlaylistItem) : Request()
|
||||
data class OnAddPlaylist(val bean: PlaylistItem) : Request()
|
||||
}
|
||||
|
||||
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentMoHomeBinding
|
||||
@ -63,6 +107,166 @@ class MoHomeFragment : MoBaseFragment<FragmentMoHomeBinding>() {
|
||||
Request.TryAgain -> {
|
||||
initData()
|
||||
}
|
||||
|
||||
is Request.ShowDialog -> {
|
||||
moreDialog = ListMoreBottomSheetDialog(
|
||||
requireActivity(),
|
||||
initMoreDialogData(it.bean),
|
||||
requireActivity(),
|
||||
this@MoHomeFragment
|
||||
)
|
||||
moreDialog?.setListMoreViewListener(this@MoHomeFragment)
|
||||
moreDialog?.show()
|
||||
}
|
||||
|
||||
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)//得到当前ID的本地数据
|
||||
if (offBean != null && offBean.bytesDownloaded?.let { bytes -> bytes > 0 } == true) {//判断当前数据库是否有这条数据。
|
||||
showRemoveDownloadDialogHint(it.bean)
|
||||
} else {
|
||||
val isFavorite =
|
||||
App.appFavoriteDBManager.getFavoriteBeanByID(it.bean.videoId)
|
||||
//判断是否已经下载了这条数据,已经下载,就直接进行数据库数据存储,反之走下载流程。
|
||||
if (DownloadUtil.downloadResourceExist(id)) {
|
||||
val favoriteBean = FavoriteBean(
|
||||
id,
|
||||
it.bean.title,
|
||||
it.bean.name,
|
||||
it.bean.thumbnail,
|
||||
isFavorite?.isFavorite ?: false
|
||||
)
|
||||
insertOfflineData(favoriteBean)
|
||||
it.bean.isOffline = true//更改状态
|
||||
requests.trySend(Request.OnUpdateDownloadUi(it.bean))
|
||||
} else {
|
||||
val downloadRequest = DownloadRequest.Builder(id, id.toUri())
|
||||
.setCustomCacheKey(id).build()
|
||||
|
||||
val downloadCount = DownloadUtil.getCurrentDownloads()
|
||||
if (downloadCount >= 3) {
|
||||
Toast.makeText(
|
||||
requireActivity(),
|
||||
getString(R.string.download_tips),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
} else {
|
||||
DownloadService.sendAddDownload(
|
||||
requireActivity(),
|
||||
MyDownloadService::class.java,
|
||||
downloadRequest,
|
||||
false
|
||||
)
|
||||
|
||||
LolAdWrapper.shared.showAdTiming(
|
||||
requireActivity(), AdPlacement.INST_DOWNLOAD
|
||||
)
|
||||
val favoriteBean = FavoriteBean(
|
||||
id,
|
||||
it.bean.title,
|
||||
it.bean.name,
|
||||
it.bean.thumbnail,
|
||||
isFavorite?.isFavorite ?: false
|
||||
)
|
||||
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(
|
||||
requireActivity(), AdPlacement.INST_DOWNLOAD
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is Request.OnDownloadRemove -> {
|
||||
val currentOfflineBean =
|
||||
App.appOfflineDBManager.getOfflineBeanByID(it.bean.videoId)
|
||||
if (currentOfflineBean != null) {
|
||||
App.appOfflineDBManager.deleteOfflineBean(currentOfflineBean)
|
||||
|
||||
it.bean.isOffline = false
|
||||
}
|
||||
requests.trySend(Request.OnUpdateDownloadUi(it.bean))
|
||||
}
|
||||
|
||||
is Request.OnUpdateDownloadUi -> {
|
||||
moreDialog?.updateDownloadBtnUi(it.bean.isOffline)//更新对话框的ui
|
||||
}
|
||||
|
||||
is Request.OnAddPlaylist -> {
|
||||
val isFavorite =
|
||||
App.appFavoriteDBManager.getFavoriteBeanByID(it.bean.videoId) != null
|
||||
|
||||
showAddPlaylistBottomDialog(
|
||||
FavoriteBean(
|
||||
videoId = it.bean.videoId,
|
||||
title = it.bean.title,
|
||||
name = it.bean.name,
|
||||
thumbnail = it.bean.thumbnail,
|
||||
isFavorite
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
events.onReceive {
|
||||
@ -97,19 +301,16 @@ class MoHomeFragment : MoBaseFragment<FragmentMoHomeBinding>() {
|
||||
for (home: Innertube.HomePage in it.homePage) {
|
||||
for (content: MusicCarouselShelfRenderer.Content in home.contents) {
|
||||
if (content.musicResponsiveListItemRenderer != null) {
|
||||
binding.contentLayout.addView(
|
||||
MusicResponsiveListView(
|
||||
requireActivity(),
|
||||
home
|
||||
)
|
||||
)
|
||||
val musicResponsiveListView =
|
||||
MusicResponsiveListView(requireActivity(), home)
|
||||
musicResponsiveListView.setOnItemMoreClickListener(this)
|
||||
binding.contentLayout.addView(musicResponsiveListView)
|
||||
break
|
||||
}
|
||||
if (content.musicTwoRowItemRenderer != null) {
|
||||
binding.contentLayout.addView(
|
||||
MusicTowRowListView(
|
||||
requireActivity(),
|
||||
home
|
||||
requireActivity(), home
|
||||
)
|
||||
)
|
||||
break
|
||||
@ -135,14 +336,14 @@ class MoHomeFragment : MoBaseFragment<FragmentMoHomeBinding>() {
|
||||
if (content.musicResponsiveListItemRenderer != null) {
|
||||
val musicResponsiveListView =
|
||||
MusicResponsiveListView(requireActivity(), home)
|
||||
musicResponsiveListView.setOnItemMoreClickListener(this)
|
||||
binding.contentLayout.addView(musicResponsiveListView)
|
||||
break
|
||||
}
|
||||
if (content.musicTwoRowItemRenderer != null) {
|
||||
binding.contentLayout.addView(
|
||||
MusicTowRowListView(
|
||||
requireActivity(),
|
||||
home
|
||||
requireActivity(), home
|
||||
)
|
||||
)
|
||||
break
|
||||
@ -206,4 +407,233 @@ class MoHomeFragment : MoBaseFragment<FragmentMoHomeBinding>() {
|
||||
binding.noContentLayout.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
override fun onMoreClick(bean: MusicCarouselShelfRenderer.Content) {
|
||||
requests.trySend(Request.ShowDialog(bean))
|
||||
}
|
||||
|
||||
private suspend fun initMoreDialogData(bean: MusicCarouselShelfRenderer.Content): PlaylistItem {
|
||||
val watchEndpoint =
|
||||
bean.musicResponsiveListItemRenderer?.flexColumns?.firstOrNull()?.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.firstOrNull()?.navigationEndpoint?.watchEndpoint
|
||||
val thumbnailUrl =
|
||||
bean.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.let {
|
||||
it.getOrNull(1) ?: it.getOrNull(0)
|
||||
}?.url
|
||||
val title =
|
||||
bean.musicResponsiveListItemRenderer?.flexColumns?.get(0)?.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.firstOrNull()?.text
|
||||
val name =
|
||||
bean.musicResponsiveListItemRenderer?.flexColumns?.get(1)?.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.firstOrNull()?.text
|
||||
|
||||
val videoId = watchEndpoint?.videoId
|
||||
|
||||
LogD(TAG, "title->$title videoId->$videoId")
|
||||
|
||||
val offlineBean = App.appOfflineDBManager.getOfflineBeanByID(videoId ?: "")
|
||||
val favoriteBean = App.appFavoriteDBManager.getFavoriteBeanByID(videoId ?: "")
|
||||
|
||||
return PlaylistItem(
|
||||
videoId = videoId ?: "",
|
||||
title = title ?: "",
|
||||
name = name ?: "",
|
||||
thumbnail = thumbnailUrl,
|
||||
bytesDownloaded = offlineBean?.bytesDownloaded ?: 0L,
|
||||
size = offlineBean?.size,
|
||||
isOffline = offlineBean?.isOffline ?: false,
|
||||
isFavorite = favoriteBean?.isFavorite ?: false
|
||||
)
|
||||
}
|
||||
|
||||
override fun onUpdateAdapterListener(download: Download, playlistItem: PlaylistItem) {
|
||||
|
||||
}
|
||||
|
||||
override fun onFavoritesClicked(playlistItem: PlaylistItem) {
|
||||
requests.trySend(Request.OnFavorites(playlistItem))
|
||||
}
|
||||
|
||||
override fun onDownloadClicked(playlistItem: PlaylistItem) {
|
||||
requests.trySend(Request.OnDownload(playlistItem))
|
||||
}
|
||||
|
||||
override fun onAddToPlaylistClicked(playlistItem: PlaylistItem) {
|
||||
requests.trySend(Request.OnAddPlaylist(playlistItem))
|
||||
}
|
||||
|
||||
private fun updateFavoriteUi(b: Boolean) {
|
||||
if (moreDialog != null) {
|
||||
moreDialog?.updateFavoriteUi(b)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showRemoveDownloadDialogHint(playlistItem: PlaylistItem) {
|
||||
val inflater = LayoutInflater.from(requireActivity())
|
||||
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(requireActivity()).setView(dialogView)
|
||||
val dialog = dialogBuilder.create()
|
||||
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
dialog.show()
|
||||
okBtn.setOnClickListener {
|
||||
dialog.dismiss()
|
||||
requests.trySend(Request.OnDownloadRemove(playlistItem))
|
||||
}
|
||||
cancelBtn.setOnClickListener {
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun insertOfflineData(favoriteBean: FavoriteBean) {
|
||||
val currentDownload = DownloadUtil.getCurrentIdDownload(favoriteBean.videoId)
|
||||
if (currentDownload != null) {
|
||||
val bytesDownloaded = currentDownload.bytesDownloaded
|
||||
val size = FileSizeConverter(currentDownload.bytesDownloaded).formattedSize()
|
||||
val bean = OfflineBean(
|
||||
videoId = favoriteBean.videoId,
|
||||
title = favoriteBean.title,
|
||||
name = favoriteBean.name,
|
||||
thumbnail = favoriteBean.thumbnail,
|
||||
isOffline = true,
|
||||
isFavorite = favoriteBean.isFavorite,
|
||||
bytesDownloaded = bytesDownloaded,
|
||||
size = size
|
||||
)
|
||||
App.appOfflineDBManager.insertOfflineBean(bean)
|
||||
} else {
|
||||
val bean = OfflineBean(
|
||||
videoId = favoriteBean.videoId,
|
||||
title = favoriteBean.title,
|
||||
name = favoriteBean.name,
|
||||
thumbnail = favoriteBean.thumbnail,
|
||||
isOffline = true,
|
||||
isFavorite = favoriteBean.isFavorite,
|
||||
)
|
||||
App.appOfflineDBManager.insertOfflineBean(bean)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun showAddPlaylistBottomDialog(favoriteBean: FavoriteBean) {
|
||||
val bottomAddPlaylistSheetDialog = BottomSheetDialog(requireActivity())
|
||||
val view = layoutInflater.inflate(R.layout.add_playlist_layout, null)
|
||||
bottomAddPlaylistSheetDialog.setContentView(view)
|
||||
val newPlayListBtn = view.findViewById<LinearLayout>(R.id.newPlayListBtn)
|
||||
val rv = view.findViewById<RecyclerView>(R.id.newPlayListRv)
|
||||
newPlayListBtn.setOnClickListener {
|
||||
bottomAddPlaylistSheetDialog.dismiss()
|
||||
showNewPlaylistBottomDialog(favoriteBean)
|
||||
}
|
||||
// 设置对话框背景为透明以显示圆角
|
||||
bottomAddPlaylistSheetDialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
|
||||
bottomAddPlaylistSheetDialog.window?.navigationBarColor =
|
||||
ContextCompat.getColor(requireActivity(), R.color.main_bg_color)
|
||||
bottomAddPlaylistSheetDialog.show()
|
||||
|
||||
val playlist = (App.appPlaylistDBManager.getAllPlaylists())
|
||||
val adapter = NewPlayListAdapter(requireActivity(), playlist)
|
||||
adapter.setOnItemClickListener(object : NewPlayListAdapter.OnItemClickListener {
|
||||
override fun onItemClick(position: Int) {
|
||||
launch {
|
||||
val playlistItem =
|
||||
App.appPlaylistDBManager.getPlaylistItems(playlist[position].id)
|
||||
val isAny = playlistItem.any { it.title == favoriteBean.title }
|
||||
if (isAny) {//如何这首歌曲已经存在歌单则不添加
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
requireActivity(),
|
||||
getString(R.string.song_exists_playlist_hint),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
} else {
|
||||
val isOffline =
|
||||
App.appOfflineDBManager.getOfflineBeanByID(favoriteBean.videoId) != null
|
||||
val isFavorite =
|
||||
App.appFavoriteDBManager.getFavoriteBeanByID(favoriteBean.videoId) != null
|
||||
App.appPlaylistDBManager.insertOrUpdatePlaylistItem(
|
||||
PlaylistItem(
|
||||
playlistId = playlist[position].id,
|
||||
videoId = favoriteBean.videoId,
|
||||
title = favoriteBean.title,
|
||||
name = favoriteBean.name,
|
||||
thumbnail = favoriteBean.thumbnail,
|
||||
isOffline = isOffline,
|
||||
isFavorite = isFavorite
|
||||
)
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
bottomAddPlaylistSheetDialog.dismiss()
|
||||
Toast.makeText(
|
||||
requireActivity(),
|
||||
getString(R.string.added_playlist_success_Hint),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
rv.layoutManager =
|
||||
LinearLayoutManager(requireActivity(), LinearLayoutManager.VERTICAL, false)
|
||||
rv.adapter = adapter
|
||||
}
|
||||
|
||||
private var bottomSheetDialog: BottomSheetDialog? = null
|
||||
private fun showNewPlaylistBottomDialog(favoriteBean: FavoriteBean) {
|
||||
bottomSheetDialog = BottomSheetDialog(requireActivity())
|
||||
val view = layoutInflater.inflate(R.layout.new_playlist_layout, null)
|
||||
bottomSheetDialog?.setContentView(view)
|
||||
val edit = view.findViewById<EditText>(R.id.playlistEt)
|
||||
val confirmBtn = view.findViewById<TextView>(R.id.confirmBtn)
|
||||
confirmBtn.setOnClickListener {
|
||||
val text = edit.text.toString().trim()
|
||||
if (text.isNotEmpty()) {
|
||||
launch {
|
||||
val playlist = App.appPlaylistDBManager.getPlaylistByTitle(text)
|
||||
if (playlist != null) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
requireActivity(),
|
||||
getString(R.string.new_playlist_duplicate_name_hint),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
} else {
|
||||
val newPlaylist = Playlist(title = text)
|
||||
App.appPlaylistDBManager.insertOrUpdatePlaylist(newPlaylist)
|
||||
withContext(Dispatchers.Main) {
|
||||
if (bottomSheetDialog != null) {
|
||||
bottomSheetDialog?.dismiss()
|
||||
}
|
||||
Toast.makeText(
|
||||
requireActivity(),
|
||||
getString(R.string.created_successfully),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
val currentPlaylist = App.appPlaylistDBManager.getPlaylistByTitle(text)
|
||||
if (currentPlaylist != null) {
|
||||
val isOffline =
|
||||
App.appOfflineDBManager.getOfflineBeanByID(favoriteBean.videoId) != null//返回非null则为true
|
||||
val isFavorite =
|
||||
App.appFavoriteDBManager.getFavoriteBeanByID(favoriteBean.videoId) != null
|
||||
val playlistItem = PlaylistItem(
|
||||
playlistId = currentPlaylist.id,
|
||||
videoId = favoriteBean.videoId,
|
||||
title = favoriteBean.title,
|
||||
name = favoriteBean.name,
|
||||
thumbnail = favoriteBean.thumbnail,
|
||||
isOffline = isOffline,
|
||||
isFavorite = isFavorite
|
||||
)
|
||||
App.appPlaylistDBManager.insertOrUpdatePlaylistItem(playlistItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 设置对话框背景为透明以显示圆角
|
||||
bottomSheetDialog?.window?.setBackgroundDrawableResource(android.R.color.transparent)
|
||||
bottomSheetDialog?.window?.navigationBarColor =
|
||||
ContextCompat.getColor(requireActivity(), R.color.main_bg_color)
|
||||
bottomSheetDialog?.show()
|
||||
}
|
||||
}
|
||||
@ -49,6 +49,7 @@ class MoMeFragment : MoBaseFragment<FragmentMoMeBinding>(), NewPlayListAdapter.O
|
||||
|
||||
sealed class Request {
|
||||
data class AddPlaylist(val text: String) : Request()
|
||||
data object UpdateUi : Request()
|
||||
}
|
||||
|
||||
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentMoMeBinding
|
||||
@ -90,6 +91,10 @@ class MoMeFragment : MoBaseFragment<FragmentMoMeBinding>(), NewPlayListAdapter.O
|
||||
getPlaylistData()
|
||||
}
|
||||
}
|
||||
|
||||
Request.UpdateUi -> {
|
||||
fragmentOnResume()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,6 +173,8 @@ class MoMeFragment : MoBaseFragment<FragmentMoMeBinding>(), NewPlayListAdapter.O
|
||||
super.onHiddenChanged(hidden)
|
||||
if (!hidden) {
|
||||
initImmersionBar()
|
||||
|
||||
requests.trySend(Request.UpdateUi)
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,4 +220,5 @@ class MoMeFragment : MoBaseFragment<FragmentMoMeBinding>(), NewPlayListAdapter.O
|
||||
bottomSheetDialog?.show()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -9,7 +9,9 @@ import org.json.JSONObject
|
||||
import melody.offline.music.R
|
||||
import melody.offline.music.adapter.ResponsiveListAdapter
|
||||
import melody.offline.music.innertube.Innertube
|
||||
import melody.offline.music.innertube.models.MusicCarouselShelfRenderer
|
||||
import melody.offline.music.util.AnalysisUtil
|
||||
import melody.offline.music.util.LogTag
|
||||
|
||||
@SuppressLint("ViewConstructor")
|
||||
class MusicResponsiveListView(context: Context, homePage: Innertube.HomePage) :
|
||||
@ -33,6 +35,14 @@ class MusicResponsiveListView(context: Context, homePage: Innertube.HomePage) :
|
||||
AnalysisUtil.logEvent(AnalysisUtil.HOME_B_MODULE_CLICK, map)
|
||||
}
|
||||
})
|
||||
adapter?.setOnItemMoreClickListener(object : ResponsiveListAdapter.OnItemMoreClickListener {
|
||||
override fun onItemMoreClick(position: Int) {
|
||||
val bean = homePage.contents[position]
|
||||
if (moreClickListener != null) {
|
||||
moreClickListener?.onMoreClick(bean)
|
||||
}
|
||||
}
|
||||
})
|
||||
rv?.layoutManager = GridLayoutManager(context, 3, GridLayoutManager.HORIZONTAL, false)
|
||||
rv?.adapter = adapter
|
||||
}
|
||||
@ -43,4 +53,14 @@ class MusicResponsiveListView(context: Context, homePage: Innertube.HomePage) :
|
||||
adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private var moreClickListener: OnMoreClickListener? = null
|
||||
|
||||
fun setOnItemMoreClickListener(listener: OnMoreClickListener) {
|
||||
moreClickListener = listener
|
||||
}
|
||||
|
||||
interface OnMoreClickListener {
|
||||
fun onMoreClick(bean: MusicCarouselShelfRenderer.Content)
|
||||
}
|
||||
}
|
||||
@ -50,8 +50,9 @@
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
@ -79,6 +80,19 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/moreBtn"
|
||||
android:layout_width="40dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:visibility="visible"
|
||||
android:layout_height="40dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:src="@drawable/three_dots_icon" />
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
Loading…
Reference in New Issue
Block a user