diff --git a/app/src/main/java/org/isoron/uhabits/AppComponent.java b/app/src/main/java/org/isoron/uhabits/AppComponent.java index 38b12530c..077457b56 100644 --- a/app/src/main/java/org/isoron/uhabits/AppComponent.java +++ b/app/src/main/java/org/isoron/uhabits/AppComponent.java @@ -26,7 +26,6 @@ import org.isoron.uhabits.io.*; import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.sqlite.*; import org.isoron.uhabits.preferences.*; -import org.isoron.uhabits.receivers.*; import org.isoron.uhabits.tasks.*; import org.isoron.uhabits.utils.*; import org.isoron.uhabits.widgets.*; @@ -57,14 +56,14 @@ public interface AppComponent IntentFactory getIntentFactory(); + IntentParser getIntentParser(); + ModelFactory getModelFactory(); PendingIntentFactory getPendingIntentFactory(); Preferences getPreferences(); - ReceiverActions getReceiverActions(); - ReminderScheduler getReminderScheduler(); TaskRunner getTaskRunner(); diff --git a/app/src/main/java/org/isoron/uhabits/activities/ActivityScope.java b/app/src/main/java/org/isoron/uhabits/activities/ActivityScope.java index bd4fdd818..3d02e80ae 100644 --- a/app/src/main/java/org/isoron/uhabits/activities/ActivityScope.java +++ b/app/src/main/java/org/isoron/uhabits/activities/ActivityScope.java @@ -25,6 +25,4 @@ import javax.inject.*; * Scope used by objects that live as long as the activity is alive. */ @Scope -public @interface ActivityScope -{ -} +public @interface ActivityScope { } diff --git a/app/src/main/java/org/isoron/uhabits/intents/IntentParser.java b/app/src/main/java/org/isoron/uhabits/intents/IntentParser.java index 1abd2155d..465773044 100644 --- a/app/src/main/java/org/isoron/uhabits/intents/IntentParser.java +++ b/app/src/main/java/org/isoron/uhabits/intents/IntentParser.java @@ -26,10 +26,16 @@ import android.support.annotation.*; import org.isoron.uhabits.models.*; import org.isoron.uhabits.utils.*; +import javax.inject.*; + +import static android.content.ContentUris.*; + +@Singleton public class IntentParser { private HabitList habits; + @Inject public IntentParser(@NonNull HabitList habits) { this.habits = habits; @@ -38,6 +44,8 @@ public class IntentParser public CheckmarkIntentData parseCheckmarkIntent(@NonNull Intent intent) { Uri uri = intent.getData(); + if (uri == null) throw new IllegalArgumentException("uri is null"); + CheckmarkIntentData data = new CheckmarkIntentData(); data.habit = parseHabit(uri); data.timestamp = parseTimestamp(intent); @@ -47,12 +55,9 @@ public class IntentParser @NonNull protected Habit parseHabit(@NonNull Uri uri) { - long habitId = ContentUris.parseId(uri); - - Habit habit = habits.getById(habitId); + Habit habit = habits.getById(parseId(uri)); if (habit == null) throw new IllegalArgumentException("habit not found"); - return habit; } @@ -60,7 +65,6 @@ public class IntentParser protected Long parseTimestamp(@NonNull Intent intent) { long today = DateUtils.getStartOfToday(); - Long timestamp = intent.getLongExtra("timestamp", today); timestamp = DateUtils.getStartOfDay(timestamp); diff --git a/app/src/main/java/org/isoron/uhabits/notifications/NotificationTray.java b/app/src/main/java/org/isoron/uhabits/notifications/NotificationTray.java new file mode 100644 index 000000000..fe62ccf9c --- /dev/null +++ b/app/src/main/java/org/isoron/uhabits/notifications/NotificationTray.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2016 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker 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. + * + * Loop Habit Tracker 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 this program. If not, see . + */ + +package org.isoron.uhabits.notifications; + +import android.app.*; +import android.content.*; +import android.support.annotation.*; +import android.support.v4.app.*; +import android.support.v4.app.NotificationCompat.*; + +import org.isoron.uhabits.*; +import org.isoron.uhabits.intents.*; +import org.isoron.uhabits.models.*; +import org.isoron.uhabits.tasks.*; +import org.isoron.uhabits.utils.*; + +import javax.inject.*; + +import static android.graphics.BitmapFactory.*; +import static org.isoron.uhabits.utils.RingtoneUtils.*; + +public class NotificationTray +{ + @NonNull + private final Context context; + + @NonNull + private final TaskRunner taskRunner; + + @NonNull + private final PendingIntentFactory pendingIntents; + + @Inject + public NotificationTray(@AppContext @NonNull Context context, + @NonNull TaskRunner taskRunner, + @NonNull PendingIntentFactory pendingIntents) + { + this.context = context; + this.taskRunner = taskRunner; + this.pendingIntents = pendingIntents; + } + + public void cancel(@NonNull Habit habit) + { + int notificationId = getNotificationId(habit); + NotificationManagerCompat.from(context).cancel(notificationId); + } + + public void show(@NonNull Habit habit, long timestamp, long reminderTime) + { + taskRunner.execute( + new ShowNotificationTask(habit, timestamp, reminderTime)); + } + + private int getNotificationId(Habit habit) + { + Long id = habit.getId(); + if (id == null) return 0; + return (int) (id % Integer.MAX_VALUE); + } + + private class ShowNotificationTask implements Task + { + int todayValue; + + private final Habit habit; + + private final long timestamp; + + private final long reminderTime; + + public ShowNotificationTask(Habit habit, + long timestamp, + long reminderTime) + { + this.habit = habit; + this.timestamp = timestamp; + this.reminderTime = reminderTime; + } + + @Override + public void doInBackground() + { + todayValue = habit.getCheckmarks().getTodayValue(); + } + + @Override + public void onPostExecute() + { + if (todayValue != Checkmark.UNCHECKED) return; + if (!shouldShowReminderToday()) return; + if (!habit.hasReminder()) return; + + WearableExtender wearableExtender = + new WearableExtender().setBackground( + decodeResource(context.getResources(), R.drawable.stripe)); + + Notification notification = new NotificationCompat.Builder(context) + .setSmallIcon(R.drawable.ic_notification) + .setContentTitle(habit.getName()) + .setContentText(habit.getDescription()) + .setContentIntent(pendingIntents.showHabit(habit)) + .setDeleteIntent(pendingIntents.dismissNotification()) + .addAction(R.drawable.ic_action_check, + context.getString(R.string.check), + pendingIntents.addCheckmark(habit, timestamp)) + .addAction(R.drawable.ic_action_snooze, + context.getString(R.string.snooze), + pendingIntents.snoozeNotification(habit)) + .setSound(getRingtoneUri(context)) + .extend(wearableExtender) + .setWhen(reminderTime) + .setShowWhen(true) + .build(); + + notification.flags |= Notification.FLAG_AUTO_CANCEL; + + NotificationManager notificationManager = + (NotificationManager) context.getSystemService( + Activity.NOTIFICATION_SERVICE); + + int notificationId = getNotificationId(habit); + notificationManager.notify(notificationId, notification); + } + + private boolean shouldShowReminderToday() + { + if (!habit.hasReminder()) return false; + Reminder reminder = habit.getReminder(); + + boolean reminderDays[] = reminder.getDays().toArray(); + int weekday = DateUtils.getWeekday(timestamp); + + return reminderDays[weekday]; + } + + } +} diff --git a/app/src/main/java/org/isoron/uhabits/preferences/Preferences.java b/app/src/main/java/org/isoron/uhabits/preferences/Preferences.java index e20539934..58aa651a2 100644 --- a/app/src/main/java/org/isoron/uhabits/preferences/Preferences.java +++ b/app/src/main/java/org/isoron/uhabits/preferences/Preferences.java @@ -59,6 +59,11 @@ public class Preferences return defaultScoreInterval; } + public long getSnoozeInterval() + { + return Long.parseLong(prefs.getString("pref_snooze_interval", "15")); + } + public void setDefaultScoreSpinnerPosition(int position) { prefs.edit().putInt("pref_score_view_interval", position).apply(); diff --git a/app/src/main/java/org/isoron/uhabits/receivers/ReceiverScope.java b/app/src/main/java/org/isoron/uhabits/receivers/ReceiverScope.java new file mode 100644 index 000000000..76fec08c2 --- /dev/null +++ b/app/src/main/java/org/isoron/uhabits/receivers/ReceiverScope.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker 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. + * + * Loop Habit Tracker 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 this program. If not, see . + */ + +package org.isoron.uhabits.receivers; + +import javax.inject.*; + +@Scope +public @interface ReceiverScope { } diff --git a/app/src/main/java/org/isoron/uhabits/receivers/ReminderController.java b/app/src/main/java/org/isoron/uhabits/receivers/ReminderController.java new file mode 100644 index 000000000..3db66579c --- /dev/null +++ b/app/src/main/java/org/isoron/uhabits/receivers/ReminderController.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2016 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker 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. + * + * Loop Habit Tracker 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 this program. If not, see . + */ + +package org.isoron.uhabits.receivers; + +import android.support.annotation.*; + +import org.isoron.uhabits.models.*; +import org.isoron.uhabits.notifications.*; +import org.isoron.uhabits.preferences.*; +import org.isoron.uhabits.utils.*; + +import javax.inject.*; + +@ReceiverScope +public class ReminderController +{ + @NonNull + private final ReminderScheduler reminderScheduler; + + @NonNull + private final NotificationTray notificationTray; + + private Preferences preferences; + + @Inject + public ReminderController(@NonNull ReminderScheduler reminderScheduler, + @NonNull NotificationTray notificationTray, + @NonNull Preferences preferences) + { + this.reminderScheduler = reminderScheduler; + this.notificationTray = notificationTray; + this.preferences = preferences; + } + + public void onBootCompleted() + { + reminderScheduler.scheduleAll(); + } + + public void onShowReminder(@NonNull Habit habit, + long timestamp, + long reminderTime) + { + notificationTray.show(habit, timestamp, reminderTime); + reminderScheduler.scheduleAll(); + } + + public void onSnooze(@NonNull Habit habit) + { + long snoozeInterval = preferences.getSnoozeInterval(); + + long now = DateUtils.getLocalTime(); + long reminderTime = now + snoozeInterval * 60 * 1000; + reminderScheduler.schedule(habit, reminderTime); + + notificationTray.cancel(habit); + } + + public void onDismiss(@NonNull Habit habit) + { + // nop + } +} diff --git a/app/src/main/java/org/isoron/uhabits/receivers/ReminderReceiver.java b/app/src/main/java/org/isoron/uhabits/receivers/ReminderReceiver.java index 5cc763d36..3f1ea8502 100644 --- a/app/src/main/java/org/isoron/uhabits/receivers/ReminderReceiver.java +++ b/app/src/main/java/org/isoron/uhabits/receivers/ReminderReceiver.java @@ -19,21 +19,17 @@ package org.isoron.uhabits.receivers; -import android.app.*; import android.content.*; -import android.graphics.*; -import android.net.*; -import android.os.*; -import android.preference.*; -import android.support.v4.app.*; import android.util.*; import org.isoron.uhabits.*; -import org.isoron.uhabits.intents.*; import org.isoron.uhabits.models.*; -import org.isoron.uhabits.tasks.*; import org.isoron.uhabits.utils.*; +import dagger.*; + +import static android.content.ContentUris.*; + /** * The Android BroadcastReceiver for Loop Habit Tracker. *

@@ -52,45 +48,50 @@ public class ReminderReceiver extends BroadcastReceiver private static final String TAG = "ReminderReceiver"; - private HabitList habits; - - private TaskRunner taskRunner; - - private ReminderScheduler reminderScheduler; - - private PendingIntentFactory pendingIntentFactory; - @Override public void onReceive(final Context context, Intent intent) { HabitsApplication app = (HabitsApplication) context.getApplicationContext(); - habits = app.getComponent().getHabitList(); - taskRunner = app.getComponent().getTaskRunner(); - reminderScheduler = app.getComponent().getReminderScheduler(); - pendingIntentFactory = app.getComponent().getPendingIntentFactory(); + ReminderComponent component = DaggerReminderReceiver_ReminderComponent + .builder() + .appComponent(app.getComponent()) + .build(); + + HabitList habits = app.getComponent().getHabitList(); + ReminderController reminderController = + component.getReminderController(); Log.i(TAG, String.format("Received intent: %s", intent.toString())); + long today = DateUtils.getStartOfToday(); + final Habit habit = habits.getById(parseId(intent.getData())); + final Long timestamp = intent.getLongExtra("timestamp", today); + final Long reminderTime = intent.getLongExtra("reminderTime", today); + try { switch (intent.getAction()) { case ACTION_SHOW_REMINDER: - onActionShowReminder(context, intent); + if (habit == null) return; + reminderController.onShowReminder(habit, timestamp, + reminderTime); break; case ACTION_DISMISS_REMINDER: - // NOP + if (habit == null) return; + reminderController.onDismiss(habit); break; case ACTION_SNOOZE_REMINDER: - onActionSnoozeReminder(context, intent); + if (habit == null) return; + reminderController.onSnooze(habit); break; case Intent.ACTION_BOOT_COMPLETED: - onActionBootCompleted(); + reminderController.onBootCompleted(); break; } } @@ -100,145 +101,10 @@ public class ReminderReceiver extends BroadcastReceiver } } - protected void onActionBootCompleted() - { - reminderScheduler.scheduleAll(); - } - - protected void onActionShowReminder(Context context, Intent intent) - { - createNotification(context, intent); - createReminderAlarmsDelayed(); - } - - private void createNotification(final Context context, final Intent intent) - { - final Uri data = intent.getData(); - final Habit habit = habits.getById(ContentUris.parseId(data)); - final Long timestamp = - intent.getLongExtra("timestamp", DateUtils.getStartOfToday()); - final Long reminderTime = - intent.getLongExtra("reminderTime", DateUtils.getStartOfToday()); - - if (habit == null) return; - - taskRunner.execute(new Task() - { - int todayValue; - - @Override - public void doInBackground() - { - todayValue = habit.getCheckmarks().getTodayValue(); - } - - @Override - public void onPostExecute() - { - if (todayValue != Checkmark.UNCHECKED) return; - if (!shouldShowReminderToday(intent, habit)) return; - if (!habit.hasReminder()) return; - - Intent contentIntent = new Intent(context, MainActivity.class); - contentIntent.setData(data); - PendingIntent contentPendingIntent = - PendingIntent.getActivity(context, 0, contentIntent, - PendingIntent.FLAG_CANCEL_CURRENT); - - PendingIntent dismissPendingIntent; - dismissPendingIntent = - pendingIntentFactory.dismissNotification(); - PendingIntent checkIntentPending = - pendingIntentFactory.addCheckmark(habit, timestamp); - PendingIntent snoozeIntentPending = - pendingIntentFactory.snoozeNotification(habit); - - Uri ringtoneUri = RingtoneUtils.getRingtoneUri(context); - - NotificationCompat.WearableExtender wearableExtender = - new NotificationCompat.WearableExtender().setBackground( - BitmapFactory.decodeResource(context.getResources(), - R.drawable.stripe)); - - Notification notification = - new NotificationCompat.Builder(context) - .setSmallIcon(R.drawable.ic_notification) - .setContentTitle(habit.getName()) - .setContentText(habit.getDescription()) - .setContentIntent(contentPendingIntent) - .setDeleteIntent(dismissPendingIntent) - .addAction(R.drawable.ic_action_check, - context.getString(R.string.check), - checkIntentPending) - .addAction(R.drawable.ic_action_snooze, - context.getString(R.string.snooze), - snoozeIntentPending) - .setSound(ringtoneUri) - .extend(wearableExtender) - .setWhen(reminderTime) - .setShowWhen(true) - .build(); - - notification.flags |= Notification.FLAG_AUTO_CANCEL; - - NotificationManager notificationManager = - (NotificationManager) context.getSystemService( - Activity.NOTIFICATION_SERVICE); - - int notificationId = (int) (habit.getId() % Integer.MAX_VALUE); - notificationManager.notify(notificationId, notification); - } - }); - } - - private void createReminderAlarmsDelayed() - { - new Handler().postDelayed(() -> { - reminderScheduler.scheduleAll(); - }, 5000); - } - - private void dismissNotification(Context context, Long habitId) - { - NotificationManager notificationManager = - (NotificationManager) context.getSystemService( - Activity.NOTIFICATION_SERVICE); - - int notificationId = (int) (habitId % Integer.MAX_VALUE); - notificationManager.cancel(notificationId); - } - - private void onActionSnoozeReminder(Context context, Intent intent) - { - Uri data = intent.getData(); - SharedPreferences prefs = - PreferenceManager.getDefaultSharedPreferences(context); - long delayMinutes = - Long.parseLong(prefs.getString("pref_snooze_interval", "15")); - - long habitId = ContentUris.parseId(data); - Habit habit = habits.getById(habitId); - - if (habit != null) - { - long reminderTime = DateUtils.getLocalTime() + delayMinutes * 60 * 1000; - reminderScheduler.schedule(habit, reminderTime); - } - - dismissNotification(context, habitId); - } - - private boolean shouldShowReminderToday(Intent intent, Habit habit) + @ReceiverScope + @Component(dependencies = AppComponent.class, modules = AppModule.class) + interface ReminderComponent { - if (!habit.hasReminder()) return false; - Reminder reminder = habit.getReminder(); - - Long timestamp = - intent.getLongExtra("timestamp", DateUtils.getStartOfToday()); - - boolean reminderDays[] = reminder.getDays().toArray(); - int weekday = DateUtils.getWeekday(timestamp); - - return reminderDays[weekday]; + ReminderController getReminderController(); } } diff --git a/app/src/main/java/org/isoron/uhabits/receivers/ReceiverActions.java b/app/src/main/java/org/isoron/uhabits/receivers/WidgetController.java similarity index 72% rename from app/src/main/java/org/isoron/uhabits/receivers/ReceiverActions.java rename to app/src/main/java/org/isoron/uhabits/receivers/WidgetController.java index dfde77bed..ffb488ba9 100644 --- a/app/src/main/java/org/isoron/uhabits/receivers/ReceiverActions.java +++ b/app/src/main/java/org/isoron/uhabits/receivers/WidgetController.java @@ -26,32 +26,38 @@ import org.isoron.uhabits.models.*; import javax.inject.*; -@Singleton -public class ReceiverActions +@ReceiverScope +public class WidgetController { + @NonNull private final CommandRunner commandRunner; @Inject - public ReceiverActions(CommandRunner commandRunner) + public WidgetController(@NonNull CommandRunner commandRunner) { this.commandRunner = commandRunner; } - public void addRepetition(@NonNull Habit habit, long timestamp) + public void onAddRepetition(@NonNull Habit habit, long timestamp) { Repetition rep = habit.getRepetitions().getByTimestamp(timestamp); if (rep != null) return; - toggleRepetition(habit, timestamp); + performToggle(habit, timestamp); } - public void removeRepetition(@NonNull Habit habit, long timestamp) + public void onRemoveRepetition(@NonNull Habit habit, long timestamp) { Repetition rep = habit.getRepetitions().getByTimestamp(timestamp); if (rep == null) return; - toggleRepetition(habit, timestamp); + performToggle(habit, timestamp); } - public void toggleRepetition(@NonNull Habit habit, long timestamp) + public void onToggleRepetition(@NonNull Habit habit, long timestamp) + { + performToggle(habit, timestamp); + } + + private void performToggle(@NonNull Habit habit, long timestamp) { commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp), habit.getId()); diff --git a/app/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.java b/app/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.java index a34ed4714..a52a85c9b 100644 --- a/app/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.java +++ b/app/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.java @@ -20,12 +20,12 @@ package org.isoron.uhabits.receivers; import android.content.*; -import android.support.annotation.*; import android.util.*; import org.isoron.uhabits.*; import org.isoron.uhabits.intents.*; -import org.isoron.uhabits.models.*; + +import dagger.*; /** * The Android BroadcastReceiver for Loop Habit Tracker. @@ -46,41 +46,37 @@ public class WidgetReceiver extends BroadcastReceiver public static final String ACTION_TOGGLE_REPETITION = "org.isoron.uhabits.ACTION_TOGGLE_REPETITION"; - @NonNull - private HabitList habits; - - @NonNull - private IntentParser parser; - - @NonNull - private ReceiverActions actions; - @Override public void onReceive(final Context context, Intent intent) { HabitsApplication app = (HabitsApplication) context.getApplicationContext(); - habits = app.getComponent().getHabitList(); - actions = app.getComponent().getReceiverActions(); - parser = new IntentParser(habits); + WidgetComponent component = DaggerWidgetReceiver_WidgetComponent + .builder() + .appComponent(app.getComponent()) + .build(); + + IntentParser parser = app.getComponent().getIntentParser(); + WidgetController controller = component.getWidgetController(); - Log.d("WidgetReceiver", - String.format("Received intent: %s", intent.toString())); try { + IntentParser.CheckmarkIntentData data; + data = parser.parseCheckmarkIntent(intent); + switch (intent.getAction()) { case ACTION_ADD_REPETITION: - onActionAddRepetition(intent); + controller.onAddRepetition(data.habit, data.timestamp); break; case ACTION_TOGGLE_REPETITION: - onActionToggleRepetition(intent); + controller.onToggleRepetition(data.habit, data.timestamp); break; case ACTION_REMOVE_REPETITION: - onActionRemoveRepetition(intent); + controller.onRemoveRepetition(data.habit, data.timestamp); break; } } @@ -90,24 +86,10 @@ public class WidgetReceiver extends BroadcastReceiver } } - private void onActionAddRepetition(Intent intent) - { - IntentParser.CheckmarkIntentData data; - data = parser.parseCheckmarkIntent(intent); - actions.addRepetition(data.habit, data.timestamp); - } - - private void onActionRemoveRepetition(Intent intent) - { - IntentParser.CheckmarkIntentData data; - data = parser.parseCheckmarkIntent(intent); - actions.removeRepetition(data.habit, data.timestamp); - } - - private void onActionToggleRepetition(Intent intent) + @ReceiverScope + @Component(dependencies = AppComponent.class, modules = AppModule.class) + interface WidgetComponent { - IntentParser.CheckmarkIntentData data; - data = parser.parseCheckmarkIntent(intent); - actions.toggleRepetition(data.habit, data.timestamp); + WidgetController getWidgetController(); } } diff --git a/app/src/test/java/org/isoron/uhabits/activities/habits/list/ListHabitsScreenTest.java b/app/src/test/java/org/isoron/uhabits/activities/habits/list/ListHabitsScreenTest.java index d90963d4f..deb46eb21 100644 --- a/app/src/test/java/org/isoron/uhabits/activities/habits/list/ListHabitsScreenTest.java +++ b/app/src/test/java/org/isoron/uhabits/activities/habits/list/ListHabitsScreenTest.java @@ -74,6 +74,8 @@ public class ListHabitsScreenTest extends BaseUnitTest private EditHabitDialogFactory editHabitDialogFactory; + private ThemeSwitcher themeSwitcher; + @Before @Override public void setUp() @@ -85,6 +87,7 @@ public class ListHabitsScreenTest extends BaseUnitTest dirFinder = mock(DirFinder.class); rootView = mock(ListHabitsRootView.class); intentFactory = mock(IntentFactory.class); + themeSwitcher = mock(ThemeSwitcher.class); confirmDeleteDialogFactory = mock(ConfirmDeleteDialogFactory.class); createHabitDialogFactory = mock(CreateHabitDialogFactory.class); filePickerDialogFactory = mock(FilePickerDialogFactory.class); @@ -93,7 +96,7 @@ public class ListHabitsScreenTest extends BaseUnitTest screen = new ListHabitsScreen(activity, commandRunner, dirFinder, rootView, - intentFactory, confirmDeleteDialogFactory, + intentFactory, themeSwitcher, confirmDeleteDialogFactory, createHabitDialogFactory, filePickerDialogFactory, colorPickerDialogFactory, editHabitDialogFactory);