WIP selector de audios

This commit is contained in:
erik-everardo 2024-02-05 20:54:53 -06:00
parent 835c7304c2
commit c790a0064c
9 changed files with 229 additions and 2 deletions

2
.idea/kotlinc.xml generated
View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="KotlinJpsPluginSettings"> <component name="KotlinJpsPluginSettings">
<option name="version" value="1.8.20" /> <option name="version" value="1.9.0" />
</component> </component>
</project> </project>

View File

@ -41,6 +41,7 @@
<activity android:name=".images.image_chooser.ui.ImageChooserActivity" android:theme="@style/Theme.Isolaatti"/> <activity android:name=".images.image_chooser.ui.ImageChooserActivity" android:theme="@style/Theme.Isolaatti"/>
<activity android:name=".profile.ui.EditProfileActivity" android:theme="@style/Theme.Isolaatti" /> <activity android:name=".profile.ui.EditProfileActivity" android:theme="@style/Theme.Isolaatti" />
<activity android:name=".audio.recorder.ui.AudioRecorderActivity" android:theme="@style/Theme.Isolaatti" /> <activity android:name=".audio.recorder.ui.AudioRecorderActivity" android:theme="@style/Theme.Isolaatti" />
<activity android:name=".audio.audio_selector.ui.AudioSelectorActivity" android:theme="@style/Theme.Isolaatti" />
<provider <provider
android:authorities="com.isolaatti.provider" android:authorities="com.isolaatti.provider"
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"

View File

@ -0,0 +1,85 @@
package com.isolaatti.audio.audio_selector.presentation
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.marginStart
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.divider.MaterialDivider
import com.isolaatti.audio.common.domain.Audio
import com.isolaatti.audio.common.domain.Playable
import com.isolaatti.audio.drafts.domain.AudioDraft
import com.isolaatti.audio.drafts.presentation.AudioDraftsAdapter
import com.isolaatti.databinding.AudioListItemBinding
class AudioSelectorAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
const val TYPE_TITLE = 1
const val TYPE_DIVIDER = 2
const val TYPE_AUDIO = 3
const val TYPE_AUDIO_DRAFT = 4
const val TYPE_UNKNOWN = -1
}
// viewholders
inner class AudioViewHolder(val audioListItemBinding: AudioListItemBinding) : RecyclerView.ViewHolder(audioListItemBinding.root)
inner class TitleViewHolder(val textView: TextView) : RecyclerView.ViewHolder(textView)
inner class DividerViewHolder(val divider: MaterialDivider) : RecyclerView.ViewHolder(divider)
data object Divider
data class TitleItem(val text: String)
private var list: List<Any> = listOf()
fun setList(item: List<Any>) {
}
override fun getItemViewType(position: Int): Int {
return when(list[position]) {
is Divider -> TYPE_DIVIDER
is TitleItem -> TYPE_TITLE
is Audio -> TYPE_AUDIO
is AudioDraft -> TYPE_AUDIO_DRAFT
else -> TYPE_UNKNOWN
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when(viewType) {
TYPE_TITLE -> {
val textView = TextView(parent.context)
TitleViewHolder(textView)
}
TYPE_DIVIDER -> {
DividerViewHolder(MaterialDivider(parent.context))
}
TYPE_AUDIO, TYPE_AUDIO_DRAFT -> {
AudioViewHolder(AudioListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
// this should not enter
else -> {
object: RecyclerView.ViewHolder(LinearLayout(parent.context)){}
}
}
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when(holder) {
is TitleViewHolder -> {
holder.textView.text = (list[position] as TitleItem).text
}
is AudioViewHolder -> {
}
}
}
}

View File

@ -0,0 +1,25 @@
package com.isolaatti.audio.audio_selector.ui
import android.os.Bundle
import com.isolaatti.common.IsolaattiBaseActivity
import com.isolaatti.databinding.ActivityAudioSelectorBinding
class AudioSelectorActivity : IsolaattiBaseActivity() {
companion object {
const val EXTRA_ID = "id"
const val EXTRA_FOR_SQUAD = "forSquad"
const val OUT_EXTRA_PLAYABLE = "playable"
}
private lateinit var binding: ActivityAudioSelectorBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAudioSelectorBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}

View File

@ -0,0 +1,39 @@
package com.isolaatti.audio.audio_selector.ui
import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.activity.result.contract.ActivityResultContract
import com.isolaatti.audio.common.domain.Audio
import com.isolaatti.audio.common.domain.Playable
import java.io.Serializable
/**
* Contract to select audio. Use SelectorConfig class to specify the context to use to select audio.
* Output: if user selected an audio or draft, it will be returned as result. Check type as convenient. Null if user cancelled
*/
class AudioSelectorContract : ActivityResultContract<AudioSelectorContract.SelectorConfig, Playable?>() {
data class SelectorConfig(val forSquad: Boolean, val id: String?): Serializable
override fun createIntent(context: Context, input: SelectorConfig): Intent {
val intent = Intent(context, AudioSelectorActivity::class.java)
intent.apply {
putExtra(AudioSelectorActivity.EXTRA_FOR_SQUAD, input.forSquad)
if(input.forSquad) {
putExtra(AudioSelectorActivity.EXTRA_ID, input.id as String)
}
}
return intent
}
override fun parseResult(resultCode: Int, intent: Intent?): Playable? {
if(resultCode == Activity.RESULT_OK) {
return intent?.extras?.getSerializable(AudioSelectorActivity.OUT_EXTRA_PLAYABLE) as? Playable
}
return null
}
}

View File

@ -15,6 +15,8 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import com.isolaatti.R import com.isolaatti.R
import com.isolaatti.audio.audio_selector.ui.AudioSelectorActivity
import com.isolaatti.audio.audio_selector.ui.AudioSelectorContract
import com.isolaatti.audio.common.domain.Audio import com.isolaatti.audio.common.domain.Audio
import com.isolaatti.audio.common.domain.Playable import com.isolaatti.audio.common.domain.Playable
import com.isolaatti.audio.drafts.domain.AudioDraft import com.isolaatti.audio.drafts.domain.AudioDraft
@ -54,6 +56,10 @@ class MarkdownEditingFragment : Fragment(){
} }
}
private val audioSelectorLauncher = registerForActivityResult(AudioSelectorContract()) {
} }
private val audioListener = object: AudioPlayerConnector.Listener { private val audioListener = object: AudioPlayerConnector.Listener {
@ -142,6 +148,7 @@ class MarkdownEditingFragment : Fragment(){
true true
} }
R.id.select_from_audios -> { R.id.select_from_audios -> {
audioSelectorLauncher.launch(AudioSelectorContract.SelectorConfig(false, null))
true true
} }
else -> false else -> false

View File

@ -0,0 +1,69 @@
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/select_audio"
app:navigationIcon="@drawable/baseline_close_24"
app:layout_constraintTop_toTopOf="parent"/>
<HorizontalScrollView
android:id="@+id/filter_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginHorizontal="8dp">
<com.google.android.material.chip.ChipGroup
android:id="@+id/filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:singleLine="true">
<com.google.android.material.chip.Chip
android:id="@+id/chip_drafts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/drafts"
android:checkable="true"
app:chipIcon="@drawable/baseline_pending_24"/>
<com.google.android.material.chip.Chip
android:id="@+id/chip_audios"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/audios"
android:checkable="true"
app:chipIcon="@drawable/baseline_audio_file_24"/>
<com.google.android.material.chip.Chip
android:id="@+id/sort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sort"
app:chipIcon="@drawable/baseline_sort_24"/>
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_to_refresh"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/filter_container"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -183,4 +183,5 @@
<string name="select_from_existing">Select from existing</string> <string name="select_from_existing">Select from existing</string>
<string name="audio_attachment">Audio attachment</string> <string name="audio_attachment">Audio attachment</string>
<string name="remove">Remove</string> <string name="remove">Remove</string>
<string name="select_audio">Select audio</string>
</resources> </resources>

View File

@ -15,7 +15,7 @@ buildscript {
plugins { plugins {
id 'com.android.application' version '8.2.2' apply false id 'com.android.application' version '8.2.2' apply false
id 'com.android.library' version '8.2.2' apply false id 'com.android.library' version '8.2.2' apply false
id 'org.jetbrains.kotlin.android' version '1.8.0' apply false id 'org.jetbrains.kotlin.android' version '1.9.0' apply false
id 'com.google.dagger.hilt.android' version '2.47' apply false id 'com.google.dagger.hilt.android' version '2.47' apply false
id 'com.google.gms.google-services' version '4.4.0' apply false id 'com.google.gms.google-services' version '4.4.0' apply false
id 'com.google.firebase.crashlytics' version '2.9.9' apply false id 'com.google.firebase.crashlytics' version '2.9.9' apply false