diff --git a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt index d23ed9b8..6c7c62f8 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt @@ -54,6 +54,7 @@ import androidx.core.view.inputmethod.InputContentInfoCompat import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.lifecycle.Observer +import androidx.lifecycle.Lifecycle import androidx.preference.PreferenceManager import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager @@ -97,6 +98,8 @@ import kotlin.collections.ArrayList import kotlin.math.max import kotlin.math.min import me.thanel.markdownedit.MarkdownEdit +import io.reactivex.android.schedulers.AndroidSchedulers +import com.uber.autodispose.android.lifecycle.autoDispose class ComposeActivity : BaseActivity(), ComposeOptionsListener, @@ -197,12 +200,14 @@ class ComposeActivity : BaseActivity(), viewModel.setupComplete.value = true stickerKeyboard.isSticky = true - - eventHub.events.subscribe { event -> - when(event) { - is StatusPreviewEvent -> onStatusPreviewReady(event.status) - } - } + + eventHub.events.observeOn(AndroidSchedulers.mainThread()) + .autoDispose(this, Lifecycle.Event.ON_DESTROY) + .subscribe { event: Event? -> + when(event) { + is StatusPreviewEvent -> onStatusPreviewReady(event.status) + } + } } private fun uriToFilename(uri: Uri): String { @@ -967,9 +972,8 @@ class ComposeActivity : BaseActivity(), } private fun onSendClicked(preview: Boolean) { - if(preview && previewBehavior.state == BottomSheetBehavior.STATE_EXPANDED) { + if(preview && previewBehavior.state != BottomSheetBehavior.STATE_HIDDEN) { previewBehavior.state = BottomSheetBehavior.STATE_HIDDEN - return } if (verifyScheduledTime()) { @@ -988,8 +992,6 @@ class ComposeActivity : BaseActivity(), emojiBehavior.state = BottomSheetBehavior.STATE_HIDDEN scheduleBehavior.state = BottomSheetBehavior.STATE_HIDDEN stickerBehavior.state = BottomSheetBehavior.STATE_HIDDEN - - // Log.d("ComposeActivityPreview", "Preview: " + status.content) } /** This is for the fancy keyboards which can insert images and stuff. */ @@ -1030,11 +1032,11 @@ class ComposeActivity : BaseActivity(), this, getString(R.string.dialog_title_finishing_media_upload), getString(R.string.dialog_message_uploading_media), true, true) - viewModel.sendStatus(contentText, spoilerText, preview).observe(this, Observer { + viewModel.sendStatus(contentText, spoilerText, preview).observeOnce(this) { finishingUploadDialog?.dismiss() if(!preview) deleteDraftAndFinish() - }) + } } else { composeEditField.error = getString(R.string.error_compose_character_limit) diff --git a/app/src/main/java/com/keylesspalace/tusky/service/SendTootService.kt b/app/src/main/java/com/keylesspalace/tusky/service/SendTootService.kt index 9dd6bba1..08f7aa4b 100644 --- a/app/src/main/java/com/keylesspalace/tusky/service/SendTootService.kt +++ b/app/src/main/java/com/keylesspalace/tusky/service/SendTootService.kt @@ -11,6 +11,7 @@ import android.content.Intent import android.os.Build import android.os.IBinder import android.os.Parcelable +import android.util.Log import androidx.core.app.NotificationCompat import androidx.core.app.ServiceCompat import androidx.core.content.ContextCompat @@ -130,8 +131,8 @@ class SendTootService : Service(), Injectable { tootToSend.retries++ - val contentType : String? = if(tootToSend.formattingSyntax.length == 0) null else tootToSend.formattingSyntax - val preview : Boolean? = if(tootToSend.preview) tootToSend.preview else null + val contentType : String? = if(tootToSend.formattingSyntax.isNotEmpty()) tootToSend.formattingSyntax else null + val preview : Boolean? = if(tootToSend.preview) true else null val newStatus = NewStatus( tootToSend.text, @@ -167,14 +168,11 @@ class SendTootService : Service(), Injectable { saveTootHelper.deleteDraft(tootToSend.savedTootUid) } - if (tootToSend.preview) { - response.body()?.let(::StatusPreviewEvent)?.let(eventHub::dispatch) - } else if (scheduled) { - response.body()?.let(::StatusScheduledEvent)?.let(eventHub::dispatch) - } else { - response.body()?.let(::StatusComposedEvent)?.let(eventHub::dispatch) + when { + tootToSend.preview -> response.body()?.let(::StatusPreviewEvent)?.let(eventHub::dispatch) + scheduled -> response.body()?.let(::StatusScheduledEvent)?.let(eventHub::dispatch) + else -> response.body()?.let(::StatusComposedEvent)?.let(eventHub::dispatch) } - notificationManager.cancel(tootId) } else { diff --git a/app/src/main/java/com/keylesspalace/tusky/util/LiveDataUtil.kt b/app/src/main/java/com/keylesspalace/tusky/util/LiveDataUtil.kt index b0048aef..867a5a81 100644 --- a/app/src/main/java/com/keylesspalace/tusky/util/LiveDataUtil.kt +++ b/app/src/main/java/com/keylesspalace/tusky/util/LiveDataUtil.kt @@ -27,6 +27,24 @@ inline fun LiveData.switchMap( crossinline switchMapFunction: (X) -> LiveData ): LiveData = Transformations.switchMap(this) { input -> switchMapFunction(input) } +fun LiveData.observeOnce(observer: (T) -> Unit) { + observeForever(object: Observer { + override fun onChanged(value: T) { + removeObserver(this) + observer(value) + } + }) +} + +fun LiveData.observeOnce(owner: LifecycleOwner, observer: (T) -> Unit) { + observe(owner, object: Observer { + override fun onChanged(value: T) { + removeObserver(this) + observer(value) + } + }) +} + inline fun LiveData.filter(crossinline predicate: (X) -> Boolean): LiveData { val liveData = MediatorLiveData() liveData.addSource(this) { value -> diff --git a/app/src/main/res/drawable/ic_preview_24dp.xml b/app/src/main/res/drawable/ic_preview_24dp.xml new file mode 100644 index 00000000..10523f9e --- /dev/null +++ b/app/src/main/res/drawable/ic_preview_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_compose.xml b/app/src/main/res/layout/activity_compose.xml index aab009ac..97559db7 100644 --- a/app/src/main/res/layout/activity_compose.xml +++ b/app/src/main/res/layout/activity_compose.xml @@ -262,7 +262,7 @@ android:paddingStart="16dp" android:paddingTop="8dp" android:paddingEnd="16dp" - android:paddingBottom="60dp" + android:paddingBottom="@dimen/compose_activity_bottom_bar_height" app:behavior_hideable="true" app:behavior_peekHeight="0dp" app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" /> @@ -276,7 +276,7 @@ android:paddingStart="24dp" android:paddingTop="12dp" android:paddingEnd="24dp" - android:paddingBottom="60dp" + android:paddingBottom="@dimen/compose_activity_bottom_bar_height" app:behavior_hideable="true" app:behavior_peekHeight="0dp" app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" /> @@ -290,7 +290,7 @@ android:paddingStart="16dp" android:paddingTop="8dp" android:paddingEnd="16dp" - android:paddingBottom="52dp" + android:paddingBottom="@dimen/compose_activity_bottom_bar_height" app:behavior_hideable="true" app:behavior_peekHeight="0dp" app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" /> @@ -301,19 +301,20 @@ android:layout_height="300dp" android:background="?attr/colorSurface" android:elevation="12dp" - android:paddingBottom="60dp" + android:paddingBottom="@dimen/compose_activity_bottom_bar_height" app:behavior_hideable="true" app:behavior_peekHeight="0dp" app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" /> - @@ -323,7 +324,7 @@ android:layout_height="wrap_content" android:background="?attr/colorSurface" /> - + 100dp 16dp + 60dp 200dp 100dp