Added option to auto delete old trashed messages

This commit is contained in:
M66B 2019-05-01 11:26:32 +02:00
parent 71daa71624
commit dc70bc540c
8 changed files with 1805 additions and 24 deletions

File diff suppressed because it is too large Load Diff

View File

@ -843,6 +843,7 @@ class Core {
int sync_days = jargs.getInt(0);
int keep_days = jargs.getInt(1);
boolean download = jargs.getBoolean(2);
boolean auto_delete = (jargs.length() > 3 && jargs.getBoolean(3));
if (keep_days == sync_days)
keep_days++;
@ -877,8 +878,18 @@ class Core {
Log.i(folder.name + " sync=" + new Date(sync_time) + " keep=" + new Date(keep_time));
// Delete old local messages
int old = db.message().deleteMessagesBefore(folder.id, keep_time);
Log.i(folder.name + " local old=" + old);
if (auto_delete && EntityFolder.TRASH.equals(folder.type)) {
List<Long> tbds = db.message().getMessagesBefore(folder.id, keep_time);
Log.i(folder.name + " local tbd=" + tbds.size());
for (Long tbd : tbds) {
EntityMessage message = db.message().getMessage(tbd);
if (message != null)
EntityOperation.queue(context, db, message, EntityOperation.DELETE);
}
} else {
int old = db.message().deleteMessagesBefore(folder.id, keep_time);
Log.i(folder.name + " local old=" + old);
}
// Get list of local uids
final List<Long> uids = db.message().getUids(folder.id, null);

View File

@ -51,7 +51,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
// https://developer.android.com/topic/libraries/architecture/room.html
@Database(
version = 77,
version = 78,
entities = {
EntityIdentity.class,
EntityAccount.class,
@ -787,6 +787,13 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `folder` ADD COLUMN `read_only` INTEGER NOT NULL DEFAULT 0");
}
})
.addMigrations(new Migration(77, 78) {
@Override
public void migrate(SupportSQLiteDatabase db) {
Log.i("DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `folder` ADD COLUMN `auto_delete` INTEGER NOT NULL DEFAULT 0");
}
})
.build();
}

View File

@ -210,12 +210,13 @@ public interface DaoFolder {
", download = :download" +
", `sync_days` = :sync_days" +
", `keep_days` = :keep_days" +
", auto_delete = :auto_delete" +
" WHERE id = :id")
int setFolderProperties(
long id,
String display, boolean unified, boolean navigation, boolean notify, boolean hide,
boolean synchronize, boolean poll, boolean download,
int sync_days, int keep_days);
int sync_days, int keep_days, boolean auto_delete);
@Query("UPDATE folder SET keywords = :keywords WHERE id = :id")
int setFolderKeywords(long id, String keywords);

View File

@ -421,6 +421,13 @@ public interface DaoMessage {
" AND operation.name = '" + EntityOperation.ADD + "')")
int deleteOrphans(long folder);
@Query("SELECT id FROM message" +
" WHERE folder = :folder" +
" AND received < :received" +
" AND NOT uid IS NULL" +
" AND NOT ui_flagged")
List<Long> getMessagesBefore(long folder, long received);
@Query("DELETE FROM message" +
" WHERE folder = :folder" +
" AND received < :received" +

View File

@ -83,6 +83,8 @@ public class EntityFolder extends EntityOrder implements Serializable {
public Integer sync_days;
@NonNull
public Integer keep_days;
@NonNull
public Boolean auto_delete = false;
public String display;
@NonNull
public Boolean hide = false;
@ -189,6 +191,7 @@ public class EntityFolder extends EntityOrder implements Serializable {
jargs.put(initialize ? Math.min(DEFAULT_INIT, keep_days) : days);
jargs.put(keep_days);
jargs.put(download);
jargs.put(auto_delete);
return jargs;
}
@ -322,6 +325,7 @@ public class EntityFolder extends EntityOrder implements Serializable {
json.put("download", download);
json.put("sync_days", sync_days);
json.put("keep_days", keep_days);
json.put("auto_delete", auto_delete);
json.put("display", display);
json.put("hide", hide);
json.put("collapsed", collapsed);
@ -357,6 +361,9 @@ public class EntityFolder extends EntityOrder implements Serializable {
else
folder.keep_days = folder.sync_days;
if (json.has("auto_delete"))
folder.auto_delete = json.getBoolean("auto_delete");
if (json.has("display") && !json.isNull("display"))
folder.display = json.getString("display");

View File

@ -42,8 +42,6 @@ import androidx.annotation.Nullable;
import com.google.android.material.snackbar.Snackbar;
import java.util.Calendar;
public class FragmentFolder extends FragmentBase {
private ViewGroup view;
private EditText etName;
@ -58,6 +56,7 @@ public class FragmentFolder extends FragmentBase {
private EditText etSyncDays;
private EditText etKeepDays;
private CheckBox cbKeepAll;
private CheckBox cbAutoDelete;
private Button btnSave;
private ContentLoadingProgressBar pbSave;
private ContentLoadingProgressBar pbWait;
@ -99,6 +98,7 @@ public class FragmentFolder extends FragmentBase {
etSyncDays = view.findViewById(R.id.etSyncDays);
etKeepDays = view.findViewById(R.id.etKeepDays);
cbKeepAll = view.findViewById(R.id.cbKeepAll);
cbAutoDelete = view.findViewById(R.id.cbAutoDelete);
btnSave = view.findViewById(R.id.btnSave);
pbSave = view.findViewById(R.id.pbSave);
pbWait = view.findViewById(R.id.pbWait);
@ -126,6 +126,7 @@ public class FragmentFolder extends FragmentBase {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
etKeepDays.setEnabled(!isChecked);
cbAutoDelete.setEnabled(!isChecked);
}
});
@ -138,6 +139,7 @@ public class FragmentFolder extends FragmentBase {
// Initialize
Helper.setViewsEnabled(view, false);
cbAutoDelete.setVisibility(View.GONE);
btnSave.setEnabled(false);
pbSave.setVisibility(View.GONE);
pbWait.setVisibility(View.VISIBLE);
@ -162,6 +164,7 @@ public class FragmentFolder extends FragmentBase {
args.putString("keep", cbKeepAll.isChecked()
? Integer.toString(Integer.MAX_VALUE)
: etKeepDays.getText().toString());
args.putBoolean("auto_delete", cbAutoDelete.isChecked());
new SimpleTask<Void>() {
@Override
@ -195,6 +198,7 @@ public class FragmentFolder extends FragmentBase {
boolean download = args.getBoolean("download");
String sync = args.getString("sync");
String keep = args.getString("keep");
boolean auto_delete = args.getBoolean("auto_delete");
if (TextUtils.isEmpty(display) || display.equals(name))
display = null;
@ -241,25 +245,9 @@ public class FragmentFolder extends FragmentBase {
db.folder().setFolderProperties(id,
display, unified, navigation, notify, hide,
synchronize, poll, download,
sync_days, keep_days);
sync_days, keep_days, auto_delete);
db.folder().setFolderError(id, null);
if (keep_days == sync_days)
keep_days++;
Calendar cal_keep = Calendar.getInstance();
cal_keep.add(Calendar.DAY_OF_MONTH, -keep_days);
cal_keep.set(Calendar.HOUR_OF_DAY, 12);
cal_keep.set(Calendar.MINUTE, 0);
cal_keep.set(Calendar.SECOND, 0);
cal_keep.set(Calendar.MILLISECOND, 0);
long keep_time = cal_keep.getTimeInMillis();
if (keep_time < 0)
keep_time = 0;
db.message().deleteMessagesBefore(id, keep_time);
EntityOperation.sync(context, folder.id, true);
}
@ -429,15 +417,20 @@ public class FragmentFolder extends FragmentBase {
cbKeepAll.setChecked(true);
else
etKeepDays.setText(Integer.toString(folder == null ? EntityFolder.DEFAULT_KEEP : folder.keep_days));
cbAutoDelete.setChecked(folder == null ? false : folder.auto_delete);
cbAutoDelete.setVisibility(folder != null && EntityFolder.TRASH.equals(folder.type) ? View.VISIBLE : View.GONE);
}
// Consider previous save as cancelled
pbWait.setVisibility(View.GONE);
Helper.setViewsEnabled(view, true);
etName.setEnabled(folder == null);
cbPoll.setEnabled(cbSynchronize.isChecked());
cbDownload.setEnabled(cbSynchronize.isChecked());
etKeepDays.setEnabled(!cbKeepAll.isChecked());
cbAutoDelete.setEnabled(!cbKeepAll.isChecked());
btnSave.setEnabled(true);
subscribed = (folder == null ? null : folder.subscribed != null && folder.subscribed);

View File

@ -182,6 +182,14 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etKeepDays" />
<CheckBox
android:id="@+id/cbAutoDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_auto_delete"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbKeepAll" />
<Button
android:id="@+id/btnSave"
android:layout_width="wrap_content"
@ -190,7 +198,7 @@
android:tag="disable"
android:text="@string/title_save"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbKeepAll" />
app:layout_constraintTop_toBottomOf="@id/cbAutoDelete" />
<eu.faircode.email.ContentLoadingProgressBar
android:id="@+id/pbSave"