From 9b91074eebdaf64cc22e48d03dd613d880a0466b Mon Sep 17 00:00:00 2001
From: ocean <503259349@qq.com>
Date: Thu, 16 May 2024 11:37:58 +0800
Subject: [PATCH] update
---
app/src/main/AndroidManifest.xml | 3 +
.../player/musicoo/activity/MoBaseActivity.kt | 15 +-
.../musicoo/activity/MoPlayDetailsActivity.kt | 37 +--
.../musicoo/activity/MoSearchMoreActivity.kt | 15 +-
.../activity/MoSingerDetailsActivity.kt | 17 +-
.../activity/MoSingerMoreSongActivity.kt | 170 +++++++++++++
.../musicoo/adapter/SingerMoreSongAdapter.kt | 145 +++++++++++
.../musicoo/adapter/TowRowListAdapter.kt | 24 +-
.../com/player/musicoo/innertube/Innertube.kt | 33 ++-
.../innertube/models/BrowseResponse.kt | 8 +-
.../innertube/requests/MoSingerlistPage.kt | 226 ++++++++++++++++--
.../musicoo/view/MusicTowRowListView.kt | 3 +-
.../musicoo/view/SingerDetailsOtherView.kt | 31 ++-
.../musicoo/view/SingerDetailsSongView.kt | 11 +
app/src/main/res/drawable/drw_dialog_bg.xml | 8 +
app/src/main/res/layout/activity_details.xml | 13 +-
.../main/res/layout/activity_search_more.xml | 4 +-
app/src/main/res/layout/details_list_item.xml | 2 +-
.../main/res/layout/dialog_description.xml | 88 ++++---
.../res/layout/singer_music_list_layout.xml | 46 +++-
20 files changed, 789 insertions(+), 110 deletions(-)
create mode 100644 app/src/main/java/com/player/musicoo/activity/MoSingerMoreSongActivity.kt
create mode 100644 app/src/main/java/com/player/musicoo/adapter/SingerMoreSongAdapter.kt
create mode 100644 app/src/main/res/drawable/drw_dialog_bg.xml
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0ac0368..0f751ca 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -62,6 +62,9 @@
+
(R.id.dialog_content)
content.text = description
- val okBtn = dialogView.findViewById(R.id.dialog_ok_btn)
+ val close = dialogView.findViewById(R.id.closeBtn)
val dialogBuilder = AlertDialog.Builder(this)
.setView(dialogView)
val dialog = dialogBuilder.create()
+ dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.show()
- okBtn.setOnClickListener {
+ close.setOnClickListener {
dialog.dismiss()
}
}
+ fun extractTextBeforeNewline(text: String): String {
+ // 用换行符分割文本,取第一个部分
+ return text.split("\n\n")[0]
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/player/musicoo/activity/MoPlayDetailsActivity.kt b/app/src/main/java/com/player/musicoo/activity/MoPlayDetailsActivity.kt
index 017929b..e9454a5 100644
--- a/app/src/main/java/com/player/musicoo/activity/MoPlayDetailsActivity.kt
+++ b/app/src/main/java/com/player/musicoo/activity/MoPlayDetailsActivity.kt
@@ -76,22 +76,28 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
// 处理来自 PrimaryActivity 的情况
updateCurrentMediaItemInfo()
} else {
- binding.nameTv.text = intent.getStringExtra(PLAY_DETAILS_NAME)
- binding.descTv.text = intent.getStringExtra(PLAY_DETAILS_DESC)
+ if (meController != null && meController.currentMediaItem != null && videoId == meController.currentMediaItem?.mediaId) {
+ //进入的id与当前的id一样就不重新去获取播放
+ updateCurrentMediaItemInfo()
+ } else {
+ binding.nameTv.text = intent.getStringExtra(PLAY_DETAILS_NAME)
+ binding.descTv.text = intent.getStringExtra(PLAY_DETAILS_DESC)
- if (videoId.isNullOrEmpty()) {
- finish()
- return
+ if (videoId.isNullOrEmpty()) {
+ finish()
+ return
+ }
+ //传入进来的ID,就是进入此界面的当前ID
+ currentVideoID = videoId
+ //根据进来界面的当前ID来获取资源。
+ initData(
+ videoId,
+ playlistId,
+ playlistSetVideoId,
+ params
+ )
}
- //传入进来的ID,就是进入此界面的当前ID
- currentVideoID = videoId
- //根据进来界面的当前ID来获取资源。
- initData(
- videoId,
- playlistId,
- playlistSetVideoId,
- params
- )
+
}
onReceive()
@@ -130,7 +136,8 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
binding.playbackErrorLayout.visibility = View.GONE
binding.loadingView.visibility = View.GONE
binding.disableClicksLayout.visibility = View.GONE
- val currentString = convertMillisToMinutesAndSecondsString(MediaControllerManager.getCurrentPosition())
+ val currentString =
+ convertMillisToMinutesAndSecondsString(MediaControllerManager.getCurrentPosition())
binding.progressDurationTv.text = currentString
if (MediaControllerManager.getDuration() > 0) {
binding.totalDurationTv.visibility = View.VISIBLE
diff --git a/app/src/main/java/com/player/musicoo/activity/MoSearchMoreActivity.kt b/app/src/main/java/com/player/musicoo/activity/MoSearchMoreActivity.kt
index 6da55e2..d3e1a60 100644
--- a/app/src/main/java/com/player/musicoo/activity/MoSearchMoreActivity.kt
+++ b/app/src/main/java/com/player/musicoo/activity/MoSearchMoreActivity.kt
@@ -83,8 +83,11 @@ class MoSearchMoreActivity : MoBaseActivity() {
}
Request.MoreData -> {
- LogD(TAG, "Request.MoreData")
- currentContinuation?.let { it1 -> initDataMore(it1) }
+ if (!currentContinuation.isNullOrEmpty()) {
+ initDataMore(currentContinuation!!)
+ }else{
+ binding.refreshLayout.finishLoadMoreWithNoMoreData()
+ }
}
}
}
@@ -138,8 +141,10 @@ class MoSearchMoreActivity : MoBaseActivity() {
@SuppressLint("NotifyDataSetChanged")
private suspend fun initDataMore(continuation: String) {
Innertube.moSearchPage(ContinuationBody(continuation = continuation))?.onSuccess { result ->
- LogD(TAG, "initDataMore result->$result")
currentContinuation = result.continuation
+ if (currentContinuation.isNullOrEmpty()) {
+ binding.refreshLayout.finishLoadMoreWithNoMoreData()
+ }
if (result.searchResultList.isNotEmpty()) {
list.addAll(result.searchResultList)
if (!isFinishing) {
@@ -147,10 +152,10 @@ class MoSearchMoreActivity : MoBaseActivity() {
}
binding.refreshLayout.finishLoadMore(true)
} else {
- binding.refreshLayout.finishLoadMore(2000, true, false)
+ binding.refreshLayout.finishLoadMoreWithNoMoreData()
}
}?.onFailure {
- binding.refreshLayout.finishLoadMore(2000, false, false)
+ binding.refreshLayout.finishLoadMoreWithNoMoreData()
}
}
diff --git a/app/src/main/java/com/player/musicoo/activity/MoSingerDetailsActivity.kt b/app/src/main/java/com/player/musicoo/activity/MoSingerDetailsActivity.kt
index 0402d4a..d2f72c9 100644
--- a/app/src/main/java/com/player/musicoo/activity/MoSingerDetailsActivity.kt
+++ b/app/src/main/java/com/player/musicoo/activity/MoSingerDetailsActivity.kt
@@ -1,15 +1,10 @@
package com.player.musicoo.activity
import android.view.View
-import androidx.recyclerview.widget.LinearLayoutManager
import com.bumptech.glide.Glide
import com.gyf.immersionbar.ktx.immersionBar
-import com.player.musicoo.adapter.DetailsListAdapter
-import com.player.musicoo.databinding.ActivityDetailsBinding
import com.player.musicoo.databinding.ActivitySingerDetailsBinding
-import com.player.musicoo.fragment.MoHomeFragment
import com.player.musicoo.innertube.Innertube
-import com.player.musicoo.innertube.requests.moPlaylistPage
import com.player.musicoo.innertube.requests.moSingerListPage
import com.player.musicoo.util.LogTag.LogD
import com.player.musicoo.view.SingerDetailsOtherView
@@ -75,6 +70,9 @@ class MoSingerDetailsActivity : MoBaseActivity() {
binding.tryAgainBtn.setOnClickListener {
requests.trySend(Request.TryAgain)
}
+ binding.singerDescExpand.setOnClickListener {
+ showSongDescriptionDialog(binding.singerDesc.text.toString())
+ }
}
private suspend fun initData(browseId: String) {
@@ -86,7 +84,14 @@ class MoSingerDetailsActivity : MoBaseActivity() {
.load(it.thumbnail)
.into(binding.singerImg)
binding.singerName.text = it.title
- binding.singerDesc.text = it.description
+ if (it.description.isNullOrEmpty()) {
+ binding.singerDesc.visibility = View.GONE
+ binding.singerDescExpand.visibility = View.GONE
+ } else {
+ binding.singerDesc.visibility = View.VISIBLE
+ binding.singerDescExpand.visibility = View.VISIBLE
+ binding.singerDesc.text = extractTextBeforeNewline(it.description)
+ }
if (it.list != null) {
for (bean: Innertube.SingerDetailsListPage in it.list) {
if (bean.contents?.musicShelfContentList != null && bean.contents.musicShelfContentList.isNotEmpty()) {
diff --git a/app/src/main/java/com/player/musicoo/activity/MoSingerMoreSongActivity.kt b/app/src/main/java/com/player/musicoo/activity/MoSingerMoreSongActivity.kt
new file mode 100644
index 0000000..bb59c7b
--- /dev/null
+++ b/app/src/main/java/com/player/musicoo/activity/MoSingerMoreSongActivity.kt
@@ -0,0 +1,170 @@
+package com.player.musicoo.activity
+
+import android.annotation.SuppressLint
+import android.view.View
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.gyf.immersionbar.ktx.immersionBar
+import com.player.musicoo.adapter.SingerMoreSongAdapter
+import com.player.musicoo.databinding.ActivitySearchMoreBinding
+import com.player.musicoo.innertube.Innertube
+import com.player.musicoo.innertube.models.bodies.BrowseBody
+import com.player.musicoo.innertube.models.bodies.ContinuationBody
+import com.player.musicoo.innertube.requests.moSingerDetailsMoreLoadMorePage
+import com.player.musicoo.innertube.requests.moSingerDetailsMorePage
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.selects.select
+
+class MoSingerMoreSongActivity : MoBaseActivity() {
+ private val requests: Channel = Channel(Channel.UNLIMITED)
+
+ enum class Request {
+ TryAgain,
+ MoreData,
+ }
+
+ companion object {
+ const val SINGER_MORE_SONG_BROWSE_ID = "singer_more_song_browse_id"
+ const val SINGER_MORE_SONG_PARAMS = "singer_more_song_params"
+ const val SINGER_MORE_TYPE = "singer_more_type"
+ }
+
+ private lateinit var binding: ActivitySearchMoreBinding
+ private var browseId: String? = null
+ private var params: String? = null
+ private var type: String? = null
+ private var list: MutableList =
+ mutableListOf()
+ private var currentContinuation: String? = null
+ private var adapter: SingerMoreSongAdapter? = null
+
+ override suspend fun main() {
+ binding = ActivitySearchMoreBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ browseId = intent.getStringExtra(SINGER_MORE_SONG_BROWSE_ID)
+ params = intent.getStringExtra(SINGER_MORE_SONG_PARAMS)
+ type = intent.getStringExtra(SINGER_MORE_TYPE)
+ if (browseId.isNullOrEmpty() || params.isNullOrEmpty()) {
+ return
+ }
+ initImmersionBar()
+ initView()
+ initAdapter()
+ initData(browseId!!, params!!)
+ onReceive()
+ }
+
+ private fun initImmersionBar() {
+ immersionBar {
+ statusBarDarkFont(false)
+ statusBarView(binding.view)
+ }
+ }
+
+ private suspend fun onReceive() {
+ while (isActive) {
+ select {
+ requests.onReceive {
+ when (it) {
+ Request.TryAgain -> {
+ initData(browseId!!, params!!)
+ }
+
+ Request.MoreData -> {
+ if (!currentContinuation.isNullOrEmpty()) {
+ initDataMore(currentContinuation!!)
+ }else{
+ binding.refreshLayout.finishLoadMoreWithNoMoreData()
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private fun initView() {
+ binding.backBtn.setOnClickListener {
+ finish()
+ }
+ binding.tryAgainBtn.setOnClickListener {
+ requests.trySend(Request.TryAgain)
+ }
+ binding.refreshLayout.setEnableRefresh(false)
+ binding.refreshLayout.setEnableLoadMore(true)
+ binding.refreshLayout.setOnLoadMoreListener {
+ requests.trySend(Request.MoreData)
+ }
+ }
+
+ private fun initAdapter() {
+ adapter = SingerMoreSongAdapter(this, list, type)
+ if (type == "MUSIC_PAGE_TYPE_ARTIST_DISCOGRAPHY") {
+ binding.rv.layoutManager = GridLayoutManager(this, 2)
+ } else {
+ binding.rv.layoutManager =
+ LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
+ }
+ binding.rv.adapter = adapter
+ }
+
+ private suspend fun initData(browseId: String, params: String) {
+ showLoadingUi()
+ Innertube.moSingerDetailsMorePage(BrowseBody(browseId = browseId, params = params))
+ ?.onSuccess { result ->
+ showDataUi()
+ val title = result.title
+ if (title.isNullOrEmpty()) {
+ binding.title.visibility = View.GONE
+ } else {
+ binding.title.visibility = View.VISIBLE
+ binding.title.text = title
+ }
+ currentContinuation = result.continuation
+ list.clear()
+ list.addAll(result.songList)
+
+ }?.onFailure {
+ showNoContentUi()
+ }
+ }
+
+ @SuppressLint("NotifyDataSetChanged")
+ private suspend fun initDataMore(continuation: String) {
+ Innertube.moSingerDetailsMoreLoadMorePage(ContinuationBody(continuation = continuation))
+ ?.onSuccess { result ->
+ currentContinuation = result.continuation
+ if (currentContinuation.isNullOrEmpty()) {
+ binding.refreshLayout.finishLoadMoreWithNoMoreData()
+ }
+ if (result.songList.isNotEmpty()) {
+ list.addAll(result.songList)
+ if (!isFinishing) {
+ adapter?.notifyDataSetChanged()
+ binding.refreshLayout.finishLoadMore(true)
+ }
+ } else {
+ binding.refreshLayout.finishLoadMoreWithNoMoreData()
+ }
+ }?.onFailure {
+ binding.refreshLayout.finishLoadMoreWithNoMoreData()
+ }
+ }
+
+
+ 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/com/player/musicoo/adapter/SingerMoreSongAdapter.kt b/app/src/main/java/com/player/musicoo/adapter/SingerMoreSongAdapter.kt
new file mode 100644
index 0000000..4b1588a
--- /dev/null
+++ b/app/src/main/java/com/player/musicoo/adapter/SingerMoreSongAdapter.kt
@@ -0,0 +1,145 @@
+package com.player.musicoo.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.media3.common.C
+import androidx.media3.common.MediaItem
+import androidx.media3.common.Player
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.player.musicoo.R
+import com.player.musicoo.activity.MoListDetailsActivity
+import com.player.musicoo.activity.MoPlayDetailsActivity
+import com.player.musicoo.activity.MoSingerDetailsActivity
+import com.player.musicoo.databinding.MusicTowRowItemBinding
+import com.player.musicoo.databinding.PlayListItemBinding
+import com.player.musicoo.databinding.SearchResultOtherItemBinding
+import com.player.musicoo.databinding.SearchResultOtherLayoutBinding
+import com.player.musicoo.innertube.Innertube
+import com.player.musicoo.media.MediaControllerManager
+import com.player.musicoo.util.LogTag
+
+class SingerMoreSongAdapter(
+ private val context: Context,
+ private val list: List,
+ private val type: String? = null,
+) :
+ RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return when (viewType) {
+ TYPE_ONE -> {
+ val binding =
+ SearchResultOtherItemBinding.inflate(
+ LayoutInflater.from(context),
+ parent,
+ false
+ )
+ ViewHolderOne(binding)
+ }
+
+ TYPE_TWO -> {
+ val binding =
+ MusicTowRowItemBinding.inflate(LayoutInflater.from(context), parent, false)
+ ViewHolderTow(binding)
+ }
+
+ else -> throw IllegalArgumentException("Invalid view type")
+ }
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ val bean = list[position]
+ when (holder.itemViewType) {
+ TYPE_ONE -> {
+ val typeOneHolder = holder as ViewHolderOne
+ typeOneHolder.bind(bean)
+ typeOneHolder.itemView.setOnClickListener {
+ val intent = Intent(context, MoPlayDetailsActivity::class.java)
+ intent.putExtra(
+ MoPlayDetailsActivity.PLAY_DETAILS_VIDEO_ID,
+ bean.videoId
+ )
+ intent.putExtra(
+ MoPlayDetailsActivity.PLAY_DETAILS_PLAY_LIST_ID,
+ bean.playlistId
+ )
+ intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_NAME, bean.title)
+ intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_DESC, bean.name)
+ context.startActivity(intent)
+ }
+ }
+
+ TYPE_TWO -> {
+ val typeTwoHolder = holder as ViewHolderTow
+ typeTwoHolder.bind(bean)
+ typeTwoHolder.itemView.setOnClickListener {
+ val intent = Intent(context, MoListDetailsActivity::class.java)
+ intent.putExtra(
+ MoListDetailsActivity.PLAY_LIST_PAGE_BROWSE_ID,
+ bean.browseId
+ )
+ context.startActivity(intent)
+ }
+ }
+ }
+ }
+
+ private val TYPE_ONE = 1
+ private val TYPE_TWO = 2
+ override fun getItemViewType(position: Int): Int {
+ return if (type == "MUSIC_PAGE_TYPE_ARTIST_DISCOGRAPHY") {
+ TYPE_TWO
+ } else {
+ TYPE_ONE
+ }
+ }
+
+ override fun getItemCount(): Int = list.size
+
+ inner class ViewHolderOne(private val binding: SearchResultOtherItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ @SuppressLint("SetTextI18n")
+ fun bind(bean: Innertube.BaseSingleColumnBrowseSongResults.SingleColumnBrowseSongResults) {
+
+ binding.apply {
+ Glide.with(context)
+ .load(bean.thumbnail)
+ .into(image)
+ title.text = bean.title
+ name.text = bean.name
+ }
+ }
+ }
+
+ inner class ViewHolderTow(private val binding: MusicTowRowItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ @SuppressLint("SetTextI18n")
+ fun bind(bean: Innertube.BaseSingleColumnBrowseSongResults.SingleColumnBrowseSongResults) {
+
+ binding.apply {
+ Glide.with(context)
+ .load(bean.thumbnail)
+ .into(image)
+ nameTv.text = bean.title
+ descTv.text = bean.name
+ }
+ }
+ }
+
+ private var itemClickListener: OnItemClickListener? = null
+
+ fun setOnItemClickListener(listener: OnItemClickListener) {
+ itemClickListener = listener
+ }
+
+ interface OnItemClickListener {
+ fun onItemClick(position: Int)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/player/musicoo/adapter/TowRowListAdapter.kt b/app/src/main/java/com/player/musicoo/adapter/TowRowListAdapter.kt
index 982d00a..fafc948 100644
--- a/app/src/main/java/com/player/musicoo/adapter/TowRowListAdapter.kt
+++ b/app/src/main/java/com/player/musicoo/adapter/TowRowListAdapter.kt
@@ -1,5 +1,6 @@
package com.player.musicoo.adapter
+import android.app.Activity
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
@@ -8,11 +9,12 @@ import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.player.musicoo.activity.MoListDetailsActivity
import com.player.musicoo.activity.MoPlayDetailsActivity
+import com.player.musicoo.activity.MoSingerDetailsActivity
import com.player.musicoo.databinding.MusicTowRowItemBinding
import com.player.musicoo.innertube.models.MusicCarouselShelfRenderer
class TowRowListAdapter(
- private val context: Context,
+ private val context: Activity,
private val list: List,
) :
RecyclerView.Adapter() {
@@ -35,6 +37,8 @@ class TowRowListAdapter(
val browseId = browseEndpoint?.browseId
+ val pageType = browseEndpoint?.type
+
val watchEndpoint = bean.musicTwoRowItemRenderer
?.navigationEndpoint
?.watchEndpoint
@@ -81,9 +85,21 @@ class TowRowListAdapter(
intent.putExtra(MoPlayDetailsActivity.PLAY_DETAILS_DESC, desc)
context.startActivity(intent)
} else {
- val intent = Intent(context, MoListDetailsActivity::class.java)
- intent.putExtra(MoListDetailsActivity.PLAY_LIST_PAGE_BROWSE_ID, browseId)
- context.startActivity(intent)
+ if (pageType == "MUSIC_PAGE_TYPE_ARTIST") {
+ val intent = Intent(context, MoSingerDetailsActivity::class.java)
+ intent.putExtra(
+ MoSingerDetailsActivity.SINGER_DETAILS_PAGE_BROWSE_ID,
+ browseId
+ )
+ context.startActivity(intent)
+ if (context is MoSingerDetailsActivity) {
+ context.finish()
+ }
+ } else {
+ val intent = Intent(context, MoListDetailsActivity::class.java)
+ intent.putExtra(MoListDetailsActivity.PLAY_LIST_PAGE_BROWSE_ID, browseId)
+ context.startActivity(intent)
+ }
}
}
}
diff --git a/app/src/main/java/com/player/musicoo/innertube/Innertube.kt b/app/src/main/java/com/player/musicoo/innertube/Innertube.kt
index 999e40a..4b5e1e5 100644
--- a/app/src/main/java/com/player/musicoo/innertube/Innertube.kt
+++ b/app/src/main/java/com/player/musicoo/innertube/Innertube.kt
@@ -1,9 +1,12 @@
package com.player.musicoo.innertube
import com.player.musicoo.innertube.models.MusicCarouselShelfRenderer
-import com.player.musicoo.innertube.models.MusicResponsiveListItemRenderer
import com.player.musicoo.innertube.models.MusicShelfRenderer
-import com.player.musicoo.innertube.models.MusicTwoRowItemRenderer
+import com.player.musicoo.innertube.models.NavigationEndpoint
+import com.player.musicoo.innertube.models.Runs
+import com.player.musicoo.innertube.models.Thumbnail
+import com.player.musicoo.innertube.utils.brotli
+import com.player.musicoo.util.LogTag
import io.ktor.client.HttpClient
import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.plugins.BrowserUserAgent
@@ -15,11 +18,6 @@ import io.ktor.client.request.header
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.serialization.kotlinx.json.json
-import com.player.musicoo.innertube.models.NavigationEndpoint
-import com.player.musicoo.innertube.models.Runs
-import com.player.musicoo.innertube.models.Thumbnail
-import com.player.musicoo.innertube.utils.brotli
-import com.player.musicoo.util.LogTag
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
@@ -176,7 +174,10 @@ object Innertube {
)
data class SingerDetailsListPage(
+ val pageType: String? = null,
val title: String?,
+ val browseId: String? = null,
+ val params: String? = null,
val contents: SingerDetailsContent?
) {
data class SingerDetailsContent(
@@ -240,6 +241,24 @@ object Innertube {
)
}
+ data class BaseSingleColumnBrowseSongResults(
+ val title: String? = null,
+ val continuation: String? = null,
+ val songList: List
+ ) {
+ data class SingleColumnBrowseSongResults(
+ val title: String?,
+ val name: String?,
+ val thumbnail: String?,
+ val videoId: String? = null,
+ val playlistId: String? = null,
+ val browseId: String? = null,
+ val params: String? = null,
+ val pageType: String? = null
+ )
+
+ }
+
data class ArtistPage(
val name: String?,
val description: String?,
diff --git a/app/src/main/java/com/player/musicoo/innertube/models/BrowseResponse.kt b/app/src/main/java/com/player/musicoo/innertube/models/BrowseResponse.kt
index 227ebf7..7fbd014 100644
--- a/app/src/main/java/com/player/musicoo/innertube/models/BrowseResponse.kt
+++ b/app/src/main/java/com/player/musicoo/innertube/models/BrowseResponse.kt
@@ -26,7 +26,7 @@ data class BrowseResponse(
@Serializable
data class ContinuationContents(
- val sectionListContinuation : SectionListContinuation?
+ val sectionListContinuation: SectionListContinuation?
)
@Serializable
@@ -34,7 +34,13 @@ data class BrowseResponse(
@JsonNames("musicVisualHeaderRenderer")
val musicImmersiveHeaderRenderer: MusicImmersiveHeaderRenderer?,
val musicDetailHeaderRenderer: MusicDetailHeaderRenderer?,
+ val musicHeaderRenderer: MusicHeaderRenderer?
) {
+ @Serializable
+ data class MusicHeaderRenderer(
+ val title: Runs?
+ )
+
@Serializable
data class MusicDetailHeaderRenderer(
val title: Runs?,
diff --git a/app/src/main/java/com/player/musicoo/innertube/requests/MoSingerlistPage.kt b/app/src/main/java/com/player/musicoo/innertube/requests/MoSingerlistPage.kt
index 2586c31..8f7d4d2 100644
--- a/app/src/main/java/com/player/musicoo/innertube/requests/MoSingerlistPage.kt
+++ b/app/src/main/java/com/player/musicoo/innertube/requests/MoSingerlistPage.kt
@@ -2,10 +2,13 @@ package com.player.musicoo.innertube.requests
import com.player.musicoo.innertube.Innertube
import com.player.musicoo.innertube.models.BrowseResponse
+import com.player.musicoo.innertube.models.ContinuationResponse
+import com.player.musicoo.innertube.models.GridRenderer
import com.player.musicoo.innertube.models.MusicCarouselShelfRenderer
import com.player.musicoo.innertube.models.MusicShelfRenderer
import com.player.musicoo.innertube.models.SectionListRenderer
import com.player.musicoo.innertube.models.bodies.BrowseBody
+import com.player.musicoo.innertube.models.bodies.ContinuationBody
import com.player.musicoo.innertube.utils.runCatchingNonCancellable
import com.player.musicoo.util.LogTag
import io.ktor.client.call.body
@@ -53,6 +56,9 @@ suspend fun Innertube.moSingerListPage(browseId: String): Result =
mutableListOf()
val musicCarouselShelfContents: MutableList =
@@ -64,6 +70,14 @@ suspend fun Innertube.moSingerListPage(browseId: String): Result${singerDetails.title}")
-// LogTag.LogD(
-// TAG,
-// "musicShelfContentList size->${singerDetails.contents?.musicShelfContentList?.size}"
-// )
-// LogTag.LogD(
-// TAG,
-// "musicCarouselShelfContentList size->${singerDetails.contents?.musicCarouselShelfContentList?.size}"
-// )
-//
-// LogTag.LogD(TAG, "--------------------------------------------")
-
+ Innertube.SingerDetailsListPage(
+ title = title,
+ contents = singerDetailsContent,
+ browseId = browseId,
+ params = params,
+ pageType = pageType,
+ )
if (title.isNotEmpty()) {
list.add(singerDetails)
}
@@ -109,4 +127,184 @@ suspend fun Innertube.moSingerListPage(browseId: String): Result? =
+ runCatchingNonCancellable {
+ val response = client.post(browse) {
+ setBody(body)
+ }.body()
+
+ val gridRenderer = response.contents
+ ?.singleColumnBrowseResultsRenderer
+ ?.tabs?.firstOrNull()
+ ?.tabRenderer
+ ?.content
+ ?.sectionListRenderer
+ ?.contents
+ ?.firstOrNull()
+ ?.gridRenderer
+
+
+ val musicPlaylistShelfRenderer = response.contents
+ ?.singleColumnBrowseResultsRenderer
+ ?.tabs
+ ?.firstOrNull()
+ ?.tabRenderer
+ ?.content
+ ?.sectionListRenderer
+ ?.contents
+ ?.firstOrNull()
+ ?.musicShelfRenderer
+
+ val title = response.header?.musicHeaderRenderer?.title?.text
+ val continuation = musicPlaylistShelfRenderer
+ ?.continuations
+ ?.firstOrNull()
+ ?.nextContinuationData
+ ?.continuation
+
+ val songList: MutableList =
+ mutableListOf()
+
+ val contentList = musicPlaylistShelfRenderer?.contents
+ val contentGridItems = gridRenderer?.items
+ if (contentList != null) {
+ for (content: MusicShelfRenderer.Content in contentList) {
+ val contentTitle = content.musicResponsiveListItemRenderer
+ ?.flexColumns
+ ?.firstOrNull()
+ ?.musicResponsiveListItemFlexColumnRenderer
+ ?.text?.text
+
+ val name = content.musicResponsiveListItemRenderer
+ ?.flexColumns
+ ?.get(1)
+ ?.musicResponsiveListItemFlexColumnRenderer
+ ?.text?.text
+
+ val thumbnail = content.musicResponsiveListItemRenderer
+ ?.thumbnail
+ ?.musicThumbnailRenderer
+ ?.thumbnail
+ ?.thumbnails?.let {
+ it.getOrNull(2) ?: it.getOrNull(1) ?: it.getOrNull(0)
+ }?.url
+
+ val navigationEndpoint = content.musicResponsiveListItemRenderer
+ ?.flexColumns
+ ?.firstOrNull()
+ ?.musicResponsiveListItemFlexColumnRenderer
+ ?.text
+ ?.runs
+ ?.firstOrNull()
+ ?.navigationEndpoint
+
+ val videoId = navigationEndpoint?.watchEndpoint?.videoId
+ val playlistId = navigationEndpoint?.watchEndpoint?.playlistId
+
+
+ songList.add(
+ Innertube.BaseSingleColumnBrowseSongResults.SingleColumnBrowseSongResults(
+ title = contentTitle,
+ name = name,
+ thumbnail = thumbnail,
+ videoId = videoId,
+ playlistId = playlistId
+ )
+ )
+ }
+ } else {
+ if (contentGridItems != null) {
+ for (content: GridRenderer.Item in contentGridItems) {
+ songList.add(
+ Innertube.BaseSingleColumnBrowseSongResults.SingleColumnBrowseSongResults(
+ title = content.musicTwoRowItemRenderer?.title?.runs?.firstOrNull()?.text,
+ name = content.musicTwoRowItemRenderer?.subtitle?.text,
+ thumbnail = content.musicTwoRowItemRenderer
+ ?.thumbnailRenderer
+ ?.musicThumbnailRenderer
+ ?.thumbnail
+ ?.thumbnails?.let {
+ it.getOrNull(2) ?: it.getOrNull(1) ?: it.getOrNull(0)
+ }?.url,
+ browseId = content.musicTwoRowItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId,
+ params = content.musicTwoRowItemRenderer?.navigationEndpoint?.browseEndpoint?.params,
+ pageType = content.musicTwoRowItemRenderer?.navigationEndpoint?.browseEndpoint?.type
+ )
+ )
+ }
+ }
+ }
+ Innertube.BaseSingleColumnBrowseSongResults(
+ title = title,
+ songList = songList,
+ continuation = continuation
+ )
+ }
+
+suspend fun Innertube.moSingerDetailsMoreLoadMorePage(body: ContinuationBody): Result? =
+ runCatchingNonCancellable {
+ val response = client.post(browse) {
+ setBody(body)
+ }.body()
+
+ val continuation = response.continuationContents
+ ?.musicShelfContinuation
+ ?.continuations
+ ?.firstOrNull()
+ ?.nextContinuationData
+ ?.continuation
+
+ val songList: MutableList =
+ mutableListOf()
+
+ val contentList = response.continuationContents?.musicShelfContinuation?.contents
+ if (contentList != null) {
+ for (content: MusicShelfRenderer.Content in contentList) {
+ val title = content.musicResponsiveListItemRenderer
+ ?.flexColumns
+ ?.firstOrNull()
+ ?.musicResponsiveListItemFlexColumnRenderer
+ ?.text?.text
+
+ val name = content.musicResponsiveListItemRenderer
+ ?.flexColumns
+ ?.get(1)
+ ?.musicResponsiveListItemFlexColumnRenderer
+ ?.text?.text
+
+ val thumbnail = content.musicResponsiveListItemRenderer
+ ?.thumbnail
+ ?.musicThumbnailRenderer
+ ?.thumbnail
+ ?.thumbnails?.let {
+ it.getOrNull(2) ?: it.getOrNull(1) ?: it.getOrNull(0)
+ }?.url
+
+ val navigationEndpoint = content.musicResponsiveListItemRenderer
+ ?.flexColumns
+ ?.firstOrNull()
+ ?.musicResponsiveListItemFlexColumnRenderer
+ ?.text
+ ?.runs
+ ?.firstOrNull()
+ ?.navigationEndpoint
+
+ val videoId = navigationEndpoint?.watchEndpoint?.videoId
+ val playlistId = navigationEndpoint?.watchEndpoint?.playlistId
+
+
+ songList.add(
+ Innertube.BaseSingleColumnBrowseSongResults.SingleColumnBrowseSongResults(
+ title, name, thumbnail, videoId, playlistId
+ )
+ )
+ }
+ }
+ Innertube.BaseSingleColumnBrowseSongResults(
+ continuation = continuation,
+ songList = songList
+ )
}
\ No newline at end of file
diff --git a/app/src/main/java/com/player/musicoo/view/MusicTowRowListView.kt b/app/src/main/java/com/player/musicoo/view/MusicTowRowListView.kt
index 8c1d6d7..5817ea9 100644
--- a/app/src/main/java/com/player/musicoo/view/MusicTowRowListView.kt
+++ b/app/src/main/java/com/player/musicoo/view/MusicTowRowListView.kt
@@ -1,6 +1,7 @@
package com.player.musicoo.view
import android.annotation.SuppressLint
+import android.app.Activity
import android.content.Context
import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
@@ -12,7 +13,7 @@ import com.player.musicoo.adapter.TowRowListAdapter
import com.player.musicoo.innertube.Innertube
@SuppressLint("ViewConstructor")
-class MusicTowRowListView(context: Context, homePage: Innertube.HomePage) : ModuleView(context) {
+class MusicTowRowListView(context: Activity, homePage: Innertube.HomePage) : ModuleView(context) {
init {
contentView = inflate(getContext(), R.layout.music_list_layout, this)
val title = contentView?.findViewById(R.id.title)
diff --git a/app/src/main/java/com/player/musicoo/view/SingerDetailsOtherView.kt b/app/src/main/java/com/player/musicoo/view/SingerDetailsOtherView.kt
index ac89771..93554e4 100644
--- a/app/src/main/java/com/player/musicoo/view/SingerDetailsOtherView.kt
+++ b/app/src/main/java/com/player/musicoo/view/SingerDetailsOtherView.kt
@@ -1,21 +1,50 @@
package com.player.musicoo.view
import android.annotation.SuppressLint
+import android.app.Activity
import android.content.Context
+import android.content.Intent
+import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.player.musicoo.R
+import com.player.musicoo.activity.MoSearchMoreActivity
+import com.player.musicoo.activity.MoSingerMoreSongActivity
import com.player.musicoo.adapter.TowRowListAdapter
import com.player.musicoo.innertube.Innertube
@SuppressLint("ViewConstructor")
-class SingerDetailsOtherView (context: Context, bean: Innertube.SingerDetailsListPage) :
+class SingerDetailsOtherView(context: Activity, bean: Innertube.SingerDetailsListPage) :
ModuleView(context) {
init {
contentView = inflate(getContext(), R.layout.singer_music_list_layout, this)
val title = contentView?.findViewById(R.id.title)
title?.text = bean.title
+ val moreBtn = contentView?.findViewById(R.id.moreBtn)
+ moreBtn?.setOnClickListener {
+ val intent = Intent(context, MoSingerMoreSongActivity::class.java)
+ intent.putExtra(
+ MoSingerMoreSongActivity.SINGER_MORE_SONG_BROWSE_ID,
+ bean.browseId
+ )
+ intent.putExtra(MoSingerMoreSongActivity.SINGER_MORE_SONG_PARAMS, bean.params)
+ intent.putExtra(MoSingerMoreSongActivity.SINGER_MORE_TYPE, bean.pageType)
+ context.startActivity(intent)
+ }
+ when (bean.pageType) {
+ "MUSIC_PAGE_TYPE_ARTIST_DISCOGRAPHY" -> {
+ moreBtn?.visibility = VISIBLE
+ }
+
+ "MUSIC_PAGE_TYPE_PLAYLIST" -> {
+ moreBtn?.visibility = VISIBLE
+ }
+
+ else -> {
+ moreBtn?.visibility = GONE
+ }
+ }
val rv = contentView?.findViewById(R.id.rv)
diff --git a/app/src/main/java/com/player/musicoo/view/SingerDetailsSongView.kt b/app/src/main/java/com/player/musicoo/view/SingerDetailsSongView.kt
index 07899f1..8c4e0c6 100644
--- a/app/src/main/java/com/player/musicoo/view/SingerDetailsSongView.kt
+++ b/app/src/main/java/com/player/musicoo/view/SingerDetailsSongView.kt
@@ -2,11 +2,14 @@ package com.player.musicoo.view
import android.annotation.SuppressLint
import android.content.Context
+import android.content.Intent
+import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.player.musicoo.R
+import com.player.musicoo.activity.MoSingerMoreSongActivity
import com.player.musicoo.adapter.SingerDetailsSongListAdapter
import com.player.musicoo.innertube.Innertube
@@ -18,6 +21,14 @@ class SingerDetailsSongView(context: Context, bean: Innertube.SingerDetailsListP
val title = contentView?.findViewById(R.id.title)
title?.text = bean.title
+ val moreBtn = contentView?.findViewById(R.id.moreBtn)
+ moreBtn?.setOnClickListener {
+ val intent = Intent(context, MoSingerMoreSongActivity::class.java)
+ intent.putExtra(MoSingerMoreSongActivity.SINGER_MORE_SONG_BROWSE_ID, bean.browseId)
+ intent.putExtra(MoSingerMoreSongActivity.SINGER_MORE_SONG_PARAMS, bean.params)
+ context.startActivity(intent)
+ }
+
val rv = contentView?.findViewById(R.id.rv)
val adapter = SingerDetailsSongListAdapter(context, bean.contents?.musicShelfContentList!!)
diff --git a/app/src/main/res/drawable/drw_dialog_bg.xml b/app/src/main/res/drawable/drw_dialog_bg.xml
new file mode 100644
index 0000000..0350839
--- /dev/null
+++ b/app/src/main/res/drawable/drw_dialog_bg.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_details.xml b/app/src/main/res/layout/activity_details.xml
index 62eac86..478b2f7 100644
--- a/app/src/main/res/layout/activity_details.xml
+++ b/app/src/main/res/layout/activity_details.xml
@@ -54,10 +54,10 @@
+ android:progressTint="@color/green" />
@@ -176,10 +176,13 @@
+ android:scrollbars="none" />
diff --git a/app/src/main/res/layout/activity_search_more.xml b/app/src/main/res/layout/activity_search_more.xml
index 87ee8ee..28a7897 100644
--- a/app/src/main/res/layout/activity_search_more.xml
+++ b/app/src/main/res/layout/activity_search_more.xml
@@ -118,9 +118,7 @@
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:overScrollMode="never"
- android:scrollbars="none"
- tools:itemCount="10"
- tools:listitem="@layout/music_responsive_item" />
+ android:scrollbars="none" />
-
+ android:padding="16dp"
+ android:layout_height="wrap_content">
-
-
-
-
-
+ android:gravity="center_vertical">
-
+
+
+
+
+
+
+
+
+
+
+
+
+ android:layout_marginBottom="16dp">
+
+
+
+
@@ -88,4 +110,4 @@
-
+
diff --git a/app/src/main/res/layout/singer_music_list_layout.xml b/app/src/main/res/layout/singer_music_list_layout.xml
index 7c3e903..da9b3ac 100644
--- a/app/src/main/res/layout/singer_music_list_layout.xml
+++ b/app/src/main/res/layout/singer_music_list_layout.xml
@@ -6,15 +6,43 @@
android:orientation="vertical"
tools:ignore="MissingDefaultResource">
-
+
+
+
+
+
+
+
+
+
+
+