diff --git a/app/src/main/java/eu/faircode/email/ActivityWidgetUnified.java b/app/src/main/java/eu/faircode/email/ActivityWidgetUnified.java index 0a2d9fdf22..df59703102 100644 --- a/app/src/main/java/eu/faircode/email/ActivityWidgetUnified.java +++ b/app/src/main/java/eu/faircode/email/ActivityWidgetUnified.java @@ -25,6 +25,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.view.View; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; @@ -34,19 +35,22 @@ import androidx.constraintlayout.widget.Group; import androidx.preference.PreferenceManager; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class ActivityWidgetUnified extends ActivityBase { private int appWidgetId; private Spinner spAccount; + private Spinner spFolder; private CheckBox cbUnseen; private CheckBox cbFlagged; private Button btnSave; private ContentLoadingProgressBar pbWait; private Group grpReady; - private ArrayAdapter adapter; + private ArrayAdapter adapterAccount; + private ArrayAdapter adapterFolder; @Override protected void onCreate(Bundle savedInstanceState) { @@ -65,6 +69,7 @@ public class ActivityWidgetUnified extends ActivityBase { setContentView(R.layout.activity_widget_unified); spAccount = findViewById(R.id.spAccount); + spFolder = findViewById(R.id.spFolder); cbUnseen = findViewById(R.id.cbUnseen); cbFlagged = findViewById(R.id.cbFlagged); btnSave = findViewById(R.id.btnSave); @@ -78,14 +83,19 @@ public class ActivityWidgetUnified extends ActivityBase { @Override public void onClick(View view) { EntityAccount account = (EntityAccount) spAccount.getSelectedItem(); + TupleFolderEx folder = (TupleFolderEx) spFolder.getSelectedItem(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ActivityWidgetUnified.this); SharedPreferences.Editor editor = prefs.edit(); if (account != null && account.id > 0) - editor.putString("widget." + appWidgetId + ".name", account.name); + if (folder != null && folder.id > 0) + editor.putString("widget." + appWidgetId + ".name", folder.getDisplayName(ActivityWidgetUnified.this)); + else + editor.putString("widget." + appWidgetId + ".name", account.name); else editor.remove("widget." + appWidgetId + ".name"); editor.putLong("widget." + appWidgetId + ".account", account == null ? -1L : account.id); + editor.putLong("widget." + appWidgetId + ".folder", folder == null ? -1L : folder.id); editor.putBoolean("widget." + appWidgetId + ".unseen", cbUnseen.isChecked()); editor.putBoolean("widget." + appWidgetId + ".flagged", cbFlagged.isChecked()); editor.apply(); @@ -98,9 +108,60 @@ public class ActivityWidgetUnified extends ActivityBase { } }); - adapter = new ArrayAdapter<>(this, R.layout.spinner_item1, android.R.id.text1, new ArrayList()); - adapter.setDropDownViewResource(R.layout.spinner_item1_dropdown); - spAccount.setAdapter(adapter); + adapterAccount = new ArrayAdapter<>(this, R.layout.spinner_item1, android.R.id.text1, new ArrayList()); + adapterAccount.setDropDownViewResource(R.layout.spinner_item1_dropdown); + spAccount.setAdapter(adapterAccount); + + adapterFolder = new ArrayAdapter<>(this, R.layout.spinner_item1, android.R.id.text1, new ArrayList()); + adapterFolder.setDropDownViewResource(R.layout.spinner_item1_dropdown); + spFolder.setAdapter(adapterFolder); + + spAccount.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + EntityAccount account = (EntityAccount) spAccount.getAdapter().getItem(position); + setFolders(account.id); + } + + @Override + public void onNothingSelected(AdapterView parent) { + setFolders(-1); + } + + private void setFolders(long account) { + Bundle args = new Bundle(); + args.putLong("account", account); + + new SimpleTask>() { + @Override + protected List onExecute(Context context, Bundle args) { + long account = args.getLong("account"); + + DB db = DB.getInstance(context); + List folders = db.folder().getFoldersEx(account); + if (folders.size() > 0) + Collections.sort(folders, folders.get(0).getComparator(context)); + return folders; + } + + @Override + protected void onExecuted(Bundle args, List folders) { + TupleFolderEx unified = new TupleFolderEx(); + unified.id = -1L; + unified.name = getString(R.string.title_widget_folder_unified); + folders.add(0, unified); + + adapterFolder.clear(); + adapterFolder.addAll(folders); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Helper.unexpectedError(getSupportFragmentManager(), ex); + } + }.execute(ActivityWidgetUnified.this, args, "widget:folders"); + } + }); grpReady.setVisibility(View.GONE); pbWait.setVisibility(View.VISIBLE); @@ -123,7 +184,7 @@ public class ActivityWidgetUnified extends ActivityBase { all.primary = false; accounts.add(0, all); - adapter.addAll(accounts); + adapterAccount.addAll(accounts); grpReady.setVisibility(View.VISIBLE); pbWait.setVisibility(View.GONE); @@ -131,7 +192,6 @@ public class ActivityWidgetUnified extends ActivityBase { @Override protected void onException(Bundle args, Throwable ex) { - Log.e(ex); Helper.unexpectedError(getSupportFragmentManager(), ex); } }.execute(this, new Bundle(), "widget:accounts"); diff --git a/app/src/main/java/eu/faircode/email/DaoMessage.java b/app/src/main/java/eu/faircode/email/DaoMessage.java index 68458ff088..3695f4a3df 100644 --- a/app/src/main/java/eu/faircode/email/DaoMessage.java +++ b/app/src/main/java/eu/faircode/email/DaoMessage.java @@ -323,7 +323,8 @@ public interface DaoMessage { " ORDER BY message.received") LiveData> liveUnseenNotify(); - String widget_unified = "SELECT message.*, account.name AS accountName" + + String widget_unified = "SELECT message.*" + + ", account.name AS accountName, folder.unified AS folderUnified" + ", SUM(1 - message.ui_seen) AS unseen" + ", COUNT(message.id) - SUM(message.ui_flagged) AS unflagged" + ", MAX(message.received) AS dummy" + @@ -331,7 +332,6 @@ public interface DaoMessage { " JOIN account ON account.id = message.account" + " JOIN folder ON folder.id = message.folder" + " WHERE account.`synchronize`" + - " AND folder.unified" + " AND NOT message.ui_hide" + " AND message.ui_snoozed IS NULL" + " AND (NOT :unseen OR NOT message.ui_seen)" + diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index 6041822848..4c37d27b8f 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -56,7 +56,6 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.RejectedExecutionException; @@ -261,14 +260,7 @@ public class ServiceSynchronize extends ServiceBase { for (int i = 0; i < last.size(); i++) { TupleMessageWidget m1 = last.get(i); TupleMessageWidget m2 = messages.get(i); - if (!m1.id.equals(m2.id) || - !Objects.equals(m1.account, m2.account) || - !Objects.equals(m1.accountName, m2.accountName) || - !MessageHelper.equal(m1.from, m2.from) || - !m1.received.equals(m2.received) || - !Objects.equals(m1.subject, m2.subject) || - !(m1.unseen == m2.unseen) || - !(m1.unflagged == m2.unflagged)) { + if (!m1.equals(m2)) { changed = true; break; } diff --git a/app/src/main/java/eu/faircode/email/TupleMessageWidget.java b/app/src/main/java/eu/faircode/email/TupleMessageWidget.java index df09ac2897..4fe9af61c4 100644 --- a/app/src/main/java/eu/faircode/email/TupleMessageWidget.java +++ b/app/src/main/java/eu/faircode/email/TupleMessageWidget.java @@ -23,15 +23,22 @@ import java.util.Objects; public class TupleMessageWidget extends EntityMessage { public String accountName; + public boolean folderUnified; public int unseen; public int unflagged; @Override public boolean equals(Object obj) { - if (obj instanceof TupleMessageEx) { - TupleMessageEx other = (TupleMessageEx) obj; - return (super.equals(obj) && + if (obj instanceof TupleMessageWidget) { + TupleMessageWidget other = (TupleMessageWidget) obj; + return (this.id.equals(other.id) && + this.account.equals(other.account) && Objects.equals(this.accountName, other.accountName) && + this.folder.equals(other.folder) && + this.folderUnified == other.folderUnified && + MessageHelper.equal(this.from, other.from) && + this.received.equals(other.received) && + Objects.equals(this.subject, other.subject) && this.unseen == other.unseen && this.unflagged == other.unflagged); } diff --git a/app/src/main/java/eu/faircode/email/WidgetUnifiedRemoteViewsFactory.java b/app/src/main/java/eu/faircode/email/WidgetUnifiedRemoteViewsFactory.java index 2da54742b7..604b94edd1 100644 --- a/app/src/main/java/eu/faircode/email/WidgetUnifiedRemoteViewsFactory.java +++ b/app/src/main/java/eu/faircode/email/WidgetUnifiedRemoteViewsFactory.java @@ -45,6 +45,7 @@ public class WidgetUnifiedRemoteViewsFactory implements RemoteViewsService.Remot private boolean threading; private boolean subject_top; private boolean subject_italic; + private long folder; private long account; private boolean unseen; private boolean flagged; @@ -73,6 +74,7 @@ public class WidgetUnifiedRemoteViewsFactory implements RemoteViewsService.Remot subject_top = prefs.getBoolean("subject_top", false); subject_italic = prefs.getBoolean("subject_italic", true); account = prefs.getLong("widget." + appWidgetId + ".account", -1L); + folder = prefs.getLong("widget." + appWidgetId + ".folder", -1L); unseen = prefs.getBoolean("widget." + appWidgetId + ".unseen", false); flagged = prefs.getBoolean("widget." + appWidgetId + ".flagged", false); colorWidgetForeground = ContextCompat.getColor(context, R.color.colorWidgetForeground); @@ -83,7 +85,8 @@ public class WidgetUnifiedRemoteViewsFactory implements RemoteViewsService.Remot DB db = DB.getInstance(context); List wmessages = db.message().getWidgetUnified(threading, unseen, flagged); for (TupleMessageWidget wmessage : wmessages) - if (account < 0 || wmessage.account == account) + if ((account < 0 || wmessage.account == account) && + (folder < 0 ? wmessage.folderUnified : wmessage.folder == folder)) messages.add(wmessage); } @@ -117,11 +120,7 @@ public class WidgetUnifiedRemoteViewsFactory implements RemoteViewsService.Remot thread.putExtra("id", message.id); views.setOnClickFillInIntent(R.id.llMessage, thread); - String froms = MessageHelper.formatAddressesShort(message.from); - if (message.unseen > 1) - froms = context.getString(R.string.title_name_count, froms, Integer.toString(message.unseen)); - - SpannableString ssFrom = new SpannableString(froms); + SpannableString ssFrom = new SpannableString(MessageHelper.formatAddressesShort(message.from)); SpannableString ssTime = new SpannableString(Helper.getRelativeTimeSpanString(context, message.received)); SpannableString ssSubject = new SpannableString(TextUtils.isEmpty(message.subject) ? "" : message.subject); SpannableString ssAccount = new SpannableString(TextUtils.isEmpty(message.accountName) ? "" : message.accountName); diff --git a/app/src/main/res/layout/activity_widget_unified.xml b/app/src/main/res/layout/activity_widget_unified.xml index e9ec03f54f..77876a155f 100644 --- a/app/src/main/res/layout/activity_widget_unified.xml +++ b/app/src/main/res/layout/activity_widget_unified.xml @@ -22,6 +22,24 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tvAccount" /> + + + + + app:layout_constraintTop_toBottomOf="@+id/spFolder" /> + app:constraint_referenced_ids="tvAccount,spAccount,tvFolder,spFolder,cbUnseen,cbFlagged,btnSave" /> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fc94da216b..f40d261086 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -968,6 +968,8 @@ Account All + Folder + Unified inbox folders Unread messages only Starred messages only