WIP quien dio like a post e historial de post
This commit is contained in:
parent
e12bbb2e94
commit
ba9aa4c395
@ -44,6 +44,7 @@
|
|||||||
<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" />
|
<activity android:name=".audio.audio_selector.ui.AudioSelectorActivity" android:theme="@style/Theme.Isolaatti" />
|
||||||
|
<activity android:name=".posting.posts.ui.PostInfoActivity" 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"
|
||||||
|
|||||||
@ -8,4 +8,6 @@ interface OnUserInteractedWithPostCallback : OnUserInteractedCallback {
|
|||||||
fun onComment(postId: Long)
|
fun onComment(postId: Long)
|
||||||
fun onOpenPost(postId: Long)
|
fun onOpenPost(postId: Long)
|
||||||
fun onPlay(audio: Audio)
|
fun onPlay(audio: Audio)
|
||||||
|
fun onMoreInfo(postId: Long)
|
||||||
|
fun onShare(postId: Long)
|
||||||
}
|
}
|
||||||
@ -10,13 +10,13 @@ import androidx.fragment.app.viewModels
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.isolaatti.common.UserItemCallback
|
import com.isolaatti.common.UserItemCallback
|
||||||
import com.isolaatti.common.UserListRecyclerViewAdapter
|
import com.isolaatti.common.UserListRecyclerViewAdapter
|
||||||
import com.isolaatti.databinding.FragmentFollowersBinding
|
import com.isolaatti.databinding.FragmentUserListBinding
|
||||||
import com.isolaatti.followers.presentation.FollowersViewModel
|
import com.isolaatti.followers.presentation.FollowersViewModel
|
||||||
import com.isolaatti.profile.domain.entity.ProfileListItem
|
import com.isolaatti.profile.domain.entity.ProfileListItem
|
||||||
import com.isolaatti.profile.ui.ProfileActivity
|
import com.isolaatti.profile.ui.ProfileActivity
|
||||||
|
|
||||||
class FollowersFragment : Fragment(), UserItemCallback {
|
class FollowersFragment : Fragment(), UserItemCallback {
|
||||||
private lateinit var binding: FragmentFollowersBinding
|
private lateinit var binding: FragmentUserListBinding
|
||||||
private val viewModel: FollowersViewModel by viewModels({ requireParentFragment() })
|
private val viewModel: FollowersViewModel by viewModels({ requireParentFragment() })
|
||||||
private lateinit var adapter: UserListRecyclerViewAdapter
|
private lateinit var adapter: UserListRecyclerViewAdapter
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ class FollowersFragment : Fragment(), UserItemCallback {
|
|||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View {
|
): View {
|
||||||
binding = FragmentFollowersBinding.inflate(inflater)
|
binding = FragmentUserListBinding.inflate(inflater)
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,13 +10,13 @@ import androidx.fragment.app.viewModels
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.isolaatti.common.UserItemCallback
|
import com.isolaatti.common.UserItemCallback
|
||||||
import com.isolaatti.common.UserListRecyclerViewAdapter
|
import com.isolaatti.common.UserListRecyclerViewAdapter
|
||||||
import com.isolaatti.databinding.FragmentFollowersBinding
|
import com.isolaatti.databinding.FragmentUserListBinding
|
||||||
import com.isolaatti.followers.presentation.FollowersViewModel
|
import com.isolaatti.followers.presentation.FollowersViewModel
|
||||||
import com.isolaatti.profile.domain.entity.ProfileListItem
|
import com.isolaatti.profile.domain.entity.ProfileListItem
|
||||||
import com.isolaatti.profile.ui.ProfileActivity
|
import com.isolaatti.profile.ui.ProfileActivity
|
||||||
|
|
||||||
class FollowingFragment : Fragment(), UserItemCallback {
|
class FollowingFragment : Fragment(), UserItemCallback {
|
||||||
private lateinit var binding: FragmentFollowersBinding
|
private lateinit var binding: FragmentUserListBinding
|
||||||
private val viewModel: FollowersViewModel by viewModels({ requireParentFragment() })
|
private val viewModel: FollowersViewModel by viewModels({ requireParentFragment() })
|
||||||
private lateinit var adapter: UserListRecyclerViewAdapter
|
private lateinit var adapter: UserListRecyclerViewAdapter
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ class FollowingFragment : Fragment(), UserItemCallback {
|
|||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View {
|
): View {
|
||||||
binding = FragmentFollowersBinding.inflate(inflater)
|
binding = FragmentUserListBinding.inflate(inflater)
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
38
app/src/main/java/com/isolaatti/markdown/Module.kt
Normal file
38
app/src/main/java/com/isolaatti/markdown/Module.kt
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package com.isolaatti.markdown
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.isolaatti.BuildConfig
|
||||||
|
import com.isolaatti.common.CoilImageLoader
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.components.ActivityComponent
|
||||||
|
import dagger.hilt.android.qualifiers.ActivityContext
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import io.noties.markwon.AbstractMarkwonPlugin
|
||||||
|
import io.noties.markwon.Markwon
|
||||||
|
import io.noties.markwon.MarkwonConfiguration
|
||||||
|
import io.noties.markwon.image.coil.CoilImagesPlugin
|
||||||
|
import io.noties.markwon.image.destination.ImageDestinationProcessorRelativeToAbsolute
|
||||||
|
import io.noties.markwon.linkify.LinkifyPlugin
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
class Module {
|
||||||
|
@Provides
|
||||||
|
fun provideMarkwon(@ApplicationContext context: Context): Markwon {
|
||||||
|
return Markwon.builder(context)
|
||||||
|
.usePlugin(object: AbstractMarkwonPlugin() {
|
||||||
|
override fun configureConfiguration(builder: MarkwonConfiguration.Builder) {
|
||||||
|
builder
|
||||||
|
.imageDestinationProcessor(
|
||||||
|
ImageDestinationProcessorRelativeToAbsolute
|
||||||
|
.create(BuildConfig.backend))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.usePlugin(CoilImagesPlugin.create(context, CoilImageLoader.imageLoader))
|
||||||
|
.usePlugin(LinkifyPlugin.create())
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,11 +15,9 @@ interface FeedsApi {
|
|||||||
@Query("olderFirst") olderFirst: Boolean,
|
@Query("olderFirst") olderFirst: Boolean,
|
||||||
@Query(value = "filterJson", encoded = false) filter: String): Call<FeedDto>
|
@Query(value = "filterJson", encoded = false) filter: String): Call<FeedDto>
|
||||||
|
|
||||||
@GET("Fetch/Post/{postId}")
|
|
||||||
fun getPost(@Path("postId") postId: Long): Call<FeedDto>
|
|
||||||
|
|
||||||
@GET("Fetch/Post/{postId}/LikedBy")
|
@GET("Fetch/Post/{postId}/LikedBy")
|
||||||
fun getLikedBy(@Path("postId") postId: Long): Call<List<ProfileListItemDto>>
|
fun getLikedBy(@Path("postId") postId: Long): Call<ResultDto<List<ProfileListItemDto>>>
|
||||||
|
|
||||||
@GET("Feed")
|
@GET("Feed")
|
||||||
fun getChronology(@Query("lastId") lastId: Long, @Query("length") length: Int): Call<FeedDto>
|
fun getChronology(@Query("lastId") lastId: Long, @Query("length") length: Int): Call<FeedDto>
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
package com.isolaatti.posting.posts.data.remote
|
package com.isolaatti.posting.posts.data.remote
|
||||||
|
|
||||||
|
import com.isolaatti.common.ResultDto
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
import retrofit2.http.Path
|
import retrofit2.http.Path
|
||||||
|
import retrofit2.http.Query
|
||||||
|
|
||||||
interface PostApi {
|
interface PostApi {
|
||||||
@POST("Posting/Make")
|
@POST("Posting/Make")
|
||||||
@ -19,4 +21,7 @@ interface PostApi {
|
|||||||
@GET("Fetch/Post/{postId}")
|
@GET("Fetch/Post/{postId}")
|
||||||
fun getPost(@Path("postId") postId: Long): Call<FeedDto.PostDto>
|
fun getPost(@Path("postId") postId: Long): Call<FeedDto.PostDto>
|
||||||
|
|
||||||
|
@GET("Posting/Post/{postId}/Versions")
|
||||||
|
fun getVersions(@Path("postId") postId: Long): Call<ResultDto<List<VersionDto>>>
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package com.isolaatti.posting.posts.data.remote
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime
|
||||||
|
|
||||||
|
data class VersionDto(
|
||||||
|
val id: Long,
|
||||||
|
val postId: Long,
|
||||||
|
val textContent: String,
|
||||||
|
val dateTime: ZonedDateTime,
|
||||||
|
val audioId: String
|
||||||
|
)
|
||||||
@ -10,8 +10,10 @@ import com.isolaatti.posting.posts.data.remote.FeedFilterDto
|
|||||||
import com.isolaatti.posting.posts.data.remote.FeedsApi
|
import com.isolaatti.posting.posts.data.remote.FeedsApi
|
||||||
import com.isolaatti.posting.posts.data.remote.PostApi
|
import com.isolaatti.posting.posts.data.remote.PostApi
|
||||||
import com.isolaatti.posting.posts.data.remote.PostDeletedDto
|
import com.isolaatti.posting.posts.data.remote.PostDeletedDto
|
||||||
|
import com.isolaatti.posting.posts.data.remote.VersionDto
|
||||||
import com.isolaatti.posting.posts.domain.PostsRepository
|
import com.isolaatti.posting.posts.domain.PostsRepository
|
||||||
import com.isolaatti.posting.posts.domain.entity.Post
|
import com.isolaatti.posting.posts.domain.entity.Post
|
||||||
|
import com.isolaatti.profile.domain.entity.ProfileListItem
|
||||||
import com.isolaatti.utils.Resource
|
import com.isolaatti.utils.Resource
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
@ -120,4 +122,40 @@ class PostsRepositoryImpl @Inject constructor(private val feedsApi: FeedsApi, pr
|
|||||||
emit(Resource.Error(Resource.Error.ErrorType.NetworkError))
|
emit(Resource.Error(Resource.Error.ErrorType.NetworkError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getUsersLikedPost(postId: Long): Flow<Resource<List<ProfileListItem>>> = flow {
|
||||||
|
emit(Resource.Loading())
|
||||||
|
try {
|
||||||
|
val response = feedsApi.getLikedBy(postId).awaitResponse()
|
||||||
|
if(response.isSuccessful) {
|
||||||
|
val dto = response.body()
|
||||||
|
if(dto != null) {
|
||||||
|
emit(Resource.Success(dto.result.map { ProfileListItem.fromDto(it) }))
|
||||||
|
return@flow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit(Resource.Error(Resource.Error.mapErrorCode(response.code())))
|
||||||
|
} catch(_: Exception) {
|
||||||
|
emit(Resource.Error(Resource.Error.ErrorType.OtherError))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPostVersions(postId: Long): Flow<Resource<List<VersionDto>>> = flow {
|
||||||
|
emit(Resource.Loading())
|
||||||
|
try {
|
||||||
|
val response = postApi.getVersions(postId).awaitResponse()
|
||||||
|
if(response.isSuccessful) {
|
||||||
|
val dto = response.body()
|
||||||
|
if(dto != null) {
|
||||||
|
emit(Resource.Success(dto.result))
|
||||||
|
}
|
||||||
|
return@flow
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(Resource.Error(Resource.Error.mapErrorCode(response.code())))
|
||||||
|
} catch(e: Exception) {
|
||||||
|
Log.e(LOG_TAG, "Error getting post versions. postId: $postId. \n ${e.message}")
|
||||||
|
emit(Resource.Error(Resource.Error.ErrorType.OtherError))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -5,7 +5,9 @@ import com.isolaatti.posting.posts.data.remote.EditPostDto
|
|||||||
import com.isolaatti.posting.posts.data.remote.FeedDto
|
import com.isolaatti.posting.posts.data.remote.FeedDto
|
||||||
import com.isolaatti.posting.posts.data.remote.FeedFilterDto
|
import com.isolaatti.posting.posts.data.remote.FeedFilterDto
|
||||||
import com.isolaatti.posting.posts.data.remote.PostDeletedDto
|
import com.isolaatti.posting.posts.data.remote.PostDeletedDto
|
||||||
|
import com.isolaatti.posting.posts.data.remote.VersionDto
|
||||||
import com.isolaatti.posting.posts.domain.entity.Post
|
import com.isolaatti.posting.posts.domain.entity.Post
|
||||||
|
import com.isolaatti.profile.domain.entity.ProfileListItem
|
||||||
import com.isolaatti.utils.Resource
|
import com.isolaatti.utils.Resource
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@ -19,4 +21,7 @@ interface PostsRepository {
|
|||||||
fun editPost(editPostDto: EditPostDto): Flow<Resource<FeedDto.PostDto>>
|
fun editPost(editPostDto: EditPostDto): Flow<Resource<FeedDto.PostDto>>
|
||||||
fun deletePost(postId: Long): Flow<Resource<PostDeletedDto>>
|
fun deletePost(postId: Long): Flow<Resource<PostDeletedDto>>
|
||||||
fun loadPost(postId: Long): Flow<Resource<Post>>
|
fun loadPost(postId: Long): Flow<Resource<Post>>
|
||||||
|
|
||||||
|
fun getUsersLikedPost(postId: Long): Flow<Resource<List<ProfileListItem>>>
|
||||||
|
fun getPostVersions(postId: Long): Flow<Resource<List<VersionDto>>>
|
||||||
}
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
package com.isolaatti.posting.posts.domain.use_case
|
||||||
|
|
||||||
|
import com.isolaatti.posting.posts.domain.PostsRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class GetPostLikedBy @Inject constructor(private val postsRepository: PostsRepository) {
|
||||||
|
operator fun invoke(postId: Long) = postsRepository.getUsersLikedPost(postId)
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.isolaatti.posting.posts.presentation
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
|
import com.isolaatti.posting.posts.ui.PostLikesFragment
|
||||||
|
import com.isolaatti.posting.posts.ui.PostVersionsFragment
|
||||||
|
|
||||||
|
class PostInfoViewPagerAdapter(fragmentActivity: FragmentActivity, private val postId: Long) : FragmentStateAdapter(fragmentActivity) {
|
||||||
|
override fun getItemCount(): Int = 2
|
||||||
|
|
||||||
|
override fun createFragment(position: Int): Fragment = if(position == 0) {
|
||||||
|
PostLikesFragment.getInstance(postId)
|
||||||
|
} else{
|
||||||
|
PostVersionsFragment.getInstance(postId)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.isolaatti.posting.posts.presentation
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.isolaatti.posting.posts.domain.use_case.GetPostLikedBy
|
||||||
|
import com.isolaatti.profile.domain.entity.ProfileListItem
|
||||||
|
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 PostLikesViewModel @Inject constructor(private val getPostLikedBy: GetPostLikedBy) : ViewModel() {
|
||||||
|
var postId: Long = 0
|
||||||
|
val users: MutableLiveData<List<ProfileListItem>> = MutableLiveData()
|
||||||
|
val loading: MutableLiveData<Boolean> = MutableLiveData()
|
||||||
|
fun getUsers() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
getPostLikedBy(postId).onEach { resource ->
|
||||||
|
when(resource) {
|
||||||
|
is Resource.Error -> {}
|
||||||
|
is Resource.Loading -> loading.postValue(true)
|
||||||
|
is Resource.Success -> {
|
||||||
|
loading.postValue(false)
|
||||||
|
users.postValue(resource.data!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.flowOn(Dispatchers.IO).launchIn(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
package com.isolaatti.posting.posts.presentation
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
|
import com.isolaatti.R
|
||||||
|
import com.isolaatti.databinding.ItemPostVersionBinding
|
||||||
|
import com.isolaatti.posting.posts.data.remote.VersionDto
|
||||||
|
import io.noties.markwon.Markwon
|
||||||
|
|
||||||
|
class PostVersionsAdapter(private val markwon: Markwon) : ListAdapter<VersionDto, PostVersionsAdapter.PostVersionViewHolder>(itemCallback) {
|
||||||
|
|
||||||
|
inner class PostVersionViewHolder(val binding: ItemPostVersionBinding) : ViewHolder(binding.root)
|
||||||
|
companion object {
|
||||||
|
val itemCallback = object: DiffUtil.ItemCallback<VersionDto>() {
|
||||||
|
override fun areItemsTheSame(oldItem: VersionDto, newItem: VersionDto): Boolean {
|
||||||
|
return oldItem.id == newItem.id
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItem: VersionDto, newItem: VersionDto): Boolean {
|
||||||
|
return oldItem == newItem
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostVersionViewHolder {
|
||||||
|
return PostVersionViewHolder(ItemPostVersionBinding.inflate(LayoutInflater.from(parent.context), parent, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: PostVersionViewHolder, position: Int) {
|
||||||
|
val item = getItem(position)
|
||||||
|
markwon.setMarkdown(holder.binding.postVersionContent, item.textContent)
|
||||||
|
holder.binding.postVersionDate.text = holder.itemView.context?.getString(R.string.edited_at, item.dateTime.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.isolaatti.posting.posts.presentation
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.isolaatti.posting.posts.data.remote.VersionDto
|
||||||
|
import com.isolaatti.posting.posts.domain.PostsRepository
|
||||||
|
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 PostVersionsViewModel @Inject constructor(private val postsRepository: PostsRepository) : ViewModel() {
|
||||||
|
val versions: MutableLiveData<List<VersionDto>> = MutableLiveData()
|
||||||
|
val loading: MutableLiveData<Boolean> = MutableLiveData()
|
||||||
|
var postId = 0L
|
||||||
|
fun getPostVersions() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
postsRepository.getPostVersions(postId).onEach { resource ->
|
||||||
|
when(resource) {
|
||||||
|
is Resource.Error -> {}
|
||||||
|
is Resource.Loading -> loading.postValue(true)
|
||||||
|
is Resource.Success -> {
|
||||||
|
loading.postValue(false)
|
||||||
|
versions.postValue(resource.data!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.flowOn(Dispatchers.IO).launchIn(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -150,6 +150,12 @@ class PostsRecyclerViewAdapter (
|
|||||||
itemBinding.audio.root.visibility = View.GONE
|
itemBinding.audio.root.visibility = View.GONE
|
||||||
itemBinding.audio.playButton.setOnClickListener(null)
|
itemBinding.audio.playButton.setOnClickListener(null)
|
||||||
}
|
}
|
||||||
|
itemBinding.shareButton.setOnClickListener {
|
||||||
|
callback.onShare(post.id)
|
||||||
|
}
|
||||||
|
itemBinding.infoButton.setOnClickListener {
|
||||||
|
callback.onMoreInfo(post.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,46 @@
|
|||||||
|
package com.isolaatti.posting.posts.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
|
import com.isolaatti.R
|
||||||
|
import com.isolaatti.common.IsolaattiBaseActivity
|
||||||
|
import com.isolaatti.databinding.ActivityPostInfoBinding
|
||||||
|
import com.isolaatti.posting.posts.presentation.PostInfoViewPagerAdapter
|
||||||
|
|
||||||
|
class PostInfoActivity : IsolaattiBaseActivity() {
|
||||||
|
private lateinit var binding: ActivityPostInfoBinding
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
binding = ActivityPostInfoBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
val postId = intent.extras?.getLong(EXTRA_POST_ID) ?: 0
|
||||||
|
if(postId != 0L) {
|
||||||
|
binding.viewPagerPostInfo.adapter = PostInfoViewPagerAdapter(this, postId)
|
||||||
|
|
||||||
|
TabLayoutMediator(binding.tabsPostInfo, binding.viewPagerPostInfo) { tab, position ->
|
||||||
|
if(position == 0) {
|
||||||
|
tab.text = getString(R.string.people_who_clapped)
|
||||||
|
} else {
|
||||||
|
tab.text = getString(R.string.post_history)
|
||||||
|
}
|
||||||
|
}.attach()
|
||||||
|
} else {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val EXTRA_POST_ID = "postId"
|
||||||
|
fun startActivity(context: Context, postId: Long) {
|
||||||
|
val intent = Intent(context, PostInfoActivity::class.java).apply {
|
||||||
|
putExtra(EXTRA_POST_ID, postId)
|
||||||
|
}
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
package com.isolaatti.posting.posts.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.common.ListUpdateEvent
|
||||||
|
import com.isolaatti.common.UpdateEvent
|
||||||
|
import com.isolaatti.common.UserItemCallback
|
||||||
|
import com.isolaatti.common.UserListRecyclerViewAdapter
|
||||||
|
import com.isolaatti.databinding.FragmentUserListBinding
|
||||||
|
import com.isolaatti.posting.posts.presentation.PostLikesViewModel
|
||||||
|
import com.isolaatti.profile.domain.entity.ProfileListItem
|
||||||
|
import com.isolaatti.profile.ui.ProfileActivity
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class PostLikesFragment : Fragment() {
|
||||||
|
private lateinit var binding: FragmentUserListBinding
|
||||||
|
private val viewModel: PostLikesViewModel by viewModels()
|
||||||
|
private var adapter: UserListRecyclerViewAdapter? = null
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
binding = FragmentUserListBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
viewModel.postId = arguments?.getLong(ARG_POST_ID) ?: 0
|
||||||
|
|
||||||
|
if(viewModel.postId != 0L)
|
||||||
|
viewModel.getUsers()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
adapter = UserListRecyclerViewAdapter(object: UserItemCallback {
|
||||||
|
override fun itemClick(userId: Int) {
|
||||||
|
ProfileActivity.startActivity(requireContext(), userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun followButtonClick(
|
||||||
|
user: ProfileListItem,
|
||||||
|
action: UserItemCallback.FollowButtonAction
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
binding.recyclerUsers.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
|
||||||
|
binding.recyclerUsers.adapter = adapter
|
||||||
|
|
||||||
|
binding.swipeToRefresh.setOnRefreshListener {
|
||||||
|
viewModel.getUsers()
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.users.observe(viewLifecycleOwner) {
|
||||||
|
adapter?.updateData(it, UpdateEvent(ListUpdateEvent.Refresh, arrayOf()))
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.loading.observe(viewLifecycleOwner) {
|
||||||
|
binding.swipeToRefresh.isRefreshing = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
companion object {
|
||||||
|
const val ARG_POST_ID = "postId"
|
||||||
|
fun getInstance(postId: Long): PostLikesFragment {
|
||||||
|
return PostLikesFragment().apply {
|
||||||
|
arguments = Bundle().apply {
|
||||||
|
putLong(ARG_POST_ID, postId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
package com.isolaatti.posting.posts.ui
|
package com.isolaatti.posting.posts.ui
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -11,6 +13,7 @@ import androidx.fragment.app.viewModels
|
|||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.isolaatti.BuildConfig
|
import com.isolaatti.BuildConfig
|
||||||
|
import com.isolaatti.R
|
||||||
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.player.AudioPlayerConnector
|
import com.isolaatti.audio.player.AudioPlayerConnector
|
||||||
@ -24,7 +27,6 @@ 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.presentation.BottomSheetPostOptionsViewModel
|
||||||
import com.isolaatti.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment
|
import com.isolaatti.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment
|
||||||
import com.isolaatti.databinding.FragmentPostListingBinding
|
import com.isolaatti.databinding.FragmentPostListingBinding
|
||||||
import com.isolaatti.home.presentation.FeedViewModel
|
|
||||||
import com.isolaatti.home.ui.FeedFragment
|
import com.isolaatti.home.ui.FeedFragment
|
||||||
import com.isolaatti.posting.comments.ui.BottomSheetPostComments
|
import com.isolaatti.posting.comments.ui.BottomSheetPostComments
|
||||||
import com.isolaatti.posting.posts.domain.entity.Post
|
import com.isolaatti.posting.posts.domain.entity.Post
|
||||||
@ -177,6 +179,19 @@ class PostListingFragment : Fragment(), OnUserInteractedWithPostCallback {
|
|||||||
audioPlayerConnector.playPauseAudio(audio)
|
audioPlayerConnector.playPauseAudio(audio)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onMoreInfo(postId: Long) {
|
||||||
|
PostInfoActivity.startActivity(requireContext(), postId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onShare(postId: Long) {
|
||||||
|
val intent = Intent.createChooser(Intent().apply {
|
||||||
|
action = Intent.ACTION_SEND
|
||||||
|
putExtra(Intent.EXTRA_TEXT, "${BuildConfig.backend}/pub/${postId}")
|
||||||
|
type = "text/plain"
|
||||||
|
}, getString(R.string.share_post))
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onProfileClick(userId: Int) {
|
override fun onProfileClick(userId: Int) {
|
||||||
ProfileActivity.startActivity(requireContext(), userId)
|
ProfileActivity.startActivity(requireContext(), userId)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,77 @@
|
|||||||
|
package com.isolaatti.posting.posts.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.databinding.FragmentPostVersionsBinding
|
||||||
|
import com.isolaatti.posting.posts.presentation.PostVersionsAdapter
|
||||||
|
import com.isolaatti.posting.posts.presentation.PostVersionsViewModel
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import io.noties.markwon.Markwon
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class PostVersionsFragment : Fragment() {
|
||||||
|
private lateinit var binding: FragmentPostVersionsBinding
|
||||||
|
private val viewModel: PostVersionsViewModel by viewModels()
|
||||||
|
private var adapter: PostVersionsAdapter? = null
|
||||||
|
|
||||||
|
@Inject lateinit var markwon: Markwon
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
binding = FragmentPostVersionsBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
viewModel.postId = arguments?.getLong(ARG_POST_ID) ?: 0
|
||||||
|
|
||||||
|
if(viewModel.postId != 0L) {
|
||||||
|
viewModel.getPostVersions()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
adapter = PostVersionsAdapter(markwon)
|
||||||
|
|
||||||
|
binding.recyclerView.adapter = adapter
|
||||||
|
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
|
||||||
|
|
||||||
|
binding.swipeToRefresh.setOnRefreshListener {
|
||||||
|
viewModel.getPostVersions()
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.versions.observe(viewLifecycleOwner) {
|
||||||
|
adapter?.submitList(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.loading.observe(viewLifecycleOwner) {
|
||||||
|
binding.swipeToRefresh.isRefreshing = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val LOG_TAG = "PostVersionsFragment"
|
||||||
|
const val ARG_POST_ID = "postId"
|
||||||
|
fun getInstance(postId: Long): PostVersionsFragment {
|
||||||
|
return PostVersionsFragment().apply {
|
||||||
|
arguments = Bundle().apply {
|
||||||
|
putLong(ARG_POST_ID, postId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,6 +15,7 @@ import com.isolaatti.R
|
|||||||
import com.isolaatti.common.IsolaattiBaseActivity
|
import com.isolaatti.common.IsolaattiBaseActivity
|
||||||
import com.isolaatti.databinding.ActivityPostViewerBinding
|
import com.isolaatti.databinding.ActivityPostViewerBinding
|
||||||
import com.isolaatti.posting.comments.ui.BottomSheetPostComments
|
import com.isolaatti.posting.comments.ui.BottomSheetPostComments
|
||||||
|
import com.isolaatti.posting.posts.ui.PostInfoActivity
|
||||||
import com.isolaatti.posting.posts.viewer.presentation.PostViewerViewModel
|
import com.isolaatti.posting.posts.viewer.presentation.PostViewerViewModel
|
||||||
import com.isolaatti.profile.ui.ProfileActivity
|
import com.isolaatti.profile.ui.ProfileActivity
|
||||||
import com.isolaatti.utils.UrlGen
|
import com.isolaatti.utils.UrlGen
|
||||||
@ -121,6 +122,10 @@ class PostViewerActivity : IsolaattiBaseActivity() {
|
|||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.likesInfo.setOnClickListener {
|
||||||
|
PostInfoActivity.startActivity(this, postId)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent?) {
|
override fun onNewIntent(intent: Intent?) {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.isolaatti.profile.ui
|
package com.isolaatti.profile.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -37,7 +38,6 @@ import com.isolaatti.databinding.FragmentDiscussionsBinding
|
|||||||
import com.isolaatti.followers.domain.FollowingState
|
import com.isolaatti.followers.domain.FollowingState
|
||||||
import com.isolaatti.images.image_chooser.ui.ImageChooserContract
|
import com.isolaatti.images.image_chooser.ui.ImageChooserContract
|
||||||
import com.isolaatti.images.image_list.ui.ImagesFragment
|
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.comments.ui.BottomSheetPostComments
|
||||||
import com.isolaatti.posting.posts.domain.entity.Post
|
import com.isolaatti.posting.posts.domain.entity.Post
|
||||||
import com.isolaatti.posting.posts.presentation.CreatePostContract
|
import com.isolaatti.posting.posts.presentation.CreatePostContract
|
||||||
@ -45,6 +45,7 @@ import com.isolaatti.posting.posts.presentation.EditPostContract
|
|||||||
import com.isolaatti.posting.posts.presentation.PostListingRecyclerViewAdapterWiring
|
import com.isolaatti.posting.posts.presentation.PostListingRecyclerViewAdapterWiring
|
||||||
import com.isolaatti.posting.posts.presentation.PostsRecyclerViewAdapter
|
import com.isolaatti.posting.posts.presentation.PostsRecyclerViewAdapter
|
||||||
import com.isolaatti.posting.posts.presentation.UpdateEvent
|
import com.isolaatti.posting.posts.presentation.UpdateEvent
|
||||||
|
import com.isolaatti.posting.posts.ui.PostInfoActivity
|
||||||
import com.isolaatti.posting.posts.viewer.ui.PostViewerActivity
|
import com.isolaatti.posting.posts.viewer.ui.PostViewerActivity
|
||||||
import com.isolaatti.profile.domain.entity.UserProfile
|
import com.isolaatti.profile.domain.entity.UserProfile
|
||||||
import com.isolaatti.profile.presentation.EditProfileContract
|
import com.isolaatti.profile.presentation.EditProfileContract
|
||||||
@ -472,6 +473,19 @@ class ProfileMainFragment : Fragment() {
|
|||||||
override fun onLoadMore() {
|
override fun onLoadMore() {
|
||||||
viewModel.getFeed(false, null)
|
viewModel.getFeed(false, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onMoreInfo(postId: Long) {
|
||||||
|
PostInfoActivity.startActivity(requireContext(), postId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onShare(postId: Long) {
|
||||||
|
val intent = Intent.createChooser(Intent().apply {
|
||||||
|
action = Intent.ACTION_SEND
|
||||||
|
putExtra(Intent.EXTRA_TEXT, "${BuildConfig.backend}/pub/${postId}")
|
||||||
|
type = "text/plain"
|
||||||
|
}, getString(R.string.share_post))
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
29
app/src/main/res/layout/activity_post_info.xml
Normal file
29
app/src/main/res/layout/activity_post_info.xml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-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">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:title="Discussion info"
|
||||||
|
app:navigationIcon="@drawable/baseline_close_24"/>
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/tabs_post_info"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_scrollFlags="scroll|snap"/>
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
|
android:id="@+id/view_pager_post_info"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
@ -1,6 +0,0 @@
|
|||||||
<?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.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@ -1,16 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
android:id="@+id/swipe_to_refresh"
|
android:id="@+id/swipe_to_refresh"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recycler_users"
|
android:id="@+id/recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
21
app/src/main/res/layout/fragment_user_list.xml
Normal file
21
app/src/main/res/layout/fragment_user_list.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/swipe_to_refresh"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_users"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
74
app/src/main/res/layout/item_post_version.xml
Normal file
74
app/src/main/res/layout/item_post_version.xml
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?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"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/post_version_date_card"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/post_version_date"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:text="@string/edited_at"
|
||||||
|
android:textAlignment="center"
|
||||||
|
tools:text="date" />
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/post_version_content_card"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/post_version_date_card"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
style="@style/Widget.Material3.CardView.Filled">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/post_version_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="content"
|
||||||
|
android:layout_margin="16dp"/>
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:background="@color/on_surface"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/post_version_date_card"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/post_version_content_card"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:background="@color/on_surface"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/post_version_content_card"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:background="@color/on_surface"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/post_version_date_card"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@ -87,6 +87,19 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:icon="@drawable/comments_solid" />
|
app:icon="@drawable/comments_solid" />
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/share_button"
|
||||||
|
style="?attr/materialIconButtonFilledTonalStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:icon="@drawable/baseline_share_24"
|
||||||
|
android:gravity="end"/>
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/info_button"
|
||||||
|
style="?attr/materialIconButtonFilledTonalStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:icon="@drawable/baseline_info_24" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@ -206,6 +206,10 @@
|
|||||||
<string name="app_version">v%s</string>
|
<string name="app_version">v%s</string>
|
||||||
<string name="new_report">New report</string>
|
<string name="new_report">New report</string>
|
||||||
<string name="report_submitted_successfully">Report submitted successfully</string>
|
<string name="report_submitted_successfully">Report submitted successfully</string>
|
||||||
|
<string name="share_post">Share post</string>
|
||||||
|
<string name="people_who_clapped">People who clapped</string>
|
||||||
|
<string name="post_history">History</string>
|
||||||
|
<string name="edited_at">Edited at %s</string>
|
||||||
<string-array name="report_reasons">
|
<string-array name="report_reasons">
|
||||||
<item>Spam</item>
|
<item>Spam</item>
|
||||||
<item>Explicit content</item>
|
<item>Explicit content</item>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user