mirror of https://github.com/M66B/FairEmail.git
Added create folder to rule move
This commit is contained in:
parent
dd6d2ba33b
commit
320748e689
|
@ -1399,6 +1399,7 @@ class Core {
|
||||||
boolean seen = jargs.optBoolean(1);
|
boolean seen = jargs.optBoolean(1);
|
||||||
boolean unflag = jargs.optBoolean(3);
|
boolean unflag = jargs.optBoolean(3);
|
||||||
boolean delete = jargs.optBoolean(4);
|
boolean delete = jargs.optBoolean(4);
|
||||||
|
boolean create = jargs.optBoolean(5);
|
||||||
|
|
||||||
Flags flags = ifolder.getPermanentFlags();
|
Flags flags = ifolder.getPermanentFlags();
|
||||||
|
|
||||||
|
@ -1411,6 +1412,20 @@ class Core {
|
||||||
if (!target.selectable)
|
if (!target.selectable)
|
||||||
throw new IllegalArgumentException("not selectable type=" + target.type);
|
throw new IllegalArgumentException("not selectable type=" + target.type);
|
||||||
|
|
||||||
|
if (create) {
|
||||||
|
Folder icreate = istore.getFolder(target.name);
|
||||||
|
if (!icreate.exists()) {
|
||||||
|
((IMAPFolder) ifolder).doCommand(new IMAPFolder.ProtocolCommand() {
|
||||||
|
@Override
|
||||||
|
public Object doCommand(IMAPProtocol protocol) throws ProtocolException {
|
||||||
|
protocol.create(target.name);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ifolder.setSubscribed(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// De-classify
|
// De-classify
|
||||||
if (!copy &&
|
if (!copy &&
|
||||||
!EntityFolder.TRASH.equals(target.type) &&
|
!EntityFolder.TRASH.equals(target.type) &&
|
||||||
|
@ -2625,6 +2640,8 @@ class Core {
|
||||||
folder.download = parent.download;
|
folder.download = parent.download;
|
||||||
folder.auto_classify_source = parent.auto_classify_source;
|
folder.auto_classify_source = parent.auto_classify_source;
|
||||||
folder.auto_classify_target = parent.auto_classify_target;
|
folder.auto_classify_target = parent.auto_classify_target;
|
||||||
|
folder.sync_days = parent.sync_days;
|
||||||
|
folder.keep_days = parent.keep_days;
|
||||||
folder.unified = parent.unified;
|
folder.unified = parent.unified;
|
||||||
folder.navigation = parent.navigation;
|
folder.navigation = parent.navigation;
|
||||||
folder.notify = parent.notify;
|
folder.notify = parent.notify;
|
||||||
|
@ -2845,7 +2862,7 @@ class Core {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void onRule(Context context, JSONArray jargs, EntityMessage message) throws JSONException, IOException, AddressException {
|
private static void onRule(Context context, JSONArray jargs, EntityMessage message) throws JSONException, MessagingException {
|
||||||
// Download message body
|
// Download message body
|
||||||
DB db = DB.getInstance(context);
|
DB db = DB.getInstance(context);
|
||||||
|
|
||||||
|
|
|
@ -609,18 +609,71 @@ public class EntityRule {
|
||||||
|
|
||||||
private boolean onActionMove(Context context, EntityMessage message, JSONObject jargs) {
|
private boolean onActionMove(Context context, EntityMessage message, JSONObject jargs) {
|
||||||
long target = jargs.optLong("target", -1);
|
long target = jargs.optLong("target", -1);
|
||||||
|
String create = jargs.optString("create");
|
||||||
boolean seen = jargs.optBoolean("seen");
|
boolean seen = jargs.optBoolean("seen");
|
||||||
boolean thread = jargs.optBoolean("thread");
|
boolean thread = jargs.optBoolean("thread");
|
||||||
|
|
||||||
DB db = DB.getInstance(context);
|
DB db = DB.getInstance(context);
|
||||||
|
|
||||||
EntityFolder folder = db.folder().getFolder(target);
|
EntityFolder folder = db.folder().getFolder(target);
|
||||||
if (folder == null)
|
if (folder == null)
|
||||||
throw new IllegalArgumentException("Rule move to folder not found name=" + name);
|
throw new IllegalArgumentException("Rule move to folder not found name=" + name);
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(create)) {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
String year = String.format(Locale.ROOT, "%04d", calendar.get(Calendar.YEAR));
|
||||||
|
String month = String.format(Locale.ROOT, "%02d", calendar.get(Calendar.MONTH) + 1);
|
||||||
|
|
||||||
|
create = create.replace("$year$", year);
|
||||||
|
create = create.replace("$month$", month);
|
||||||
|
|
||||||
|
String domain = "";
|
||||||
|
if (message.from != null &&
|
||||||
|
message.from.length > 0 &&
|
||||||
|
message.from[0] instanceof InternetAddress) {
|
||||||
|
InternetAddress from = (InternetAddress) message.from[0];
|
||||||
|
domain = UriHelper.getEmailDomain(from.getAddress());
|
||||||
|
}
|
||||||
|
create = create.replace("$domain$", domain);
|
||||||
|
|
||||||
|
String name = folder.name + folder.separator + create;
|
||||||
|
EntityFolder created = db.folder().getFolderByName(message.account, name);
|
||||||
|
if (created == null) {
|
||||||
|
created = new EntityFolder();
|
||||||
|
created.tbc = true;
|
||||||
|
created.account = folder.account;
|
||||||
|
created.namespace = folder.namespace;
|
||||||
|
created.separator = folder.separator;
|
||||||
|
created.name = name;
|
||||||
|
created.type = EntityFolder.USER;
|
||||||
|
created.subscribed = true;
|
||||||
|
created.setProperties();
|
||||||
|
|
||||||
|
EntityAccount account = db.account().getAccount(folder.account);
|
||||||
|
created.setSpecials(account);
|
||||||
|
|
||||||
|
created.synchronize = folder.synchronize;
|
||||||
|
created.poll = folder.poll;
|
||||||
|
created.poll_factor = folder.poll_factor;
|
||||||
|
created.download = folder.download;
|
||||||
|
created.auto_classify_source = folder.auto_classify_source;
|
||||||
|
created.auto_classify_target = folder.auto_classify_target;
|
||||||
|
created.sync_days = folder.sync_days;
|
||||||
|
created.keep_days = folder.keep_days;
|
||||||
|
created.unified = folder.unified;
|
||||||
|
created.navigation = folder.navigation;
|
||||||
|
created.notify = folder.notify;
|
||||||
|
|
||||||
|
created.id = db.folder().insertFolder(created);
|
||||||
|
}
|
||||||
|
target = created.id;
|
||||||
|
}
|
||||||
|
|
||||||
List<EntityMessage> messages = db.message().getMessagesByThread(
|
List<EntityMessage> messages = db.message().getMessagesByThread(
|
||||||
message.account, message.thread, thread ? null : message.id, message.folder);
|
message.account, message.thread, thread ? null : message.id, message.folder);
|
||||||
for (EntityMessage threaded : messages)
|
for (EntityMessage threaded : messages)
|
||||||
EntityOperation.queue(context, threaded, EntityOperation.MOVE, target, seen, null, true);
|
EntityOperation.queue(context, threaded, EntityOperation.MOVE, target,
|
||||||
|
seen, null, true, false, !TextUtils.isEmpty(create));
|
||||||
|
|
||||||
message.ui_hide = true;
|
message.ui_hide = true;
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,7 @@ public class FragmentRule extends FragmentBase {
|
||||||
private EditText etKeyword;
|
private EditText etKeyword;
|
||||||
|
|
||||||
private Button btnFolder;
|
private Button btnFolder;
|
||||||
|
private EditText etMoveCreate;
|
||||||
private CheckBox cbMoveSeen;
|
private CheckBox cbMoveSeen;
|
||||||
private CheckBox cbMoveThread;
|
private CheckBox cbMoveThread;
|
||||||
|
|
||||||
|
@ -290,6 +291,7 @@ public class FragmentRule extends FragmentBase {
|
||||||
etKeyword = view.findViewById(R.id.etKeyword);
|
etKeyword = view.findViewById(R.id.etKeyword);
|
||||||
|
|
||||||
btnFolder = view.findViewById(R.id.btnFolder);
|
btnFolder = view.findViewById(R.id.btnFolder);
|
||||||
|
etMoveCreate = view.findViewById(R.id.etMoveCreate);
|
||||||
cbMoveSeen = view.findViewById(R.id.cbMoveSeen);
|
cbMoveSeen = view.findViewById(R.id.cbMoveSeen);
|
||||||
cbMoveThread = view.findViewById(R.id.cbMoveThread);
|
cbMoveThread = view.findViewById(R.id.cbMoveThread);
|
||||||
|
|
||||||
|
@ -1170,6 +1172,7 @@ public class FragmentRule extends FragmentBase {
|
||||||
long target = jaction.optLong("target", -1);
|
long target = jaction.optLong("target", -1);
|
||||||
showFolder(target);
|
showFolder(target);
|
||||||
if (type == EntityRule.TYPE_MOVE) {
|
if (type == EntityRule.TYPE_MOVE) {
|
||||||
|
etMoveCreate.setText(jaction.optString("create"));
|
||||||
cbMoveSeen.setChecked(jaction.optBoolean("seen"));
|
cbMoveSeen.setChecked(jaction.optBoolean("seen"));
|
||||||
cbMoveThread.setChecked(jaction.optBoolean("thread"));
|
cbMoveThread.setChecked(jaction.optBoolean("thread"));
|
||||||
}
|
}
|
||||||
|
@ -1525,6 +1528,7 @@ public class FragmentRule extends FragmentBase {
|
||||||
Object tag = btnFolder.getTag();
|
Object tag = btnFolder.getTag();
|
||||||
jaction.put("target", tag instanceof Long ? (long) tag : -1);
|
jaction.put("target", tag instanceof Long ? (long) tag : -1);
|
||||||
if (action.type == EntityRule.TYPE_MOVE) {
|
if (action.type == EntityRule.TYPE_MOVE) {
|
||||||
|
jaction.put("create", etMoveCreate.getText().toString().trim());
|
||||||
jaction.put("seen", cbMoveSeen.isChecked());
|
jaction.put("seen", cbMoveSeen.isChecked());
|
||||||
jaction.put("thread", cbMoveThread.isChecked());
|
jaction.put("thread", cbMoveThread.isChecked());
|
||||||
}
|
}
|
||||||
|
|
|
@ -786,6 +786,37 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tvMoveTarget" />
|
app:layout_constraintTop_toBottomOf="@id/tvMoveTarget" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvMoveCreate"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:text="@string/title_rule_folder_create"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/btnFolder" />
|
||||||
|
|
||||||
|
<eu.faircode.email.EditTextPlain
|
||||||
|
android:id="@+id/etMoveCreate"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/title_optional"
|
||||||
|
android:inputType="text"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tvMoveCreate" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvMoveCreateRemark"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="$year$ $month$ $domain$"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
|
android:textStyle="italic"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/etMoveCreate" />
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:id="@+id/cbMoveSeen"
|
android:id="@+id/cbMoveSeen"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -793,7 +824,7 @@
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:text="@string/title_rule_seen"
|
android:text="@string/title_rule_seen"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/btnFolder" />
|
app:layout_constraintTop_toBottomOf="@id/tvMoveCreateRemark" />
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:id="@+id/cbMoveThread"
|
android:id="@+id/cbMoveThread"
|
||||||
|
@ -873,7 +904,6 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:hint="@string/title_optional"
|
|
||||||
android:text="@string/title_rule_forward_to"
|
android:text="@string/title_rule_forward_to"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
@ -883,6 +913,7 @@
|
||||||
android:id="@+id/etTo"
|
android:id="@+id/etTo"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/title_optional"
|
||||||
android:inputType="textEmailAddress"
|
android:inputType="textEmailAddress"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/ibTo"
|
app:layout_constraintEnd_toStartOf="@+id/ibTo"
|
||||||
|
@ -992,6 +1023,7 @@
|
||||||
android:layout_marginTop="6dp"
|
android:layout_marginTop="6dp"
|
||||||
android:text="@string/title_rule_alarm_hint"
|
android:text="@string/title_rule_alarm_hint"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
|
android:textStyle="italic"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/cbAlarm" />
|
app:layout_constraintTop_toBottomOf="@+id/cbAlarm" />
|
||||||
|
|
||||||
|
@ -1026,6 +1058,7 @@
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:text="@string/title_rule_automation_hint"
|
android:text="@string/title_rule_automation_hint"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
|
android:textStyle="italic"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/etAlarmDuration" />
|
app:layout_constraintTop_toBottomOf="@+id/etAlarmDuration" />
|
||||||
|
|
||||||
|
@ -1036,11 +1069,11 @@
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:drawableStart="@drawable/twotone_warning_24"
|
android:drawableStart="@drawable/twotone_warning_24"
|
||||||
android:drawablePadding="6dp"
|
android:drawablePadding="6dp"
|
||||||
app:drawableTint="?attr/colorWarning"
|
|
||||||
android:text="@string/title_rule_delete_hint"
|
android:text="@string/title_rule_delete_hint"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
android:textColor="?attr/colorWarning"
|
android:textColor="?attr/colorWarning"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
app:drawableTint="?attr/colorWarning"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/tvAutomation" />
|
app:layout_constraintTop_toBottomOf="@+id/tvAutomation" />
|
||||||
|
|
||||||
|
@ -1096,7 +1129,7 @@
|
||||||
android:id="@+id/grpMoveProp"
|
android:id="@+id/grpMoveProp"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:constraint_referenced_ids="cbMoveSeen,cbMoveThread" />
|
app:constraint_referenced_ids="tvMoveCreate,etMoveCreate,tvMoveCreateRemark,cbMoveSeen,cbMoveThread" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Group
|
<androidx.constraintlayout.widget.Group
|
||||||
android:id="@+id/grpAnswer"
|
android:id="@+id/grpAnswer"
|
||||||
|
|
|
@ -1728,6 +1728,7 @@
|
||||||
<string name="title_rule_hours">Hours</string>
|
<string name="title_rule_hours">Hours</string>
|
||||||
<string name="title_rule_schedule_end">From the end of the time condition</string>
|
<string name="title_rule_schedule_end">From the end of the time condition</string>
|
||||||
<string name="title_rule_folder">Folder</string>
|
<string name="title_rule_folder">Folder</string>
|
||||||
|
<string name="title_rule_folder_create">Create subfolder</string>
|
||||||
<string name="title_rule_thread">All messages in same conversation and folder</string>
|
<string name="title_rule_thread">All messages in same conversation and folder</string>
|
||||||
<string name="title_rule_identity">Identity</string>
|
<string name="title_rule_identity">Identity</string>
|
||||||
<string name="title_rule_template">Reply template</string>
|
<string name="title_rule_template">Reply template</string>
|
||||||
|
|
Loading…
Reference in New Issue