Added swipe to summarize

This commit is contained in:
M66B 2024-05-14 14:17:00 +02:00
parent 20f9d67b88
commit 5c7f366e30
9 changed files with 81 additions and 31 deletions

View File

@ -9,6 +9,7 @@ For support you can use [the contact form](https://contact.faircode.eu/?product=
### Next version
* Added "AI" summarize quick action
* Added "AI" summarize swipe action
* Small improvements and minor bug fixes
Preview versions are available [here](https://bitbucket.org/M66B/fairemail-test/downloads/).

View File

@ -9,6 +9,7 @@ For support you can use [the contact form](https://contact.faircode.eu/?product=
### Next version
* Added "AI" summarize quick action
* Added "AI" summarize swipe action
* Small improvements and minor bug fixes
Preview versions are available [here](https://bitbucket.org/M66B/fairemail-test/downloads/).

View File

@ -7278,14 +7278,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
}
private void onActionSummarize(TupleMessageEx message) {
Bundle args = new Bundle();
args.putLong("id", message.id);
args.putString("from", MessageHelper.formatAddresses(message.from));
args.putString("subject", message.subject);
FragmentDialogSummarize fragment = new FragmentDialogSummarize();
fragment.setArguments(args);
fragment.show(parentFragment.getParentFragmentManager(), "message:summary");
FragmentDialogSummarize.summarize(message, parentFragment.getParentFragmentManager());
}
private void onActionForceLight(TupleMessageEx message) {

View File

@ -127,6 +127,7 @@ public class EntityMessage implements Serializable {
static final Long SWIPE_ACTION_JUNK = -8L;
static final Long SWIPE_ACTION_REPLY = -9L;
static final Long SWIPE_ACTION_IMPORTANCE = -10L;
static final Long SWIPE_ACTION_SUMMARIZE = -11L;
private static final int MAX_SNOOZED = 300;
@ -754,6 +755,8 @@ public class EntityMessage implements Serializable {
return "junk";
if (SWIPE_ACTION_REPLY.equals(type))
return "reply";
if (SWIPE_ACTION_SUMMARIZE.equals(type))
return "summarize";
return "???";
}

View File

@ -2139,6 +2139,13 @@ public class FragmentAccount extends FragmentBase {
importance.name = context.getString(R.string.title_set_importance);
folders.add(importance);
if (OpenAI.isAvailable(context) || Gemini.isAvailable(context)) {
EntityFolder summarize = new EntityFolder();
summarize.id = EntityMessage.SWIPE_ACTION_SUMMARIZE;
summarize.name = context.getString(R.string.title_summarize);
folders.add(summarize);
}
EntityFolder move = new EntityFolder();
move.id = EntityMessage.SWIPE_ACTION_MOVE;
move.name = context.getString(R.string.title_move);

View File

@ -32,6 +32,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentManager;
import androidx.preference.PreferenceManager;
import org.jsoup.nodes.Document;
@ -165,4 +166,15 @@ public class FragmentDialogSummarize extends FragmentDialogBase {
return builder.create();
}
public static void summarize(EntityMessage message, FragmentManager fm) {
Bundle args = new Bundle();
args.putLong("id", message.id);
args.putString("from", MessageHelper.formatAddresses(message.from));
args.putString("subject", message.subject);
FragmentDialogSummarize fragment = new FragmentDialogSummarize();
fragment.setArguments(args);
fragment.show(fm, "message:summary");
}
}

View File

@ -1635,14 +1635,7 @@ public class FragmentMessages extends FragmentBase
if (result == null || result.single == null || !result.single.content)
return;
Bundle args = new Bundle();
args.putLong("id", result.single.id);
args.putString("from", MessageHelper.formatAddresses(result.single.from));
args.putString("subject", result.single.subject);
FragmentDialogSummarize fragment = new FragmentDialogSummarize();
fragment.setArguments(args);
fragment.show(getParentFragmentManager(), "message:summary");
FragmentDialogSummarize.summarize(result.single, getParentFragmentManager());
}
});
@ -3010,6 +3003,13 @@ public class FragmentMessages extends FragmentBase
if (message.uid == null && message.accountProtocol == EntityAccount.TYPE_IMAP)
return 0;
if (!message.content) {
if (EntityMessage.SWIPE_ACTION_SUMMARIZE.equals(swipes.swipe_left))
swipes.swipe_left = null;
if (EntityMessage.SWIPE_ACTION_SUMMARIZE.equals(swipes.swipe_right))
swipes.swipe_right = null;
}
if (message.folderReadOnly) {
if (!EntityMessage.SWIPE_ACTION_SEEN.equals(swipes.swipe_left) &&
!EntityMessage.SWIPE_ACTION_FLAG.equals(swipes.swipe_left))
@ -3161,6 +3161,8 @@ public class FragmentMessages extends FragmentBase
? R.drawable.twotone_visibility_24 : R.drawable.twotone_timer_off_24));
else if (EntityMessage.SWIPE_ACTION_MOVE.equals(action))
icon = R.drawable.twotone_folder_24;
else if (EntityMessage.SWIPE_ACTION_SUMMARIZE.equals(action))
icon = R.drawable.twotone_smart_toy_24;
else if (EntityMessage.SWIPE_ACTION_JUNK.equals(action))
icon = R.drawable.twotone_report_24;
else if (EntityMessage.SWIPE_ACTION_DELETE.equals(action) ||
@ -3323,6 +3325,9 @@ public class FragmentMessages extends FragmentBase
else if (EntityMessage.SWIPE_ACTION_MOVE.equals(action)) {
redraw(viewHolder);
onSwipeMove(message);
} else if (EntityMessage.SWIPE_ACTION_SUMMARIZE.equals(action)) {
redraw(viewHolder);
onSwipeSummarize(message);
} else if (EntityMessage.SWIPE_ACTION_JUNK.equals(action)) {
redraw(viewHolder);
onSwipeJunk(message);
@ -3409,8 +3414,10 @@ public class FragmentMessages extends FragmentBase
@Override
public void run() {
try {
final Context context = getContext();
int order = 1;
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(getContext(), getViewLifecycleOwner(), anchor);
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, getViewLifecycleOwner(), anchor);
if (message.ui_seen)
popupMenu.getMenu().add(Menu.NONE, R.string.title_unseen, order++, R.string.title_unseen)
@ -3452,6 +3459,11 @@ public class FragmentMessages extends FragmentBase
.setIcon(R.drawable.twotone_south_24)
.setEnabled(!EntityMessage.PRIORITIY_LOW.equals(message.importance));
if (OpenAI.isAvailable(context) || Gemini.isAvailable(context)) {
popupMenu.getMenu().add(Menu.NONE, R.string.title_summarize, order++, R.string.title_summarize)
.setIcon(R.drawable.twotone_smart_toy_24);
}
if (message.accountProtocol == EntityAccount.TYPE_IMAP) {
popupMenu.getMenu().add(Menu.NONE, R.string.title_move, order++, R.string.title_move)
.setIcon(R.drawable.twotone_drive_file_move_24);
@ -3461,7 +3473,7 @@ public class FragmentMessages extends FragmentBase
popupMenu.getMenu().add(Menu.NONE, R.string.title_delete_permanently, order++, R.string.title_delete_permanently)
.setIcon(R.drawable.twotone_delete_forever_24);
popupMenu.insertIcons(getContext());
popupMenu.insertIcons(context);
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
@ -3497,6 +3509,9 @@ public class FragmentMessages extends FragmentBase
} else if (itemId == R.string.title_importance_high) {
onActionSetImportanceSelection(EntityMessage.PRIORITIY_HIGH, message.id, false);
return true;
} else if (itemId == R.string.title_summarize) {
onSwipeSummarize(message);
return true;
} else if (itemId == R.string.title_move) {
onSwipeMove(message);
return true;
@ -3565,6 +3580,16 @@ public class FragmentMessages extends FragmentBase
fragment.show(getParentFragmentManager(), "swipe:move");
}
private void onSwipeSummarize(final @NonNull TupleMessageEx message) {
final Context context = getContext();
if (OpenAI.isAvailable(context) || Gemini.isAvailable(context))
FragmentDialogSummarize.summarize(message, getParentFragmentManager());
else
context.startActivity(new Intent(context, ActivitySetup.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
.putExtra("tab", "integrations"));
}
private void onSwipeJunk(final @NonNull TupleMessageEx message) {
if (message.accountProtocol == EntityAccount.TYPE_POP) {
Bundle aargs = new Bundle();

View File

@ -338,7 +338,7 @@ public class FragmentPop extends FragmentBase {
etInterval.setHint(Integer.toString(EntityAccount.DEFAULT_POLL_INTERVAL));
adapterSwipe = new ArrayAdapter<>(getContext(), R.layout.spinner_item1, android.R.id.text1, getSwipeActions());
adapterSwipe = new ArrayAdapter<>(getContext(), R.layout.spinner_item1, android.R.id.text1, getSwipeActions(getContext()));
adapterSwipe.setDropDownViewResource(R.layout.spinner_item1_dropdown);
spLeft.setAdapter(adapterSwipe);
@ -903,7 +903,7 @@ public class FragmentPop extends FragmentBase {
cbIdentity.setChecked(account == null);
List<EntityFolder> folders = getSwipeActions();
List<EntityFolder> folders = getSwipeActions(getContext());
for (int pos = 0; pos < folders.size(); pos++) {
EntityFolder folder = folders.get(pos);
@ -1088,7 +1088,7 @@ public class FragmentPop extends FragmentBase {
}.execute(this, args, "account:delete");
}
private List<EntityFolder> getSwipeActions() {
private List<EntityFolder> getSwipeActions(Context context) {
List<EntityFolder> folders = new ArrayList<>();
EntityFolder ask = new EntityFolder();
@ -1098,9 +1098,19 @@ public class FragmentPop extends FragmentBase {
EntityFolder seen = new EntityFolder();
seen.id = EntityMessage.SWIPE_ACTION_SEEN;
seen.name = getString(R.string.title_seen);
seen.name = getString(R.string.title_seen_unseen);
folders.add(seen);
EntityFolder snooze = new EntityFolder();
snooze.id = EntityMessage.SWIPE_ACTION_SNOOZE;
snooze.name = getString(R.string.title_snooze_now);
folders.add(snooze);
EntityFolder hide = new EntityFolder();
hide.id = EntityMessage.SWIPE_ACTION_HIDE;
hide.name = getString(R.string.title_hide);
folders.add(hide);
EntityFolder flag = new EntityFolder();
flag.id = EntityMessage.SWIPE_ACTION_FLAG;
flag.name = getString(R.string.title_flag);
@ -1111,15 +1121,12 @@ public class FragmentPop extends FragmentBase {
importance.name = getString(R.string.title_set_importance);
folders.add(importance);
EntityFolder snooze = new EntityFolder();
snooze.id = EntityMessage.SWIPE_ACTION_SNOOZE;
snooze.name = getString(R.string.title_snooze_now);
folders.add(snooze);
EntityFolder hide = new EntityFolder();
hide.id = EntityMessage.SWIPE_ACTION_HIDE;
hide.name = getString(R.string.title_hide);
folders.add(hide);
if (OpenAI.isAvailable(context) || Gemini.isAvailable(context)) {
EntityFolder summarize = new EntityFolder();
summarize.id = EntityMessage.SWIPE_ACTION_SUMMARIZE;
summarize.name = context.getString(R.string.title_summarize);
folders.add(summarize);
}
EntityFolder junk = new EntityFolder();
junk.id = EntityMessage.SWIPE_ACTION_JUNK;

View File

@ -9,6 +9,7 @@ Acantholipan
Next version
* Added "AI" summarize quick action
* Added "AI" summarize swipe action
* Small improvements and minor bug fixes
Preview versions are available here.