diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f04ecef..08cf6d3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -69,6 +69,9 @@
+
${bean}")
- relax.offline.music.App.appOfflineDBManager.insertOfflineBean(bean)
- }
+ suspend fun insertOfflineData(mediaItem: MediaItem) {
+ val bean = OfflineBean(
+ videoId = mediaItem.mediaId,
+ title = mediaItem.mediaMetadata.title.toString(),
+ name = mediaItem.mediaMetadata.artist.toString(),
+ thumbnail = mediaItem.mediaMetadata.artworkUri.toString(),
+ isOffline = true
+ )
+ LogTag.LogD(Innertube.TAG, "insertOfflineBean bean->${bean}")
+ relax.offline.music.App.appOfflineDBManager.insertOfflineBean(bean)
+ }
+
+ suspend fun insertFavoriteData(mediaItem: MediaItem) {
+ val bean = FavoriteBean(
+ videoId = mediaItem.mediaId,
+ title = mediaItem.mediaMetadata.title.toString(),
+ name = mediaItem.mediaMetadata.artist.toString(),
+ thumbnail = mediaItem.mediaMetadata.artworkUri.toString(),
+ isFavorite = true
+ )
+ LogTag.LogD(Innertube.TAG, "insertFavoriteBean bean->${bean}")
+ App.appFavoriteDBManager.insertFavoriteBean(bean)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/relax/offline/music/activity/MoLikedSongsActivity.kt b/app/src/main/java/relax/offline/music/activity/MoLikedSongsActivity.kt
new file mode 100644
index 0000000..1b58f2b
--- /dev/null
+++ b/app/src/main/java/relax/offline/music/activity/MoLikedSongsActivity.kt
@@ -0,0 +1,148 @@
+package relax.offline.music.activity
+
+import android.annotation.SuppressLint
+import android.view.View
+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 relax.offline.music.App
+import relax.offline.music.adapter.LikedSongsAdapter
+import relax.offline.music.bean.FavoriteBean
+import relax.offline.music.databinding.ActivityLikedSongsBinding
+
+class MoLikedSongsActivity : MoBaseActivity(), LikedSongsAdapter.OnItemFavoritesClickListener {
+
+ private val requests: Channel = Channel(Channel.UNLIMITED)
+
+ sealed class Request {
+ data object TryAgain : Request()
+ data class UpdateFavorite(val bean: FavoriteBean) : Request()
+ }
+
+ private lateinit var binding: ActivityLikedSongsBinding
+ private var adapter: LikedSongsAdapter? = null
+ private var favoriteBeans: MutableList = mutableListOf()
+
+ override suspend fun main() {
+ binding = ActivityLikedSongsBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ initImmersionBar()
+ initView()
+ initAdapter()
+ initData()
+ onReceive()
+ }
+
+ private fun initImmersionBar() {
+ immersionBar {
+ statusBarDarkFont(false)
+ statusBarView(binding.view)
+ }
+ }
+
+ @SuppressLint("NotifyDataSetChanged")
+ private suspend fun onReceive() {
+ while (isActive) {
+ select {
+ requests.onReceive {
+ when (it) {
+ is Request.TryAgain -> {
+ initData()
+ }
+
+ is Request.UpdateFavorite -> {
+ it.bean.isFavorite = !it.bean.isFavorite
+ adapter?.notifyDataSetChanged()
+
+ val currentFavoriteBean =
+ App.appFavoriteDBManager.getFavoriteBeanByID(it.bean.videoId)
+ if (currentFavoriteBean != null) {
+ App.appFavoriteDBManager.updateFavoriteBean(it.bean)
+ }
+ }
+ }
+ }
+ 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()
+ }
+ }
+
+ private fun initView() {
+ binding.backBtn.setOnClickListener {
+ finish()
+ }
+ binding.tryAgainBtn.setOnClickListener {
+ requests.trySend(Request.TryAgain)
+ }
+ }
+
+ private fun initAdapter() {
+ adapter = LikedSongsAdapter(this, favoriteBeans)
+ adapter?.setOnFavoritesItemClickListener(this)
+ binding.rv.layoutManager =
+ LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
+ binding.rv.adapter = adapter
+ }
+
+ override fun onFavoritesItemClick(position: Int) {
+ requests.trySend(Request.UpdateFavorite(favoriteBeans[position]))
+ }
+
+ @SuppressLint("NotifyDataSetChanged")
+ private suspend fun initData() {
+ showLoadingUi()
+ favoriteBeans.clear()
+ val beans = App.appFavoriteDBManager.getAllFavoriteBeans()
+ val filteredBeans = beans.filter { it.isFavorite }
+ favoriteBeans.addAll(filteredBeans)
+ if (favoriteBeans.size > 0) {
+ showDataUi()
+ } else {
+ showNoContentUi()
+ }
+ if (adapter != null) {
+ adapter?.notifyDataSetChanged()
+ }
+ }
+
+ 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
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/relax/offline/music/activity/MoPlayDetailsActivity.kt b/app/src/main/java/relax/offline/music/activity/MoPlayDetailsActivity.kt
index a47518c..5ce97b5 100644
--- a/app/src/main/java/relax/offline/music/activity/MoPlayDetailsActivity.kt
+++ b/app/src/main/java/relax/offline/music/activity/MoPlayDetailsActivity.kt
@@ -38,14 +38,25 @@ import relax.offline.music.util.PlayMode
import relax.offline.music.util.asMediaItem
import relax.offline.music.util.convertMillisToMinutesAndSecondsString
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.selects.select
import relax.offline.music.App
+import relax.offline.music.bean.FavoriteBean
@OptIn(UnstableApi::class)
class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
+ private val requests: Channel = Channel(Channel.UNLIMITED)
+
+ sealed class Request {
+ data object OnFavorites : Request()
+ data class OnDownload(val mediaItem: MediaItem) : Request()
+ data class UpdateFavorite(val id: String) : Request()
+ }
+
+
companion object {
const val PLAY_DETAILS_VIDEO_ID = "play_details_videoId"
const val PLAY_DETAILS_PLAY_LIST_ID = "play_details_playlistId"
@@ -120,6 +131,32 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
} else {
binding.playbackErrorLayout.visibility = View.VISIBLE
}
+ } else if (comeFrom != null && comeFrom == MoLikedSongsActivity::class.java) {
+ LogD(TAG, "从liked songs 进入")
+ binding.nameTv.text = intent.getStringExtra(PLAY_DETAILS_NAME)
+ binding.descTv.text = intent.getStringExtra(PLAY_DETAILS_DESC)
+ val favoriteBeans = App.appFavoriteDBManager.getAllFavoriteBeans()
+ val allFilteredBeans = favoriteBeans.filter { it.isFavorite}//过滤只有为true的值
+ //找到当前点击进来的歌曲media
+ val findCurrentMedia = allFilteredBeans.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 = allFilteredBeans
+ .map { mapAll -> mapAll.asMediaItem }//转换成MediaItem
+ .filter { filter -> filter.mediaId != videoId }//过滤掉id相等的。
+ it.addMediaItems(mediaItems)
+ }
+ updatePlayListDataAndAdapter()
+ } else {
+ binding.playbackErrorLayout.visibility = View.VISIBLE
+ }
} else {
LogD(TAG, "从点击任意歌曲进入")
binding.nameTv.text = intent.getStringExtra(PLAY_DETAILS_NAME)
@@ -157,13 +194,52 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
else -> {}
}
}
+ requests.onReceive {
+ when (it) {
+ is Request.OnFavorites -> {
+ if (meController != null && meController.currentMediaItem != null) {
+ val currentMediaItem = meController.currentMediaItem
+ val currentFavoriteBean =
+ App.appFavoriteDBManager.getFavoriteBeanByID(currentMediaItem?.mediaId!!)
+ if (currentFavoriteBean != null) {
+ currentFavoriteBean.isFavorite = !currentFavoriteBean.isFavorite
+ App.appFavoriteDBManager.updateFavoriteBean(currentFavoriteBean)
+ } else {
+ insertFavoriteData(currentMediaItem)
+ }
+ requests.trySend(Request.UpdateFavorite(currentMediaItem.mediaId))
+ }
+ }
+
+ is Request.OnDownload -> {
+ insertOfflineData(it.mediaItem)
+ }
+
+ is Request.UpdateFavorite -> {
+ val currentFavoriteBean =
+ App.appFavoriteDBManager.getFavoriteBeanByID(it.id)
+ LogD(TAG, "UpdateFavorite->${currentFavoriteBean}")
+ if (currentFavoriteBean != null) {
+ updateFavoriteUi(currentFavoriteBean.isFavorite)
+ } else {
+ updateFavoriteUi(false)
+ }
+ }
+ }
+ }
}
}
}
- private fun activityOnResume() {
+ private suspend fun activityOnResume() {
+ //更新收藏按钮状态
// if (meController != null && meController.currentMediaItem != null) {
-// updateInfoUi(meController.currentMediaItem)
+// val currentMediaItem = meController.currentMediaItem
+// val currentFavoriteBean =
+// App.appFavoriteDBManager.getFavoriteBeanByID(currentMediaItem?.mediaId!!)
+// if (currentFavoriteBean != null) {
+// updateFavoriteUi(currentFavoriteBean.isFavorite)
+// }
// }
}
@@ -236,6 +312,13 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
}
}
+ private fun updateFavoriteUi(b: Boolean) {
+ if (b) {
+ binding.favoritesImg.setImageResource(R.drawable.favorited_icon)
+ } else {
+ binding.favoritesImg.setImageResource(R.drawable.not_favorited_icon)
+ }
+ }
private fun initPlayerListener() {
meController?.addListener(playerListener)
@@ -401,7 +484,9 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
}
}
}
-
+ binding.favoritesBtn.setOnClickListener {
+ requests.trySend(Request.OnFavorites)
+ }
binding.downloadBtn.setOnClickListener {
if (meController != null && meController.currentMediaItem != null) {
val currentMediaItem = meController.currentMediaItem
@@ -411,8 +496,6 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
return@setOnClickListener
}
- insertOfflineData(currentMediaItem!!)
-
val downloadRequest = DownloadRequest
.Builder(contentId, contentId.toUri())
.setCustomCacheKey(contentId)
@@ -423,8 +506,9 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
downloadRequest,
false
)
- }
+ requests.trySend(Request.OnDownload(currentMediaItem!!))
+ }
}
}
@@ -610,6 +694,7 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
}
// currentVideoID = mediaItem.mediaId
updateDownloadUi(mediaItem.mediaId)
+ requests.trySend(Request.UpdateFavorite(mediaItem.mediaId))//更新喜欢状态
Glide.with(this)
.asBitmap()
diff --git a/app/src/main/java/relax/offline/music/adapter/LikedSongsAdapter.kt b/app/src/main/java/relax/offline/music/adapter/LikedSongsAdapter.kt
new file mode 100644
index 0000000..419fcb5
--- /dev/null
+++ b/app/src/main/java/relax/offline/music/adapter/LikedSongsAdapter.kt
@@ -0,0 +1,110 @@
+package relax.offline.music.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.content.Intent
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import relax.offline.music.R
+import relax.offline.music.activity.MoLikedSongsActivity
+import relax.offline.music.activity.MoPlayDetailsActivity
+import relax.offline.music.bean.FavoriteBean
+import relax.offline.music.databinding.LikedListItemBinding
+import relax.offline.music.media.MediaControllerManager
+
+class LikedSongsAdapter(
+ private val context: Context,
+ private val list: List,
+) :
+ RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = LikedListItemBinding.inflate(LayoutInflater.from(context), parent, false)
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val bean = list[position]
+ holder.bind(bean)
+
+ holder.itemView.setOnClickListener {
+ val intent = Intent(context, MoPlayDetailsActivity::class.java)
+ intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_VIDEO_ID, bean.videoId)
+ intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_NAME, bean.title)
+ intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_DESC, bean.name)
+ intent.putExtra(
+ MoPlayDetailsActivity.PLAY_DETAILS_COME_FROM,
+ MoLikedSongsActivity::class.java
+ )
+ context.startActivity(intent)
+ }
+ holder.binding.favoritesBtn.setOnClickListener {
+ if (itemFavoritesClickListener != null) {
+ itemFavoritesClickListener?.onFavoritesItemClick(position)
+ }
+ }
+ }
+
+ override fun getItemCount(): Int = list.size
+
+ inner class ViewHolder(val binding: LikedListItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ @SuppressLint("SetTextI18n")
+ fun bind(bean: FavoriteBean) {
+
+ binding.apply {
+ Glide.with(context)
+ .load(bean.thumbnail)
+ .into(image)
+ title.text = bean.title
+ if (bean.name.isEmpty()) {
+ name.visibility = View.GONE
+ } else {
+ name.visibility = View.VISIBLE
+ name.text = bean.name
+ }
+ if (bean.isFavorite) {
+ binding.favoritesImg.setImageResource(R.drawable.favorited_icon)
+ } else {
+ binding.favoritesImg.setImageResource(R.drawable.not_favorited_icon)
+ }
+ val meController = MediaControllerManager.getController()
+ if (meController != null && meController.currentMediaItem != null) {
+ if (meController.currentMediaItem?.mediaId == bean.videoId) {
+ binding.listPlayView.visibility = View.VISIBLE
+ binding.title.setTextColor(context.getColor(R.color.green))
+ binding.name.setTextColor(context.getColor(R.color.green_60))
+ } else {
+ binding.title.setTextColor(context.getColor(R.color.white))
+ binding.name.setTextColor(context.getColor(R.color.white_60))
+ binding.listPlayView.visibility = View.GONE
+ }
+ }
+ }
+ }
+ }
+
+ private var itemClickListener: OnItemClickListener? = null
+
+ fun setOnItemClickListener(listener: OnItemClickListener) {
+ itemClickListener = listener
+ }
+
+ interface OnItemClickListener {
+ fun onItemClick(position: Int)
+ }
+
+ private var itemFavoritesClickListener: OnItemFavoritesClickListener? = null
+
+ fun setOnFavoritesItemClickListener(listener: OnItemFavoritesClickListener) {
+ itemFavoritesClickListener = listener
+ }
+
+ interface OnItemFavoritesClickListener {
+ fun onFavoritesItemClick(position: Int)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/relax/offline/music/bean/FavoriteBean.kt b/app/src/main/java/relax/offline/music/bean/FavoriteBean.kt
new file mode 100644
index 0000000..d0b5e1a
--- /dev/null
+++ b/app/src/main/java/relax/offline/music/bean/FavoriteBean.kt
@@ -0,0 +1,20 @@
+package relax.offline.music.bean
+
+import androidx.annotation.Keep
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+import java.io.Serializable
+
+@Keep
+@Entity
+data class FavoriteBean(
+ @ColumnInfo(name = "videoId") var videoId: String,
+ @ColumnInfo(name = "title") var title: String,
+ @ColumnInfo(name = "name") var name: String,
+ @ColumnInfo(name = "thumbnail") var thumbnail: String? = null,
+ @ColumnInfo(name = "isFavorite") var isFavorite: Boolean
+) : Serializable {
+ @PrimaryKey(autoGenerate = true)
+ var id: Long = 0
+}
\ No newline at end of file
diff --git a/app/src/main/java/relax/offline/music/database/AppFavoriteDBManager.kt b/app/src/main/java/relax/offline/music/database/AppFavoriteDBManager.kt
new file mode 100644
index 0000000..83985f9
--- /dev/null
+++ b/app/src/main/java/relax/offline/music/database/AppFavoriteDBManager.kt
@@ -0,0 +1,81 @@
+package relax.offline.music.database
+
+import android.content.Context
+import androidx.room.Room
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import relax.offline.music.bean.FavoriteBean
+import relax.offline.music.util.LogTag
+
+class AppFavoriteDBManager private constructor(context: Context) {
+
+ companion object {
+ @Volatile
+ private var instance: AppFavoriteDBManager? = null
+
+ fun getInstance(context: Context): AppFavoriteDBManager {
+ return instance ?: synchronized(this) {
+ instance ?: AppFavoriteDBManager(context).also { instance = it }
+ }
+ }
+ }
+
+ private val database = Room.databaseBuilder(
+ context.applicationContext,
+ AppFavoriteDatabase::class.java, "favorite_data_base"
+ ).build()
+
+ private val dao = database.localFavoriteDao()
+
+ suspend fun insertFavoriteBean(bean: FavoriteBean) {
+ withContext(Dispatchers.IO) {
+ val offlineBean = getFavoriteBeanByID(bean.videoId)
+ if (offlineBean == null) {
+ dao.insertFavoriteBean(bean)
+ } else {
+ dao.updateFavoriteBean(bean)
+ }
+ }
+ }
+
+ suspend fun insertOfflineListBean(list: List) {
+ withContext(Dispatchers.IO) {
+ for (bean in list) {
+ val offlineBean = getFavoriteBeanByID(bean.videoId)
+ if (offlineBean == null) {
+ dao.insertFavoriteBean(bean)
+ } else {
+ dao.updateFavoriteBean(bean)
+ }
+ }
+ }
+ }
+
+ suspend fun getAllFavoriteBeans(): List {
+ return withContext(Dispatchers.IO) {
+ dao.getAllFavoriteBeans()
+ }
+ }
+
+ suspend fun deleteFavoriteBean(bean: FavoriteBean) {
+ withContext(Dispatchers.IO) {
+ dao.deleteFavoriteBean(bean)
+ }
+ }
+
+ suspend fun deleteAllFavoriteBean() {
+ withContext(Dispatchers.IO) {
+ dao.deleteAllFavoriteBean()
+ }
+ }
+
+ suspend fun updateFavoriteBean(bean: FavoriteBean) {
+ withContext(Dispatchers.IO) {
+ dao.updateFavoriteBean(bean)
+ }
+ }
+
+ suspend fun getFavoriteBeanByID(id: String): FavoriteBean? {
+ return dao.getFavoriteBeanByID(id)
+ }
+}
diff --git a/app/src/main/java/relax/offline/music/database/AppFavoriteDatabase.kt b/app/src/main/java/relax/offline/music/database/AppFavoriteDatabase.kt
new file mode 100644
index 0000000..7627fe4
--- /dev/null
+++ b/app/src/main/java/relax/offline/music/database/AppFavoriteDatabase.kt
@@ -0,0 +1,10 @@
+package relax.offline.music.database
+
+import androidx.room.Database
+import androidx.room.RoomDatabase
+import relax.offline.music.bean.FavoriteBean
+
+@Database(entities = [FavoriteBean::class], version = 1, exportSchema = false)
+abstract class AppFavoriteDatabase : RoomDatabase() {
+ abstract fun localFavoriteDao(): FavoriteDao
+}
\ No newline at end of file
diff --git a/app/src/main/java/relax/offline/music/database/FavoriteDao.kt b/app/src/main/java/relax/offline/music/database/FavoriteDao.kt
new file mode 100644
index 0000000..e6e7701
--- /dev/null
+++ b/app/src/main/java/relax/offline/music/database/FavoriteDao.kt
@@ -0,0 +1,30 @@
+package relax.offline.music.database
+
+import androidx.room.*
+import relax.offline.music.bean.FavoriteBean
+
+@Dao
+interface FavoriteDao {
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun insertFavoriteBean(bean: FavoriteBean)
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun insertFavoriteBeans(beans: List)
+
+ @Query("SELECT * FROM FavoriteBean")
+ suspend fun getAllFavoriteBeans(): List
+
+ @Delete
+ suspend fun deleteFavoriteBean(bean: FavoriteBean)
+
+ @Query("DELETE FROM FavoriteBean")
+ suspend fun deleteAllFavoriteBean()
+
+ @Update
+ suspend fun updateFavoriteBean(bean: FavoriteBean)
+
+ @Query("SELECT * FROM FavoriteBean WHERE videoId = :id LIMIT 1")
+ suspend fun getFavoriteBeanByID(id: String): FavoriteBean?
+
+}
diff --git a/app/src/main/java/relax/offline/music/fragment/MoMeFragment.kt b/app/src/main/java/relax/offline/music/fragment/MoMeFragment.kt
index fea66fc..5b38f73 100644
--- a/app/src/main/java/relax/offline/music/fragment/MoMeFragment.kt
+++ b/app/src/main/java/relax/offline/music/fragment/MoMeFragment.kt
@@ -5,14 +5,14 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Toast
import com.gyf.immersionbar.ktx.immersionBar
-import relax.offline.music.R
-import relax.offline.music.activity.MoOfflineSongsActivity
-import relax.offline.music.databinding.FragmentMoMeBinding
-import relax.offline.music.util.DownloadUtil
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.isActive
import kotlinx.coroutines.selects.select
import relax.offline.music.App
+import relax.offline.music.R
+import relax.offline.music.activity.MoLikedSongsActivity
+import relax.offline.music.activity.MoOfflineSongsActivity
+import relax.offline.music.databinding.FragmentMoMeBinding
class MoMeFragment : MoBaseFragment() {
@@ -57,7 +57,17 @@ class MoMeFragment : MoBaseFragment() {
private fun initView() {
binding.likedSongsBtn.setOnClickListener {
-
+ val count = binding.likedSongsTv.text.toString().trim().toInt()
+ if (count > 0) {
+ val intent = Intent(context, MoLikedSongsActivity::class.java)
+ startActivity(intent)
+ } else {
+ Toast.makeText(
+ activity,
+ getString(R.string.liked_songs_no_data_prompt),
+ Toast.LENGTH_LONG
+ ).show()
+ }
}
binding.offlineSongsBtn.setOnClickListener {
val count = binding.offlineSongsTv.text.toString().trim().toInt()
@@ -79,6 +89,11 @@ class MoMeFragment : MoBaseFragment() {
val offlineBeans = App.appOfflineDBManager.getAllOfflineBeans()
val count = offlineBeans.count { it.bytesDownloaded?.let { bytes -> bytes > 0 } == true }
binding.offlineSongsTv.text = "$count"
+
+ //过滤只有为true的才计数
+ val favoriteBeans = App.appFavoriteDBManager.getAllFavoriteBeans()
+ val favorites = favoriteBeans.count { it.isFavorite }
+ binding.likedSongsTv.text = "$favorites"
}
override fun onResume() {
diff --git a/app/src/main/java/relax/offline/music/media/MediaControllerManager.kt b/app/src/main/java/relax/offline/music/media/MediaControllerManager.kt
index 3fe0c21..2976e42 100644
--- a/app/src/main/java/relax/offline/music/media/MediaControllerManager.kt
+++ b/app/src/main/java/relax/offline/music/media/MediaControllerManager.kt
@@ -9,7 +9,6 @@ import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.MoreExecutors
import relax.offline.music.service.PlaybackService
-@UnstableApi
object MediaControllerManager {
private var mediaController: MediaController? = null
private var controllerFuture: ListenableFuture? = null
diff --git a/app/src/main/java/relax/offline/music/service/PlaybackService.kt b/app/src/main/java/relax/offline/music/service/PlaybackService.kt
index 9f15552..57a67af 100644
--- a/app/src/main/java/relax/offline/music/service/PlaybackService.kt
+++ b/app/src/main/java/relax/offline/music/service/PlaybackService.kt
@@ -3,6 +3,7 @@ package relax.offline.music.service
import android.content.Intent
import android.net.Uri
import android.os.Handler
+import androidx.annotation.OptIn
import androidx.core.net.toUri
import androidx.media3.common.AudioAttributes
import androidx.media3.common.C
@@ -42,8 +43,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import relax.offline.music.util.RingBuffer
-
-@UnstableApi
+@OptIn(UnstableApi::class)
class PlaybackService : MediaSessionService(), Player.Listener {
private val TAG = LogTag.VO_SERVICE_LOG
private var mediaSession: MediaSession? = null
diff --git a/app/src/main/java/relax/offline/music/util/Utils.kt b/app/src/main/java/relax/offline/music/util/Utils.kt
index ca75cac..b853135 100644
--- a/app/src/main/java/relax/offline/music/util/Utils.kt
+++ b/app/src/main/java/relax/offline/music/util/Utils.kt
@@ -9,6 +9,7 @@ import androidx.core.os.bundleOf
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import androidx.media3.common.util.UnstableApi
+import relax.offline.music.bean.FavoriteBean
import relax.offline.music.bean.OfflineBean
import relax.offline.music.innertube.Innertube
import relax.offline.music.innertube.models.bodies.ContinuationBody
@@ -30,6 +31,21 @@ val OfflineBean.asMediaItem: MediaItem
)
.build()
+val FavoriteBean.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
@OptIn(UnstableApi::class)
get() = MediaItem.Builder()
diff --git a/app/src/main/res/layout/activity_liked_songs.xml b/app/src/main/res/layout/activity_liked_songs.xml
new file mode 100644
index 0000000..1d4a0ea
--- /dev/null
+++ b/app/src/main/res/layout/activity_liked_songs.xml
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/liked_list_item.xml b/app/src/main/res/layout/liked_list_item.xml
new file mode 100644
index 0000000..b9bd04e
--- /dev/null
+++ b/app/src/main/res/layout/liked_list_item.xml
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file