make replying work

This commit is contained in:
Konrad Pozniak 2020-08-27 18:51:13 +02:00
parent 92333c8b57
commit 98811300d8
6 changed files with 44 additions and 8 deletions

View File

@ -80,7 +80,6 @@ class TimelineFragment : DaggerFragment(R.layout.fragment_timeline), TimeLineAct
adapter.addLoadStateListener { adapter.addLoadStateListener {
if (it.refresh != LoadState.Loading) { if (it.refresh != LoadState.Loading) {
binding.timelineSwipeRefresh.isRefreshing = false binding.timelineSwipeRefresh.isRefreshing = false
} }
} }
} }
@ -94,7 +93,7 @@ class TimelineFragment : DaggerFragment(R.layout.fragment_timeline), TimeLineAct
} }
override fun onReply(status: StatusEntity) { override fun onReply(status: StatusEntity) {
TODO("Not yet implemented") startActivity(DetailActivity.newIntent(requireContext(), status.actionableId, reply = true))
} }
override fun onMediaVisibilityChanged(status: StatusEntity) { override fun onMediaVisibilityChanged(status: StatusEntity) {

View File

@ -6,7 +6,6 @@ import android.os.Bundle
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.Insets import androidx.core.graphics.Insets
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.ConcatAdapter import androidx.recyclerview.widget.ConcatAdapter
import at.connyduck.pixelcat.R import at.connyduck.pixelcat.R
import at.connyduck.pixelcat.components.general.BaseActivity import at.connyduck.pixelcat.components.general.BaseActivity
@ -75,7 +74,7 @@ class DetailActivity : BaseActivity(), TimeLineActionListener {
viewModel.currentStatus.observe( viewModel.currentStatus.observe(
this, this,
Observer { {
when (it) { when (it) {
is Success -> { is Success -> {
binding.detailSwipeRefresh.show() binding.detailSwipeRefresh.show()
@ -84,6 +83,12 @@ class DetailActivity : BaseActivity(), TimeLineActionListener {
binding.detailSwipeRefresh.isRefreshing = false binding.detailSwipeRefresh.isRefreshing = false
binding.detailRecyclerView.show() binding.detailRecyclerView.show()
statusAdapter.submitList(listOf(it.data)) statusAdapter.submitList(listOf(it.data))
it.data?.let { status ->
if (intent.getBooleanExtra(EXTRA_REPLY, false)) {
intent.removeExtra(EXTRA_REPLY)
onReply(status)
}
}
} }
is Loading -> { is Loading -> {
binding.detailSwipeRefresh.hide() binding.detailSwipeRefresh.hide()
@ -102,7 +107,7 @@ class DetailActivity : BaseActivity(), TimeLineActionListener {
viewModel.replies.observe( viewModel.replies.observe(
this, this,
Observer { {
if (it is Success) { if (it is Success) {
repliesAdapter.submitList(it.data) repliesAdapter.submitList(it.data)
} }
@ -122,6 +127,12 @@ class DetailActivity : BaseActivity(), TimeLineActionListener {
val replyBottomsheet = BottomSheetBehavior.from(binding.detailReplyBottomSheet) val replyBottomsheet = BottomSheetBehavior.from(binding.detailReplyBottomSheet)
replyBottomsheet.state = BottomSheetBehavior.STATE_EXPANDED replyBottomsheet.state = BottomSheetBehavior.STATE_EXPANDED
binding.detailReply.requestFocus() binding.detailReply.requestFocus()
binding.detailReply.setText("@" + status.account.username + " ")
binding.detailReply.setSelection(binding.detailReply.text?.length ?: 0)
binding.detailReplyLayout.setEndIconOnClickListener {
viewModel.onReply(status, binding.detailReply.text?.toString().orEmpty())
}
} }
override fun onMediaVisibilityChanged(status: StatusEntity) { override fun onMediaVisibilityChanged(status: StatusEntity) {
@ -134,10 +145,12 @@ class DetailActivity : BaseActivity(), TimeLineActionListener {
companion object { companion object {
private const val EXTRA_STATUS_ID = "STATUS_ID" private const val EXTRA_STATUS_ID = "STATUS_ID"
private const val EXTRA_REPLY = "REPLY"
fun newIntent(context: Context, statusId: String): Intent { fun newIntent(context: Context, statusId: String, reply: Boolean = false): Intent {
return Intent(context, DetailActivity::class.java).apply { return Intent(context, DetailActivity::class.java).apply {
putExtra(EXTRA_STATUS_ID, statusId) putExtra(EXTRA_STATUS_ID, statusId)
putExtra(EXTRA_REPLY, reply)
} }
} }
} }

View File

@ -31,15 +31,18 @@ import at.connyduck.pixelcat.db.AccountManager
import at.connyduck.pixelcat.db.AppDatabase import at.connyduck.pixelcat.db.AppDatabase
import at.connyduck.pixelcat.db.entitity.StatusEntity import at.connyduck.pixelcat.db.entitity.StatusEntity
import at.connyduck.pixelcat.db.entitity.toEntity import at.connyduck.pixelcat.db.entitity.toEntity
import at.connyduck.pixelcat.model.NewStatus
import at.connyduck.pixelcat.network.FediverseApi import at.connyduck.pixelcat.network.FediverseApi
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.Locale
import javax.inject.Inject import javax.inject.Inject
class DetailViewModel @Inject constructor( class DetailViewModel @Inject constructor(
private val api: FediverseApi, private val api: FediverseApi,
private val db: AppDatabase, private val db: AppDatabase,
private val accountManager: AccountManager, private val accountManager: AccountManager,
private val useCases: TimelineUseCases private val useCases: TimelineUseCases,
private val fediverseApi: FediverseApi
) : ViewModel() { ) : ViewModel() {
val currentStatus = MutableLiveData<UiState<StatusEntity>>() val currentStatus = MutableLiveData<UiState<StatusEntity>>()
@ -122,4 +125,19 @@ class DetailViewModel @Inject constructor(
useCases.onMediaVisibilityChanged(status) useCases.onMediaVisibilityChanged(status)
} }
} }
fun onReply(statusToReply: StatusEntity, replyText: String) {
viewModelScope.launch {
fediverseApi.reply(
NewStatus(
status = replyText,
inReplyToId = statusToReply.actionableId,
visibility = statusToReply.visibility.name.toLowerCase(Locale.ROOT),
sensitive = statusToReply.sensitive,
mediaIds = null
)
)
}
}
} }

View File

@ -56,7 +56,7 @@ class NetworkModule {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
okHttpClientBuilder.addInterceptor( okHttpClientBuilder.addInterceptor(
HttpLoggingInterceptor().apply { HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BASIC level = HttpLoggingInterceptor.Level.BODY
} }
) )
} }

View File

@ -165,6 +165,11 @@ interface FediverseApi {
@Body status: NewStatus @Body status: NewStatus
): NetworkResponse<Status> ): NetworkResponse<Status>
@POST("api/v1/statuses")
suspend fun reply(
@Body status: NewStatus
): NetworkResponse<Status>
@POST("api/v1/statuses/{id}/favourite") @POST("api/v1/statuses/{id}/favourite")
suspend fun favouriteStatus( suspend fun favouriteStatus(
@Path("id") statusId: String @Path("id") statusId: String

View File

@ -77,6 +77,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/detailReplyLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"