mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 01:07:47 +00:00
Allow editing of contact names.
Took care to properly format CJK names.
This commit is contained in:
parent
54dbffaf30
commit
e6c16cf28d
@ -407,6 +407,10 @@
|
|||||||
android:theme="@style/TextSecure.LightTheme"
|
android:theme="@style/TextSecure.LightTheme"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||||
|
|
||||||
|
<activity android:name=".contactshare.ContactNameEditActivity"
|
||||||
|
android:theme="@style/TextSecure.LightNoActionBar"
|
||||||
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||||
|
|
||||||
<activity android:name=".contactshare.SharedContactDetailsActivity"
|
<activity android:name=".contactshare.SharedContactDetailsActivity"
|
||||||
android:theme="@style/TextSecure.LightNoActionBar"
|
android:theme="@style/TextSecure.LightNoActionBar"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||||
|
70
res/layout/activity_contact_name_edit.xml
Normal file
70
res/layout/activity_contact_name_edit.xml
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<android.support.v7.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:theme="@style/TextSecure.LightActionBar"
|
||||||
|
android:background="@color/signal_primary"
|
||||||
|
android:elevation="4dp"/>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="12dp">
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||||
|
android:id="@+id/name_edit_display_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
|
android:textSize="20sp"
|
||||||
|
tools:text="Peter Parker"/>
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.components.emoji.EmojiEditText
|
||||||
|
android:id="@+id/name_edit_prefix"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/ContactNameEditActivity_prefix"/>
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.components.emoji.EmojiEditText
|
||||||
|
android:id="@+id/name_edit_given_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/ContactNameEditActivity_given_name"/>
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.components.emoji.EmojiEditText
|
||||||
|
android:id="@+id/name_edit_middle_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/ContactNameEditActivity_middle_name"/>
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.components.emoji.EmojiEditText
|
||||||
|
android:id="@+id/name_edit_family_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/ContactNameEditActivity_family_name"/>
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.components.emoji.EmojiEditText
|
||||||
|
android:id="@+id/name_edit_suffix"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/ContactNameEditActivity_suffix"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -28,6 +28,15 @@
|
|||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
tools:text="Peter Parker"/>
|
tools:text="Peter Parker"/>
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/editable_contact_name_edit_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/ic_create_white_24dp"
|
||||||
|
android:tint="@color/signal_primary"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
@ -97,6 +97,13 @@
|
|||||||
<string name="ContactsDatabase_message_s">Message %s</string>
|
<string name="ContactsDatabase_message_s">Message %s</string>
|
||||||
<string name="ContactsDatabase_signal_call_s">Signal Call %s</string>
|
<string name="ContactsDatabase_signal_call_s">Signal Call %s</string>
|
||||||
|
|
||||||
|
<!-- ContactNameEditActivity -->
|
||||||
|
<string name="ContactNameEditActivity_given_name">Given name</string>
|
||||||
|
<string name="ContactNameEditActivity_family_name">Family name</string>
|
||||||
|
<string name="ContactNameEditActivity_prefix">Prefix</string>
|
||||||
|
<string name="ContactNameEditActivity_suffix">Suffix</string>
|
||||||
|
<string name="ContactNameEditActivity_middle_name">Middle name</string>
|
||||||
|
|
||||||
<!-- ContactShareEditActivity -->
|
<!-- ContactShareEditActivity -->
|
||||||
<string name="ContactShareEditActivity_type_home">Home</string>
|
<string name="ContactShareEditActivity_type_home">Home</string>
|
||||||
<string name="ContactShareEditActivity_type_mobile">Mobile</string>
|
<string name="ContactShareEditActivity_type_mobile">Mobile</string>
|
||||||
|
@ -0,0 +1,156 @@
|
|||||||
|
package org.thoughtcrime.securesms.contactshare;
|
||||||
|
|
||||||
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v7.widget.Toolbar;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
||||||
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||||
|
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||||
|
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||||
|
|
||||||
|
import static org.thoughtcrime.securesms.contactshare.Contact.*;
|
||||||
|
|
||||||
|
public class ContactNameEditActivity extends PassphraseRequiredActionBarActivity {
|
||||||
|
|
||||||
|
public static final String KEY_NAME = "name";
|
||||||
|
public static final String KEY_CONTACT_INDEX = "contact_index";
|
||||||
|
|
||||||
|
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||||
|
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||||
|
|
||||||
|
private TextView displayNameView;
|
||||||
|
private ContactNameEditViewModel viewModel;
|
||||||
|
|
||||||
|
static Intent getIntent(@NonNull Context context, @NonNull Name name, int contactPosition) {
|
||||||
|
Intent intent = new Intent(context, ContactNameEditActivity.class);
|
||||||
|
intent.putExtra(KEY_NAME, name);
|
||||||
|
intent.putExtra(KEY_CONTACT_INDEX, contactPosition);
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreCreate() {
|
||||||
|
dynamicTheme.onCreate(this);
|
||||||
|
dynamicLanguage.onCreate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState, boolean ready) {
|
||||||
|
super.onCreate(savedInstanceState, ready);
|
||||||
|
|
||||||
|
if (getIntent() == null) {
|
||||||
|
throw new IllegalStateException("You must supply extras to this activity. Please use the #getIntent() method.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Name name = getIntent().getParcelableExtra(KEY_NAME);
|
||||||
|
if (name == null) {
|
||||||
|
throw new IllegalStateException("You must supply a name to this activity. Please use the #getIntent() method.");
|
||||||
|
}
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_contact_name_edit);
|
||||||
|
|
||||||
|
initializeToolbar();
|
||||||
|
initializeViews(name);
|
||||||
|
|
||||||
|
viewModel = ViewModelProviders.of(this).get(ContactNameEditViewModel.class);
|
||||||
|
viewModel.setName(name);
|
||||||
|
viewModel.getDisplayName().observe(this, displayNameView::setText);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
dynamicTheme.onResume(this);
|
||||||
|
dynamicLanguage.onResume(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeToolbar() {
|
||||||
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
toolbar.setTitle("");
|
||||||
|
toolbar.setNavigationIcon(R.drawable.ic_check_white_24dp);
|
||||||
|
toolbar.setNavigationOnClickListener(v -> {
|
||||||
|
Intent resultIntent = new Intent();
|
||||||
|
resultIntent.putExtra(KEY_NAME, viewModel.getName());
|
||||||
|
resultIntent.putExtra(KEY_CONTACT_INDEX, getIntent().getIntExtra(KEY_CONTACT_INDEX, -1));
|
||||||
|
setResult(RESULT_OK, resultIntent);
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeViews(@NonNull Name name) {
|
||||||
|
displayNameView = findViewById(R.id.name_edit_display_name);
|
||||||
|
|
||||||
|
TextView givenName = findViewById(R.id.name_edit_given_name);
|
||||||
|
TextView familyName = findViewById(R.id.name_edit_family_name);
|
||||||
|
TextView middleName = findViewById(R.id.name_edit_middle_name);
|
||||||
|
TextView prefix = findViewById(R.id.name_edit_prefix);
|
||||||
|
TextView suffix = findViewById(R.id.name_edit_suffix);
|
||||||
|
|
||||||
|
givenName.setText(name.getGivenName());
|
||||||
|
familyName.setText(name.getFamilyName());
|
||||||
|
middleName.setText(name.getMiddleName());
|
||||||
|
prefix.setText(name.getPrefix());
|
||||||
|
suffix.setText(name.getSuffix());
|
||||||
|
|
||||||
|
givenName.addTextChangedListener(new SimpleTextWatcher() {
|
||||||
|
@Override
|
||||||
|
void onTextChanged(String text) {
|
||||||
|
viewModel.updateGivenName(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
familyName.addTextChangedListener(new SimpleTextWatcher() {
|
||||||
|
@Override
|
||||||
|
void onTextChanged(String text) {
|
||||||
|
viewModel.updateFamilyName(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
middleName.addTextChangedListener(new SimpleTextWatcher() {
|
||||||
|
@Override
|
||||||
|
void onTextChanged(String text) {
|
||||||
|
viewModel.updateMiddleName(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
prefix.addTextChangedListener(new SimpleTextWatcher() {
|
||||||
|
@Override
|
||||||
|
void onTextChanged(String text) {
|
||||||
|
viewModel.updatePrefix(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
suffix.addTextChangedListener(new SimpleTextWatcher() {
|
||||||
|
@Override
|
||||||
|
void onTextChanged(String text) {
|
||||||
|
viewModel.updateSuffix(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static abstract class SimpleTextWatcher implements TextWatcher {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
onTextChanged(s.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) { }
|
||||||
|
|
||||||
|
abstract void onTextChanged(String text);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
package org.thoughtcrime.securesms.contactshare;
|
||||||
|
|
||||||
|
import android.arch.lifecycle.LiveData;
|
||||||
|
import android.arch.lifecycle.MutableLiveData;
|
||||||
|
import android.arch.lifecycle.ViewModel;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import static org.thoughtcrime.securesms.contactshare.Contact.*;
|
||||||
|
|
||||||
|
public class ContactNameEditViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private final MutableLiveData<String> displayName;
|
||||||
|
|
||||||
|
private String givenName;
|
||||||
|
private String familyName;
|
||||||
|
private String middleName;
|
||||||
|
private String prefix;
|
||||||
|
private String suffix;
|
||||||
|
|
||||||
|
public ContactNameEditViewModel() {
|
||||||
|
this.displayName = new MutableLiveData<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setName(@NonNull Name name) {
|
||||||
|
givenName = name.getGivenName();
|
||||||
|
familyName = name.getFamilyName();
|
||||||
|
middleName = name.getMiddleName();
|
||||||
|
prefix = name.getPrefix();
|
||||||
|
suffix = name.getSuffix();
|
||||||
|
|
||||||
|
displayName.postValue(buildDisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Name getName() {
|
||||||
|
return new Name(displayName.getValue(), givenName, familyName, prefix, suffix, middleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
LiveData<String> getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateGivenName(@NonNull String givenName) {
|
||||||
|
this.givenName = givenName;
|
||||||
|
displayName.postValue(buildDisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateFamilyName(@NonNull String familyName) {
|
||||||
|
this.familyName = familyName;
|
||||||
|
displayName.postValue(buildDisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePrefix(@NonNull String prefix) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
displayName.postValue(buildDisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSuffix(@NonNull String suffix) {
|
||||||
|
this.suffix = suffix;
|
||||||
|
displayName.postValue(buildDisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateMiddleName(@NonNull String middleName) {
|
||||||
|
this.middleName = middleName;
|
||||||
|
displayName.postValue(buildDisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildDisplayName() {
|
||||||
|
boolean isCJKV = isCJKV(givenName) && isCJKV(middleName) && isCJKV(familyName) && isCJKV(prefix) && isCJKV(suffix);
|
||||||
|
if (isCJKV) {
|
||||||
|
return joinString(familyName, givenName, prefix, suffix, middleName);
|
||||||
|
}
|
||||||
|
return joinString(prefix, givenName, middleName, familyName, suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String joinString(String... values) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
for (String value : values) {
|
||||||
|
if (!TextUtils.isEmpty(value)) {
|
||||||
|
builder.append(value).append(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isCJKV(@Nullable String value) {
|
||||||
|
if (TextUtils.isEmpty(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int offset = 0; offset < value.length(); ) {
|
||||||
|
int codepoint = Character.codePointAt(value, offset);
|
||||||
|
|
||||||
|
if (!isCodepointCJKV(codepoint)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += Character.charCount(codepoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isCodepointCJKV(int codepoint) {
|
||||||
|
if (codepoint == (int)' ') return true;
|
||||||
|
|
||||||
|
Character.UnicodeBlock block = Character.UnicodeBlock.of(codepoint);
|
||||||
|
|
||||||
|
boolean isCJKV = Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS.equals(block) ||
|
||||||
|
Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A.equals(block) ||
|
||||||
|
Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B.equals(block) ||
|
||||||
|
Character.UnicodeBlock.CJK_COMPATIBILITY.equals(block) ||
|
||||||
|
Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS.equals(block) ||
|
||||||
|
Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS.equals(block) ||
|
||||||
|
Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT.equals(block) ||
|
||||||
|
Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT.equals(block) ||
|
||||||
|
Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION.equals(block) ||
|
||||||
|
Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS.equals(block) ||
|
||||||
|
Character.UnicodeBlock.KANGXI_RADICALS.equals(block) ||
|
||||||
|
Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS.equals(block) ||
|
||||||
|
Character.UnicodeBlock.HIRAGANA.equals(block) ||
|
||||||
|
Character.UnicodeBlock.KATAKANA.equals(block) ||
|
||||||
|
Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS.equals(block) ||
|
||||||
|
Character.UnicodeBlock.HANGUL_JAMO.equals(block) ||
|
||||||
|
Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO.equals(block) ||
|
||||||
|
Character.UnicodeBlock.HANGUL_SYLLABLES.equals(block);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= 19) {
|
||||||
|
isCJKV |= Character.isIdeographic(codepoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isCJKV;
|
||||||
|
}
|
||||||
|
}
|
@ -25,12 +25,14 @@ import org.thoughtcrime.securesms.util.DynamicTheme;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.thoughtcrime.securesms.contactshare.Contact.*;
|
||||||
import static org.thoughtcrime.securesms.contactshare.ContactShareEditViewModel.*;
|
import static org.thoughtcrime.securesms.contactshare.ContactShareEditViewModel.*;
|
||||||
|
|
||||||
public class ContactShareEditActivity extends PassphraseRequiredActionBarActivity {
|
public class ContactShareEditActivity extends PassphraseRequiredActionBarActivity implements ContactShareEditAdapter.EventListener {
|
||||||
|
|
||||||
public static final String KEY_CONTACTS = "contacts";
|
public static final String KEY_CONTACTS = "contacts";
|
||||||
private static final String KEY_CONTACT_IDS = "ids";
|
private static final String KEY_CONTACT_IDS = "ids";
|
||||||
|
private static final int CODE_NAME_EDIT = 55;
|
||||||
|
|
||||||
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
||||||
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||||
@ -73,7 +75,7 @@ public class ContactShareEditActivity extends PassphraseRequiredActionBarActivit
|
|||||||
contactList.setLayoutManager(new LinearLayoutManager(this));
|
contactList.setLayoutManager(new LinearLayoutManager(this));
|
||||||
contactList.getLayoutManager().setAutoMeasureEnabled(true);
|
contactList.getLayoutManager().setAutoMeasureEnabled(true);
|
||||||
|
|
||||||
ContactShareEditAdapter contactAdapter = new ContactShareEditAdapter(GlideApp.with(this), dynamicLanguage.getCurrentLocale());
|
ContactShareEditAdapter contactAdapter = new ContactShareEditAdapter(GlideApp.with(this), dynamicLanguage.getCurrentLocale(), this);
|
||||||
contactList.setAdapter(contactAdapter);
|
contactList.setAdapter(contactAdapter);
|
||||||
|
|
||||||
ContactRepository contactRepository = new ContactRepository(this,
|
ContactRepository contactRepository = new ContactRepository(this,
|
||||||
@ -117,4 +119,25 @@ public class ContactShareEditActivity extends PassphraseRequiredActionBarActivit
|
|||||||
|
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNameEditClicked(int position, @NonNull Name name) {
|
||||||
|
startActivityForResult(ContactNameEditActivity.getIntent(this, name, position), CODE_NAME_EDIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
|
if (requestCode != CODE_NAME_EDIT || resultCode != RESULT_OK || data == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int position = data.getIntExtra(ContactNameEditActivity.KEY_CONTACT_INDEX, -1);
|
||||||
|
Name name = data.getParcelableExtra(ContactNameEditActivity.KEY_NAME);
|
||||||
|
|
||||||
|
if (name != null) {
|
||||||
|
viewModel.updateContactName(position, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,15 +20,19 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import static org.thoughtcrime.securesms.contactshare.Contact.*;
|
||||||
|
|
||||||
public class ContactShareEditAdapter extends RecyclerView.Adapter<ContactShareEditAdapter.ContactEditViewHolder> {
|
public class ContactShareEditAdapter extends RecyclerView.Adapter<ContactShareEditAdapter.ContactEditViewHolder> {
|
||||||
|
|
||||||
private final Locale locale;
|
|
||||||
private final GlideRequests glideRequests;
|
private final GlideRequests glideRequests;
|
||||||
|
private final Locale locale;
|
||||||
|
private final EventListener eventListener;
|
||||||
private final List<Contact> contacts;
|
private final List<Contact> contacts;
|
||||||
|
|
||||||
ContactShareEditAdapter(@NonNull GlideRequests glideRequests, @NonNull Locale locale) {
|
ContactShareEditAdapter(@NonNull GlideRequests glideRequests, @NonNull Locale locale, @NonNull EventListener eventListener) {
|
||||||
this.locale = locale;
|
|
||||||
this.glideRequests = glideRequests;
|
this.glideRequests = glideRequests;
|
||||||
|
this.locale = locale;
|
||||||
|
this.eventListener = eventListener;
|
||||||
this.contacts = new ArrayList<>();
|
this.contacts = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +43,7 @@ public class ContactShareEditAdapter extends RecyclerView.Adapter<ContactShareEd
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(ContactEditViewHolder holder, int position) {
|
public void onBindViewHolder(ContactEditViewHolder holder, int position) {
|
||||||
holder.bind(contacts.get(position), glideRequests);
|
holder.bind(position, contacts.get(position), glideRequests, eventListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -61,6 +65,7 @@ public class ContactShareEditAdapter extends RecyclerView.Adapter<ContactShareEd
|
|||||||
|
|
||||||
private final AvatarImageView avatar;
|
private final AvatarImageView avatar;
|
||||||
private final TextView name;
|
private final TextView name;
|
||||||
|
private final View nameEditButton;
|
||||||
private final ContactFieldAdapter fieldAdapter;
|
private final ContactFieldAdapter fieldAdapter;
|
||||||
|
|
||||||
ContactEditViewHolder(View itemView, @NonNull Locale locale) {
|
ContactEditViewHolder(View itemView, @NonNull Locale locale) {
|
||||||
@ -68,6 +73,7 @@ public class ContactShareEditAdapter extends RecyclerView.Adapter<ContactShareEd
|
|||||||
|
|
||||||
this.avatar = itemView.findViewById(R.id.editable_contact_avatar);
|
this.avatar = itemView.findViewById(R.id.editable_contact_avatar);
|
||||||
this.name = itemView.findViewById(R.id.editable_contact_name);
|
this.name = itemView.findViewById(R.id.editable_contact_name);
|
||||||
|
this.nameEditButton = itemView.findViewById(R.id.editable_contact_name_edit_button);
|
||||||
this.fieldAdapter = new ContactFieldAdapter(locale, true);
|
this.fieldAdapter = new ContactFieldAdapter(locale, true);
|
||||||
|
|
||||||
RecyclerView fields = itemView.findViewById(R.id.editable_contact_fields);
|
RecyclerView fields = itemView.findViewById(R.id.editable_contact_fields);
|
||||||
@ -76,7 +82,7 @@ public class ContactShareEditAdapter extends RecyclerView.Adapter<ContactShareEd
|
|||||||
fields.setAdapter(fieldAdapter);
|
fields.setAdapter(fieldAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(@NonNull Contact contact, @NonNull GlideRequests glideRequests) {
|
void bind(int position, @NonNull Contact contact, @NonNull GlideRequests glideRequests, @NonNull EventListener eventListener) {
|
||||||
Context context = itemView.getContext();
|
Context context = itemView.getContext();
|
||||||
|
|
||||||
if (contact.getAvatarAttachment() != null && contact.getAvatarAttachment().getDataUri() != null) {
|
if (contact.getAvatarAttachment() != null && contact.getAvatarAttachment().getDataUri() != null) {
|
||||||
@ -93,7 +99,12 @@ public class ContactShareEditAdapter extends RecyclerView.Adapter<ContactShareEd
|
|||||||
}
|
}
|
||||||
|
|
||||||
name.setText(ContactUtil.getDisplayName(contact));
|
name.setText(ContactUtil.getDisplayName(contact));
|
||||||
|
nameEditButton.setOnClickListener(v -> eventListener.onNameEditClicked(position, contact.getName()));
|
||||||
fieldAdapter.setFields(context, contact.getPhoneNumbers(), contact.getEmails(), contact.getPostalAddresses());
|
fieldAdapter.setFields(context, contact.getPhoneNumbers(), contact.getEmails(), contact.getPostalAddresses());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface EventListener {
|
||||||
|
void onNameEditClicked(int position, @NonNull Name name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import android.support.annotation.NonNull;
|
|||||||
|
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.contactshare.Contact.Name;
|
||||||
import org.thoughtcrime.securesms.util.SingleLiveEvent;
|
import org.thoughtcrime.securesms.util.SingleLiveEvent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -60,6 +61,25 @@ class ContactShareEditViewModel extends ViewModel {
|
|||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateContactName(int contactPosition, @NonNull Name name) {
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
events.postValue(Event.BAD_CONTACT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Contact> currentContacts = getCurrentContacts();
|
||||||
|
Contact original = currentContacts.remove(contactPosition);
|
||||||
|
|
||||||
|
currentContacts.add(new Contact(name,
|
||||||
|
original.getOrganization(),
|
||||||
|
original.getPhoneNumbers(),
|
||||||
|
original.getEmails(),
|
||||||
|
original.getPostalAddresses(),
|
||||||
|
original.getAvatar()));
|
||||||
|
|
||||||
|
contacts.postValue(currentContacts);
|
||||||
|
}
|
||||||
|
|
||||||
private <E extends Selectable> List<E> trimSelectables(List<E> selectables) {
|
private <E extends Selectable> List<E> trimSelectables(List<E> selectables) {
|
||||||
return Stream.of(selectables).filter(Selectable::isSelected).toList();
|
return Stream.of(selectables).filter(Selectable::isSelected).toList();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user