Add 'Add to contacts' button to bottom sheet.

master
Greyson Parrelli 2020-06-08 13:20:07 -04:00
parent 8b91f8f9e7
commit 59916f1e95
8 changed files with 103 additions and 35 deletions

View File

@ -207,6 +207,7 @@ import org.thoughtcrime.securesms.recipients.RecipientExporter;
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.recipients.ui.bottomsheet.RecipientBottomSheetDialogFragment;
import org.thoughtcrime.securesms.registration.RegistrationNavigationActivity;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.sms.MessageSender;
@ -594,7 +595,14 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
handleImageFromDeviceCameraApp();
break;
case ADD_CONTACT:
onRecipientChanged(recipient.get());
SimpleTask.run(() -> {
try {
DirectoryHelper.refreshDirectoryFor(this, recipient.get(), false);
} catch (IOException e) {
Log.w(TAG, "Failed to refresh user after adding to contacts.");
}
return null;
}, nothing -> onRecipientChanged(recipient.get()));
break;
case PICK_LOCATION:
SignalPlace place = new SignalPlace(PlacePickerActivity.addressFromData(data));

View File

@ -1,5 +1,7 @@
package org.thoughtcrime.securesms.recipients.ui.bottomsheet;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
@ -20,6 +22,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.AvatarImageView;
import org.thoughtcrime.securesms.groups.GroupId;
import org.thoughtcrime.securesms.recipients.RecipientExporter;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.ThemeUtil;
@ -27,8 +30,14 @@ import org.thoughtcrime.securesms.util.Util;
import java.util.Objects;
/**
* A bottom sheet that shows some simple recipient details, as well as some actions (like calling,
* adding to contacts, etc).
*/
public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogFragment {
public static final int REQUEST_CODE_ADD_CONTACT = 1111;
private static final String ARGS_RECIPIENT_ID = "RECIPIENT_ID";
private static final String ARGS_GROUP_ID = "GROUP_ID";
@ -40,6 +49,7 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
private Button secureCallButton;
private Button blockButton;
private Button unblockButton;
private Button addContactButton;
private Button viewSafetyNumberButton;
private Button makeGroupAdminButton;
private Button removeAdminButton;
@ -67,6 +77,7 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
setStyle(DialogFragment.STYLE_NORMAL,
ThemeUtil.isDarkTheme(requireContext()) ? R.style.Theme_Signal_RecipientBottomSheet
: R.style.Theme_Signal_RecipientBottomSheet_Light);
super.onCreate(savedInstanceState);
}
@ -74,18 +85,19 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.recipient_bottom_sheet, container, false);
avatar = view.findViewById(R.id.recipient_avatar);
fullName = view.findViewById(R.id.full_name);
usernameNumber = view.findViewById(R.id.username_number);
messageButton = view.findViewById(R.id.message_button);
secureCallButton = view.findViewById(R.id.secure_call_button);
blockButton = view.findViewById(R.id.block_button);
unblockButton = view.findViewById(R.id.unblock_button);
viewSafetyNumberButton = view.findViewById(R.id.view_safety_number_button);
makeGroupAdminButton = view.findViewById(R.id.make_group_admin_button);
removeAdminButton = view.findViewById(R.id.remove_group_admin_button);
removeFromGroupButton = view.findViewById(R.id.remove_from_group_button);
adminActionBusy = view.findViewById(R.id.admin_action_busy);
avatar = view.findViewById(R.id.rbs_recipient_avatar);
fullName = view.findViewById(R.id.rbs_full_name);
usernameNumber = view.findViewById(R.id.rbs_username_number);
messageButton = view.findViewById(R.id.rbs_message_button);
secureCallButton = view.findViewById(R.id.rbs_secure_call_button);
blockButton = view.findViewById(R.id.rbs_block_button);
unblockButton = view.findViewById(R.id.rbs_unblock_button);
addContactButton = view.findViewById(R.id.rbs_add_contact_button);
viewSafetyNumberButton = view.findViewById(R.id.rbs_view_safety_number_button);
makeGroupAdminButton = view.findViewById(R.id.rbs_make_group_admin_button);
removeAdminButton = view.findViewById(R.id.rbs_remove_group_admin_button);
removeFromGroupButton = view.findViewById(R.id.rbs_remove_from_group_button);
adminActionBusy = view.findViewById(R.id.rbs_admin_action_busy);
return view;
}
@ -125,6 +137,15 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
unblockButton.setVisibility(blocked ? View.VISIBLE : View.GONE);
secureCallButton.setVisibility(recipient.isRegistered() ? View.VISIBLE : View.GONE);
if (recipient.isSystemContact() || recipient.isGroup()) {
addContactButton.setVisibility(View.GONE);
} else {
addContactButton.setVisibility(View.VISIBLE);
addContactButton.setOnClickListener(v -> {
startActivityForResult(RecipientExporter.export(recipient).asAddContactIntent(), REQUEST_CODE_ADD_CONTACT);
});
}
});
viewModel.getAdminActionStatus().observe(getViewLifecycleOwner(), adminStatus -> {
@ -175,4 +196,11 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
removeFromGroupButton.setEnabled(!busy);
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_ADD_CONTACT) {
viewModel.onAddedToContacts();
}
}
}

View File

@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.util.Consumer;
import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.IdentityDatabase;
import org.thoughtcrime.securesms.groups.GroupChangeBusyException;
@ -64,6 +65,16 @@ final class RecipientDialogRepository {
recipientCallback::onRecipient);
}
void refreshRecipient() {
SignalExecutors.UNBOUNDED.execute(() -> {
try {
DirectoryHelper.refreshDirectoryFor(context, Recipient.resolved(recipientId), false);
} catch (IOException e) {
Log.w(TAG, "Failed to refresh user after adding to contacts.");
}
});
}
void getGroupName(@NonNull Consumer<String> stringConsumer) {
SimpleTask.run(SignalExecutors.BOUNDED,
() -> DatabaseFactory.getGroupDatabase(context).requireGroup(Objects.requireNonNull(groupId)).getTitle(),

View File

@ -11,6 +11,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
@ -166,6 +167,10 @@ final class RecipientDialogViewModel extends ViewModel {
.show());
}
void onAddedToContacts() {
recipientDialogRepository.refreshRecipient();
}
@WorkerThread
private void showErrorToast(@NonNull GroupChangeFailureReason e) {
Util.runOnMain(() -> Toast.makeText(context, GroupErrors.getUserDisplayMessage(e), Toast.LENGTH_LONG).show());

View File

@ -7,7 +7,7 @@
tools:theme="@style/Theme.Signal.RecipientBottomSheet.Light">
<org.thoughtcrime.securesms.components.AvatarImageView
android:id="@+id/recipient_avatar"
android:id="@+id/rbs_recipient_avatar"
android:layout_width="96dp"
android:layout_height="96dp"
android:layout_gravity="center_horizontal"
@ -18,18 +18,18 @@
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="@+id/admin_action_busy"
android:id="@+id/rbs_admin_action_busy"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/recipient_avatar"
app:layout_constraintEnd_toEndOf="@+id/recipient_avatar"
app:layout_constraintStart_toStartOf="@+id/recipient_avatar"
app:layout_constraintTop_toTopOf="@+id/recipient_avatar"
app:layout_constraintBottom_toBottomOf="@+id/rbs_recipient_avatar"
app:layout_constraintEnd_toEndOf="@+id/rbs_recipient_avatar"
app:layout_constraintStart_toStartOf="@+id/rbs_recipient_avatar"
app:layout_constraintTop_toTopOf="@+id/rbs_recipient_avatar"
tools:visibility="visible" />
<TextView
android:id="@+id/full_name"
android:id="@+id/rbs_full_name"
style="@style/TextAppearance.Signal.Body1.Bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -38,11 +38,11 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/recipient_avatar"
tools:text="Miyuki Shibata" />
app:layout_constraintTop_toBottomOf="@id/rbs_recipient_avatar"
tools:text="Gwen Stacy" />
<TextView
android:id="@+id/username_number"
android:id="@+id/rbs_username_number"
style="@style/Signal.Text.Body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -50,8 +50,8 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/full_name"
tools:text="\@shibatabread +1 555-654-6657" />
app:layout_constraintTop_toBottomOf="@+id/rbs_full_name"
tools:text="\@spidergwen +1 555-654-6657" />
<LinearLayout
android:layout_width="0dp"
@ -61,10 +61,10 @@
android:paddingBottom="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/username_number">
app:layout_constraintTop_toBottomOf="@+id/rbs_username_number">
<Button
android:id="@+id/message_button"
android:id="@+id/rbs_message_button"
style="@style/Widget.Signal.Button.TextButton.Drawable"
android:layout_width="match_parent"
android:layout_height="56dp"
@ -74,7 +74,7 @@
app:drawableStartCompat="?attr/recipient_message_icon" />
<Button
android:id="@+id/secure_call_button"
android:id="@+id/rbs_secure_call_button"
style="@style/Widget.Signal.Button.TextButton.Drawable"
android:layout_width="match_parent"
android:layout_height="56dp"
@ -84,7 +84,7 @@
app:drawableStartCompat="?attr/recipient_call_icon" />
<Button
android:id="@+id/block_button"
android:id="@+id/rbs_block_button"
style="@style/Widget.Signal.Button.TextButton.Drawable"
android:layout_width="match_parent"
android:layout_height="56dp"
@ -96,7 +96,7 @@
tools:visibility="visible" />
<Button
android:id="@+id/unblock_button"
android:id="@+id/rbs_unblock_button"
style="@style/Widget.Signal.Button.TextButton.Drawable"
android:layout_width="match_parent"
android:layout_height="56dp"
@ -108,7 +108,19 @@
tools:visibility="visible" />
<Button
android:id="@+id/view_safety_number_button"
android:id="@+id/rbs_add_contact_button"
style="@style/Widget.Signal.Button.TextButton.Drawable"
android:layout_width="match_parent"
android:layout_height="56dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="@string/RecipientBottomSheet_add_to_contacts"
android:visibility="gone"
app:drawableStartCompat="?attr/recipient_add_contact_icon"
tools:visibility="visible" />
<Button
android:id="@+id/rbs_view_safety_number_button"
style="@style/Widget.Signal.Button.TextButton.Drawable"
android:layout_width="match_parent"
android:layout_height="56dp"
@ -118,7 +130,7 @@
app:drawableStartCompat="?attr/recipient_view_safety_icon" />
<Button
android:id="@+id/make_group_admin_button"
android:id="@+id/rbs_make_group_admin_button"
style="@style/Widget.Signal.Button.TextButton.Drawable"
android:layout_width="match_parent"
android:layout_height="56dp"
@ -130,7 +142,7 @@
tools:visibility="visible" />
<Button
android:id="@+id/remove_group_admin_button"
android:id="@+id/rbs_remove_group_admin_button"
style="@style/Widget.Signal.Button.TextButton.Drawable"
android:layout_width="match_parent"
android:layout_height="56dp"
@ -142,7 +154,7 @@
tools:visibility="visible" />
<Button
android:id="@+id/remove_from_group_button"
android:id="@+id/rbs_remove_from_group_button"
style="@style/Widget.Signal.Button.TextButton.Drawable"
android:layout_width="match_parent"
android:layout_height="56dp"

View File

@ -297,6 +297,7 @@
<attr name="recipient_message_icon" format="reference"/>
<attr name="recipient_call_icon" format="reference"/>
<attr name="recipient_block_icon" format="reference"/>
<attr name="recipient_add_contact_icon" format="reference"/>
<attr name="recipient_view_safety_icon" format="reference"/>
<attr name="recipient_make_admin_icon" format="reference"/>
<attr name="recipient_remove_icon" format="reference"/>

View File

@ -2302,6 +2302,7 @@
<string name="RecipientBottomSheet_call">Call</string>
<string name="RecipientBottomSheet_block">Block</string>
<string name="RecipientBottomSheet_unblock">Unblock</string>
<string name="RecipientBottomSheet_add_to_contacts">Add to contacts</string>
<string name="RecipientBottomSheet_view_safety_number">View safety number</string>
<string name="RecipientBottomSheet_make_group_admin">Make group admin</string>
<string name="RecipientBottomSheet_remove_as_admin">Remove as admin</string>

View File

@ -870,11 +870,12 @@
<item name="title_text_color_secondary">@color/core_grey_60</item>
<item name="android:navigationBarColor" tools:ignore="NewApi">@color/white</item>
<item name="android:windowLightNavigationBar" tools:ignore="NewApi">false</item>
<item name="android:windowLightNavigationBar" tools:ignore="NewApi">true</item>
<item name="recipient_message_icon">@drawable/ic_message_outline_tinted_24</item>
<item name="recipient_call_icon">@drawable/ic_phone_right_outline_tinted_24</item>
<item name="recipient_block_icon">@drawable/ic_block_tinted_24</item>
<item name="recipient_add_contact_icon">@drawable/ic_plus_24</item>
<item name="recipient_view_safety_icon">@drawable/ic_info_outline_tinted_24</item>
<item name="recipient_make_admin_icon">@drawable/ic_group_outline_24</item>
<item name="recipient_remove_icon">@drawable/ic_leave_tinted_24</item>
@ -896,6 +897,7 @@
<item name="recipient_message_icon">@drawable/ic_message_solid_tinted_24</item>
<item name="recipient_call_icon">@drawable/ic_phone_right_solid_tinted_24</item>
<item name="recipient_block_icon">@drawable/ic_block_tinted_24</item>
<item name="recipient_add_contact_icon">@drawable/ic_plus_24</item>
<item name="recipient_view_safety_icon">@drawable/ic_info_solid_tinted_24</item>
<item name="recipient_make_admin_icon">@drawable/ic_group_solid_24</item>
<item name="recipient_remove_icon">@drawable/ic_leave_tinted_24</item>