From 9d76dafa47b5eb198aec402b6d8db19ade0bf146 Mon Sep 17 00:00:00 2001 From: ocean <503259349@qq.com> Date: Fri, 21 Jun 2024 11:12:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=9C=AC=E5=9C=B0=E9=9F=B3?= =?UTF-8?q?=E4=B9=90=E6=95=B0=E6=8D=AE=E5=BA=93=E5=AD=97=E6=AE=B5=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../offline/music/activity/MoBaseActivity.kt | 4 +- .../music/activity/MoListDetailsActivity.kt | 32 +++++---- .../music/activity/MoOfflineSongsActivity.kt | 72 +++++++++++++++++-- .../music/adapter/OfflineSongsAdapter.kt | 28 +++++++- .../melody/offline/music/bean/OfflineBean.kt | 3 +- .../music/database/AppOfflineDBManager.kt | 14 +++- .../music/database/AppOfflineDatabase.kt | 2 +- app/src/main/res/drawable/three_dots_icon.xml | 9 +++ app/src/main/res/layout/offline_list_item.xml | 39 +++++++++- 9 files changed, 172 insertions(+), 31 deletions(-) create mode 100644 app/src/main/res/drawable/three_dots_icon.xml diff --git a/app/src/main/java/melody/offline/music/activity/MoBaseActivity.kt b/app/src/main/java/melody/offline/music/activity/MoBaseActivity.kt index 13f0529..3a3dd67 100644 --- a/app/src/main/java/melody/offline/music/activity/MoBaseActivity.kt +++ b/app/src/main/java/melody/offline/music/activity/MoBaseActivity.kt @@ -238,12 +238,14 @@ abstract class MoBaseActivity : AppCompatActivity(), CoroutineScope by MainScope suspend fun insertOfflineData(mediaItem: MediaItem) { + val favoriteBean = App.appFavoriteDBManager.getFavoriteBeanByID(mediaItem.mediaId) val bean = OfflineBean( videoId = mediaItem.mediaId, title = mediaItem.mediaMetadata.title.toString(), name = mediaItem.mediaMetadata.artist.toString(), thumbnail = mediaItem.mediaMetadata.artworkUri.toString(), - isOffline = true + isOffline = true, + isFavorite = favoriteBean?.isFavorite ?: false ) LogTag.LogD(TAG, "insertOfflineBean bean->${bean}") App.appOfflineDBManager.insertOfflineBean(bean) diff --git a/app/src/main/java/melody/offline/music/activity/MoListDetailsActivity.kt b/app/src/main/java/melody/offline/music/activity/MoListDetailsActivity.kt index d19b994..f82f149 100644 --- a/app/src/main/java/melody/offline/music/activity/MoListDetailsActivity.kt +++ b/app/src/main/java/melody/offline/music/activity/MoListDetailsActivity.kt @@ -95,6 +95,10 @@ class MoListDetailsActivity : MoBaseActivity() { } private fun initView() { + adapter = DetailsListAdapter(this, myList) + binding.rv.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false) + binding.rv.adapter = adapter + binding.backBtn.setOnClickListener { finish() } @@ -120,28 +124,28 @@ class MoListDetailsActivity : MoBaseActivity() { } } + @SuppressLint("NotifyDataSetChanged") private suspend fun initData(browseId: String) { showLoadingUi() Innertube.moPlaylistPage(browseId)?.onSuccess { if (this.isDestroyed || this.isFinishing) { return } + LogD(TAG, "moPlaylistPage onSuccess->${it.moPlaylistOrAlbumListBean}") + if (it.moPlaylistOrAlbumListBean.isNotEmpty()) { + showDataUi() + Glide.with(this).load(it.thumbnail).into(binding.imageView) - showDataUi() - Glide.with(this).load(it.thumbnail).into(binding.imageView) + binding.title.text = it.title + binding.subtitle.text = it.subtitle + binding.secondSubtitle.text = it.secondSubtitle - binding.title.text = it.title - binding.subtitle.text = it.subtitle - binding.secondSubtitle.text = it.secondSubtitle - - adapter = DetailsListAdapter(this, it.moPlaylistOrAlbumListBean) - binding.rv.layoutManager = - LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false) - binding.rv.adapter = adapter - - - myList.clear() - myList.addAll(it.moPlaylistOrAlbumListBean) + myList.clear() + myList.addAll(it.moPlaylistOrAlbumListBean) + adapter?.notifyDataSetChanged() + } else { + showNoContentUi() + } }?.onFailure { showNoContentUi() LogD(TAG, "moPlaylistPage onFailure->${it}") diff --git a/app/src/main/java/melody/offline/music/activity/MoOfflineSongsActivity.kt b/app/src/main/java/melody/offline/music/activity/MoOfflineSongsActivity.kt index 65d1c0a..189fa96 100644 --- a/app/src/main/java/melody/offline/music/activity/MoOfflineSongsActivity.kt +++ b/app/src/main/java/melody/offline/music/activity/MoOfflineSongsActivity.kt @@ -2,6 +2,7 @@ package melody.offline.music.activity import android.annotation.SuppressLint import android.view.View +import androidx.media3.common.MediaItem import androidx.recyclerview.widget.LinearLayoutManager import com.gyf.immersionbar.ktx.immersionBar import kotlinx.coroutines.channels.Channel @@ -14,12 +15,18 @@ import melody.offline.music.ads.AdPlacement import melody.offline.music.ads.LolAdWrapper import melody.offline.music.bean.OfflineBean import melody.offline.music.databinding.ActivityOfflineSongsBinding +import melody.offline.music.util.AnalysisUtil +import melody.offline.music.util.LogTag +import org.json.JSONObject class MoOfflineSongsActivity : MoBaseActivity() { private val requests: Channel = Channel(Channel.UNLIMITED) - enum class Request { - TryAgain, + sealed class Request { + data object TryAgain : Request() + data object OnFavorites : Request() + data class OnDownload(val mediaItem: MediaItem) : Request() + data class UpdateFavorite(val id: String) : Request() } private lateinit var binding: ActivityOfflineSongsBinding @@ -54,6 +61,48 @@ class MoOfflineSongsActivity : MoBaseActivity() { Request.TryAgain -> { initData() } + + is Request.OnDownload -> { + + } + + Request.OnFavorites -> { + if (meController != null && meController.currentMediaItem != null) { + val currentMediaItem = meController.currentMediaItem + val jsonObject = JSONObject() + jsonObject.put( + "song_title", "${currentMediaItem?.mediaMetadata?.title}" + ) + val songMap = mutableMapOf( + Pair( + AnalysisUtil.PARAM_VALUE, jsonObject.toString() + ) + ) + val currentFavoriteBean = + App.appFavoriteDBManager.getFavoriteBeanByID(currentMediaItem?.mediaId!!) + 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(currentMediaItem) + AnalysisUtil.logEvent(AnalysisUtil.PLAYER_B_LOVE_CLICK, songMap) + } + requests.trySend(Request.UpdateFavorite(currentMediaItem.mediaId)) + } + } + + is Request.UpdateFavorite -> { + + } } } events.onReceive { @@ -103,8 +152,12 @@ class MoOfflineSongsActivity : MoBaseActivity() { private fun initAdapter() { adapter = OfflineSongsAdapter(this, offlineList) - binding.rv.layoutManager = - LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false) + adapter?.setOnFavoriteClickListener(object : OfflineSongsAdapter.OnFavoriteClickListener { + override fun onFavoriteClick(position: Int) { + requests.trySend(Request.OnFavorites) + } + }) + binding.rv.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false) binding.rv.adapter = adapter } @@ -114,8 +167,15 @@ class MoOfflineSongsActivity : MoBaseActivity() { offlineList.clear() val offlineBeans = App.appOfflineDBManager.getAllOfflineBeans() - val filteredBeans = - offlineBeans.filter { it.bytesDownloaded?.let { bytes -> bytes > 0 } == true } + // 更新 + offlineBeans.forEach { offlineBean -> + val favoriteBean = App.appFavoriteDBManager.getFavoriteBeanByID(offlineBean.videoId) + if (offlineBean.id == favoriteBean?.id) { + offlineBean.isFavorite = favoriteBean.isFavorite + App.appOfflineDBManager.updateOfflineBean(offlineBean) + } + } + val filteredBeans = offlineBeans.filter { it.bytesDownloaded?.let { bytes -> bytes > 0 } == true } offlineList.addAll(filteredBeans) if (offlineList.size > 0) { showDataUi() diff --git a/app/src/main/java/melody/offline/music/adapter/OfflineSongsAdapter.kt b/app/src/main/java/melody/offline/music/adapter/OfflineSongsAdapter.kt index 7afa184..abcdf22 100644 --- a/app/src/main/java/melody/offline/music/adapter/OfflineSongsAdapter.kt +++ b/app/src/main/java/melody/offline/music/adapter/OfflineSongsAdapter.kt @@ -30,12 +30,20 @@ class OfflineSongsAdapter( val bean = list[position] holder.bind(bean) + holder.binding.favoritedBtn.setOnClickListener { + if (favoriteClickListener != null) { + favoriteClickListener?.onFavoriteClick(position) + } + } 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, MoOfflineSongsActivity::class.java) + intent.putExtra( + MoPlayDetailsActivity.PLAY_DETAILS_COME_FROM, + MoOfflineSongsActivity::class.java + ) context.startActivity(intent) } @@ -43,7 +51,7 @@ class OfflineSongsAdapter( override fun getItemCount(): Int = list.size - inner class ViewHolder(private val binding: OfflineListItemBinding) : + inner class ViewHolder(val binding: OfflineListItemBinding) : RecyclerView.ViewHolder(binding.root) { @SuppressLint("SetTextI18n") @@ -76,6 +84,12 @@ class OfflineSongsAdapter( binding.listPlayView.visibility = View.GONE } } + + if (bean.isFavorite) { + binding.favoritedImg.setImageResource(R.drawable.favorited_icon) + } else { + binding.favoritedImg.setImageResource(R.drawable.not_favorited_icon) + } } } } @@ -89,4 +103,14 @@ class OfflineSongsAdapter( interface OnItemClickListener { fun onItemClick(position: Int) } + + private var favoriteClickListener: OnFavoriteClickListener? = null + + fun setOnFavoriteClickListener(listener: OnFavoriteClickListener) { + favoriteClickListener = listener + } + + interface OnFavoriteClickListener { + fun onFavoriteClick(position: Int) + } } \ No newline at end of file diff --git a/app/src/main/java/melody/offline/music/bean/OfflineBean.kt b/app/src/main/java/melody/offline/music/bean/OfflineBean.kt index 2088b03..3cce9c6 100644 --- a/app/src/main/java/melody/offline/music/bean/OfflineBean.kt +++ b/app/src/main/java/melody/offline/music/bean/OfflineBean.kt @@ -15,7 +15,8 @@ data class OfflineBean( @ColumnInfo(name = "thumbnail") var thumbnail: String? = null, @ColumnInfo(name = "bytesDownloaded") var bytesDownloaded: Long? = null, @ColumnInfo(name = "size") var size: String? = null, - @ColumnInfo(name = "isOffline") var isOffline: Boolean + @ColumnInfo(name = "isOffline") var isOffline: Boolean, + @ColumnInfo(name = "isFavorite") var isFavorite: Boolean ) : Serializable { @PrimaryKey(autoGenerate = true) var id: Long = 0 diff --git a/app/src/main/java/melody/offline/music/database/AppOfflineDBManager.kt b/app/src/main/java/melody/offline/music/database/AppOfflineDBManager.kt index 978906c..5ed211f 100644 --- a/app/src/main/java/melody/offline/music/database/AppOfflineDBManager.kt +++ b/app/src/main/java/melody/offline/music/database/AppOfflineDBManager.kt @@ -2,6 +2,8 @@ package melody.offline.music.database import android.content.Context import androidx.room.Room +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase import melody.offline.music.bean.OfflineBean import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -19,10 +21,16 @@ class AppOfflineDBManager private constructor(context: Context) { } } + val MIGRATION_1_2 = object : Migration(1, 2) { + override fun migrate(database: SupportSQLiteDatabase) { + // 在数据库中添加新的列 + database.execSQL("ALTER TABLE OfflineBean ADD COLUMN isFavorite INTEGER NOT NULL DEFAULT 0") + } + } + private val database = Room.databaseBuilder( - context.applicationContext, - AppOfflineDatabase::class.java, "offline_data_base" - ).build() + context.applicationContext, AppOfflineDatabase::class.java, "offline_data_base" + ).addMigrations(MIGRATION_1_2).build() private val dao = database.localOfflineDao() diff --git a/app/src/main/java/melody/offline/music/database/AppOfflineDatabase.kt b/app/src/main/java/melody/offline/music/database/AppOfflineDatabase.kt index c795982..4e887e7 100644 --- a/app/src/main/java/melody/offline/music/database/AppOfflineDatabase.kt +++ b/app/src/main/java/melody/offline/music/database/AppOfflineDatabase.kt @@ -5,7 +5,7 @@ import androidx.room.Database import androidx.room.RoomDatabase import melody.offline.music.bean.OfflineBean -@Database(entities = [OfflineBean::class], version = 1, exportSchema = false) +@Database(entities = [OfflineBean::class], version = 2, exportSchema = false) abstract class AppOfflineDatabase : RoomDatabase() { abstract fun localOfflineDao(): OfflineDao } \ No newline at end of file diff --git a/app/src/main/res/drawable/three_dots_icon.xml b/app/src/main/res/drawable/three_dots_icon.xml new file mode 100644 index 0000000..1b2eb4d --- /dev/null +++ b/app/src/main/res/drawable/three_dots_icon.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/offline_list_item.xml b/app/src/main/res/layout/offline_list_item.xml index 36a8125..b396f1d 100644 --- a/app/src/main/res/layout/offline_list_item.xml +++ b/app/src/main/res/layout/offline_list_item.xml @@ -59,8 +59,8 @@ @@ -78,8 +78,8 @@ + android:textSize="12dp" /> + + + + + + + + + + + + + + \ No newline at end of file