From 5e536c3fa55ea37316b6b55e79d05c9fc12190e8 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 4 Nov 2020 14:19:14 -0500 Subject: [PATCH] Render GV1->GV2 migration event. --- .../securesms/BindableConversationItem.java | 1 + .../conversation/ConversationFragment.java | 7 +- .../conversation/ConversationUpdateItem.java | 49 +++++--- .../securesms/database/MessageDatabase.java | 2 +- .../securesms/database/MmsDatabase.java | 2 +- .../securesms/database/MmsSmsColumns.java | 4 + .../securesms/database/SmsDatabase.java | 25 +++- .../database/model/MessageRecord.java | 24 +++- .../groups/ui/GroupMemberListView.java | 7 ++ ...sV1MigrationBottomSheetDialogFragment.java | 79 +++++++++++++ .../migration/GroupsV1MigrationViewModel.java | 44 +++++++ .../securesms/jobs/GroupV1MigrationJob.java | 2 +- .../res/drawable/paragraph_marker_dark.xml | 13 +++ .../res/drawable/paragraph_marker_light.xml | 13 +++ .../res/layout/conversation_item_update.xml | 8 ++ ...psv1_migration_learn_more_bottom_sheet.xml | 110 ++++++++++++++++++ app/src/main/res/layout/item_member_view.xml | 31 +++++ app/src/main/res/values/attrs.xml | 3 + app/src/main/res/values/strings.xml | 19 +++ app/src/main/res/values/styles.xml | 24 ++++ app/src/main/res/values/themes.xml | 6 +- 21 files changed, 447 insertions(+), 26 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationBottomSheetDialogFragment.java create mode 100644 app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationViewModel.java create mode 100644 app/src/main/res/drawable/paragraph_marker_dark.xml create mode 100644 app/src/main/res/drawable/paragraph_marker_light.xml create mode 100644 app/src/main/res/layout/groupsv1_migration_learn_more_bottom_sheet.xml create mode 100644 app/src/main/res/layout/item_member_view.xml diff --git a/app/src/main/java/org/thoughtcrime/securesms/BindableConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/BindableConversationItem.java index 84fb46dc5f..bdaad0ef63 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/BindableConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/BindableConversationItem.java @@ -59,6 +59,7 @@ public interface BindableConversationItem extends Unbindable { void onVoiceNotePause(@NonNull Uri uri); void onVoiceNotePlay(@NonNull Uri uri, long messageId, double position); void onVoiceNoteSeekTo(@NonNull Uri uri, double position); + void onGroupMigrationLearnMoreClicked(@NonNull List pendingRecipients); /** @return true if handled, false if you want to let the normal url handling continue */ boolean onUrlClicked(@NonNull String url); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java index 5ac355938e..f8cfa22f27 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java @@ -22,7 +22,6 @@ import android.app.Activity; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; @@ -90,6 +89,7 @@ import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; +import org.thoughtcrime.securesms.groups.ui.migration.GroupsV1MigrationBottomSheetDialogFragment; import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob; import org.thoughtcrime.securesms.jobs.MultiDeviceViewOnceOpenJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; @@ -1417,6 +1417,11 @@ public class ConversationFragment extends LoggingFragment { public boolean onUrlClicked(@NonNull String url) { return CommunicationActions.handlePotentialGroupLinkUrl(requireActivity(), url); } + + @Override + public void onGroupMigrationLearnMoreClicked(@NonNull List pendingRecipients) { + GroupsV1MigrationBottomSheetDialogFragment.showForLearnMore(requireFragmentManager(), pendingRecipients); + } } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java index ce61fb8a7b..4f8d0b17ed 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java @@ -42,12 +42,14 @@ public final class ConversationUpdateItem extends LinearLayout private Set batchSelected; - private TextView body; - private LiveRecipient sender; - private ConversationMessage conversationMessage; - private MessageRecord messageRecord; - private Locale locale; - private LiveData displayBody; + private TextView body; + private TextView actionButton; + private LiveRecipient sender; + private ConversationMessage conversationMessage; + private Optional nextMessageRecord; + private MessageRecord messageRecord; + private LiveData displayBody; + private EventListener eventListener; private final UpdateObserver updateObserver = new UpdateObserver(); private final SenderObserver senderObserver = new SenderObserver(); @@ -63,7 +65,8 @@ public final class ConversationUpdateItem extends LinearLayout @Override public void onFinishInflate() { super.onFinishInflate(); - this.body = findViewById(R.id.conversation_update_body); + this.body = findViewById(R.id.conversation_update_body); + this.actionButton = findViewById(R.id.conversation_update_action); this.setOnClickListener(new InternalClickListener(null)); } @@ -82,12 +85,12 @@ public final class ConversationUpdateItem extends LinearLayout { this.batchSelected = batchSelected; - bind(lifecycleOwner, conversationMessage, locale); + bind(lifecycleOwner, conversationMessage, nextMessageRecord); } @Override public void setEventListener(@Nullable EventListener listener) { - // No events to report yet + this.eventListener = listener; } @Override @@ -95,10 +98,13 @@ public final class ConversationUpdateItem extends LinearLayout return conversationMessage; } - private void bind(@NonNull LifecycleOwner lifecycleOwner, @NonNull ConversationMessage conversationMessage, @NonNull Locale locale) { + private void bind(@NonNull LifecycleOwner lifecycleOwner, + @NonNull ConversationMessage conversationMessage, + @NonNull Optional nextMessageRecord) + { this.conversationMessage = conversationMessage; this.messageRecord = conversationMessage.getMessageRecord(); - this.locale = locale; + this.nextMessageRecord = nextMessageRecord; observeSender(lifecycleOwner, messageRecord.getIndividualRecipient()); @@ -106,7 +112,7 @@ public final class ConversationUpdateItem extends LinearLayout LiveData liveUpdateMessage = LiveUpdateMessage.fromMessageDescription(getContext(), updateDescription); LiveData spannableMessage = loading(liveUpdateMessage); - present(conversationMessage); + present(conversationMessage, nextMessageRecord); observeDisplayBody(lifecycleOwner, spannableMessage); } @@ -156,9 +162,24 @@ public final class ConversationUpdateItem extends LinearLayout } } - private void present(ConversationMessage conversationMessage) { + private void present(ConversationMessage conversationMessage, @NonNull Optional nextMessageRecord) { if (batchSelected.contains(conversationMessage)) setSelected(true); else setSelected(false); + + if (conversationMessage.getMessageRecord().isGroupV1MigrationEvent() && + (!nextMessageRecord.isPresent() || !nextMessageRecord.get().isGroupV1MigrationEvent())) + { + actionButton.setText(R.string.ConversationUpdateItem_learn_more); + actionButton.setVisibility(VISIBLE); + actionButton.setOnClickListener(v -> { + if (batchSelected.isEmpty() && eventListener != null) { + eventListener.onGroupMigrationLearnMoreClicked(conversationMessage.getMessageRecord().getGroupV1MigrationEventInvites()); + } + }); + } else { + actionButton.setVisibility(GONE); + actionButton.setOnClickListener(null); + } } @Override @@ -170,7 +191,7 @@ public final class ConversationUpdateItem extends LinearLayout @Override public void onChanged(Recipient recipient) { - present(conversationMessage); + present(conversationMessage, nextMessageRecord); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java index 24b88f30ec..cdeb1ecfc5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java @@ -137,7 +137,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns public abstract long insertMessageOutbox(@NonNull OutgoingMediaMessage message, long threadId, boolean forceSms, @Nullable SmsDatabase.InsertListener insertListener) throws MmsException; public abstract long insertMessageOutbox(@NonNull OutgoingMediaMessage message, long threadId, boolean forceSms, int defaultReceiptStatus, @Nullable SmsDatabase.InsertListener insertListener) throws MmsException; public abstract void insertProfileNameChangeMessages(@NonNull Recipient recipient, @NonNull String newProfileName, @NonNull String previousProfileName); - public abstract void insertGroupV1MigrationEvent(@NonNull RecipientId recipientId, long threadId, List pendingRecipients); + public abstract void insertGroupV1MigrationEvents(@NonNull RecipientId recipientId, long threadId, List pendingRecipients); public abstract boolean deleteMessage(long messageId); abstract void deleteThread(long threadId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java index 5fd012b3b1..6d49fb72f7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -415,7 +415,7 @@ public class MmsDatabase extends MessageDatabase { } @Override - public void insertGroupV1MigrationEvent(@NonNull RecipientId recipientId, long threadId, List pendingRecipients) { + public void insertGroupV1MigrationEvents(@NonNull RecipientId recipientId, long threadId, List pendingRecipients) { throw new UnsupportedOperationException(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsColumns.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsColumns.java index e909e06c40..8bda39820b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsColumns.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsColumns.java @@ -266,6 +266,10 @@ public interface MmsSmsColumns { return type == PROFILE_CHANGE_TYPE; } + public static boolean isGroupV1MigrationEvent(long type) { + return type == GV1_MIGRATION_TYPE; + } + public static long translateFromSystemBaseType(long theirType) { // public static final int NONE_TYPE = 0; // public static final int INBOX_TYPE = 1; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index 94810dfa15..1a0ea20ca6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -740,7 +740,22 @@ public class SmsDatabase extends MessageDatabase { } @Override - public void insertGroupV1MigrationEvent(@NonNull RecipientId recipientId, long threadId, List pendingRecipients) { + public void insertGroupV1MigrationEvents(@NonNull RecipientId recipientId, long threadId, @NonNull List pendingRecipients) { + insertGroupV1MigrationNotification(recipientId, threadId); + + if (pendingRecipients.size() > 0) { + insertGroupV1MigrationEvent(recipientId, threadId, pendingRecipients); + } + + notifyConversationListeners(threadId); + ApplicationDependencies.getJobManager().add(new TrimThreadJob(threadId)); + } + + private void insertGroupV1MigrationNotification(@NonNull RecipientId recipientId, long threadId) { + insertGroupV1MigrationEvent(recipientId, threadId, Collections.emptyList()); + } + + private void insertGroupV1MigrationEvent(@NonNull RecipientId recipientId, long threadId, @NonNull List pendingRecipients) { ContentValues values = new ContentValues(); values.put(RECIPIENT_ID, recipientId.serialize()); values.put(ADDRESS_DEVICE_ID, 1); @@ -749,12 +764,12 @@ public class SmsDatabase extends MessageDatabase { values.put(READ, 1); values.put(TYPE, Types.GV1_MIGRATION_TYPE); values.put(THREAD_ID, threadId); - values.put(BODY, RecipientId.toSerializedList(pendingRecipients)); + + if (pendingRecipients.size() > 0) { + values.put(BODY, RecipientId.toSerializedList(pendingRecipients)); + } databaseHelper.getWritableDatabase().insert(TABLE_NAME, null, values); - - notifyConversationListeners(threadId); - ApplicationDependencies.getJobManager().add(new TrimThreadJob(threadId)); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java index 71b3e7cac1..7a30b83fa0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java @@ -17,7 +17,6 @@ package org.thoughtcrime.securesms.database.model; import android.content.Context; -import android.graphics.Color; import android.text.Spannable; import android.text.SpannableString; import android.text.style.RelativeSizeSpan; @@ -46,6 +45,7 @@ import org.thoughtcrime.securesms.util.DateUtils; import org.thoughtcrime.securesms.util.ExpirationUtil; import org.thoughtcrime.securesms.util.GroupUtil; import org.thoughtcrime.securesms.util.StringUtil; +import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Function; import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil; import org.whispersystems.signalservice.api.util.UuidUtil; @@ -172,6 +172,13 @@ public abstract class MessageRecord extends DisplayRecord { } else if (isEndSession()) { if (isOutgoing()) return staticUpdateDescription(context.getString(R.string.SmsMessageRecord_secure_session_reset), R.drawable.ic_update_info_light_16, R.drawable.ic_update_info_dark_16); else return fromRecipient(getIndividualRecipient(), r-> context.getString(R.string.SmsMessageRecord_secure_session_reset_s, r.getDisplayName(context)), R.drawable.ic_update_info_light_16, R.drawable.ic_update_info_dark_16); + } else if (isGroupV1MigrationEvent()) { + if (Util.isEmpty(getBody())) { + return staticUpdateDescription(context.getString(R.string.MessageRecord_this_group_was_updated_to_a_new_group), R.drawable.ic_update_group_role_light_16, R.drawable.ic_update_group_role_dark_16); + } else { + int count = getGroupV1MigrationEventInvites().size(); + return staticUpdateDescription(context.getResources().getQuantityString(R.plurals.MessageRecord_members_couldnt_be_added_to_the_new_group_and_have_been_invited, count, count), R.drawable.ic_update_group_add_light_16, R.drawable.ic_update_group_add_dark_16); + } } return null; @@ -347,9 +354,22 @@ public abstract class MessageRecord extends DisplayRecord { return SmsDatabase.Types.isInvalidVersionKeyExchange(type); } + public boolean isGroupV1MigrationEvent() { + return SmsDatabase.Types.isGroupV1MigrationEvent(type); + } + + public @NonNull List getGroupV1MigrationEventInvites() { + if (isGroupV1MigrationEvent()) { + return RecipientId.fromSerializedList(getBody()); + } else { + return Collections.emptyList(); + } + } + public boolean isUpdate() { return isGroupAction() || isJoined() || isExpirationTimerUpdate() || isCallLog() || - isEndSession() || isIdentityUpdate() || isIdentityVerified() || isIdentityDefault() || isProfileChange(); + isEndSession() || isIdentityUpdate() || isIdentityVerified() || isIdentityDefault() || + isProfileChange() || isGroupV1MigrationEvent(); } public boolean isMediaPending() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupMemberListView.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupMemberListView.java index 0a00108f77..0188c42f34 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupMemberListView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupMemberListView.java @@ -9,7 +9,10 @@ import androidx.annotation.Nullable; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.annimon.stream.Stream; + import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.recipients.Recipient; import java.util.List; @@ -74,6 +77,10 @@ public final class GroupMemberListView extends RecyclerView { membersAdapter.updateData(recipients); } + public void setDisplayOnlyMembers(@NonNull List recipients) { + membersAdapter.updateData(Stream.of(recipients).map(r -> new GroupMemberEntry.FullMember(r, false)).toList()); + } + @Override protected void onMeasure(int widthSpec, int heightSpec) { if (maxHeight > 0) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationBottomSheetDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationBottomSheetDialogFragment.java new file mode 100644 index 0000000000..225de366ce --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationBottomSheetDialogFragment.java @@ -0,0 +1,79 @@ +package org.thoughtcrime.securesms.groups.ui.migration; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.ViewModelProviders; + +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.groups.ui.GroupMemberListView; +import org.thoughtcrime.securesms.recipients.Recipient; +import org.thoughtcrime.securesms.recipients.RecipientId; +import org.thoughtcrime.securesms.util.BottomSheetUtil; +import org.thoughtcrime.securesms.util.ThemeUtil; + +import java.util.ArrayList; +import java.util.List; + +public final class GroupsV1MigrationBottomSheetDialogFragment extends BottomSheetDialogFragment { + + private static final String KEY_PENDING = "pending"; + + private GroupsV1MigrationViewModel viewModel; + private GroupMemberListView pendingList; + private TextView pendingTitle; + + public static void showForLearnMore(@NonNull FragmentManager manager, @NonNull List pendingRecipients) { + Bundle args = new Bundle(); + args.putParcelableArrayList(KEY_PENDING, new ArrayList<>(pendingRecipients)); + + GroupsV1MigrationBottomSheetDialogFragment fragment = new GroupsV1MigrationBottomSheetDialogFragment(); + fragment.setArguments(args); + + fragment.show(manager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG); + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + setStyle(DialogFragment.STYLE_NORMAL, + ThemeUtil.isDarkTheme(requireContext()) ? R.style.Theme_Signal_RoundedBottomSheet + : R.style.Theme_Signal_RoundedBottomSheet_Light); + + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return inflater.inflate(R.layout.groupsv1_migration_learn_more_bottom_sheet, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + this.pendingTitle = view.findViewById(R.id.gv1_learn_more_pending_title); + this.pendingList = view.findViewById(R.id.gv1_learn_more_pending_list); + + List pending = getArguments().containsKey(KEY_PENDING) ? getArguments().getParcelableArrayList(KEY_PENDING) : null; + + this.viewModel = ViewModelProviders.of(this, new GroupsV1MigrationViewModel.Factory(pending)).get(GroupsV1MigrationViewModel.class); + viewModel.getPendingMembers().observe(getViewLifecycleOwner(), this::onPendingMembersChanged); + } + + @Override + public void show(@NonNull FragmentManager manager, @Nullable String tag) { + BottomSheetUtil.show(manager, tag, this); + } + + private void onPendingMembersChanged(@NonNull List pendingMembers) { + pendingTitle.setText(getResources().getQuantityText(R.plurals.GroupsV1MigrationLearnMore_these_members_will_need_to_accept_an_invite, pendingMembers.size())); + pendingList.setDisplayOnlyMembers(pendingMembers); + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationViewModel.java new file mode 100644 index 0000000000..7f2d42afaa --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationViewModel.java @@ -0,0 +1,44 @@ +package org.thoughtcrime.securesms.groups.ui.migration; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import org.thoughtcrime.securesms.recipients.Recipient; +import org.thoughtcrime.securesms.recipients.RecipientId; +import org.thoughtcrime.securesms.util.concurrent.SignalExecutors; + +import java.util.List; + +class GroupsV1MigrationViewModel extends ViewModel { + + private final MutableLiveData> pendingMembers; + + private GroupsV1MigrationViewModel(@NonNull List pendingMembers) { + this.pendingMembers = new MutableLiveData<>(); + + SignalExecutors.BOUNDED.execute(() -> { + this.pendingMembers.postValue(Recipient.resolvedList(pendingMembers)); + }); + } + + @NonNull LiveData> getPendingMembers() { + return pendingMembers; + } + + static class Factory extends ViewModelProvider.NewInstanceFactory { + + private final List pendingMembers; + + Factory(List pendingMembers) { + this.pendingMembers = pendingMembers; + } + + @Override + public @NonNull T create(@NonNull Class modelClass) { + return modelClass.cast(new GroupsV1MigrationViewModel(pendingMembers)); + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java index 8f34790ed2..f1b0842ddd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java @@ -285,7 +285,7 @@ public class GroupV1MigrationJob extends BaseJob { Log.i(TAG, "[Local] Migrating group over to the version we were added to: V" + decryptedGroup.getRevision()); DatabaseFactory.getGroupDatabase(context).migrateToV2(gv1Id, decryptedGroup); - DatabaseFactory.getSmsDatabase(context).insertGroupV1MigrationEvent(groupRecipient.getId(), threadId, pendingRecipients); + DatabaseFactory.getSmsDatabase(context).insertGroupV1MigrationEvents(groupRecipient.getId(), threadId, pendingRecipients); Log.i(TAG, "[Local] Applying all changes since V" + decryptedGroup.getRevision()); try { diff --git a/app/src/main/res/drawable/paragraph_marker_dark.xml b/app/src/main/res/drawable/paragraph_marker_dark.xml new file mode 100644 index 0000000000..654064b47a --- /dev/null +++ b/app/src/main/res/drawable/paragraph_marker_dark.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/paragraph_marker_light.xml b/app/src/main/res/drawable/paragraph_marker_light.xml new file mode 100644 index 0000000000..e02a5a3b0e --- /dev/null +++ b/app/src/main/res/drawable/paragraph_marker_light.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/conversation_item_update.xml b/app/src/main/res/layout/conversation_item_update.xml index 85ae0fdcd7..0925af94e1 100644 --- a/app/src/main/res/layout/conversation_item_update.xml +++ b/app/src/main/res/layout/conversation_item_update.xml @@ -24,4 +24,12 @@ android:textColor="?attr/conversation_item_update_text_color" tools:text="Gwen Stacy set the disappearing message timer to 1 hour" /> + + diff --git a/app/src/main/res/layout/groupsv1_migration_learn_more_bottom_sheet.xml b/app/src/main/res/layout/groupsv1_migration_learn_more_bottom_sheet.xml new file mode 100644 index 0000000000..5fc0e26627 --- /dev/null +++ b/app/src/main/res/layout/groupsv1_migration_learn_more_bottom_sheet.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_member_view.xml b/app/src/main/res/layout/item_member_view.xml new file mode 100644 index 0000000000..fec6830665 --- /dev/null +++ b/app/src/main/res/layout/item_member_view.xml @@ -0,0 +1,31 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 19d34d5329..9c70469ba5 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -297,6 +297,9 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 41a3a3eb37..e270720103 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -539,6 +539,19 @@ Learn more These users can’t be automatically added to this group by you.\n\nThey’ve been invited to join the group, and won’t see any group messages until they accept. + + What are New Groups? + New Groups have features like @mentions and group admins, and will support more features in the future. + All message history and media has been kept from before the upgrade. + + This member will need to accept an invite to join this group again and will not receive group messages until they accept: + These members will need to accept an invite to join this group again and will not receive group messages until they accept: + + + This member is not capable of joining New Groups, and has been removed from the group: + These members are not capable of joining New Groups, and have been removed from the group: + + Leave group? You will no longer be able to send or receive messages in this group. @@ -951,6 +964,11 @@ You set the disappearing message timer to %1$s. %1$s set the disappearing message timer to %2$s. The disappearing message timer has been set to %1$s. + This group was updated to a New Group. + + %1$s member couldn\'t be added to the New Group and has been invited to join. + %1$s members couldn\'t be added to the New Group and have been invited to join. + %1$s changed their profile name to %2$s. @@ -1773,6 +1791,7 @@ Loading + Learn more Play … Pause diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 8c3f66b091..13d5c33f6c 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -522,6 +522,30 @@ @color/core_grey_50 + + + +