kopia lustrzana https://github.com/ryukoposting/Signal-Android
Insert temporary warning update message during message request state.
rodzic
ad81b310e3
commit
59c49254e7
|
@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.components.voice.VoiceNotePlaybackState;
|
||||||
import org.thoughtcrime.securesms.contactshare.Contact;
|
import org.thoughtcrime.securesms.contactshare.Contact;
|
||||||
import org.thoughtcrime.securesms.conversation.ConversationItem;
|
import org.thoughtcrime.securesms.conversation.ConversationItem;
|
||||||
import org.thoughtcrime.securesms.conversation.ConversationMessage;
|
import org.thoughtcrime.securesms.conversation.ConversationMessage;
|
||||||
|
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
||||||
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4Playable;
|
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4Playable;
|
||||||
|
@ -75,6 +76,7 @@ public interface BindableConversationItem extends Unbindable, GiphyMp4Playable {
|
||||||
void onInviteFriendsToGroupClicked(@NonNull GroupId.V2 groupId);
|
void onInviteFriendsToGroupClicked(@NonNull GroupId.V2 groupId);
|
||||||
void onEnableCallNotificationsClicked();
|
void onEnableCallNotificationsClicked();
|
||||||
void onPlayInlineContent(ConversationMessage conversationMessage);
|
void onPlayInlineContent(ConversationMessage conversationMessage);
|
||||||
|
void onInMemoryMessageClicked(@NonNull InMemoryMessageRecord messageRecord);
|
||||||
|
|
||||||
/** @return true if handled, false if you want to let the normal url handling continue */
|
/** @return true if handled, false if you want to let the normal url handling continue */
|
||||||
boolean onUrlClicked(@NonNull String url);
|
boolean onUrlClicked(@NonNull String url);
|
||||||
|
|
|
@ -1,35 +1,37 @@
|
||||||
package org.thoughtcrime.securesms.conversation;
|
package org.thoughtcrime.securesms.conversation;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents metadata about a conversation.
|
* Represents metadata about a conversation.
|
||||||
*/
|
*/
|
||||||
final class ConversationData {
|
final class ConversationData {
|
||||||
private final long threadId;
|
private final long threadId;
|
||||||
private final long lastSeen;
|
private final long lastSeen;
|
||||||
private final int lastSeenPosition;
|
private final int lastSeenPosition;
|
||||||
private final int lastScrolledPosition;
|
private final int lastScrolledPosition;
|
||||||
private final boolean hasSent;
|
private final boolean hasSent;
|
||||||
private final boolean isMessageRequestAccepted;
|
private final int jumpToPosition;
|
||||||
private final int jumpToPosition;
|
private final int threadSize;
|
||||||
private final int threadSize;
|
private final MessageRequestData messageRequestData;
|
||||||
|
|
||||||
ConversationData(long threadId,
|
ConversationData(long threadId,
|
||||||
long lastSeen,
|
long lastSeen,
|
||||||
int lastSeenPosition,
|
int lastSeenPosition,
|
||||||
int lastScrolledPosition,
|
int lastScrolledPosition,
|
||||||
boolean hasSent,
|
boolean hasSent,
|
||||||
boolean isMessageRequestAccepted,
|
|
||||||
int jumpToPosition,
|
int jumpToPosition,
|
||||||
int threadSize)
|
int threadSize,
|
||||||
|
@NonNull MessageRequestData messageRequestData)
|
||||||
{
|
{
|
||||||
this.threadId = threadId;
|
this.threadId = threadId;
|
||||||
this.lastSeen = lastSeen;
|
this.lastSeen = lastSeen;
|
||||||
this.lastSeenPosition = lastSeenPosition;
|
this.lastSeenPosition = lastSeenPosition;
|
||||||
this.lastScrolledPosition = lastScrolledPosition;
|
this.lastScrolledPosition = lastScrolledPosition;
|
||||||
this.hasSent = hasSent;
|
this.hasSent = hasSent;
|
||||||
this.isMessageRequestAccepted = isMessageRequestAccepted;
|
this.jumpToPosition = jumpToPosition;
|
||||||
this.jumpToPosition = jumpToPosition;
|
this.threadSize = threadSize;
|
||||||
this.threadSize = threadSize;
|
this.messageRequestData = messageRequestData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getThreadId() {
|
public long getThreadId() {
|
||||||
|
@ -52,10 +54,6 @@ final class ConversationData {
|
||||||
return hasSent;
|
return hasSent;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isMessageRequestAccepted() {
|
|
||||||
return isMessageRequestAccepted;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean shouldJumpToMessage() {
|
boolean shouldJumpToMessage() {
|
||||||
return jumpToPosition >= 0;
|
return jumpToPosition >= 0;
|
||||||
}
|
}
|
||||||
|
@ -71,4 +69,37 @@ final class ConversationData {
|
||||||
int getThreadSize() {
|
int getThreadSize() {
|
||||||
return threadSize;
|
return threadSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull MessageRequestData getMessageRequestData() {
|
||||||
|
return messageRequestData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class MessageRequestData {
|
||||||
|
|
||||||
|
private final boolean messageRequestAccepted;
|
||||||
|
private final boolean groupsInCommon;
|
||||||
|
private final boolean isGroup;
|
||||||
|
|
||||||
|
public MessageRequestData(boolean messageRequestAccepted) {
|
||||||
|
this(messageRequestAccepted, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageRequestData(boolean messageRequestAccepted, boolean groupsInCommon, boolean isGroup) {
|
||||||
|
this.messageRequestAccepted = messageRequestAccepted;
|
||||||
|
this.groupsInCommon = groupsInCommon;
|
||||||
|
this.isGroup = isGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMessageRequestAccepted() {
|
||||||
|
return messageRequestAccepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean includeWarningUpdateMessage() {
|
||||||
|
return !messageRequestAccepted && !groupsInCommon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGroup() {
|
||||||
|
return isGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,11 @@ import com.annimon.stream.Stream;
|
||||||
|
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
import org.signal.paging.PagedDataSource;
|
import org.signal.paging.PagedDataSource;
|
||||||
|
import org.thoughtcrime.securesms.conversation.ConversationData.MessageRequestData;
|
||||||
import org.thoughtcrime.securesms.conversation.ConversationMessage.ConversationMessageFactory;
|
import org.thoughtcrime.securesms.conversation.ConversationMessage.ConversationMessageFactory;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.Mention;
|
import org.thoughtcrime.securesms.database.model.Mention;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.util.Stopwatch;
|
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||||
|
@ -30,18 +32,20 @@ class ConversationDataSource implements PagedDataSource<ConversationMessage> {
|
||||||
|
|
||||||
private static final String TAG = Log.tag(ConversationDataSource.class);
|
private static final String TAG = Log.tag(ConversationDataSource.class);
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final long threadId;
|
private final long threadId;
|
||||||
|
private final MessageRequestData messageRequestData;
|
||||||
|
|
||||||
ConversationDataSource(@NonNull Context context, long threadId) {
|
ConversationDataSource(@NonNull Context context, long threadId, @NonNull MessageRequestData messageRequestData) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.threadId = threadId;
|
this.threadId = threadId;
|
||||||
|
this.messageRequestData = messageRequestData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
int size = DatabaseFactory.getMmsSmsDatabase(context).getConversationCount(threadId);
|
int size = DatabaseFactory.getMmsSmsDatabase(context).getConversationCount(threadId) + (messageRequestData.includeWarningUpdateMessage() ? 1 : 0);
|
||||||
|
|
||||||
Log.d(TAG, "size() for thread " + threadId + ": " + (System.currentTimeMillis() - startTime) + " ms");
|
Log.d(TAG, "size() for thread " + threadId + ": " + (System.currentTimeMillis() - startTime) + " ms");
|
||||||
|
|
||||||
|
@ -55,7 +59,7 @@ class ConversationDataSource implements PagedDataSource<ConversationMessage> {
|
||||||
List<MessageRecord> records = new ArrayList<>(length);
|
List<MessageRecord> records = new ArrayList<>(length);
|
||||||
MentionHelper mentionHelper = new MentionHelper();
|
MentionHelper mentionHelper = new MentionHelper();
|
||||||
|
|
||||||
try (MmsSmsDatabase.Reader reader = db.readerFor(db.getConversation(threadId, start, length))) {
|
try (MmsSmsDatabase.Reader reader = MmsSmsDatabase.readerFor(db.getConversation(threadId, start, length))) {
|
||||||
MessageRecord record;
|
MessageRecord record;
|
||||||
while ((record = reader.getNext()) != null && !cancellationSignal.isCanceled()) {
|
while ((record = reader.getNext()) != null && !cancellationSignal.isCanceled()) {
|
||||||
records.add(record);
|
records.add(record);
|
||||||
|
@ -63,6 +67,10 @@ class ConversationDataSource implements PagedDataSource<ConversationMessage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (messageRequestData.includeWarningUpdateMessage() && (start + length >= size())) {
|
||||||
|
records.add(new InMemoryMessageRecord.NoGroupsInCommon(threadId, messageRequestData.isGroup()));
|
||||||
|
}
|
||||||
|
|
||||||
stopwatch.split("messages");
|
stopwatch.split("messages");
|
||||||
|
|
||||||
mentionHelper.fetchMentions(context);
|
mentionHelper.fetchMentions(context);
|
||||||
|
|
|
@ -64,6 +64,7 @@ import androidx.recyclerview.widget.RecyclerView.OnScrollListener;
|
||||||
|
|
||||||
import com.annimon.stream.Collectors;
|
import com.annimon.stream.Collectors;
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import org.signal.core.util.StreamUtil;
|
import org.signal.core.util.StreamUtil;
|
||||||
import org.signal.core.util.concurrent.SignalExecutors;
|
import org.signal.core.util.concurrent.SignalExecutors;
|
||||||
|
@ -93,6 +94,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.MessageDatabase;
|
import org.thoughtcrime.securesms.database.MessageDatabase;
|
||||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
||||||
|
@ -1040,7 +1042,7 @@ public class ConversationFragment extends LoggingFragment {
|
||||||
adapter.setFooterView(conversationBanner);
|
adapter.setFooterView(conversationBanner);
|
||||||
|
|
||||||
Runnable afterScroll = () -> {
|
Runnable afterScroll = () -> {
|
||||||
if (!conversation.isMessageRequestAccepted()) {
|
if (!conversation.getMessageRequestData().isMessageRequestAccepted()) {
|
||||||
snapToTopDataObserver.requestScrollPosition(adapter.getItemCount() - 1);
|
snapToTopDataObserver.requestScrollPosition(adapter.getItemCount() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1065,7 +1067,7 @@ public class ConversationFragment extends LoggingFragment {
|
||||||
getListAdapter().pulseAtPosition(conversation.getJumpToPosition());
|
getListAdapter().pulseAtPosition(conversation.getJumpToPosition());
|
||||||
})
|
})
|
||||||
.submit();
|
.submit();
|
||||||
} else if (conversation.isMessageRequestAccepted()) {
|
} else if (conversation.getMessageRequestData().isMessageRequestAccepted()) {
|
||||||
snapToTopDataObserver.buildScrollPosition(conversation.shouldScrollToLastSeen() ? lastSeenPosition : lastScrolledPosition)
|
snapToTopDataObserver.buildScrollPosition(conversation.shouldScrollToLastSeen() ? lastSeenPosition : lastScrolledPosition)
|
||||||
.withOnPerformScroll((layoutManager, position) -> layoutManager.scrollToPositionWithOffset(position, list.getHeight()))
|
.withOnPerformScroll((layoutManager, position) -> layoutManager.scrollToPositionWithOffset(position, list.getHeight()))
|
||||||
.withOnScrollRequestComplete(afterScroll)
|
.withOnScrollRequestComplete(afterScroll)
|
||||||
|
@ -1609,6 +1611,19 @@ public class ConversationFragment extends LoggingFragment {
|
||||||
public void onPlayInlineContent(ConversationMessage conversationMessage) {
|
public void onPlayInlineContent(ConversationMessage conversationMessage) {
|
||||||
getListAdapter().playInlineContent(conversationMessage);
|
getListAdapter().playInlineContent(conversationMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInMemoryMessageClicked(@NonNull InMemoryMessageRecord messageRecord) {
|
||||||
|
if (messageRecord instanceof InMemoryMessageRecord.NoGroupsInCommon) {
|
||||||
|
boolean isGroup = ((InMemoryMessageRecord.NoGroupsInCommon) messageRecord).isGroup();
|
||||||
|
new MaterialAlertDialogBuilder(requireContext(), R.style.Signal_ThemeOverlay_Dialog_Rounded)
|
||||||
|
.setMessage(isGroup ? R.string.GroupsInCommonMessageRequest__none_of_your_contacts_or_people_you_chat_with_are_in_this_group
|
||||||
|
: R.string.GroupsInCommonMessageRequest__you_have_no_groups_in_common_with_this_person)
|
||||||
|
.setNeutralButton(R.string.GroupsInCommonMessageRequest__about_message_requests, (d, w) -> CommunicationActions.openBrowserLink(requireContext(), getString(R.string.GroupsInCommonMessageRequest__support_article)))
|
||||||
|
.setPositiveButton(R.string.GroupsInCommonMessageRequest__okay, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshList() {
|
public void refreshList() {
|
||||||
|
|
|
@ -10,13 +10,16 @@ import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
import org.signal.core.util.concurrent.SignalExecutors;
|
import org.signal.core.util.concurrent.SignalExecutors;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||||
import org.thoughtcrime.securesms.util.BubbleUtil;
|
import org.thoughtcrime.securesms.util.BubbleUtil;
|
||||||
import org.thoughtcrime.securesms.util.ConversationUtil;
|
import org.thoughtcrime.securesms.util.ConversationUtil;
|
||||||
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
class ConversationRepository {
|
class ConversationRepository {
|
||||||
|
@ -51,16 +54,15 @@ class ConversationRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull ConversationData getConversationDataInternal(long threadId, int jumpToPosition) {
|
private @NonNull ConversationData getConversationDataInternal(long threadId, int jumpToPosition) {
|
||||||
ThreadDatabase.ConversationMetadata metadata = DatabaseFactory.getThreadDatabase(context).getConversationMetadata(threadId);
|
ThreadDatabase.ConversationMetadata metadata = DatabaseFactory.getThreadDatabase(context).getConversationMetadata(threadId);
|
||||||
int threadSize = DatabaseFactory.getMmsSmsDatabase(context).getConversationCount(threadId);
|
int threadSize = DatabaseFactory.getMmsSmsDatabase(context).getConversationCount(threadId);
|
||||||
|
long lastSeen = metadata.getLastSeen();
|
||||||
long lastSeen = metadata.getLastSeen();
|
boolean hasSent = metadata.hasSent();
|
||||||
boolean hasSent = metadata.hasSent();
|
int lastSeenPosition = 0;
|
||||||
int lastSeenPosition = 0;
|
long lastScrolled = metadata.getLastScrolled();
|
||||||
long lastScrolled = metadata.getLastScrolled();
|
int lastScrolledPosition = 0;
|
||||||
int lastScrolledPosition = 0;
|
boolean isMessageRequestAccepted = RecipientUtil.isMessageRequestAccepted(context, threadId);
|
||||||
|
ConversationData.MessageRequestData messageRequestData = new ConversationData.MessageRequestData(isMessageRequestAccepted);
|
||||||
boolean isMessageRequestAccepted = RecipientUtil.isMessageRequestAccepted(context, threadId);
|
|
||||||
|
|
||||||
if (lastSeen > 0) {
|
if (lastSeen > 0) {
|
||||||
lastSeenPosition = DatabaseFactory.getMmsSmsDatabase(context).getMessagePositionOnOrAfterTimestamp(threadId, lastSeen);
|
lastSeenPosition = DatabaseFactory.getMmsSmsDatabase(context).getMessagePositionOnOrAfterTimestamp(threadId, lastSeen);
|
||||||
|
@ -74,6 +76,28 @@ class ConversationRepository {
|
||||||
lastScrolledPosition = DatabaseFactory.getMmsSmsDatabase(context).getMessagePositionOnOrAfterTimestamp(threadId, lastScrolled);
|
lastScrolledPosition = DatabaseFactory.getMmsSmsDatabase(context).getMessagePositionOnOrAfterTimestamp(threadId, lastScrolled);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ConversationData(threadId, lastSeen, lastSeenPosition, lastScrolledPosition, hasSent, isMessageRequestAccepted, jumpToPosition, threadSize);
|
if (!isMessageRequestAccepted) {
|
||||||
|
boolean isGroup = false;
|
||||||
|
boolean recipientIsKnownOrHasGroupsInCommon = false;
|
||||||
|
Recipient threadRecipient = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId);
|
||||||
|
if (threadRecipient.isGroup()) {
|
||||||
|
Optional<GroupDatabase.GroupRecord> group = DatabaseFactory.getGroupDatabase(context).getGroup(threadRecipient.getId());
|
||||||
|
if (group.isPresent()) {
|
||||||
|
List<Recipient> recipients = Recipient.resolvedList(group.get().getMembers());
|
||||||
|
for (Recipient recipient : recipients) {
|
||||||
|
if ((recipient.isProfileSharing() || recipient.hasGroupsInCommon()) && !recipient.isSelf()) {
|
||||||
|
recipientIsKnownOrHasGroupsInCommon = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isGroup = true;
|
||||||
|
} else if (threadRecipient.hasGroupsInCommon()) {
|
||||||
|
recipientIsKnownOrHasGroupsInCommon = true;
|
||||||
|
}
|
||||||
|
messageRequestData = new ConversationData.MessageRequestData(isMessageRequestAccepted, recipientIsKnownOrHasGroupsInCommon, isGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ConversationData(threadId, lastSeen, lastSeenPosition, lastScrolledPosition, hasSent, jumpToPosition, threadSize, messageRequestData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.VerifyIdentityActivity;
|
||||||
import org.thoughtcrime.securesms.conversation.ui.error.EnableCallNotificationSettingsDialog;
|
import org.thoughtcrime.securesms.conversation.ui.error.EnableCallNotificationSettingsDialog;
|
||||||
import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord;
|
import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.GroupCallUpdateDetailsUtil;
|
import org.thoughtcrime.securesms.database.model.GroupCallUpdateDetailsUtil;
|
||||||
|
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.LiveUpdateMessage;
|
import org.thoughtcrime.securesms.database.model.LiveUpdateMessage;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.UpdateDescription;
|
import org.thoughtcrime.securesms.database.model.UpdateDescription;
|
||||||
|
@ -340,6 +341,15 @@ public final class ConversationUpdateItem extends FrameLayout
|
||||||
eventListener.onEnableCallNotificationsClicked();
|
eventListener.onEnableCallNotificationsClicked();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (conversationMessage.getMessageRecord().isInMemoryMessageRecord() && ((InMemoryMessageRecord) conversationMessage.getMessageRecord()).showActionButton()) {
|
||||||
|
InMemoryMessageRecord inMemoryMessageRecord = (InMemoryMessageRecord) conversationMessage.getMessageRecord();
|
||||||
|
actionButton.setVisibility(VISIBLE);
|
||||||
|
actionButton.setText(inMemoryMessageRecord.getActionButtonText());
|
||||||
|
actionButton.setOnClickListener(v -> {
|
||||||
|
if (eventListener != null) {
|
||||||
|
eventListener.onInMemoryMessageClicked(inMemoryMessageRecord);
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
actionButton.setVisibility(GONE);
|
actionButton.setVisibility(GONE);
|
||||||
actionButton.setOnClickListener(null);
|
actionButton.setOnClickListener(null);
|
||||||
|
|
|
@ -21,7 +21,6 @@ import org.thoughtcrime.securesms.mediasend.Media;
|
||||||
import org.thoughtcrime.securesms.mediasend.MediaRepository;
|
import org.thoughtcrime.securesms.mediasend.MediaRepository;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
|
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
|
||||||
import org.whispersystems.libsignal.util.Pair;
|
import org.whispersystems.libsignal.util.Pair;
|
||||||
|
@ -72,12 +71,14 @@ class ConversationViewModel extends ViewModel {
|
||||||
});
|
});
|
||||||
|
|
||||||
LiveData<Pair<Long, PagedData<ConversationMessage>>> pagedDataForThreadId = Transformations.map(metadata, data -> {
|
LiveData<Pair<Long, PagedData<ConversationMessage>>> pagedDataForThreadId = Transformations.map(metadata, data -> {
|
||||||
final int startPosition;
|
int startPosition;
|
||||||
|
ConversationData.MessageRequestData messageRequestData = data.getMessageRequestData();
|
||||||
|
|
||||||
if (data.shouldJumpToMessage()) {
|
if (data.shouldJumpToMessage()) {
|
||||||
startPosition = data.getJumpToPosition();
|
startPosition = data.getJumpToPosition();
|
||||||
} else if (data.isMessageRequestAccepted() && data.shouldScrollToLastSeen()) {
|
} else if (messageRequestData.isMessageRequestAccepted() && data.shouldScrollToLastSeen()) {
|
||||||
startPosition = data.getLastSeenPosition();
|
startPosition = data.getLastSeenPosition();
|
||||||
} else if (data.isMessageRequestAccepted()) {
|
} else if (messageRequestData.isMessageRequestAccepted()) {
|
||||||
startPosition = data.getLastScrolledPosition();
|
startPosition = data.getLastScrolledPosition();
|
||||||
} else {
|
} else {
|
||||||
startPosition = data.getThreadSize();
|
startPosition = data.getThreadSize();
|
||||||
|
@ -86,7 +87,7 @@ class ConversationViewModel extends ViewModel {
|
||||||
ApplicationDependencies.getDatabaseObserver().unregisterObserver(messageObserver);
|
ApplicationDependencies.getDatabaseObserver().unregisterObserver(messageObserver);
|
||||||
ApplicationDependencies.getDatabaseObserver().registerConversationObserver(data.getThreadId(), messageObserver);
|
ApplicationDependencies.getDatabaseObserver().registerConversationObserver(data.getThreadId(), messageObserver);
|
||||||
|
|
||||||
ConversationDataSource dataSource = new ConversationDataSource(context, data.getThreadId());
|
ConversationDataSource dataSource = new ConversationDataSource(context, data.getThreadId(), messageRequestData);
|
||||||
PagingConfig config = new PagingConfig.Builder()
|
PagingConfig config = new PagingConfig.Builder()
|
||||||
.setPageSize(25)
|
.setPageSize(25)
|
||||||
.setBufferPages(3)
|
.setBufferPages(3)
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
package org.thoughtcrime.securesms.database.model;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In memory message record for use in temporary conversation messages.
|
||||||
|
*/
|
||||||
|
public class InMemoryMessageRecord extends MessageRecord {
|
||||||
|
|
||||||
|
private InMemoryMessageRecord(long id,
|
||||||
|
String body,
|
||||||
|
Recipient conversationRecipient,
|
||||||
|
long threadId,
|
||||||
|
long type)
|
||||||
|
{
|
||||||
|
super(id,
|
||||||
|
body,
|
||||||
|
conversationRecipient,
|
||||||
|
conversationRecipient,
|
||||||
|
1,
|
||||||
|
System.currentTimeMillis(),
|
||||||
|
System.currentTimeMillis(),
|
||||||
|
System.currentTimeMillis(),
|
||||||
|
threadId,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
type,
|
||||||
|
Collections.emptyList(),
|
||||||
|
Collections.emptyList(),
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
System.currentTimeMillis(),
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
Collections.emptyList(),
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMms() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMmsNotification() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInMemoryMessageRecord() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean showActionButton() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @StringRes int getActionButtonText() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warning message to show during message request state if you do not have groups in common
|
||||||
|
* with an individual or do not know anyone in the group.
|
||||||
|
*/
|
||||||
|
public static final class NoGroupsInCommon extends InMemoryMessageRecord {
|
||||||
|
private final boolean isGroup;
|
||||||
|
|
||||||
|
public NoGroupsInCommon(long threadId, boolean isGroup) {
|
||||||
|
super(-1, "", Recipient.UNKNOWN, threadId, 0);
|
||||||
|
this.isGroup = isGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable UpdateDescription getUpdateDisplayBody(@NonNull Context context) {
|
||||||
|
return UpdateDescription.staticDescription(context.getString(isGroup ? R.string.ConversationUpdateItem_no_contacts_in_this_group_review_requests_carefully
|
||||||
|
: R.string.ConversationUpdateItem_no_groups_in_common_review_requests_carefully),
|
||||||
|
R.drawable.ic_update_info_16);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUpdate() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean showActionButton() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGroup() {
|
||||||
|
return isGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @StringRes int getActionButtonText() {
|
||||||
|
return R.string.ConversationUpdateItem_learn_more;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -489,6 +489,10 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||||
return MmsSmsColumns.Types.isFailedDecryptType(type);
|
return MmsSmsColumns.Types.isFailedDecryptType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInMemoryMessageRecord() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected static SpannableString emphasisAdded(String sequence) {
|
protected static SpannableString emphasisAdded(String sequence) {
|
||||||
SpannableString spannable = new SpannableString(sequence);
|
SpannableString spannable = new SpannableString(sequence);
|
||||||
spannable.setSpan(new RelativeSizeSpan(0.9f), 0, sequence.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
spannable.setSpan(new RelativeSizeSpan(0.9f), 0, sequence.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
|
|
@ -117,7 +117,7 @@
|
||||||
<style name="Signal.ThemeOverlay.Dialog.Rounded" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
|
<style name="Signal.ThemeOverlay.Dialog.Rounded" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
|
||||||
<item name="alertDialogStyle">@style/Signal.MaterialAlertDialog</item>
|
<item name="alertDialogStyle">@style/Signal.MaterialAlertDialog</item>
|
||||||
<item name="android:background">@color/signal_background_dialog</item>
|
<item name="android:background">@color/signal_background_dialog</item>
|
||||||
<item name="android:textColorPrimary">@color/signal_text_primary_dialog</item>
|
<item name="materialAlertDialogBodyTextStyle">@style/Signal.Text.Body</item>
|
||||||
<item name="buttonBarPositiveButtonStyle">@style/Signal.Widget.Button.Dialog</item>
|
<item name="buttonBarPositiveButtonStyle">@style/Signal.Widget.Button.Dialog</item>
|
||||||
<item name="buttonBarNeutralButtonStyle">@style/Signal.Widget.Button.Dialog</item>
|
<item name="buttonBarNeutralButtonStyle">@style/Signal.Widget.Button.Dialog</item>
|
||||||
<item name="buttonBarNegativeButtonStyle">@style/Signal.Widget.Button.Dialog</item>
|
<item name="buttonBarNegativeButtonStyle">@style/Signal.Widget.Button.Dialog</item>
|
||||||
|
|
|
@ -1880,6 +1880,8 @@
|
||||||
<string name="ConversationUpdateItem_call_is_full">Call is full</string>
|
<string name="ConversationUpdateItem_call_is_full">Call is full</string>
|
||||||
<string name="ConversationUpdateItem_invite_friends">Invite friends</string>
|
<string name="ConversationUpdateItem_invite_friends">Invite friends</string>
|
||||||
<string name="ConversationUpdateItem_enable_call_notifications">Enable Call Notifications</string>
|
<string name="ConversationUpdateItem_enable_call_notifications">Enable Call Notifications</string>
|
||||||
|
<string name="ConversationUpdateItem_no_groups_in_common_review_requests_carefully">No groups in common. Review requests carefully.</string>
|
||||||
|
<string name="ConversationUpdateItem_no_contacts_in_this_group_review_requests_carefully">No contacts in this group. Review requests carefully.</string>
|
||||||
|
|
||||||
<!-- audio_view -->
|
<!-- audio_view -->
|
||||||
<string name="audio_view__play_pause_accessibility_description">Play … Pause</string>
|
<string name="audio_view__play_pause_accessibility_description">Play … Pause</string>
|
||||||
|
@ -3337,6 +3339,13 @@
|
||||||
<string name="CanNotSendPaymentDialog__to_send_a_payment_to_this_user">To send a payment to this user they need to accept a message request from you. Send them a message to create a message request.</string>
|
<string name="CanNotSendPaymentDialog__to_send_a_payment_to_this_user">To send a payment to this user they need to accept a message request from you. Send them a message to create a message request.</string>
|
||||||
<string name="CanNotSendPaymentDialog__send_a_message">Send a message</string>
|
<string name="CanNotSendPaymentDialog__send_a_message">Send a message</string>
|
||||||
|
|
||||||
|
<!-- GroupsInCommonMessageRequest -->
|
||||||
|
<string name="GroupsInCommonMessageRequest__you_have_no_groups_in_common_with_this_person">You have no groups in common with this person. Review requests carefully before accepting to avoid unwanted messages.</string>
|
||||||
|
<string name="GroupsInCommonMessageRequest__none_of_your_contacts_or_people_you_chat_with_are_in_this_group">None of your contacts or people you chat with are in this group. Review requests carefully before accepting to avoid unwanted messages.</string>
|
||||||
|
<string name="GroupsInCommonMessageRequest__about_message_requests">About message requests</string>
|
||||||
|
<string name="GroupsInCommonMessageRequest__okay">Okay</string>
|
||||||
|
<string name="GroupsInCommonMessageRequest__support_article" translatable="false">https://support.signal.org/hc/articles/360007459591</string>
|
||||||
|
|
||||||
<!-- EOF -->
|
<!-- EOF -->
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Ładowanie…
Reference in New Issue