Skip to content

Commit

Permalink
Merge pull request #221 from gavine99/send_immediately_35
Browse files Browse the repository at this point in the history
Send delayed sms immediately
  • Loading branch information
octoshrimpy authored Jan 29, 2025
2 parents 693533a + c7e5899 commit d376f1b
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 193 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
override val messagePartClickIntent: Subject<Long> by lazy { messageAdapter.partClicks }
override val messagesSelectedIntent by lazy { messageAdapter.selectionChanges }
override val cancelSendingIntent: Subject<Long> by lazy { messageAdapter.cancelSending }
override val sendNowIntent: Subject<Long> by lazy { messageAdapter.sendNow }
override val attachmentDeletedIntent: Subject<Attachment> by lazy { attachmentAdapter.attachmentDeleted }
override val textChangedIntent by lazy { message.textChanges() }
override val attachIntent by lazy { Observable.merge(attach.clicks(), attachingBackground.clicks()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ interface ComposeView : QkView<ComposeState> {
val messagePartClickIntent: Subject<Long>
val messagesSelectedIntent: Observable<List<Long>>
val cancelSendingIntent: Subject<Long>
val sendNowIntent: Subject<Long>
val attachmentDeletedIntent: Subject<Attachment>
val textChangedIntent: Observable<CharSequence>
val attachIntent: Observable<Unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,26 @@ class ComposeViewModel @Inject constructor(
cancelMessage.execute(CancelDelayedMessage.Params(message.id, message.threadId))
}

// send a delayed message now
view.sendNowIntent
.mapNotNull(messageRepo::getMessage)
.autoDisposable(view.scope())
.subscribe { message ->
cancelMessage.execute(CancelDelayedMessage.Params(message.id, message.threadId))
val address = listOf(conversationRepo
.getConversation(threadId)?.recipients?.firstOrNull()?.address ?: message.address)
sendMessage.execute(
SendMessage.Params(
message.subId,
message.threadId,
address,
message.body,
listOf(), // sms with attachments (mms) can't be delayed so we can know attachments are empty for a 'send now' delayed sms
0
)
)
}

// Set the current conversation
Observables
.combineLatest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package dev.octoshrimpy.quik.feature.compose
import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.Typeface
import android.os.Build
import android.text.Layout
import android.text.Spannable
import android.text.SpannableString
Expand Down Expand Up @@ -69,6 +70,7 @@ import kotlinx.android.synthetic.main.message_list_item_in.status
import kotlinx.android.synthetic.main.message_list_item_in.timestamp
import kotlinx.android.synthetic.main.message_list_item_in.view.*
import kotlinx.android.synthetic.main.message_list_item_out.*
import kotlinx.android.synthetic.main.message_list_item_out.view.cancel
import java.util.*
import java.util.concurrent.TimeUnit
import javax.inject.Inject
Expand Down Expand Up @@ -106,6 +108,7 @@ class MessagesAdapter @Inject constructor(
val clicks: Subject<Long> = PublishSubject.create()
val partClicks: Subject<Long> = PublishSubject.create()
val cancelSending: Subject<Long> = PublishSubject.create()
val sendNow: Subject<Long> = PublishSubject.create()

var data: Pair<Conversation, RealmResults<Message>>? = null
set(value) {
Expand Down Expand Up @@ -157,6 +160,7 @@ class MessagesAdapter @Inject constructor(
view = layoutInflater.inflate(R.layout.message_list_item_out, parent, false)
view.findViewById<ImageView>(R.id.cancelIcon).setTint(theme.theme)
view.findViewById<ProgressBar>(R.id.cancel).setTint(theme.theme)
view.findViewById<ImageView>(R.id.sendNowIcon).setTint(theme.theme)
} else {
view = layoutInflater.inflate(R.layout.message_list_item_in, parent, false)
}
Expand Down Expand Up @@ -202,25 +206,37 @@ class MessagesAdapter @Inject constructor(
// Update the selected state
holder.containerView.isActivated = isSelected(message.id) || highlight == message.id

// Bind the cancel view
holder.cancel?.let { cancel ->
val isCancellable = message.isSending() && message.date > System.currentTimeMillis()
cancel.setVisible(isCancellable)
cancel.clicks().subscribe { cancelSending.onNext(message.id) }
cancel.progress = 2

if (isCancellable) {
val delay = when (prefs.sendDelay.get()) {
Preferences.SEND_DELAY_SHORT -> 3000
Preferences.SEND_DELAY_MEDIUM -> 5000
Preferences.SEND_DELAY_LONG -> 10000
else -> 0
}
val progress = (1 - (message.date - System.currentTimeMillis()) / delay.toFloat()) * 100
// Bind the cancelFrame (cancel button) view
if (holder.cancelFrame != null) {
holder.cancelFrame.let { cancelFrame ->
val isCancellable = message.isSending() && message.date > System.currentTimeMillis()
cancelFrame.visibility = if (isCancellable) View.VISIBLE else View.GONE
cancelFrame.clicks().subscribe { cancelSending.onNext(message.id) }
cancelFrame.cancel.progress = 2

if (isCancellable) {
val delay = when (prefs.sendDelay.get()) {
Preferences.SEND_DELAY_SHORT -> 3000
Preferences.SEND_DELAY_MEDIUM -> 5000
Preferences.SEND_DELAY_LONG -> 10000
else -> 0
}
val progress =
(1 - (message.date - System.currentTimeMillis()) / delay.toFloat()) * 100

ObjectAnimator.ofInt(cancel, "progress", progress.toInt(), 100)
ObjectAnimator.ofInt(cancelFrame.cancel, "progress", progress.toInt(), 100)
.setDuration(message.date - System.currentTimeMillis())
.start()
}
}
}

// Bind the send now icon view
if (holder.sendNowIcon != null) {
holder.sendNowIcon.let { sendNowIcon ->
val isCancellable = message.isSending() && message.date > System.currentTimeMillis()
sendNowIcon.visibility = if (isCancellable) View.VISIBLE else View.GONE
sendNowIcon.clicks().subscribe { sendNow.onNext(message.id) }
}
}

Expand Down
2 changes: 0 additions & 2 deletions presentation/src/main/res/layout/compose_activity.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="12dp"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingTop="8dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@id/messageBackground"
Expand Down
167 changes: 89 additions & 78 deletions presentation/src/main/res/layout/message_list_item_in.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,96 +17,107 @@
~ You should have received a copy of the GNU General Public License
~ along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground">
android:layout_marginEnd="36dp"
android:background="?attr/selectableItemBackground"
android:orientation="vertical">

<dev.octoshrimpy.quik.common.widget.QkTextView
android:id="@+id/timestamp"
style="@style/TextSecondary"
android:layout_width="wrap_content"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="8dp"
app:layout_constraintEnd_toStartOf="@id/sim"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Tue at 11:39pm" />
android:background="?attr/selectableItemBackground">

<ImageView
android:id="@+id/sim"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginEnd="2dp"
android:src="@drawable/ic_sim_card_black_24dp"
android:tint="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="@id/timestamp"
app:layout_constraintEnd_toStartOf="@id/simIndex"
app:layout_constraintStart_toEndOf="@id/timestamp"
app:layout_constraintTop_toTopOf="@id/timestamp" />
<dev.octoshrimpy.quik.common.widget.QkTextView
android:id="@+id/timestamp"
style="@style/TextSecondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="8dp"
app:layout_constraintEnd_toStartOf="@id/sim"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Tue at 11:39pm" />

<dev.octoshrimpy.quik.common.widget.QkTextView
android:id="@+id/simIndex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="@id/timestamp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/sim"
app:layout_constraintTop_toTopOf="@id/timestamp"
app:textSize="tertiary"
tools:text="1" />
<ImageView
android:id="@+id/sim"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginEnd="2dp"
android:src="@drawable/ic_sim_card_black_24dp"
app:layout_constraintBottom_toBottomOf="@id/timestamp"
app:layout_constraintEnd_toStartOf="@id/simIndex"
app:layout_constraintStart_toEndOf="@id/timestamp"
app:layout_constraintTop_toTopOf="@id/timestamp"
app:tint="?android:attr/textColorSecondary" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/attachments"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:nestedScrollingEnabled="false"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@id/timestamp"
tools:itemCount="1"
tools:listitem="@layout/mms_image_preview_list_item" />
<dev.octoshrimpy.quik.common.widget.QkTextView
android:id="@+id/simIndex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="@id/timestamp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/sim"
app:layout_constraintTop_toTopOf="@id/timestamp"
app:textSize="tertiary"
tools:text="1" />

<dev.octoshrimpy.quik.common.widget.AvatarView
android:id="@+id/avatar"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="12dp"
app:layout_constraintBottom_toBottomOf="@id/body"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

<dev.octoshrimpy.quik.common.widget.TightTextView
android:id="@+id/body"
style="@style/TextPrimary"
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="12dp"
android:autoLink="email|phone|web"
android:background="@drawable/message_only"
android:gravity="start|center_vertical"
android:minHeight="36dp"
android:textIsSelectable="true"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@id/attachments"
app:layout_constraintWidth_max="384dp"
tools:backgroundTint="@color/tools_theme"
tools:text="@tools:sample/lorem/random" />
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent">

<dev.octoshrimpy.quik.common.widget.AvatarView
android:id="@+id/avatar"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="bottom"
app:layout_constraintBottom_toBottomOf="@id/body"
app:layout_constraintStart_toStartOf="parent" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:orientation="vertical">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/attachments"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="1"
tools:listitem="@layout/mms_image_preview_list_item" />

<dev.octoshrimpy.quik.common.widget.TightTextView
android:id="@+id/body"
style="@style/TextPrimary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:autoLink="email|phone|web"
android:background="@drawable/message_only"
android:gravity="start|center_vertical"
android:minHeight="36dp"
android:textIsSelectable="true"
tools:backgroundTint="@color/tools_theme"
tools:text="@tools:sample/lorem/random" />
</LinearLayout>

</LinearLayout>

<dev.octoshrimpy.quik.common.widget.QkTextView
android:id="@+id/status"
Expand All @@ -123,4 +134,4 @@
app:textSize="tertiary"
tools:text="Sending..." />

</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
Loading

0 comments on commit d376f1b

Please sign in to comment.