Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

display reactions #2554

Merged
merged 5 commits into from Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions res/drawable/reaction_pill_background.xml
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1000dp" />
<solid android:color="@color/reaction_pill_background" />
<stroke android:color="@color/reaction_pill_border" android:width="1dp" />
</shape>
6 changes: 6 additions & 0 deletions res/drawable/reaction_pill_background_selected.xml
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1000dp" />
<solid android:color="@color/reaction_pill_background_selected" />
<stroke android:color="@color/reaction_pill_border_selected" android:width="1dp" />
</shape>
10 changes: 10 additions & 0 deletions res/layout/conversation_item_received.xml
Expand Up @@ -220,5 +220,15 @@

</LinearLayout>

<org.thoughtcrime.securesms.reactions.ReactionsConversationView
android:id="@+id/reactions_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/body_bubble"
android:layout_alignStart="@id/body_bubble"
android:layout_marginTop="-4dp"
android:orientation="horizontal"
app:message_type="incoming" />

</RelativeLayout>
</org.thoughtcrime.securesms.ConversationItem>
10 changes: 10 additions & 0 deletions res/layout/conversation_item_sent.xml
Expand Up @@ -197,6 +197,16 @@

</LinearLayout>

<org.thoughtcrime.securesms.reactions.ReactionsConversationView
android:id="@+id/reactions_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/body_bubble"
android:layout_alignEnd="@id/body_bubble"
android:layout_marginTop="-4dp"
android:orientation="horizontal"
app:message_type="outgoing" />

<!-- the following view is only left because it is used as a reference for positioning above.
removing would require some re-layouting, it's just not done yet.-->
<View
Expand Down
37 changes: 37 additions & 0 deletions res/layout/reactions_pill.xml
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

red pill or blue pill?

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
tools:viewBindingIgnore="true"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="26dp"
android:layout_marginStart="1dp"
android:layout_marginEnd="1dp"
android:paddingStart="7dp"
android:paddingEnd="7dp"
android:gravity="center">

<org.thoughtcrime.securesms.components.emoji.EmojiImageView
android:id="@+id/reactions_pill_emoji"
android:layout_width="17dp"
android:layout_height="17dp" />

<Space
android:id="@+id/reactions_pill_spacer"
android:layout_width="4dp"
android:layout_height="wrap_content" />

<TextView
android:id="@+id/reactions_pill_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:textSize="12dp"
android:fontFamily="sans-serif-medium"
android:textColor="@color/reaction_pill_text_color"
tools:text="23"
tools:ignore="SpUsage" />

</LinearLayout>
9 changes: 9 additions & 0 deletions res/values-night/colors.xml
@@ -0,0 +1,9 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<color name="reaction_pill_background">@color/black</color>
<color name="reaction_pill_border">#80414347</color>
<color name="reaction_pill_text_color">@color/core_dark_05</color>
<color name="reaction_pill_background_selected">#ff282828</color>
<color name="reaction_pill_border_selected">@color/reaction_pill_border</color>
<color name="reaction_pill_text_color_selected">@color/reaction_pill_text_color</color>
</resources>
7 changes: 7 additions & 0 deletions res/values/attrs.xml
Expand Up @@ -250,6 +250,13 @@
<attr name="quote_colorSecondary" format="color" />
</declare-styleable>

<declare-styleable name="ReactionsConversationView">
<attr name="reaction_type" format="enum">
<enum name="outgoing" value="1" />
<enum name="incoming" value="2" />
</attr>
</declare-styleable>

<declare-styleable name="ConversationAdaptiveActionsToolbar">
<attr name="aat_max_shown" format="integer" />
</declare-styleable>
Expand Down
7 changes: 7 additions & 0 deletions res/values/colors.xml
Expand Up @@ -75,4 +75,11 @@
<!-- unknown_sender fits in dark mode and lite mode (also other chat/contact colors fit in both modes);
unknown_sender is used for the sender-name/quote-bar if the sender is unknown -->
<color name="unknown_sender">#ff999999</color>

<color name="reaction_pill_background">#ffffff</color>
<color name="reaction_pill_border">#80f1f1f1</color>
<color name="reaction_pill_text_color">#545863</color>
<color name="reaction_pill_background_selected">@color/gray5</color>
<color name="reaction_pill_border_selected">@color/reaction_pill_border</color>
<color name="reaction_pill_text_color_selected">@color/reaction_pill_text_color</color>
</resources>
2 changes: 2 additions & 0 deletions res/values/strings.xml
Expand Up @@ -722,6 +722,8 @@
<string name="emoji_symbols">Symbols</string>
<string name="emoji_flags">Flags</string>

<!-- Reactions -->
<string name="ReactionsConversationView_plus">+%1$d</string>

<!-- automatically delete message -->
<string name="delete_old_messages">Delete Old Messages</string>
Expand Down
1 change: 1 addition & 0 deletions src/com/b44t/messenger/DcContext.java
Expand Up @@ -11,6 +11,7 @@ public class DcContext {
public final static int DC_EVENT_ERROR = 400;
public final static int DC_EVENT_ERROR_SELF_NOT_IN_GROUP = 410;
public final static int DC_EVENT_MSGS_CHANGED = 2000;
public final static int DC_EVENT_REACTIONS_CHANGED = 2001;
public final static int DC_EVENT_INCOMING_MSG = 2005;
public final static int DC_EVENT_MSGS_NOTICED = 2008;
public final static int DC_EVENT_MSG_DELIVERED = 2010;
Expand Down
39 changes: 39 additions & 0 deletions src/com/b44t/messenger/rpc/Reaction.java
@@ -0,0 +1,39 @@
package com.b44t.messenger.rpc;

import androidx.annotation.Nullable;

public class Reaction {
// The reaction emoji string.
private final String emoji;
// The count of users that have reacted with this reaction.
private final int count;
// true if self-account reacted with this reaction, false otherwise.
private final boolean isFromSelf;

public Reaction(String emoji, int count, boolean isFromSelf) {
this.emoji = emoji;
this.count = count;
this.isFromSelf = isFromSelf;
}

public String getEmoji() {
return emoji;
}

public int getCount() {
return count;
}

public boolean isFromSelf() {
return isFromSelf;
}

@Override
public boolean equals(@Nullable Object obj) {
if (obj instanceof Reaction) {
Reaction reaction = (Reaction) obj;
return emoji.equals(reaction.getEmoji()) && count == reaction.getCount() && isFromSelf == reaction.isFromSelf();
}
return false;
}
}
26 changes: 26 additions & 0 deletions src/com/b44t/messenger/rpc/Reactions.java
@@ -0,0 +1,26 @@
package com.b44t.messenger.rpc;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Reactions {
// Map from a contact to it's reaction to message.
private final HashMap<Integer, String[]> reactionsByContact;
// Unique reactions, sorted in descending order.
private final ArrayList<Reaction> reactions;

public Reactions(HashMap<Integer, String[]> reactionsByContact, ArrayList<Reaction> reactions) {
this.reactionsByContact = reactionsByContact;
this.reactions = reactions;
}

public Map<Integer, String[]> getReactionsByContact() {
return reactionsByContact;
}

public List<Reaction> getReactions() {
return reactions;
}
}
11 changes: 7 additions & 4 deletions src/com/b44t/messenger/rpc/Rpc.java
Expand Up @@ -8,7 +8,6 @@
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
Expand Down Expand Up @@ -41,7 +40,7 @@ private void processResponse() throws JsonSyntaxException {
} else if (response.result != null) {
future.set(response.result);
} else {
future.setException(new RpcException("Got JSON-RPC response witout result or error: " + jsonResponse));
future.setException(new RpcException("Got JSON-RPC response without result or error: " + jsonResponse));
}
}

Expand Down Expand Up @@ -100,9 +99,13 @@ public HttpResponse getHttpResponse(int accountId, String url) throws RpcExcepti
return gson.fromJson(getResult("get_http_response", accountId, url), HttpResponse.class);
}

public Reactions getMsgReactions(int accountId, int msgId) throws RpcException {
return gson.fromJson(getResult("get_message_reactions", accountId, msgId), Reactions.class);
}


private static class Request {
public String jsonrpc = "2.0";
private final String jsonrpc = "2.0";
public String method;
public Object[] params;
public int id;
Expand All @@ -115,7 +118,7 @@ public Request(String method, Object[] params, int id) {
}

private static class Response {
public int id = 0;
public int id;
public JsonElement result;
public JsonElement error;

Expand Down
5 changes: 4 additions & 1 deletion src/org/thoughtcrime/securesms/BaseConversationItem.java
Expand Up @@ -13,6 +13,7 @@
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcMsg;
import com.b44t.messenger.rpc.Rpc;

import org.thoughtcrime.securesms.connect.DcHelper;

Expand All @@ -30,6 +31,7 @@ public abstract class BaseConversationItem extends LinearLayout

protected final Context context;
protected final DcContext dcContext;
protected final Rpc rpc;

protected @NonNull Set<DcMsg> batchSelected = new HashSet<>();

Expand All @@ -39,6 +41,7 @@ public BaseConversationItem(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
this.dcContext = DcHelper.getContext(context);
this.rpc = DcHelper.getRpc(context);
}

protected void bind(@NonNull DcMsg messageRecord,
Expand Down Expand Up @@ -92,7 +95,7 @@ public void onClick(View v) {
}

protected class ClickListener implements View.OnClickListener {
private OnClickListener parent;
private final OnClickListener parent;

ClickListener(@Nullable OnClickListener parent) {
this.parent = parent;
Expand Down
2 changes: 2 additions & 0 deletions src/org/thoughtcrime/securesms/ConversationFragment.java
Expand Up @@ -119,6 +119,7 @@ public void onCreate(Bundle icicle) {
DcEventCenter eventCenter = DcHelper.getEventCenter(getContext());
eventCenter.addObserver(DcContext.DC_EVENT_INCOMING_MSG, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSGS_CHANGED, this);
eventCenter.addObserver(DcContext.DC_EVENT_REACTIONS_CHANGED, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSG_DELIVERED, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSG_FAILED, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSG_READ, this);
Expand Down Expand Up @@ -972,6 +973,7 @@ public void handleEvent(@NonNull DcEvent event) {
}
break;

case DcContext.DC_EVENT_REACTIONS_CHANGED:
case DcContext.DC_EVENT_INCOMING_MSG:
case DcContext.DC_EVENT_MSG_DELIVERED:
case DcContext.DC_EVENT_MSG_FAILED:
Expand Down
19 changes: 19 additions & 0 deletions src/org/thoughtcrime/securesms/ConversationItem.java
Expand Up @@ -39,6 +39,8 @@
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcMsg;
import com.b44t.messenger.rpc.Reactions;
import com.b44t.messenger.rpc.RpcException;

import org.thoughtcrime.securesms.audio.AudioSlidePlayer;
import org.thoughtcrime.securesms.components.AudioView;
Expand All @@ -59,6 +61,7 @@
import org.thoughtcrime.securesms.mms.SlideClickListener;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.mms.StickerSlide;
import org.thoughtcrime.securesms.reactions.ReactionsConversationView;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
import org.thoughtcrime.securesms.util.MediaUtil;
Expand Down Expand Up @@ -97,6 +100,7 @@ public class ConversationItem extends BaseConversationItem
@Nullable private QuoteView quoteView;
private ConversationItemFooter footer;
private ConversationItemFooter stickerFooter;
private ReactionsConversationView reactionsView;
private TextView groupSender;
private View groupSenderHolder;
private AvatarImageView contactPhoto;
Expand Down Expand Up @@ -134,6 +138,7 @@ protected void onFinishInflate() {
this.bodyText = findViewById(R.id.conversation_item_body);
this.footer = findViewById(R.id.conversation_item_footer);
this.stickerFooter = findViewById(R.id.conversation_item_sticker_footer);
this.reactionsView = findViewById(R.id.reactions_view);
this.groupSender = findViewById(R.id.group_message_sender);
this.contactPhoto = findViewById(R.id.contact_photo);
this.contactPhotoHolder = findViewById(R.id.contact_photo_container);
Expand Down Expand Up @@ -185,6 +190,7 @@ public void bind(@NonNull DcMsg messageRecord,
setGroupMessageStatus();
setAuthor(messageRecord, showSender);
setMessageSpacing(context);
setReactions(messageRecord);
setFooter(messageRecord, locale);
setQuote(messageRecord);
}
Expand Down Expand Up @@ -667,6 +673,19 @@ private void setFooter(@NonNull DcMsg current, @NonNull Locale locale) {
activeFooter.setMessageRecord(current, locale);
}

private void setReactions(@NonNull DcMsg current) {
try {
Reactions reactions = rpc.getMsgReactions(dcContext.getAccountId(), current.getId());
if (reactions == null) {
reactionsView.clear();
} else {
reactionsView.setReactions(reactions.getReactions());
}
} catch (RpcException e) {
reactionsView.clear();
}
}

private ConversationItemFooter getActiveFooter(@NonNull DcMsg messageRecord) {
if (hasSticker(messageRecord)) {
return stickerFooter;
Expand Down