mirror of
https://github.com/M66B/FairEmail.git
synced 2025-02-24 07:01:05 +00:00
Concept forward multiple
This commit is contained in:
parent
8f75ed1020
commit
f37fe854c4
4 changed files with 149 additions and 0 deletions
|
@ -274,6 +274,11 @@ public interface DaoMessage {
|
|||
" AND folder.type <> '" + EntityFolder.OUTBOX + "'")
|
||||
LiveData<TupleFtsStats> liveFts();
|
||||
|
||||
@Query("SELECT COUNT(*) FROM message" +
|
||||
" WHERE id IN (:ids)" +
|
||||
" AND raw IS NULL or NOT raw")
|
||||
LiveData<Integer> liveRaw(long[] ids);
|
||||
|
||||
@Query("SELECT *" +
|
||||
" FROM message" +
|
||||
" WHERE id = :id")
|
||||
|
|
|
@ -441,6 +441,10 @@ public class EntityMessage implements Serializable {
|
|||
}
|
||||
|
||||
File getRawFile(Context context) {
|
||||
return getRawFile(context, id);
|
||||
}
|
||||
|
||||
static File getRawFile(Context context, Long id) {
|
||||
File dir = new File(context.getFilesDir(), "raw");
|
||||
if (!dir.exists())
|
||||
dir.mkdir();
|
||||
|
|
|
@ -98,6 +98,7 @@ import androidx.appcompat.app.AlertDialog;
|
|||
import androidx.appcompat.widget.PopupMenu;
|
||||
import androidx.constraintlayout.widget.Group;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.core.view.MenuItemCompat;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
@ -106,6 +107,7 @@ import androidx.fragment.app.FragmentResultListener;
|
|||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
@ -2645,6 +2647,11 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
|
|||
if (message == null)
|
||||
continue;
|
||||
|
||||
result.count++;
|
||||
|
||||
if (message.raw != null && message.raw)
|
||||
result.raw++;
|
||||
|
||||
EntityAccount account = accounts.get(message.account);
|
||||
if (account == null) {
|
||||
account = db.account().getAccount(message.account);
|
||||
|
@ -2816,6 +2823,9 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
|
|||
if (result.hasJunk && !result.isJunk && !result.isDrafts) // has junk and not junk/drafts
|
||||
popupMenu.getMenu().add(Menu.NONE, R.string.title_spam, order++, R.string.title_spam);
|
||||
|
||||
if (result.accounts.size() > 0 /* IMAP */ && BuildConfig.DEBUG)
|
||||
popupMenu.getMenu().add(Menu.NONE, R.string.title_raw_send, order++, R.string.title_raw_send);
|
||||
|
||||
for (EntityAccount account : result.accounts) {
|
||||
String title = getString(R.string.title_move_to_account, account.name);
|
||||
SpannableString ss = new SpannableString(title);
|
||||
|
@ -2882,6 +2892,9 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
|
|||
} else if (itemId == R.string.title_spam) {
|
||||
onActionJunkSelection();
|
||||
return true;
|
||||
} else if (itemId == R.string.title_raw_send) {
|
||||
onActionRaw();
|
||||
return true;
|
||||
} else if (itemId == R.string.title_move_to_account) {
|
||||
long account = target.getIntent().getLongExtra("account", -1);
|
||||
onActionMoveSelectionAccount(account, false, result.folders);
|
||||
|
@ -3298,6 +3311,105 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
|
|||
}.execute(this, args, "messages:move");
|
||||
}
|
||||
|
||||
private void onActionRaw() {
|
||||
Bundle args = new Bundle();
|
||||
args.putLongArray("ids", getSelection());
|
||||
|
||||
selectionTracker.clearSelection();
|
||||
|
||||
new SimpleTask<Integer>() {
|
||||
@Override
|
||||
protected Integer onExecute(Context context, Bundle args) {
|
||||
long[] ids = args.getLongArray("ids");
|
||||
|
||||
int count = 0;
|
||||
DB db = DB.getInstance(context);
|
||||
for (long id : ids) {
|
||||
EntityMessage message = db.message().getMessage(id);
|
||||
if (message == null)
|
||||
continue;
|
||||
|
||||
if (message.raw == null || !message.raw) {
|
||||
count++;
|
||||
EntityOperation.queue(context, message, EntityOperation.RAW);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onExecuted(Bundle args, Integer count) {
|
||||
long[] ids = args.getLongArray("ids");
|
||||
|
||||
if (count == 0) {
|
||||
send(ids);
|
||||
return;
|
||||
}
|
||||
|
||||
final Context context = getContext();
|
||||
|
||||
LayoutInflater inflator = LayoutInflater.from(context);
|
||||
View dview = inflator.inflate(R.layout.dialog_forward, null);
|
||||
TextView tvMessages = dview.findViewById(R.id.tvMessages);
|
||||
|
||||
tvMessages.setText(null);
|
||||
|
||||
final AlertDialog dialog = new AlertDialog.Builder(context)
|
||||
.setView(dview)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show();
|
||||
|
||||
DB db = DB.getInstance(context);
|
||||
final LiveData<Integer> ld = db.message().liveRaw(ids);
|
||||
ld.observe(getViewLifecycleOwner(), new Observer<Integer>() {
|
||||
@Override
|
||||
public void onChanged(Integer remaining) {
|
||||
if (remaining == null)
|
||||
return;
|
||||
|
||||
tvMessages.setText(getResources().getQuantityString(R.plurals.title_moving_messages, remaining, remaining));
|
||||
|
||||
if (remaining == 0) {
|
||||
ld.removeObserver(this);
|
||||
dialog.dismiss();
|
||||
send(ids);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onException(Bundle args, Throwable ex) {
|
||||
Log.unexpectedError(getParentFragmentManager(), ex);
|
||||
}
|
||||
|
||||
private void send(long[] ids) {
|
||||
try {
|
||||
final Context context = getContext();
|
||||
|
||||
ArrayList<Uri> uris = new ArrayList<>();
|
||||
for (long id : ids) {
|
||||
File file = EntityMessage.getRawFile(context, id);
|
||||
Uri uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, file);
|
||||
uris.add(uri);
|
||||
}
|
||||
|
||||
Intent send = new Intent(Intent.ACTION_SEND_MULTIPLE);
|
||||
send.setPackage(BuildConfig.APPLICATION_ID);
|
||||
send.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
|
||||
send.setType("message/rfc822");
|
||||
send.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
|
||||
context.startActivity(send);
|
||||
} catch (Throwable ex) {
|
||||
// java.lang.IllegalArgumentException: Failed to resolve canonical path for ...
|
||||
Log.unexpectedError(getParentFragmentManager(), ex);
|
||||
}
|
||||
}
|
||||
}.execute(this, args, "messages:forward");
|
||||
}
|
||||
|
||||
private void onActionMoveSelectionAccount(long account, boolean copy, List<Long> disabled) {
|
||||
Bundle args = new Bundle();
|
||||
args.putString("title", getString(copy ? R.string.title_copy_to : R.string.title_move_to_folder));
|
||||
|
@ -7804,6 +7916,8 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
|
|||
}
|
||||
|
||||
private class MoreResult {
|
||||
int count;
|
||||
int raw;
|
||||
boolean seen;
|
||||
boolean unseen;
|
||||
boolean visible;
|
||||
|
|
26
app/src/main/res/layout/dialog_forward.xml
Normal file
26
app/src/main/res/layout/dialog_forward.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="24dp">
|
||||
|
||||
<eu.faircode.email.FixedTextView
|
||||
android:id="@+id/tvCaption"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/title_raw_send"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<eu.faircode.email.FixedTextView
|
||||
android:id="@+id/tvMessages"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="12 messages"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvCaption" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Reference in a new issue