From b277eda261c8815ee7e611fc6e18d3b76a53d238 Mon Sep 17 00:00:00 2001 From: M66B Date: Sun, 5 Nov 2023 10:17:59 +0100 Subject: [PATCH] Added folder select to count widget --- .../eu/faircode/email/ActivityWidget.java | 104 +++++++++++++++++- .../java/eu/faircode/email/DaoFolder.java | 7 +- .../java/eu/faircode/email/DaoMessage.java | 11 +- .../eu/faircode/email/TupleMessageStats.java | 2 + .../main/java/eu/faircode/email/Widget.java | 10 +- app/src/main/res/layout/activity_widget.xml | 20 +++- app/src/main/res/values/strings.xml | 1 + 7 files changed, 139 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/ActivityWidget.java b/app/src/main/java/eu/faircode/email/ActivityWidget.java index 3d7e24d001..59d093e683 100644 --- a/app/src/main/java/eu/faircode/email/ActivityWidget.java +++ b/app/src/main/java/eu/faircode/email/ActivityWidget.java @@ -29,6 +29,7 @@ import android.os.Build; import android.os.Bundle; import android.util.TypedValue; import android.view.View; +import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; @@ -39,6 +40,8 @@ import android.widget.RadioButton; import android.widget.Spinner; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.constraintlayout.widget.Group; import androidx.core.content.ContextCompat; import androidx.core.graphics.ColorUtils; @@ -49,12 +52,14 @@ import com.flask.colorpicker.builder.ColorPickerClickListener; import com.flask.colorpicker.builder.ColorPickerDialogBuilder; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class ActivityWidget extends ActivityBase { private int appWidgetId; private Spinner spAccount; + private Spinner spFolder; private CheckBox cbDayNight; private CheckBox cbSemiTransparent; private ViewButtonColor btnBgColor; @@ -70,6 +75,7 @@ public class ActivityWidget extends ActivityBase { private Group grpReady; private ArrayAdapter adapterAccount; + private ArrayAdapter adapterFolder; @Override protected void onCreate(Bundle savedInstanceState) { @@ -86,6 +92,7 @@ public class ActivityWidget extends ActivityBase { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); long account = prefs.getLong("widget." + appWidgetId + ".account", -1L); + long folder = prefs.getLong("widget." + appWidgetId + ".folder", -1L); boolean daynight = prefs.getBoolean("widget." + appWidgetId + ".daynight", false); boolean semi = prefs.getBoolean("widget." + appWidgetId + ".semi", true); int background = prefs.getInt("widget." + appWidgetId + ".background", Color.TRANSPARENT); @@ -101,6 +108,7 @@ public class ActivityWidget extends ActivityBase { setContentView(R.layout.activity_widget); spAccount = findViewById(R.id.spAccount); + spFolder = findViewById(R.id.spFolder); cbDayNight = findViewById(R.id.cbDayNight); cbSemiTransparent = findViewById(R.id.cbSemiTransparent); btnBgColor = findViewById(R.id.btnBgColor); @@ -256,14 +264,19 @@ public class ActivityWidget extends ActivityBase { @Override public void onClick(View view) { EntityAccount account = (EntityAccount) spAccount.getSelectedItem(); + EntityFolder folder = (EntityFolder) spFolder.getSelectedItem(); int pos = spFontSize.getSelectedItemPosition(); SharedPreferences.Editor editor = prefs.edit(); - if (account != null && account.id > 0) - editor.putString("widget." + appWidgetId + ".name", account.name); - else - editor.remove("widget." + appWidgetId + ".name"); + if (folder == null) { + if (account != null && account.id > 0) + editor.putString("widget." + appWidgetId + ".name", account.name); + else + editor.remove("widget." + appWidgetId + ".name"); + } else + editor.putString("widget." + appWidgetId + ".name", folder.getDisplayName(ActivityWidget.this)); editor.putLong("widget." + appWidgetId + ".account", account == null ? -1L : account.id); + editor.putLong("widget." + appWidgetId + ".folder", folder == null ? -1L : folder.id); editor.putBoolean("widget." + appWidgetId + ".daynight", cbDayNight.isChecked()); editor.putBoolean("widget." + appWidgetId + ".semi", cbSemiTransparent.isChecked()); editor.putInt("widget." + appWidgetId + ".background", btnBgColor.getColor()); @@ -288,6 +301,89 @@ public class ActivityWidget extends ActivityBase { adapterAccount.setDropDownViewResource(R.layout.spinner_item1_dropdown); spAccount.setAdapter(adapterAccount); + adapterFolder = new ArrayAdapter(this, R.layout.spinner_item1, android.R.id.text1, new ArrayList()) { + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + return localize(position, super.getView(position, convertView, parent)); + } + + @Override + public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + return localize(position, super.getDropDownView(position, convertView, parent)); + } + + private View localize(int position, View view) { + EntityFolder folder = getItem(position); + if (folder != null) { + TextView tv = view.findViewById(android.R.id.text1); + tv.setText(EntityFolder.localizeName(view.getContext(), folder.name)); + } + return view; + } + }; + 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().getNotifyingFolders(account); + if (folders != null && folders.size() > 0) + Collections.sort(folders, folders.get(0).getComparator(context)); + return folders; + } + + @Override + protected void onExecuted(Bundle args, List folders) { + if (folders == null) + folders = new ArrayList<>(); + + EntityFolder notifying = new EntityFolder(); + notifying.id = -1L; + notifying.name = getString(R.string.title_widget_folder_notifying); + folders.add(0, notifying); + + adapterFolder.clear(); + adapterFolder.addAll(folders); + + int select = 0; + for (int i = 0; i < folders.size(); i++) + if (folders.get(i).id.equals(folder)) { + select = i; + break; + } + + spFolder.setSelection(select); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Log.unexpectedError(getSupportFragmentManager(), ex); + } + }.execute(ActivityWidget.this, args, "widget:folders"); + } + }); + // Initialize ((TextView) inOld.findViewById(R.id.tvCount)).setText("3"); ((TextView) inNew.findViewById(R.id.tvCount)).setText("3"); diff --git a/app/src/main/java/eu/faircode/email/DaoFolder.java b/app/src/main/java/eu/faircode/email/DaoFolder.java index b660465888..da842bbb58 100644 --- a/app/src/main/java/eu/faircode/email/DaoFolder.java +++ b/app/src/main/java/eu/faircode/email/DaoFolder.java @@ -174,10 +174,11 @@ public interface DaoFolder { " AND folder.synchronize") List getSynchronizingFolders(long account); - @Query("SELECT * FROM folder" + + @Query("SELECT folder.* FROM folder" + + " JOIN account_view AS account ON account.id = folder.account" + " WHERE folder.account = :account" + - " AND folder.`synchronize`" + - " AND folder.notify") + " AND folder.notify" + + " AND account.`synchronize`") List getNotifyingFolders(long account); @Query("SELECT * FROM folder" + diff --git a/app/src/main/java/eu/faircode/email/DaoMessage.java b/app/src/main/java/eu/faircode/email/DaoMessage.java index 342ca26590..5b0c78a9a4 100644 --- a/app/src/main/java/eu/faircode/email/DaoMessage.java +++ b/app/src/main/java/eu/faircode/email/DaoMessage.java @@ -568,7 +568,7 @@ public interface DaoMessage { LiveData> liveUnseenNotify(); @Transaction - @Query("SELECT account.id AS account," + + @Query("SELECT account.id AS account, folder.id AS folder," + " COUNT(message.id) AS unseen," + " SUM(CASE WHEN account.created IS NULL OR message.received > account.created OR message.sent > account.created THEN NOT ui_ignored ELSE 0 END) AS notifying" + " FROM message" + @@ -579,11 +579,11 @@ public interface DaoMessage { " AND folder.notify" + " AND message.notifying <> " + EntityMessage.NOTIFYING_IGNORE + " AND NOT (message.ui_seen OR message.ui_hide)" + - " GROUP BY account.id" + - " ORDER BY account.id") + " GROUP BY folder.id" + + " ORDER BY folder.id") LiveData> liveWidgetUnseen(Long account); - @Query("SELECT :account AS account," + + @Query("SELECT :account AS account, folder.id AS folder," + " COUNT(message.id) AS unseen," + " SUM(CASE WHEN account.created IS NULL OR message.received > account.created OR message.sent > account.created THEN NOT ui_ignored ELSE 0 END) AS notifying" + " FROM message" + @@ -591,10 +591,11 @@ public interface DaoMessage { " JOIN folder_view AS folder ON folder.id = message.folder" + " WHERE (:account IS NULL OR account.id = :account)" + " AND account.`synchronize`" + + " AND (:folder IS NULL OR folder.id = :folder)" + " AND folder.notify" + " AND message.notifying <> " + EntityMessage.NOTIFYING_IGNORE + " AND NOT (message.ui_seen OR message.ui_hide)") - TupleMessageStats getWidgetUnseen(Long account); + TupleMessageStats getWidgetUnseen(Long account, Long folder); @Transaction @Query("SELECT folder, COUNT(*) AS total" + diff --git a/app/src/main/java/eu/faircode/email/TupleMessageStats.java b/app/src/main/java/eu/faircode/email/TupleMessageStats.java index f66a0da070..4f8e18999b 100644 --- a/app/src/main/java/eu/faircode/email/TupleMessageStats.java +++ b/app/src/main/java/eu/faircode/email/TupleMessageStats.java @@ -26,6 +26,7 @@ import java.util.Objects; public class TupleMessageStats { public Long account; + public Long folder; public Integer unseen; public Integer notifying; @@ -34,6 +35,7 @@ public class TupleMessageStats { if (obj instanceof TupleMessageStats) { TupleMessageStats other = (TupleMessageStats) obj; return (Objects.equals(this.account, other.account) && + Objects.equals(this.folder, other.folder) && Objects.equals(this.unseen, other.unseen) && Objects.equals(this.notifying, other.notifying)); } else diff --git a/app/src/main/java/eu/faircode/email/Widget.java b/app/src/main/java/eu/faircode/email/Widget.java index eb6658a56e..6cd568e3cf 100644 --- a/app/src/main/java/eu/faircode/email/Widget.java +++ b/app/src/main/java/eu/faircode/email/Widget.java @@ -59,6 +59,7 @@ public class Widget extends AppWidgetProvider { for (int appWidgetId : appWidgetIds) { String name = prefs.getString("widget." + appWidgetId + ".name", null); long account = prefs.getLong("widget." + appWidgetId + ".account", -1L); + long folder = prefs.getLong("widget." + appWidgetId + ".folder", -1L); boolean daynight = prefs.getBoolean("widget." + appWidgetId + ".daynight", false); boolean semi = prefs.getBoolean("widget." + appWidgetId + ".semi", true); int background = prefs.getInt("widget." + appWidgetId + ".background", Color.TRANSPARENT); @@ -76,7 +77,7 @@ public class Widget extends AppWidgetProvider { folders = new ArrayList<>(); PendingIntent pi; - if (folders.size() == 1) { + if (folders.size() == 1 || folder >= 0) { Intent view = new Intent(context, ActivityView.class); view.setAction("folder:" + folders.get(0).id); view.putExtra("account", account); @@ -106,8 +107,11 @@ public class Widget extends AppWidgetProvider { } } - TupleMessageStats stats = db.message().getWidgetUnseen(account < 0 ? null : account); - EntityLog.log(context, "Widget account=" + account + " ignore=" + unseen_ignored + " " + stats); + TupleMessageStats stats = db.message().getWidgetUnseen( + account < 0 ? null : account, + folder < 0 ? null : folder); + EntityLog.log(context, "Widget account=" + account + " folder=" + folder + + " ignore=" + unseen_ignored + " " + stats); Integer unseen = (unseen_ignored ? stats.notifying : stats.unseen); if (unseen == null) diff --git a/app/src/main/res/layout/activity_widget.xml b/app/src/main/res/layout/activity_widget.xml index 2a98097f9f..5f804b9b7e 100644 --- a/app/src/main/res/layout/activity_widget.xml +++ b/app/src/main/res/layout/activity_widget.xml @@ -30,6 +30,24 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tvAccount" /> + + + + + app:layout_constraintTop_toBottomOf="@id/spFolder" /> All Folder Unified inbox folders + Folders with new message notifications Unread messages only Starred messages only Text size