use of org.thoughtcrime.securesms.database.model.ReactionRecord in project Signal-Android by WhisperSystems.
the class ConversationParentFragment method onCustomReactionSelected.
@Override
public void onCustomReactionSelected(@NonNull MessageRecord messageRecord, boolean hasAddedCustomEmoji) {
ReactionRecord oldRecord = Stream.of(messageRecord.getReactions()).filter(record -> record.getAuthor().equals(Recipient.self().getId())).findFirst().orElse(null);
if (oldRecord != null && hasAddedCustomEmoji) {
final Context context = requireContext().getApplicationContext();
reactionDelegate.hide();
SignalExecutors.BOUNDED.execute(() -> MessageSender.sendReactionRemoval(context, new MessageId(messageRecord.getId(), messageRecord.isMms()), oldRecord));
} else {
reactionDelegate.hideForReactWithAny();
ReactWithAnyEmojiBottomSheetDialogFragment.createForMessageRecord(messageRecord, reactWithAnyEmojiStartPage).show(getChildFragmentManager(), "BOTTOM");
}
}
use of org.thoughtcrime.securesms.database.model.ReactionRecord in project Signal-Android by WhisperSystems.
the class ConversationDataSource method load.
@Override
@Nullable
public ConversationMessage load(@NonNull MessageId messageId) {
Stopwatch stopwatch = new Stopwatch("load(" + messageId + "), thread " + threadId);
MessageDatabase database = messageId.isMms() ? SignalDatabase.mms() : SignalDatabase.sms();
MessageRecord record = database.getMessageRecordOrNull(messageId.getId());
stopwatch.split("message");
try {
if (record != null) {
List<Mention> mentions;
if (messageId.isMms()) {
mentions = SignalDatabase.mentions().getMentionsForMessage(messageId.getId());
} else {
mentions = Collections.emptyList();
}
stopwatch.split("mentions");
List<ReactionRecord> reactions = SignalDatabase.reactions().getReactions(messageId);
record = ReactionHelper.recordWithReactions(record, reactions);
stopwatch.split("reactions");
if (messageId.isMms()) {
List<DatabaseAttachment> attachments = SignalDatabase.attachments().getAttachmentsForMessage(messageId.getId());
if (attachments.size() > 0) {
record = ((MediaMmsMessageRecord) record).withAttachments(context, attachments);
}
}
stopwatch.split("attachments");
return ConversationMessage.ConversationMessageFactory.createWithUnresolvedData(ApplicationDependencies.getApplication(), record, mentions);
} else {
return null;
}
} finally {
stopwatch.stop(TAG);
}
}
use of org.thoughtcrime.securesms.database.model.ReactionRecord in project Signal-Android by WhisperSystems.
the class ConversationFragment method postMarkAsReadRequest.
private void postMarkAsReadRequest() {
if (getListAdapter().hasNoConversationMessages()) {
return;
}
int position = getListLayoutManager().findFirstVisibleItemPosition();
if (position == getListAdapter().getItemCount() - 1) {
return;
}
if (position >= (isTypingIndicatorShowing() ? 1 : 0)) {
ConversationMessage item = getListAdapter().getItem(position);
if (item != null) {
MessageRecord record = item.getMessageRecord();
long latestReactionReceived = Stream.of(record.getReactions()).map(ReactionRecord::getDateReceived).max(Long::compareTo).orElse(0L);
markReadHelper.onViewsRevealed(Math.max(record.getDateReceived(), latestReactionReceived));
}
}
}
use of org.thoughtcrime.securesms.database.model.ReactionRecord in project Signal-Android by WhisperSystems.
the class MessageContentProcessor method handleReaction.
@Nullable
private MessageId handleReaction(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Recipient senderRecipient) {
log(content.getTimestamp(), "Handle reaction for message " + message.getReaction().get().getTargetSentTimestamp());
SignalServiceDataMessage.Reaction reaction = message.getReaction().get();
if (!EmojiUtil.isEmoji(reaction.getEmoji())) {
Log.w(TAG, "Reaction text is not a valid emoji! Ignoring the message.");
return null;
}
Recipient targetAuthor = Recipient.externalPush(reaction.getTargetAuthor());
MessageRecord targetMessage = SignalDatabase.mmsSms().getMessageFor(reaction.getTargetSentTimestamp(), targetAuthor.getId());
if (targetMessage == null) {
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Could not find matching message! Putting it in the early message cache. timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
ApplicationDependencies.getEarlyMessageCache().store(targetAuthor.getId(), reaction.getTargetSentTimestamp(), content);
return null;
}
if (targetMessage.isRemoteDelete()) {
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Found a matching message, but it's flagged as remotely deleted. timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
return null;
}
ThreadRecord targetThread = SignalDatabase.threads().getThreadRecord(targetMessage.getThreadId());
if (targetThread == null) {
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Could not find a thread for the message! timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
return null;
}
Recipient threadRecipient = targetThread.getRecipient().resolve();
if (threadRecipient.isGroup() && !threadRecipient.getParticipants().contains(senderRecipient)) {
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Reaction author is not in the group! timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
return null;
}
if (!threadRecipient.isGroup() && !senderRecipient.equals(threadRecipient) && !senderRecipient.isSelf()) {
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Reaction author is not a part of the 1:1 thread! timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
return null;
}
MessageId targetMessageId = new MessageId(targetMessage.getId(), targetMessage.isMms());
if (reaction.isRemove()) {
SignalDatabase.reactions().deleteReaction(targetMessageId, senderRecipient.getId());
ApplicationDependencies.getMessageNotifier().updateNotification(context);
} else {
ReactionRecord reactionRecord = new ReactionRecord(reaction.getEmoji(), senderRecipient.getId(), message.getTimestamp(), System.currentTimeMillis());
SignalDatabase.reactions().addReaction(targetMessageId, reactionRecord);
ApplicationDependencies.getMessageNotifier().updateNotification(context, targetMessage.getThreadId(), false);
}
return new MessageId(targetMessage.getId(), targetMessage.isMms());
}
use of org.thoughtcrime.securesms.database.model.ReactionRecord in project Signal-Android by WhisperSystems.
the class ReactionsConversationView method buildSortedReactionsList.
@NonNull
private static List<Reaction> buildSortedReactionsList(@NonNull List<ReactionRecord> records) {
Map<String, Reaction> counters = new LinkedHashMap<>();
RecipientId selfId = Recipient.self().getId();
for (ReactionRecord record : records) {
String baseEmoji = EmojiUtil.getCanonicalRepresentation(record.getEmoji());
Reaction info = counters.get(baseEmoji);
if (info == null) {
info = new Reaction(baseEmoji, record.getEmoji(), 1, record.getDateReceived(), selfId.equals(record.getAuthor()));
} else {
info.update(record.getEmoji(), record.getDateReceived(), selfId.equals(record.getAuthor()));
}
counters.put(baseEmoji, info);
}
List<Reaction> reactions = new ArrayList<>(counters.values());
Collections.sort(reactions, Collections.reverseOrder());
if (reactions.size() > 3) {
List<Reaction> shortened = new ArrayList<>(3);
shortened.add(reactions.get(0));
shortened.add(reactions.get(1));
shortened.add(Stream.of(reactions).skip(2).reduce(new Reaction(null, null, 0, 0, false), Reaction::merge));
return shortened;
} else {
return reactions;
}
}
Aggregations