reproduccion de audio en lista de audios y fixes varios
This commit is contained in:
parent
bfa0fdcecf
commit
cd10aced57
@ -16,13 +16,72 @@ class AudiosAdapter(
|
||||
private val onOptionsClick: ((audio: Audio, button: View) -> Boolean)
|
||||
) : RecyclerView.Adapter<AudiosAdapter.AudiosViewHolder>() {
|
||||
|
||||
enum class Payload {
|
||||
PlayStateChanged, IsLoadingChanged
|
||||
}
|
||||
|
||||
private var data: List<Audio> = listOf()
|
||||
private var currentPlaying: Audio? = null
|
||||
|
||||
fun setData(audios: List<Audio>) {
|
||||
data = audios
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun setIsPlaying(isPlaying: Boolean, audio: Audio) {
|
||||
if(audio == currentPlaying) {
|
||||
val index = data.indexOf(audio)
|
||||
if(index == -1) return
|
||||
|
||||
data[index].isPlaying = isPlaying
|
||||
|
||||
notifyItemChanged(index, Payload.PlayStateChanged)
|
||||
return
|
||||
}
|
||||
|
||||
val prevIndex = data.indexOf(currentPlaying)
|
||||
|
||||
if(prevIndex != -1) {
|
||||
data[prevIndex].isPlaying = false
|
||||
notifyItemChanged(prevIndex, Payload.PlayStateChanged)
|
||||
}
|
||||
val newIndex = data.indexOf(audio)
|
||||
if(newIndex != -1) {
|
||||
data[newIndex].isPlaying = isPlaying
|
||||
notifyItemChanged(newIndex, Payload.PlayStateChanged)
|
||||
}
|
||||
|
||||
currentPlaying = audio
|
||||
}
|
||||
|
||||
fun setIsLoadingAudio(isLoading: Boolean, audio: Audio) {
|
||||
if(audio == currentPlaying) {
|
||||
val index = data.indexOf(audio)
|
||||
if(index == -1) return
|
||||
|
||||
data[index].isLoading = isLoading
|
||||
|
||||
notifyItemChanged(index, Payload.IsLoadingChanged)
|
||||
return
|
||||
}
|
||||
val prevIndex = data.indexOf(currentPlaying)
|
||||
|
||||
if(prevIndex != -1) {
|
||||
data[prevIndex].isLoading = false
|
||||
notifyItemChanged(prevIndex, Payload.IsLoadingChanged)
|
||||
}
|
||||
val newIndex = data.indexOf(audio)
|
||||
if(newIndex != -1) {
|
||||
data[newIndex].isLoading = isLoading
|
||||
notifyItemChanged(newIndex, Payload.IsLoadingChanged)
|
||||
}
|
||||
currentPlaying = audio
|
||||
}
|
||||
|
||||
fun updateAudioProgress(total: Int, progress: Int, audio: Audio) {
|
||||
|
||||
}
|
||||
|
||||
inner class AudiosViewHolder(val binding: AudioListItemBinding) : ViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AudiosViewHolder {
|
||||
@ -34,25 +93,53 @@ class AudiosAdapter(
|
||||
return data.size
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: AudiosViewHolder, position: Int) {
|
||||
override fun onBindViewHolder(
|
||||
holder: AudiosViewHolder,
|
||||
position: Int,
|
||||
payloads: MutableList<Any>
|
||||
) {
|
||||
val audio = data[position]
|
||||
if(payloads.isEmpty()) {
|
||||
|
||||
holder.binding.audioName.text = audio.name
|
||||
holder.binding.audioAuthor.text = audio.userName
|
||||
holder.binding.thumbnail.load(audio.thumbnail)
|
||||
|
||||
holder.binding.audioItemOptionsButton.setOnClickListener {
|
||||
onOptionsClick(audio, it)
|
||||
holder.binding.audioName.text = audio.name
|
||||
holder.binding.audioAuthor.text = audio.userName
|
||||
holder.binding.thumbnail.load(audio.thumbnail)
|
||||
|
||||
holder.binding.audioItemOptionsButton.setOnClickListener {
|
||||
onOptionsClick(audio, it)
|
||||
}
|
||||
|
||||
holder.binding.playButton.icon = ResourcesCompat.getDrawable(
|
||||
holder.itemView.resources,
|
||||
if(audio.isPlaying) R.drawable.baseline_pause_24 else R.drawable.baseline_play_arrow_24,
|
||||
null
|
||||
)
|
||||
|
||||
holder.binding.loading.visibility = if(audio.isLoading) View.VISIBLE else View.GONE
|
||||
|
||||
holder.binding.playButton.setOnClickListener {
|
||||
onPlayClick(audio)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
holder.binding.playButton.icon = ResourcesCompat.getDrawable(
|
||||
holder.itemView.resources,
|
||||
if(audio.isPlaying) R.drawable.baseline_pause_24 else R.drawable.baseline_play_arrow_24,
|
||||
null
|
||||
)
|
||||
// only updates play button
|
||||
if(payloads.contains(Payload.PlayStateChanged)) {
|
||||
holder.binding.playButton.icon = ResourcesCompat.getDrawable(
|
||||
holder.itemView.resources,
|
||||
if(audio.isPlaying) R.drawable.baseline_pause_24 else R.drawable.baseline_play_arrow_24,
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
holder.binding.playButton.setOnClickListener {
|
||||
onPlayClick(audio)
|
||||
if(payloads.contains(Payload.IsLoadingChanged)) {
|
||||
holder.binding.loading.visibility = if(audio.isLoading) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: AudiosViewHolder, position: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
@ -8,12 +8,15 @@ import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.isolaatti.R
|
||||
import com.isolaatti.audio.audios_list.presentation.AudiosAdapter
|
||||
import com.isolaatti.audio.audios_list.presentation.AudiosViewModel
|
||||
import com.isolaatti.audio.common.domain.Audio
|
||||
import com.isolaatti.audio.common.domain.Playable
|
||||
import com.isolaatti.audio.player.AudioPlayerConnector
|
||||
import com.isolaatti.common.ErrorMessageViewModel
|
||||
import com.isolaatti.databinding.FragmentAudiosBinding
|
||||
import com.isolaatti.utils.Resource
|
||||
@ -29,6 +32,8 @@ class AudiosFragment : Fragment() {
|
||||
private lateinit var adapter: AudiosAdapter
|
||||
private var privilegedUserId by Delegates.notNull<Int>()
|
||||
|
||||
private lateinit var audioPlayerConnector: AudioPlayerConnector
|
||||
|
||||
private var loadedFirstTime = false
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@ -55,13 +60,44 @@ class AudiosFragment : Fragment() {
|
||||
true
|
||||
}
|
||||
|
||||
private val onAudioPlayClick: ((audio: Audio) -> Unit) = {
|
||||
// Play audio
|
||||
private val onAudioPlayClick: (audio: Audio) -> Unit = {
|
||||
audioPlayerConnector.playPauseAudio(it)
|
||||
}
|
||||
|
||||
private val audioPlayerConnectorListener: AudioPlayerConnector.Listener = object: AudioPlayerConnector.Listener {
|
||||
override fun onPlaying(isPlaying: Boolean, audio: Playable) {
|
||||
if(audio is Audio)
|
||||
adapter.setIsPlaying(isPlaying, audio)
|
||||
}
|
||||
|
||||
override fun isLoading(isLoading: Boolean, audio: Playable) {
|
||||
if(audio is Audio)
|
||||
adapter.setIsLoadingAudio(isLoading, audio)
|
||||
}
|
||||
|
||||
override fun progressChanged(second: Int, audio: Playable) {
|
||||
|
||||
}
|
||||
|
||||
override fun durationChanged(duration: Int, audio: Playable) {
|
||||
|
||||
}
|
||||
|
||||
override fun onEnded(audio: Playable) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
audioPlayerConnector = AudioPlayerConnector(requireContext())
|
||||
|
||||
audioPlayerConnector.addListener(audioPlayerConnectorListener)
|
||||
|
||||
viewLifecycleOwner.lifecycle.addObserver(audioPlayerConnector)
|
||||
|
||||
adapter = AudiosAdapter(onPlayClick = onAudioPlayClick, onOptionsClick = onOptionsClick)
|
||||
|
||||
viewBinding.recyclerAudios.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
|
||||
@ -73,6 +109,10 @@ class AudiosFragment : Fragment() {
|
||||
privilegedUserId = arguments.sourceId.toInt()
|
||||
viewModel.loadAudios(privilegedUserId)
|
||||
}
|
||||
|
||||
viewBinding.topAppBar.setNavigationOnClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupObservers() {
|
||||
@ -94,7 +134,7 @@ class AudiosFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
const val SOURCE_PROFILE = "source_profile"
|
||||
const val SOURCE_SQUAD = "source_squads"
|
||||
|
||||
@ -5,6 +5,7 @@ import android.net.Uri
|
||||
abstract class Playable {
|
||||
var isPlaying: Boolean = false
|
||||
abstract val uri: Uri
|
||||
var isLoading: Boolean = false
|
||||
|
||||
/**
|
||||
* Image url, null indicating no image should be shown
|
||||
@ -26,5 +27,4 @@ abstract class Playable {
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -22,7 +22,7 @@ class AudioDraftsRepositoryImpl(private val audiosDraftsDao: AudiosDraftsDao) :
|
||||
}
|
||||
|
||||
override fun deleteDrafts(draftIds: LongArray): Flow<Boolean> = flow {
|
||||
val drafts = audiosDraftsDao.getAudioDraftsByIds(draftIds)
|
||||
val drafts = audiosDraftsDao.getAudioDraftsByIds(*draftIds)
|
||||
audiosDraftsDao.deleteDrafts(drafts)
|
||||
|
||||
try {
|
||||
|
||||
@ -9,20 +9,20 @@ import androidx.room.Update
|
||||
@Dao
|
||||
interface AudiosDraftsDao {
|
||||
@Insert
|
||||
suspend fun insertAudioDraft(audioDraftEntity: AudioDraftEntity): Long
|
||||
fun insertAudioDraft(audioDraftEntity: AudioDraftEntity): Long
|
||||
|
||||
@Query("SELECT * FROM audio_drafts WHERE id = :draftId")
|
||||
suspend fun getAudioDraftById(draftId: Long): AudioDraftEntity?
|
||||
fun getAudioDraftById(draftId: Long): AudioDraftEntity?
|
||||
|
||||
@Query("SELECT * FROM audio_drafts WHERE id in (:draftId)")
|
||||
suspend fun getAudioDraftsByIds(draftId: LongArray): Array<AudioDraftEntity>
|
||||
fun getAudioDraftsByIds(vararg draftId: Long): Array<AudioDraftEntity>
|
||||
|
||||
@Query("SELECT * FROM audio_drafts ORDER BY id DESC")
|
||||
suspend fun getDrafts(): List<AudioDraftEntity>
|
||||
fun getDrafts(): List<AudioDraftEntity>
|
||||
|
||||
@Delete
|
||||
suspend fun deleteDrafts(draft: Array<AudioDraftEntity>)
|
||||
fun deleteDrafts(draft: Array<AudioDraftEntity>)
|
||||
|
||||
@Query("UPDATE audio_drafts SET name = :name WHERE id = :id")
|
||||
suspend fun renameDraft(id: Long, name: String): Int
|
||||
fun renameDraft(id: Long, name: String): Int
|
||||
}
|
||||
@ -12,8 +12,8 @@ interface KeyValueDao {
|
||||
fun getValue(key: String): Flow<String>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun setValue(entity: KeyValueEntity)
|
||||
fun setValue(entity: KeyValueEntity)
|
||||
|
||||
@Query("SELECT value FROM key_values WHERE id = :key")
|
||||
suspend fun getValueAsync(key: String): String?
|
||||
fun getValueAsync(key: String): String?
|
||||
}
|
||||
@ -12,6 +12,18 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:visibility="gone"
|
||||
android:translationZ="5dp"
|
||||
app:layout_constraintTop_toTopOf="@id/play_button"
|
||||
app:layout_constraintBottom_toBottomOf="@id/play_button"
|
||||
app:layout_constraintStart_toStartOf="@id/play_button"
|
||||
app:layout_constraintEnd_toEndOf="@id/play_button"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/play_button"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user