Browse Source

Move by APPEND/DELETE if no MOVE capability

main
M66B 6 years ago
parent
commit
0aaf2e948f
6 changed files with 22 additions and 58 deletions
  1. +0
    -8
      app/src/main/java/eu/faircode/email/AdapterAccount.java
  2. +1
    -10
      app/src/main/java/eu/faircode/email/DB.java
  3. +0
    -2
      app/src/main/java/eu/faircode/email/EntityAccount.java
  4. +3
    -16
      app/src/main/java/eu/faircode/email/FragmentMessage.java
  5. +17
    -11
      app/src/main/java/eu/faircode/email/ServiceSynchronize.java
  6. +1
    -11
      app/src/main/res/layout/item_account.xml

+ 0
- 8
app/src/main/java/eu/faircode/email/AdapterAccount.java View File

@ -21,13 +21,11 @@ package eu.faircode.email;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.util.DiffUtil; import android.support.v7.util.DiffUtil;
import android.support.v7.util.ListUpdateCallback; import android.support.v7.util.ListUpdateCallback;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -44,7 +42,6 @@ import java.util.Locale;
public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHolder> { public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHolder> {
private Context context; private Context context;
private boolean debug;
private List<EntityAccount> all = new ArrayList<>(); private List<EntityAccount> all = new ArrayList<>();
private List<EntityAccount> filtered = new ArrayList<>(); private List<EntityAccount> filtered = new ArrayList<>();
@ -56,7 +53,6 @@ public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHold
ImageView ivSync; ImageView ivSync;
TextView tvHost; TextView tvHost;
TextView tvUser; TextView tvUser;
TextView tvCapabilities;
ViewHolder(View itemView) { ViewHolder(View itemView) {
super(itemView); super(itemView);
@ -67,7 +63,6 @@ public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHold
ivSync = itemView.findViewById(R.id.ivSync); ivSync = itemView.findViewById(R.id.ivSync);
tvHost = itemView.findViewById(R.id.tvHost); tvHost = itemView.findViewById(R.id.tvHost);
tvUser = itemView.findViewById(R.id.tvUser); tvUser = itemView.findViewById(R.id.tvUser);
tvCapabilities = itemView.findViewById(R.id.tvCapabilities);
} }
private void wire() { private void wire() {
@ -94,7 +89,6 @@ public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHold
AdapterAccount(Context context) { AdapterAccount(Context context) {
this.context = context; this.context = context;
this.debug = PreferenceManager.getDefaultSharedPreferences(context).getBoolean("debug", false);
setHasStableIds(true); setHasStableIds(true);
} }
@ -204,8 +198,6 @@ public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHold
holder.ivSync.setVisibility(account.synchronize ? View.VISIBLE : View.INVISIBLE); holder.ivSync.setVisibility(account.synchronize ? View.VISIBLE : View.INVISIBLE);
holder.tvHost.setText(String.format("%s:%d", account.host, account.port)); holder.tvHost.setText(String.format("%s:%d", account.host, account.port));
holder.tvUser.setText(account.user); holder.tvUser.setText(account.user);
holder.tvCapabilities.setText(TextUtils.join(", ", account.capabilities));
holder.tvCapabilities.setVisibility(debug ? View.VISIBLE : View.GONE);
holder.wire(); holder.wire();
} }


+ 1
- 10
app/src/main/java/eu/faircode/email/DB.java View File

@ -41,7 +41,7 @@ import android.util.Log;
EntityAttachment.class, EntityAttachment.class,
EntityOperation.class EntityOperation.class
}, },
version = 5,
version = 4,
exportSchema = true exportSchema = true
) )
@ -78,7 +78,6 @@ public abstract class DB extends RoomDatabase {
.addMigrations(MIGRATION_1_2) .addMigrations(MIGRATION_1_2)
.addMigrations(MIGRATION_2_3) .addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4) .addMigrations(MIGRATION_3_4)
.addMigrations(MIGRATION_4_5)
.build(); .build();
} }
@ -114,14 +113,6 @@ public abstract class DB extends RoomDatabase {
} }
}; };
private static final Migration MIGRATION_4_5 = new Migration(4, 5) {
@Override
public void migrate(SupportSQLiteDatabase db) {
Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `account` ADD COLUMN `capabilities` TEXT NOT NULL DEFAULT ''");
}
};
public static class Converters { public static class Converters {
@TypeConverter @TypeConverter
public static String[] fromStringArray(String value) { public static String[] fromStringArray(String value) {


+ 0
- 2
app/src/main/java/eu/faircode/email/EntityAccount.java View File

@ -46,8 +46,6 @@ public class EntityAccount {
public Boolean primary; public Boolean primary;
@NonNull @NonNull
public Boolean synchronize; public Boolean synchronize;
@NonNull
public String[] capabilities;
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {


+ 3
- 16
app/src/main/java/eu/faircode/email/FragmentMessage.java View File

@ -25,7 +25,6 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.constraint.Group; import android.support.constraint.Group;
@ -57,7 +56,6 @@ import android.widget.TextView;
import java.text.Collator; import java.text.Collator;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
@ -212,13 +210,12 @@ public class FragmentMessage extends FragmentEx {
rvAttachment.setAdapter(adapter); rvAttachment.setAdapter(adapter);
final DB db = DB.getInstance(getContext()); final DB db = DB.getInstance(getContext());
final boolean debug = PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean("debug", false);
// Observe message // Observe message
db.message().liveMessage(id).observe(this, new Observer<TupleMessageEx>() { db.message().liveMessage(id).observe(this, new Observer<TupleMessageEx>() {
@Override @Override
public void onChanged(@Nullable final TupleMessageEx message) { public void onChanged(@Nullable final TupleMessageEx message) {
if (message == null || (message.ui_hide && !debug)) {
if (message == null || message.ui_hide) {
// Message gone (moved, deleted) // Message gone (moved, deleted)
if (FragmentMessage.this.isVisible()) if (FragmentMessage.this.isVisible())
getFragmentManager().popBackStack(); getFragmentManager().popBackStack();
@ -266,7 +263,7 @@ public class FragmentMessage extends FragmentEx {
db.folder().liveFolders(message.account).removeObservers(FragmentMessage.this); db.folder().liveFolders(message.account).removeObservers(FragmentMessage.this);
db.folder().liveFolders(message.account).observe(FragmentMessage.this, new Observer<List<EntityFolder>>() { db.folder().liveFolders(message.account).observe(FragmentMessage.this, new Observer<List<EntityFolder>>() {
@Override @Override
public void onChanged(@Nullable List<EntityFolder> folders) {
public void onChanged(@Nullable final List<EntityFolder> folders) {
boolean hasTrash = false; boolean hasTrash = false;
boolean hasJunk = false; boolean hasJunk = false;
boolean hasArchive = false; boolean hasArchive = false;
@ -287,19 +284,9 @@ public class FragmentMessage extends FragmentEx {
bottom_navigation.getMenu().findItem(R.id.action_trash).setVisible(hasTrash); bottom_navigation.getMenu().findItem(R.id.action_trash).setVisible(hasTrash);
bottom_navigation.getMenu().findItem(R.id.action_spam).setVisible(!outbox && hasJunk); bottom_navigation.getMenu().findItem(R.id.action_spam).setVisible(!outbox && hasJunk);
bottom_navigation.getMenu().findItem(R.id.action_move).setVisible(false);
bottom_navigation.getMenu().findItem(R.id.action_move).setVisible(!outbox && (!inbox || hasUser));
bottom_navigation.getMenu().findItem(R.id.action_archive).setVisible(!outbox && hasArchive); bottom_navigation.getMenu().findItem(R.id.action_archive).setVisible(!outbox && hasArchive);
bottom_navigation.setVisibility(View.VISIBLE); bottom_navigation.setVisibility(View.VISIBLE);
final boolean fHasUser = hasUser;
db.account().liveAccount(message.id).removeObservers(FragmentMessage.this);
db.account().liveAccount(message.account).observe(FragmentMessage.this, new Observer<EntityAccount>() {
@Override
public void onChanged(@Nullable EntityAccount account) {
boolean move = Arrays.asList(account.capabilities).contains("MOVE");
bottom_navigation.getMenu().findItem(R.id.action_move).setVisible(!outbox && (!inbox || fHasUser) && move);
}
});
} }
}); });
} }


+ 17
- 11
app/src/main/java/eu/faircode/email/ServiceSynchronize.java View File

@ -336,15 +336,6 @@ public class ServiceSynchronize extends LifecycleService {
try { try {
DB db = DB.getInstance(ServiceSynchronize.this); DB db = DB.getInstance(ServiceSynchronize.this);
List<String> capabilities = new ArrayList<>();
if (fstore.hasCapability("IDLE"))
capabilities.add("IDLE");
if (fstore.hasCapability("MOVE"))
capabilities.add("MOVE");
account.capabilities = capabilities.toArray(new String[0]);
db.account().updateAccount(account);
Log.i(Helper.TAG, "capabilities=" + TextUtils.join(",", capabilities));
synchronizeFolders(account, fstore); synchronizeFolders(account, fstore);
for (final EntityFolder folder : db.folder().getFolders(account.id, true)) { for (final EntityFolder folder : db.folder().getFolders(account.id, true)) {
@ -739,7 +730,22 @@ public class ServiceSynchronize extends LifecycleService {
throw new MessageRemovedException(); throw new MessageRemovedException();
Folder itarget = istore.getFolder(target.name); Folder itarget = istore.getFolder(target.name);
ifolder.moveMessages(new Message[]{imessage}, itarget);
if (istore.hasCapability("MOVE"))
ifolder.moveMessages(new Message[]{imessage}, itarget);
else {
Log.i(Helper.TAG, "MOVE by APPEND/DELETE");
EntityMessage msg = message.getMessage(op.message);
// Execute append
Properties props = MessageHelper.getSessionProperties();
Session isession = Session.getInstance(props, null);
MimeMessage icopy = MessageHelper.from(msg, isession);
itarget.appendMessages(new Message[]{icopy});
// Execute delete
imessage.setFlag(Flags.Flag.DELETED, true);
ifolder.expunge();
}
message.deleteMessage(op.message); message.deleteMessage(op.message);
@ -872,7 +878,7 @@ public class ServiceSynchronize extends LifecycleService {
} catch (NullPointerException ex) { } catch (NullPointerException ex) {
Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
// There is probably no use in repeating
// There is no use in repeating
operation.deleteOperation(op.id); operation.deleteOperation(op.id);
reportError(null, folder.name, ex); reportError(null, folder.name, ex);
} }


+ 1
- 11
app/src/main/res/layout/item_account.xml View File

@ -61,16 +61,6 @@
app:layout_constraintStart_toEndOf="@id/tvHost" app:layout_constraintStart_toEndOf="@id/tvHost"
app:layout_constraintTop_toBottomOf="@id/ivSync" /> app:layout_constraintTop_toBottomOf="@id/ivSync" />
<TextView
android:id="@+id/tvCapabilities"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:text="capabilities"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvHost" />
<View <View
android:id="@+id/vSeparator" android:id="@+id/vSeparator"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -78,5 +68,5 @@
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:background="?attr/colorSeparator" android:background="?attr/colorSeparator"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvCapabilities" />
app:layout_constraintTop_toBottomOf="@id/tvHost" />
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>

Loading…
Cancel
Save