WIP comentarios
This commit is contained in:
parent
bde81ee4e7
commit
4fc72786af
@ -23,7 +23,7 @@ import com.isolaatti.drafts.ui.DraftsActivity
|
|||||||
import com.isolaatti.home.presentation.FeedViewModel
|
import com.isolaatti.home.presentation.FeedViewModel
|
||||||
import com.isolaatti.picture_viewer.ui.PictureViewerActivity
|
import com.isolaatti.picture_viewer.ui.PictureViewerActivity
|
||||||
import com.isolaatti.posting.PostViewerActivity
|
import com.isolaatti.posting.PostViewerActivity
|
||||||
import com.isolaatti.posting.comments.presentation.BottomSheetPostComments
|
import com.isolaatti.posting.comments.ui.BottomSheetPostComments
|
||||||
import com.isolaatti.posting.common.domain.OnUserInteractedWithPostCallback
|
import com.isolaatti.posting.common.domain.OnUserInteractedWithPostCallback
|
||||||
import com.isolaatti.posting.common.domain.Ownable
|
import com.isolaatti.posting.common.domain.Ownable
|
||||||
import com.isolaatti.posting.common.options_bottom_sheet.domain.OptionClicked
|
import com.isolaatti.posting.common.options_bottom_sheet.domain.OptionClicked
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import retrofit2.http.Query
|
|||||||
|
|
||||||
interface CommentsApi {
|
interface CommentsApi {
|
||||||
@POST("Posting/Post/{postId}/Comment")
|
@POST("Posting/Post/{postId}/Comment")
|
||||||
fun postComment(@Body commentToPost: CommentToPostDto): Call<Nothing>
|
fun postComment(@Path("postId") postId: Long, @Body commentToPost: CommentToPostDto): Call<CommentDto>
|
||||||
|
|
||||||
@GET("Fetch/Post/{postId}/Comments")
|
@GET("Fetch/Post/{postId}/Comments")
|
||||||
fun getCommentsOfPosts(@Path("postId") postId: Long, @Query("lastId") lastId: Long, @Query("take") count: Int): Call<FeedCommentsDto>
|
fun getCommentsOfPosts(@Path("postId") postId: Long, @Query("lastId") lastId: Long, @Query("take") count: Int): Call<FeedCommentsDto>
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import com.isolaatti.posting.comments.data.remote.CommentToPostDto
|
|||||||
import com.isolaatti.posting.comments.data.remote.CommentsApi
|
import com.isolaatti.posting.comments.data.remote.CommentsApi
|
||||||
import com.isolaatti.posting.comments.domain.CommentsRepository
|
import com.isolaatti.posting.comments.domain.CommentsRepository
|
||||||
import com.isolaatti.posting.comments.domain.model.Comment
|
import com.isolaatti.posting.comments.domain.model.Comment
|
||||||
|
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
|
||||||
import retrofit2.awaitResponse
|
import retrofit2.awaitResponse
|
||||||
@ -26,8 +27,17 @@ class CommentsRepositoryImpl @Inject constructor(private val commentsApi: Commen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun postComment(commentToPostDto: CommentToPostDto, postId: Long): Flow<Boolean> = flow {
|
override fun postComment(content: String, audioId: String?, postId: Long): Flow<Resource<Comment>> = flow {
|
||||||
val response = commentsApi.postComment(commentToPostDto).awaitResponse()
|
emit(Resource.Loading())
|
||||||
emit(response.isSuccessful)
|
val commentToPostDto = CommentToPostDto(content, audioId)
|
||||||
|
val response = commentsApi.postComment(postId, commentToPostDto).awaitResponse()
|
||||||
|
if(response.isSuccessful) {
|
||||||
|
val responseBody = response.body()
|
||||||
|
if(responseBody != null) {
|
||||||
|
emit(Resource.Success(Comment.fromCommentDto(responseBody)))
|
||||||
|
return@flow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit(Resource.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,12 +1,12 @@
|
|||||||
package com.isolaatti.posting.comments.domain
|
package com.isolaatti.posting.comments.domain
|
||||||
|
|
||||||
import com.isolaatti.posting.comments.data.remote.CommentDto
|
import com.isolaatti.posting.comments.data.remote.CommentDto
|
||||||
import com.isolaatti.posting.comments.data.remote.CommentToPostDto
|
|
||||||
import com.isolaatti.posting.comments.domain.model.Comment
|
import com.isolaatti.posting.comments.domain.model.Comment
|
||||||
|
import com.isolaatti.utils.Resource
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface CommentsRepository {
|
interface CommentsRepository {
|
||||||
fun getComments(postId: Long, lastId: Long): Flow<MutableList<Comment>>
|
fun getComments(postId: Long, lastId: Long): Flow<MutableList<Comment>>
|
||||||
fun getComment(commentId: Long): Flow<CommentDto>
|
fun getComment(commentId: Long): Flow<CommentDto>
|
||||||
fun postComment(commentToPostDto: CommentToPostDto, postId: Long): Flow<Boolean>
|
fun postComment(content: String, audioId: String?, postId: Long): Flow<Resource<Comment>>
|
||||||
}
|
}
|
||||||
@ -26,5 +26,16 @@ data class Comment(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun fromCommentDto(dto: CommentDto): Comment {
|
||||||
|
return Comment(
|
||||||
|
id = dto.comment.id,
|
||||||
|
textContent = dto.comment.textContent,
|
||||||
|
userId = dto.comment.userId,
|
||||||
|
postId = dto.comment.postId,
|
||||||
|
date = dto.comment.date,
|
||||||
|
username = dto.username
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
package com.isolaatti.posting.comments.domain.use_case
|
||||||
|
|
||||||
|
import com.isolaatti.posting.comments.domain.CommentsRepository
|
||||||
|
import com.isolaatti.posting.comments.domain.model.Comment
|
||||||
|
import com.isolaatti.utils.Resource
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class PostComment @Inject constructor(private val commentsRepository: CommentsRepository) {
|
||||||
|
operator fun invoke(content: String, postId: Long): Flow<Resource<Comment>> {
|
||||||
|
return commentsRepository.postComment(content, null, postId)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package com.isolaatti.posting.comments.presentation
|
package com.isolaatti.posting.comments.presentation
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
@ -7,12 +8,16 @@ import com.isolaatti.databinding.CommentLayoutBinding
|
|||||||
import com.isolaatti.posting.comments.data.remote.CommentDto
|
import com.isolaatti.posting.comments.data.remote.CommentDto
|
||||||
import com.isolaatti.posting.comments.domain.model.Comment
|
import com.isolaatti.posting.comments.domain.model.Comment
|
||||||
import com.isolaatti.posting.common.domain.OnUserInteractedCallback
|
import com.isolaatti.posting.common.domain.OnUserInteractedCallback
|
||||||
|
import com.isolaatti.posting.posts.presentation.PostsRecyclerViewAdapter
|
||||||
import com.isolaatti.utils.UrlGen
|
import com.isolaatti.utils.UrlGen
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
import io.noties.markwon.Markwon
|
import io.noties.markwon.Markwon
|
||||||
|
|
||||||
class CommentsRecyclerViewAdapter(private var list: List<Comment>, private val markwon: Markwon, private val callback: OnUserInteractedCallback) : RecyclerView.Adapter<CommentsRecyclerViewAdapter.CommentViewHolder>() {
|
class CommentsRecyclerViewAdapter(private var list: List<Comment>, private val markwon: Markwon, private val callback: OnUserInteractedCallback) : RecyclerView.Adapter<CommentsRecyclerViewAdapter.CommentViewHolder>() {
|
||||||
|
|
||||||
|
private var previousSize = 0
|
||||||
|
var blockInfiniteScroll = false
|
||||||
|
|
||||||
inner class CommentViewHolder(val viewBinding: CommentLayoutBinding) : RecyclerView.ViewHolder(viewBinding.root)
|
inner class CommentViewHolder(val viewBinding: CommentLayoutBinding) : RecyclerView.ViewHolder(viewBinding.root)
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CommentViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CommentViewHolder {
|
||||||
@ -21,6 +26,15 @@ class CommentsRecyclerViewAdapter(private var list: List<Comment>, private val m
|
|||||||
|
|
||||||
override fun getItemCount(): Int = list.count()
|
override fun getItemCount(): Int = list.count()
|
||||||
|
|
||||||
|
private var requestedNewContent = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this method when new content has been added on onLoadMore() callback
|
||||||
|
*/
|
||||||
|
fun newContentRequestFinished() {
|
||||||
|
requestedNewContent = false
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: CommentViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: CommentViewHolder, position: Int) {
|
||||||
val comment = list[position]
|
val comment = list[position]
|
||||||
|
|
||||||
@ -36,11 +50,53 @@ class CommentsRecyclerViewAdapter(private var list: List<Comment>, private val m
|
|||||||
Picasso.get()
|
Picasso.get()
|
||||||
.load(UrlGen.userProfileImage(comment.userId))
|
.load(UrlGen.userProfileImage(comment.userId))
|
||||||
.into(holder.viewBinding.avatarPicture)
|
.into(holder.viewBinding.avatarPicture)
|
||||||
|
|
||||||
|
val totalItems = list.size
|
||||||
|
if(totalItems > 0 && !requestedNewContent) {
|
||||||
|
if(position == totalItems - 1 && !blockInfiniteScroll) {
|
||||||
|
requestedNewContent = true
|
||||||
|
callback.onLoadMore()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun submitList(commentDtoList: List<Comment>) {
|
}
|
||||||
val lastIndex = if(list.count() - 1 < 1) 0 else list.count() - 1
|
}
|
||||||
list = commentDtoList
|
|
||||||
notifyItemRangeChanged(lastIndex, commentDtoList.count())
|
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
fun updateList(updatedList: List<Comment>, updateEvent: UpdateEvent? = null) {
|
||||||
|
|
||||||
|
if(updateEvent == null) {
|
||||||
|
list = updatedList
|
||||||
|
|
||||||
|
notifyDataSetChanged()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val commentUpdated = updateEvent.affectedPosition?.let { list?.get(it) }
|
||||||
|
val position = updateEvent.affectedPosition
|
||||||
|
|
||||||
|
previousSize = itemCount
|
||||||
|
list = updatedList
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
when(updateEvent.updateType) {
|
||||||
|
|
||||||
|
UpdateEvent.UpdateType.COMMENT_REMOVED -> {
|
||||||
|
if(commentUpdated != null && position != null)
|
||||||
|
notifyItemRemoved(position)
|
||||||
|
}
|
||||||
|
UpdateEvent.UpdateType.COMMENT_ADDED_TOP -> {
|
||||||
|
notifyItemInserted(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateEvent.UpdateType.COMMENT_PAGE_ADDED_BOTTOM -> {
|
||||||
|
notifyItemInserted(previousSize)
|
||||||
|
}
|
||||||
|
UpdateEvent.UpdateType.REFRESH -> {
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7,6 +7,8 @@ import androidx.lifecycle.viewModelScope
|
|||||||
import com.isolaatti.posting.comments.data.remote.CommentDto
|
import com.isolaatti.posting.comments.data.remote.CommentDto
|
||||||
import com.isolaatti.posting.comments.domain.model.Comment
|
import com.isolaatti.posting.comments.domain.model.Comment
|
||||||
import com.isolaatti.posting.comments.domain.use_case.GetComments
|
import com.isolaatti.posting.comments.domain.use_case.GetComments
|
||||||
|
import com.isolaatti.posting.comments.domain.use_case.PostComment
|
||||||
|
import com.isolaatti.utils.Resource
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
@ -16,10 +18,14 @@ import kotlinx.coroutines.launch
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class CommentsViewModel @Inject constructor(private val getComments: GetComments) : ViewModel() {
|
class CommentsViewModel @Inject constructor(private val getComments: GetComments, private val postComment: PostComment) : ViewModel() {
|
||||||
private val _comments: MutableLiveData<List<Comment>> = MutableLiveData()
|
private val commentsList: MutableList<Comment> = mutableListOf()
|
||||||
|
|
||||||
val comments: LiveData<List<Comment>> get() = _comments
|
private val _comments: MutableLiveData<Pair<List<Comment>, UpdateEvent>> = MutableLiveData()
|
||||||
|
|
||||||
|
val comments: LiveData<Pair<List<Comment>, UpdateEvent>> get() = _comments
|
||||||
|
val commentPosted: MutableLiveData<Boolean?> = MutableLiveData()
|
||||||
|
val noMoreContent: MutableLiveData<Boolean?> = MutableLiveData()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* postId to query comments for. First page will be fetched when set.
|
* postId to query comments for. First page will be fetched when set.
|
||||||
@ -33,12 +39,18 @@ class CommentsViewModel @Inject constructor(private val getComments: GetComments
|
|||||||
|
|
||||||
private var lastId: Long = 0L
|
private var lastId: Long = 0L
|
||||||
|
|
||||||
fun getContent() {
|
fun getContent(refresh: Boolean = false) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
if(refresh) {
|
||||||
|
commentsList.clear()
|
||||||
|
}
|
||||||
getComments(postId, lastId).onEach {
|
getComments(postId, lastId).onEach {
|
||||||
val newList = _comments.value?.toMutableList() ?: mutableListOf()
|
val eventType = if((commentsList.isNotEmpty())) UpdateEvent.UpdateType.COMMENT_PAGE_ADDED_BOTTOM else UpdateEvent.UpdateType.REFRESH
|
||||||
newList.addAll(it)
|
commentsList.addAll(it)
|
||||||
_comments.postValue(newList)
|
_comments.postValue(Pair(commentsList, UpdateEvent(eventType, null)))
|
||||||
|
if(it.isEmpty()) {
|
||||||
|
noMoreContent.postValue(true)
|
||||||
|
}
|
||||||
if(it.isNotEmpty()){
|
if(it.isNotEmpty()){
|
||||||
lastId = it.last().id
|
lastId = it.last().id
|
||||||
}
|
}
|
||||||
@ -47,13 +59,37 @@ class CommentsViewModel @Inject constructor(private val getComments: GetComments
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun postComment(content: String) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
postComment(content, postId).onEach {
|
||||||
|
when(it) {
|
||||||
|
is Resource.Success -> {
|
||||||
|
commentPosted.postValue(true)
|
||||||
|
putCommentAtTheBeginning(it.data!!)
|
||||||
|
}
|
||||||
|
is Resource.Loading -> {
|
||||||
|
|
||||||
|
}
|
||||||
|
is Resource.Error -> {
|
||||||
|
commentPosted.postValue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.flowOn(Dispatchers.IO).launchIn(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handledCommentPosted() {
|
||||||
|
commentPosted.postValue(null)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use when new comment has been posted
|
* Use when new comment has been posted
|
||||||
*/
|
*/
|
||||||
fun putCommentAtTheBeginning(commentDto: Comment) {
|
private fun putCommentAtTheBeginning(comment: Comment) {
|
||||||
val newList: MutableList<Comment> = mutableListOf(commentDto)
|
val newList: MutableList<Comment> = mutableListOf(comment)
|
||||||
newList.addAll(_comments.value ?: mutableListOf())
|
newList.addAll(commentsList)
|
||||||
_comments.postValue(newList)
|
commentsList.clear()
|
||||||
|
commentsList.addAll(newList)
|
||||||
|
_comments.postValue(Pair(commentsList, UpdateEvent(UpdateEvent.UpdateType.COMMENT_ADDED_TOP, null)))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package com.isolaatti.posting.comments.presentation
|
||||||
|
|
||||||
|
|
||||||
|
data class UpdateEvent(val updateType: UpdateType, val affectedPosition: Int?) {
|
||||||
|
enum class UpdateType {
|
||||||
|
COMMENT_REMOVED,
|
||||||
|
COMMENT_ADDED_TOP,
|
||||||
|
COMMENT_PAGE_ADDED_BOTTOM,
|
||||||
|
REFRESH
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,9 +1,11 @@
|
|||||||
package com.isolaatti.posting.comments.presentation
|
package com.isolaatti.posting.comments.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.core.widget.doOnTextChanged
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
@ -13,15 +15,16 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
|
|||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
import com.isolaatti.common.Dialogs
|
import com.isolaatti.common.Dialogs
|
||||||
import com.isolaatti.databinding.BottomSheetPostCommentsBinding
|
import com.isolaatti.databinding.BottomSheetPostCommentsBinding
|
||||||
import com.isolaatti.home.FeedFragment
|
|
||||||
import com.isolaatti.posting.comments.domain.model.Comment
|
import com.isolaatti.posting.comments.domain.model.Comment
|
||||||
|
import com.isolaatti.posting.comments.presentation.CommentsRecyclerViewAdapter
|
||||||
|
import com.isolaatti.posting.comments.presentation.CommentsViewModel
|
||||||
|
import com.isolaatti.posting.comments.presentation.UpdateEvent
|
||||||
import com.isolaatti.posting.common.domain.OnUserInteractedCallback
|
import com.isolaatti.posting.common.domain.OnUserInteractedCallback
|
||||||
import com.isolaatti.posting.common.domain.Ownable
|
import com.isolaatti.posting.common.domain.Ownable
|
||||||
import com.isolaatti.posting.common.options_bottom_sheet.domain.OptionClicked
|
import com.isolaatti.posting.common.options_bottom_sheet.domain.OptionClicked
|
||||||
import com.isolaatti.posting.common.options_bottom_sheet.domain.Options
|
import com.isolaatti.posting.common.options_bottom_sheet.domain.Options
|
||||||
import com.isolaatti.posting.common.options_bottom_sheet.presentation.BottomSheetPostOptionsViewModel
|
import com.isolaatti.posting.common.options_bottom_sheet.presentation.BottomSheetPostOptionsViewModel
|
||||||
import com.isolaatti.posting.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment
|
import com.isolaatti.posting.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment
|
||||||
import com.isolaatti.posting.posts.domain.entity.Post
|
|
||||||
import com.isolaatti.profile.ui.ProfileActivity
|
import com.isolaatti.profile.ui.ProfileActivity
|
||||||
import com.isolaatti.utils.PicassoImagesPluginDef
|
import com.isolaatti.utils.PicassoImagesPluginDef
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
@ -36,12 +39,12 @@ class BottomSheetPostComments() : BottomSheetDialogFragment(), OnUserInteractedC
|
|||||||
|
|
||||||
private lateinit var viewBinding: BottomSheetPostCommentsBinding
|
private lateinit var viewBinding: BottomSheetPostCommentsBinding
|
||||||
val viewModel: CommentsViewModel by viewModels()
|
val viewModel: CommentsViewModel by viewModels()
|
||||||
|
private lateinit var adapter: CommentsRecyclerViewAdapter
|
||||||
|
|
||||||
val optionsViewModel: BottomSheetPostOptionsViewModel by activityViewModels()
|
val optionsViewModel: BottomSheetPostOptionsViewModel by activityViewModels()
|
||||||
|
|
||||||
val optionsObserver: Observer<OptionClicked?> = Observer { optionClicked ->
|
val optionsObserver: Observer<OptionClicked?> = Observer { optionClicked ->
|
||||||
if(optionClicked?.callerId == BottomSheetPostComments.CALLER_ID) {
|
if(optionClicked?.callerId == CALLER_ID) {
|
||||||
val comment = optionClicked.payload as? Comment ?: return@Observer
|
val comment = optionClicked.payload as? Comment ?: return@Observer
|
||||||
when(optionClicked.optionId) {
|
when(optionClicked.optionId) {
|
||||||
Options.Option.OPTION_DELETE -> {
|
Options.Option.OPTION_DELETE -> {
|
||||||
@ -65,6 +68,58 @@ class BottomSheetPostComments() : BottomSheetDialogFragment(), OnUserInteractedC
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val commentPostedObserver: Observer<Boolean?> = Observer {
|
||||||
|
when(it) {
|
||||||
|
true -> {
|
||||||
|
clearNewCommentUi()
|
||||||
|
Toast.makeText(requireContext(), "comment posted", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
false -> {
|
||||||
|
Toast.makeText(requireContext(), "comment failed to post", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
null -> return@Observer
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.handledCommentPosted()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setObservers() {
|
||||||
|
viewModel.comments.observe(viewLifecycleOwner) {
|
||||||
|
val (list, updateEvent) = it
|
||||||
|
adapter.updateList(list, updateEvent)
|
||||||
|
if(updateEvent.updateType == UpdateEvent.UpdateType.COMMENT_ADDED_TOP) {
|
||||||
|
(viewBinding.recyclerComments.layoutManager as LinearLayoutManager).scrollToPosition(0)
|
||||||
|
} else {
|
||||||
|
adapter.newContentRequestFinished()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewModel.noMoreContent.observe(viewLifecycleOwner) {
|
||||||
|
if(it == true) {
|
||||||
|
adapter.blockInfiniteScroll = true
|
||||||
|
viewModel.noMoreContent.postValue(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
optionsViewModel.optionClicked.observe(viewLifecycleOwner, optionsObserver)
|
||||||
|
viewModel.commentPosted.observe(viewLifecycleOwner, commentPostedObserver)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setListeners() {
|
||||||
|
viewBinding.newCommentTextField.editText?.doOnTextChanged { text, start, before, count ->
|
||||||
|
viewBinding.submitCommentButton.isEnabled = !text.isNullOrBlank()
|
||||||
|
}
|
||||||
|
|
||||||
|
viewBinding.submitCommentButton.setOnClickListener {
|
||||||
|
val content = viewBinding.newCommentTextField.editText?.text ?: return@setOnClickListener
|
||||||
|
viewModel.postComment(content.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearNewCommentUi() {
|
||||||
|
viewBinding.newCommentTextField.editText?.text?.clear()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
val postId = arguments?.getLong(ARG_POST_ID)
|
val postId = arguments?.getLong(ARG_POST_ID)
|
||||||
@ -102,23 +157,16 @@ class BottomSheetPostComments() : BottomSheetDialogFragment(), OnUserInteractedC
|
|||||||
.usePlugin(LinkifyPlugin.create())
|
.usePlugin(LinkifyPlugin.create())
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val adapter = CommentsRecyclerViewAdapter(listOf(), markwon, this)
|
adapter = CommentsRecyclerViewAdapter(listOf(), markwon, this)
|
||||||
viewBinding.recyclerComments.adapter = adapter
|
viewBinding.recyclerComments.adapter = adapter
|
||||||
viewBinding.recyclerComments.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
|
viewBinding.recyclerComments.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
|
||||||
|
|
||||||
viewModel.comments.observe(viewLifecycleOwner) {
|
// ensures send button is enabled when there is content on text field,
|
||||||
adapter.submitList(it)
|
// even if no change event is triggered
|
||||||
}
|
viewBinding.submitCommentButton.isEnabled = !viewBinding.newCommentTextField.editText?.text.isNullOrBlank()
|
||||||
|
|
||||||
// New comment area
|
|
||||||
val textField = viewBinding.newCommentTextField
|
|
||||||
|
|
||||||
textField.setStartIconOnClickListener {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
optionsViewModel.optionClicked.observe(viewLifecycleOwner, optionsObserver)
|
|
||||||
|
|
||||||
|
setObservers()
|
||||||
|
setListeners()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -148,6 +196,6 @@ class BottomSheetPostComments() : BottomSheetDialogFragment(), OnUserInteractedC
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onLoadMore() {
|
override fun onLoadMore() {
|
||||||
TODO("Not yet implemented")
|
viewModel.getContent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,13 +19,12 @@ import com.isolaatti.databinding.FragmentDiscussionsBinding
|
|||||||
import com.isolaatti.followers.domain.FollowingState
|
import com.isolaatti.followers.domain.FollowingState
|
||||||
import com.isolaatti.home.FeedFragment
|
import com.isolaatti.home.FeedFragment
|
||||||
import com.isolaatti.posting.PostViewerActivity
|
import com.isolaatti.posting.PostViewerActivity
|
||||||
import com.isolaatti.posting.comments.presentation.BottomSheetPostComments
|
import com.isolaatti.posting.comments.ui.BottomSheetPostComments
|
||||||
import com.isolaatti.posting.common.domain.Ownable
|
import com.isolaatti.posting.common.domain.Ownable
|
||||||
import com.isolaatti.posting.common.options_bottom_sheet.domain.OptionClicked
|
import com.isolaatti.posting.common.options_bottom_sheet.domain.OptionClicked
|
||||||
import com.isolaatti.posting.common.options_bottom_sheet.domain.Options
|
import com.isolaatti.posting.common.options_bottom_sheet.domain.Options
|
||||||
import com.isolaatti.posting.common.options_bottom_sheet.presentation.BottomSheetPostOptionsViewModel
|
import com.isolaatti.posting.common.options_bottom_sheet.presentation.BottomSheetPostOptionsViewModel
|
||||||
import com.isolaatti.posting.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment
|
import com.isolaatti.posting.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment
|
||||||
import com.isolaatti.posting.posts.data.remote.FeedDto
|
|
||||||
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
|
||||||
import com.isolaatti.posting.posts.presentation.EditPostContract
|
import com.isolaatti.posting.posts.presentation.EditPostContract
|
||||||
|
|||||||
@ -0,0 +1,4 @@
|
|||||||
|
package com.isolaatti.squads.ui
|
||||||
|
|
||||||
|
class SquadsActivity {
|
||||||
|
}
|
||||||
@ -80,6 +80,7 @@
|
|||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:layout_marginEnd="4dp"
|
android:layout_marginEnd="4dp"
|
||||||
android:layout_marginBottom="4dp"
|
android:layout_marginBottom="4dp"
|
||||||
|
android:enabled="false"
|
||||||
app:icon="@drawable/baseline_send_24"
|
app:icon="@drawable/baseline_send_24"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user