mirror of https://github.com/M66B/FairEmail.git
Added account to local contacts
This commit is contained in:
parent
d63536b3fc
commit
5d98923ffc
File diff suppressed because it is too large
Load Diff
|
@ -509,14 +509,15 @@ public class ActivitySetup extends ActivityBilling implements FragmentManager.On
|
||||||
}
|
}
|
||||||
jaccount.put("folders", jfolders);
|
jaccount.put("folders", jfolders);
|
||||||
|
|
||||||
|
// Contacts
|
||||||
|
JSONArray jcontacts = new JSONArray();
|
||||||
|
for (EntityContact contact : db.contact().getContacts(account.id))
|
||||||
|
jcontacts.put(contact.toJSON());
|
||||||
|
jaccount.put("contacts", jcontacts);
|
||||||
|
|
||||||
jaccounts.put(jaccount);
|
jaccounts.put(jaccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contacts
|
|
||||||
JSONArray jcontacts = new JSONArray();
|
|
||||||
for (EntityContact contact : db.contact().getContacts())
|
|
||||||
jcontacts.put(contact.toJSON());
|
|
||||||
|
|
||||||
// Answers
|
// Answers
|
||||||
JSONArray janswers = new JSONArray();
|
JSONArray janswers = new JSONArray();
|
||||||
for (EntityAnswer answer : db.answer().getAnswers())
|
for (EntityAnswer answer : db.answer().getAnswers())
|
||||||
|
@ -535,7 +536,6 @@ public class ActivitySetup extends ActivityBilling implements FragmentManager.On
|
||||||
|
|
||||||
JSONObject jexport = new JSONObject();
|
JSONObject jexport = new JSONObject();
|
||||||
jexport.put("accounts", jaccounts);
|
jexport.put("accounts", jaccounts);
|
||||||
jexport.put("contacts", jcontacts);
|
|
||||||
jexport.put("answers", janswers);
|
jexport.put("answers", janswers);
|
||||||
jexport.put("settings", jsettings);
|
jexport.put("settings", jsettings);
|
||||||
|
|
||||||
|
@ -700,21 +700,22 @@ public class ActivitySetup extends ActivityBilling implements FragmentManager.On
|
||||||
Log.i("Imported folder=" + folder.name);
|
Log.i("Imported folder=" + folder.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Contacts
|
||||||
|
JSONArray jcontacts = jaccount.getJSONArray("contacts");
|
||||||
|
for (int c = 0; c < jcontacts.length(); c++) {
|
||||||
|
JSONObject jcontact = (JSONObject) jcontacts.get(c);
|
||||||
|
EntityContact contact = EntityContact.fromJSON(jcontact);
|
||||||
|
contact.account = account.id;
|
||||||
|
if (db.contact().getContact(contact.account, contact.type, contact.email) == null) {
|
||||||
|
contact.id = db.contact().insertContact(contact);
|
||||||
|
Log.i("Imported contact=" + contact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update swipe left/right
|
// Update swipe left/right
|
||||||
db.account().updateAccount(account);
|
db.account().updateAccount(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contacts
|
|
||||||
JSONArray jcontacts = jimport.getJSONArray("contacts");
|
|
||||||
for (int c = 0; c < jcontacts.length(); c++) {
|
|
||||||
JSONObject jcontact = (JSONObject) jcontacts.get(c);
|
|
||||||
EntityContact contact = EntityContact.fromJSON(jcontact);
|
|
||||||
if (db.contact().getContact(contact.type, contact.email) == null) {
|
|
||||||
contact.id = db.contact().insertContact(contact);
|
|
||||||
Log.i("Imported contact=" + contact);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Answers
|
// Answers
|
||||||
JSONArray janswers = jimport.getJSONArray("answers");
|
JSONArray janswers = jimport.getJSONArray("answers");
|
||||||
for (int a = 0; a < janswers.length(); a++) {
|
for (int a = 0; a < janswers.length(); a++) {
|
||||||
|
|
|
@ -51,8 +51,8 @@ public class AdapterContact extends RecyclerView.Adapter<AdapterContact.ViewHold
|
||||||
private int textColorSecondary;
|
private int textColorSecondary;
|
||||||
|
|
||||||
private String search = null;
|
private String search = null;
|
||||||
private List<EntityContact> all = new ArrayList<>();
|
private List<TupleContactEx> all = new ArrayList<>();
|
||||||
private List<EntityContact> selected = new ArrayList<>();
|
private List<TupleContactEx> selected = new ArrayList<>();
|
||||||
|
|
||||||
private static NumberFormat nf = NumberFormat.getNumberInstance();
|
private static NumberFormat nf = NumberFormat.getNumberInstance();
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ public class AdapterContact extends RecyclerView.Adapter<AdapterContact.ViewHold
|
||||||
view.setOnLongClickListener(null);
|
view.setOnLongClickListener(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindTo(EntityContact contact) {
|
private void bindTo(TupleContactEx contact) {
|
||||||
view.setAlpha(contact.state == EntityContact.STATE_IGNORE ? Helper.LOW_LIGHT : 1.0f);
|
view.setAlpha(contact.state == EntityContact.STATE_IGNORE ? Helper.LOW_LIGHT : 1.0f);
|
||||||
|
|
||||||
if (contact.type == EntityContact.TYPE_FROM)
|
if (contact.type == EntityContact.TYPE_FROM)
|
||||||
|
@ -105,7 +105,7 @@ public class AdapterContact extends RecyclerView.Adapter<AdapterContact.ViewHold
|
||||||
ivAvatar.setImageURI(Uri.parse(contact.avatar + "/photo"));
|
ivAvatar.setImageURI(Uri.parse(contact.avatar + "/photo"));
|
||||||
|
|
||||||
tvName.setText(contact.name == null ? contact.email : contact.name);
|
tvName.setText(contact.name == null ? contact.email : contact.name);
|
||||||
tvEmail.setText(contact.email);
|
tvEmail.setText(contact.accountName + "/" + contact.email);
|
||||||
tvTimes.setText(nf.format(contact.times_contacted));
|
tvTimes.setText(nf.format(contact.times_contacted));
|
||||||
tvLast.setText(contact.last_contacted == null ? null
|
tvLast.setText(contact.last_contacted == null ? null
|
||||||
: DateUtils.getRelativeTimeSpanString(context, contact.last_contacted));
|
: DateUtils.getRelativeTimeSpanString(context, contact.last_contacted));
|
||||||
|
@ -124,7 +124,7 @@ public class AdapterContact extends RecyclerView.Adapter<AdapterContact.ViewHold
|
||||||
if (pos == RecyclerView.NO_POSITION)
|
if (pos == RecyclerView.NO_POSITION)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EntityContact contact = selected.get(pos);
|
TupleContactEx contact = selected.get(pos);
|
||||||
if (contact.state == EntityContact.STATE_DEFAULT)
|
if (contact.state == EntityContact.STATE_DEFAULT)
|
||||||
contact.state = EntityContact.STATE_FAVORITE;
|
contact.state = EntityContact.STATE_FAVORITE;
|
||||||
else
|
else
|
||||||
|
@ -166,7 +166,7 @@ public class AdapterContact extends RecyclerView.Adapter<AdapterContact.ViewHold
|
||||||
if (pos == RecyclerView.NO_POSITION)
|
if (pos == RecyclerView.NO_POSITION)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
EntityContact contact = selected.get(pos);
|
TupleContactEx contact = selected.get(pos);
|
||||||
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putLong("id", contact.id);
|
args.putLong("id", contact.id);
|
||||||
|
@ -207,18 +207,18 @@ public class AdapterContact extends RecyclerView.Adapter<AdapterContact.ViewHold
|
||||||
setHasStableIds(true);
|
setHasStableIds(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(@NonNull List<EntityContact> contacts) {
|
public void set(@NonNull List<TupleContactEx> contacts) {
|
||||||
Log.i("Set contacts=" + contacts.size());
|
Log.i("Set contacts=" + contacts.size());
|
||||||
|
|
||||||
all = contacts;
|
all = contacts;
|
||||||
|
|
||||||
List<EntityContact> items;
|
List<TupleContactEx> items;
|
||||||
if (TextUtils.isEmpty(search))
|
if (TextUtils.isEmpty(search))
|
||||||
items = all;
|
items = all;
|
||||||
else {
|
else {
|
||||||
items = new ArrayList<>();
|
items = new ArrayList<>();
|
||||||
String query = search.toLowerCase().trim();
|
String query = search.toLowerCase().trim();
|
||||||
for (EntityContact contact : contacts)
|
for (TupleContactEx contact : contacts)
|
||||||
if (contact.email.toLowerCase().contains(query) ||
|
if (contact.email.toLowerCase().contains(query) ||
|
||||||
(contact.name != null && contact.name.toLowerCase().contains(query)))
|
(contact.name != null && contact.name.toLowerCase().contains(query)))
|
||||||
items.add(contact);
|
items.add(contact);
|
||||||
|
@ -258,10 +258,10 @@ public class AdapterContact extends RecyclerView.Adapter<AdapterContact.ViewHold
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DiffCallback extends DiffUtil.Callback {
|
private class DiffCallback extends DiffUtil.Callback {
|
||||||
private List<EntityContact> prev = new ArrayList<>();
|
private List<TupleContactEx> prev = new ArrayList<>();
|
||||||
private List<EntityContact> next = new ArrayList<>();
|
private List<TupleContactEx> next = new ArrayList<>();
|
||||||
|
|
||||||
DiffCallback(List<EntityContact> prev, List<EntityContact> next) {
|
DiffCallback(List<TupleContactEx> prev, List<TupleContactEx> next) {
|
||||||
this.prev.addAll(prev);
|
this.prev.addAll(prev);
|
||||||
this.next.addAll(next);
|
this.next.addAll(next);
|
||||||
}
|
}
|
||||||
|
@ -278,15 +278,15 @@ public class AdapterContact extends RecyclerView.Adapter<AdapterContact.ViewHold
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
|
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
|
||||||
EntityContact c1 = prev.get(oldItemPosition);
|
TupleContactEx c1 = prev.get(oldItemPosition);
|
||||||
EntityContact c2 = next.get(newItemPosition);
|
TupleContactEx c2 = next.get(newItemPosition);
|
||||||
return c1.id.equals(c2.id);
|
return c1.id.equals(c2.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
|
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
|
||||||
EntityContact c1 = prev.get(oldItemPosition);
|
TupleContactEx c1 = prev.get(oldItemPosition);
|
||||||
EntityContact c2 = next.get(newItemPosition);
|
TupleContactEx c2 = next.get(newItemPosition);
|
||||||
return c1.equals(c2);
|
return c1.equals(c2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,7 +310,7 @@ public class AdapterContact extends RecyclerView.Adapter<AdapterContact.ViewHold
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
holder.unwire();
|
holder.unwire();
|
||||||
EntityContact contact = selected.get(position);
|
TupleContactEx contact = selected.get(position);
|
||||||
holder.bindTo(contact);
|
holder.bindTo(contact);
|
||||||
holder.wire();
|
holder.wire();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1259,14 +1259,16 @@ class Core {
|
||||||
String email = ((InternetAddress) recipient).getAddress();
|
String email = ((InternetAddress) recipient).getAddress();
|
||||||
String name = ((InternetAddress) recipient).getPersonal();
|
String name = ((InternetAddress) recipient).getPersonal();
|
||||||
Uri avatar = ContactInfo.getLookupUri(context, new Address[]{recipient});
|
Uri avatar = ContactInfo.getLookupUri(context, new Address[]{recipient});
|
||||||
EntityContact contact = db.contact().getContact(type, email);
|
EntityContact contact = db.contact().getContact(folder.account, type, email);
|
||||||
if (contact == null) {
|
if (contact == null) {
|
||||||
contact = new EntityContact();
|
contact = new EntityContact();
|
||||||
|
contact.account = folder.account;
|
||||||
contact.type = type;
|
contact.type = type;
|
||||||
contact.email = email;
|
contact.email = email;
|
||||||
contact.name = name;
|
contact.name = name;
|
||||||
contact.avatar = (avatar == null ? null : avatar.toString());
|
contact.avatar = (avatar == null ? null : avatar.toString());
|
||||||
contact.times_contacted = 1;
|
contact.times_contacted = 1;
|
||||||
|
contact.first_contacted = message.received;
|
||||||
contact.last_contacted = message.received;
|
contact.last_contacted = message.received;
|
||||||
contact.id = db.contact().insertContact(contact);
|
contact.id = db.contact().insertContact(contact);
|
||||||
Log.i("Inserted contact=" + contact + " type=" + type);
|
Log.i("Inserted contact=" + contact + " type=" + type);
|
||||||
|
@ -1274,6 +1276,7 @@ class Core {
|
||||||
contact.name = name;
|
contact.name = name;
|
||||||
contact.avatar = (avatar == null ? null : avatar.toString());
|
contact.avatar = (avatar == null ? null : avatar.toString());
|
||||||
contact.times_contacted++;
|
contact.times_contacted++;
|
||||||
|
contact.first_contacted = Math.min(contact.first_contacted, message.received);
|
||||||
contact.last_contacted = message.received;
|
contact.last_contacted = message.received;
|
||||||
db.contact().updateContact(contact);
|
db.contact().updateContact(contact);
|
||||||
Log.i("Updated contact=" + contact + " type=" + type);
|
Log.i("Updated contact=" + contact + " type=" + type);
|
||||||
|
|
|
@ -50,7 +50,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
|
||||||
// https://developer.android.com/topic/libraries/architecture/room.html
|
// https://developer.android.com/topic/libraries/architecture/room.html
|
||||||
|
|
||||||
@Database(
|
@Database(
|
||||||
version = 57,
|
version = 58,
|
||||||
entities = {
|
entities = {
|
||||||
EntityIdentity.class,
|
EntityIdentity.class,
|
||||||
EntityAccount.class,
|
EntityAccount.class,
|
||||||
|
@ -624,6 +624,30 @@ public abstract class DB extends RoomDatabase {
|
||||||
db.execSQL("CREATE INDEX `index_contact_favorite` ON `contact` (`favorite`)");
|
db.execSQL("CREATE INDEX `index_contact_favorite` ON `contact` (`favorite`)");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.addMigrations(new Migration(57, 58) {
|
||||||
|
@Override
|
||||||
|
public void migrate(SupportSQLiteDatabase db) {
|
||||||
|
Log.i("DB migration from version " + startVersion + " to " + endVersion);
|
||||||
|
db.execSQL("DROP TABLE `contact`");
|
||||||
|
db.execSQL("CREATE TABLE IF NOT EXISTS `contact`" +
|
||||||
|
" (`id` INTEGER PRIMARY KEY AUTOINCREMENT" +
|
||||||
|
", `account` INTEGER NOT NULL" +
|
||||||
|
", `type` INTEGER NOT NULL" +
|
||||||
|
", `email` TEXT NOT NULL" +
|
||||||
|
", `name` TEXT, `avatar` TEXT" +
|
||||||
|
", `times_contacted` INTEGER NOT NULL" +
|
||||||
|
", `first_contacted` INTEGER NOT NULL" +
|
||||||
|
", `last_contacted` INTEGER NOT NULL" +
|
||||||
|
", `state` INTEGER NOT NULL" +
|
||||||
|
", FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )");
|
||||||
|
db.execSQL("CREATE UNIQUE INDEX `index_contact_account_type_email` ON `contact` (`account`, `type`, `email`)");
|
||||||
|
db.execSQL("CREATE INDEX `index_contact_email` ON `contact` (`email`)");
|
||||||
|
db.execSQL("CREATE INDEX `index_contact_name` ON `contact` (`name`)");
|
||||||
|
db.execSQL("CREATE INDEX `index_contact_times_contacted` ON `contact` (`times_contacted`)");
|
||||||
|
db.execSQL("CREATE INDEX `index_contact_last_contacted` ON `contact` (`last_contacted`)");
|
||||||
|
db.execSQL("CREATE INDEX `index_contact_state` ON `contact` (`state`)");
|
||||||
|
}
|
||||||
|
})
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,17 +31,20 @@ import androidx.room.Update;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
public interface DaoContact {
|
public interface DaoContact {
|
||||||
@Query("SELECT * FROM contact")
|
|
||||||
List<EntityContact> getContacts();
|
|
||||||
|
|
||||||
@Query("SELECT * FROM contact" +
|
@Query("SELECT * FROM contact" +
|
||||||
|
" WHERE account = :account")
|
||||||
|
List<EntityContact> getContacts(long account);
|
||||||
|
|
||||||
|
@Query("SELECT contact.*, account.name AS accountName" +
|
||||||
|
" FROM contact" +
|
||||||
|
" JOIN account ON account.id = contact.account" +
|
||||||
" ORDER BY times_contacted DESC, last_contacted DESC")
|
" ORDER BY times_contacted DESC, last_contacted DESC")
|
||||||
LiveData<List<EntityContact>> liveContacts();
|
LiveData<List<TupleContactEx>> liveContacts();
|
||||||
|
|
||||||
@Query("SELECT * FROM contact" +
|
@Query("SELECT * FROM contact" +
|
||||||
" WHERE favorite <> " + EntityContact.STATE_IGNORE +
|
" WHERE state <> " + EntityContact.STATE_IGNORE +
|
||||||
" ORDER BY" +
|
" ORDER BY" +
|
||||||
" CASE WHEN favorite = " + EntityContact.STATE_FAVORITE + " THEN 0 ELSE 1 END" +
|
" CASE WHEN state = " + EntityContact.STATE_FAVORITE + " THEN 0 ELSE 1 END" +
|
||||||
", times_contacted DESC" +
|
", times_contacted DESC" +
|
||||||
", last_contacted DESC" +
|
", last_contacted DESC" +
|
||||||
" LIMIT :count")
|
" LIMIT :count")
|
||||||
|
@ -49,9 +52,10 @@ public interface DaoContact {
|
||||||
|
|
||||||
@Query("SELECT *" +
|
@Query("SELECT *" +
|
||||||
" FROM contact" +
|
" FROM contact" +
|
||||||
" WHERE email = :email" +
|
" WHERE account = :account" +
|
||||||
" AND (:type IS NULL OR type = :type)")
|
" AND type = :type" +
|
||||||
EntityContact getContact(Integer type, String email);
|
" AND email = :email")
|
||||||
|
EntityContact getContact(long account, int type, String email);
|
||||||
|
|
||||||
@Query("SELECT id AS _id, name, email" +
|
@Query("SELECT id AS _id, name, email" +
|
||||||
", CASE type" +
|
", CASE type" +
|
||||||
|
@ -60,9 +64,10 @@ public interface DaoContact {
|
||||||
" ELSE '?'" +
|
" ELSE '?'" +
|
||||||
" END AS type" +
|
" END AS type" +
|
||||||
" FROM contact" +
|
" FROM contact" +
|
||||||
" WHERE name LIKE :name" +
|
" WHERE (:account IS NULL OR account = :account)" +
|
||||||
" AND (:type IS NULL OR type = :type)")
|
" AND (:type IS NULL OR type = :type)" +
|
||||||
Cursor searchContacts(Integer type, String name);
|
" AND (email LIKE :query COLLATE NOCASE OR name LIKE :query COLLATE NOCASE)")
|
||||||
|
Cursor searchContacts(Long account, Integer type, String query);
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
long insertContact(EntityContact contact);
|
long insertContact(EntityContact contact);
|
||||||
|
@ -70,13 +75,13 @@ public interface DaoContact {
|
||||||
@Update
|
@Update
|
||||||
int updateContact(EntityContact contact);
|
int updateContact(EntityContact contact);
|
||||||
|
|
||||||
@Query("UPDATE contact SET favorite = :state WHERE id = :id")
|
@Query("UPDATE contact SET state = :state WHERE id = :id")
|
||||||
int setContactState(long id, int state);
|
int setContactState(long id, int state);
|
||||||
|
|
||||||
@Query("DELETE FROM contact" +
|
@Query("DELETE FROM contact" +
|
||||||
" WHERE last_contacted IS NOT NULL" +
|
" WHERE last_contacted IS NOT NULL" +
|
||||||
" AND last_contacted < :before" +
|
" AND last_contacted < :before" +
|
||||||
" AND favorite <> " + EntityContact.STATE_FAVORITE)
|
" AND state <> " + EntityContact.STATE_FAVORITE)
|
||||||
int deleteContacts(long before);
|
int deleteContacts(long before);
|
||||||
|
|
||||||
@Query("DELETE FROM contact")
|
@Query("DELETE FROM contact")
|
||||||
|
|
|
@ -27,23 +27,27 @@ import java.util.Objects;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.room.ColumnInfo;
|
|
||||||
import androidx.room.Entity;
|
import androidx.room.Entity;
|
||||||
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
|
import static androidx.room.ForeignKey.CASCADE;
|
||||||
|
|
||||||
// https://developer.android.com/training/data-storage/room/defining-data
|
// https://developer.android.com/training/data-storage/room/defining-data
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = EntityContact.TABLE_NAME,
|
tableName = EntityContact.TABLE_NAME,
|
||||||
foreignKeys = {
|
foreignKeys = {
|
||||||
|
@ForeignKey(childColumns = "account", entity = EntityAccount.class, parentColumns = "id", onDelete = CASCADE)
|
||||||
},
|
},
|
||||||
indices = {
|
indices = {
|
||||||
@Index(value = {"email", "type"}, unique = true),
|
@Index(value = {"account", "type", "email"}, unique = true),
|
||||||
@Index(value = {"name", "type"}),
|
@Index(value = {"email"}),
|
||||||
|
@Index(value = {"name"}),
|
||||||
@Index(value = {"times_contacted"}),
|
@Index(value = {"times_contacted"}),
|
||||||
@Index(value = {"last_contacted"}),
|
@Index(value = {"last_contacted"}),
|
||||||
@Index(value = {"favorite"})
|
@Index(value = {"state"})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
public class EntityContact implements Serializable {
|
public class EntityContact implements Serializable {
|
||||||
|
@ -59,6 +63,8 @@ public class EntityContact implements Serializable {
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
public Long id;
|
public Long id;
|
||||||
@NonNull
|
@NonNull
|
||||||
|
public Long account;
|
||||||
|
@NonNull
|
||||||
public int type;
|
public int type;
|
||||||
@NonNull
|
@NonNull
|
||||||
public String email;
|
public String email;
|
||||||
|
@ -67,9 +73,11 @@ public class EntityContact implements Serializable {
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public Integer times_contacted;
|
public Integer times_contacted;
|
||||||
|
@NonNull
|
||||||
|
public Long first_contacted;
|
||||||
|
@NonNull
|
||||||
public Long last_contacted;
|
public Long last_contacted;
|
||||||
@NonNull
|
@NonNull
|
||||||
@ColumnInfo(name = "favorite")
|
|
||||||
public Integer state = STATE_DEFAULT;
|
public Integer state = STATE_DEFAULT;
|
||||||
|
|
||||||
public JSONObject toJSON() throws JSONException {
|
public JSONObject toJSON() throws JSONException {
|
||||||
|
@ -80,6 +88,7 @@ public class EntityContact implements Serializable {
|
||||||
json.put("name", name);
|
json.put("name", name);
|
||||||
json.put("avatar", avatar);
|
json.put("avatar", avatar);
|
||||||
json.put("times_contacted", times_contacted);
|
json.put("times_contacted", times_contacted);
|
||||||
|
json.put("first_contacted", first_contacted);
|
||||||
json.put("last_contacted", last_contacted);
|
json.put("last_contacted", last_contacted);
|
||||||
json.put("state", state);
|
json.put("state", state);
|
||||||
return json;
|
return json;
|
||||||
|
@ -97,18 +106,10 @@ public class EntityContact implements Serializable {
|
||||||
if (json.has("avatar") && !json.isNull("avatar"))
|
if (json.has("avatar") && !json.isNull("avatar"))
|
||||||
contact.avatar = json.getString("avatar");
|
contact.avatar = json.getString("avatar");
|
||||||
|
|
||||||
if (json.has("times_contacted"))
|
contact.times_contacted = json.getInt("times_contacted");
|
||||||
contact.times_contacted = json.getInt("times_contacted");
|
contact.first_contacted = json.getLong("first_contacted");
|
||||||
else
|
contact.last_contacted = json.getLong("last_contacted");
|
||||||
contact.times_contacted = 1;
|
contact.state = json.getInt("state");
|
||||||
|
|
||||||
if (json.has("last_contacted") && !json.isNull("last_contacted"))
|
|
||||||
contact.last_contacted = json.getLong("last_contacted");
|
|
||||||
|
|
||||||
if (json.has("favorite"))
|
|
||||||
contact.state = (json.getBoolean("favorite") ? 1 : 0);
|
|
||||||
if (json.has("state"))
|
|
||||||
contact.state = json.getInt("state");
|
|
||||||
|
|
||||||
return contact;
|
return contact;
|
||||||
}
|
}
|
||||||
|
@ -117,14 +118,15 @@ public class EntityContact implements Serializable {
|
||||||
public boolean equals(@Nullable Object obj) {
|
public boolean equals(@Nullable Object obj) {
|
||||||
if (obj instanceof EntityContact) {
|
if (obj instanceof EntityContact) {
|
||||||
EntityContact other = (EntityContact) obj;
|
EntityContact other = (EntityContact) obj;
|
||||||
return (this.type == other.type &&
|
return (this.account == other.account &&
|
||||||
|
this.type == other.type &&
|
||||||
this.email.equals(other.email) &&
|
this.email.equals(other.email) &&
|
||||||
Objects.equals(this.name, other.name) &&
|
Objects.equals(this.name, other.name) &&
|
||||||
Objects.equals(this.avatar, other.avatar) &&
|
Objects.equals(this.avatar, other.avatar) &&
|
||||||
this.times_contacted.equals(other.times_contacted) &&
|
this.times_contacted.equals(other.times_contacted) &&
|
||||||
Objects.equals(this.last_contacted, other.last_contacted) &&
|
this.first_contacted.equals(first_contacted) &&
|
||||||
|
this.last_contacted.equals(last_contacted) &&
|
||||||
this.state.equals(other.state));
|
this.state.equals(other.state));
|
||||||
|
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,7 +473,7 @@ public class FragmentCompose extends FragmentBase {
|
||||||
@Override
|
@Override
|
||||||
public Cursor runQuery(CharSequence typed) {
|
public Cursor runQuery(CharSequence typed) {
|
||||||
Log.i("Searching local contact=" + typed);
|
Log.i("Searching local contact=" + typed);
|
||||||
return db.contact().searchContacts(null, "%" + typed + "%");
|
return db.contact().searchContacts(null, null, "%" + typed + "%");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -92,9 +92,9 @@ public class FragmentContacts extends FragmentBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
DB db = DB.getInstance(getContext());
|
DB db = DB.getInstance(getContext());
|
||||||
db.contact().liveContacts().observe(getViewLifecycleOwner(), new Observer<List<EntityContact>>() {
|
db.contact().liveContacts().observe(getViewLifecycleOwner(), new Observer<List<TupleContactEx>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(List<EntityContact> contacts) {
|
public void onChanged(List<TupleContactEx> contacts) {
|
||||||
if (contacts == null)
|
if (contacts == null)
|
||||||
contacts = new ArrayList<>();
|
contacts = new ArrayList<>();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package eu.faircode.email;
|
||||||
|
|
||||||
|
public class TupleContactEx extends EntityContact {
|
||||||
|
public String accountName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof TupleContactEx) {
|
||||||
|
TupleContactEx other = (TupleContactEx) obj;
|
||||||
|
return (super.equals(obj) &&
|
||||||
|
accountName.equals(other.accountName));
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue