WIP
This commit is contained in:
parent
96fd70556b
commit
3ff49d73ce
@ -3,14 +3,16 @@ package com.isolaatti.audio.audios_list.presentation
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||
import coil.load
|
||||
import com.isolaatti.R
|
||||
import com.isolaatti.audio.common.domain.Audio
|
||||
import com.isolaatti.databinding.AudioListItemBinding
|
||||
|
||||
class AudiosAdapter(
|
||||
private val onClick: ((audio: Audio) -> Unit),
|
||||
private val onPlayClick: ((audio: Audio) -> Unit),
|
||||
private val onOptionsClick: ((audio: Audio, button: View) -> Boolean)
|
||||
) : RecyclerView.Adapter<AudiosAdapter.AudiosViewHolder>() {
|
||||
|
||||
@ -39,12 +41,18 @@ class AudiosAdapter(
|
||||
holder.binding.audioAuthor.text = audio.userName
|
||||
holder.binding.thumbnail.load(audio.thumbnail)
|
||||
|
||||
holder.binding.root.setOnClickListener {
|
||||
onClick(audio)
|
||||
}
|
||||
|
||||
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.playButton.setOnClickListener {
|
||||
onPlayClick(audio)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -18,6 +18,7 @@ import com.isolaatti.common.ErrorMessageViewModel
|
||||
import com.isolaatti.databinding.FragmentAudiosBinding
|
||||
import com.isolaatti.utils.Resource
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
@AndroidEntryPoint
|
||||
class AudiosFragment : Fragment() {
|
||||
@ -26,6 +27,7 @@ class AudiosFragment : Fragment() {
|
||||
private val errorViewModel: ErrorMessageViewModel by activityViewModels()
|
||||
private val arguments: AudiosFragmentArgs by navArgs()
|
||||
private lateinit var adapter: AudiosAdapter
|
||||
private var privilegedUserId by Delegates.notNull<Int>()
|
||||
|
||||
private var loadedFirstTime = false
|
||||
override fun onCreateView(
|
||||
@ -42,20 +44,25 @@ class AudiosFragment : Fragment() {
|
||||
val popup = PopupMenu(requireContext(), button)
|
||||
popup.menuInflater.inflate(R.menu.audio_item_menu, popup.menu)
|
||||
|
||||
if(audio.userId != privilegedUserId) {
|
||||
popup.menu.removeItem(R.id.rename_item)
|
||||
popup.menu.removeItem(R.id.delete_item)
|
||||
popup.menu.removeItem(R.id.set_as_profile_audio)
|
||||
}
|
||||
|
||||
popup.show()
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
private val onAudioClick: ((audio: Audio) -> Unit) = {
|
||||
private val onAudioPlayClick: ((audio: Audio) -> Unit) = {
|
||||
// Play audio
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
adapter = AudiosAdapter(onClick = onAudioClick, onOptionsClick = onOptionsClick)
|
||||
adapter = AudiosAdapter(onPlayClick = onAudioPlayClick, onOptionsClick = onOptionsClick)
|
||||
|
||||
viewBinding.recyclerAudios.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
|
||||
viewBinding.recyclerAudios.adapter = adapter
|
||||
@ -63,7 +70,8 @@ class AudiosFragment : Fragment() {
|
||||
|
||||
setupObservers()
|
||||
if(arguments.source == SOURCE_PROFILE) {
|
||||
viewModel.loadAudios(arguments.sourceId.toInt())
|
||||
privilegedUserId = arguments.sourceId.toInt()
|
||||
viewModel.loadAudios(privilegedUserId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.isolaatti.audio.common.domain
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.core.net.toUri
|
||||
import com.isolaatti.audio.common.data.AudioDto
|
||||
import com.isolaatti.common.Ownable
|
||||
import com.isolaatti.connectivity.RetrofitClient.Companion.BASE_URL
|
||||
@ -13,17 +15,16 @@ data class Audio(
|
||||
val creationTime: ZonedDateTime,
|
||||
override val userId: Int,
|
||||
val userName: String
|
||||
): Ownable, Serializable {
|
||||
var playing: Boolean = false
|
||||
val downloadUrl: String get() {
|
||||
return "${BASE_URL}audios/$id.webm"
|
||||
): Ownable, Playable(), Serializable {
|
||||
|
||||
override val uri: Uri get() {
|
||||
return "${BASE_URL}audios/$id.webm".toUri()
|
||||
}
|
||||
|
||||
val thumbnail: String get() {
|
||||
override val thumbnail: String get() {
|
||||
return UrlGen.userProfileImage(userId)
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
fun fromDto(audioDto: AudioDto): Audio {
|
||||
return Audio(
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
package com.isolaatti.audio.common.domain
|
||||
|
||||
import android.net.Uri
|
||||
|
||||
abstract class Playable {
|
||||
var isPlaying: Boolean = false
|
||||
abstract val uri: Uri
|
||||
|
||||
/**
|
||||
* Image url, null indicating no image should be shown
|
||||
*/
|
||||
abstract val thumbnail: String?
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package com.isolaatti.audio.recorder.data
|
||||
package com.isolaatti.audio.drafts.data
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
@ -1,4 +1,4 @@
|
||||
package com.isolaatti.audio.recorder.data
|
||||
package com.isolaatti.audio.drafts.data
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
@ -0,0 +1,18 @@
|
||||
package com.isolaatti.audio.drafts.domain
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.core.net.toUri
|
||||
import com.isolaatti.MyApplication
|
||||
import com.isolaatti.audio.common.domain.Playable
|
||||
import java.io.File
|
||||
|
||||
data class AudioDraft(val id: Long, val name: String, val localStorageRelativePath: String) : Playable() {
|
||||
override val thumbnail: String?
|
||||
get() = null
|
||||
|
||||
override val uri: Uri
|
||||
get() {
|
||||
val appFiles = MyApplication.myApp.applicationContext.filesDir
|
||||
return File(appFiles, localStorageRelativePath).toUri()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package com.isolaatti.audio.drafts.presentation
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||
import com.isolaatti.R
|
||||
import com.isolaatti.audio.drafts.domain.AudioDraft
|
||||
import com.isolaatti.databinding.AudioListItemBinding
|
||||
|
||||
class AudioDraftsAdapter(
|
||||
private val onOptionsClicked: (item: AudioDraft, view: View) -> Unit = { _,_ -> },
|
||||
private val onPlayClicked: (item: AudioDraft , view: View) -> Unit = { _,_ -> },
|
||||
private val onItemClicked: (item: AudioDraft , view: View) -> Unit = { _,_ -> }
|
||||
) : ListAdapter<AudioDraft, AudioDraftsAdapter.AudioDraftViewHolder>(diffCallback) {
|
||||
inner class AudioDraftViewHolder(val audioListItemBinding: AudioListItemBinding) : ViewHolder(audioListItemBinding.root)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AudioDraftViewHolder {
|
||||
return AudioDraftViewHolder(
|
||||
AudioListItemBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: AudioDraftViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
holder.audioListItemBinding.apply {
|
||||
audioName.text = item.name
|
||||
audioItemOptionsButton.setOnClickListener { onOptionsClicked(item, it) }
|
||||
playButton.icon = ResourcesCompat.getDrawable(
|
||||
holder.itemView.resources,
|
||||
if(item.isPlaying) R.drawable.baseline_pause_24 else R.drawable.baseline_play_arrow_24,
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val diffCallback = object: DiffUtil.ItemCallback<AudioDraft>() {
|
||||
override fun areItemsTheSame(oldItem: AudioDraft, newItem: AudioDraft): Boolean {
|
||||
return oldItem.id == newItem.id
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: AudioDraft, newItem: AudioDraft): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
package com.isolaatti.audio.drafts.presentation
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
class AudioDraftsViewModel : ViewModel() {
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.isolaatti.audio.drafts.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.isolaatti.audio.drafts.domain.AudioDraft
|
||||
import com.isolaatti.audio.drafts.presentation.AudioDraftsAdapter
|
||||
import com.isolaatti.audio.drafts.presentation.AudioDraftsViewModel
|
||||
import com.isolaatti.databinding.FragmentAudioDraftsBinding
|
||||
|
||||
class AudioDraftsFragment : Fragment() {
|
||||
private lateinit var binding: FragmentAudioDraftsBinding
|
||||
private val viewModel: AudioDraftsViewModel by viewModels()
|
||||
|
||||
private var adapter: AudioDraftsAdapter? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = FragmentAudioDraftsBinding.inflate(inflater)
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
adapter = AudioDraftsAdapter(
|
||||
onPlayClicked = { item: AudioDraft, view: View ->
|
||||
|
||||
|
||||
},
|
||||
onOptionsClicked = { item, button ->
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
binding.recycler.adapter = adapter
|
||||
binding.recycler.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -157,7 +157,7 @@ class AudioPlayerConnector(
|
||||
return
|
||||
}
|
||||
this.audio = audio
|
||||
mediaItem = MediaItem.fromUri(Uri.parse(audio.downloadUrl))
|
||||
mediaItem = MediaItem.fromUri(audio.uri)
|
||||
|
||||
player?.setMediaItem(mediaItem!!)
|
||||
}
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
package com.isolaatti.audio.recorder.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
class AudioDraftsFragment : Fragment() {
|
||||
|
||||
}
|
||||
@ -2,8 +2,8 @@ package com.isolaatti.database
|
||||
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import com.isolaatti.audio.recorder.data.AudioDraftEntity
|
||||
import com.isolaatti.audio.recorder.data.AudiosDraftsDao
|
||||
import com.isolaatti.audio.drafts.data.AudioDraftEntity
|
||||
import com.isolaatti.audio.drafts.data.AudiosDraftsDao
|
||||
import com.isolaatti.auth.data.local.UserInfoDao
|
||||
import com.isolaatti.auth.data.local.UserInfoEntity
|
||||
import com.isolaatti.settings.data.KeyValueDao
|
||||
|
||||
@ -11,12 +11,23 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/play_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
android:layout_marginStart="4dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/thumbnail"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_margin="16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="4dp"
|
||||
app:layout_constraintStart_toEndOf="@id/play_button"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
tools:src="@drawable/baseline_image_24" />
|
||||
|
||||
11
app/src/main/res/layout/fragment_audio_drafts.xml
Normal file
11
app/src/main/res/layout/fragment_audio_drafts.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@ -6,4 +6,12 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:title="@string/delete" />
|
||||
|
||||
<item
|
||||
android:id="@+id/rename_item"
|
||||
android:title="@string/rename"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/set_as_profile_audio"
|
||||
android:title="@string/set_as_profile_audio"/>
|
||||
</menu>
|
||||
@ -177,4 +177,6 @@
|
||||
<string name="recover_password">Recover password</string>
|
||||
<string name="old_password_not_correct">Password not changed, old password did not match. If you don\'t remember your password, you can always recover it.</string>
|
||||
<string name="new_password_is_invalid">New password is invalid. Please check it meets the requirements</string>
|
||||
<string name="rename">Rename</string>
|
||||
<string name="set_as_profile_audio">Set as profile audio</string>
|
||||
</resources>
|
||||
Loading…
x
Reference in New Issue
Block a user