mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-26 15:57:34 +00:00
Remove NewGroupUI FeatureFlag.
This commit is contained in:
@@ -249,10 +249,6 @@
|
|||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||||
|
|
||||||
<activity android:name=".GroupCreateActivity"
|
|
||||||
android:windowSoftInputMode="stateVisible"
|
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
|
||||||
|
|
||||||
<activity android:name=".groups.ui.pendingmemberinvites.PendingMemberInvitesActivity"
|
<activity android:name=".groups.ui.pendingmemberinvites.PendingMemberInvitesActivity"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
||||||
android:theme="@style/Theme.Signal.DayNight.NoActionBar" />
|
android:theme="@style/Theme.Signal.DayNight.NoActionBar" />
|
||||||
@@ -414,10 +410,6 @@
|
|||||||
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:name=".RecipientPreferenceActivity"
|
|
||||||
android:theme="@style/Theme.Signal.DayNight.NoActionBar"
|
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
|
||||||
|
|
||||||
<activity android:name=".mediasend.AvatarSelectionActivity"
|
<activity android:name=".mediasend.AvatarSelectionActivity"
|
||||||
android:theme="@style/TextSecure.FullScreenMedia"
|
android:theme="@style/TextSecure.FullScreenMedia"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||||
|
@@ -271,7 +271,7 @@ public final class ContactSelectionListFragment extends Fragment
|
|||||||
|
|
||||||
RecyclerViewConcatenateAdapterStickyHeader concatenateAdapter = new RecyclerViewConcatenateAdapterStickyHeader();
|
RecyclerViewConcatenateAdapterStickyHeader concatenateAdapter = new RecyclerViewConcatenateAdapterStickyHeader();
|
||||||
|
|
||||||
if (listCallback != null && FeatureFlags.newGroupUI()) {
|
if (listCallback != null) {
|
||||||
if (FeatureFlags.groupsV2create() && FeatureFlags.groupsV2internalTest()) {
|
if (FeatureFlags.groupsV2create() && FeatureFlags.groupsV2internalTest()) {
|
||||||
headerAdapter = new FixedViewsAdapter(createNewGroupItem(listCallback), createNewGroupsV1GroupItem(listCallback));
|
headerAdapter = new FixedViewsAdapter(createNewGroupItem(listCallback), createNewGroupsV1GroupItem(listCallback));
|
||||||
} else {
|
} else {
|
||||||
@@ -518,7 +518,7 @@ public final class ContactSelectionListFragment extends Fragment
|
|||||||
|
|
||||||
private void markContactSelected(@NonNull SelectedContact selectedContact) {
|
private void markContactSelected(@NonNull SelectedContact selectedContact) {
|
||||||
cursorRecyclerViewAdapter.addSelectedContact(selectedContact);
|
cursorRecyclerViewAdapter.addSelectedContact(selectedContact);
|
||||||
if (isMulti() && FeatureFlags.newGroupUI()) {
|
if (isMulti()) {
|
||||||
addChipForSelectedContact(selectedContact);
|
addChipForSelectedContact(selectedContact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,629 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 Open Whisper Systems
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.thoughtcrime.securesms;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
|
||||||
import com.bumptech.glide.request.target.SimpleTarget;
|
|
||||||
import com.bumptech.glide.request.transition.Transition;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.components.PushRecipientsPanel;
|
|
||||||
import org.thoughtcrime.securesms.components.PushRecipientsPanel.RecipientsPanelChangedListener;
|
|
||||||
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode;
|
|
||||||
import org.thoughtcrime.securesms.contacts.RecipientsEditor;
|
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
|
|
||||||
import org.thoughtcrime.securesms.conversation.ConversationActivity;
|
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
|
||||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
|
||||||
import org.thoughtcrime.securesms.groups.GroupId;
|
|
||||||
import org.thoughtcrime.securesms.groups.GroupManager;
|
|
||||||
import org.thoughtcrime.securesms.groups.GroupManager.GroupActionResult;
|
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
|
||||||
import org.thoughtcrime.securesms.mediasend.AvatarSelectionActivity;
|
|
||||||
import org.thoughtcrime.securesms.mediasend.AvatarSelectionBottomSheetDialogFragment;
|
|
||||||
import org.thoughtcrime.securesms.mediasend.Media;
|
|
||||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
|
||||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
|
||||||
import org.thoughtcrime.securesms.profiles.edit.EditProfileActivity;
|
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
|
||||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
|
||||||
import org.thoughtcrime.securesms.util.SelectedRecipientsAdapter;
|
|
||||||
import org.thoughtcrime.securesms.util.SelectedRecipientsAdapter.OnRecipientDeletedListener;
|
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|
||||||
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
|
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Activity to create and update {@link GroupId.V1} groups
|
|
||||||
*
|
|
||||||
* @author Jake McGinty
|
|
||||||
*/
|
|
||||||
public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|
||||||
implements OnRecipientDeletedListener,
|
|
||||||
RecipientsPanelChangedListener
|
|
||||||
{
|
|
||||||
|
|
||||||
private final static String TAG = GroupCreateActivity.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final String GROUP_ID_EXTRA = "group_id";
|
|
||||||
private static final String GROUP_THREAD_EXTRA = "group_thread";
|
|
||||||
|
|
||||||
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
|
||||||
|
|
||||||
private static final short REQUEST_CODE_SELECT_AVATAR = 26165;
|
|
||||||
private static final int PICK_CONTACT = 1;
|
|
||||||
|
|
||||||
private EditText groupName;
|
|
||||||
private ListView listView;
|
|
||||||
private ImageView avatar;
|
|
||||||
private TextView creatingText;
|
|
||||||
private Bitmap avatarBmp;
|
|
||||||
|
|
||||||
@NonNull private Optional<GroupData> groupToUpdate = Optional.absent();
|
|
||||||
|
|
||||||
public static Intent newEditGroupIntent(@NonNull Context context, @NonNull GroupId.V1 groupId) {
|
|
||||||
Intent intent = new Intent(context, GroupCreateActivity.class);
|
|
||||||
intent.putExtra(GroupCreateActivity.GROUP_ID_EXTRA, groupId.toString());
|
|
||||||
return intent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPreCreate() {
|
|
||||||
dynamicTheme.onCreate(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle state, boolean ready) {
|
|
||||||
setContentView(R.layout.group_create_activity);
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
initializeAppBar();
|
|
||||||
initializeResources();
|
|
||||||
initializeExistingGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
dynamicTheme.onResume(this);
|
|
||||||
updateViewState();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isSignalGroup() {
|
|
||||||
return TextSecurePreferences.isPushRegistered(this) && !getAdapter().hasNonPushMembers();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disableSignalGroupViews(int reasonResId) {
|
|
||||||
View pushDisabled = findViewById(R.id.push_disabled);
|
|
||||||
pushDisabled.setVisibility(View.VISIBLE);
|
|
||||||
((TextView) findViewById(R.id.push_disabled_reason)).setText(reasonResId);
|
|
||||||
avatar.setEnabled(false);
|
|
||||||
groupName.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enableSignalGroupViews() {
|
|
||||||
findViewById(R.id.push_disabled).setVisibility(View.GONE);
|
|
||||||
avatar.setEnabled(true);
|
|
||||||
groupName.setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
|
||||||
private void updateViewState() {
|
|
||||||
if (!TextSecurePreferences.isPushRegistered(this)) {
|
|
||||||
disableSignalGroupViews(R.string.GroupCreateActivity_youre_not_registered_for_signal);
|
|
||||||
getSupportActionBar().setTitle(R.string.GroupCreateActivity_actionbar_mms_title);
|
|
||||||
} else if (getAdapter().hasNonPushMembers()) {
|
|
||||||
disableSignalGroupViews(R.string.GroupCreateActivity_contacts_dont_support_push);
|
|
||||||
getSupportActionBar().setTitle(R.string.GroupCreateActivity_actionbar_mms_title);
|
|
||||||
} else {
|
|
||||||
enableSignalGroupViews();
|
|
||||||
getSupportActionBar().setTitle(groupToUpdate.isPresent()
|
|
||||||
? R.string.GroupCreateActivity_actionbar_edit_title
|
|
||||||
: R.string.GroupCreateActivity_actionbar_title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isActiveInDirectory(Recipient recipient) {
|
|
||||||
return recipient.resolve().getRegistered() == RecipientDatabase.RegisteredState.REGISTERED;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addSelectedContacts(@NonNull Recipient... recipients) {
|
|
||||||
new AddMembersTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, recipients);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addSelectedContacts(@NonNull Collection<Recipient> recipients) {
|
|
||||||
addSelectedContacts(recipients.toArray(new Recipient[recipients.size()]));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeAppBar() {
|
|
||||||
Drawable upIcon = ContextCompat.getDrawable(this, R.drawable.ic_arrow_left_24);
|
|
||||||
getSupportActionBar().setHomeAsUpIndicator(upIcon);
|
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeResources() {
|
|
||||||
RecipientsEditor recipientsEditor = findViewById(R.id.recipients_text);
|
|
||||||
PushRecipientsPanel recipientsPanel = findViewById(R.id.recipients);
|
|
||||||
|
|
||||||
listView = findViewById(R.id.selected_contacts_list);
|
|
||||||
avatar = findViewById(R.id.avatar);
|
|
||||||
groupName = findViewById(R.id.group_name);
|
|
||||||
creatingText = findViewById(R.id.creating_group_text);
|
|
||||||
|
|
||||||
SelectedRecipientsAdapter adapter = new SelectedRecipientsAdapter(this);
|
|
||||||
adapter.setOnRecipientDeletedListener(this);
|
|
||||||
listView.setAdapter(adapter);
|
|
||||||
|
|
||||||
recipientsEditor.setHint(R.string.recipients_panel__add_members);
|
|
||||||
recipientsPanel.setPanelChangeListener(this);
|
|
||||||
|
|
||||||
findViewById(R.id.contacts_button).setOnClickListener(new AddRecipientButtonListener());
|
|
||||||
|
|
||||||
avatar.setImageDrawable(getDefaultGroupAvatar());
|
|
||||||
avatar.setOnClickListener(view -> AvatarSelectionBottomSheetDialogFragment.create(avatarBmp != null, false, REQUEST_CODE_SELECT_AVATAR, true).show(getSupportFragmentManager(), null));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Drawable getDefaultGroupAvatar() {
|
|
||||||
return new ResourceContactPhoto(R.drawable.ic_group_outline_34, R.drawable.ic_group_outline_20).asDrawable(this, ContactColors.UNKNOWN_COLOR.toConversationColor(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeExistingGroup() {
|
|
||||||
final GroupId groupId = GroupId.parseNullableOrThrow(getIntent().getStringExtra(GROUP_ID_EXTRA));
|
|
||||||
|
|
||||||
if (groupId != null) {
|
|
||||||
GroupId.V1 groupIdV1 = groupId.requireV1();
|
|
||||||
|
|
||||||
new FillExistingGroupInfoAsyncTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, groupIdV1);
|
|
||||||
|
|
||||||
if (FeatureFlags.newGroupUI()) {
|
|
||||||
avatar.setOnClickListener(v -> startActivity(EditProfileActivity.getIntentForGroupProfile(this, groupIdV1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
|
||||||
MenuInflater inflater = this.getMenuInflater();
|
|
||||||
menu.clear();
|
|
||||||
|
|
||||||
inflater.inflate(R.menu.group_create, menu);
|
|
||||||
super.onPrepareOptionsMenu(menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
super.onOptionsItemSelected(item);
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case android.R.id.home:
|
|
||||||
finish();
|
|
||||||
return true;
|
|
||||||
case R.id.menu_create_group:
|
|
||||||
if (groupToUpdate.isPresent()) handleGroupUpdate();
|
|
||||||
else handleGroupCreate();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRecipientDeleted(Recipient recipient) {
|
|
||||||
getAdapter().remove(recipient);
|
|
||||||
updateViewState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRecipientsPanelUpdate(List<Recipient> recipients) {
|
|
||||||
if (recipients != null && !recipients.isEmpty()) addSelectedContacts(recipients);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleGroupCreate() {
|
|
||||||
if (getAdapter().getCount() < 1) {
|
|
||||||
Log.i(TAG, getString(R.string.GroupCreateActivity_contacts_no_members));
|
|
||||||
Toast.makeText(getApplicationContext(), R.string.GroupCreateActivity_contacts_no_members, Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isSignalGroup()) {
|
|
||||||
new CreateSignalGroupTask(this, avatarBmp, getGroupName(), getAdapter().getRecipients()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
|
||||||
} else {
|
|
||||||
new CreateMmsGroupTask(this, getAdapter().getRecipients()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleGroupUpdate() {
|
|
||||||
new UpdateSignalGroupV1Task(this, groupToUpdate.get().id, avatarBmp,
|
|
||||||
getGroupName(), getAdapter().getRecipients()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleOpenConversation(long threadId, Recipient recipient) {
|
|
||||||
Intent intent = new Intent(this, ConversationActivity.class);
|
|
||||||
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
|
|
||||||
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
|
|
||||||
intent.putExtra(ConversationActivity.RECIPIENT_EXTRA, recipient.getId());
|
|
||||||
startActivity(intent);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
private SelectedRecipientsAdapter getAdapter() {
|
|
||||||
return (SelectedRecipientsAdapter) listView.getAdapter();
|
|
||||||
}
|
|
||||||
|
|
||||||
private @Nullable String getGroupName() {
|
|
||||||
return groupName.getText() != null ? groupName.getText().toString() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityResult(int reqCode, int resultCode, final Intent data) {
|
|
||||||
super.onActivityResult(reqCode, resultCode, data);
|
|
||||||
|
|
||||||
if (data == null || resultCode != Activity.RESULT_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (reqCode) {
|
|
||||||
case PICK_CONTACT:
|
|
||||||
List<RecipientId> selected = data.getParcelableArrayListExtra(PushContactSelectionActivity.KEY_SELECTED_RECIPIENTS);
|
|
||||||
|
|
||||||
for (RecipientId contact : selected) {
|
|
||||||
Recipient recipient = Recipient.resolved(contact);
|
|
||||||
addSelectedContacts(recipient);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case REQUEST_CODE_SELECT_AVATAR:
|
|
||||||
if (data.getBooleanExtra("delete", false)) {
|
|
||||||
avatarBmp = null;
|
|
||||||
avatar.setImageDrawable(getDefaultGroupAvatar());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Media result = data.getParcelableExtra(AvatarSelectionActivity.EXTRA_MEDIA);
|
|
||||||
final DecryptableUri decryptableUri = new DecryptableUri(result.getUri());
|
|
||||||
|
|
||||||
GlideApp.with(this)
|
|
||||||
.asBitmap()
|
|
||||||
.load(decryptableUri)
|
|
||||||
.skipMemoryCache(true)
|
|
||||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
|
||||||
.centerCrop()
|
|
||||||
.override(AvatarHelper.AVATAR_DIMENSIONS, AvatarHelper.AVATAR_DIMENSIONS)
|
|
||||||
.into(new SimpleTarget<Bitmap>() {
|
|
||||||
@Override
|
|
||||||
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
|
||||||
setAvatar(decryptableUri, resource);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AddRecipientButtonListener implements View.OnClickListener {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Intent intent = new Intent(GroupCreateActivity.this, PushContactSelectionActivity.class);
|
|
||||||
if (groupToUpdate.isPresent()) {
|
|
||||||
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, DisplayMode.FLAG_PUSH);
|
|
||||||
} else {
|
|
||||||
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, DisplayMode.FLAG_PUSH | DisplayMode.FLAG_SMS);
|
|
||||||
}
|
|
||||||
startActivityForResult(intent, PICK_CONTACT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class CreateMmsGroupTask extends AsyncTask<Void,Void,GroupActionResult> {
|
|
||||||
private final GroupCreateActivity activity;
|
|
||||||
private final Set<Recipient> members;
|
|
||||||
|
|
||||||
public CreateMmsGroupTask(GroupCreateActivity activity, Set<Recipient> members) {
|
|
||||||
this.activity = activity;
|
|
||||||
this.members = members;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected GroupActionResult doInBackground(Void... avoid) {
|
|
||||||
List<RecipientId> memberAddresses = new LinkedList<>();
|
|
||||||
|
|
||||||
for (Recipient recipient : members) {
|
|
||||||
memberAddresses.add(recipient.getId());
|
|
||||||
}
|
|
||||||
memberAddresses.add(Recipient.self().getId());
|
|
||||||
|
|
||||||
GroupId.Mms groupId = DatabaseFactory.getGroupDatabase(activity).getOrCreateMmsGroupForMembers(memberAddresses);
|
|
||||||
RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(activity).getOrInsertFromGroupId(groupId);
|
|
||||||
Recipient groupRecipient = Recipient.resolved(groupRecipientId);
|
|
||||||
long threadId = DatabaseFactory.getThreadDatabase(activity).getThreadIdFor(groupRecipient, ThreadDatabase.DistributionTypes.DEFAULT);
|
|
||||||
|
|
||||||
return new GroupActionResult(groupRecipient, threadId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(GroupActionResult result) {
|
|
||||||
activity.handleOpenConversation(result.getThreadId(), result.getGroupRecipient());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onProgressUpdate(Void... values) {
|
|
||||||
super.onProgressUpdate(values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private abstract static class SignalGroupTask extends AsyncTask<Void,Void,Optional<GroupActionResult>> {
|
|
||||||
|
|
||||||
protected GroupCreateActivity activity;
|
|
||||||
protected Bitmap avatar;
|
|
||||||
protected Set<Recipient> members;
|
|
||||||
protected String name;
|
|
||||||
|
|
||||||
public SignalGroupTask(GroupCreateActivity activity,
|
|
||||||
Bitmap avatar,
|
|
||||||
String name,
|
|
||||||
Set<Recipient> members)
|
|
||||||
{
|
|
||||||
this.activity = activity;
|
|
||||||
this.avatar = avatar;
|
|
||||||
this.name = name;
|
|
||||||
this.members = members;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPreExecute() {
|
|
||||||
activity.findViewById(R.id.group_details_layout).setVisibility(View.GONE);
|
|
||||||
activity.findViewById(R.id.creating_group_layout).setVisibility(View.VISIBLE);
|
|
||||||
activity.findViewById(R.id.menu_create_group).setVisibility(View.GONE);
|
|
||||||
final int titleResId = activity.groupToUpdate.isPresent()
|
|
||||||
? R.string.GroupCreateActivity_updating_group
|
|
||||||
: R.string.GroupCreateActivity_creating_group;
|
|
||||||
activity.creatingText.setText(activity.getString(titleResId, activity.getGroupName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Optional<GroupActionResult> groupActionResultOptional) {
|
|
||||||
if (activity.isFinishing()) return;
|
|
||||||
activity.findViewById(R.id.group_details_layout).setVisibility(View.VISIBLE);
|
|
||||||
activity.findViewById(R.id.creating_group_layout).setVisibility(View.GONE);
|
|
||||||
activity.findViewById(R.id.menu_create_group).setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class CreateSignalGroupTask extends SignalGroupTask {
|
|
||||||
public CreateSignalGroupTask(GroupCreateActivity activity, Bitmap avatar, String name, Set<Recipient> members) {
|
|
||||||
super(activity, avatar, name, members);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Optional<GroupActionResult> doInBackground(Void... aVoid) {
|
|
||||||
return Optional.of(GroupManager.createGroupV1(activity, members, BitmapUtil.toByteArray(avatar), name, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Optional<GroupActionResult> result) {
|
|
||||||
if (result.isPresent() && result.get().getThreadId() > -1) {
|
|
||||||
if (!activity.isFinishing()) {
|
|
||||||
activity.handleOpenConversation(result.get().getThreadId(), result.get().getGroupRecipient());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
super.onPostExecute(result);
|
|
||||||
Toast.makeText(activity.getApplicationContext(),
|
|
||||||
R.string.GroupCreateActivity_contacts_invalid_number, Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class UpdateSignalGroupV1Task extends SignalGroupTask {
|
|
||||||
private final GroupId.V1 groupId;
|
|
||||||
|
|
||||||
UpdateSignalGroupV1Task(GroupCreateActivity activity, GroupId.V1 groupId,
|
|
||||||
Bitmap avatar, String name, Set<Recipient> members)
|
|
||||||
{
|
|
||||||
super(activity, avatar, name, members);
|
|
||||||
this.groupId = groupId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Optional<GroupActionResult> doInBackground(Void... aVoid) {
|
|
||||||
return Optional.fromNullable(GroupManager.updateGroup(activity, groupId, members, BitmapUtil.toByteArray(avatar), name));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Optional<GroupActionResult> result) {
|
|
||||||
if (result.isPresent() && result.get().getThreadId() > -1) {
|
|
||||||
if (!activity.isFinishing()) {
|
|
||||||
Intent intent = activity.getIntent();
|
|
||||||
intent.putExtra(GROUP_THREAD_EXTRA, result.get().getThreadId());
|
|
||||||
intent.putExtra(GROUP_ID_EXTRA, result.get().getGroupRecipient().requireGroupId().toString());
|
|
||||||
activity.setResult(RESULT_OK, intent);
|
|
||||||
activity.finish();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
super.onPostExecute(result);
|
|
||||||
Toast.makeText(activity.getApplicationContext(),
|
|
||||||
R.string.GroupCreateActivity_contacts_invalid_number, Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class AddMembersTask extends AsyncTask<Recipient,Void,List<AddMembersTask.Result>> {
|
|
||||||
static class Result {
|
|
||||||
Optional<Recipient> recipient;
|
|
||||||
boolean isPush;
|
|
||||||
String reason;
|
|
||||||
|
|
||||||
public Result(@Nullable Recipient recipient, boolean isPush, @Nullable String reason) {
|
|
||||||
this.recipient = Optional.fromNullable(recipient);
|
|
||||||
this.isPush = isPush;
|
|
||||||
this.reason = reason;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private GroupCreateActivity activity;
|
|
||||||
private boolean failIfNotPush;
|
|
||||||
|
|
||||||
public AddMembersTask(@NonNull GroupCreateActivity activity) {
|
|
||||||
this.activity = activity;
|
|
||||||
this.failIfNotPush = activity.groupToUpdate.isPresent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<Result> doInBackground(Recipient... recipients) {
|
|
||||||
final List<Result> results = new LinkedList<>();
|
|
||||||
|
|
||||||
for (Recipient recipient : recipients) {
|
|
||||||
boolean isPush = isActiveInDirectory(recipient);
|
|
||||||
|
|
||||||
if (failIfNotPush && !isPush) {
|
|
||||||
results.add(new Result(null, false, activity.getString(R.string.GroupCreateActivity_cannot_add_non_push_to_existing_group,
|
|
||||||
recipient.getDisplayName(activity))));
|
|
||||||
} else if (TextUtils.equals(TextSecurePreferences.getLocalNumber(activity), recipient.getE164().or(""))) {
|
|
||||||
results.add(new Result(null, false, activity.getString(R.string.GroupCreateActivity_youre_already_in_the_group)));
|
|
||||||
} else {
|
|
||||||
results.add(new Result(recipient, isPush, null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(List<Result> results) {
|
|
||||||
if (activity.isFinishing()) return;
|
|
||||||
|
|
||||||
for (Result result : results) {
|
|
||||||
if (result.recipient.isPresent()) {
|
|
||||||
activity.getAdapter().add(result.recipient.get(), result.isPush);
|
|
||||||
} else {
|
|
||||||
Toast.makeText(activity, result.reason, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
activity.updateViewState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class FillExistingGroupInfoAsyncTask extends ProgressDialogAsyncTask<GroupId.V1, Void, Optional<GroupData>> {
|
|
||||||
private GroupCreateActivity activity;
|
|
||||||
|
|
||||||
public FillExistingGroupInfoAsyncTask(GroupCreateActivity activity) {
|
|
||||||
super(activity,
|
|
||||||
R.string.GroupCreateActivity_loading_group_details,
|
|
||||||
R.string.please_wait);
|
|
||||||
this.activity = activity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Optional<GroupData> doInBackground(GroupId.V1... groupIds) {
|
|
||||||
final GroupDatabase db = DatabaseFactory.getGroupDatabase(activity);
|
|
||||||
final List<Recipient> recipients = db.getGroupMembers(groupIds[0], GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF);
|
|
||||||
final Optional<GroupRecord> group = db.getGroup(groupIds[0]);
|
|
||||||
final Set<Recipient> existingContacts = new HashSet<>(recipients.size());
|
|
||||||
existingContacts.addAll(recipients);
|
|
||||||
|
|
||||||
if (group.isPresent()) {
|
|
||||||
Bitmap avatar = null;
|
|
||||||
try {
|
|
||||||
avatar = BitmapFactory.decodeStream(AvatarHelper.getAvatar(getContext(), group.get().getRecipientId()));
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.w(TAG, "Failed to read avatar.");
|
|
||||||
}
|
|
||||||
return Optional.of(new GroupData(groupIds[0],
|
|
||||||
existingContacts,
|
|
||||||
avatar,
|
|
||||||
BitmapUtil.toByteArray(avatar),
|
|
||||||
group.get().getTitle()));
|
|
||||||
} else {
|
|
||||||
return Optional.absent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Optional<GroupData> group) {
|
|
||||||
super.onPostExecute(group);
|
|
||||||
|
|
||||||
if (group.isPresent() && !activity.isFinishing()) {
|
|
||||||
activity.groupToUpdate = group;
|
|
||||||
|
|
||||||
activity.groupName.setText(group.get().name);
|
|
||||||
if (group.get().avatarBmp != null) {
|
|
||||||
activity.setAvatar(group.get().avatarBytes, group.get().avatarBmp);
|
|
||||||
}
|
|
||||||
SelectedRecipientsAdapter adapter = new SelectedRecipientsAdapter(activity, group.get().recipients);
|
|
||||||
adapter.setOnRecipientDeletedListener(activity);
|
|
||||||
activity.listView.setAdapter(adapter);
|
|
||||||
activity.updateViewState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> void setAvatar(T model, Bitmap bitmap) {
|
|
||||||
avatarBmp = bitmap;
|
|
||||||
GlideApp.with(this)
|
|
||||||
.load(model)
|
|
||||||
.circleCrop()
|
|
||||||
.skipMemoryCache(true)
|
|
||||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
|
||||||
.into(avatar);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class GroupData {
|
|
||||||
GroupId.V1 id;
|
|
||||||
Set<Recipient> recipients;
|
|
||||||
Bitmap avatarBmp;
|
|
||||||
byte[] avatarBytes;
|
|
||||||
String name;
|
|
||||||
|
|
||||||
GroupData(GroupId.V1 id, Set<Recipient> recipients, Bitmap avatarBmp, byte[] avatarBytes, String name) {
|
|
||||||
this.id = id;
|
|
||||||
this.recipients = recipients;
|
|
||||||
this.avatarBmp = avatarBmp;
|
|
||||||
this.avatarBytes = avatarBytes;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,774 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.media.Ringtone;
|
|
||||||
import android.media.RingtoneManager;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.telephony.PhoneNumberUtils;
|
|
||||||
import android.util.Pair;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
import androidx.core.view.ViewCompat;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.loader.app.LoaderManager;
|
|
||||||
import androidx.loader.content.Loader;
|
|
||||||
import androidx.preference.CheckBoxPreference;
|
|
||||||
import androidx.preference.ListPreference;
|
|
||||||
import androidx.preference.Preference;
|
|
||||||
import androidx.preference.PreferenceCategory;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
|
||||||
import org.thoughtcrime.securesms.color.MaterialColors;
|
|
||||||
import org.thoughtcrime.securesms.components.SwitchPreferenceCompat;
|
|
||||||
import org.thoughtcrime.securesms.components.ThreadPhotoRailView;
|
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
|
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto;
|
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
|
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
|
||||||
import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord;
|
|
||||||
import org.thoughtcrime.securesms.database.MediaDatabase;
|
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
|
||||||
import org.thoughtcrime.securesms.database.loaders.RecipientMediaLoader;
|
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|
||||||
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
|
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
|
||||||
import org.thoughtcrime.securesms.mediaoverview.MediaOverviewActivity;
|
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
|
||||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
|
||||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
|
||||||
import org.thoughtcrime.securesms.preferences.CorrectedPreferenceFragment;
|
|
||||||
import org.thoughtcrime.securesms.preferences.widgets.ColorPickerPreference;
|
|
||||||
import org.thoughtcrime.securesms.preferences.widgets.ContactPreference;
|
|
||||||
import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
|
||||||
import org.thoughtcrime.securesms.recipients.ui.managerecipient.ManageRecipientActivity;
|
|
||||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
|
||||||
import org.thoughtcrime.securesms.util.DynamicDarkToolbarTheme;
|
|
||||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
|
||||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|
||||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
|
||||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
|
||||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
|
||||||
public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActivity implements LoaderManager.LoaderCallbacks<Cursor>
|
|
||||||
{
|
|
||||||
private static final String TAG = RecipientPreferenceActivity.class.getSimpleName();
|
|
||||||
|
|
||||||
public static final String RECIPIENT_ID = "recipient";
|
|
||||||
|
|
||||||
private static final String PREFERENCE_MUTED = "pref_key_recipient_mute";
|
|
||||||
private static final String PREFERENCE_MESSAGE_TONE = "pref_key_recipient_ringtone";
|
|
||||||
private static final String PREFERENCE_CALL_TONE = "pref_key_recipient_call_ringtone";
|
|
||||||
private static final String PREFERENCE_MESSAGE_VIBRATE = "pref_key_recipient_vibrate";
|
|
||||||
private static final String PREFERENCE_CALL_VIBRATE = "pref_key_recipient_call_vibrate";
|
|
||||||
private static final String PREFERENCE_BLOCK = "pref_key_recipient_block";
|
|
||||||
private static final String PREFERENCE_COLOR = "pref_key_recipient_color";
|
|
||||||
private static final String PREFERENCE_IDENTITY = "pref_key_recipient_identity";
|
|
||||||
private static final String PREFERENCE_ABOUT = "pref_key_number";
|
|
||||||
private static final String PREFERENCE_CUSTOM_NOTIFICATIONS = "pref_key_recipient_custom_notifications";
|
|
||||||
|
|
||||||
private final DynamicTheme dynamicTheme = new DynamicDarkToolbarTheme();
|
|
||||||
|
|
||||||
private ImageView avatar;
|
|
||||||
private GlideRequests glideRequests;
|
|
||||||
private RecipientId recipientId;
|
|
||||||
private TextView threadPhotoRailLabel;
|
|
||||||
private ThreadPhotoRailView threadPhotoRailView;
|
|
||||||
private CollapsingToolbarLayout toolbarLayout;
|
|
||||||
|
|
||||||
public static @NonNull Intent getLaunchIntent(@NonNull Context context, @NonNull RecipientId id) {
|
|
||||||
if (FeatureFlags.newGroupUI()) {
|
|
||||||
return ManageRecipientActivity.newIntent(context, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getOldLaunchIntent(context, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static Intent getOldLaunchIntent(@NonNull Context context, @NonNull RecipientId id) {
|
|
||||||
Intent intent = new Intent(context, RecipientPreferenceActivity.class);
|
|
||||||
intent.putExtra(RecipientPreferenceActivity.RECIPIENT_ID, id);
|
|
||||||
|
|
||||||
return intent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPreCreate() {
|
|
||||||
dynamicTheme.onCreate(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle instanceState, boolean ready) {
|
|
||||||
setContentView(R.layout.recipient_preference_activity);
|
|
||||||
this.glideRequests = GlideApp.with(this);
|
|
||||||
this.recipientId = getIntent().getParcelableExtra(RECIPIENT_ID);
|
|
||||||
|
|
||||||
LiveRecipient recipient = Recipient.live(recipientId);
|
|
||||||
|
|
||||||
initializeToolbar();
|
|
||||||
setHeader(recipient.get());
|
|
||||||
recipient.observe(this, this::setHeader);
|
|
||||||
|
|
||||||
LoaderManager.getInstance(this).initLoader(0, null, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
dynamicTheme.onResume(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.preference_fragment);
|
|
||||||
fragment.onActivityResult(requestCode, resultCode, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
super.onOptionsItemSelected(item);
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case android.R.id.home:
|
|
||||||
onBackPressed();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeToolbar() {
|
|
||||||
this.toolbarLayout = findViewById(R.id.collapsing_toolbar);
|
|
||||||
this.avatar = findViewById(R.id.avatar);
|
|
||||||
this.threadPhotoRailView = findViewById(R.id.recent_photos);
|
|
||||||
this.threadPhotoRailLabel = findViewById(R.id.rail_label);
|
|
||||||
|
|
||||||
this.toolbarLayout.setExpandedTitleColor(ThemeUtil.getThemedColor(this, R.attr.conversation_title_color));
|
|
||||||
this.toolbarLayout.setCollapsedTitleTextColor(ThemeUtil.getThemedColor(this, R.attr.conversation_title_color));
|
|
||||||
|
|
||||||
this.threadPhotoRailView.setListener(mediaRecord ->
|
|
||||||
startActivity(MediaPreviewActivity.intentFromMediaRecord(RecipientPreferenceActivity.this,
|
|
||||||
mediaRecord,
|
|
||||||
ViewCompat.getLayoutDirection(threadPhotoRailView) == ViewCompat.LAYOUT_DIRECTION_LTR)));
|
|
||||||
|
|
||||||
SimpleTask.run(
|
|
||||||
() -> DatabaseFactory.getThreadDatabase(this).getThreadIdFor(recipientId),
|
|
||||||
(threadId) -> {
|
|
||||||
if (threadId == null) {
|
|
||||||
Log.i(TAG, "No thread id for recipient.");
|
|
||||||
} else {
|
|
||||||
this.threadPhotoRailLabel.setOnClickListener(v -> startActivity(MediaOverviewActivity.forThread(this, threadId)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
|
||||||
setSupportActionBar(toolbar);
|
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
||||||
getSupportActionBar().setLogo(null);
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
|
||||||
getWindow().setStatusBarColor(Color.TRANSPARENT);
|
|
||||||
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.recipient_preference_root), (v, insets) -> {
|
|
||||||
ViewUtil.setTopMargin(toolbar, insets.getSystemWindowInsetTop());
|
|
||||||
return insets;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setHeader(@NonNull Recipient recipient) {
|
|
||||||
ContactPhoto contactPhoto = recipient.isLocalNumber() ? new ProfileContactPhoto(recipient, recipient.getProfileAvatar())
|
|
||||||
: recipient.getContactPhoto();
|
|
||||||
FallbackContactPhoto fallbackPhoto = recipient.isLocalNumber() ? new ResourceContactPhoto(R.drawable.ic_profile_outline_40, R.drawable.ic_profile_outline_20, R.drawable.ic_person_large)
|
|
||||||
: recipient.getFallbackContactPhoto();
|
|
||||||
|
|
||||||
glideRequests.load(contactPhoto)
|
|
||||||
.fallback(fallbackPhoto.asCallCard(this))
|
|
||||||
.error(fallbackPhoto.asCallCard(this))
|
|
||||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
|
||||||
.addListener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
avatar.setOnClickListener(null);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
|
|
||||||
avatar.setOnClickListener(v -> startActivity(AvatarPreviewActivity.intentFromRecipientId(RecipientPreferenceActivity.this, recipient.getId()),
|
|
||||||
AvatarPreviewActivity.createTransitionBundle(RecipientPreferenceActivity.this, avatar)));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(this.avatar);
|
|
||||||
|
|
||||||
if (contactPhoto == null) this.avatar.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
|
||||||
else this.avatar.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
|
||||||
|
|
||||||
this.avatar.setBackgroundColor(recipient.getColor().toActionBarColor(this));
|
|
||||||
this.toolbarLayout.setTitle(recipient.getDisplayName(this));
|
|
||||||
this.toolbarLayout.setContentScrimColor(recipient.getColor().toActionBarColor(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NonNull Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
|
||||||
return new RecipientMediaLoader(this, recipientId, RecipientMediaLoader.MediaType.GALLERY, MediaDatabase.Sorting.Newest);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
|
|
||||||
if (data != null && data.getCount() > 0) {
|
|
||||||
this.threadPhotoRailLabel.setVisibility(View.VISIBLE);
|
|
||||||
this.threadPhotoRailView.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
this.threadPhotoRailLabel.setVisibility(View.GONE);
|
|
||||||
this.threadPhotoRailView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.threadPhotoRailView.setCursor(glideRequests, data);
|
|
||||||
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putParcelable(RECIPIENT_ID, recipientId);
|
|
||||||
initFragment(R.id.preference_fragment, new RecipientPreferenceFragment(), null, bundle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoaderReset(@NonNull Loader<Cursor> loader) {
|
|
||||||
this.threadPhotoRailView.setCursor(glideRequests, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class RecipientPreferenceFragment extends CorrectedPreferenceFragment {
|
|
||||||
private LiveRecipient recipient;
|
|
||||||
private boolean canHaveSafetyNumber;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle icicle) {
|
|
||||||
Log.i(TAG, "onCreate (fragment)");
|
|
||||||
super.onCreate(icicle);
|
|
||||||
|
|
||||||
initializeRecipients();
|
|
||||||
|
|
||||||
this.canHaveSafetyNumber = recipient.get().isRegistered() && !recipient.get().isLocalNumber();
|
|
||||||
|
|
||||||
Preference customNotificationsPref = this.findPreference(PREFERENCE_CUSTOM_NOTIFICATIONS);
|
|
||||||
|
|
||||||
if (NotificationChannels.supported()) {
|
|
||||||
((SwitchPreferenceCompat) customNotificationsPref).setChecked(recipient.get().getNotificationChannel() != null);
|
|
||||||
customNotificationsPref.setOnPreferenceChangeListener(new CustomNotificationsChangedListener());
|
|
||||||
|
|
||||||
this.findPreference(PREFERENCE_MESSAGE_TONE).setDependency(PREFERENCE_CUSTOM_NOTIFICATIONS);
|
|
||||||
this.findPreference(PREFERENCE_MESSAGE_VIBRATE).setDependency(PREFERENCE_CUSTOM_NOTIFICATIONS);
|
|
||||||
|
|
||||||
if (recipient.get().getNotificationChannel() != null) {
|
|
||||||
final Context context = requireContext();
|
|
||||||
new AsyncTask<Void, Void, Void>() {
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Void... voids) {
|
|
||||||
RecipientDatabase db = DatabaseFactory.getRecipientDatabase(getContext());
|
|
||||||
db.setMessageRingtone(recipient.getId(), NotificationChannels.getMessageRingtone(context, recipient.get()));
|
|
||||||
db.setMessageVibrate(recipient.getId(), NotificationChannels.getMessageVibrate(context, recipient.get()) ? VibrateState.ENABLED : VibrateState.DISABLED);
|
|
||||||
NotificationChannels.ensureCustomChannelConsistency(context);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
customNotificationsPref.setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.findPreference(PREFERENCE_MESSAGE_TONE)
|
|
||||||
.setOnPreferenceChangeListener(new RingtoneChangeListener(false));
|
|
||||||
this.findPreference(PREFERENCE_MESSAGE_TONE)
|
|
||||||
.setOnPreferenceClickListener(new RingtoneClickedListener(false));
|
|
||||||
this.findPreference(PREFERENCE_CALL_TONE)
|
|
||||||
.setOnPreferenceChangeListener(new RingtoneChangeListener(true));
|
|
||||||
this.findPreference(PREFERENCE_CALL_TONE)
|
|
||||||
.setOnPreferenceClickListener(new RingtoneClickedListener(true));
|
|
||||||
this.findPreference(PREFERENCE_MESSAGE_VIBRATE)
|
|
||||||
.setOnPreferenceChangeListener(new VibrateChangeListener(false));
|
|
||||||
this.findPreference(PREFERENCE_CALL_VIBRATE)
|
|
||||||
.setOnPreferenceChangeListener(new VibrateChangeListener(true));
|
|
||||||
this.findPreference(PREFERENCE_MUTED)
|
|
||||||
.setOnPreferenceClickListener(new MuteClickedListener());
|
|
||||||
this.findPreference(PREFERENCE_BLOCK)
|
|
||||||
.setOnPreferenceClickListener(new BlockClickedListener());
|
|
||||||
this.findPreference(PREFERENCE_COLOR)
|
|
||||||
.setOnPreferenceChangeListener(new ColorChangeListener());
|
|
||||||
((ContactPreference)this.findPreference(PREFERENCE_ABOUT))
|
|
||||||
.setListener(new AboutNumberClickedListener());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) {
|
|
||||||
Log.i(TAG, "onCreatePreferences...");
|
|
||||||
addPreferencesFromResource(R.xml.recipient_preferences);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
|
|
||||||
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
setSummaries(recipient.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
if (requestCode == 1 && resultCode == RESULT_OK && data != null) {
|
|
||||||
Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
|
|
||||||
|
|
||||||
findPreference(PREFERENCE_MESSAGE_TONE).getOnPreferenceChangeListener().onPreferenceChange(findPreference(PREFERENCE_MESSAGE_TONE), uri);
|
|
||||||
} else if (requestCode == 2 && resultCode == RESULT_OK && data != null) {
|
|
||||||
Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
|
|
||||||
|
|
||||||
findPreference(PREFERENCE_CALL_TONE).getOnPreferenceChangeListener().onPreferenceChange(findPreference(PREFERENCE_CALL_TONE), uri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
|
|
||||||
RecyclerView recyclerView = super.onCreateRecyclerView(inflater, parent, savedInstanceState);
|
|
||||||
recyclerView.setItemAnimator(null);
|
|
||||||
recyclerView.setLayoutAnimation(null);
|
|
||||||
return recyclerView;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeRecipients() {
|
|
||||||
this.recipient = Recipient.live(getArguments().getParcelable(RECIPIENT_ID));
|
|
||||||
this.recipient.observe(this, this::setSummaries);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setSummaries(Recipient recipient) {
|
|
||||||
CheckBoxPreference mutePreference = (CheckBoxPreference) this.findPreference(PREFERENCE_MUTED);
|
|
||||||
Preference customPreference = this.findPreference(PREFERENCE_CUSTOM_NOTIFICATIONS);
|
|
||||||
Preference ringtoneMessagePreference = this.findPreference(PREFERENCE_MESSAGE_TONE);
|
|
||||||
Preference ringtoneCallPreference = this.findPreference(PREFERENCE_CALL_TONE);
|
|
||||||
ListPreference vibrateMessagePreference = (ListPreference) this.findPreference(PREFERENCE_MESSAGE_VIBRATE);
|
|
||||||
ListPreference vibrateCallPreference = (ListPreference) this.findPreference(PREFERENCE_CALL_VIBRATE);
|
|
||||||
ColorPickerPreference colorPreference = (ColorPickerPreference) this.findPreference(PREFERENCE_COLOR);
|
|
||||||
Preference blockPreference = this.findPreference(PREFERENCE_BLOCK);
|
|
||||||
Preference identityPreference = this.findPreference(PREFERENCE_IDENTITY);
|
|
||||||
PreferenceCategory callCategory = (PreferenceCategory)this.findPreference("call_settings");
|
|
||||||
PreferenceCategory aboutCategory = (PreferenceCategory)this.findPreference("about");
|
|
||||||
PreferenceCategory aboutDivider = (PreferenceCategory)this.findPreference("about_divider");
|
|
||||||
ContactPreference aboutPreference = (ContactPreference)this.findPreference(PREFERENCE_ABOUT);
|
|
||||||
PreferenceCategory privacyCategory = (PreferenceCategory) this.findPreference("privacy_settings");
|
|
||||||
PreferenceCategory divider = (PreferenceCategory) this.findPreference("divider");
|
|
||||||
|
|
||||||
mutePreference.setChecked(recipient.isMuted());
|
|
||||||
|
|
||||||
ringtoneMessagePreference.setSummary(ringtoneMessagePreference.isEnabled() ? getRingtoneSummary(getContext(), recipient.getMessageRingtone()) : "");
|
|
||||||
ringtoneCallPreference.setSummary(getRingtoneSummary(getContext(), recipient.getCallRingtone()));
|
|
||||||
|
|
||||||
Pair<String, Integer> vibrateMessageSummary = getVibrateSummary(getContext(), recipient.getMessageVibrate());
|
|
||||||
Pair<String, Integer> vibrateCallSummary = getVibrateSummary(getContext(), recipient.getCallVibrate());
|
|
||||||
|
|
||||||
vibrateMessagePreference.setSummary(vibrateMessagePreference.isEnabled() ? vibrateMessageSummary.first : "");
|
|
||||||
vibrateMessagePreference.setValueIndex(vibrateMessageSummary.second);
|
|
||||||
|
|
||||||
vibrateCallPreference.setSummary(vibrateCallSummary.first);
|
|
||||||
vibrateCallPreference.setValueIndex(vibrateCallSummary.second);
|
|
||||||
|
|
||||||
blockPreference.setVisible(RecipientUtil.isBlockable(recipient));
|
|
||||||
if (recipient.isBlocked()) blockPreference.setTitle(R.string.RecipientPreferenceActivity_unblock);
|
|
||||||
else blockPreference.setTitle(R.string.RecipientPreferenceActivity_block);
|
|
||||||
|
|
||||||
if (recipient.isLocalNumber()) {
|
|
||||||
mutePreference.setVisible(false);
|
|
||||||
customPreference.setVisible(false);
|
|
||||||
ringtoneMessagePreference.setVisible(false);
|
|
||||||
vibrateMessagePreference.setVisible(false);
|
|
||||||
|
|
||||||
if (identityPreference != null) identityPreference.setVisible(false);
|
|
||||||
if (aboutCategory != null) aboutCategory.setVisible(false);
|
|
||||||
if (aboutDivider != null) aboutDivider.setVisible(false);
|
|
||||||
if (privacyCategory != null) privacyCategory.setVisible(false);
|
|
||||||
if (divider != null) divider.setVisible(false);
|
|
||||||
if (callCategory != null) callCategory.setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recipient.isGroup()) {
|
|
||||||
if (colorPreference != null) colorPreference.setVisible(false);
|
|
||||||
if (identityPreference != null) identityPreference.setVisible(false);
|
|
||||||
if (callCategory != null) callCategory.setVisible(false);
|
|
||||||
if (aboutCategory != null) aboutCategory.setVisible(false);
|
|
||||||
if (aboutDivider != null) aboutDivider.setVisible(false);
|
|
||||||
if (divider != null) divider.setVisible(false);
|
|
||||||
} else {
|
|
||||||
colorPreference.setColors(MaterialColors.CONVERSATION_PALETTE.asConversationColorArray(requireActivity()));
|
|
||||||
colorPreference.setColor(recipient.getColor().toActionBarColor(requireActivity()));
|
|
||||||
|
|
||||||
aboutPreference.setTitle(recipient.getDisplayName(requireContext()));
|
|
||||||
aboutPreference.setSummary(recipient.resolve().getE164().or(""));
|
|
||||||
aboutPreference.setState(recipient.getRegistered() == RecipientDatabase.RegisteredState.REGISTERED, recipient.isBlocked());
|
|
||||||
|
|
||||||
IdentityUtil.getRemoteIdentityKey(getActivity(), recipient).addListener(new ListenableFuture.Listener<Optional<IdentityRecord>>() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(Optional<IdentityRecord> result) {
|
|
||||||
if (result.isPresent()) {
|
|
||||||
if (identityPreference != null) identityPreference.setOnPreferenceClickListener(new IdentityClickedListener(result.get()));
|
|
||||||
if (identityPreference != null) identityPreference.setEnabled(true);
|
|
||||||
} else if (canHaveSafetyNumber) {
|
|
||||||
if (identityPreference != null) identityPreference.setSummary(R.string.RecipientPreferenceActivity_available_once_a_message_has_been_sent_or_received);
|
|
||||||
if (identityPreference != null) identityPreference.setEnabled(false);
|
|
||||||
} else {
|
|
||||||
if (identityPreference != null) getPreferenceScreen().removePreference(identityPreference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(ExecutionException e) {
|
|
||||||
if (identityPreference != null) getPreferenceScreen().removePreference(identityPreference);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recipient.isMmsGroup() && privacyCategory != null) {
|
|
||||||
privacyCategory.setVisible(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private @NonNull String formatRecipient(@NonNull Recipient recipient) {
|
|
||||||
if (recipient.getE164().isPresent()) return PhoneNumberUtils.formatNumber(recipient.requireE164());
|
|
||||||
else if (recipient.getEmail().isPresent()) return recipient.requireEmail();
|
|
||||||
else return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private @NonNull String getRingtoneSummary(@NonNull Context context, @Nullable Uri ringtone) {
|
|
||||||
if (ringtone == null) {
|
|
||||||
return context.getString(R.string.preferences__default);
|
|
||||||
} else if (ringtone.toString().isEmpty()) {
|
|
||||||
return context.getString(R.string.preferences__silent);
|
|
||||||
} else {
|
|
||||||
Ringtone tone = RingtoneManager.getRingtone(getActivity(), ringtone);
|
|
||||||
|
|
||||||
if (tone != null) {
|
|
||||||
return tone.getTitle(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return context.getString(R.string.preferences__default);
|
|
||||||
}
|
|
||||||
|
|
||||||
private @NonNull Pair<String, Integer> getVibrateSummary(@NonNull Context context, @NonNull VibrateState vibrateState) {
|
|
||||||
if (vibrateState == VibrateState.DEFAULT) {
|
|
||||||
return new Pair<>(context.getString(R.string.preferences__default), 0);
|
|
||||||
} else if (vibrateState == VibrateState.ENABLED) {
|
|
||||||
return new Pair<>(context.getString(R.string.RecipientPreferenceActivity_enabled), 1);
|
|
||||||
} else {
|
|
||||||
return new Pair<>(context.getString(R.string.RecipientPreferenceActivity_disabled), 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RingtoneChangeListener implements Preference.OnPreferenceChangeListener {
|
|
||||||
|
|
||||||
private final boolean calls;
|
|
||||||
|
|
||||||
RingtoneChangeListener(boolean calls) {
|
|
||||||
this.calls = calls;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
||||||
final Context context = preference.getContext();
|
|
||||||
|
|
||||||
Uri value = (Uri)newValue;
|
|
||||||
|
|
||||||
Uri defaultValue;
|
|
||||||
|
|
||||||
if (calls) defaultValue = TextSecurePreferences.getCallNotificationRingtone(context);
|
|
||||||
else defaultValue = TextSecurePreferences.getNotificationRingtone(context);
|
|
||||||
|
|
||||||
if (defaultValue.equals(value)) value = null;
|
|
||||||
else if (value == null) value = Uri.EMPTY;
|
|
||||||
|
|
||||||
|
|
||||||
new AsyncTask<Uri, Void, Void>() {
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Uri... params) {
|
|
||||||
if (calls) {
|
|
||||||
DatabaseFactory.getRecipientDatabase(context).setCallRingtone(recipient.getId(), params[0]);
|
|
||||||
} else {
|
|
||||||
DatabaseFactory.getRecipientDatabase(context).setMessageRingtone(recipient.getId(), params[0]);
|
|
||||||
NotificationChannels.updateMessageRingtone(context, recipient.get(), params[0]);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, value);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RingtoneClickedListener implements Preference.OnPreferenceClickListener {
|
|
||||||
|
|
||||||
private final boolean calls;
|
|
||||||
|
|
||||||
RingtoneClickedListener(boolean calls) {
|
|
||||||
this.calls = calls;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
|
||||||
Uri current;
|
|
||||||
Uri defaultUri;
|
|
||||||
|
|
||||||
if (calls) {
|
|
||||||
current = recipient.get().getCallRingtone();
|
|
||||||
defaultUri = TextSecurePreferences.getCallNotificationRingtone(getContext());
|
|
||||||
} else {
|
|
||||||
current = recipient.get().getMessageRingtone();
|
|
||||||
defaultUri = TextSecurePreferences.getNotificationRingtone(getContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current == null) current = Settings.System.DEFAULT_NOTIFICATION_URI;
|
|
||||||
else if (current.toString().isEmpty()) current = null;
|
|
||||||
|
|
||||||
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
|
|
||||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true);
|
|
||||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
|
|
||||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, defaultUri);
|
|
||||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, calls ? RingtoneManager.TYPE_RINGTONE : RingtoneManager.TYPE_NOTIFICATION);
|
|
||||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, current);
|
|
||||||
|
|
||||||
startActivityForResult(intent, calls ? 2 : 1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class VibrateChangeListener implements Preference.OnPreferenceChangeListener {
|
|
||||||
|
|
||||||
private final boolean call;
|
|
||||||
|
|
||||||
VibrateChangeListener(boolean call) {
|
|
||||||
this.call = call;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
||||||
int value = Integer.parseInt((String) newValue);
|
|
||||||
final VibrateState vibrateState = VibrateState.fromId(value);
|
|
||||||
final Context context = preference.getContext();
|
|
||||||
|
|
||||||
new AsyncTask<Void, Void, Void>() {
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Void... params) {
|
|
||||||
if (call) {
|
|
||||||
DatabaseFactory.getRecipientDatabase(context).setCallVibrate(recipient.getId(), vibrateState);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DatabaseFactory.getRecipientDatabase(context).setMessageVibrate(recipient.getId(), vibrateState);
|
|
||||||
NotificationChannels.updateMessageVibrate(context, recipient.get(), vibrateState);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ColorChangeListener implements Preference.OnPreferenceChangeListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
||||||
final Context context = getContext();
|
|
||||||
if (context == null) return true;
|
|
||||||
|
|
||||||
final int value = (Integer) newValue;
|
|
||||||
final MaterialColor selectedColor = MaterialColors.CONVERSATION_PALETTE.getByColor(context, value);
|
|
||||||
final MaterialColor currentColor = recipient.get().getColor();
|
|
||||||
|
|
||||||
if (selectedColor == null) return true;
|
|
||||||
|
|
||||||
if (preference.isEnabled() && !currentColor.equals(selectedColor)) {
|
|
||||||
new AsyncTask<Void, Void, Void>() {
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Void... params) {
|
|
||||||
DatabaseFactory.getRecipientDatabase(context).setColor(recipient.getId(), selectedColor);
|
|
||||||
|
|
||||||
if (recipient.get().resolve().getRegistered() == RecipientDatabase.RegisteredState.REGISTERED) {
|
|
||||||
ApplicationDependencies.getJobManager().add(new MultiDeviceContactUpdateJob(recipient.getId()));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MuteClickedListener implements Preference.OnPreferenceClickListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
|
||||||
if (recipient.get().isMuted()) handleUnmute(preference.getContext());
|
|
||||||
else handleMute(preference.getContext());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleMute(@NonNull Context context) {
|
|
||||||
MuteDialog.show(context, until -> setMuted(context, recipient.get(), until));
|
|
||||||
|
|
||||||
setSummaries(recipient.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleUnmute(@NonNull Context context) {
|
|
||||||
setMuted(context, recipient.get(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setMuted(@NonNull final Context context, final Recipient recipient, final long until) {
|
|
||||||
new AsyncTask<Void, Void, Void>() {
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Void... params) {
|
|
||||||
DatabaseFactory.getRecipientDatabase(context)
|
|
||||||
.setMuted(recipient.getId(), until);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class IdentityClickedListener implements Preference.OnPreferenceClickListener {
|
|
||||||
|
|
||||||
private final IdentityRecord identityKey;
|
|
||||||
|
|
||||||
private IdentityClickedListener(IdentityRecord identityKey) {
|
|
||||||
Log.i(TAG, "Identity record: " + identityKey);
|
|
||||||
this.identityKey = identityKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
|
||||||
startActivity(VerifyIdentityActivity.newIntent(preference.getContext(), identityKey));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class BlockClickedListener implements Preference.OnPreferenceClickListener {
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
|
||||||
Context context = preference.getContext();
|
|
||||||
|
|
||||||
if (recipient.get().isBlocked()) {
|
|
||||||
BlockUnblockDialog.showUnblockFor(context, getLifecycle(), recipient.get(), () -> RecipientUtil.unblock(context, recipient.get()));
|
|
||||||
} else {
|
|
||||||
BlockUnblockDialog.showBlockFor(context, getLifecycle(), recipient.get(), () -> RecipientUtil.block(context, recipient.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AboutNumberClickedListener implements ContactPreference.Listener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMessageClicked() {
|
|
||||||
CommunicationActions.startConversation(getContext(), recipient.get(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSecureCallClicked() {
|
|
||||||
CommunicationActions.startVoiceCall(getActivity(), recipient.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSecureVideoClicked() {
|
|
||||||
CommunicationActions.startVideoCall(getActivity(), recipient.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onInSecureCallClicked() {
|
|
||||||
CommunicationActions.startInsecureCall(requireActivity(), recipient.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLongClick() {
|
|
||||||
if (recipient.get().hasE164()) {
|
|
||||||
Util.copyToClipboard(requireContext(), recipient.get().requireE164());
|
|
||||||
ServiceUtil.getVibrator(requireContext()).vibrate(250);
|
|
||||||
Toast.makeText(requireContext(), R.string.RecipientBottomSheet_copied_to_clipboard, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class CustomNotificationsChangedListener implements Preference.OnPreferenceChangeListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
||||||
final Context context = preference.getContext();
|
|
||||||
final boolean enabled = (boolean) newValue;
|
|
||||||
|
|
||||||
new AsyncTask<Void, Void, Void>() {
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Void... params) {
|
|
||||||
if (enabled) {
|
|
||||||
String channel = NotificationChannels.createChannelFor(context, recipient.get());
|
|
||||||
DatabaseFactory.getRecipientDatabase(context).setNotificationChannel(recipient.getId(), channel);
|
|
||||||
} else {
|
|
||||||
NotificationChannels.deleteChannelFor(context, recipient.get());
|
|
||||||
DatabaseFactory.getRecipientDatabase(context).setNotificationChannel(recipient.getId(), null);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -16,7 +16,6 @@ import androidx.fragment.app.FragmentActivity;
|
|||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.RecipientPreferenceActivity;
|
|
||||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||||
@@ -26,8 +25,8 @@ import org.thoughtcrime.securesms.mms.GlideApp;
|
|||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.ui.bottomsheet.RecipientBottomSheetDialogFragment;
|
import org.thoughtcrime.securesms.recipients.ui.bottomsheet.RecipientBottomSheetDialogFragment;
|
||||||
|
import org.thoughtcrime.securesms.recipients.ui.managerecipient.ManageRecipientActivity;
|
||||||
import org.thoughtcrime.securesms.util.AvatarUtil;
|
import org.thoughtcrime.securesms.util.AvatarUtil;
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
|
||||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -165,7 +164,7 @@ public final class AvatarImageView extends AppCompatImageView {
|
|||||||
if (quickContactEnabled) {
|
if (quickContactEnabled) {
|
||||||
super.setOnClickListener(v -> {
|
super.setOnClickListener(v -> {
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
if (FeatureFlags.newGroupUI() && recipient.isPushGroup()) {
|
if (recipient.isPushGroup()) {
|
||||||
context.startActivity(ManageGroupActivity.newIntent(context, recipient.requireGroupId().requirePush()),
|
context.startActivity(ManageGroupActivity.newIntent(context, recipient.requireGroupId().requirePush()),
|
||||||
ManageGroupActivity.createTransitionBundle(context, this));
|
ManageGroupActivity.createTransitionBundle(context, this));
|
||||||
} else {
|
} else {
|
||||||
@@ -173,7 +172,7 @@ public final class AvatarImageView extends AppCompatImageView {
|
|||||||
RecipientBottomSheetDialogFragment.create(recipient.getId(), null)
|
RecipientBottomSheetDialogFragment.create(recipient.getId(), null)
|
||||||
.show(((FragmentActivity) context).getSupportFragmentManager(), "BOTTOM");
|
.show(((FragmentActivity) context).getSupportFragmentManager(), "BOTTOM");
|
||||||
} else {
|
} else {
|
||||||
context.startActivity(RecipientPreferenceActivity.getLaunchIntent(context, recipient.getId()));
|
context.startActivity(ManageRecipientActivity.newIntent(context, recipient.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -82,14 +82,12 @@ import org.greenrobot.eventbus.ThreadMode;
|
|||||||
import org.thoughtcrime.securesms.ApplicationContext;
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
import org.thoughtcrime.securesms.BlockUnblockDialog;
|
import org.thoughtcrime.securesms.BlockUnblockDialog;
|
||||||
import org.thoughtcrime.securesms.ExpirationDialog;
|
import org.thoughtcrime.securesms.ExpirationDialog;
|
||||||
import org.thoughtcrime.securesms.GroupCreateActivity;
|
|
||||||
import org.thoughtcrime.securesms.GroupMembersDialog;
|
import org.thoughtcrime.securesms.GroupMembersDialog;
|
||||||
import org.thoughtcrime.securesms.MainActivity;
|
import org.thoughtcrime.securesms.MainActivity;
|
||||||
import org.thoughtcrime.securesms.MuteDialog;
|
import org.thoughtcrime.securesms.MuteDialog;
|
||||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
||||||
import org.thoughtcrime.securesms.PromptMmsActivity;
|
import org.thoughtcrime.securesms.PromptMmsActivity;
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.RecipientPreferenceActivity;
|
|
||||||
import org.thoughtcrime.securesms.ShortcutLauncherActivity;
|
import org.thoughtcrime.securesms.ShortcutLauncherActivity;
|
||||||
import org.thoughtcrime.securesms.TransportOption;
|
import org.thoughtcrime.securesms.TransportOption;
|
||||||
import org.thoughtcrime.securesms.VerifyIdentityActivity;
|
import org.thoughtcrime.securesms.VerifyIdentityActivity;
|
||||||
@@ -207,6 +205,7 @@ import org.thoughtcrime.securesms.recipients.RecipientExporter;
|
|||||||
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||||
|
import org.thoughtcrime.securesms.recipients.ui.managerecipient.ManageRecipientActivity;
|
||||||
import org.thoughtcrime.securesms.registration.RegistrationNavigationActivity;
|
import org.thoughtcrime.securesms.registration.RegistrationNavigationActivity;
|
||||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||||
@@ -225,7 +224,6 @@ import org.thoughtcrime.securesms.util.DrawableUtil;
|
|||||||
import org.thoughtcrime.securesms.util.DynamicDarkToolbarTheme;
|
import org.thoughtcrime.securesms.util.DynamicDarkToolbarTheme;
|
||||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
|
||||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||||
import org.thoughtcrime.securesms.util.MessageUtil;
|
import org.thoughtcrime.securesms.util.MessageUtil;
|
||||||
@@ -757,10 +755,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
menu.findItem(R.id.menu_distribution_conversation).setChecked(true);
|
menu.findItem(R.id.menu_distribution_conversation).setChecked(true);
|
||||||
}
|
}
|
||||||
inflater.inflate(R.menu.conversation_active_group_options, menu);
|
inflater.inflate(R.menu.conversation_active_group_options, menu);
|
||||||
} else if (isActiveV2Group || isActiveGroup && FeatureFlags.newGroupUI()) {
|
} else if (isActiveV2Group || isActiveGroup) {
|
||||||
inflater.inflate(R.menu.conversation_active_group_options, menu);
|
inflater.inflate(R.menu.conversation_active_group_options, menu);
|
||||||
} else if (isActiveGroup) {
|
|
||||||
inflater.inflate(R.menu.conversation_push_group_options, menu);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,9 +799,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
hideMenuItem(menu, R.id.menu_mute_notifications);
|
hideMenuItem(menu, R.id.menu_mute_notifications);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FeatureFlags.newGroupUI()) {
|
|
||||||
hideMenuItem(menu, R.id.menu_group_recipients);
|
hideMenuItem(menu, R.id.menu_group_recipients);
|
||||||
}
|
|
||||||
|
|
||||||
if (isActiveV2Group) {
|
if (isActiveV2Group) {
|
||||||
hideMenuItem(menu, R.id.menu_mute_notifications);
|
hideMenuItem(menu, R.id.menu_mute_notifications);
|
||||||
@@ -884,7 +878,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
case R.id.menu_group_recipients: handleDisplayGroupRecipients(); return true;
|
case R.id.menu_group_recipients: handleDisplayGroupRecipients(); return true;
|
||||||
case R.id.menu_distribution_broadcast: handleDistributionBroadcastEnabled(item); return true;
|
case R.id.menu_distribution_broadcast: handleDistributionBroadcastEnabled(item); return true;
|
||||||
case R.id.menu_distribution_conversation: handleDistributionConversationEnabled(item); return true;
|
case R.id.menu_distribution_conversation: handleDistributionConversationEnabled(item); return true;
|
||||||
case R.id.menu_edit_group: handleEditPushGroupV1(); return true;
|
|
||||||
case R.id.menu_group_settings: handleManageGroup(); return true;
|
case R.id.menu_group_settings: handleManageGroup(); return true;
|
||||||
case R.id.menu_leave: handleLeavePushGroup(); return true;
|
case R.id.menu_leave: handleLeavePushGroup(); return true;
|
||||||
case R.id.menu_invite: handleInviteLink(); return true;
|
case R.id.menu_invite: handleInviteLink(); return true;
|
||||||
@@ -1042,14 +1035,14 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleConversationSettings() {
|
private void handleConversationSettings() {
|
||||||
if (FeatureFlags.newGroupUI() && isGroupConversation()) {
|
if (isGroupConversation()) {
|
||||||
handleManageGroup();
|
handleManageGroup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInMessageRequest()) return;
|
if (isInMessageRequest()) return;
|
||||||
|
|
||||||
Intent intent = RecipientPreferenceActivity.getLaunchIntent(this, recipient.getId());
|
Intent intent = ManageRecipientActivity.newIntent(this, recipient.getId());
|
||||||
startActivitySceneTransition(intent, titleView.findViewById(R.id.contact_photo_image), "avatar");
|
startActivitySceneTransition(intent, titleView.findViewById(R.id.contact_photo_image), "avatar");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1206,10 +1199,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleEditPushGroupV1() {
|
|
||||||
startActivityForResult(GroupCreateActivity.newEditGroupIntent(ConversationActivity.this, recipient.get().requireGroupId().requireV1()), GROUP_EDIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleManageGroup() {
|
private void handleManageGroup() {
|
||||||
startActivityForResult(ManageGroupActivity.newIntent(ConversationActivity.this, recipient.get().requireGroupId()),
|
startActivityForResult(ManageGroupActivity.newIntent(ConversationActivity.this, recipient.get().requireGroupId()),
|
||||||
GROUP_EDIT,
|
GROUP_EDIT,
|
||||||
|
@@ -15,12 +15,10 @@ import com.annimon.stream.Stream;
|
|||||||
|
|
||||||
import org.thoughtcrime.securesms.ContactSelectionActivity;
|
import org.thoughtcrime.securesms.ContactSelectionActivity;
|
||||||
import org.thoughtcrime.securesms.ContactSelectionListFragment;
|
import org.thoughtcrime.securesms.ContactSelectionListFragment;
|
||||||
import org.thoughtcrime.securesms.GroupCreateActivity;
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader;
|
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader;
|
||||||
import org.thoughtcrime.securesms.groups.ui.addtogroup.AddToGroupViewModel.Event;
|
import org.thoughtcrime.securesms.groups.ui.addtogroup.AddToGroupViewModel.Event;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -44,10 +42,6 @@ public final class AddToGroupsActivity extends ContactSelectionActivity {
|
|||||||
@NonNull RecipientId recipientId,
|
@NonNull RecipientId recipientId,
|
||||||
@NonNull List<RecipientId> currentGroupsMemberOf)
|
@NonNull List<RecipientId> currentGroupsMemberOf)
|
||||||
{
|
{
|
||||||
if (!FeatureFlags.newGroupUI()) {
|
|
||||||
return new Intent(context, GroupCreateActivity.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
Intent intent = new Intent(context, AddToGroupsActivity.class);
|
Intent intent = new Intent(context, AddToGroupsActivity.class);
|
||||||
|
|
||||||
intent.putExtra(ContactSelectionListFragment.MULTI_SELECT, false);
|
intent.putExtra(ContactSelectionListFragment.MULTI_SELECT, false);
|
||||||
|
@@ -13,7 +13,6 @@ import com.annimon.stream.Stream;
|
|||||||
|
|
||||||
import org.thoughtcrime.securesms.ContactSelectionActivity;
|
import org.thoughtcrime.securesms.ContactSelectionActivity;
|
||||||
import org.thoughtcrime.securesms.ContactSelectionListFragment;
|
import org.thoughtcrime.securesms.ContactSelectionListFragment;
|
||||||
import org.thoughtcrime.securesms.GroupCreateActivity;
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader;
|
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader;
|
||||||
import org.thoughtcrime.securesms.groups.ui.creategroup.details.AddGroupDetailsActivity;
|
import org.thoughtcrime.securesms.groups.ui.creategroup.details.AddGroupDetailsActivity;
|
||||||
@@ -30,10 +29,6 @@ public class CreateGroupActivity extends ContactSelectionActivity {
|
|||||||
private View next;
|
private View next;
|
||||||
|
|
||||||
public static Intent newIntent(@NonNull Context context) {
|
public static Intent newIntent(@NonNull Context context) {
|
||||||
if (!FeatureFlags.newGroupUI()) {
|
|
||||||
return new Intent(context, GroupCreateActivity.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
Intent intent = new Intent(context, CreateGroupActivity.class);
|
Intent intent = new Intent(context, CreateGroupActivity.class);
|
||||||
|
|
||||||
intent.putExtra(ContactSelectionListFragment.MULTI_SELECT, true);
|
intent.putExtra(ContactSelectionListFragment.MULTI_SELECT, true);
|
||||||
|
@@ -16,7 +16,6 @@ import androidx.lifecycle.ViewModelProvider;
|
|||||||
|
|
||||||
import org.thoughtcrime.securesms.BlockUnblockDialog;
|
import org.thoughtcrime.securesms.BlockUnblockDialog;
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.RecipientPreferenceActivity;
|
|
||||||
import org.thoughtcrime.securesms.VerifyIdentityActivity;
|
import org.thoughtcrime.securesms.VerifyIdentityActivity;
|
||||||
import org.thoughtcrime.securesms.database.IdentityDatabase;
|
import org.thoughtcrime.securesms.database.IdentityDatabase;
|
||||||
import org.thoughtcrime.securesms.groups.GroupId;
|
import org.thoughtcrime.securesms.groups.GroupId;
|
||||||
@@ -27,6 +26,7 @@ import org.thoughtcrime.securesms.groups.ui.addtogroup.AddToGroupsActivity;
|
|||||||
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.recipients.RecipientUtil;
|
||||||
|
import org.thoughtcrime.securesms.recipients.ui.managerecipient.ManageRecipientActivity;
|
||||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||||
@@ -112,7 +112,7 @@ final class RecipientDialogViewModel extends ViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onAvatarClicked(@NonNull Activity activity) {
|
void onAvatarClicked(@NonNull Activity activity) {
|
||||||
activity.startActivity(RecipientPreferenceActivity.getLaunchIntent(activity, recipientDialogRepository.getRecipientId()));
|
activity.startActivity(ManageRecipientActivity.newIntent(activity, recipientDialogRepository.getRecipientId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void onMakeGroupAdminClicked(@NonNull Activity activity) {
|
void onMakeGroupAdminClicked(@NonNull Activity activity) {
|
||||||
|
@@ -58,7 +58,6 @@ public final class FeatureFlags {
|
|||||||
private static final String REMOTE_DELETE = "android.remoteDelete";
|
private static final String REMOTE_DELETE = "android.remoteDelete";
|
||||||
private static final String PROFILE_FOR_CALLING = "android.profileForCalling";
|
private static final String PROFILE_FOR_CALLING = "android.profileForCalling";
|
||||||
private static final String CALLING_PIP = "android.callingPip";
|
private static final String CALLING_PIP = "android.callingPip";
|
||||||
private static final String NEW_GROUP_UI_KILL_SWITCH = "android.newGroupUI.KillSwitch";
|
|
||||||
private static final String VERSIONED_PROFILES = "android.versionedProfiles";
|
private static final String VERSIONED_PROFILES = "android.versionedProfiles";
|
||||||
private static final String GROUPS_V2 = "android.groupsv2";
|
private static final String GROUPS_V2 = "android.groupsv2";
|
||||||
private static final String GROUPS_V2_CREATE = "android.groupsv2.create";
|
private static final String GROUPS_V2_CREATE = "android.groupsv2.create";
|
||||||
@@ -78,7 +77,6 @@ public final class FeatureFlags {
|
|||||||
REMOTE_DELETE,
|
REMOTE_DELETE,
|
||||||
PROFILE_FOR_CALLING,
|
PROFILE_FOR_CALLING,
|
||||||
CALLING_PIP,
|
CALLING_PIP,
|
||||||
NEW_GROUP_UI_KILL_SWITCH,
|
|
||||||
VERSIONED_PROFILES,
|
VERSIONED_PROFILES,
|
||||||
GROUPS_V2,
|
GROUPS_V2,
|
||||||
GROUPS_V2_CREATE,
|
GROUPS_V2_CREATE,
|
||||||
@@ -235,11 +233,6 @@ public final class FeatureFlags {
|
|||||||
return getBoolean(CALLING_PIP, false);
|
return getBoolean(CALLING_PIP, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** New group UI elements. */
|
|
||||||
public static boolean newGroupUI() {
|
|
||||||
return !getBoolean(NEW_GROUP_UI_KILL_SWITCH, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Read and write versioned profile information. */
|
/** Read and write versioned profile information. */
|
||||||
public static boolean versionedProfiles() {
|
public static boolean versionedProfiles() {
|
||||||
return getBoolean(VERSIONED_PROFILES, false);
|
return getBoolean(VERSIONED_PROFILES, false);
|
||||||
|
@@ -1,165 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.util;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.BaseAdapter;
|
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class SelectedRecipientsAdapter extends BaseAdapter {
|
|
||||||
@NonNull private Context context;
|
|
||||||
@Nullable private OnRecipientDeletedListener onRecipientDeletedListener;
|
|
||||||
@NonNull private List<RecipientWrapper> recipients;
|
|
||||||
|
|
||||||
public SelectedRecipientsAdapter(@NonNull Context context) {
|
|
||||||
this(context, Collections.<Recipient>emptyList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public SelectedRecipientsAdapter(@NonNull Context context,
|
|
||||||
@NonNull Collection<Recipient> existingRecipients)
|
|
||||||
{
|
|
||||||
this.context = context;
|
|
||||||
this.recipients = wrapExistingMembers(existingRecipients);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(@NonNull Recipient recipient, boolean isPush) {
|
|
||||||
if (!find(recipient).isPresent()) {
|
|
||||||
RecipientWrapper wrapper = new RecipientWrapper(recipient, true, isPush);
|
|
||||||
this.recipients.add(0, wrapper);
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<RecipientWrapper> find(@NonNull Recipient recipient) {
|
|
||||||
RecipientWrapper found = null;
|
|
||||||
for (RecipientWrapper wrapper : recipients) {
|
|
||||||
if (wrapper.getRecipient().equals(recipient)) found = wrapper;
|
|
||||||
}
|
|
||||||
return Optional.fromNullable(found);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(@NonNull Recipient recipient) {
|
|
||||||
Optional<RecipientWrapper> match = find(recipient);
|
|
||||||
if (match.isPresent()) {
|
|
||||||
recipients.remove(match.get());
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Recipient> getRecipients() {
|
|
||||||
final Set<Recipient> recipientSet = new HashSet<>(recipients.size());
|
|
||||||
for (RecipientWrapper wrapper : recipients) {
|
|
||||||
recipientSet.add(wrapper.getRecipient());
|
|
||||||
}
|
|
||||||
return recipientSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return recipients.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasNonPushMembers() {
|
|
||||||
for (RecipientWrapper wrapper : recipients) {
|
|
||||||
if (!wrapper.isPush()) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getItem(int position) {
|
|
||||||
return recipients.get(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(int position) {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(final int position, View v, final ViewGroup parent) {
|
|
||||||
if (v == null) {
|
|
||||||
v = LayoutInflater.from(context).inflate(R.layout.selected_recipient_list_item, parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
final RecipientWrapper rw = (RecipientWrapper)getItem(position);
|
|
||||||
final Recipient p = rw.getRecipient();
|
|
||||||
final boolean modifiable = rw.isModifiable();
|
|
||||||
|
|
||||||
TextView name = (TextView) v.findViewById(R.id.name);
|
|
||||||
TextView phone = (TextView) v.findViewById(R.id.phone);
|
|
||||||
ImageButton delete = (ImageButton) v.findViewById(R.id.delete);
|
|
||||||
|
|
||||||
name.setText(p.getDisplayName(v.getContext()));
|
|
||||||
phone.setText(p.getE164().or(""));
|
|
||||||
delete.setVisibility(modifiable ? View.VISIBLE : View.GONE);
|
|
||||||
delete.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
if (onRecipientDeletedListener != null) {
|
|
||||||
onRecipientDeletedListener.onRecipientDeleted(recipients.get(position).getRecipient());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<RecipientWrapper> wrapExistingMembers(Collection<Recipient> recipients) {
|
|
||||||
final LinkedList<RecipientWrapper> wrapperList = new LinkedList<>();
|
|
||||||
for (Recipient recipient : recipients) {
|
|
||||||
wrapperList.add(new RecipientWrapper(recipient, false, true));
|
|
||||||
}
|
|
||||||
return wrapperList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnRecipientDeletedListener(@Nullable OnRecipientDeletedListener listener) {
|
|
||||||
onRecipientDeletedListener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnRecipientDeletedListener {
|
|
||||||
void onRecipientDeleted(Recipient recipient);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class RecipientWrapper {
|
|
||||||
private final Recipient recipient;
|
|
||||||
private final boolean modifiable;
|
|
||||||
private final boolean push;
|
|
||||||
|
|
||||||
public RecipientWrapper(final @NonNull Recipient recipient,
|
|
||||||
final boolean modifiable,
|
|
||||||
final boolean push)
|
|
||||||
{
|
|
||||||
this.recipient = recipient;
|
|
||||||
this.modifiable = modifiable;
|
|
||||||
this.push = push;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NonNull Recipient getRecipient() {
|
|
||||||
return recipient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isModifiable() {
|
|
||||||
return modifiable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPush() {
|
|
||||||
return push;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<gradient
|
|
||||||
android:angle="90"
|
|
||||||
android:startColor="#3A000000"
|
|
||||||
android:centerColor="#1D000000"
|
|
||||||
android:endColor="@android:color/transparent"/>
|
|
||||||
</shape>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<gradient
|
|
||||||
android:angle="270"
|
|
||||||
android:startColor="#26000000"
|
|
||||||
android:centerColor="#0C000000"
|
|
||||||
android:endColor="@android:color/transparent"/>
|
|
||||||
</shape>
|
|
@@ -1,102 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="20dp"
|
|
||||||
android:gravity="center_vertical">
|
|
||||||
|
|
||||||
<LinearLayout android:id="@+id/group_details_layout"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="106dp"
|
|
||||||
android:paddingStart="14dp"
|
|
||||||
android:paddingEnd="18dp"
|
|
||||||
android:paddingTop="14dp"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical">
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.ImageDivet android:id="@+id/avatar"
|
|
||||||
android:layout_width="70dp"
|
|
||||||
android:layout_height="70dp"
|
|
||||||
position="bottom_right"
|
|
||||||
android:layout_marginEnd="10dp"
|
|
||||||
android:contentDescription="@string/GroupCreateActivity_avatar_content_description" />
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiEditText
|
|
||||||
android:id="@+id/group_name"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:padding="10dp"
|
|
||||||
android:lines="1"
|
|
||||||
android:maxLength="255"
|
|
||||||
android:inputType="textAutoCorrect"
|
|
||||||
android:hint="@string/GroupCreateActivity_group_name_hint" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout android:id="@+id/creating_group_layout"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="106dp"
|
|
||||||
android:paddingStart="18dp"
|
|
||||||
android:paddingEnd="18dp"
|
|
||||||
android:paddingTop="18dp"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<ProgressBar android:id="@+id/creating_progress_bar"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="10dp"
|
|
||||||
style="@android:style/Widget.ProgressBar"
|
|
||||||
android:indeterminate="true" />
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
|
||||||
android:id="@+id/creating_group_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:padding="10dp"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<RelativeLayout android:id="@+id/push_disabled"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="106dp"
|
|
||||||
android:padding="15dp"
|
|
||||||
android:gravity="center_vertical|center_horizontal"
|
|
||||||
android:background="#aa000000"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/push_disabled_reason"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:padding="8dp"
|
|
||||||
android:background="#dd222222"
|
|
||||||
android:textColor="#ffeeeeee"
|
|
||||||
android:fontFamily="sans-serif-light"
|
|
||||||
android:textSize="16sp"
|
|
||||||
android:text="@string/GroupCreateActivity_contacts_dont_support_push" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.PushRecipientsPanel android:id="@+id/recipients"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingStart="15dp"
|
|
||||||
android:paddingEnd="15dp" />
|
|
||||||
|
|
||||||
<ListView android:id="@+id/selected_contacts_list"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
@@ -1,99 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:id="@+id/recipient_preference_root"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginStart="0dp"
|
|
||||||
android:layout_marginEnd="0dp"
|
|
||||||
android:background="@color/transparent"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
|
||||||
android:id="@+id/app_bar_layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="300dp"
|
|
||||||
android:background="@color/transparent">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
|
||||||
android:id="@+id/collapsing_toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="@color/transparent"
|
|
||||||
app:layout_scrollFlags="scroll|exitUntilCollapsed">
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/avatar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:transitionName="avatar"
|
|
||||||
app:layout_collapseMode="parallax"
|
|
||||||
app:layout_collapseParallaxMultiplier="0.7"/>
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="88dp"
|
|
||||||
android:background="@drawable/recipient_preference_scrim_top"
|
|
||||||
app:layout_collapseMode="pin"/>
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="98dp"
|
|
||||||
android:layout_gravity="bottom"
|
|
||||||
android:layout_alignBottom="@+id/image"
|
|
||||||
android:background="@drawable/recipient_preference_scrim_bottom"/>
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:background="@color/transparent"
|
|
||||||
android:theme="@style/TextSecure.DarkActionBar.Conversation"
|
|
||||||
app:layout_collapseMode="pin" >
|
|
||||||
|
|
||||||
</androidx.appcompat.widget.Toolbar>
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
|
||||||
android:id="@+id/scroll_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:fillViewport="true"
|
|
||||||
android:descendantFocusability="blocksDescendants"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
|
||||||
|
|
||||||
<LinearLayout android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/rail_label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:text="@string/recipient_preference_activity__shared_media"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:focusableInTouchMode="true"
|
|
||||||
style="?android:attr/preferenceCategoryStyle"
|
|
||||||
android:textColor="@color/core_ultramarine"/>
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.ThreadPhotoRailView
|
|
||||||
android:id="@+id/recent_photos"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="90dp"
|
|
||||||
android:visibility="visible"
|
|
||||||
android:layout_marginBottom="16dp"/>
|
|
||||||
|
|
||||||
<include layout="@layout/preference_divider"/>
|
|
||||||
|
|
||||||
<FrameLayout android:id="@+id/preference_fragment"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@@ -1,35 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:padding="10dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/name"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/phone"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_below="@id/name"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
|
||||||
android:fontFamily="sans-serif-light" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/delete"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:background="#00ffffff"
|
|
||||||
android:contentDescription="@string/GroupCreateActivity_remove_member_description"
|
|
||||||
android:src="@drawable/ic_menu_remove_holo_light" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<item android:id="@+id/menu_edit_group"
|
|
||||||
android:title="@string/conversation__menu_edit_group"
|
|
||||||
app:showAsAction="collapseActionView" />
|
|
||||||
|
|
||||||
<item android:id="@+id/menu_leave"
|
|
||||||
android:title="@string/conversation__menu_leave_group"
|
|
||||||
app:showAsAction="collapseActionView"/>
|
|
||||||
|
|
||||||
</menu>
|
|
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<item android:title="@string/GroupCreateActivity_menu_apply_button"
|
|
||||||
android:id="@+id/menu_create_group"
|
|
||||||
android:icon="?menu_accept_icon"
|
|
||||||
app:showAsAction="always|withText"/>
|
|
||||||
|
|
||||||
</menu>
|
|
@@ -236,12 +236,6 @@
|
|||||||
<item>@string/arrays__disabled</item>
|
<item>@string/arrays__disabled</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="recipient_vibrate_values">
|
|
||||||
<item>0</item>
|
|
||||||
<item>1</item>
|
|
||||||
<item>2</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<string-array name="pref_notification_privacy_entries">
|
<string-array name="pref_notification_privacy_entries">
|
||||||
<item>@string/arrays__name_and_message</item>
|
<item>@string/arrays__name_and_message</item>
|
||||||
<item>@string/arrays__name_only</item>
|
<item>@string/arrays__name_only</item>
|
||||||
|
@@ -430,25 +430,6 @@
|
|||||||
<string name="GiphyFragmentPagerAdapter_gifs">GIFs</string>
|
<string name="GiphyFragmentPagerAdapter_gifs">GIFs</string>
|
||||||
<string name="GiphyFragmentPagerAdapter_stickers">Stickers</string>
|
<string name="GiphyFragmentPagerAdapter_stickers">Stickers</string>
|
||||||
|
|
||||||
<!-- GroupCreateActivity -->
|
|
||||||
<string name="GroupCreateActivity_actionbar_title">New group</string>
|
|
||||||
<string name="GroupCreateActivity_actionbar_edit_title">Edit group</string>
|
|
||||||
<string name="GroupCreateActivity_actionbar_manage_title">Manage group</string>
|
|
||||||
<string name="GroupCreateActivity_group_name_hint">Group name</string>
|
|
||||||
<string name="GroupCreateActivity_actionbar_mms_title">New MMS group</string>
|
|
||||||
<string name="GroupCreateActivity_contacts_dont_support_push">You have selected a contact that doesn\'t support Signal groups, so this group will be MMS.</string>
|
|
||||||
<string name="GroupCreateActivity_youre_not_registered_for_signal">You\'re not registered for Signal messages and calls, so Signal groups are disabled. Please try registering in Settings > Advanced.</string>
|
|
||||||
<string name="GroupCreateActivity_contacts_no_members">You need at least one person in your group!</string>
|
|
||||||
<string name="GroupCreateActivity_contacts_invalid_number">One of the members of your group has a number that can\'t be read correctly. Please fix or remove that contact and try again.</string>
|
|
||||||
<string name="GroupCreateActivity_avatar_content_description">Group avatar</string>
|
|
||||||
<string name="GroupCreateActivity_menu_apply_button">Apply</string>
|
|
||||||
<string name="GroupCreateActivity_creating_group">Creating %1$s…</string>
|
|
||||||
<string name="GroupCreateActivity_updating_group">Updating %1$s…</string>
|
|
||||||
<string name="GroupCreateActivity_cannot_add_non_push_to_existing_group">Couldn\'t add %1$s because they\'re not a Signal user.</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_remove_member_description">Remove member</string>
|
|
||||||
|
|
||||||
<!-- AddToGroupActivity -->
|
<!-- AddToGroupActivity -->
|
||||||
<string name="AddToGroupActivity_add_member">Add member?</string>
|
<string name="AddToGroupActivity_add_member">Add member?</string>
|
||||||
<string name="AddToGroupActivity_add_s_to_s">Add \"%1$s\" to \"%2$s\"?</string>
|
<string name="AddToGroupActivity_add_s_to_s">Add \"%1$s\" to \"%2$s\"?</string>
|
||||||
@@ -1657,20 +1638,6 @@
|
|||||||
<!-- recipient_preferences_activity -->
|
<!-- recipient_preferences_activity -->
|
||||||
<string name="recipient_preference_activity__shared_media">Shared media</string>
|
<string name="recipient_preference_activity__shared_media">Shared media</string>
|
||||||
|
|
||||||
<!-- recipient_preferences -->
|
|
||||||
<string name="recipient_preferences__mute_conversation">Mute conversation</string>
|
|
||||||
<string name="recipient_preferences__custom_notifications">Custom notifications</string>
|
|
||||||
<string name="recipient_preferences__custom_notifications_settings">System notification settings</string>
|
|
||||||
<string name="recipient_preferences__notification_sound">Notification sound</string>
|
|
||||||
<string name="recipient_preferences__vibrate">Vibrate</string>
|
|
||||||
<string name="recipient_preferences__block">Block</string>
|
|
||||||
<string name="recipient_preferences__color">Color</string>
|
|
||||||
<string name="recipient_preferences__view_safety_number">View safety number</string>
|
|
||||||
<string name="recipient_preferences__chat_settings">Chat settings</string>
|
|
||||||
<string name="recipient_preferences__privacy">Privacy</string>
|
|
||||||
<string name="recipient_preferences__call_settings">Call settings</string>
|
|
||||||
<string name="recipient_preferences__ringtone">Ringtone</string>
|
|
||||||
|
|
||||||
<!--- redphone_call_controls -->
|
<!--- redphone_call_controls -->
|
||||||
<string name="redphone_call_card__signal_call">Signal Call</string>
|
<string name="redphone_call_card__signal_call">Signal Call</string>
|
||||||
|
|
||||||
|
@@ -1,84 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<PreferenceCategory android:key="about" android:title="@string/recipient_preferences__about">
|
|
||||||
<org.thoughtcrime.securesms.preferences.widgets.ContactPreference android:key="pref_key_number" android:persistent="false"/>
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory android:key="about_divider" android:layout="@layout/preference_divider"/>
|
|
||||||
|
|
||||||
<PreferenceCategory android:key="notification_settings" android:title="@string/recipient_preferences__chat_settings">
|
|
||||||
<org.thoughtcrime.securesms.components.SwitchPreferenceCompat
|
|
||||||
android:key="pref_key_recipient_mute"
|
|
||||||
android:title="@string/recipient_preferences__mute_conversation"
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:disableDependentsState="true"
|
|
||||||
android:persistent="false" />
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.SwitchPreferenceCompat
|
|
||||||
android:key="pref_key_recipient_custom_notifications"
|
|
||||||
android:title="@string/recipient_preferences__custom_notifications"
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:persistent="false" />
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.preferences.widgets.SignalPreference
|
|
||||||
android:dependency="pref_key_recipient_mute"
|
|
||||||
android:key="pref_key_recipient_ringtone"
|
|
||||||
android:title="@string/recipient_preferences__notification_sound"
|
|
||||||
android:persistent="false"/>
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.preferences.widgets.SignalListPreference
|
|
||||||
android:dependency="pref_key_recipient_mute"
|
|
||||||
android:key="pref_key_recipient_vibrate"
|
|
||||||
android:title="@string/recipient_preferences__vibrate"
|
|
||||||
android:entries="@array/recipient_vibrate_entries"
|
|
||||||
android:entryValues="@array/recipient_vibrate_values"
|
|
||||||
android:defaultValue="0"
|
|
||||||
android:persistent="false"/>
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.preferences.widgets.ColorPickerPreference
|
|
||||||
android:key="pref_key_recipient_color"
|
|
||||||
android:title="@string/recipient_preferences__color"
|
|
||||||
android:defaultValue="@android:color/black"
|
|
||||||
android:negativeButtonText="@null"
|
|
||||||
android:positiveButtonText="@null"
|
|
||||||
android:persistent="false"
|
|
||||||
app:numColumns="5" />
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory android:layout="@layout/preference_divider"/>
|
|
||||||
|
|
||||||
<PreferenceCategory android:key="call_settings" android:title="@string/recipient_preferences__call_settings">
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.preferences.widgets.SignalPreference
|
|
||||||
android:key="pref_key_recipient_call_ringtone"
|
|
||||||
android:title="@string/recipient_preferences__ringtone"
|
|
||||||
android:persistent="false"/>
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.preferences.widgets.SignalListPreference
|
|
||||||
android:key="pref_key_recipient_call_vibrate"
|
|
||||||
android:title="@string/recipient_preferences__vibrate"
|
|
||||||
android:entries="@array/recipient_vibrate_entries"
|
|
||||||
android:entryValues="@array/recipient_vibrate_values"
|
|
||||||
android:defaultValue="0"
|
|
||||||
android:persistent="false"/>
|
|
||||||
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory android:key="divider" android:layout="@layout/preference_divider"/>
|
|
||||||
|
|
||||||
<PreferenceCategory android:key="privacy_settings" android:title="@string/recipient_preferences__privacy">
|
|
||||||
|
|
||||||
<Preference android:key="pref_key_recipient_identity"
|
|
||||||
android:title="@string/recipient_preferences__view_safety_number"
|
|
||||||
android:persistent="false"
|
|
||||||
android:enabled="false"/>
|
|
||||||
|
|
||||||
<Preference android:key="pref_key_recipient_block"
|
|
||||||
android:title="@string/recipient_preferences__block"
|
|
||||||
android:persistent="false"/>
|
|
||||||
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
</PreferenceScreen>
|
|
Reference in New Issue
Block a user