WIP audios
This commit is contained in:
parent
a1c8b49607
commit
0322f79579
24
app/src/main/java/com/isolaatti/audio/Module.kt
Normal file
24
app/src/main/java/com/isolaatti/audio/Module.kt
Normal file
@ -0,0 +1,24 @@
|
||||
package com.isolaatti.audio
|
||||
|
||||
import com.isolaatti.audio.common.data.AudiosApi
|
||||
import com.isolaatti.audio.common.data.AudiosRepositoryImpl
|
||||
import com.isolaatti.audio.common.domain.AudiosRepository
|
||||
import com.isolaatti.connectivity.RetrofitClient
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class Module {
|
||||
@Provides
|
||||
fun provideAudiosApi(retrofitClient: RetrofitClient): AudiosApi {
|
||||
return retrofitClient.client.create(AudiosApi::class.java)
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideAudiosRepository(audiosApi: AudiosApi): AudiosRepository {
|
||||
return AudiosRepositoryImpl(audiosApi)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.isolaatti.audio.audios_list.presentation
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||
import coil.load
|
||||
import com.isolaatti.audio.common.domain.Audio
|
||||
import com.isolaatti.databinding.AudioListItemBinding
|
||||
|
||||
class AudiosAdapter(
|
||||
private val onClick: ((audio: Audio) -> Unit),
|
||||
private val onOptionsClick: ((audio: Audio, button: View) -> Boolean)
|
||||
) : RecyclerView.Adapter<AudiosAdapter.AudiosViewHolder>() {
|
||||
|
||||
private var data: List<Audio> = listOf()
|
||||
|
||||
fun setData(audios: List<Audio>) {
|
||||
data = audios
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
inner class AudiosViewHolder(val binding: AudioListItemBinding) : ViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AudiosViewHolder {
|
||||
val binding = AudioListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return AudiosViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return data.size
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: AudiosViewHolder, position: Int) {
|
||||
val audio = data[position]
|
||||
|
||||
holder.binding.audioName.text = audio.name
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.isolaatti.audio.audios_list.presentation
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.isolaatti.audio.common.domain.Audio
|
||||
import com.isolaatti.audio.common.domain.AudiosRepository
|
||||
import com.isolaatti.utils.Resource
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class AudiosViewModel @Inject constructor(private val audiosRepository: AudiosRepository) : ViewModel() {
|
||||
val resource: MutableLiveData<Resource<List<Audio>>> = MutableLiveData()
|
||||
|
||||
|
||||
fun loadAudios(userId: Int) {
|
||||
viewModelScope.launch {
|
||||
audiosRepository.getAudiosOfUser(userId, null).onEach {
|
||||
resource.postValue(it)
|
||||
|
||||
}.flowOn(Dispatchers.IO).launchIn(this)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
package com.isolaatti.audio.audios_list.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.fragment.app.viewModels
|
||||
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.common.ErrorMessageViewModel
|
||||
import com.isolaatti.databinding.FragmentAudiosBinding
|
||||
import com.isolaatti.utils.Resource
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class AudiosFragment : Fragment() {
|
||||
lateinit var viewBinding: FragmentAudiosBinding
|
||||
private val viewModel: AudiosViewModel by viewModels()
|
||||
private val errorViewModel: ErrorMessageViewModel by activityViewModels()
|
||||
private val arguments: AudiosFragmentArgs by navArgs()
|
||||
private lateinit var adapter: AudiosAdapter
|
||||
|
||||
private var loadedFirstTime = false
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
viewBinding = FragmentAudiosBinding.inflate(inflater)
|
||||
|
||||
return viewBinding.root
|
||||
}
|
||||
|
||||
private val onOptionsClick: ((audio: Audio, button: View) -> Boolean) = { audio, button ->
|
||||
val popup = PopupMenu(requireContext(), button)
|
||||
popup.menuInflater.inflate(R.menu.audio_item_menu, popup.menu)
|
||||
|
||||
|
||||
popup.show()
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
private val onAudioClick: ((audio: Audio) -> Unit) = {
|
||||
// Play audio
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
adapter = AudiosAdapter(onClick = onAudioClick, onOptionsClick = onOptionsClick)
|
||||
|
||||
viewBinding.recyclerAudios.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
|
||||
viewBinding.recyclerAudios.adapter = adapter
|
||||
|
||||
|
||||
setupObservers()
|
||||
if(arguments.source == SOURCE_PROFILE) {
|
||||
viewModel.loadAudios(arguments.sourceId.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupObservers() {
|
||||
viewModel.resource.observe(viewLifecycleOwner) { resource ->
|
||||
when(resource) {
|
||||
is Resource.Error -> {
|
||||
errorViewModel.error.postValue(resource.errorType)
|
||||
}
|
||||
is Resource.Loading -> {
|
||||
if(!loadedFirstTime) {
|
||||
viewBinding.progressBarLoading.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
is Resource.Success -> {
|
||||
viewBinding.progressBarLoading.visibility = View.GONE
|
||||
loadedFirstTime = true
|
||||
adapter.setData(resource.data!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val SOURCE_PROFILE = "source_profile"
|
||||
const val SOURCE_SQUAD = "source_squads"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.isolaatti.audio.common.data
|
||||
|
||||
import java.time.ZonedDateTime
|
||||
|
||||
data class AudiosDto(val data: List<AudioDto>)
|
||||
data class AudioDto(
|
||||
val id: String,
|
||||
val name: String,
|
||||
val creationTime: ZonedDateTime,
|
||||
val userId: Int,
|
||||
val firestoreObjectPath: String,
|
||||
val userName: String
|
||||
)
|
||||
@ -0,0 +1,11 @@
|
||||
package com.isolaatti.audio.common.data
|
||||
|
||||
import retrofit2.Call
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface AudiosApi {
|
||||
@GET("/api/Audios/OfUser/{userId}")
|
||||
fun getAudiosOfUser(@Path("userId") userId: Int, @Query("lastAudioId") lastAudioId: String?): Call<AudiosDto>
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.isolaatti.audio.common.data
|
||||
|
||||
import android.util.Log
|
||||
import com.isolaatti.audio.common.domain.Audio
|
||||
import com.isolaatti.audio.common.domain.AudiosRepository
|
||||
import com.isolaatti.utils.Resource
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import retrofit2.awaitResponse
|
||||
import javax.inject.Inject
|
||||
|
||||
class AudiosRepositoryImpl @Inject constructor(private val audiosApi: AudiosApi) : AudiosRepository {
|
||||
override fun getAudiosOfUser(userId: Int, lastId: String?): Flow<Resource<List<Audio>>> = flow {
|
||||
emit(Resource.Loading())
|
||||
try {
|
||||
val response = audiosApi.getAudiosOfUser(userId, lastId).awaitResponse()
|
||||
|
||||
if(response.isSuccessful) {
|
||||
val body = response.body()
|
||||
if(body == null) {
|
||||
emit(Resource.Error(Resource.Error.ErrorType.ServerError))
|
||||
return@flow
|
||||
}
|
||||
|
||||
emit(Resource.Success(body.data.map { Audio.fromDto(it) }))
|
||||
}
|
||||
} catch(e: Exception) {
|
||||
Log.e("AudiosRepositoryImpl", e.message.toString())
|
||||
emit(Resource.Error(Resource.Error.ErrorType.NetworkError))
|
||||
}
|
||||
}
|
||||
}
|
||||
37
app/src/main/java/com/isolaatti/audio/common/domain/Audio.kt
Normal file
37
app/src/main/java/com/isolaatti/audio/common/domain/Audio.kt
Normal file
@ -0,0 +1,37 @@
|
||||
package com.isolaatti.audio.common.domain
|
||||
|
||||
import com.isolaatti.audio.common.data.AudioDto
|
||||
import com.isolaatti.common.Ownable
|
||||
import com.isolaatti.connectivity.RetrofitClient.Companion.BASE_URL
|
||||
import com.isolaatti.utils.UrlGen
|
||||
import java.time.ZonedDateTime
|
||||
|
||||
data class Audio(
|
||||
val id: String,
|
||||
val name: String,
|
||||
val creationTime: ZonedDateTime,
|
||||
override val userId: Int,
|
||||
val userName: String
|
||||
): Ownable {
|
||||
var playing: Boolean = false
|
||||
val downloadUrl: String get() {
|
||||
return "${BASE_URL}/$id"
|
||||
}
|
||||
|
||||
val thumbnail: String get() {
|
||||
return UrlGen.userProfileImage(userId)
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
fun fromDto(audioDto: AudioDto): Audio {
|
||||
return Audio(
|
||||
id = audioDto.id,
|
||||
name = audioDto.name,
|
||||
creationTime = audioDto.creationTime,
|
||||
userId = audioDto.userId,
|
||||
userName = audioDto.userName
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package com.isolaatti.audio.common.domain
|
||||
|
||||
import com.isolaatti.utils.Resource
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface AudiosRepository {
|
||||
fun getAudiosOfUser(userId: Int, lastId: String?): Flow<Resource<List<Audio>>>
|
||||
}
|
||||
@ -1,10 +1,12 @@
|
||||
package com.isolaatti.connectivity
|
||||
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.isolaatti.BuildConfig
|
||||
import com.isolaatti.type_adapters.LocalDateTimeAdapter
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import java.io.IOException
|
||||
import java.time.ZonedDateTime
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
@ -25,10 +27,14 @@ class RetrofitClient @Inject constructor(private val authenticationInterceptor:
|
||||
.addInterceptor(authenticationInterceptor)
|
||||
.build()
|
||||
|
||||
private val gson = GsonBuilder()
|
||||
.registerTypeAdapter(ZonedDateTime::class.java, LocalDateTimeAdapter())
|
||||
.create()
|
||||
|
||||
|
||||
val client: Retrofit get() = Retrofit.Builder()
|
||||
.baseUrl(BASE_URL)
|
||||
.client(okHttpClient)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.addConverterFactory(GsonConverterFactory.create(gson))
|
||||
.build()
|
||||
}
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
package com.isolaatti.profile.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.isolaatti.databinding.FragmentAudiosBinding
|
||||
|
||||
class AudiosFragment : Fragment() {
|
||||
lateinit var viewBinding: FragmentAudiosBinding
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
viewBinding = FragmentAudiosBinding.inflate(inflater)
|
||||
|
||||
return viewBinding.root
|
||||
}
|
||||
}
|
||||
@ -19,26 +19,26 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import coil.load
|
||||
import com.isolaatti.BuildConfig
|
||||
import com.isolaatti.R
|
||||
import com.isolaatti.audio.audios_list.ui.AudiosFragment
|
||||
import com.isolaatti.common.CoilImageLoader.imageLoader
|
||||
import com.isolaatti.common.Dialogs
|
||||
import com.isolaatti.common.ErrorMessageViewModel
|
||||
import com.isolaatti.databinding.FragmentDiscussionsBinding
|
||||
import com.isolaatti.followers.domain.FollowingState
|
||||
import com.isolaatti.posting.posts.viewer.ui.PostViewerActivity
|
||||
import com.isolaatti.posting.comments.ui.BottomSheetPostComments
|
||||
import com.isolaatti.common.Ownable
|
||||
import com.isolaatti.common.options_bottom_sheet.domain.OptionClicked
|
||||
import com.isolaatti.common.options_bottom_sheet.domain.Options
|
||||
import com.isolaatti.common.options_bottom_sheet.presentation.BottomSheetPostOptionsViewModel
|
||||
import com.isolaatti.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment
|
||||
import com.isolaatti.databinding.FragmentDiscussionsBinding
|
||||
import com.isolaatti.followers.domain.FollowingState
|
||||
import com.isolaatti.images.image_list.ui.ImagesFragment
|
||||
import com.isolaatti.images.picture_viewer.ui.PictureViewerActivity
|
||||
import com.isolaatti.posting.comments.ui.BottomSheetPostComments
|
||||
import com.isolaatti.posting.posts.domain.entity.Post
|
||||
import com.isolaatti.posting.posts.presentation.CreatePostContract
|
||||
import com.isolaatti.posting.posts.presentation.EditPostContract
|
||||
import com.isolaatti.posting.posts.presentation.PostListingRecyclerViewAdapterWiring
|
||||
import com.isolaatti.posting.posts.presentation.PostsRecyclerViewAdapter
|
||||
import com.isolaatti.posting.posts.presentation.UpdateEvent
|
||||
import com.isolaatti.posting.posts.viewer.ui.PostViewerActivity
|
||||
import com.isolaatti.profile.domain.entity.UserProfile
|
||||
import com.isolaatti.profile.presentation.ProfileViewModel
|
||||
import com.isolaatti.utils.UrlGen
|
||||
@ -214,7 +214,7 @@ class ProfileMainFragment : Fragment() {
|
||||
viewBinding.bottomAppBar.setOnMenuItemClickListener {
|
||||
when(it.itemId) {
|
||||
R.id.audios_menu_item -> {
|
||||
findNavController().navigate(ProfileMainFragmentDirections.actionDiscussionsFragmentToAudiosFragment())
|
||||
findNavController().navigate(ProfileMainFragmentDirections.actionDiscussionsFragmentToAudiosFragment(AudiosFragment.SOURCE_PROFILE, userId.toString()))
|
||||
true
|
||||
}
|
||||
R.id.images_menu_item -> {
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.isolaatti.type_adapters
|
||||
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import java.lang.reflect.Type
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class LocalDateTimeAdapter : JsonDeserializer<ZonedDateTime> {
|
||||
override fun deserialize(
|
||||
json: JsonElement?,
|
||||
typeOfT: Type?,
|
||||
context: JsonDeserializationContext?
|
||||
): ZonedDateTime {
|
||||
return ZonedDateTime.parse(json?.asString, DateTimeFormatter.ISO_DATE_TIME)
|
||||
}
|
||||
}
|
||||
67
app/src/main/res/layout/audio_list_item.xml
Normal file
67
app/src/main/res/layout/audio_list_item.xml
Normal file
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginVertical="4dp"
|
||||
style="?attr/materialCardViewFilledStyle"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_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"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
tools:src="@drawable/baseline_image_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/audio_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
|
||||
android:layout_marginEnd="8dp"
|
||||
android:lines="1"
|
||||
android:textSize="16sp"
|
||||
|
||||
app:layout_constraintBottom_toTopOf="@+id/audio_author"
|
||||
app:layout_constraintEnd_toStartOf="@+id/audio_item_options_button"
|
||||
app:layout_constraintStart_toEndOf="@id/thumbnail"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Hello" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/audio_author"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/audio_item_options_button"
|
||||
app:layout_constraintStart_toEndOf="@id/thumbnail"
|
||||
tools:text="Erik" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/audio_item_options_button"
|
||||
style="?attr/materialIconButtonFilledTonalStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:icon="@drawable/baseline_more_horiz_24"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:contentDescription="@string/audio_options"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
@ -2,7 +2,8 @@
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout 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">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
@ -15,4 +16,17 @@
|
||||
app:navigationIconTint="@color/on_surface"
|
||||
app:titleCentered="true"/>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_audios"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar_loading"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
9
app/src/main/res/menu/audio_item_menu.xml
Normal file
9
app/src/main/res/menu/audio_item_menu.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/delete_item"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:title="@string/delete" />
|
||||
</menu>
|
||||
@ -31,8 +31,14 @@
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/audiosFragment"
|
||||
android:name="com.isolaatti.profile.ui.AudiosFragment"
|
||||
android:label="AudiosFragment" />
|
||||
android:name="com.isolaatti.audio.audios_list.ui.AudiosFragment"
|
||||
android:label="AudiosFragment" >
|
||||
<argument
|
||||
android:name="source"
|
||||
app:argType="string" />
|
||||
<argument android:name="sourceId"
|
||||
app:argType="string" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/imagesFragment"
|
||||
android:name="com.isolaatti.images.image_list.ui.ImagesFragment"
|
||||
@ -64,4 +70,7 @@
|
||||
android:name="userId"
|
||||
app:argType="integer" />
|
||||
</fragment>
|
||||
<argument
|
||||
android:name="userId"
|
||||
app:argType="integer" />
|
||||
</navigation>
|
||||
@ -121,4 +121,5 @@
|
||||
<string name="delete_images_dialog_message">Remove %d images?</string>
|
||||
<string name="selected_images_count">Images selected: %d</string>
|
||||
<string name="picture_name">Picture name</string>
|
||||
<string name="audio_options">Audio options</string>
|
||||
</resources>
|
||||
Loading…
x
Reference in New Issue
Block a user