mirror of https://github.com/M66B/FairEmail.git
Added rule action local notes
This commit is contained in:
parent
f0a0c46b44
commit
ba7b2302b4
|
@ -6,6 +6,11 @@ For support you can use [the contact form](https://contact.faircode.eu/?product=
|
||||||
|
|
||||||
### [Ubirajara](https://en.wikipedia.org/wiki/Ubirajara_jubatus)
|
### [Ubirajara](https://en.wikipedia.org/wiki/Ubirajara_jubatus)
|
||||||
|
|
||||||
|
### Next version
|
||||||
|
|
||||||
|
* Added rule action to add local notes
|
||||||
|
* Updated [translations](https://crowdin.com/project/open-source-email)
|
||||||
|
|
||||||
### 1.2093 - 2023-08-14
|
### 1.2093 - 2023-08-14
|
||||||
|
|
||||||
* Small improvements and minor bug fixes
|
* Small improvements and minor bug fixes
|
||||||
|
|
1
FAQ.md
1
FAQ.md
|
@ -2676,6 +2676,7 @@ You can select one of these actions to apply to matching messages:
|
||||||
* Add star
|
* Add star
|
||||||
* Set importance (local priority)
|
* Set importance (local priority)
|
||||||
* Add keyword
|
* Add keyword
|
||||||
|
* Add local notes (since version 1.2094)
|
||||||
* Move
|
* Move
|
||||||
* Copy (Gmail: label)
|
* Copy (Gmail: label)
|
||||||
* Delete permanently (since version 1.1801)
|
* Delete permanently (since version 1.1801)
|
||||||
|
|
|
@ -6,6 +6,11 @@ For support you can use [the contact form](https://contact.faircode.eu/?product=
|
||||||
|
|
||||||
### [Ubirajara](https://en.wikipedia.org/wiki/Ubirajara_jubatus)
|
### [Ubirajara](https://en.wikipedia.org/wiki/Ubirajara_jubatus)
|
||||||
|
|
||||||
|
### Next version
|
||||||
|
|
||||||
|
* Added rule action to add local notes
|
||||||
|
* Updated [translations](https://crowdin.com/project/open-source-email)
|
||||||
|
|
||||||
### 1.2093 - 2023-08-14
|
### 1.2093 - 2023-08-14
|
||||||
|
|
||||||
* Small improvements and minor bug fixes
|
* Small improvements and minor bug fixes
|
||||||
|
|
|
@ -207,6 +207,9 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> {
|
||||||
resend = jaction.optBoolean("resend");
|
resend = jaction.optBoolean("resend");
|
||||||
setAction(resend ? R.string.title_rule_resend : getAction(type), to);
|
setAction(resend ? R.string.title_rule_resend : getAction(type), to);
|
||||||
}
|
}
|
||||||
|
} else if (type == EntityRule.TYPE_NOTES) {
|
||||||
|
String notes = jaction.getString("notes");
|
||||||
|
setAction(getAction(type), notes);
|
||||||
} else
|
} else
|
||||||
setAction(getAction(type), null);
|
setAction(getAction(type), null);
|
||||||
|
|
||||||
|
@ -557,6 +560,8 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> {
|
||||||
return R.string.title_rule_sound;
|
return R.string.title_rule_sound;
|
||||||
case EntityRule.TYPE_LOCAL_ONLY:
|
case EntityRule.TYPE_LOCAL_ONLY:
|
||||||
return R.string.title_rule_local_only;
|
return R.string.title_rule_local_only;
|
||||||
|
case EntityRule.TYPE_NOTES:
|
||||||
|
return R.string.title_rule_notes;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown action type=" + type);
|
throw new IllegalArgumentException("Unknown action type=" + type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,7 @@ public class EntityRule {
|
||||||
static final int TYPE_DELETE = 15;
|
static final int TYPE_DELETE = 15;
|
||||||
static final int TYPE_SOUND = 16;
|
static final int TYPE_SOUND = 16;
|
||||||
static final int TYPE_LOCAL_ONLY = 17;
|
static final int TYPE_LOCAL_ONLY = 17;
|
||||||
|
static final int TYPE_NOTES = 18;
|
||||||
|
|
||||||
static final String ACTION_AUTOMATION = BuildConfig.APPLICATION_ID + ".AUTOMATION";
|
static final String ACTION_AUTOMATION = BuildConfig.APPLICATION_ID + ".AUTOMATION";
|
||||||
static final String EXTRA_RULE = "rule";
|
static final String EXTRA_RULE = "rule";
|
||||||
|
@ -603,6 +604,8 @@ public class EntityRule {
|
||||||
return onActionSound(context, message, jaction);
|
return onActionSound(context, message, jaction);
|
||||||
case TYPE_LOCAL_ONLY:
|
case TYPE_LOCAL_ONLY:
|
||||||
return onActionLocalOnly(context, message, jaction);
|
return onActionLocalOnly(context, message, jaction);
|
||||||
|
case TYPE_NOTES:
|
||||||
|
return onActionNotes(context, message, jaction);
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown rule type=" + type + " name=" + name);
|
throw new IllegalArgumentException("Unknown rule type=" + type + " name=" + name);
|
||||||
}
|
}
|
||||||
|
@ -681,6 +684,11 @@ public class EntityRule {
|
||||||
return;
|
return;
|
||||||
case TYPE_LOCAL_ONLY:
|
case TYPE_LOCAL_ONLY:
|
||||||
return;
|
return;
|
||||||
|
case TYPE_NOTES:
|
||||||
|
String notes = jargs.optString("notes");
|
||||||
|
if (TextUtils.isEmpty(notes))
|
||||||
|
throw new IllegalArgumentException(context.getString(R.string.title_rule_notes_missing));
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown rule type=" + type);
|
throw new IllegalArgumentException("Unknown rule type=" + type);
|
||||||
}
|
}
|
||||||
|
@ -1317,6 +1325,16 @@ public class EntityRule {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean onActionNotes(Context context, EntityMessage message, JSONObject jargs) throws JSONException {
|
||||||
|
String notes = jargs.getString("notes");
|
||||||
|
Integer color = (jargs.has("color") ? jargs.getInt("color") : null);
|
||||||
|
|
||||||
|
DB db = DB.getInstance(context);
|
||||||
|
db.message().setMessageNotes(message.id, notes, color);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private static Calendar getRelativeCalendar(boolean all, int minutes, long reference) {
|
private static Calendar getRelativeCalendar(boolean all, int minutes, long reference) {
|
||||||
int d = minutes / (24 * 60);
|
int d = minutes / (24 * 60);
|
||||||
int h = minutes / 60 % 24;
|
int h = minutes / 60 % 24;
|
||||||
|
|
|
@ -169,6 +169,9 @@ public class FragmentRule extends FragmentBase {
|
||||||
|
|
||||||
private TextView tvAutomation;
|
private TextView tvAutomation;
|
||||||
|
|
||||||
|
private EditText etNotes;
|
||||||
|
private ViewButtonColor btnColorNotes;
|
||||||
|
|
||||||
private BottomNavigationView bottom_navigation;
|
private BottomNavigationView bottom_navigation;
|
||||||
private ContentLoadingProgressBar pbWait;
|
private ContentLoadingProgressBar pbWait;
|
||||||
|
|
||||||
|
@ -186,6 +189,7 @@ public class FragmentRule extends FragmentBase {
|
||||||
private Group grpAutomation;
|
private Group grpAutomation;
|
||||||
private Group grpDelete;
|
private Group grpDelete;
|
||||||
private Group grpLocalOnly;
|
private Group grpLocalOnly;
|
||||||
|
private Group grpNotes;
|
||||||
|
|
||||||
private ArrayAdapter<String> adapterGroup;
|
private ArrayAdapter<String> adapterGroup;
|
||||||
private ArrayAdapter<String> adapterDay;
|
private ArrayAdapter<String> adapterDay;
|
||||||
|
@ -215,6 +219,7 @@ public class FragmentRule extends FragmentBase {
|
||||||
private final static int REQUEST_DATE_AFTER = 11;
|
private final static int REQUEST_DATE_AFTER = 11;
|
||||||
private final static int REQUEST_DATE_BEFORE = 12;
|
private final static int REQUEST_DATE_BEFORE = 12;
|
||||||
private final static int REQUEST_FOLDER = 13;
|
private final static int REQUEST_FOLDER = 13;
|
||||||
|
private final static int REQUEST_COLOR_NOTES = 14;
|
||||||
|
|
||||||
private static final List<String> HEADER_CONDITIONS = Collections.unmodifiableList(Arrays.asList(
|
private static final List<String> HEADER_CONDITIONS = Collections.unmodifiableList(Arrays.asList(
|
||||||
"$$seen$",
|
"$$seen$",
|
||||||
|
@ -354,6 +359,9 @@ public class FragmentRule extends FragmentBase {
|
||||||
|
|
||||||
tvAutomation = view.findViewById(R.id.tvAutomation);
|
tvAutomation = view.findViewById(R.id.tvAutomation);
|
||||||
|
|
||||||
|
etNotes = view.findViewById(R.id.etNotes);
|
||||||
|
btnColorNotes = view.findViewById(R.id.btnColorNotes);
|
||||||
|
|
||||||
bottom_navigation = view.findViewById(R.id.bottom_navigation);
|
bottom_navigation = view.findViewById(R.id.bottom_navigation);
|
||||||
|
|
||||||
pbWait = view.findViewById(R.id.pbWait);
|
pbWait = view.findViewById(R.id.pbWait);
|
||||||
|
@ -372,6 +380,7 @@ public class FragmentRule extends FragmentBase {
|
||||||
grpAutomation = view.findViewById(R.id.grpAutomation);
|
grpAutomation = view.findViewById(R.id.grpAutomation);
|
||||||
grpDelete = view.findViewById(R.id.grpDelete);
|
grpDelete = view.findViewById(R.id.grpDelete);
|
||||||
grpLocalOnly = view.findViewById(R.id.grpLocalOnly);
|
grpLocalOnly = view.findViewById(R.id.grpLocalOnly);
|
||||||
|
grpNotes = view.findViewById(R.id.grpNotes);
|
||||||
|
|
||||||
adapterGroup = new ArrayAdapter<>(getContext(), R.layout.spinner_item1_dropdown, android.R.id.text1);
|
adapterGroup = new ArrayAdapter<>(getContext(), R.layout.spinner_item1_dropdown, android.R.id.text1);
|
||||||
etGroup.setThreshold(1);
|
etGroup.setThreshold(1);
|
||||||
|
@ -625,8 +634,10 @@ public class FragmentRule extends FragmentBase {
|
||||||
actions.add(new Action(EntityRule.TYPE_SNOOZE, getString(R.string.title_rule_snooze)));
|
actions.add(new Action(EntityRule.TYPE_SNOOZE, getString(R.string.title_rule_snooze)));
|
||||||
actions.add(new Action(EntityRule.TYPE_FLAG, getString(R.string.title_rule_flag)));
|
actions.add(new Action(EntityRule.TYPE_FLAG, getString(R.string.title_rule_flag)));
|
||||||
actions.add(new Action(EntityRule.TYPE_IMPORTANCE, getString(R.string.title_rule_importance)));
|
actions.add(new Action(EntityRule.TYPE_IMPORTANCE, getString(R.string.title_rule_importance)));
|
||||||
if (protocol == EntityAccount.TYPE_IMAP) {
|
if (protocol == EntityAccount.TYPE_IMAP)
|
||||||
actions.add(new Action(EntityRule.TYPE_KEYWORD, getString(R.string.title_rule_keyword)));
|
actions.add(new Action(EntityRule.TYPE_KEYWORD, getString(R.string.title_rule_keyword)));
|
||||||
|
actions.add(new Action(EntityRule.TYPE_NOTES, getString(R.string.title_rule_notes)));
|
||||||
|
if (protocol == EntityAccount.TYPE_IMAP) {
|
||||||
actions.add(new Action(EntityRule.TYPE_MOVE, getString(R.string.title_rule_move)));
|
actions.add(new Action(EntityRule.TYPE_MOVE, getString(R.string.title_rule_move)));
|
||||||
actions.add(new Action(EntityRule.TYPE_COPY, getString(R.string.title_rule_copy)));
|
actions.add(new Action(EntityRule.TYPE_COPY, getString(R.string.title_rule_copy)));
|
||||||
}
|
}
|
||||||
|
@ -787,6 +798,21 @@ public class FragmentRule extends FragmentBase {
|
||||||
EntityRule.EXTRA_SENDER,
|
EntityRule.EXTRA_SENDER,
|
||||||
EntityRule.EXTRA_SUBJECT})));
|
EntityRule.EXTRA_SUBJECT})));
|
||||||
|
|
||||||
|
btnColorNotes.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putInt("color", btnColorNotes.getColor());
|
||||||
|
args.putString("title", getString(R.string.title_rule_notes));
|
||||||
|
args.putBoolean("reset", true);
|
||||||
|
|
||||||
|
FragmentDialogColor fragment = new FragmentDialogColor();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
fragment.setTargetFragment(FragmentRule.this, REQUEST_COLOR_NOTES);
|
||||||
|
fragment.show(getParentFragmentManager(), "rule:color:notes");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
bottom_navigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
|
bottom_navigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
|
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
|
||||||
|
@ -822,6 +848,7 @@ public class FragmentRule extends FragmentBase {
|
||||||
grpAutomation.setVisibility(View.GONE);
|
grpAutomation.setVisibility(View.GONE);
|
||||||
grpDelete.setVisibility(View.GONE);
|
grpDelete.setVisibility(View.GONE);
|
||||||
grpLocalOnly.setVisibility(View.GONE);
|
grpLocalOnly.setVisibility(View.GONE);
|
||||||
|
grpNotes.setVisibility(View.GONE);
|
||||||
|
|
||||||
pbWait.setVisibility(View.VISIBLE);
|
pbWait.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
@ -991,6 +1018,12 @@ public class FragmentRule extends FragmentBase {
|
||||||
if (resultCode == RESULT_OK && data != null)
|
if (resultCode == RESULT_OK && data != null)
|
||||||
onFolderSelected(data.getBundleExtra("args"));
|
onFolderSelected(data.getBundleExtra("args"));
|
||||||
break;
|
break;
|
||||||
|
case REQUEST_COLOR_NOTES:
|
||||||
|
if (resultCode == RESULT_OK && data != null) {
|
||||||
|
Bundle args = data.getBundleExtra("args");
|
||||||
|
btnColorNotes.setColor(args.getInt("color"));
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
Log.e(ex);
|
Log.e(ex);
|
||||||
|
@ -1319,6 +1352,13 @@ public class FragmentRule extends FragmentBase {
|
||||||
etAlarmDuration.setEnabled(alarm);
|
etAlarmDuration.setEnabled(alarm);
|
||||||
etAlarmDuration.setText(duration == 0 ? null : Integer.toString(duration));
|
etAlarmDuration.setText(duration == 0 ? null : Integer.toString(duration));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EntityRule.TYPE_NOTES:
|
||||||
|
etNotes.setText(jaction.getString("notes"));
|
||||||
|
btnColorNotes.setColor(
|
||||||
|
!jaction.has("color") || jaction.isNull("color")
|
||||||
|
? null : jaction.getInt("color"));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int pos = 0; pos < adapterAction.getCount(); pos++)
|
for (int pos = 0; pos < adapterAction.getCount(); pos++)
|
||||||
|
@ -1376,6 +1416,7 @@ public class FragmentRule extends FragmentBase {
|
||||||
grpAutomation.setVisibility(type == EntityRule.TYPE_AUTOMATION ? View.VISIBLE : View.GONE);
|
grpAutomation.setVisibility(type == EntityRule.TYPE_AUTOMATION ? View.VISIBLE : View.GONE);
|
||||||
grpDelete.setVisibility(type == EntityRule.TYPE_DELETE ? View.VISIBLE : View.GONE);
|
grpDelete.setVisibility(type == EntityRule.TYPE_DELETE ? View.VISIBLE : View.GONE);
|
||||||
grpLocalOnly.setVisibility(type == EntityRule.TYPE_LOCAL_ONLY ? View.VISIBLE : View.GONE);
|
grpLocalOnly.setVisibility(type == EntityRule.TYPE_LOCAL_ONLY ? View.VISIBLE : View.GONE);
|
||||||
|
grpNotes.setVisibility(type == EntityRule.TYPE_NOTES ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onActionDelete() {
|
private void onActionDelete() {
|
||||||
|
@ -1706,6 +1747,13 @@ public class FragmentRule extends FragmentBase {
|
||||||
Log.e(ex);
|
Log.e(ex);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EntityRule.TYPE_NOTES:
|
||||||
|
jaction.put("notes", etNotes.getText().toString());
|
||||||
|
int ncolor = btnColorNotes.getColor();
|
||||||
|
if (ncolor != Color.TRANSPARENT)
|
||||||
|
jaction.put("color", ncolor);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1239,6 +1239,48 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/tvDelete" />
|
app:layout_constraintTop_toBottomOf="@+id/tvDelete" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvNotes"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:text="@string/title_rule_notes"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tvLocalOnly" />
|
||||||
|
|
||||||
|
<eu.faircode.email.EditTextPlain
|
||||||
|
android:id="@+id/etNotes"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textCapSentences"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tvNotes" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvColorNotes"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:text="@string/title_color"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/etNotes" />
|
||||||
|
|
||||||
|
<eu.faircode.email.ViewButtonColor
|
||||||
|
android:id="@+id/btnColorNotes"
|
||||||
|
style="?android:attr/buttonStyleSmall"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="6dp"
|
||||||
|
android:paddingHorizontal="6dp"
|
||||||
|
android:tag="disable"
|
||||||
|
android:text="@string/title_select"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tvColorNotes" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Group
|
<androidx.constraintlayout.widget.Group
|
||||||
android:id="@+id/grpReady"
|
android:id="@+id/grpReady"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
@ -1334,6 +1376,12 @@
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:constraint_referenced_ids="tvLocalOnly" />
|
app:constraint_referenced_ids="tvLocalOnly" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Group
|
||||||
|
android:id="@+id/grpNotes"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:constraint_referenced_ids="tvNotes,etNotes,btnColorNotes" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</eu.faircode.email.ScrollViewEx>
|
</eu.faircode.email.ScrollViewEx>
|
||||||
|
|
||||||
|
|
|
@ -1895,6 +1895,7 @@
|
||||||
<string name="title_rule_keyword">Keyword</string>
|
<string name="title_rule_keyword">Keyword</string>
|
||||||
<string name="title_rule_keyword_add">Add</string>
|
<string name="title_rule_keyword_add">Add</string>
|
||||||
<string name="title_rule_keyword_delete">Delete</string>
|
<string name="title_rule_keyword_delete">Delete</string>
|
||||||
|
<string name="title_rule_notes">Local notes</string>
|
||||||
<string name="title_rule_move">Move</string>
|
<string name="title_rule_move">Move</string>
|
||||||
<string name="title_rule_copy">Copy (label)</string>
|
<string name="title_rule_copy">Copy (label)</string>
|
||||||
<string name="title_rule_answer">Reply/forward</string>
|
<string name="title_rule_answer">Reply/forward</string>
|
||||||
|
@ -1955,6 +1956,7 @@
|
||||||
<string name="title_rule_answer_missing">Template missing</string>
|
<string name="title_rule_answer_missing">Template missing</string>
|
||||||
<string name="title_rule_keyword_missing">Keyword missing</string>
|
<string name="title_rule_keyword_missing">Keyword missing</string>
|
||||||
<string name="title_rule_automation_hint">This will send the intent \'%1$s\' with the extras \'%2$s\'</string>
|
<string name="title_rule_automation_hint">This will send the intent \'%1$s\' with the extras \'%2$s\'</string>
|
||||||
|
<string name="title_rule_notes_missing">Local notes missing</string>
|
||||||
<string name="title_rule_delete_hint">Permanent deletion is irreversible, so make sure the rule conditions are correct!</string>
|
<string name="title_rule_delete_hint">Permanent deletion is irreversible, so make sure the rule conditions are correct!</string>
|
||||||
<string name="title_rule_local_only_hint" translatable="false">Try to avoid bridging notifications to other devices, such as smartwatches. Not all devices support this.</string>
|
<string name="title_rule_local_only_hint" translatable="false">Try to avoid bridging notifications to other devices, such as smartwatches. Not all devices support this.</string>
|
||||||
<string name="title_rule_edit_group">Edit group …</string>
|
<string name="title_rule_edit_group">Edit group …</string>
|
||||||
|
|
|
@ -6,6 +6,11 @@ For support you can use the contact form.
|
||||||
|
|
||||||
Ubirajara
|
Ubirajara
|
||||||
|
|
||||||
|
Next version
|
||||||
|
|
||||||
|
* Added rule action to add local notes
|
||||||
|
* Updated translations
|
||||||
|
|
||||||
1.2093 - 2023-08-14
|
1.2093 - 2023-08-14
|
||||||
|
|
||||||
* Small improvements and minor bug fixes
|
* Small improvements and minor bug fixes
|
||||||
|
|
Loading…
Reference in New Issue