mirror of
https://github.com/M66B/FairEmail.git
synced 2026-01-04 11:54:10 +01:00
Improved operation handling/display
This commit is contained in:
@@ -60,7 +60,7 @@ public class AdapterOperation extends RecyclerView.Adapter<AdapterOperation.View
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
|
||||
this.itemView = itemView;
|
||||
this.itemView = itemView.findViewById(R.id.clItem);
|
||||
tvFolder = itemView.findViewById(R.id.tvFolder);
|
||||
tvMessage = itemView.findViewById(R.id.tvMessage);
|
||||
tvOperation = itemView.findViewById(R.id.tvOperation);
|
||||
@@ -77,6 +77,8 @@ public class AdapterOperation extends RecyclerView.Adapter<AdapterOperation.View
|
||||
}
|
||||
|
||||
private void bindTo(TupleOperationEx operation) {
|
||||
itemView.setAlpha(operation.synchronize ? 1.0f : Helper.LOW_LIGHT);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(operation.name);
|
||||
try {
|
||||
|
||||
@@ -28,24 +28,36 @@ import androidx.room.Query;
|
||||
|
||||
@Dao
|
||||
public interface DaoOperation {
|
||||
@Query("SELECT * FROM operation" +
|
||||
" WHERE folder = :folder" +
|
||||
@Query("SELECT operation.*, account.name AS accountName, folder.name AS folderName" +
|
||||
" ,((account.synchronize IS NULL OR account.synchronize)" +
|
||||
" AND (NOT folder.account IS NULL OR identity.synchronize)) AS synchronize" +
|
||||
" FROM operation" +
|
||||
" JOIN folder ON folder.id = operation.folder" +
|
||||
" LEFT JOIN message ON message.id = operation.message" +
|
||||
" LEFT JOIN account ON account.id = message.account" +
|
||||
" LEFT JOIN identity ON identity.id = message.identity" +
|
||||
" ORDER BY" +
|
||||
" CASE WHEN name = '" + EntityOperation.SYNC + "' THEN" +
|
||||
" CASE WHEN :outbox THEN -1 ELSE 1 END" +
|
||||
" CASE WHEN operation.name = '" + EntityOperation.SYNC + "' THEN" +
|
||||
" CASE WHEN folder.account IS NULL THEN -1 ELSE 1 END" + // outbox
|
||||
" ELSE 0" +
|
||||
" END" +
|
||||
", id")
|
||||
List<EntityOperation> getOperationsByFolder(long folder, boolean outbox);
|
||||
|
||||
@Query("SELECT operation.*, account.name AS accountName, folder.name AS folderName" +
|
||||
" FROM operation" +
|
||||
" JOIN folder ON folder.id = operation.folder" +
|
||||
" LEFT JOIN account ON account.id = folder.account" +
|
||||
" ORDER BY operation.id")
|
||||
LiveData<List<TupleOperationEx>> liveOperations();
|
||||
|
||||
@Query("SELECT * FROM operation WHERE folder = :folder ORDER BY id")
|
||||
@Query("SELECT operation.* FROM operation" +
|
||||
" JOIN folder ON folder.id = operation.folder" +
|
||||
" LEFT JOIN message ON message.id = operation.message" +
|
||||
" LEFT JOIN account ON account.id = message.account" +
|
||||
" LEFT JOIN identity ON identity.id = message.identity" +
|
||||
" WHERE operation.folder = :folder" +
|
||||
" AND (account.synchronize IS NULL OR account.synchronize)" +
|
||||
" AND (NOT folder.account IS NULL OR identity.synchronize)" +
|
||||
" ORDER BY" +
|
||||
" CASE WHEN operation.name = '" + EntityOperation.SYNC + "' THEN" +
|
||||
" CASE WHEN folder.account IS NULL THEN -1 ELSE 1 END" + // outbox
|
||||
" ELSE 0" +
|
||||
" END" +
|
||||
", id")
|
||||
LiveData<List<EntityOperation>> liveOperations(long folder);
|
||||
|
||||
@Query("SELECT * FROM operation ORDER BY id")
|
||||
|
||||
@@ -1189,7 +1189,7 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":folder." + folder.id);
|
||||
|
||||
@Override
|
||||
public void onChanged(List<EntityOperation> operations) {
|
||||
public void onChanged(final List<EntityOperation> operations) {
|
||||
boolean process = false;
|
||||
List<Long> current = new ArrayList<>();
|
||||
for (EntityOperation op : operations) {
|
||||
@@ -1229,7 +1229,7 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
db.folder().setFolderError(folder.id, null);
|
||||
}
|
||||
|
||||
processOperations(account, folder, isession, istore, ifolder, state);
|
||||
processOperations(account, folder, operations, isession, istore, ifolder, state);
|
||||
|
||||
} catch (Throwable ex) {
|
||||
Log.e(folder.name, ex);
|
||||
@@ -1432,13 +1432,14 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
}
|
||||
}
|
||||
|
||||
private void processOperations(EntityAccount account, EntityFolder folder, Session isession, IMAPStore istore, IMAPFolder ifolder, ServiceState state) throws MessagingException, JSONException, IOException {
|
||||
private void processOperations(
|
||||
EntityAccount account, EntityFolder folder, List<EntityOperation> ops, Session isession,
|
||||
IMAPStore istore, IMAPFolder ifolder, ServiceState state)
|
||||
throws MessagingException, JSONException, IOException {
|
||||
try {
|
||||
Log.i(folder.name + " start process");
|
||||
|
||||
DB db = DB.getInstance(this);
|
||||
List<EntityOperation> ops = db.operation().getOperationsByFolder(
|
||||
folder.id, EntityFolder.OUTBOX.equals(folder.type));
|
||||
Log.i(folder.name + " pending operations=" + ops.size());
|
||||
for (int i = 0; i < ops.size() && state.running(); i++) {
|
||||
EntityOperation op = ops.get(i);
|
||||
@@ -1866,11 +1867,8 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
private void doSend(EntityMessage message, DB db) throws MessagingException, IOException {
|
||||
// Send message
|
||||
EntityIdentity ident = db.identity().getIdentity(message.identity);
|
||||
if (!ident.synchronize) {
|
||||
// Message will remain in outbox
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark attempt
|
||||
if (message.last_attempt == null) {
|
||||
message.last_attempt = new Date().getTime();
|
||||
db.message().setMessageLastAttempt(message.id, message.last_attempt);
|
||||
@@ -3005,7 +3003,7 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":outbox");
|
||||
|
||||
@Override
|
||||
public void onChanged(List<EntityOperation> operations) {
|
||||
public void onChanged(final List<EntityOperation> operations) {
|
||||
boolean process = false;
|
||||
List<Long> current = new ArrayList<>();
|
||||
for (EntityOperation op : operations) {
|
||||
@@ -3025,7 +3023,7 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
Log.i(outbox.name + " process");
|
||||
|
||||
db.folder().setFolderSyncState(outbox.id, "syncing");
|
||||
processOperations(null, outbox, null, null, null, state);
|
||||
processOperations(null, outbox, operations, null, null, null, state);
|
||||
db.folder().setFolderError(outbox.id, null);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(outbox.name, ex);
|
||||
|
||||
@@ -22,6 +22,7 @@ package eu.faircode.email;
|
||||
public class TupleOperationEx extends EntityOperation {
|
||||
public String accountName;
|
||||
public String folderName;
|
||||
public boolean synchronize;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
@@ -29,7 +30,8 @@ public class TupleOperationEx extends EntityOperation {
|
||||
TupleOperationEx other = (TupleOperationEx) obj;
|
||||
return (super.equals(obj) &&
|
||||
(this.accountName == null ? other.accountName == null : accountName.equals(other.accountName)) &&
|
||||
(this.folderName == null ? other.folderName == null : this.folderName.equals(other.folderName)));
|
||||
(this.folderName == null ? other.folderName == null : this.folderName.equals(other.folderName)) &&
|
||||
this.synchronize == other.synchronize);
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,74 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout 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="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginBottom="3dp">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvFolder"
|
||||
android:layout_width="120dp"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/clItem"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="start"
|
||||
android:singleLine="true"
|
||||
android:text="Folder"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginBottom="3dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMessage"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:gravity="end"
|
||||
android:text="1234567"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintStart_toEndOf="@id/tvFolder"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<TextView
|
||||
android:id="@+id/tvFolder"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="start"
|
||||
android:singleLine="true"
|
||||
android:text="Folder"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvOperation"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="Name"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintEnd_toStartOf="@+id/tvTime"
|
||||
app:layout_constraintStart_toEndOf="@id/tvMessage"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<TextView
|
||||
android:id="@+id/tvMessage"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:gravity="end"
|
||||
android:text="1234567"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintStart_toEndOf="@id/tvFolder"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:text="Time"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<TextView
|
||||
android:id="@+id/tvOperation"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="Name"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintEnd_toStartOf="@+id/tvTime"
|
||||
app:layout_constraintStart_toEndOf="@id/tvMessage"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/barrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="bottom"
|
||||
app:constraint_referenced_ids="tvFolder,tvMessage,tvOperation,tvTime" />
|
||||
<TextView
|
||||
android:id="@+id/tvTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:text="Time"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvError"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:text="error"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textColor="?attr/colorWarning"
|
||||
android:textIsSelectable="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/barrier" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/barrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="bottom"
|
||||
app:constraint_referenced_ids="tvFolder,tvMessage,tvOperation,tvTime" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvError"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:text="error"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textColor="?attr/colorWarning"
|
||||
android:textIsSelectable="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/barrier" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</FrameLayout>
|
||||
Reference in New Issue
Block a user