mirror of
https://github.com/M66B/FairEmail.git
synced 2025-03-03 02:05:36 +00:00
Added undo
This commit is contained in:
parent
5af0dd9708
commit
198d9fba0f
7 changed files with 1746 additions and 11 deletions
1687
app/schemas/eu.faircode.email.DB/67.json
Normal file
1687
app/schemas/eu.faircode.email.DB/67.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -51,7 +51,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
|
|||
// https://developer.android.com/topic/libraries/architecture/room.html
|
||||
|
||||
@Database(
|
||||
version = 66,
|
||||
version = 67,
|
||||
entities = {
|
||||
EntityIdentity.class,
|
||||
EntityAccount.class,
|
||||
|
@ -709,6 +709,13 @@ public abstract class DB extends RoomDatabase {
|
|||
db.execSQL("ALTER TABLE `message` ADD COLUMN `receipt_request` INTEGER");
|
||||
}
|
||||
})
|
||||
.addMigrations(new Migration(66, 67) {
|
||||
@Override
|
||||
public void migrate(SupportSQLiteDatabase db) {
|
||||
Log.i("DB migration from version " + startVersion + " to " + endVersion);
|
||||
db.execSQL("ALTER TABLE `message` ADD COLUMN `revision` INTEGER");
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -333,6 +333,9 @@ public interface DaoMessage {
|
|||
@Query("UPDATE message SET error = :error WHERE id = :id")
|
||||
int setMessageError(long id, String error);
|
||||
|
||||
@Query("UPDATE message SET revision = :revision WHERE id = :id")
|
||||
int setMessageRevision(long id, Integer revision);
|
||||
|
||||
@Query("UPDATE message SET content = :content, preview = :preview, warning = :warning WHERE id = :id")
|
||||
int setMessageContent(long id, boolean content, String preview, String warning);
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ public class EntityMessage implements Serializable {
|
|||
@NonNull
|
||||
public Boolean ui_browsed = false;
|
||||
public Long ui_snoozed;
|
||||
public Integer revision; // compose
|
||||
public String warning; // persistent
|
||||
public String error; // volatile
|
||||
public Long last_attempt; // send
|
||||
|
@ -157,6 +158,13 @@ public class EntityMessage implements Serializable {
|
|||
return new File(dir, id.toString());
|
||||
}
|
||||
|
||||
File getFile(Context context, int revision) {
|
||||
File dir = new File(context.getFilesDir(), "revision");
|
||||
if (!dir.exists())
|
||||
dir.mkdir();
|
||||
return new File(dir, id + "." + revision);
|
||||
}
|
||||
|
||||
File getRefFile(Context context) {
|
||||
File dir = new File(context.getFilesDir(), "references");
|
||||
if (!dir.exists())
|
||||
|
|
|
@ -1914,6 +1914,8 @@ public class FragmentCompose extends FragmentBase {
|
|||
grpHeader.setVisibility(View.VISIBLE);
|
||||
grpAddresses.setVisibility("reply_all".equals(action) ? View.VISIBLE : View.GONE);
|
||||
|
||||
bottom_navigation.getMenu().findItem(R.id.action_undo).setEnabled(draft.revision != null);
|
||||
|
||||
getActivity().invalidateOptionsMenu();
|
||||
|
||||
new SimpleTask<List<TupleIdentityEx>>() {
|
||||
|
@ -2165,8 +2167,7 @@ public class FragmentCompose extends FragmentBase {
|
|||
!MessageHelper.equal(draft.cc, acc) ||
|
||||
!MessageHelper.equal(draft.bcc, abcc) ||
|
||||
!Objects.equals(draft.subject, subject) ||
|
||||
last_available != available ||
|
||||
!body.equals(Helper.readText(draft.getFile(context))));
|
||||
last_available != available);
|
||||
|
||||
last_available = available;
|
||||
|
||||
|
@ -2180,13 +2181,35 @@ public class FragmentCompose extends FragmentBase {
|
|||
draft.bcc = abcc;
|
||||
draft.subject = subject;
|
||||
draft.received = new Date().getTime();
|
||||
|
||||
draft.sender = MessageHelper.getSortKey(draft.from);
|
||||
Uri lookupUri = ContactInfo.getLookupUri(context, draft.from);
|
||||
draft.avatar = (lookupUri == null ? null : lookupUri.toString());
|
||||
|
||||
db.message().updateMessage(draft);
|
||||
}
|
||||
|
||||
String previous = Helper.readText(draft.getFile(context));
|
||||
if (!body.equals(previous) || action == R.id.action_undo) {
|
||||
dirty = true;
|
||||
|
||||
if (action == R.id.action_undo) {
|
||||
body = Helper.readText(draft.getFile(context, draft.revision));
|
||||
|
||||
if (draft.revision > 1)
|
||||
draft.revision--;
|
||||
else
|
||||
draft.revision = null;
|
||||
} else {
|
||||
if (draft.revision == null)
|
||||
draft.revision = 1;
|
||||
else
|
||||
draft.revision++;
|
||||
|
||||
Helper.writeText(draft.getFile(context, draft.revision), previous);
|
||||
}
|
||||
|
||||
Helper.writeText(draft.getFile(context), body);
|
||||
|
||||
db.message().setMessageRevision(draft.id, draft.revision);
|
||||
db.message().setMessageContent(draft.id, true, HtmlHelper.getPreview(body), null);
|
||||
|
||||
Core.updateMessageSize(context, draft.id);
|
||||
|
@ -2230,7 +2253,7 @@ public class FragmentCompose extends FragmentBase {
|
|||
}
|
||||
});
|
||||
}
|
||||
} else if (action == R.id.action_save || action == R.id.menu_encrypt) {
|
||||
} else if (action == R.id.action_save || action == R.id.action_undo || action == R.id.menu_encrypt) {
|
||||
if (BuildConfig.DEBUG || dirty)
|
||||
EntityOperation.queue(context, db, draft, EntityOperation.ADD);
|
||||
|
||||
|
@ -2310,10 +2333,15 @@ public class FragmentCompose extends FragmentBase {
|
|||
etCc.setText(MessageHelper.formatAddressesCompose(draft.cc));
|
||||
etBcc.setText(MessageHelper.formatAddressesCompose(draft.bcc));
|
||||
|
||||
bottom_navigation.getMenu().findItem(R.id.action_undo).setEnabled(draft.revision != null);
|
||||
|
||||
if (action == R.id.action_delete) {
|
||||
autosave = false;
|
||||
finish();
|
||||
|
||||
} else if (action == R.id.action_undo) {
|
||||
showDraft(draft);
|
||||
|
||||
} else if (action == R.id.action_save) {
|
||||
// Do nothing
|
||||
|
||||
|
@ -2396,7 +2424,7 @@ public class FragmentCompose extends FragmentBase {
|
|||
}.execute(FragmentCompose.this, args, "compose:show");
|
||||
}
|
||||
|
||||
private void showDraft(EntityMessage draft) {
|
||||
private void showDraft(final EntityMessage draft) {
|
||||
Bundle args = new Bundle();
|
||||
args.putLong("id", draft.id);
|
||||
args.putBoolean("show_images", show_images);
|
||||
|
@ -2411,6 +2439,7 @@ public class FragmentCompose extends FragmentBase {
|
|||
edit_bar.setVisibility(style ? View.VISIBLE : View.GONE);
|
||||
bottom_navigation.setVisibility(View.VISIBLE);
|
||||
Helper.setViewsEnabled(view, true);
|
||||
bottom_navigation.getMenu().findItem(R.id.action_undo).setEnabled(draft.revision != null);
|
||||
|
||||
getActivity().invalidateOptionsMenu();
|
||||
}
|
||||
|
@ -2420,7 +2449,6 @@ public class FragmentCompose extends FragmentBase {
|
|||
final long id = args.getLong("id");
|
||||
final boolean show_images = args.getBoolean("show_images", false);
|
||||
|
||||
|
||||
DB db = DB.getInstance(context);
|
||||
EntityMessage draft = db.message().getMessage(id);
|
||||
if (draft == null)
|
||||
|
|
|
@ -70,11 +70,14 @@ public class WorkerCleanup extends Worker {
|
|||
|
||||
List<File> files = new ArrayList<>();
|
||||
File[] messages = new File(context.getFilesDir(), "messages").listFiles();
|
||||
File[] revision = new File(context.getFilesDir(), "revision").listFiles();
|
||||
File[] references = new File(context.getFilesDir(), "references").listFiles();
|
||||
File[] raws = new File(context.getFilesDir(), "raw").listFiles();
|
||||
|
||||
if (messages != null)
|
||||
files.addAll(Arrays.asList(messages));
|
||||
if (revision != null)
|
||||
files.addAll(Arrays.asList(revision));
|
||||
if (references != null)
|
||||
files.addAll(Arrays.asList(references));
|
||||
if (raws != null)
|
||||
|
@ -83,7 +86,7 @@ public class WorkerCleanup extends Worker {
|
|||
// Cleanup message files
|
||||
Log.i("Cleanup message files");
|
||||
for (File file : files) {
|
||||
long id = Long.parseLong(file.getName());
|
||||
long id = Long.parseLong(file.getName().split("\\.")[0]);
|
||||
if (db.message().countMessage(id) == 0) {
|
||||
Log.i("Deleting " + file);
|
||||
if (!file.delete())
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
<item
|
||||
android:id="@+id/action_undo"
|
||||
android:icon="@drawable/baseline_undo_24"
|
||||
android:title="@string/title_undo"
|
||||
android:visible="false" />
|
||||
android:title="@string/title_undo" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_send"
|
||||
|
|
Loading…
Reference in a new issue