diff --git a/core/domain/src/main/kotlin/org/moire/ultrasonic/domain/PodcastsChannel.kt b/core/domain/src/main/kotlin/org/moire/ultrasonic/domain/PodcastsChannel.kt index 5eed9886..8f76fb47 100644 --- a/core/domain/src/main/kotlin/org/moire/ultrasonic/domain/PodcastsChannel.kt +++ b/core/domain/src/main/kotlin/org/moire/ultrasonic/domain/PodcastsChannel.kt @@ -7,7 +7,8 @@ data class PodcastsChannel( val title: String?, val url: String?, val description: String?, - val status: String? + val status: String?, + val coverArt: String? = null ) : GenericEntry(), Serializable { companion object { diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/adapters/PodcastChannelRowBinder.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/adapters/PodcastChannelRowBinder.kt new file mode 100644 index 00000000..49608e3c --- /dev/null +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/adapters/PodcastChannelRowBinder.kt @@ -0,0 +1,50 @@ +/* + * PodcastChannelRowBinder.kt + * Copyright (C) 2009-2026 Ultrasonic developers + * + * Distributed under terms of the GNU GPLv3 license. + */ + +package org.moire.ultrasonic.adapters + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.core.view.isGone +import com.drakeet.multitype.ItemViewBinder +import org.moire.ultrasonic.R +import org.moire.ultrasonic.domain.PodcastsChannel +import org.moire.ultrasonic.subsonic.ImageLoaderProvider +import org.moire.ultrasonic.util.FileUtil + +class PodcastChannelRowBinder( + private val onItemClick: (PodcastsChannel) -> Unit, + private val imageLoaderProvider: ImageLoaderProvider +) : ItemViewBinder() { + + override fun onBindViewHolder(holder: AlbumRowDelegate.ListViewHolder, item: PodcastsChannel) { + holder.album.text = item.title + holder.artist.text = item.url + holder.star.isGone = true + holder.details.setOnClickListener { onItemClick(item) } + holder.coverArt.setOnClickListener { onItemClick(item) } + + if (item.coverArt != null) { + imageLoaderProvider.executeOn { + it.loadImage( + holder.coverArt, + item.coverArt, + FileUtil.getArtistArtKey(item.title, false), + false, + 0 + ) + } + } else { + holder.coverArt.setImageResource(R.drawable.unknown_album) + } + } + + override fun onCreateViewHolder( + inflater: LayoutInflater, + parent: ViewGroup + ): AlbumRowDelegate.ListViewHolder = AlbumRowDelegate.ListViewHolder(parent, inflater) +} diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIPodcastConverter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIPodcastConverter.kt index e0f9c2fa..41079706 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIPodcastConverter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/domain/APIPodcastConverter.kt @@ -11,7 +11,8 @@ fun PodcastChannel.toDomainEntity(): PodcastsChannel = PodcastsChannel( this.title, this.url, this.description, - this.status + this.status, + this.coverArt.ifEmpty { null } ) fun List.toDomainEntitiesList(): List = this diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/PodcastFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/PodcastFragment.kt index 2b1eb026..f592cfff 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/PodcastFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/PodcastFragment.kt @@ -12,12 +12,10 @@ import android.view.MenuItem import android.view.View import androidx.lifecycle.LiveData import androidx.navigation.fragment.findNavController -import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel import org.moire.ultrasonic.NavigationGraphDirections import org.moire.ultrasonic.R -import org.moire.ultrasonic.adapters.PopupMenuFactory -import org.moire.ultrasonic.adapters.TextRowBinder +import org.moire.ultrasonic.adapters.PodcastChannelRowBinder import org.moire.ultrasonic.domain.PodcastsChannel import org.moire.ultrasonic.fragment.FragmentTitle.setTitle import org.moire.ultrasonic.model.PodcastListModel @@ -27,8 +25,6 @@ import org.moire.ultrasonic.model.PodcastListModel */ class PodcastFragment : MultiListFragment() { - private val popupMenuFactory: PopupMenuFactory by inject() - /** * The ViewModel to use to get the data */ @@ -53,11 +49,9 @@ class PodcastFragment : MultiListFragment() { viewAdapter.register( PodcastsChannel::class.java, - TextRowBinder( - textResolver = { it.title }, + PodcastChannelRowBinder( onItemClick = { onItemClick(it) }, - onContextMenuItemClick = { _, _ -> false }, - popupMenuFactory = popupMenuFactory + imageLoaderProvider = imageLoaderProvider ) ) } diff --git a/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIPodcastConverterTest.kt b/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIPodcastConverterTest.kt index ec997c43..5a4cf502 100644 --- a/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIPodcastConverterTest.kt +++ b/ultrasonic/src/test/kotlin/org/moire/ultrasonic/domain/APIPodcastConverterTest.kt @@ -31,9 +31,16 @@ class APIPodcastConverterTest { status `should be equal to` entity.status title `should be equal to` entity.title url `should be equal to` entity.url + coverArt `should be equal to` entity.coverArt } } + @Test + fun `Should map empty coverArt to null`() { + val entity = PodcastChannel(id = "1", coverArt = "") + entity.toDomainEntity().coverArt `should be equal to` null + } + @Test fun `Should convert list of podcasts channels to domain entites list`() { val entitiesList = listOf(