Show send state/errors

pull/50/head
M66B 6 years ago
parent 92fc1349f0
commit ab485f8d43

@ -2,11 +2,11 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 1, "version": 1,
"identityHash": "6213f410bff60ef85d8608f09052327d", "identityHash": "23016f9b3ae09175ada077c837687ab6",
"entities": [ "entities": [
{ {
"tableName": "identity", "tableName": "identity",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `replyto` TEXT, `account` INTEGER NOT NULL, `host` TEXT NOT NULL, `port` INTEGER NOT NULL, `starttls` INTEGER NOT NULL, `user` TEXT NOT NULL, `password` TEXT NOT NULL, `primary` INTEGER NOT NULL, `synchronize` INTEGER NOT NULL, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `replyto` TEXT, `account` INTEGER NOT NULL, `host` TEXT NOT NULL, `port` INTEGER NOT NULL, `starttls` INTEGER NOT NULL, `user` TEXT NOT NULL, `password` TEXT NOT NULL, `primary` INTEGER NOT NULL, `synchronize` INTEGER NOT NULL, `state` TEXT, `error` TEXT, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -79,6 +79,18 @@
"columnName": "synchronize", "columnName": "synchronize",
"affinity": "INTEGER", "affinity": "INTEGER",
"notNull": true "notNull": true
},
{
"fieldPath": "state",
"columnName": "state",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "error",
"columnName": "error",
"affinity": "TEXT",
"notNull": false
} }
], ],
"primaryKey": { "primaryKey": {
@ -770,7 +782,7 @@
], ],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"6213f410bff60ef85d8608f09052327d\")" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"23016f9b3ae09175ada077c837687ab6\")"
] ]
} }
} }

@ -54,6 +54,7 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
ImageView ivSync; ImageView ivSync;
TextView tvUser; TextView tvUser;
TextView tvHost; TextView tvHost;
ImageView ivState;
TextView tvAccount; TextView tvAccount;
TextView tvError; TextView tvError;
@ -66,6 +67,7 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
ivSync = itemView.findViewById(R.id.ivSync); ivSync = itemView.findViewById(R.id.ivSync);
tvUser = itemView.findViewById(R.id.tvUser); tvUser = itemView.findViewById(R.id.tvUser);
tvHost = itemView.findViewById(R.id.tvHost); tvHost = itemView.findViewById(R.id.tvHost);
ivState = itemView.findViewById(R.id.ivState);
tvAccount = itemView.findViewById(R.id.tvAccount); tvAccount = itemView.findViewById(R.id.tvAccount);
tvError = itemView.findViewById(R.id.tvError); tvError = itemView.findViewById(R.id.tvError);
} }
@ -85,7 +87,17 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
tvUser.setText(identity.email); tvUser.setText(identity.email);
tvHost.setText(String.format("%s:%d", identity.host, identity.port)); tvHost.setText(String.format("%s:%d", identity.host, identity.port));
tvAccount.setText(identity.accountName); tvAccount.setText(identity.accountName);
tvError.setVisibility(View.GONE);
if ("connected".equals(identity.state))
ivState.setImageResource(R.drawable.baseline_cloud_24);
else if ("connecting".equals(identity.state))
ivState.setImageResource(R.drawable.baseline_cloud_queue_24);
else
ivState.setImageResource(R.drawable.baseline_cloud_off_24);
ivState.setVisibility(identity.synchronize ? View.VISIBLE : View.INVISIBLE);
tvError.setText(identity.error);
tvError.setVisibility(identity.error == null ? View.GONE : View.VISIBLE);
} }
@Override @Override

@ -71,7 +71,7 @@ public abstract class DB extends RoomDatabase {
private static DB sInstance; private static DB sInstance;
private static final String DB_NAME = "fairemail.db"; private static final String DB_NAME = "fairemail";
public static synchronized DB getInstance(Context context) { public static synchronized DB getInstance(Context context) {
if (sInstance == null) if (sInstance == null)

@ -51,6 +51,12 @@ public interface DaoIdentity {
@Update @Update
void updateIdentity(EntityIdentity identity); void updateIdentity(EntityIdentity identity);
@Query("UPDATE identity SET state = :state WHERE id = :id")
int setIdentityState(long id, String state);
@Query("UPDATE identity SET error = :error WHERE id = :id")
int setIdentityError(long id, String error);
@Query("UPDATE identity SET `primary` = 0") @Query("UPDATE identity SET `primary` = 0")
void resetPrimary(); void resetPrimary();

@ -61,6 +61,7 @@ public class EntityAccount {
this.password.equals(other.password) && this.password.equals(other.password) &&
this.primary.equals(other.primary) && this.primary.equals(other.primary) &&
this.synchronize.equals(other.synchronize) && this.synchronize.equals(other.synchronize) &&
(this.seen_until == null ? other.seen_until == null : this.seen_until.equals(other.seen_until)) &&
(this.state == null ? other.state == null : this.state.equals(other.state)) && (this.state == null ? other.state == null : this.state.equals(other.state)) &&
(this.error == null ? other.error == null : this.error.equals(other.error))); (this.error == null ? other.error == null : this.error.equals(other.error)));
} else } else

@ -62,6 +62,8 @@ public class EntityIdentity {
public Boolean primary; public Boolean primary;
@NonNull @NonNull
public Boolean synchronize; public Boolean synchronize;
public String state;
public String error;
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
@ -77,7 +79,9 @@ public class EntityIdentity {
this.user.equals(other.user) && this.user.equals(other.user) &&
this.password.equals(other.password) && this.password.equals(other.password) &&
this.primary.equals(other.primary) && this.primary.equals(other.primary) &&
this.synchronize.equals(other.synchronize)); this.synchronize.equals(other.synchronize) &&
(this.state == null ? other.state == null : this.state.equals(other.state)) &&
(this.error == null ? other.error == null : this.error.equals(other.error)));
} else } else
return false; return false;
} }

@ -435,6 +435,9 @@ public class FragmentAccount extends FragmentEx {
account.synchronize = synchronize; account.synchronize = synchronize;
account.primary = (account.synchronize && args.getBoolean("primary")); account.primary = (account.synchronize && args.getBoolean("primary"));
if (!synchronize)
account.error = null;
if (account.primary) if (account.primary)
db.account().resetPrimary(); db.account().resetPrimary();
@ -443,9 +446,6 @@ public class FragmentAccount extends FragmentEx {
else else
account.id = db.account().insertAccount(account); account.id = db.account().insertAccount(account);
if (!synchronize)
db.account().setAccountError(account.id, null);
List<EntityFolder> folders = new ArrayList<>(); List<EntityFolder> folders = new ArrayList<>();
EntityFolder inbox = new EntityFolder(); EntityFolder inbox = new EntityFolder();
@ -479,7 +479,7 @@ public class FragmentAccount extends FragmentEx {
} }
for (EntityFolder folder : folders) { for (EntityFolder folder : folders) {
db.folder().setFolderUser(folder.account, folder.type); db.folder().setFolderUser(account.id, folder.type);
EntityFolder existing = db.folder().getFolderByName(account.id, folder.name); EntityFolder existing = db.folder().getFolderByName(account.id, folder.name);
if (existing == null) { if (existing == null) {
folder.account = account.id; folder.account = account.id;

@ -276,6 +276,9 @@ public class FragmentIdentity extends FragmentEx {
identity.synchronize = synchronize; identity.synchronize = synchronize;
identity.primary = (identity.synchronize && args.getBoolean("primary")); identity.primary = (identity.synchronize && args.getBoolean("primary"));
if (!identity.synchronize)
identity.error = null;
if (identity.primary) if (identity.primary)
db.identity().resetPrimary(); db.identity().resetPrimary();

@ -978,7 +978,10 @@ public class ServiceSynchronize extends LifecycleService {
Transport itransport = isession.getTransport(ident.starttls ? "smtp" : "smtps"); Transport itransport = isession.getTransport(ident.starttls ? "smtp" : "smtps");
try { try {
// Connect transport // Connect transport
db.identity().setIdentityState(ident.id, "connecting");
itransport.connect(ident.host, ident.port, ident.user, ident.password); itransport.connect(ident.host, ident.port, ident.user, ident.password);
db.identity().setIdentityState(ident.id, "connected");
db.identity().setIdentityError(ident.id, null);
// Send message // Send message
Address[] to = imessage.getAllRecipients(); Address[] to = imessage.getAllRecipients();
@ -1013,8 +1016,15 @@ public class ServiceSynchronize extends LifecycleService {
} finally { } finally {
db.endTransaction(); db.endTransaction();
} }
} catch (MessagingException ex) {
db.identity().setIdentityError(ident.id, Helper.formatThrowable(ex));
throw ex;
} finally { } finally {
itransport.close(); try {
itransport.close();
} finally {
db.identity().setIdentityState(ident.id, null);
}
} }
} }

@ -50,6 +50,16 @@
app:layout_constraintStart_toEndOf="@+id/ivPrimary" app:layout_constraintStart_toEndOf="@+id/ivPrimary"
app:layout_constraintTop_toBottomOf="@id/ivSync" /> app:layout_constraintTop_toBottomOf="@id/ivSync" />
<ImageView
android:id="@+id/ivState"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="6dp"
android:layout_marginStart="6dp"
android:src="@drawable/baseline_cloud_off_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvUser" />
<TextView <TextView
android:id="@+id/tvHost" android:id="@+id/tvHost"
android:layout_width="0dp" android:layout_width="0dp"
@ -59,9 +69,10 @@
android:maxLines="1" android:maxLines="1"
android:text="host" android:text="host"
android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintBottom_toBottomOf="@id/ivState"
app:layout_constraintEnd_toStartOf="@+id/tvAccount" app:layout_constraintEnd_toStartOf="@+id/tvAccount"
app:layout_constraintStart_toEndOf="@+id/ivPrimary" app:layout_constraintStart_toEndOf="@+id/ivPrimary"
app:layout_constraintTop_toBottomOf="@id/tvUser" /> app:layout_constraintTop_toTopOf="@id/ivState" />
<TextView <TextView
android:id="@+id/tvAccount" android:id="@+id/tvAccount"
@ -72,9 +83,10 @@
android:text="account" android:text="account"
android:textAlignment="textEnd" android:textAlignment="textEnd"
android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintBottom_toBottomOf="@id/ivState"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tvHost" app:layout_constraintStart_toEndOf="@id/tvHost"
app:layout_constraintTop_toBottomOf="@id/tvUser" /> app:layout_constraintTop_toTopOf="@id/ivState" />
<TextView <TextView
android:id="@+id/tvError" android:id="@+id/tvError"

Loading…
Cancel
Save