mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 01:07:47 +00:00
Add group profile sharing logic
// FREEBIE
This commit is contained in:
parent
f17af19d09
commit
64ad9ec9dd
@ -23,6 +23,12 @@
|
|||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:clipChildren="false">
|
android:clipChildren="false">
|
||||||
|
|
||||||
|
<ViewStub android:id="@+id/group_share_profile_view_stub"
|
||||||
|
android:layout="@layout/conversation_activity_group_share_profile_stub"
|
||||||
|
android:inflatedId="@+id/group_share_profile_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<ViewStub android:id="@+id/unverified_banner_stub"
|
<ViewStub android:id="@+id/unverified_banner_stub"
|
||||||
android:layout="@layout/conversation_activity_unverified_banner_stub"
|
android:layout="@layout/conversation_activity_unverified_banner_stub"
|
||||||
android:inflatedId="@+id/unverified_banner"
|
android:inflatedId="@+id/unverified_banner"
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<org.thoughtcrime.securesms.profiles.GroupShareProfileView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/group_share_profile_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
27
res/layout/profile_group_share_view.xml
Normal file
27
res/layout/profile_group_share_view.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/reminder_background"
|
||||||
|
android:focusable="true"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:src="@drawable/ic_face_white_24dp"/>
|
||||||
|
|
||||||
|
<TextView android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:text="@string/profile_group_share_view__make_your_profile_name_and_photo_visible_to_this_group"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -327,6 +327,11 @@
|
|||||||
<string name="GroupCreateActivity_loading_group_details">Loading group details...</string>
|
<string name="GroupCreateActivity_loading_group_details">Loading group details...</string>
|
||||||
<string name="GroupCreateActivity_youre_already_in_the_group">You\'re already in the group.</string>
|
<string name="GroupCreateActivity_youre_already_in_the_group">You\'re already in the group.</string>
|
||||||
|
|
||||||
|
<!-- GroupShareProfileView -->
|
||||||
|
<string name="GroupShareProfileView_share_your_profile_name_and_photo_with_this_group">Share your profile name and photo with this group?</string>
|
||||||
|
<string name="GroupShareProfileView_do_you_want_to_make_your_profile_name_and_photo_visible_to_all_current_and_future_members_of_this_group">Do you want to make your profile name and photo visible to all current and future members of this group?</string>
|
||||||
|
<string name="GroupShareProfileView_make_visible">Make visible</string>
|
||||||
|
|
||||||
<!-- GroupMembersDialog -->
|
<!-- GroupMembersDialog -->
|
||||||
<string name="GroupMembersDialog_me">Me</string>
|
<string name="GroupMembersDialog_me">Me</string>
|
||||||
|
|
||||||
@ -959,6 +964,9 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="GroupUtil_group_name_is_now">Group name is now \'%1$s\'.</string>
|
<string name="GroupUtil_group_name_is_now">Group name is now \'%1$s\'.</string>
|
||||||
|
|
||||||
|
<!-- profile_group_share_view -->
|
||||||
|
<string name="profile_group_share_view__make_your_profile_name_and_photo_visible_to_this_group">Make your profile name and photo visible to this group?</string>
|
||||||
|
|
||||||
<!-- prompt_passphrase_activity -->
|
<!-- prompt_passphrase_activity -->
|
||||||
<string name="prompt_passphrase_activity__unlock">Unlock</string>
|
<string name="prompt_passphrase_activity__unlock">Unlock</string>
|
||||||
|
|
||||||
|
@ -127,6 +127,7 @@ import org.thoughtcrime.securesms.mms.Slide;
|
|||||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||||
import org.thoughtcrime.securesms.notifications.MarkReadReceiver;
|
import org.thoughtcrime.securesms.notifications.MarkReadReceiver;
|
||||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||||
|
import org.thoughtcrime.securesms.profiles.GroupShareProfileView;
|
||||||
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
|
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
||||||
@ -206,20 +207,21 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
private static final int PICK_GIF = 9;
|
private static final int PICK_GIF = 9;
|
||||||
private static final int SMS_DEFAULT = 10;
|
private static final int SMS_DEFAULT = 10;
|
||||||
|
|
||||||
private MasterSecret masterSecret;
|
private MasterSecret masterSecret;
|
||||||
protected ComposeText composeText;
|
protected ComposeText composeText;
|
||||||
private AnimatingToggle buttonToggle;
|
private AnimatingToggle buttonToggle;
|
||||||
private SendButton sendButton;
|
private SendButton sendButton;
|
||||||
private ImageButton attachButton;
|
private ImageButton attachButton;
|
||||||
protected ConversationTitleView titleView;
|
protected ConversationTitleView titleView;
|
||||||
private TextView charactersLeft;
|
private TextView charactersLeft;
|
||||||
private ConversationFragment fragment;
|
private ConversationFragment fragment;
|
||||||
private Button unblockButton;
|
private Button unblockButton;
|
||||||
private Button makeDefaultSmsButton;
|
private Button makeDefaultSmsButton;
|
||||||
private InputAwareLayout container;
|
private InputAwareLayout container;
|
||||||
private View composePanel;
|
private View composePanel;
|
||||||
protected Stub<ReminderView> reminderView;
|
protected Stub<ReminderView> reminderView;
|
||||||
private Stub<UnverifiedBannerView> unverifiedBannerView;
|
private Stub<UnverifiedBannerView> unverifiedBannerView;
|
||||||
|
private Stub<GroupShareProfileView> groupShareProfileView;
|
||||||
|
|
||||||
private AttachmentTypeSelector attachmentTypeSelector;
|
private AttachmentTypeSelector attachmentTypeSelector;
|
||||||
private AttachmentManager attachmentManager;
|
private AttachmentManager attachmentManager;
|
||||||
@ -323,6 +325,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
titleView.setTitle(recipient);
|
titleView.setTitle(recipient);
|
||||||
setActionBarColor(recipient.getColor());
|
setActionBarColor(recipient.getColor());
|
||||||
setBlockedUserState(recipient, isSecureText, isDefaultSms);
|
setBlockedUserState(recipient, isSecureText, isDefaultSms);
|
||||||
|
setGroupShareProfileReminder(recipient);
|
||||||
calculateCharactersRemaining();
|
calculateCharactersRemaining();
|
||||||
|
|
||||||
MessageNotifier.setVisibleThread(threadId);
|
MessageNotifier.setVisibleThread(threadId);
|
||||||
@ -1149,6 +1152,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
container = ViewUtil.findById(this, R.id.layout_container);
|
container = ViewUtil.findById(this, R.id.layout_container);
|
||||||
reminderView = ViewUtil.findStubById(this, R.id.reminder_stub);
|
reminderView = ViewUtil.findStubById(this, R.id.reminder_stub);
|
||||||
unverifiedBannerView = ViewUtil.findStubById(this, R.id.unverified_banner_stub);
|
unverifiedBannerView = ViewUtil.findStubById(this, R.id.unverified_banner_stub);
|
||||||
|
groupShareProfileView = ViewUtil.findStubById(this, R.id.group_share_profile_view_stub);
|
||||||
quickAttachmentDrawer = ViewUtil.findById(this, R.id.quick_attachment_drawer);
|
quickAttachmentDrawer = ViewUtil.findById(this, R.id.quick_attachment_drawer);
|
||||||
quickAttachmentToggle = ViewUtil.findById(this, R.id.quick_attachment_toggle);
|
quickAttachmentToggle = ViewUtil.findById(this, R.id.quick_attachment_toggle);
|
||||||
inputPanel = ViewUtil.findById(this, R.id.bottom_panel);
|
inputPanel = ViewUtil.findById(this, R.id.bottom_panel);
|
||||||
@ -1274,6 +1278,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
titleView.setVerified(identityRecords.isVerified());
|
titleView.setVerified(identityRecords.isVerified());
|
||||||
setBlockedUserState(recipient, isSecureText, isDefaultSms);
|
setBlockedUserState(recipient, isSecureText, isDefaultSms);
|
||||||
setActionBarColor(recipient.getColor());
|
setActionBarColor(recipient.getColor());
|
||||||
|
setGroupShareProfileReminder(recipient);
|
||||||
updateInviteReminder(recipient.hasSeenInviteReminder());
|
updateInviteReminder(recipient.hasSeenInviteReminder());
|
||||||
updateDefaultSubscriptionId(recipient.getDefaultSubscriptionId());
|
updateDefaultSubscriptionId(recipient.getDefaultSubscriptionId());
|
||||||
initializeSecurity(isSecureText, isDefaultSms);
|
initializeSecurity(isSecureText, isDefaultSms);
|
||||||
@ -1460,6 +1465,15 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setGroupShareProfileReminder(@NonNull Recipient recipient) {
|
||||||
|
if (recipient.isPushGroupRecipient() && !recipient.isProfileSharing()) {
|
||||||
|
groupShareProfileView.get().setRecipient(recipient);
|
||||||
|
groupShareProfileView.get().setVisibility(View.VISIBLE);
|
||||||
|
} else if (groupShareProfileView.resolved()) {
|
||||||
|
groupShareProfileView.get().setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void calculateCharactersRemaining() {
|
private void calculateCharactersRemaining() {
|
||||||
String messageBody = composeText.getTextTrimmed();
|
String messageBody = composeText.getTextTrimmed();
|
||||||
TransportOption transportOption = sendButton.getSelectedTransport();
|
TransportOption transportOption = sendButton.getSelectedTransport();
|
||||||
|
@ -56,6 +56,7 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
|||||||
import org.thoughtcrime.securesms.database.Address;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
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.RecipientDatabase;
|
||||||
import org.thoughtcrime.securesms.database.loaders.ConversationLoader;
|
import org.thoughtcrime.securesms.database.loaders.ConversationLoader;
|
||||||
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;
|
||||||
@ -430,7 +431,7 @@ public class ConversationFragment extends Fragment
|
|||||||
setLastSeen(loader.getLastSeen());
|
setLastSeen(loader.getLastSeen());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loader.hasSent() && !recipient.isGroupRecipient() && recipient.getName() == null) {
|
if (!loader.hasSent() && !recipient.isSystemContact() && !recipient.isGroupRecipient() && recipient.getRegistered() != RecipientDatabase.RegisteredState.REGISTERED) {
|
||||||
getListAdapter().setHeaderView(unknownSenderView);
|
getListAdapter().setHeaderView(unknownSenderView);
|
||||||
} else {
|
} else {
|
||||||
getListAdapter().setHeaderView(null);
|
getListAdapter().setHeaderView(null);
|
||||||
|
@ -71,9 +71,6 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
|||||||
|
|
||||||
initializeContactUpdatesReceiver();
|
initializeContactUpdatesReceiver();
|
||||||
|
|
||||||
Intent intent = new Intent(this, CreateProfileActivity.class);
|
|
||||||
startActivity(intent);
|
|
||||||
|
|
||||||
RatingManager.showRatingDialogIfNecessary(this);
|
RatingManager.showRatingDialogIfNecessary(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
|||||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||||
import org.whispersystems.jobqueue.JobParameters;
|
import org.whispersystems.jobqueue.JobParameters;
|
||||||
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
||||||
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||||
@ -138,6 +139,7 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
|
|||||||
{
|
{
|
||||||
SignalServiceMessageSender messageSender = messageSenderFactory.create();
|
SignalServiceMessageSender messageSender = messageSenderFactory.create();
|
||||||
String groupId = message.getRecipient().getAddress().toGroupString();
|
String groupId = message.getRecipient().getAddress().toGroupString();
|
||||||
|
Optional<byte[]> profileKey = getProfileKey(message.getRecipient());
|
||||||
List<Recipient> recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupId, false);
|
List<Recipient> recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupId, false);
|
||||||
MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints();
|
MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints();
|
||||||
List<Attachment> scaledAttachments = scaleAttachments(masterSecret, mediaConstraints, message.getAttachments());
|
List<Attachment> scaledAttachments = scaleAttachments(masterSecret, mediaConstraints, message.getAttachments());
|
||||||
@ -154,15 +156,23 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
|
|||||||
SignalServiceAttachment avatar = attachmentStreams.isEmpty() ? null : attachmentStreams.get(0);
|
SignalServiceAttachment avatar = attachmentStreams.isEmpty() ? null : attachmentStreams.get(0);
|
||||||
SignalServiceGroup.Type type = groupMessage.isGroupQuit() ? SignalServiceGroup.Type.QUIT : SignalServiceGroup.Type.UPDATE;
|
SignalServiceGroup.Type type = groupMessage.isGroupQuit() ? SignalServiceGroup.Type.QUIT : SignalServiceGroup.Type.UPDATE;
|
||||||
SignalServiceGroup group = new SignalServiceGroup(type, GroupUtil.getDecodedId(groupId), groupContext.getName(), groupContext.getMembersList(), avatar);
|
SignalServiceGroup group = new SignalServiceGroup(type, GroupUtil.getDecodedId(groupId), groupContext.getName(), groupContext.getMembersList(), avatar);
|
||||||
SignalServiceDataMessage groupDataMessage = new SignalServiceDataMessage(message.getSentTimeMillis(), group, null, null);
|
SignalServiceDataMessage groupDataMessage = SignalServiceDataMessage.newBuilder()
|
||||||
|
.withTimestamp(message.getSentTimeMillis())
|
||||||
|
.asGroupMessage(group)
|
||||||
|
.build();
|
||||||
|
|
||||||
messageSender.sendMessage(addresses, groupDataMessage);
|
messageSender.sendMessage(addresses, groupDataMessage);
|
||||||
} else {
|
} else {
|
||||||
SignalServiceGroup group = new SignalServiceGroup(GroupUtil.getDecodedId(groupId));
|
SignalServiceGroup group = new SignalServiceGroup(GroupUtil.getDecodedId(groupId));
|
||||||
SignalServiceDataMessage groupMessage = new SignalServiceDataMessage(message.getSentTimeMillis(), group,
|
SignalServiceDataMessage groupMessage = SignalServiceDataMessage.newBuilder()
|
||||||
attachmentStreams, message.getBody(), false,
|
.withTimestamp(message.getSentTimeMillis())
|
||||||
(int)(message.getExpiresIn() / 1000),
|
.asGroupMessage(group)
|
||||||
message.isExpirationUpdate(), null);
|
.withAttachments(attachmentStreams)
|
||||||
|
.withBody(message.getBody())
|
||||||
|
.withExpiration((int)(message.getExpiresIn() / 1000))
|
||||||
|
.asExpirationUpdate(message.isExpirationUpdate())
|
||||||
|
.withProfileKey(profileKey.orNull())
|
||||||
|
.build();
|
||||||
|
|
||||||
messageSender.sendMessage(addresses, groupMessage);
|
messageSender.sendMessage(addresses, groupMessage);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
package org.thoughtcrime.securesms.profiles;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.support.annotation.AttrRes;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.annotation.RequiresApi;
|
||||||
|
import android.support.annotation.StyleRes;
|
||||||
|
import android.support.v7.app.AlertDialog;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
|
||||||
|
public class GroupShareProfileView extends FrameLayout {
|
||||||
|
|
||||||
|
private View container;
|
||||||
|
private @Nullable Recipient recipient;
|
||||||
|
|
||||||
|
public GroupShareProfileView(@NonNull Context context) {
|
||||||
|
super(context);
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroupShareProfileView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroupShareProfileView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
public GroupShareProfileView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialize() {
|
||||||
|
inflate(getContext(), R.layout.profile_group_share_view, this);
|
||||||
|
|
||||||
|
this.container = ViewUtil.findById(this, R.id.container);
|
||||||
|
this.container.setOnClickListener(view -> {
|
||||||
|
if (this.recipient != null) {
|
||||||
|
new AlertDialog.Builder(getContext())
|
||||||
|
.setIconAttribute(R.attr.dialog_info_icon)
|
||||||
|
.setTitle(R.string.GroupShareProfileView_share_your_profile_name_and_photo_with_this_group)
|
||||||
|
.setMessage(R.string.GroupShareProfileView_do_you_want_to_make_your_profile_name_and_photo_visible_to_all_current_and_future_members_of_this_group)
|
||||||
|
.setPositiveButton(R.string.GroupShareProfileView_make_visible, (dialog, which) -> {
|
||||||
|
DatabaseFactory.getRecipientDatabase(getContext()).setProfileSharing(recipient, true);
|
||||||
|
})
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipient(@NonNull Recipient recipient) {
|
||||||
|
this.recipient = recipient;
|
||||||
|
}
|
||||||
|
}
|
@ -430,6 +430,9 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized RegisteredState getRegistered() {
|
public synchronized RegisteredState getRegistered() {
|
||||||
|
if (isPushGroupRecipient()) return RegisteredState.REGISTERED;
|
||||||
|
else if (isMmsGroupRecipient()) return RegisteredState.NOT_REGISTERED;
|
||||||
|
|
||||||
return registered;
|
return registered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user