diff --git a/app/src/main/java/com/isolaatti/audio/audios_list/presentation/AudiosAdapter.kt b/app/src/main/java/com/isolaatti/audio/audios_list/presentation/AudiosAdapter.kt index 9fdbd9c..867db7e 100644 --- a/app/src/main/java/com/isolaatti/audio/audios_list/presentation/AudiosAdapter.kt +++ b/app/src/main/java/com/isolaatti/audio/audios_list/presentation/AudiosAdapter.kt @@ -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() { @@ -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) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/isolaatti/audio/audios_list/ui/AudiosFragment.kt b/app/src/main/java/com/isolaatti/audio/audios_list/ui/AudiosFragment.kt index 84dd772..a12ff31 100644 --- a/app/src/main/java/com/isolaatti/audio/audios_list/ui/AudiosFragment.kt +++ b/app/src/main/java/com/isolaatti/audio/audios_list/ui/AudiosFragment.kt @@ -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() 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) } } diff --git a/app/src/main/java/com/isolaatti/audio/common/domain/Audio.kt b/app/src/main/java/com/isolaatti/audio/common/domain/Audio.kt index 59b69f5..72c91d9 100644 --- a/app/src/main/java/com/isolaatti/audio/common/domain/Audio.kt +++ b/app/src/main/java/com/isolaatti/audio/common/domain/Audio.kt @@ -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( diff --git a/app/src/main/java/com/isolaatti/audio/common/domain/Playable.kt b/app/src/main/java/com/isolaatti/audio/common/domain/Playable.kt new file mode 100644 index 0000000..9d91f1e --- /dev/null +++ b/app/src/main/java/com/isolaatti/audio/common/domain/Playable.kt @@ -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? +} \ No newline at end of file diff --git a/app/src/main/java/com/isolaatti/audio/recorder/data/AudioDraftEntity.kt b/app/src/main/java/com/isolaatti/audio/drafts/data/AudioDraftEntity.kt similarity index 83% rename from app/src/main/java/com/isolaatti/audio/recorder/data/AudioDraftEntity.kt rename to app/src/main/java/com/isolaatti/audio/drafts/data/AudioDraftEntity.kt index 50f2b8f..4bb9980 100644 --- a/app/src/main/java/com/isolaatti/audio/recorder/data/AudioDraftEntity.kt +++ b/app/src/main/java/com/isolaatti/audio/drafts/data/AudioDraftEntity.kt @@ -1,4 +1,4 @@ -package com.isolaatti.audio.recorder.data +package com.isolaatti.audio.drafts.data import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/app/src/main/java/com/isolaatti/audio/recorder/data/AudiosDraftsDao.kt b/app/src/main/java/com/isolaatti/audio/drafts/data/AudiosDraftsDao.kt similarity index 93% rename from app/src/main/java/com/isolaatti/audio/recorder/data/AudiosDraftsDao.kt rename to app/src/main/java/com/isolaatti/audio/drafts/data/AudiosDraftsDao.kt index 0b73993..bcea2f8 100644 --- a/app/src/main/java/com/isolaatti/audio/recorder/data/AudiosDraftsDao.kt +++ b/app/src/main/java/com/isolaatti/audio/drafts/data/AudiosDraftsDao.kt @@ -1,4 +1,4 @@ -package com.isolaatti.audio.recorder.data +package com.isolaatti.audio.drafts.data import androidx.room.Dao import androidx.room.Delete diff --git a/app/src/main/java/com/isolaatti/audio/drafts/domain/AudioDraft.kt b/app/src/main/java/com/isolaatti/audio/drafts/domain/AudioDraft.kt new file mode 100644 index 0000000..2a23594 --- /dev/null +++ b/app/src/main/java/com/isolaatti/audio/drafts/domain/AudioDraft.kt @@ -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() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/isolaatti/audio/drafts/presentation/AudioDraftsAdapter.kt b/app/src/main/java/com/isolaatti/audio/drafts/presentation/AudioDraftsAdapter.kt new file mode 100644 index 0000000..2985e66 --- /dev/null +++ b/app/src/main/java/com/isolaatti/audio/drafts/presentation/AudioDraftsAdapter.kt @@ -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(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() { + override fun areItemsTheSame(oldItem: AudioDraft, newItem: AudioDraft): Boolean { + return oldItem.id == newItem.id + } + + override fun areContentsTheSame(oldItem: AudioDraft, newItem: AudioDraft): Boolean { + return oldItem == newItem + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/isolaatti/audio/drafts/presentation/AudioDraftsViewModel.kt b/app/src/main/java/com/isolaatti/audio/drafts/presentation/AudioDraftsViewModel.kt new file mode 100644 index 0000000..e562f97 --- /dev/null +++ b/app/src/main/java/com/isolaatti/audio/drafts/presentation/AudioDraftsViewModel.kt @@ -0,0 +1,6 @@ +package com.isolaatti.audio.drafts.presentation + +import androidx.lifecycle.ViewModel + +class AudioDraftsViewModel : ViewModel() { +} \ No newline at end of file diff --git a/app/src/main/java/com/isolaatti/audio/drafts/ui/AudioDraftsFragment.kt b/app/src/main/java/com/isolaatti/audio/drafts/ui/AudioDraftsFragment.kt new file mode 100644 index 0000000..2e14965 --- /dev/null +++ b/app/src/main/java/com/isolaatti/audio/drafts/ui/AudioDraftsFragment.kt @@ -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) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/isolaatti/audio/player/AudioPlayerConnector.kt b/app/src/main/java/com/isolaatti/audio/player/AudioPlayerConnector.kt index 6a9d06f..ae8a147 100644 --- a/app/src/main/java/com/isolaatti/audio/player/AudioPlayerConnector.kt +++ b/app/src/main/java/com/isolaatti/audio/player/AudioPlayerConnector.kt @@ -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!!) } diff --git a/app/src/main/java/com/isolaatti/audio/recorder/ui/AudioDraftsFragment.kt b/app/src/main/java/com/isolaatti/audio/recorder/ui/AudioDraftsFragment.kt deleted file mode 100644 index b6595b0..0000000 --- a/app/src/main/java/com/isolaatti/audio/recorder/ui/AudioDraftsFragment.kt +++ /dev/null @@ -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() { - -} \ No newline at end of file diff --git a/app/src/main/java/com/isolaatti/database/AppDatabase.kt b/app/src/main/java/com/isolaatti/database/AppDatabase.kt index 3ab3d6a..f61333b 100644 --- a/app/src/main/java/com/isolaatti/database/AppDatabase.kt +++ b/app/src/main/java/com/isolaatti/database/AppDatabase.kt @@ -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 diff --git a/app/src/main/res/layout/audio_list_item.xml b/app/src/main/res/layout/audio_list_item.xml index e1381aa..2840759 100644 --- a/app/src/main/res/layout/audio_list_item.xml +++ b/app/src/main/res/layout/audio_list_item.xml @@ -11,12 +11,23 @@ + + + diff --git a/app/src/main/res/layout/fragment_audio_drafts.xml b/app/src/main/res/layout/fragment_audio_drafts.xml new file mode 100644 index 0000000..fc9f6d7 --- /dev/null +++ b/app/src/main/res/layout/fragment_audio_drafts.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/audio_item_menu.xml b/app/src/main/res/menu/audio_item_menu.xml index 4745922..fa19d8f 100644 --- a/app/src/main/res/menu/audio_item_menu.xml +++ b/app/src/main/res/menu/audio_item_menu.xml @@ -6,4 +6,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:title="@string/delete" /> + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c6a6d61..8a7afa4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -177,4 +177,6 @@ Recover password Password not changed, old password did not match. If you don\'t remember your password, you can always recover it. New password is invalid. Please check it meets the requirements + Rename + Set as profile audio \ No newline at end of file