render inReplyTo message
This commit is contained in:
parent
a4fe60dece
commit
1b3c7b6a42
|
@ -96,15 +96,34 @@ public final class MessageWithContentReactions
|
||||||
|
|
||||||
public String textContent() {
|
public String textContent() {
|
||||||
final var content = Iterables.getFirst(this.contents, null);
|
final var content = Iterables.getFirst(this.contents, null);
|
||||||
final var text = Strings.nullToEmpty(content == null ? null : content.body);
|
return Strings.nullToEmpty(content == null ? null : content.body);
|
||||||
return text;
|
|
||||||
// return text.substring(0,Math.min(text.length(),20));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasPreview() {
|
public boolean hasPreview() {
|
||||||
return Iterables.tryFind(this.contents, c -> c.type == PartType.FILE).isPresent();
|
return Iterables.tryFind(this.contents, c -> c.type == PartType.FILE).isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasInReplyTo() {
|
||||||
|
return this.inReplyTo != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant inReplyToSentAt() {
|
||||||
|
return this.inReplyTo == null ? null : this.inReplyTo.sentAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String inReplyToSender() {
|
||||||
|
return this.inReplyTo == null ? null : this.inReplyTo.fromResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String inReplyToTextContent() {
|
||||||
|
final var inReplyTo = this.inReplyTo;
|
||||||
|
if (inReplyTo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final var content = Iterables.getFirst(inReplyTo.contents, null);
|
||||||
|
return Strings.nullToEmpty(content == null ? null : content.body);
|
||||||
|
}
|
||||||
|
|
||||||
public AddressWithName getAddressWithName() {
|
public AddressWithName getAddressWithName() {
|
||||||
if (isKnownSender()) {
|
if (isKnownSender()) {
|
||||||
return new AddressWithName(individualAddress(), individualName());
|
return new AddressWithName(individualAddress(), individualName());
|
||||||
|
|
|
@ -15,6 +15,7 @@ import im.conversations.android.databinding.ItemMessageReceivedBinding;
|
||||||
import im.conversations.android.databinding.ItemMessageSentBinding;
|
import im.conversations.android.databinding.ItemMessageSentBinding;
|
||||||
import im.conversations.android.databinding.ItemMessageSeparatorBinding;
|
import im.conversations.android.databinding.ItemMessageSeparatorBinding;
|
||||||
import im.conversations.android.ui.AvatarFetcher;
|
import im.conversations.android.ui.AvatarFetcher;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -27,6 +28,8 @@ public class MessageAdapter
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(MessageAdapter.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(MessageAdapter.class);
|
||||||
|
|
||||||
|
private Consumer<Long> onNavigateToInReplyTo;
|
||||||
|
|
||||||
public MessageAdapter(@NonNull DiffUtil.ItemCallback<MessageAdapterItem> diffCallback) {
|
public MessageAdapter(@NonNull DiffUtil.ItemCallback<MessageAdapterItem> diffCallback) {
|
||||||
super(diffCallback);
|
super(diffCallback);
|
||||||
}
|
}
|
||||||
|
@ -90,7 +93,12 @@ public class MessageAdapter
|
||||||
@NonNull AbstractMessageViewHolder holder,
|
@NonNull AbstractMessageViewHolder holder,
|
||||||
@NonNull final MessageWithContentReactions message) {
|
@NonNull final MessageWithContentReactions message) {
|
||||||
holder.setItem(message);
|
holder.setItem(message);
|
||||||
|
final var inReplyTo = message.inReplyTo;
|
||||||
if (holder instanceof MessageReceivedViewHolder messageReceivedViewHolder) {
|
if (holder instanceof MessageReceivedViewHolder messageReceivedViewHolder) {
|
||||||
|
if (inReplyTo != null) {
|
||||||
|
messageReceivedViewHolder.binding.embeddedMessage.setOnClickListener(
|
||||||
|
view -> onNavigateToInReplyTo.accept(inReplyTo.id));
|
||||||
|
}
|
||||||
final var addressWithName = message.getAddressWithName();
|
final var addressWithName = message.getAddressWithName();
|
||||||
final var avatar = message.getAvatar();
|
final var avatar = message.getAvatar();
|
||||||
if (avatar != null) {
|
if (avatar != null) {
|
||||||
|
@ -98,9 +106,18 @@ public class MessageAdapter
|
||||||
} else {
|
} else {
|
||||||
AvatarFetcher.setDefault(messageReceivedViewHolder.binding.avatar, addressWithName);
|
AvatarFetcher.setDefault(messageReceivedViewHolder.binding.avatar, addressWithName);
|
||||||
}
|
}
|
||||||
|
} else if (holder instanceof MessageSentViewHolder messageSentViewHolder) {
|
||||||
|
if (inReplyTo != null) {
|
||||||
|
messageSentViewHolder.binding.embeddedMessage.setOnClickListener(
|
||||||
|
view -> onNavigateToInReplyTo.accept(inReplyTo.id));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOnNavigateToInReplyTo(final Consumer<Long> consumer) {
|
||||||
|
this.onNavigateToInReplyTo = consumer;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract static class AbstractMessageViewHolder extends RecyclerView.ViewHolder {
|
protected abstract static class AbstractMessageViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
private AbstractMessageViewHolder(@NonNull View itemView) {
|
private AbstractMessageViewHolder(@NonNull View itemView) {
|
||||||
|
|
|
@ -53,6 +53,7 @@ public class ChatFragment extends Fragment {
|
||||||
this.binding.messages.setLayoutManager(linearLayoutManager);
|
this.binding.messages.setLayoutManager(linearLayoutManager);
|
||||||
this.recyclerViewScroller = new RecyclerViewScroller(this.binding.messages);
|
this.recyclerViewScroller = new RecyclerViewScroller(this.binding.messages);
|
||||||
this.messageAdapter = new MessageAdapter(new MessageComparator());
|
this.messageAdapter = new MessageAdapter(new MessageComparator());
|
||||||
|
this.messageAdapter.setOnNavigateToInReplyTo(this::onNavigateToInReplyTo);
|
||||||
this.binding.messages.setAdapter(this.messageAdapter);
|
this.binding.messages.setAdapter(this.messageAdapter);
|
||||||
|
|
||||||
this.chatViewModel.getMessages().observe(getViewLifecycleOwner(), this::submitPagingData);
|
this.chatViewModel.getMessages().observe(getViewLifecycleOwner(), this::submitPagingData);
|
||||||
|
@ -64,10 +65,6 @@ public class ChatFragment extends Fragment {
|
||||||
NavControllers.findNavController(requireActivity(), R.id.nav_host_fragment)
|
NavControllers.findNavController(requireActivity(), R.id.nav_host_fragment)
|
||||||
.popBackStack();
|
.popBackStack();
|
||||||
});
|
});
|
||||||
this.binding.addContent.setOnClickListener(
|
|
||||||
v -> {
|
|
||||||
scrollToMessageId(1039);
|
|
||||||
});
|
|
||||||
this.binding.messageLayout.setEndIconOnClickListener(
|
this.binding.messageLayout.setEndIconOnClickListener(
|
||||||
v -> {
|
v -> {
|
||||||
this.scrollToPositionToEnd();
|
this.scrollToPositionToEnd();
|
||||||
|
@ -76,6 +73,10 @@ public class ChatFragment extends Fragment {
|
||||||
return this.binding.getRoot();
|
return this.binding.getRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onNavigateToInReplyTo(long messageId) {
|
||||||
|
this.scrollToMessageId(messageId);
|
||||||
|
}
|
||||||
|
|
||||||
private void submitPagingData(final Boolean isShowDateSeparators) {
|
private void submitPagingData(final Boolean isShowDateSeparators) {
|
||||||
final var pagingData = this.chatViewModel.getMessages().getValue();
|
final var pagingData = this.chatViewModel.getMessages().getValue();
|
||||||
if (pagingData == null) {
|
if (pagingData == null) {
|
||||||
|
|
|
@ -34,6 +34,53 @@
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintWidth_max="@dimen/message_bubble_max_width">
|
app:layout_constraintWidth_max="@dimen/message_bubble_max_width">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/embeddedMessage"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?colorPrimaryContainer"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:visibility="@{message.hasInReplyTo ? View.VISIBLE : View.GONE}"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/embeddedMessageSender"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@{message.inReplyToSender}"
|
||||||
|
android:textAppearance="?textAppearanceTitleSmall"
|
||||||
|
android:textColor="?colorOnPrimaryContainer"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Romeo Montague" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4sp"
|
||||||
|
android:textAppearance="?textAppearanceLabelSmall"
|
||||||
|
android:textColor="?colorOnPrimaryContainer"
|
||||||
|
app:datetime="@{message.inReplyToSentAt}"
|
||||||
|
app:layout_constraintBaseline_toBaselineOf="@+id/embeddedMessageSender"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/embeddedMessageSender"
|
||||||
|
tools:text="11:23 PM" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/embeddedMessageText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4sp"
|
||||||
|
android:text="@{message.inReplyToTextContent}"
|
||||||
|
android:textAppearance="?textAppearanceBodySmall"
|
||||||
|
android:textColor="?colorOnPrimaryContainer"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/embeddedMessageSender"
|
||||||
|
tools:text="In lorem orci, faucibus a magna a, auctor feugiat lorem. Sed efficitur turpis nisi, nec ultrices arcu tempus et. Nulla consectetur sodales tortor, at cursus erat ultricies non." />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/image"
|
android:id="@+id/image"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -43,13 +90,14 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHeight_max="@dimen/message_preview_max_height"
|
app:layout_constraintHeight_max="@dimen/message_preview_max_height"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toBottomOf="@+id/embeddedMessage"
|
||||||
app:layout_constraintWidth_max="@dimen/message_preview_max_width" />
|
app:layout_constraintWidth_max="@dimen/message_preview_max_width" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/textContentWrapper"
|
android:id="@+id/textContentWrapper"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
|
|
@ -24,6 +24,53 @@
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintWidth_max="@dimen/message_bubble_max_width">
|
app:layout_constraintWidth_max="@dimen/message_bubble_max_width">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/embeddedMessage"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?colorPrimaryContainer"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:visibility="@{message.hasInReplyTo ? View.VISIBLE : View.GONE}"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/embeddedMessageSender"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@{message.inReplyToSender}"
|
||||||
|
android:textAppearance="?textAppearanceTitleSmall"
|
||||||
|
android:textColor="?colorOnPrimaryContainer"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Romeo Montague" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4sp"
|
||||||
|
android:textAppearance="?textAppearanceLabelSmall"
|
||||||
|
android:textColor="?colorOnPrimaryContainer"
|
||||||
|
app:datetime="@{message.inReplyToSentAt}"
|
||||||
|
app:layout_constraintBaseline_toBaselineOf="@+id/embeddedMessageSender"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/embeddedMessageSender"
|
||||||
|
tools:text="11:23 PM" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/embeddedMessageText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4sp"
|
||||||
|
android:text="@{message.inReplyToTextContent}"
|
||||||
|
android:textAppearance="?textAppearanceBodySmall"
|
||||||
|
android:textColor="?colorOnPrimaryContainer"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/embeddedMessageSender"
|
||||||
|
tools:text="In lorem orci, faucibus a magna a, auctor feugiat lorem. Sed efficitur turpis nisi, nec ultrices arcu tempus et. Nulla consectetur sodales tortor, at cursus erat ultricies non." />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/image"
|
android:id="@+id/image"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -33,13 +80,14 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHeight_max="@dimen/message_preview_max_height"
|
app:layout_constraintHeight_max="@dimen/message_preview_max_height"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toBottomOf="@+id/embeddedMessage"
|
||||||
app:layout_constraintWidth_max="@dimen/message_preview_max_width" />
|
app:layout_constraintWidth_max="@dimen/message_preview_max_width" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/textContentWrapper"
|
android:id="@+id/textContentWrapper"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
@ -56,7 +104,6 @@
|
||||||
android:textColor="?colorOnSecondaryContainer"
|
android:textColor="?colorOnSecondaryContainer"
|
||||||
tools:text="Quisque sit amet metus faucibus, egestas est eu, hendrerit mauris. Suspendisse pretium nisl purus, vitae vestibulum sapien rhoncus nec. Quisque molestie ante felis, vel dapibus ex mattis a. Morbi venenatis vestibulum neque, vel ornare sapien. Aliquam erat volutpat. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. " />
|
tools:text="Quisque sit amet metus faucibus, egestas est eu, hendrerit mauris. Suspendisse pretium nisl purus, vitae vestibulum sapien rhoncus nec. Quisque molestie ante felis, vel dapibus ex mattis a. Morbi venenatis vestibulum neque, vel ornare sapien. Aliquam erat volutpat. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. " />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue