mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-07 09:38:52 -06:00
Add option to make notifications sticky
This commit is contained in:
@@ -50,19 +50,19 @@ public class PendingIntentFactory
|
|||||||
public PendingIntent addCheckmark(@NonNull Habit habit,
|
public PendingIntent addCheckmark(@NonNull Habit habit,
|
||||||
@Nullable Long timestamp)
|
@Nullable Long timestamp)
|
||||||
{
|
{
|
||||||
Uri data = habit.getUri();
|
|
||||||
Intent checkIntent = new Intent(context, WidgetReceiver.class);
|
Intent checkIntent = new Intent(context, WidgetReceiver.class);
|
||||||
checkIntent.setData(data);
|
checkIntent.setData(habit.getUri());
|
||||||
checkIntent.setAction(WidgetReceiver.ACTION_ADD_REPETITION);
|
checkIntent.setAction(WidgetReceiver.ACTION_ADD_REPETITION);
|
||||||
if (timestamp != null) checkIntent.putExtra("timestamp", timestamp);
|
if (timestamp != null) checkIntent.putExtra("timestamp", timestamp);
|
||||||
return PendingIntent.getBroadcast(context, 1, checkIntent,
|
return PendingIntent.getBroadcast(context, 1, checkIntent,
|
||||||
FLAG_UPDATE_CURRENT);
|
FLAG_UPDATE_CURRENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PendingIntent dismissNotification()
|
public PendingIntent dismissNotification(@NonNull Habit habit)
|
||||||
{
|
{
|
||||||
Intent deleteIntent = new Intent(context, ReminderReceiver.class);
|
Intent deleteIntent = new Intent(context, ReminderReceiver.class);
|
||||||
deleteIntent.setAction(WidgetReceiver.ACTION_DISMISS_REMINDER);
|
deleteIntent.setAction(WidgetReceiver.ACTION_DISMISS_REMINDER);
|
||||||
|
deleteIntent.setData(habit.getUri());
|
||||||
return PendingIntent.getBroadcast(context, 0, deleteIntent,
|
return PendingIntent.getBroadcast(context, 0, deleteIntent,
|
||||||
FLAG_UPDATE_CURRENT);
|
FLAG_UPDATE_CURRENT);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,16 +29,20 @@ import org.isoron.uhabits.*;
|
|||||||
import org.isoron.uhabits.commands.*;
|
import org.isoron.uhabits.commands.*;
|
||||||
import org.isoron.uhabits.intents.*;
|
import org.isoron.uhabits.intents.*;
|
||||||
import org.isoron.uhabits.models.*;
|
import org.isoron.uhabits.models.*;
|
||||||
|
import org.isoron.uhabits.preferences.*;
|
||||||
import org.isoron.uhabits.tasks.*;
|
import org.isoron.uhabits.tasks.*;
|
||||||
import org.isoron.uhabits.utils.*;
|
import org.isoron.uhabits.utils.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import javax.inject.*;
|
import javax.inject.*;
|
||||||
|
|
||||||
import static android.graphics.BitmapFactory.*;
|
import static android.graphics.BitmapFactory.*;
|
||||||
import static org.isoron.uhabits.utils.RingtoneUtils.*;
|
import static org.isoron.uhabits.utils.RingtoneUtils.*;
|
||||||
|
|
||||||
@AppScope
|
@AppScope
|
||||||
public class NotificationTray implements CommandRunner.Listener
|
public class NotificationTray
|
||||||
|
implements CommandRunner.Listener, Preferences.Listener
|
||||||
{
|
{
|
||||||
@NonNull
|
@NonNull
|
||||||
private final Context context;
|
private final Context context;
|
||||||
@@ -49,32 +53,42 @@ public class NotificationTray implements CommandRunner.Listener
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final PendingIntentFactory pendingIntents;
|
private final PendingIntentFactory pendingIntents;
|
||||||
|
|
||||||
private CommandRunner commandRunner;
|
@NonNull
|
||||||
|
private final CommandRunner commandRunner;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final Preferences preferences;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final HashMap<Habit, NotificationData> active;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public NotificationTray(@AppContext @NonNull Context context,
|
public NotificationTray(@AppContext @NonNull Context context,
|
||||||
@NonNull TaskRunner taskRunner,
|
@NonNull TaskRunner taskRunner,
|
||||||
@NonNull PendingIntentFactory pendingIntents,
|
@NonNull PendingIntentFactory pendingIntents,
|
||||||
@NonNull CommandRunner commandRunner)
|
@NonNull CommandRunner commandRunner,
|
||||||
|
@NonNull Preferences preferences)
|
||||||
{
|
{
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.taskRunner = taskRunner;
|
this.taskRunner = taskRunner;
|
||||||
this.pendingIntents = pendingIntents;
|
this.pendingIntents = pendingIntents;
|
||||||
this.commandRunner = commandRunner;
|
this.commandRunner = commandRunner;
|
||||||
|
this.preferences = preferences;
|
||||||
|
this.active = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancel(@NonNull Habit habit)
|
public void cancel(@NonNull Habit habit)
|
||||||
{
|
{
|
||||||
int notificationId = getNotificationId(habit);
|
int notificationId = getNotificationId(habit);
|
||||||
NotificationManagerCompat.from(context).cancel(notificationId);
|
NotificationManagerCompat.from(context).cancel(notificationId);
|
||||||
|
active.remove(habit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCommandExecuted(@NonNull Command command,
|
public void onCommandExecuted(@NonNull Command command,
|
||||||
@Nullable Long refreshKey)
|
@Nullable Long refreshKey)
|
||||||
{
|
{
|
||||||
if (!(command instanceof ToggleRepetitionCommand))
|
if (!(command instanceof ToggleRepetitionCommand)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
ToggleRepetitionCommand toggleCommand =
|
ToggleRepetitionCommand toggleCommand =
|
||||||
(ToggleRepetitionCommand) command;
|
(ToggleRepetitionCommand) command;
|
||||||
@@ -84,20 +98,29 @@ public class NotificationTray implements CommandRunner.Listener
|
|||||||
cancel(habit);
|
cancel(habit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNotificationsChanged()
|
||||||
|
{
|
||||||
|
reshowAll();
|
||||||
|
}
|
||||||
|
|
||||||
public void show(@NonNull Habit habit, long timestamp, long reminderTime)
|
public void show(@NonNull Habit habit, long timestamp, long reminderTime)
|
||||||
{
|
{
|
||||||
taskRunner.execute(
|
NotificationData data = new NotificationData(timestamp, reminderTime);
|
||||||
new ShowNotificationTask(habit, timestamp, reminderTime));
|
active.put(habit, data);
|
||||||
|
taskRunner.execute(new ShowNotificationTask(habit, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startListening()
|
public void startListening()
|
||||||
{
|
{
|
||||||
commandRunner.addListener(this);
|
commandRunner.addListener(this);
|
||||||
|
preferences.addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopListening()
|
public void stopListening()
|
||||||
{
|
{
|
||||||
commandRunner.removeListener(this);
|
commandRunner.removeListener(this);
|
||||||
|
preferences.removeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getNotificationId(Habit habit)
|
private int getNotificationId(Habit habit)
|
||||||
@@ -107,6 +130,28 @@ public class NotificationTray implements CommandRunner.Listener
|
|||||||
return (int) (id % Integer.MAX_VALUE);
|
return (int) (id % Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void reshowAll()
|
||||||
|
{
|
||||||
|
for (Habit habit : active.keySet())
|
||||||
|
{
|
||||||
|
NotificationData data = active.get(habit);
|
||||||
|
taskRunner.execute(new ShowNotificationTask(habit, data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NotificationData
|
||||||
|
{
|
||||||
|
public final long timestamp;
|
||||||
|
|
||||||
|
public final long reminderTime;
|
||||||
|
|
||||||
|
public NotificationData(long timestamp, long reminderTime)
|
||||||
|
{
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.reminderTime = reminderTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class ShowNotificationTask implements Task
|
private class ShowNotificationTask implements Task
|
||||||
{
|
{
|
||||||
int todayValue;
|
int todayValue;
|
||||||
@@ -117,13 +162,11 @@ public class NotificationTray implements CommandRunner.Listener
|
|||||||
|
|
||||||
private final long reminderTime;
|
private final long reminderTime;
|
||||||
|
|
||||||
public ShowNotificationTask(Habit habit,
|
public ShowNotificationTask(Habit habit, NotificationData data)
|
||||||
long timestamp,
|
|
||||||
long reminderTime)
|
|
||||||
{
|
{
|
||||||
this.habit = habit;
|
this.habit = habit;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = data.timestamp;
|
||||||
this.reminderTime = reminderTime;
|
this.reminderTime = data.reminderTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -148,7 +191,7 @@ public class NotificationTray implements CommandRunner.Listener
|
|||||||
.setContentTitle(habit.getName())
|
.setContentTitle(habit.getName())
|
||||||
.setContentText(habit.getDescription())
|
.setContentText(habit.getDescription())
|
||||||
.setContentIntent(pendingIntents.showHabit(habit))
|
.setContentIntent(pendingIntents.showHabit(habit))
|
||||||
.setDeleteIntent(pendingIntents.dismissNotification())
|
.setDeleteIntent(pendingIntents.dismissNotification(habit))
|
||||||
.addAction(R.drawable.ic_action_check,
|
.addAction(R.drawable.ic_action_check,
|
||||||
context.getString(R.string.check),
|
context.getString(R.string.check),
|
||||||
pendingIntents.addCheckmark(habit, timestamp))
|
pendingIntents.addCheckmark(habit, timestamp))
|
||||||
@@ -159,6 +202,7 @@ public class NotificationTray implements CommandRunner.Listener
|
|||||||
.extend(wearableExtender)
|
.extend(wearableExtender)
|
||||||
.setWhen(reminderTime)
|
.setWhen(reminderTime)
|
||||||
.setShowWhen(true)
|
.setShowWhen(true)
|
||||||
|
.setOngoing(preferences.shouldMakeNotificationsSticky())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
NotificationManager notificationManager =
|
NotificationManager notificationManager =
|
||||||
@@ -179,6 +223,5 @@ public class NotificationTray implements CommandRunner.Listener
|
|||||||
|
|
||||||
return reminderDays[weekday];
|
return reminderDays[weekday];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,6 +169,11 @@ public class Preferences
|
|||||||
shouldReverseCheckmarks = null;
|
shouldReverseCheckmarks = null;
|
||||||
for(Listener l : listeners) l.onCheckmarkOrderChanged();
|
for(Listener l : listeners) l.onCheckmarkOrderChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(key.equals("pref_sticky_notifications"))
|
||||||
|
{
|
||||||
|
for(Listener l : listeners) l.onNotificationsChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeListener(Listener listener)
|
public void removeListener(Listener listener)
|
||||||
@@ -200,6 +205,11 @@ public class Preferences
|
|||||||
return shouldReverseCheckmarks;
|
return shouldReverseCheckmarks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean shouldMakeNotificationsSticky()
|
||||||
|
{
|
||||||
|
return prefs.getBoolean("pref_sticky_notifications", false);
|
||||||
|
}
|
||||||
|
|
||||||
public void updateLastAppVersion()
|
public void updateLastAppVersion()
|
||||||
{
|
{
|
||||||
prefs.edit().putInt("last_version", BuildConfig.VERSION_CODE).apply();
|
prefs.edit().putInt("last_version", BuildConfig.VERSION_CODE).apply();
|
||||||
@@ -223,5 +233,7 @@ public class Preferences
|
|||||||
public interface Listener
|
public interface Listener
|
||||||
{
|
{
|
||||||
default void onCheckmarkOrderChanged() {}
|
default void onCheckmarkOrderChanged() {}
|
||||||
|
|
||||||
|
default void onNotificationsChanged() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,6 @@ public class ReminderController
|
|||||||
|
|
||||||
public void onDismiss(@NonNull Habit habit)
|
public void onDismiss(@NonNull Habit habit)
|
||||||
{
|
{
|
||||||
// nop
|
notificationTray.cancel(habit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,4 +185,7 @@
|
|||||||
<string name="filter">Filter</string>
|
<string name="filter">Filter</string>
|
||||||
<string name="hide_completed">Hide completed</string>
|
<string name="hide_completed">Hide completed</string>
|
||||||
<string name="hide_archived">Hide archived</string>
|
<string name="hide_archived">Hide archived</string>
|
||||||
|
|
||||||
|
<string name="sticky_notifications">Make notifications sticky</string>
|
||||||
|
<string name="sticky_notifications_description">Prevents notifications from being swiped away.</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -62,6 +62,12 @@
|
|||||||
android:key="reminderSound"
|
android:key="reminderSound"
|
||||||
android:title="@string/reminder_sound"/>
|
android:title="@string/reminder_sound"/>
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="pref_sticky_notifications"
|
||||||
|
android:title="@string/sticky_notifications"
|
||||||
|
android:summary="@string/sticky_notifications_description"/>
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
|||||||
Reference in New Issue
Block a user