8770fbe986
* Convert ComposeActivity to Kotlin * More ComposeActivity cleanups * Move ComposeActivity to it's own package * Remove ComposeActivity.IntentBuilder * Re-do part of the media downsizing/uploading * Add sending of status to ViewModel, draft media descriptions * Allow uploading video, update description after uploading * Enable camera, enable upload cancelling * Cleanup of ComposeActivity * Extract CaptionDialog, extract ComposeActivity methods * Fix handling of redrafted media * Add initial state and media uploading out of Activity * Change ComposeOptions.mentionedUsernames to be Set rather than List We probably don't want repeated usernames when we are writing a post and Set provides such guarantee for free plus it tells it to the callers. The only disadvantage is lack of order but it shouldn't be a problem. * Add combineOptionalLiveData. Add docs. It it useful for nullable LiveData's. I think we cannot differentiate between value not being set and value being null so I just added the variant without null check. * Add poll support to Compose. * cleanup code * move more classes into compose package * cleanup code * fix button behavior * add error handling for media upload * add caching for instance data again * merge develop * fix scheduled toots * delete unused string * cleanup ComposeActivity * fix restoring media from drafts * make media upload code a little bit clearer * cleanup autocomplete search code * avoid duplicate object creation in SavedTootActivity * perf: avoid unnecessary work when initializing ComposeActivity * add license header to new files * use small toot button on bigger displays * fix ComposeActivityTest * fix bad merge * use Singles.zip instead of Single.zip
168 lines
6.3 KiB
Kotlin
168 lines
6.3 KiB
Kotlin
package com.keylesspalace.tusky
|
|
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.os.Bundle
|
|
import android.view.View
|
|
import androidx.appcompat.widget.Toolbar
|
|
import androidx.lifecycle.Lifecycle
|
|
import androidx.recyclerview.widget.DividerItemDecoration
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
|
import com.keylesspalace.tusky.adapter.ScheduledTootAdapter
|
|
import com.keylesspalace.tusky.appstore.EventHub
|
|
import com.keylesspalace.tusky.appstore.StatusScheduledEvent
|
|
import com.keylesspalace.tusky.components.compose.ComposeActivity
|
|
import com.keylesspalace.tusky.di.Injectable
|
|
import com.keylesspalace.tusky.entity.ScheduledStatus
|
|
import com.keylesspalace.tusky.network.MastodonApi
|
|
import com.keylesspalace.tusky.util.hide
|
|
import com.keylesspalace.tusky.util.show
|
|
import com.uber.autodispose.AutoDispose.autoDisposable
|
|
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider.from
|
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
|
import kotlinx.android.synthetic.main.activity_scheduled_toot.*
|
|
import okhttp3.ResponseBody
|
|
import retrofit2.Call
|
|
import retrofit2.Callback
|
|
import retrofit2.Response
|
|
import javax.inject.Inject
|
|
|
|
|
|
class ScheduledTootActivity : BaseActivity(), ScheduledTootAdapter.ScheduledTootAction, Injectable {
|
|
|
|
companion object {
|
|
@JvmStatic
|
|
fun newIntent(context: Context): Intent {
|
|
return Intent(context, ScheduledTootActivity::class.java)
|
|
}
|
|
}
|
|
|
|
lateinit var adapter: ScheduledTootAdapter
|
|
|
|
@Inject
|
|
lateinit var mastodonApi: MastodonApi
|
|
@Inject
|
|
lateinit var eventHub: EventHub
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
setContentView(R.layout.activity_scheduled_toot)
|
|
|
|
val toolbar = findViewById<Toolbar>(R.id.toolbar)
|
|
|
|
setSupportActionBar(toolbar)
|
|
val bar = supportActionBar
|
|
if (bar != null) {
|
|
bar.title = getString(R.string.title_scheduled_toot)
|
|
bar.setDisplayHomeAsUpEnabled(true)
|
|
bar.setDisplayShowHomeEnabled(true)
|
|
}
|
|
|
|
swipe_refresh_layout.setOnRefreshListener(this::refreshStatuses)
|
|
|
|
scheduled_toot_list.setHasFixedSize(true)
|
|
val layoutManager = LinearLayoutManager(this)
|
|
scheduled_toot_list.layoutManager = layoutManager
|
|
val divider = DividerItemDecoration(this, layoutManager.orientation)
|
|
scheduled_toot_list.addItemDecoration(divider)
|
|
adapter = ScheduledTootAdapter(this)
|
|
scheduled_toot_list.adapter = adapter
|
|
|
|
loadStatuses()
|
|
|
|
eventHub.events
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
.`as`(autoDisposable(from(this, Lifecycle.Event.ON_DESTROY)))
|
|
.subscribe { event ->
|
|
if (event is StatusScheduledEvent) {
|
|
refreshStatuses()
|
|
}
|
|
}
|
|
}
|
|
|
|
fun loadStatuses() {
|
|
progress_bar.visibility = View.VISIBLE
|
|
mastodonApi.scheduledStatuses()
|
|
.enqueue(object : Callback<List<ScheduledStatus>> {
|
|
override fun onResponse(call: Call<List<ScheduledStatus>>, response: Response<List<ScheduledStatus>>) {
|
|
progress_bar.visibility = View.GONE
|
|
if (response.body().isNullOrEmpty()) {
|
|
errorMessageView.show()
|
|
errorMessageView.setup(R.drawable.elephant_friend_empty, R.string.message_empty,
|
|
null)
|
|
} else {
|
|
show(response.body()!!)
|
|
}
|
|
}
|
|
|
|
override fun onFailure(call: Call<List<ScheduledStatus>>, t: Throwable) {
|
|
progress_bar.visibility = View.GONE
|
|
errorMessageView.show()
|
|
errorMessageView.setup(R.drawable.elephant_error, R.string.error_generic) {
|
|
errorMessageView.hide()
|
|
loadStatuses()
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
private fun refreshStatuses() {
|
|
swipe_refresh_layout.isRefreshing = true
|
|
mastodonApi.scheduledStatuses()
|
|
.enqueue(object : Callback<List<ScheduledStatus>> {
|
|
override fun onResponse(call: Call<List<ScheduledStatus>>, response: Response<List<ScheduledStatus>>) {
|
|
swipe_refresh_layout.isRefreshing = false
|
|
if (response.body().isNullOrEmpty()) {
|
|
errorMessageView.show()
|
|
errorMessageView.setup(R.drawable.elephant_friend_empty, R.string.message_empty,
|
|
null)
|
|
} else {
|
|
show(response.body()!!)
|
|
}
|
|
}
|
|
|
|
override fun onFailure(call: Call<List<ScheduledStatus>>, t: Throwable) {
|
|
swipe_refresh_layout.isRefreshing = false
|
|
}
|
|
})
|
|
}
|
|
|
|
fun show(statuses: List<ScheduledStatus>) {
|
|
adapter.setItems(statuses)
|
|
adapter.notifyDataSetChanged()
|
|
}
|
|
|
|
override fun edit(position: Int, item: ScheduledStatus?) {
|
|
if (item == null) {
|
|
return
|
|
}
|
|
val intent = ComposeActivity.startIntent(this, ComposeActivity.ComposeOptions(
|
|
tootText = item.params.text,
|
|
contentWarning = item.params.spoilerText,
|
|
mediaAttachments = item.mediaAttachments,
|
|
inReplyToId = item.params.inReplyToId,
|
|
visibility = item.params.visibility,
|
|
scheduledAt = item.scheduledAt,
|
|
sensitive = item.params.sensitive
|
|
))
|
|
startActivity(intent)
|
|
delete(position, item)
|
|
}
|
|
|
|
override fun delete(position: Int, item: ScheduledStatus?) {
|
|
if (item == null) {
|
|
return
|
|
}
|
|
mastodonApi.deleteScheduledStatus(item.id)
|
|
.enqueue(object : Callback<ResponseBody> {
|
|
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
|
|
adapter.removeItem(position)
|
|
}
|
|
|
|
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
|
|
|
|
}
|
|
})
|
|
}
|
|
}
|