mirror of
https://github.com/M66B/FairEmail.git
synced 2025-01-01 04:35:57 +00:00
Decouple notifications and widget/badge
This commit is contained in:
parent
ebc7c98425
commit
8511de077a
5 changed files with 99 additions and 36 deletions
|
@ -108,15 +108,11 @@ import javax.mail.search.OrTerm;
|
|||
import javax.mail.search.ReceivedDateTerm;
|
||||
import javax.mail.search.SearchTerm;
|
||||
|
||||
import me.leolin.shortcutbadger.ShortcutBadger;
|
||||
|
||||
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
|
||||
import static androidx.core.app.NotificationCompat.DEFAULT_LIGHTS;
|
||||
import static androidx.core.app.NotificationCompat.DEFAULT_SOUND;
|
||||
|
||||
class Core {
|
||||
private static int lastUnseen = -1;
|
||||
|
||||
private static final int MAX_NOTIFICATION_COUNT = 100; // per group
|
||||
private static final long AFTER_SEND_DELAY = 10 * 1000L; // milliseconds
|
||||
private static final int SYNC_CHUNCK_SIZE = 200;
|
||||
|
@ -2246,16 +2242,6 @@ class Core {
|
|||
}
|
||||
}
|
||||
|
||||
static void notifyReset(Context context) {
|
||||
lastUnseen = -1;
|
||||
Widget.update(context, -1);
|
||||
try {
|
||||
ShortcutBadger.removeCount(context);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
}
|
||||
|
||||
static void notifyMessages(Context context, List<TupleMessageEx> messages, Map<Long, List<Long>> groupNotifying) {
|
||||
if (messages == null)
|
||||
messages = new ArrayList<>();
|
||||
|
@ -2265,21 +2251,14 @@ class Core {
|
|||
if (nm == null)
|
||||
return;
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
boolean badge = prefs.getBoolean("badge", true);
|
||||
boolean unseen_ignored = prefs.getBoolean("unseen_ignored", false);
|
||||
boolean pro = ActivityBilling.isPro(context);
|
||||
|
||||
int unseen = 0;
|
||||
Map<Long, List<TupleMessageEx>> groupMessages = new HashMap<>();
|
||||
for (long group : groupNotifying.keySet())
|
||||
groupMessages.put(group, new ArrayList<>());
|
||||
|
||||
// Current
|
||||
for (TupleMessageEx message : messages) {
|
||||
if (!message.ui_seen && (!unseen_ignored || !message.ui_ignored) && message.ui_hide == 0)
|
||||
unseen++;
|
||||
|
||||
// Check if notification channel enabled
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O &&
|
||||
message.notifying == 0 && message.from != null && message.from.length > 0) {
|
||||
|
@ -2311,17 +2290,6 @@ class Core {
|
|||
}
|
||||
}
|
||||
|
||||
// Update widget/badge count
|
||||
if (lastUnseen < 0 || unseen != lastUnseen) {
|
||||
lastUnseen = unseen;
|
||||
Widget.update(context, unseen);
|
||||
try {
|
||||
ShortcutBadger.applyCount(context, badge ? unseen : 0);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Difference
|
||||
for (long group : groupMessages.keySet()) {
|
||||
// Difference
|
||||
|
|
|
@ -248,6 +248,15 @@ public interface DaoMessage {
|
|||
" WHERE message.id = :id")
|
||||
LiveData<TupleMessageEx> liveMessage(long id);
|
||||
|
||||
@Query("SELECT COUNT(message.id) AS unseen, SUM(message.ui_ignored) AS ignored" +
|
||||
" FROM message" +
|
||||
" JOIN account ON account.id = message.account" +
|
||||
" JOIN folder ON folder.id = message.folder" +
|
||||
" WHERE account.`synchronize`" +
|
||||
" AND folder.notify" +
|
||||
" AND NOT (message.ui_seen OR message.ui_hide <> 0)")
|
||||
LiveData<TupleMessageStats> liveUnseen();
|
||||
|
||||
@Query("SELECT message.*" +
|
||||
", account.pop AS accountPop, account.name AS accountName, IFNULL(identity.color, account.color) AS accountColor, account.notify AS accountNotify" +
|
||||
", folder.name AS folderName, folder.display AS folderDisplay, folder.type AS folderType, folder.read_only AS folderReadOnly" +
|
||||
|
|
|
@ -78,6 +78,8 @@ import javax.mail.event.MessageCountEvent;
|
|||
import javax.mail.event.StoreEvent;
|
||||
import javax.mail.event.StoreListener;
|
||||
|
||||
import me.leolin.shortcutbadger.ShortcutBadger;
|
||||
|
||||
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
|
||||
|
||||
public class ServiceSynchronize extends ServiceBase {
|
||||
|
@ -145,6 +147,28 @@ public class ServiceSynchronize extends ServiceBase {
|
|||
}
|
||||
});
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
db.message().liveUnseen().observe(this, new Observer<TupleMessageStats>() {
|
||||
private TupleMessageStats lastStats = null;
|
||||
|
||||
@Override
|
||||
public void onChanged(TupleMessageStats stats) {
|
||||
if (stats != null) {
|
||||
boolean unseen_ignored = prefs.getBoolean("unseen_ignored", false);
|
||||
if (!unseen_ignored || stats.ignored == null)
|
||||
stats.ignored = 0;
|
||||
|
||||
if (!stats.equals(lastStats)) {
|
||||
Log.i("Stats " + stats);
|
||||
lastStats = stats;
|
||||
|
||||
setUnseen(stats.unseen - stats.ignored);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final TwoStateOwner cowner = new TwoStateOwner(this, "liveUnseenNotify");
|
||||
|
||||
db.folder().liveSynchronizing().observe(this, new Observer<Integer>() {
|
||||
|
@ -264,7 +288,7 @@ public class ServiceSynchronize extends ServiceBase {
|
|||
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
cm.unregisterNetworkCallback(onNetworkCallback);
|
||||
|
||||
Core.notifyReset(this);
|
||||
setUnseen(null);
|
||||
|
||||
try {
|
||||
stopForeground(true);
|
||||
|
@ -381,6 +405,22 @@ public class ServiceSynchronize extends ServiceBase {
|
|||
return builder;
|
||||
}
|
||||
|
||||
private void setUnseen(Integer unseen) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
boolean badge = prefs.getBoolean("badge", true);
|
||||
|
||||
Widget.update(this, unseen);
|
||||
|
||||
try {
|
||||
if (unseen == null || !badge)
|
||||
ShortcutBadger.removeCount(this);
|
||||
else
|
||||
ShortcutBadger.applyCount(this, unseen);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void onAlarm() {
|
||||
schedule(this);
|
||||
onReload(true, "alarm");
|
||||
|
|
46
app/src/main/java/eu/faircode/email/TupleMessageStats.java
Normal file
46
app/src/main/java/eu/faircode/email/TupleMessageStats.java
Normal file
|
@ -0,0 +1,46 @@
|
|||
package eu.faircode.email;
|
||||
|
||||
/*
|
||||
This file is part of FairEmail.
|
||||
|
||||
FairEmail is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FairEmail is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2018-2019 by Marcel Bokhorst (M66B)
|
||||
*/
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class TupleMessageStats {
|
||||
public Integer unseen;
|
||||
public Integer ignored;
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (obj instanceof TupleMessageStats) {
|
||||
TupleMessageStats other = (TupleMessageStats) obj;
|
||||
return (Objects.equals(this.unseen, other.unseen) &&
|
||||
Objects.equals(this.ignored, other.ignored));
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "unseen=" + unseen + " ignored=" + ignored;
|
||||
}
|
||||
}
|
|
@ -46,13 +46,13 @@ public class Widget extends AppWidgetProvider {
|
|||
});
|
||||
}
|
||||
|
||||
static void update(Context context, int count) {
|
||||
static void update(Context context, Integer count) {
|
||||
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
|
||||
int[] appWidgetIds = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, Widget.class));
|
||||
update(context, appWidgetManager, appWidgetIds, count);
|
||||
}
|
||||
|
||||
private static void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds, int count) {
|
||||
private static void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds, Integer count) {
|
||||
NumberFormat nf = NumberFormat.getIntegerInstance();
|
||||
|
||||
Intent view = new Intent(context, ActivityView.class);
|
||||
|
@ -66,7 +66,7 @@ public class Widget extends AppWidgetProvider {
|
|||
|
||||
views.setOnClickPendingIntent(R.id.widget, pi);
|
||||
|
||||
if (count < 0)
|
||||
if (count == null)
|
||||
views.setTextViewText(R.id.tvCount, "?");
|
||||
else if (count > 99)
|
||||
views.setTextViewText(R.id.tvCount, "∞");
|
||||
|
|
Loading…
Reference in a new issue