mirror of
https://github.com/M66B/FairEmail.git
synced 2026-03-29 05:15:13 +02:00
Fixes and improvements
- Last loaders/executors have been gone - Improved debug info - Fixed multiple draft saves
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "7814b856d44afe54b8912106df1e673b",
|
||||
"identityHash": "262ca4c3e0dbf6673b00b8b19fc219de",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "identity",
|
||||
@@ -660,7 +660,7 @@
|
||||
},
|
||||
{
|
||||
"tableName": "operation",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `folder` INTEGER NOT NULL, `message` INTEGER NOT NULL, `name` TEXT NOT NULL, `args` TEXT NOT NULL, `error` TEXT, FOREIGN KEY(`folder`) REFERENCES `folder`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`message`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `folder` INTEGER NOT NULL, `message` INTEGER NOT NULL, `name` TEXT NOT NULL, `args` TEXT NOT NULL, `created` INTEGER NOT NULL, FOREIGN KEY(`folder`) REFERENCES `folder`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`message`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
@@ -693,10 +693,10 @@
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "error",
|
||||
"columnName": "error",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
"fieldPath": "created",
|
||||
"columnName": "created",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
@@ -751,7 +751,7 @@
|
||||
],
|
||||
"setupQueries": [
|
||||
"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, \"7814b856d44afe54b8912106df1e673b\")"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"262ca4c3e0dbf6673b00b8b19fc219de\")"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -40,18 +41,17 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
import androidx.recyclerview.widget.ListUpdateCallback;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class AdapterAttachment extends RecyclerView.Adapter<AdapterAttachment.ViewHolder> {
|
||||
private Context context;
|
||||
private ExecutorService executor = Executors.newCachedThreadPool();
|
||||
private LifecycleOwner owner;
|
||||
|
||||
private List<TupleAttachment> all = new ArrayList<>();
|
||||
private List<TupleAttachment> filtered = new ArrayList<>();
|
||||
@@ -140,58 +140,84 @@ public class AdapterAttachment extends RecyclerView.Adapter<AdapterAttachment.Vi
|
||||
return;
|
||||
}
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putLong("id", attachment.id);
|
||||
args.putSerializable("file", file);
|
||||
args.putSerializable("dir", dir);
|
||||
|
||||
// View
|
||||
executor.submit(new Runnable() {
|
||||
new SimpleTask<Void>() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Create file
|
||||
if (!file.exists()) {
|
||||
dir.mkdir();
|
||||
file.createNewFile();
|
||||
protected Void onLoad(Context context, Bundle args) throws Throwable {
|
||||
long id = args.getLong("id");
|
||||
File file = (File) args.getSerializable("file");
|
||||
File dir = (File) args.getSerializable("dir");
|
||||
|
||||
// Get attachment content
|
||||
byte[] content = DB.getInstance(context).attachment().getContent(attachment.id);
|
||||
// Create file
|
||||
if (!file.exists()) {
|
||||
dir.mkdir();
|
||||
file.createNewFile();
|
||||
|
||||
// Write attachment content to file
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(file);
|
||||
fos.write(content);
|
||||
} finally {
|
||||
if (fos != null)
|
||||
fos.close();
|
||||
}
|
||||
// Get attachment content
|
||||
byte[] content = DB.getInstance(context).attachment().getContent(id);
|
||||
|
||||
// Write attachment content to file
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(file);
|
||||
fos.write(content);
|
||||
} finally {
|
||||
if (fos != null)
|
||||
fos.close();
|
||||
}
|
||||
|
||||
// Start viewer
|
||||
context.startActivity(intent);
|
||||
} catch (Throwable ex) {
|
||||
Log.i(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
protected void onLoaded(Bundle args, Void data) {
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onException(Bundle args, Throwable ex) {
|
||||
Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}.load(context, owner, args);
|
||||
} else {
|
||||
if (attachment.progress == null)
|
||||
// Download
|
||||
executor.submit(new Runnable() {
|
||||
if (attachment.progress == null) {
|
||||
Bundle args = new Bundle();
|
||||
args.putLong("id", attachment.id);
|
||||
args.putLong("message", attachment.message);
|
||||
args.putInt("sequence", attachment.sequence);
|
||||
|
||||
new SimpleTask<Void>() {
|
||||
@Override
|
||||
public void run() {
|
||||
protected Void onLoad(Context context, Bundle args) {
|
||||
long id = args.getLong("id");
|
||||
long message = args.getLong("message");
|
||||
long sequence = args.getInt("sequence");
|
||||
|
||||
// No need for a transaction
|
||||
DB db = DB.getInstance(context);
|
||||
db.attachment().setProgress(attachment.id, 0);
|
||||
db.attachment().setProgress(id, 0);
|
||||
|
||||
EntityMessage message = db.message().getMessage(attachment.message);
|
||||
EntityOperation.queue(db, message, EntityOperation.ATTACHMENT, attachment.sequence);
|
||||
EntityMessage msg = db.message().getMessage(message);
|
||||
EntityOperation.queue(db, msg, EntityOperation.ATTACHMENT, sequence);
|
||||
EntityOperation.process(context);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}.load(context, owner, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AdapterAttachment(Context context) {
|
||||
AdapterAttachment(Context context, LifecycleOwner owner) {
|
||||
this.context = context;
|
||||
this.owner = owner;
|
||||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,14 @@ import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.paging.PagedListAdapter;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
@@ -39,8 +46,11 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMessage.ViewHolder> {
|
||||
private Context context;
|
||||
private LifecycleOwner owner;
|
||||
private ViewType viewType;
|
||||
|
||||
private boolean debug;
|
||||
private DateFormat df = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.LONG);
|
||||
|
||||
enum ViewType {FOLDER, THREAD}
|
||||
|
||||
@@ -87,7 +97,7 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
|
||||
pbLoading.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void bindTo(TupleMessageEx message) {
|
||||
private void bindTo(final TupleMessageEx message) {
|
||||
pbLoading.setVisibility(View.GONE);
|
||||
|
||||
if (EntityFolder.DRAFTS.equals(message.folderType) ||
|
||||
@@ -111,8 +121,25 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
|
||||
tvCount.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
message.error += (message.ui_hide ? " HIDDEN " : " ") + message.msgid + "/" + message.uid + "/" + message.id;
|
||||
if (debug) {
|
||||
DB db = DB.getInstance(context);
|
||||
db.operation().getOperationsByMessage(message.id).removeObservers(owner);
|
||||
db.operation().getOperationsByMessage(message.id).observe(owner, new Observer<List<EntityOperation>>() {
|
||||
@Override
|
||||
public void onChanged(List<EntityOperation> operations) {
|
||||
String text = message.error +
|
||||
"\n" + message.id + " " + df.format(new Date(message.received)) +
|
||||
"\n" + (message.ui_hide ? "HIDDEN " : " ") + message.uid + "/" + message.id +
|
||||
"\n" + message.msgid;
|
||||
for (EntityOperation op : operations)
|
||||
text += "\n" + op.name + " " + df.format(new Date(op.created));
|
||||
|
||||
tvError.setText(text);
|
||||
tvError.setVisibility(View.VISIBLE);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
tvError.setText(message.error);
|
||||
tvError.setVisibility(message.error == null ? View.GONE : View.VISIBLE);
|
||||
@@ -165,9 +192,10 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
|
||||
}
|
||||
}
|
||||
|
||||
AdapterMessage(Context context, ViewType viewType) {
|
||||
AdapterMessage(Context context, LifecycleOwner owner, ViewType viewType) {
|
||||
super(DIFF_CALLBACK);
|
||||
this.context = context;
|
||||
this.owner = owner;
|
||||
this.viewType = viewType;
|
||||
this.debug = PreferenceManager.getDefaultSharedPreferences(context).getBoolean("debug", false);
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ public interface DaoMessage {
|
||||
@Query("SELECT uid FROM message WHERE folder = :folder AND received >= :received AND NOT uid IS NULL")
|
||||
List<Long> getUids(long folder, long received);
|
||||
|
||||
// in case of duplicate message IDs
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
long insertMessage(EntityMessage message);
|
||||
|
||||
|
||||
@@ -21,15 +21,18 @@ package eu.faircode.email;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.Query;
|
||||
import androidx.room.Update;
|
||||
|
||||
@Dao
|
||||
public interface DaoOperation {
|
||||
@Query("SELECT * FROM operation WHERE message = :message ORDER BY id")
|
||||
LiveData<List<EntityOperation>> getOperationsByMessage(long message);
|
||||
|
||||
@Query("SELECT * FROM operation WHERE folder = :folder ORDER BY id")
|
||||
List<EntityOperation> getOperations(long folder);
|
||||
List<EntityOperation> getOperationsByFolder(long folder);
|
||||
|
||||
@Query("SELECT COUNT(id) FROM operation WHERE folder = :folder")
|
||||
int getOperationCount(long folder);
|
||||
@@ -37,9 +40,6 @@ public interface DaoOperation {
|
||||
@Insert
|
||||
long insertOperation(EntityOperation operation);
|
||||
|
||||
@Update
|
||||
void updateOperation(EntityOperation operation);
|
||||
|
||||
@Query("DELETE FROM operation WHERE id = :id")
|
||||
void deleteOperation(long id);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.util.Log;
|
||||
import org.json.JSONArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -61,7 +62,8 @@ public class EntityOperation {
|
||||
public String name;
|
||||
@NonNull
|
||||
public String args;
|
||||
public String error;
|
||||
@NonNull
|
||||
public Long created;
|
||||
|
||||
public static final String SEEN = "seen";
|
||||
public static final String ADD = "add";
|
||||
@@ -96,6 +98,7 @@ public class EntityOperation {
|
||||
operation.message = message.id;
|
||||
operation.name = name;
|
||||
operation.args = jsonArray.toString();
|
||||
operation.created = new Date().getTime();
|
||||
operation.id = db.operation().insertOperation(operation);
|
||||
|
||||
Intent intent = new Intent();
|
||||
@@ -129,8 +132,7 @@ public class EntityOperation {
|
||||
return (this.folder.equals(other.folder) &&
|
||||
this.message.equals(other.message) &&
|
||||
this.name.equals(other.name) &&
|
||||
this.args.equals(other.args) &&
|
||||
(this.error == null ? other.error == null : this.error.equals(other.error)));
|
||||
this.args.equals(other.args));
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ public class FragmentCompose extends FragmentEx {
|
||||
LinearLayoutManager llm = new LinearLayoutManager(getContext());
|
||||
rvAttachment.setLayoutManager(llm);
|
||||
|
||||
adapter = new AdapterAttachment(getContext());
|
||||
adapter = new AdapterAttachment(getContext(), getViewLifecycleOwner());
|
||||
rvAttachment.setAdapter(adapter);
|
||||
|
||||
return view;
|
||||
@@ -757,36 +757,40 @@ public class FragmentCompose extends FragmentEx {
|
||||
EntityOperation.queue(db, draft, EntityOperation.MOVE, trash.id);
|
||||
|
||||
} else if (action == R.id.action_save) {
|
||||
// Save message ID
|
||||
String msgid = draft.msgid;
|
||||
if (draft.uid == null)
|
||||
db.message().updateMessage(draft);
|
||||
else {
|
||||
// Save message ID
|
||||
String msgid = draft.msgid;
|
||||
|
||||
// Save attachments
|
||||
List<EntityAttachment> attachments = db.attachment().getAttachments(draft.id);
|
||||
for (EntityAttachment attachment : attachments)
|
||||
attachment.content = db.attachment().getContent(attachment.id);
|
||||
// Save attachments
|
||||
List<EntityAttachment> attachments = db.attachment().getAttachments(draft.id);
|
||||
for (EntityAttachment attachment : attachments)
|
||||
attachment.content = db.attachment().getContent(attachment.id);
|
||||
|
||||
// Delete previous draft
|
||||
draft.msgid = null;
|
||||
draft.ui_hide = true;
|
||||
db.message().updateMessage(draft);
|
||||
// Delete previous draft
|
||||
draft.msgid = null;
|
||||
draft.ui_hide = true;
|
||||
db.message().updateMessage(draft);
|
||||
|
||||
EntityOperation.queue(db, draft, EntityOperation.DELETE);
|
||||
EntityOperation.queue(db, draft, EntityOperation.DELETE);
|
||||
|
||||
// Create new draft
|
||||
draft.id = null;
|
||||
draft.uid = null;
|
||||
draft.msgid = msgid;
|
||||
draft.ui_hide = false;
|
||||
draft.id = db.message().insertMessage(draft);
|
||||
// Create new draft
|
||||
draft.id = null;
|
||||
draft.uid = null;
|
||||
draft.msgid = msgid;
|
||||
draft.ui_hide = false;
|
||||
draft.id = db.message().insertMessage(draft);
|
||||
|
||||
// Restore attachments
|
||||
for (EntityAttachment attachment : attachments) {
|
||||
attachment.message = draft.id;
|
||||
db.attachment().insertAttachment(attachment);
|
||||
// Restore attachments
|
||||
for (EntityAttachment attachment : attachments) {
|
||||
attachment.message = draft.id;
|
||||
db.attachment().insertAttachment(attachment);
|
||||
}
|
||||
|
||||
EntityOperation.queue(db, draft, EntityOperation.ADD);
|
||||
}
|
||||
|
||||
EntityOperation.queue(db, draft, EntityOperation.ADD);
|
||||
|
||||
} else if (action == R.id.action_send) {
|
||||
// Check data
|
||||
if (draft.identity == null)
|
||||
|
||||
@@ -66,7 +66,6 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class FragmentMessage extends FragmentEx {
|
||||
private boolean debug;
|
||||
private TextView tvFrom;
|
||||
private TextView tvTime;
|
||||
private TextView tvSubject;
|
||||
@@ -86,6 +85,7 @@ public class FragmentMessage extends FragmentEx {
|
||||
|
||||
private AdapterAttachment adapter;
|
||||
|
||||
private boolean debug;
|
||||
private DateFormat df = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
|
||||
|
||||
@Override
|
||||
@@ -93,11 +93,10 @@ public class FragmentMessage extends FragmentEx {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_message, container, false);
|
||||
|
||||
this.debug = PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean("debug", false);
|
||||
|
||||
// Get arguments
|
||||
Bundle args = getArguments();
|
||||
final long id = (args == null ? -1 : args.getLong("id"));
|
||||
debug = PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean("debug", false);
|
||||
|
||||
// Get controls
|
||||
tvFrom = view.findViewById(R.id.tvFrom);
|
||||
@@ -226,7 +225,7 @@ public class FragmentMessage extends FragmentEx {
|
||||
LinearLayoutManager llm = new LinearLayoutManager(getContext());
|
||||
rvAttachment.setLayoutManager(llm);
|
||||
|
||||
adapter = new AdapterAttachment(getContext());
|
||||
adapter = new AdapterAttachment(getContext(), getViewLifecycleOwner());
|
||||
rvAttachment.setAdapter(adapter);
|
||||
|
||||
return view;
|
||||
@@ -246,21 +245,19 @@ public class FragmentMessage extends FragmentEx {
|
||||
db.message().liveMessage(id).observe(getViewLifecycleOwner(), new Observer<TupleMessageEx>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable final TupleMessageEx message) {
|
||||
if (message == null || message.ui_hide) {
|
||||
if (message == null || (!(debug && BuildConfig.DEBUG) && message.ui_hide)) {
|
||||
// Message gone (moved, deleted)
|
||||
if (FragmentMessage.this.isVisible())
|
||||
getFragmentManager().popBackStack();
|
||||
} else {
|
||||
setSubtitle(Helper.localizeFolderName(getContext(), message.folderName));
|
||||
|
||||
String extra = (debug ? (message.ui_hide ? "HIDDEN " : "") + message.uid + "/" + message.id + " " : "");
|
||||
|
||||
tvFrom.setText(message.from == null ? null : MessageHelper.getFormattedAddresses(message.from, true));
|
||||
tvTime.setText(message.sent == null ? null : df.format(new Date(message.sent)));
|
||||
tvSubject.setText(message.subject);
|
||||
|
||||
tvCount.setText(extra + Integer.toString(message.count));
|
||||
tvCount.setVisibility(debug || message.count > 1 ? View.VISIBLE : View.GONE);
|
||||
tvCount.setText(Integer.toString(message.count));
|
||||
tvCount.setVisibility(message.count > 1 ? View.VISIBLE : View.GONE);
|
||||
|
||||
tvTo.setText(message.to == null ? null : MessageHelper.getFormattedAddresses(message.to, true));
|
||||
tvCc.setText(message.cc == null ? null : MessageHelper.getFormattedAddresses(message.cc, true));
|
||||
@@ -287,9 +284,6 @@ public class FragmentMessage extends FragmentEx {
|
||||
}
|
||||
});
|
||||
|
||||
if (debug)
|
||||
message.error += (message.ui_hide ? " HIDDEN " : " ") + message.msgid + "/" + message.uid + "/" + message.id;
|
||||
|
||||
tvError.setText(message.error);
|
||||
tvError.setVisibility(message.error == null ? View.GONE : View.VISIBLE);
|
||||
|
||||
@@ -629,12 +623,16 @@ public class FragmentMessage extends FragmentEx {
|
||||
try {
|
||||
db.beginTransaction();
|
||||
|
||||
EntityMessage message = db.message().getMessage(id);
|
||||
message.ui_hide = true;
|
||||
db.message().updateMessage(message);
|
||||
if (debug && BuildConfig.DEBUG)
|
||||
db.message().deleteMessage(id);
|
||||
else {
|
||||
EntityMessage message = db.message().getMessage(id);
|
||||
message.ui_hide = true;
|
||||
db.message().updateMessage(message);
|
||||
|
||||
EntityFolder trash = db.folder().getFolderByType(message.account, EntityFolder.TRASH);
|
||||
EntityOperation.queue(db, message, EntityOperation.MOVE, trash.id);
|
||||
EntityFolder trash = db.folder().getFolderByType(message.account, EntityFolder.TRASH);
|
||||
EntityOperation.queue(db, message, EntityOperation.MOVE, trash.id);
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
|
||||
@@ -76,7 +76,9 @@ public class FragmentMessages extends FragmentEx {
|
||||
LinearLayoutManager llm = new LinearLayoutManager(getContext());
|
||||
rvMessage.setLayoutManager(llm);
|
||||
|
||||
adapter = new AdapterMessage(getContext(),
|
||||
adapter = new AdapterMessage(
|
||||
getContext(),
|
||||
getViewLifecycleOwner(),
|
||||
thread < 0
|
||||
? AdapterMessage.ViewType.FOLDER
|
||||
: AdapterMessage.ViewType.THREAD);
|
||||
|
||||
@@ -710,7 +710,7 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
Log.i(Helper.TAG, folder.name + " start process");
|
||||
|
||||
DB db = DB.getInstance(this);
|
||||
List<EntityOperation> ops = db.operation().getOperations(folder.id);
|
||||
List<EntityOperation> ops = db.operation().getOperationsByFolder(folder.id);
|
||||
Log.i(Helper.TAG, folder.name + " pending operations=" + ops.size());
|
||||
for (EntityOperation op : ops)
|
||||
try {
|
||||
@@ -719,11 +719,12 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
" msg=" + op.message +
|
||||
" args=" + op.args);
|
||||
|
||||
EntityMessage message = db.message().getMessage(op.message);
|
||||
if (message == null)
|
||||
throw new MessageRemovedException();
|
||||
|
||||
try {
|
||||
JSONArray jargs = new JSONArray(op.args);
|
||||
EntityMessage message = db.message().getMessage(op.message);
|
||||
if (message == null)
|
||||
throw new MessageRemovedException();
|
||||
|
||||
if (EntityOperation.SEEN.equals(op.name))
|
||||
doSeen(folder, ifolder, message, jargs);
|
||||
@@ -735,7 +736,7 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
doMove(folder, isession, istore, ifolder, message, jargs, db);
|
||||
|
||||
else if (EntityOperation.DELETE.equals(op.name))
|
||||
doDelete(folder, ifolder, message, db);
|
||||
doDelete(folder, ifolder, message, jargs, db);
|
||||
|
||||
else if (EntityOperation.SEND.equals(op.name))
|
||||
doSend(db, message);
|
||||
@@ -749,8 +750,8 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
// Operation succeeded
|
||||
db.operation().deleteOperation(op.id);
|
||||
} catch (Throwable ex) {
|
||||
op.error = Helper.formatThrowable(ex);
|
||||
db.operation().updateOperation(op);
|
||||
message.error = Helper.formatThrowable(ex);
|
||||
db.message().updateMessage(message);
|
||||
|
||||
if (BuildConfig.DEBUG && ex instanceof NullPointerException) {
|
||||
db.operation().deleteOperation(op.id);
|
||||
@@ -786,9 +787,8 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
|
||||
private void doSeen(EntityFolder folder, IMAPFolder ifolder, EntityMessage message, JSONArray jargs) throws MessagingException, JSONException {
|
||||
// Mark message (un)seen
|
||||
|
||||
if (message.uid == null) {
|
||||
Log.w(Helper.TAG, folder.name + " local op seen id=" + message.id + " uid=" + message.uid);
|
||||
Log.w(Helper.TAG, folder.name + " local op seen id=" + message.id);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -814,12 +814,8 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
|
||||
private void doMove(EntityFolder folder, Session isession, IMAPStore istore, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws JSONException, MessagingException {
|
||||
// Move message
|
||||
|
||||
if (BuildConfig.DEBUG && message.uid == null) {
|
||||
Log.w(Helper.TAG, "Move local message id=" + message.id);
|
||||
db.message().deleteMessage(message.id);
|
||||
return;
|
||||
}
|
||||
if (message.uid == null)
|
||||
throw new IllegalArgumentException("MOVE local id=" + message.id);
|
||||
|
||||
long id = jargs.getLong(0);
|
||||
EntityFolder target = db.folder().getFolder(id);
|
||||
@@ -850,18 +846,17 @@ public class ServiceSynchronize extends LifecycleService {
|
||||
}
|
||||
}
|
||||
|
||||
private void doDelete(EntityFolder folder, IMAPFolder ifolder, EntityMessage message, DB db) throws MessagingException {
|
||||
private void doDelete(EntityFolder folder, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws MessagingException, JSONException {
|
||||
// Delete message
|
||||
if (message.uid == null)
|
||||
Log.w(Helper.TAG, folder.name + " Delete local message id=" + message.id);
|
||||
else {
|
||||
Message imessage = ifolder.getMessageByUID(message.uid);
|
||||
if (imessage == null)
|
||||
throw new MessageRemovedException();
|
||||
throw new IllegalArgumentException("DELETE local id=" + message.id);
|
||||
|
||||
imessage.setFlag(Flags.Flag.DELETED, true);
|
||||
ifolder.expunge();
|
||||
}
|
||||
Message imessage = ifolder.getMessageByUID(message.uid);
|
||||
if (imessage == null)
|
||||
throw new MessageRemovedException();
|
||||
|
||||
imessage.setFlag(Flags.Flag.DELETED, true);
|
||||
ifolder.expunge();
|
||||
|
||||
db.message().deleteMessage(message.id);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,10 @@ import androidx.lifecycle.OnLifecycleEvent;
|
||||
public abstract class SimpleTask<T> implements LifecycleObserver {
|
||||
private boolean alive = true;
|
||||
|
||||
public void load(Context context, LifecycleOwner owner, Bundle args) {
|
||||
run(context, owner, args);
|
||||
}
|
||||
|
||||
public void load(AppCompatActivity activity, Bundle args) {
|
||||
run(activity, activity, args);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:text="error"
|
||||
android:text="error\ndebug info\noperation 1\n operation 2"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
||||
Reference in New Issue
Block a user