This commit is contained in:
erike 2023-08-25 00:18:32 -06:00
parent 1e02f0bc6f
commit f91fa2d27d
12 changed files with 141 additions and 22 deletions

View File

@ -11,5 +11,6 @@ object Dialogs {
.setMessage(R.string.post_will_dropped)
.setPositiveButton(R.string.yes_continue) {_, _ -> onContinue(true)}
.setNegativeButton(R.string.cancel) { _, _ -> onContinue(false)}
.setOnCancelListener { onContinue(false) }
}
}

View File

@ -1,6 +1,5 @@
package com.isolaatti.home
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
@ -10,7 +9,6 @@ import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
@ -31,8 +29,9 @@ 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.presentation.BottomSheetPostOptionsViewModel
import com.isolaatti.posting.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment
import com.isolaatti.posting.posts.presentation.CreatePostContract
import com.isolaatti.posting.posts.presentation.EditPostContract
import com.isolaatti.posting.posts.presentation.PostsRecyclerViewAdapter
import com.isolaatti.posting.posts.ui.CreatePostActivity
import com.isolaatti.profile.ui.ProfileActivity
import com.isolaatti.settings.ui.SettingsActivity
import com.isolaatti.utils.PicassoImagesPluginDef
@ -62,12 +61,24 @@ class FeedFragment : Fragment(), OnUserInteractedWithPostCallback {
private lateinit var viewBinding: FragmentFeedBinding
private lateinit var adapter: PostsRecyclerViewAdapter
private val createDiscussion = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if(it.resultCode == Activity.RESULT_OK) {
// region launchers
private val createDiscussion = registerForActivityResult(CreatePostContract()) {
if(it != null) {
Toast.makeText(requireContext(), R.string.posted_successfully, Toast.LENGTH_SHORT).show()
}
}
private val editDiscussion = registerForActivityResult(EditPostContract()) {
if(it != null) {
viewModel.onPostUpdate(it)
}
}
// endregion
// region observers
val optionsObserver: Observer<OptionClicked?> = Observer { optionClicked ->
if(optionClicked?.callerId == CALLER_ID) {
// post id should come as payload
@ -84,7 +95,7 @@ class FeedFragment : Fragment(), OnUserInteractedWithPostCallback {
}
Options.Option.OPTION_EDIT -> {
optionsViewModel.handle()
CreatePostActivity.startActivityEditMode(requireContext(), postId)
editDiscussion.launch(postId)
}
Options.Option.OPTION_REPORT -> {
@ -93,6 +104,9 @@ class FeedFragment : Fragment(), OnUserInteractedWithPostCallback {
}
}
// endregion
// region lifecycle
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
@ -102,6 +116,9 @@ class FeedFragment : Fragment(), OnUserInteractedWithPostCallback {
return viewBinding.root
}
// endregion
// region events
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewBinding.topAppBar.setNavigationOnClickListener {
@ -156,7 +173,7 @@ class FeedFragment : Fragment(), OnUserInteractedWithPostCallback {
viewBinding.topAppBar.setOnMenuItemClickListener {
when(it.itemId) {
R.id.menu_item_new_discussion -> {
createDiscussion.launch(Intent(requireContext(),CreatePostActivity::class.java))
createDiscussion.launch(Unit)
true
}
else -> {
@ -232,4 +249,6 @@ class FeedFragment : Fragment(), OnUserInteractedWithPostCallback {
override fun onLoadMore() {
viewModel.getFeed(false)
}
// endregion
}

View File

@ -3,8 +3,8 @@ package com.isolaatti.posting.posts.data.remote
data class EditPostDto(
val privacy: Int,
val content: String,
val audioId: String?,
val squadId: String?,
val audioId: String? = null,
val squadId: String? = null,
val postId: Long
) {
companion object {

View File

@ -2,7 +2,9 @@ package com.isolaatti.posting.posts.data.remote
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
interface PostApi {
@POST("Posting/Make")
@ -14,4 +16,7 @@ interface PostApi {
@POST("Posting/Delete")
fun deletePost(@Body postToDelete: DeletePostDto): Call<PostDeletedDto>
@GET("Fetch/Post/{postId}")
fun getPost(@Path("postId") postId: Long): Call<FeedDto.PostDto>
}

View File

@ -111,4 +111,23 @@ class PostsRepositoryImpl @Inject constructor(private val feedsApi: FeedsApi, pr
emit(Resource.Error(Resource.Error.ErrorType.NetworkError))
}
}
override fun loadPost(postId: Long): Flow<Resource<FeedDto.PostDto>> = flow {
emit(Resource.Loading())
try {
val result = postApi.getPost(postId).execute()
if(result.isSuccessful) {
emit(Resource.Success(result.body()))
return@flow
}
when(result.code()) {
401 -> emit(Resource.Error(Resource.Error.ErrorType.AuthError))
404 -> emit(Resource.Error(Resource.Error.ErrorType.NotFoundError))
500 -> emit(Resource.Error(Resource.Error.ErrorType.ServerError))
else -> emit(Resource.Error(Resource.Error.ErrorType.OtherError))
}
} catch(_: Exception) {
emit(Resource.Error(Resource.Error.ErrorType.NetworkError))
}
}
}

View File

@ -17,4 +17,5 @@ interface PostsRepository {
fun makePost(createPostDto: CreatePostDto): Flow<Resource<FeedDto.PostDto>>
fun editPost(editPostDto: EditPostDto): Flow<Resource<FeedDto.PostDto>>
fun deletePost(postId: Long): Flow<Resource<PostDeletedDto>>
fun loadPost(postId: Long): Flow<Resource<FeedDto.PostDto>>
}

View File

@ -0,0 +1,13 @@
package com.isolaatti.posting.posts.domain.use_case
import com.isolaatti.posting.posts.data.remote.FeedDto
import com.isolaatti.posting.posts.domain.PostsRepository
import com.isolaatti.utils.Resource
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
class LoadSinglePost @Inject constructor(private val postsRepository: PostsRepository) {
operator fun invoke(postId: Long): Flow<Resource<FeedDto.PostDto>> {
return postsRepository.loadPost(postId)
}
}

View File

@ -0,0 +1,21 @@
package com.isolaatti.posting.posts.presentation
import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import androidx.activity.result.contract.ActivityResultContract
import com.isolaatti.posting.posts.data.remote.FeedDto
import com.isolaatti.posting.posts.ui.CreatePostActivity
class CreatePostContract : ActivityResultContract<Unit, FeedDto.PostDto?>() {
override fun createIntent(context: Context, input: Unit): Intent {
return Intent(context, CreatePostActivity::class.java)
}
override fun parseResult(resultCode: Int, intent: Intent?): FeedDto.PostDto? {
return if(resultCode == RESULT_OK) {
intent?.extras?.getParcelable(CreatePostActivity.EXTRA_KEY_POST_POSTED)
} else {
null
}
}
}

View File

@ -5,8 +5,10 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.isolaatti.posting.posts.data.remote.CreatePostDto
import com.isolaatti.posting.posts.data.remote.EditPostDto
import com.isolaatti.posting.posts.data.remote.EditPostDto.Companion.PRIVACY_ISOLAATTI
import com.isolaatti.posting.posts.data.remote.FeedDto
import com.isolaatti.posting.posts.domain.use_case.EditPost
import com.isolaatti.posting.posts.domain.use_case.LoadSinglePost
import com.isolaatti.posting.posts.domain.use_case.MakePost
import com.isolaatti.utils.Resource
import dagger.hilt.android.lifecycle.HiltViewModel
@ -18,11 +20,12 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class CreatePostViewModel @Inject constructor(private val makePost: MakePost, private val editPost: EditPost) : ViewModel() {
class CreatePostViewModel @Inject constructor(private val makePost: MakePost, private val editPost: EditPost, private val loadPost: LoadSinglePost) : ViewModel() {
val validation: MutableLiveData<Boolean> = MutableLiveData(false)
val posted: MutableLiveData<FeedDto.PostDto?> = MutableLiveData()
val error: MutableLiveData<Resource.Error.ErrorType?> = MutableLiveData()
val loading: MutableLiveData<Boolean> = MutableLiveData(false)
val postToEdit: MutableLiveData<EditPostDto> = MutableLiveData()
fun postDiscussion(content: String) {
viewModelScope.launch {
@ -64,4 +67,16 @@ class CreatePostViewModel @Inject constructor(private val makePost: MakePost, pr
}
}
fun loadDiscussion(postId: Long) {
viewModelScope.launch {
loadPost(postId).onEach { postRes ->
if(postRes is Resource.Success) {
postRes.data?.let {
postToEdit.postValue(EditPostDto(PRIVACY_ISOLAATTI, content = it.post.textContent, postId = it.post.id))
}
}
}.flowOn(Dispatchers.IO).launchIn(this)
}
}
}

View File

@ -0,0 +1,25 @@
package com.isolaatti.posting.posts.presentation
import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.activity.result.contract.ActivityResultContract
import com.isolaatti.posting.posts.data.remote.FeedDto
import com.isolaatti.posting.posts.ui.CreatePostActivity
class EditPostContract : ActivityResultContract<Long, FeedDto.PostDto?>() {
override fun createIntent(context: Context, input: Long): Intent {
return Intent(context, CreatePostActivity::class.java).apply {
putExtra(CreatePostActivity.EXTRA_KEY_MODE, CreatePostActivity.EXTRA_MODE_EDIT)
putExtra(CreatePostActivity.EXTRA_KEY_POST_ID, input)
}
}
override fun parseResult(resultCode: Int, intent: Intent?): FeedDto.PostDto? {
return if(resultCode == Activity.RESULT_OK) {
intent?.extras?.getParcelable(CreatePostActivity.EXTRA_KEY_POST_POSTED)
} else {
null
}
}
}

View File

@ -93,4 +93,8 @@ abstract class PostListingViewModelBase : ViewModel() {
}.flowOn(Dispatchers.IO).launchIn(this)
}
}
fun onPostUpdate(post: FeedDto.PostDto) {
}
}

View File

@ -1,14 +1,10 @@
package com.isolaatti.posting.posts.ui
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.PersistableBundle
import android.view.View
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat
import androidx.core.widget.doOnTextChanged
import com.isolaatti.R
import com.isolaatti.common.IsolaattiBaseActivity
@ -32,14 +28,6 @@ class CreatePostActivity : IsolaattiBaseActivity() {
const val EXTRA_KEY_POST_ID = "postId"
const val EXTRA_KEY_POST_POSTED = "post"
fun startActivityEditMode(context: Context, postId: Long) {
val intent = Intent(context, CreatePostActivity::class.java).apply {
putExtra(EXTRA_KEY_MODE, EXTRA_MODE_EDIT)
putExtra(EXTRA_KEY_POST_ID, postId)
}
context.startActivity(intent)
}
}
lateinit var binding: ActivityCreatePostBinding
@ -65,6 +53,10 @@ class CreatePostActivity : IsolaattiBaseActivity() {
binding = ActivityCreatePostBinding.inflate(layoutInflater)
if(mode == EXTRA_MODE_EDIT && postId != 0L) {
viewModel.loadDiscussion(postId)
}
setupUI()
@ -117,6 +109,10 @@ class CreatePostActivity : IsolaattiBaseActivity() {
viewModel.loading.observe(this@CreatePostActivity) {
binding.progressBarLoading.visibility = if(it) View.VISIBLE else View.GONE
}
viewModel.postToEdit.observe(this) {
binding.filledTextField.editText?.setText(it.content)
}
}
private fun exit() {