Show typing indicators

This commit is contained in:
Niels Andriesse
2021-06-24 11:22:32 +10:00
parent f66309afd8
commit 38710814e2
9 changed files with 84 additions and 12 deletions

View File

@@ -8,6 +8,7 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import org.thoughtcrime.securesms.conversation.v2.TypingIndicatorView;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsession.utilities.ThemeUtil;

View File

@@ -26,6 +26,8 @@ import kotlinx.android.synthetic.main.view_input_bar_recording.*
import kotlinx.android.synthetic.main.view_input_bar_recording.view.*
import network.loki.messenger.R
import org.session.libsession.messaging.mentions.MentionsManager
import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarButton
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarDelegate
@@ -106,6 +108,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
addOpenGroupGuidelinesIfNeeded()
scrollToBottomButton.setOnClickListener { conversationRecyclerView.smoothScrollToPosition(0) }
updateUnreadCount()
setUpTypingObserver()
}
private fun setUpRecyclerView() {
@@ -175,6 +178,15 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
conversationRecyclerView.layoutParams = recyclerViewLayoutParams
}
private fun setUpTypingObserver() {
ApplicationContext.getInstance(this).typingStatusRepository.getTypists(threadID).observe(this) { state ->
val recipients = if (state != null) state.typists else listOf()
typingIndicatorViewContainer.isVisible = recipients.isNotEmpty()
typingIndicatorViewContainer.setTypists(recipients)
inputBarHeightChanged(inputBar.height)
}
}
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
ConversationMenuHelper.onPrepareOptionsMenu(menu, menuInflater, thread, this) { onOptionsItemSelected(it) }
super.onPrepareOptionsMenu(menu)
@@ -189,9 +201,12 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
// region Updating & Animation
override fun inputBarHeightChanged(newValue: Int) {
// 36 DP is the exact height of the typing indicator view. It's also exactly 18 * 2, and 18 is the large message
// corner radius. This makes 36 DP look "correct" in the context of other messages on the screen.
val typingIndicatorHeight = if (typingIndicatorViewContainer.isVisible) toPx(36, resources) else 0
// Recycler view
val recyclerViewLayoutParams = conversationRecyclerView.layoutParams as RelativeLayout.LayoutParams
recyclerViewLayoutParams.bottomMargin = newValue + additionalContentContainer.height
recyclerViewLayoutParams.bottomMargin = newValue + additionalContentContainer.height + typingIndicatorHeight
conversationRecyclerView.layoutParams = recyclerViewLayoutParams
// Additional content container
val additionalContentContainerLayoutParams = additionalContentContainer.layoutParams as RelativeLayout.LayoutParams

View File

@@ -1,4 +1,4 @@
package org.thoughtcrime.securesms.components;
package org.thoughtcrime.securesms.conversation.v2;
import android.content.Context;
import android.content.res.TypedArray;
@@ -13,18 +13,14 @@ import android.widget.LinearLayout;
import network.loki.messenger.R;
public class TypingIndicatorView extends LinearLayout {
private boolean isActive;
private long startTime;
private static final long DURATION = 300;
private static final long PRE_DELAY = 500;
private static final long POST_DELAY = 500;
private static final long CYCLE_DURATION = 1500;
private static final long DOT_DURATION = 600;
private static final float MIN_ALPHA = 0.4f;
private static final float MIN_SCALE = 0.75f;
private boolean isActive;
private long startTime;
private View dot1;
private View dot2;
private View dot3;
@@ -40,7 +36,7 @@ public class TypingIndicatorView extends LinearLayout {
}
private void initialize(@Nullable AttributeSet attrs) {
inflate(getContext(), R.layout.typing_indicator_view, this);
inflate(getContext(), R.layout.view_typing_indicator, this);
setWillNotDraw(false);

View File

@@ -0,0 +1,25 @@
package org.thoughtcrime.securesms.conversation.v2
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.view_conversation_typing_container.view.*
import network.loki.messenger.R
import org.session.libsession.utilities.recipients.Recipient
class TypingIndicatorViewContainer : LinearLayout {
constructor(context: Context) : super(context) { initialize() }
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() }
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initialize() }
private fun initialize() {
LayoutInflater.from(context).inflate(R.layout.view_conversation_typing_container, this)
}
fun setTypists(typists: List<Recipient>) {
if (typists.isEmpty()) { typingIndicator.stopAnimation(); return }
typingIndicator.startAnimation()
}
}