diff --git a/app/src/androidTest/java/org/isoron/uhabits/BaseAndroidTest.java b/app/src/androidTest/java/org/isoron/uhabits/BaseAndroidTest.java
index 0bb843323..e4e3715b6 100644
--- a/app/src/androidTest/java/org/isoron/uhabits/BaseAndroidTest.java
+++ b/app/src/androidTest/java/org/isoron/uhabits/BaseAndroidTest.java
@@ -24,15 +24,12 @@ import android.content.*;
import android.os.*;
import android.support.annotation.*;
import android.support.test.*;
-import android.support.test.runner.*;
-import android.test.suitebuilder.annotation.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
-import org.junit.runner.*;
import java.util.*;
import java.util.concurrent.*;
@@ -43,8 +40,6 @@ import static junit.framework.Assert.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
-@RunWith(AndroidJUnit4.class)
-@MediumTest
public class BaseAndroidTest
{
// 8:00am, January 25th, 2015 (UTC)
diff --git a/app/src/main/java/org/isoron/uhabits/AndroidModule.java b/app/src/main/java/org/isoron/uhabits/AndroidModule.java
index 06deb46d4..e2d7902e8 100644
--- a/app/src/main/java/org/isoron/uhabits/AndroidModule.java
+++ b/app/src/main/java/org/isoron/uhabits/AndroidModule.java
@@ -21,11 +21,8 @@ package org.isoron.uhabits;
import android.content.*;
-import org.isoron.uhabits.commands.*;
-import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.models.sqlite.*;
-import org.isoron.uhabits.utils.*;
import javax.inject.*;
@@ -42,52 +39,21 @@ public class AndroidModule
{
@Provides
@Singleton
- CommandRunner provideCommandRunner()
- {
- return new CommandRunner();
- }
-
- @Provides
- @Singleton
- HabitList provideHabitList()
+ static HabitList provideHabitList()
{
return SQLiteHabitList.getInstance();
}
@Provides
- ModelFactory provideModelFactory()
+ static ModelFactory provideModelFactory()
{
return new SQLModelFactory();
}
@Provides
@Singleton
- Preferences providePreferences()
- {
- return new Preferences();
- }
-
- @Provides
- @Singleton
- WidgetPreferences provideWidgetPreferences()
- {
- return new WidgetPreferences();
- }
-
- @Provides
- @Singleton
- ReminderScheduler provideReminderScheduler()
- {
- Context context = HabitsApplication.getContext();
- IntentScheduler intentScheduler = new IntentScheduler(context);
- IntentFactory intentFactory = new IntentFactory(context);
- return new ReminderScheduler(intentFactory, intentScheduler);
- }
-
- @Provides
- @Singleton
- HabitLogger provideLogger()
+ static Context provideApplicationContext()
{
- return new HabitLogger();
+ return HabitsApplication.getContext();
}
}
diff --git a/app/src/main/java/org/isoron/uhabits/BaseComponent.java b/app/src/main/java/org/isoron/uhabits/BaseComponent.java
index d5cb21b29..b4d13fe8a 100644
--- a/app/src/main/java/org/isoron/uhabits/BaseComponent.java
+++ b/app/src/main/java/org/isoron/uhabits/BaseComponent.java
@@ -20,11 +20,13 @@
package org.isoron.uhabits;
import org.isoron.uhabits.commands.*;
+import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.io.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.receivers.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.ui.*;
+import org.isoron.uhabits.ui.common.dialogs.*;
import org.isoron.uhabits.ui.habits.edit.*;
import org.isoron.uhabits.ui.habits.list.*;
import org.isoron.uhabits.ui.habits.list.controllers.*;
@@ -40,6 +42,8 @@ import org.isoron.uhabits.widgets.*;
*/
public interface BaseComponent
{
+ IntentFactory getIntentFactory();
+
void inject(CheckmarkButtonController checkmarkButtonController);
void inject(ListHabitsController listHabitsController);
@@ -90,7 +94,7 @@ public interface BaseComponent
void inject(HabitsCSVExporter habitsCSVExporter);
- void inject(BaseDialogFragment baseDialogFragment);
+ void inject(BaseDialog baseDialog);
void inject(ShowHabitController showHabitController);
@@ -109,4 +113,12 @@ public interface BaseComponent
void inject(ReminderReceiver reminderReceiver);
void inject(ReminderScheduler reminderScheduler);
+
+ void inject(ListHabitsScreen listHabitsScreen);
+
+ void inject(ShowHabitScreen showHabitScreen);
+
+ void inject(ConfirmDeleteDialog confirmDeleteDialog);
+
+ void inject(PendingIntentFactory pendingIntentFactory);
}
diff --git a/app/src/main/java/org/isoron/uhabits/HabitLogger.java b/app/src/main/java/org/isoron/uhabits/HabitLogger.java
index 752a33401..6a0f83e3d 100644
--- a/app/src/main/java/org/isoron/uhabits/HabitLogger.java
+++ b/app/src/main/java/org/isoron/uhabits/HabitLogger.java
@@ -28,8 +28,17 @@ import org.isoron.uhabits.utils.*;
import java.text.*;
import java.util.*;
+import javax.inject.*;
+
+@Singleton
public class HabitLogger
{
+ @Inject
+ public HabitLogger()
+ {
+
+ }
+
public void logReminderScheduled(@NonNull Habit habit,
@NonNull Long reminderTime)
{
diff --git a/app/src/main/java/org/isoron/uhabits/commands/CommandRunner.java b/app/src/main/java/org/isoron/uhabits/commands/CommandRunner.java
index d1051e744..299aa1fa6 100644
--- a/app/src/main/java/org/isoron/uhabits/commands/CommandRunner.java
+++ b/app/src/main/java/org/isoron/uhabits/commands/CommandRunner.java
@@ -26,16 +26,20 @@ import org.isoron.uhabits.tasks.BaseTask;
import java.util.LinkedList;
+import javax.inject.*;
+
/**
* A CommandRunner executes and undoes commands.
*
* CommandRunners also allows objects to subscribe to it, and receive events
* whenever a command is performed.
*/
+@Singleton
public class CommandRunner
{
private LinkedList listeners;
+ @Inject
public CommandRunner()
{
listeners = new LinkedList<>();
diff --git a/app/src/main/java/org/isoron/uhabits/intents/IntentFactory.java b/app/src/main/java/org/isoron/uhabits/intents/IntentFactory.java
index 090e4e414..19a222bbe 100644
--- a/app/src/main/java/org/isoron/uhabits/intents/IntentFactory.java
+++ b/app/src/main/java/org/isoron/uhabits/intents/IntentFactory.java
@@ -19,94 +19,53 @@
package org.isoron.uhabits.intents;
-import android.app.*;
import android.content.*;
import android.net.*;
-import android.support.annotation.*;
+import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
-import org.isoron.uhabits.receivers.*;
+import org.isoron.uhabits.ui.about.*;
import org.isoron.uhabits.ui.habits.show.*;
+import org.isoron.uhabits.ui.intro.*;
+import org.isoron.uhabits.ui.settings.*;
-import static android.app.PendingIntent.*;
+import javax.inject.*;
public class IntentFactory
{
- @NonNull
- private final Context context;
-
- public IntentFactory(@NonNull Context context)
+ @Inject
+ public IntentFactory()
{
- this.context = context;
- }
- public PendingIntent buildAddCheckmark(@NonNull Habit habit,
- @Nullable Long timestamp)
- {
- Uri data = habit.getUri();
- Intent checkIntent = new Intent(context, WidgetReceiver.class);
- checkIntent.setData(data);
- checkIntent.setAction(WidgetReceiver.ACTION_ADD_REPETITION);
- if (timestamp != null) checkIntent.putExtra("timestamp", timestamp);
- return PendingIntent.getBroadcast(context, 1, checkIntent,
- FLAG_UPDATE_CURRENT);
}
- public PendingIntent buildDismissNotification()
+ public Intent startAboutActivity(Context context)
{
- Intent deleteIntent = new Intent(context, ReminderReceiver.class);
- deleteIntent.setAction(WidgetReceiver.ACTION_DISMISS_REMINDER);
- return PendingIntent.getBroadcast(context, 0, deleteIntent,
- FLAG_UPDATE_CURRENT);
+ return new Intent(context, AboutActivity.class);
}
- public PendingIntent buildShowReminder(@NonNull Habit habit,
- @Nullable Long reminderTime,
- long timestamp)
+ public Intent startIntroActivity(Context context)
{
- Uri uri = habit.getUri();
-
- Intent intent = new Intent(context, ReminderReceiver.class);
- intent.setAction(ReminderReceiver.ACTION_SHOW_REMINDER);
- intent.setData(uri);
- intent.putExtra("timestamp", timestamp);
- intent.putExtra("reminderTime", reminderTime);
- int reqCode = ((int) (habit.getId() % Integer.MAX_VALUE)) + 1;
- return PendingIntent.getBroadcast(context, reqCode, intent,
- FLAG_UPDATE_CURRENT);
+ return new Intent(context, IntroActivity.class);
}
- public PendingIntent buildSnoozeNotification(@NonNull Habit habit)
+ public Intent startSettingsActivity(Context context)
{
- Uri data = habit.getUri();
- Intent snoozeIntent = new Intent(context, ReminderReceiver.class);
- snoozeIntent.setData(data);
- snoozeIntent.setAction(ReminderReceiver.ACTION_SNOOZE_REMINDER);
- return PendingIntent.getBroadcast(context, 0, snoozeIntent,
- FLAG_UPDATE_CURRENT);
+ return new Intent(context, SettingsActivity.class);
}
- public PendingIntent buildToggleCheckmark(@NonNull Habit habit,
- @Nullable Long timestamp)
+ public Intent startShowHabitActivity(Context context, Habit habit)
{
- Uri data = habit.getUri();
- Intent checkIntent = new Intent(context, WidgetReceiver.class);
- checkIntent.setData(data);
- checkIntent.setAction(WidgetReceiver.ACTION_TOGGLE_REPETITION);
- if (timestamp != null) checkIntent.putExtra("timestamp", timestamp);
- return PendingIntent.getBroadcast(context, 2, checkIntent,
- FLAG_UPDATE_CURRENT);
+ Intent intent = new Intent(context, ShowHabitActivity.class);
+ intent.setData(habit.getUri());
+ return intent;
}
- public PendingIntent buildViewHabit(Habit habit)
+ public Intent viewFAQ(Context context)
{
- Uri uri = habit.getUri();
-
- Intent intent = new Intent(context, ShowHabitActivity.class);
- intent.setData(uri);
- return android.support.v4.app.TaskStackBuilder
- .create(context)
- .addNextIntentWithParentStack(intent)
- .getPendingIntent(0, FLAG_UPDATE_CURRENT);
+ Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse(context.getString(R.string.helpURL)));
+ return intent;
}
}
diff --git a/app/src/main/java/org/isoron/uhabits/intents/IntentScheduler.java b/app/src/main/java/org/isoron/uhabits/intents/IntentScheduler.java
index 5bcca76e7..76bf70b89 100644
--- a/app/src/main/java/org/isoron/uhabits/intents/IntentScheduler.java
+++ b/app/src/main/java/org/isoron/uhabits/intents/IntentScheduler.java
@@ -24,13 +24,17 @@ import android.content.*;
import android.os.*;
import android.support.annotation.*;
+import javax.inject.*;
+
import static android.app.AlarmManager.*;
import static android.content.Context.*;
+@Singleton
public class IntentScheduler
{
private final AlarmManager manager;
+ @Inject
public IntentScheduler(@NonNull Context context)
{
manager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
diff --git a/app/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.java b/app/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.java
new file mode 100644
index 000000000..b7d687dc9
--- /dev/null
+++ b/app/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.java
@@ -0,0 +1,118 @@
+/*
+ * 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.intents;
+
+import android.app.*;
+import android.content.*;
+import android.net.*;
+import android.support.annotation.*;
+
+import org.isoron.uhabits.*;
+import org.isoron.uhabits.models.*;
+import org.isoron.uhabits.receivers.*;
+
+import javax.inject.*;
+
+import static android.app.PendingIntent.*;
+
+@Singleton
+public class PendingIntentFactory
+{
+ @NonNull
+ private final Context context;
+
+ @Inject
+ protected IntentFactory intentFactory;
+
+ @Inject
+ public PendingIntentFactory(@NonNull Context context)
+ {
+ this.context = context;
+ HabitsApplication.getComponent().inject(this);
+ }
+
+ public PendingIntent addCheckmark(@NonNull Habit habit,
+ @Nullable Long timestamp)
+ {
+ Uri data = habit.getUri();
+ Intent checkIntent = new Intent(context, WidgetReceiver.class);
+ checkIntent.setData(data);
+ checkIntent.setAction(WidgetReceiver.ACTION_ADD_REPETITION);
+ if (timestamp != null) checkIntent.putExtra("timestamp", timestamp);
+ return PendingIntent.getBroadcast(context, 1, checkIntent,
+ FLAG_UPDATE_CURRENT);
+ }
+
+ public PendingIntent dismissNotification()
+ {
+ Intent deleteIntent = new Intent(context, ReminderReceiver.class);
+ deleteIntent.setAction(WidgetReceiver.ACTION_DISMISS_REMINDER);
+ return PendingIntent.getBroadcast(context, 0, deleteIntent,
+ FLAG_UPDATE_CURRENT);
+ }
+
+ public PendingIntent showReminder(@NonNull Habit habit,
+ @Nullable Long reminderTime,
+ long timestamp)
+ {
+ Uri uri = habit.getUri();
+
+ Intent intent = new Intent(context, ReminderReceiver.class);
+ intent.setAction(ReminderReceiver.ACTION_SHOW_REMINDER);
+ intent.setData(uri);
+ intent.putExtra("timestamp", timestamp);
+ intent.putExtra("reminderTime", reminderTime);
+ int reqCode = ((int) (habit.getId() % Integer.MAX_VALUE)) + 1;
+ return PendingIntent.getBroadcast(context, reqCode, intent,
+ FLAG_UPDATE_CURRENT);
+ }
+
+ public PendingIntent snoozeNotification(@NonNull Habit habit)
+ {
+ Uri data = habit.getUri();
+ Intent snoozeIntent = new Intent(context, ReminderReceiver.class);
+ snoozeIntent.setData(data);
+ snoozeIntent.setAction(ReminderReceiver.ACTION_SNOOZE_REMINDER);
+ return PendingIntent.getBroadcast(context, 0, snoozeIntent,
+ FLAG_UPDATE_CURRENT);
+ }
+
+ public PendingIntent toggleCheckmark(@NonNull Habit habit,
+ @Nullable Long timestamp)
+ {
+ Uri data = habit.getUri();
+ Intent checkIntent = new Intent(context, WidgetReceiver.class);
+ checkIntent.setData(data);
+ checkIntent.setAction(WidgetReceiver.ACTION_TOGGLE_REPETITION);
+ if (timestamp != null) checkIntent.putExtra("timestamp", timestamp);
+ return PendingIntent.getBroadcast(context, 2, checkIntent,
+ FLAG_UPDATE_CURRENT);
+ }
+
+ public PendingIntent showHabit(Habit habit)
+ {
+ Intent intent = intentFactory.startShowHabitActivity(context, habit);
+
+ return android.support.v4.app.TaskStackBuilder
+ .create(context)
+ .addNextIntentWithParentStack(intent)
+ .getPendingIntent(0, FLAG_UPDATE_CURRENT);
+ }
+}
diff --git a/app/src/main/java/org/isoron/uhabits/io/DirFinder.java b/app/src/main/java/org/isoron/uhabits/io/DirFinder.java
new file mode 100644
index 000000000..08754b4af
--- /dev/null
+++ b/app/src/main/java/org/isoron/uhabits/io/DirFinder.java
@@ -0,0 +1,106 @@
+/*
+ * 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.io;
+
+import android.content.*;
+import android.os.*;
+import android.support.annotation.*;
+import android.util.*;
+
+import org.isoron.uhabits.*;
+
+import java.io.*;
+
+import javax.inject.*;
+
+import static android.support.v4.content.ContextCompat.*;
+
+/**
+ * A DirFinder locates suitable directories for storing user files.
+ */
+public class DirFinder
+{
+ private static final String TAG = "DirFinder";
+
+ private final Context context;
+
+ @Inject
+ public DirFinder()
+ {
+ context = HabitsApplication.getContext();
+ }
+
+ @Nullable
+ public File findSDCardDir(@Nullable String subpath)
+ {
+ File parents[] = new File[]{
+ Environment.getExternalStorageDirectory()
+ };
+
+ return findDir(parents, subpath);
+ }
+
+ @Nullable
+ public File findStorageDir(@Nullable String relativePath)
+ {
+ File potentialParents[] = getExternalFilesDirs(context, null);
+
+ if (potentialParents == null)
+ {
+ Log.e(TAG, "getFilesDir: getExternalFilesDirs returned null");
+ return null;
+ }
+
+ return findDir(potentialParents, relativePath);
+ }
+
+ @Nullable
+ private File findDir(@NonNull File potentialParents[],
+ @Nullable String relativePath)
+ {
+ if (relativePath == null) relativePath = "";
+
+ File chosenDir = null;
+ for (File dir : potentialParents)
+ {
+ if (dir == null || !dir.canWrite()) continue;
+ chosenDir = dir;
+ break;
+ }
+
+ if (chosenDir == null)
+ {
+ Log.e(TAG,
+ "getDir: all potential parents are null or non-writable");
+ return null;
+ }
+
+ File dir = new File(
+ String.format("%s/%s/", chosenDir.getAbsolutePath(), relativePath));
+ if (!dir.exists() && !dir.mkdirs())
+ {
+ Log.e(TAG,
+ "getDir: chosen dir does not exist and cannot be created");
+ return null;
+ }
+
+ return dir;
+ }
+}
diff --git a/app/src/main/java/org/isoron/uhabits/models/sqlite/SQLModelFactory.java b/app/src/main/java/org/isoron/uhabits/models/sqlite/SQLModelFactory.java
index 904391e36..70b1e9e70 100644
--- a/app/src/main/java/org/isoron/uhabits/models/sqlite/SQLModelFactory.java
+++ b/app/src/main/java/org/isoron/uhabits/models/sqlite/SQLModelFactory.java
@@ -21,11 +21,20 @@ package org.isoron.uhabits.models.sqlite;
import org.isoron.uhabits.models.*;
+import javax.inject.*;
+
/**
* Factory that provides models backed by an SQLite database.
*/
+@Singleton
public class SQLModelFactory implements ModelFactory
{
+ @Inject
+ public SQLModelFactory()
+ {
+
+ }
+
@Override
public RepetitionList buildRepetitionList(Habit habit)
{
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 1808fe376..18e2f604c 100644
--- a/app/src/main/java/org/isoron/uhabits/receivers/ReminderReceiver.java
+++ b/app/src/main/java/org/isoron/uhabits/receivers/ReminderReceiver.java
@@ -145,14 +145,15 @@ public class ReminderReceiver extends BroadcastReceiver
context, 0, contentIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
- IntentFactory intentFactory = new IntentFactory(context);
+ PendingIntentFactory
+ pendingIntentFactory = new PendingIntentFactory(context);
PendingIntent dismissPendingIntent;
- dismissPendingIntent = intentFactory.buildDismissNotification();
+ dismissPendingIntent = pendingIntentFactory.dismissNotification();
PendingIntent checkIntentPending =
- intentFactory.buildAddCheckmark(habit, timestamp);
+ pendingIntentFactory.addCheckmark(habit, timestamp);
PendingIntent snoozeIntentPending =
- intentFactory.buildSnoozeNotification(habit);
+ pendingIntentFactory.snoozeNotification(habit);
Uri ringtoneUri = RingtoneUtils.getRingtoneUri(context);
diff --git a/app/src/main/java/org/isoron/uhabits/ui/BaseActivity.java b/app/src/main/java/org/isoron/uhabits/ui/BaseActivity.java
index d286e2fe0..dabaa86fb 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/BaseActivity.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/BaseActivity.java
@@ -24,6 +24,7 @@ import android.os.*;
import android.support.annotation.*;
import android.support.v7.app.*;
import android.view.*;
+import android.widget.*;
import org.isoron.uhabits.utils.*;
@@ -51,6 +52,8 @@ abstract public class BaseActivity extends AppCompatActivity
@Nullable
private BaseScreen screen;
+ private Toast toast;
+
@Override
public boolean onCreateOptionsMenu(@Nullable Menu menu)
{
@@ -78,6 +81,30 @@ abstract public class BaseActivity extends AppCompatActivity
this.screen = screen;
}
+ public void showDialog(AppCompatDialogFragment dialog, String tag)
+ {
+ dialog.show(getSupportFragmentManager(), tag);
+ }
+
+ public void showDialog(AppCompatDialog dialog)
+ {
+ dialog.show();
+ }
+
+ /**
+ * Shows a message on the screen.
+ *
+ * @param stringId the string resource id for this message.
+ */
+ public void showMessage(@StringRes Integer stringId)
+ {
+ if (stringId == null) return;
+ if (toast == null)
+ toast = Toast.makeText(this, stringId, Toast.LENGTH_SHORT);
+ else toast.setText(stringId);
+ toast.show();
+ }
+
@Override
public void uncaughtException(@Nullable Thread thread,
@Nullable Throwable ex)
diff --git a/app/src/main/java/org/isoron/uhabits/ui/BaseScreen.java b/app/src/main/java/org/isoron/uhabits/ui/BaseScreen.java
index 08b30526b..5b034a2e0 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/BaseScreen.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/BaseScreen.java
@@ -27,12 +27,11 @@ import android.os.*;
import android.support.annotation.*;
import android.support.v7.app.*;
import android.support.v7.view.ActionMode;
-import android.support.v7.widget.Toolbar;
+import android.support.v7.widget.*;
import android.view.*;
-import android.widget.*;
import org.isoron.uhabits.*;
-import org.isoron.uhabits.tasks.ProgressBar;
+import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.utils.*;
import java.io.*;
@@ -48,8 +47,6 @@ public abstract class BaseScreen
{
protected BaseActivity activity;
- private Toast toast;
-
@Nullable
private BaseRootView rootView;
@@ -155,6 +152,11 @@ public abstract class BaseScreen
activity.setBaseMenu(menu);
}
+ public void showMessage(@StringRes int stringId)
+ {
+ activity.showMessage(stringId);
+ }
+
/**
* Sets the root view for this screen.
*
@@ -179,20 +181,6 @@ public abstract class BaseScreen
this.selectionMenu = menu;
}
- /**
- * Shows a message on the screen.
- *
- * @param stringId the string resource id for this message.
- */
- public void showMessage(@Nullable Integer stringId)
- {
- if (stringId == null) return;
- if (toast == null)
- toast = Toast.makeText(activity, stringId, Toast.LENGTH_SHORT);
- else toast.setText(stringId);
- toast.show();
- }
-
public void showSendEmailScreen(String to, String subject, String content)
{
Intent intent = new Intent();
@@ -225,11 +213,6 @@ public abstract class BaseScreen
activity.startSupportActionMode(new ActionModeWrapper());
}
- protected void showDialog(AppCompatDialogFragment dialog, String tag)
- {
- dialog.show(activity.getSupportFragmentManager(), tag);
- }
-
public void invalidateToolbar()
{
if (rootView == null) return;
diff --git a/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/ColorPickerDialog.java b/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/ColorPickerDialog.java
new file mode 100644
index 000000000..c296c0713
--- /dev/null
+++ b/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/ColorPickerDialog.java
@@ -0,0 +1,58 @@
+/*
+ * 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.ui.common.dialogs;
+
+import android.content.*;
+
+import org.isoron.uhabits.*;
+import org.isoron.uhabits.utils.*;
+
+/**
+ * Dialog that allows the user to choose a color.
+ */
+public class ColorPickerDialog extends com.android.colorpicker.ColorPickerDialog
+{
+ public static ColorPickerDialog newInstance(int paletteColor)
+ {
+ ColorPickerDialog dialog = new ColorPickerDialog();
+ Context context = dialog.getContext();
+
+ int color = ColorUtils.getColor(context, paletteColor);
+
+ dialog.initialize(R.string.color_picker_default_title,
+ ColorUtils.getPalette(context), color, 4,
+ com.android.colorpicker.ColorPickerDialog.SIZE_SMALL);
+
+ return dialog;
+ }
+
+ public void setListener(OnColorSelectedListener listener)
+ {
+ super.setOnColorSelectedListener(c -> {
+ c = ColorUtils.colorToPaletteIndex(getContext(), c);
+ listener.onColorSelected(c);
+ });
+ }
+
+ public interface OnColorSelectedListener
+ {
+ void onColorSelected(int color);
+ }
+}
diff --git a/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/ConfirmDeleteDialog.java b/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/ConfirmDeleteDialog.java
new file mode 100644
index 000000000..556b67393
--- /dev/null
+++ b/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/ConfirmDeleteDialog.java
@@ -0,0 +1,60 @@
+/*
+ * 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.ui.common.dialogs;
+
+import android.content.*;
+import android.support.annotation.*;
+import android.support.v7.app.*;
+
+import org.isoron.uhabits.*;
+
+import butterknife.*;
+
+/**
+ * Dialog that asks the user confirmation before executing a delete operation.
+ */
+public class ConfirmDeleteDialog extends AlertDialog
+{
+ @BindString(R.string.delete_habits_message)
+ protected String question;
+
+ @BindString(android.R.string.yes)
+ protected String yes;
+
+ @BindString(android.R.string.no)
+ protected String no;
+
+ protected ConfirmDeleteDialog(@NonNull Context context,
+ @NonNull Callback callback)
+ {
+ super(context);
+ ButterKnife.bind(this);
+
+ setTitle(R.string.delete_habits);
+ setMessage(question);
+ setButton(BUTTON_POSITIVE, yes, (dialog, which) -> callback.run());
+ setButton(BUTTON_NEGATIVE, no, (dialog, which) -> {});
+ }
+
+ public interface Callback
+ {
+ void run();
+ }
+}
diff --git a/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/DialogFactory.java b/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/DialogFactory.java
new file mode 100644
index 000000000..a684d7704
--- /dev/null
+++ b/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/DialogFactory.java
@@ -0,0 +1,71 @@
+/*
+ * 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.ui.common.dialogs;
+
+import android.content.*;
+import android.support.annotation.*;
+
+import org.isoron.uhabits.models.*;
+import org.isoron.uhabits.ui.habits.edit.*;
+
+import java.io.*;
+
+import javax.inject.*;
+
+public class DialogFactory
+{
+ @Inject
+ public DialogFactory()
+ {
+
+ }
+
+ @NonNull
+ public ColorPickerDialog buildColorPicker(int paletteColor)
+ {
+ return ColorPickerDialog.newInstance(paletteColor);
+ }
+
+ @NonNull
+ public ConfirmDeleteDialog buildConfirmDeleteDialog(
+ @NonNull Context context,
+ @NonNull ConfirmDeleteDialog.Callback callback)
+ {
+ return new ConfirmDeleteDialog(context, callback);
+ }
+
+ @NonNull
+ public CreateHabitDialog buildCreateHabitDialog()
+ {
+ return new CreateHabitDialog();
+ }
+
+ @NonNull
+ public EditHabitDialog buildEditHabitDialog(Habit habit)
+ {
+ return EditHabitDialog.newInstance(habit);
+ }
+
+ @NonNull
+ public FilePickerDialog buildFilePicker(Context context, File dir)
+ {
+ return new FilePickerDialog(context, dir);
+ }
+}
diff --git a/app/src/main/java/org/isoron/uhabits/ui/settings/FilePickerDialog.java b/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/FilePickerDialog.java
similarity index 84%
rename from app/src/main/java/org/isoron/uhabits/ui/settings/FilePickerDialog.java
rename to app/src/main/java/org/isoron/uhabits/ui/common/dialogs/FilePickerDialog.java
index 8d7faa1c7..c6a97f0fb 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/settings/FilePickerDialog.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/FilePickerDialog.java
@@ -17,50 +17,43 @@
* with this program. If not, see .
*/
-package org.isoron.uhabits.ui.settings;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.support.annotation.NonNull;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager.LayoutParams;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.util.Arrays;
+package org.isoron.uhabits.ui.common.dialogs;
+import android.content.*;
+import android.support.annotation.*;
+import android.support.v7.app.*;
+import android.view.*;
+import android.view.WindowManager.*;
+import android.widget.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Dialog that allows the user to pick a file.
+ */
public class FilePickerDialog implements AdapterView.OnItemClickListener
{
private static final String PARENT_DIR = "..";
- private final Activity activity;
+ private final Context context;
private ListView list;
- private Dialog dialog;
+ private AppCompatDialog dialog;
private File currentPath;
- public interface OnFileSelectedListener
- {
- void onFileSelected(File file);
- }
-
private OnFileSelectedListener listener;
- public FilePickerDialog(Activity activity, File initialDirectory)
+ public FilePickerDialog(Context context, File initialDirectory)
{
- this.activity = activity;
+ this.context = context;
- list = new ListView(activity);
+ list = new ListView(context);
list.setOnItemClickListener(this);
- dialog = new Dialog(activity);
+ dialog = new AppCompatDialog(context);
dialog.setContentView(list);
dialog
.getWindow()
@@ -69,6 +62,11 @@ public class FilePickerDialog implements AdapterView.OnItemClickListener
navigateTo(initialDirectory);
}
+ public AppCompatDialog getDialog()
+ {
+ return dialog;
+ }
+
@Override
public void onItemClick(AdapterView> parent,
View view,
@@ -92,27 +90,14 @@ public class FilePickerDialog implements AdapterView.OnItemClickListener
}
}
- public void show()
- {
- dialog.show();
- }
-
public void setListener(OnFileSelectedListener listener)
{
this.listener = listener;
}
- private void navigateTo(File path)
+ public void show()
{
- if (!path.exists()) return;
-
- File[] dirs = path.listFiles(new ReadableDirFilter());
- File[] files = path.listFiles(new RegularReadableFileFilter());
- if (dirs == null || files == null) return;
-
- this.currentPath = path;
- dialog.setTitle(currentPath.getPath());
- list.setAdapter(new FilePickerAdapter(getFileList(path, dirs, files)));
+ dialog.show();
}
@NonNull
@@ -144,11 +129,38 @@ public class FilePickerDialog implements AdapterView.OnItemClickListener
return fileList;
}
+ private void navigateTo(File path)
+ {
+ if (!path.exists()) return;
+
+ File[] dirs = path.listFiles(new ReadableDirFilter());
+ File[] files = path.listFiles(new RegularReadableFileFilter());
+ if (dirs == null || files == null) return;
+
+ this.currentPath = path;
+ dialog.setTitle(currentPath.getPath());
+ list.setAdapter(new FilePickerAdapter(getFileList(path, dirs, files)));
+ }
+
+ public interface OnFileSelectedListener
+ {
+ void onFileSelected(File file);
+ }
+
+ private static class ReadableDirFilter implements FileFilter
+ {
+ @Override
+ public boolean accept(File file)
+ {
+ return (file.isDirectory() && file.canRead());
+ }
+ }
+
private class FilePickerAdapter extends ArrayAdapter
{
public FilePickerAdapter(@NonNull String[] fileList)
{
- super(FilePickerDialog.this.activity,
+ super(FilePickerDialog.this.context,
android.R.layout.simple_list_item_1, fileList);
}
@@ -162,15 +174,6 @@ public class FilePickerDialog implements AdapterView.OnItemClickListener
}
}
- private static class ReadableDirFilter implements FileFilter
- {
- @Override
- public boolean accept(File file)
- {
- return (file.isDirectory() && file.canRead());
- }
- }
-
private class RegularReadableFileFilter implements FileFilter
{
@Override
diff --git a/app/src/main/java/org/isoron/uhabits/ui/habits/edit/HistoryEditorDialog.java b/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/HistoryEditorDialog.java
similarity index 98%
rename from app/src/main/java/org/isoron/uhabits/ui/habits/edit/HistoryEditorDialog.java
rename to app/src/main/java/org/isoron/uhabits/ui/common/dialogs/HistoryEditorDialog.java
index 3aa60ef76..d625e8a70 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/habits/edit/HistoryEditorDialog.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/HistoryEditorDialog.java
@@ -17,7 +17,7 @@
* with this program. If not, see .
*/
-package org.isoron.uhabits.ui.habits.edit;
+package org.isoron.uhabits.ui.common.dialogs;
import android.app.*;
import android.content.*;
diff --git a/app/src/main/java/org/isoron/uhabits/ui/habits/edit/WeekdayPickerDialog.java b/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/WeekdayPickerDialog.java
similarity index 79%
rename from app/src/main/java/org/isoron/uhabits/ui/habits/edit/WeekdayPickerDialog.java
rename to app/src/main/java/org/isoron/uhabits/ui/common/dialogs/WeekdayPickerDialog.java
index 477c736f0..ca0fee0f3 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/habits/edit/WeekdayPickerDialog.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/common/dialogs/WeekdayPickerDialog.java
@@ -17,39 +17,39 @@
* with this program. If not, see .
*/
-package org.isoron.uhabits.ui.habits.edit;
+package org.isoron.uhabits.ui.common.dialogs;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
+import android.app.*;
+import android.content.*;
+import android.os.*;
import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatDialogFragment;
+import android.support.v7.app.*;
-import org.isoron.uhabits.R;
-import org.isoron.uhabits.utils.DateUtils;
+import org.isoron.uhabits.*;
+import org.isoron.uhabits.utils.*;
+/**
+ * Dialog that allows the user to pick one or more days of the week.
+ */
public class WeekdayPickerDialog extends AppCompatDialogFragment implements
DialogInterface.OnMultiChoiceClickListener,
DialogInterface.OnClickListener
{
- public interface OnWeekdaysPickedListener
- {
- void onWeekdaysPicked(boolean[] selectedDays);
- }
-
private boolean[] selectedDays;
private OnWeekdaysPickedListener listener;
- public void setListener(OnWeekdaysPickedListener listener)
+ @Override
+ public void onClick(DialogInterface dialog, int which, boolean isChecked)
{
- this.listener = listener;
+ selectedDays[which] = isChecked;
}
- public void setSelectedDays(boolean[] selectedDays)
+ @Override
+ public void onClick(DialogInterface dialog, int which)
{
- this.selectedDays = selectedDays;
+ if (listener != null) listener.onWeekdaysPicked(selectedDays);
}
@Override
@@ -61,28 +61,25 @@ public class WeekdayPickerDialog extends AppCompatDialogFragment implements
.setMultiChoiceItems(DateUtils.getLongDayNames(), selectedDays,
this)
.setPositiveButton(android.R.string.yes, this)
- .setNegativeButton(android.R.string.cancel,
- new DialogInterface.OnClickListener()
- {
- @Override
- public void onClick(DialogInterface dialog, int which)
- {
- dismiss();
- }
- });
+ .setNegativeButton(android.R.string.cancel, (dialog, which) -> {
+ dismiss();
+ });
return builder.create();
}
- @Override
- public void onClick(DialogInterface dialog, int which, boolean isChecked)
+ public void setListener(OnWeekdaysPickedListener listener)
{
- selectedDays[which] = isChecked;
+ this.listener = listener;
}
- @Override
- public void onClick(DialogInterface dialog, int which)
+ public void setSelectedDays(boolean[] selectedDays)
{
- if (listener != null) listener.onWeekdaysPicked(selectedDays);
+ this.selectedDays = selectedDays;
+ }
+
+ public interface OnWeekdaysPickedListener
+ {
+ void onWeekdaysPicked(boolean[] selectedDays);
}
}
diff --git a/app/src/main/java/org/isoron/uhabits/ui/habits/edit/BaseDialogFragment.java b/app/src/main/java/org/isoron/uhabits/ui/habits/edit/BaseDialog.java
similarity index 85%
rename from app/src/main/java/org/isoron/uhabits/ui/habits/edit/BaseDialogFragment.java
rename to app/src/main/java/org/isoron/uhabits/ui/habits/edit/BaseDialog.java
index 8b597694f..656c3d163 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/habits/edit/BaseDialogFragment.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/habits/edit/BaseDialog.java
@@ -25,14 +25,14 @@ import android.support.v7.app.*;
import android.text.format.*;
import android.view.*;
-import com.android.colorpicker.*;
import com.android.datetimepicker.time.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
-import org.isoron.uhabits.utils.*;
+import org.isoron.uhabits.ui.common.dialogs.*;
import org.isoron.uhabits.utils.DateUtils;
+import org.isoron.uhabits.utils.*;
import java.util.*;
@@ -40,7 +40,7 @@ import javax.inject.*;
import butterknife.*;
-public abstract class BaseDialogFragment extends AppCompatDialogFragment
+public abstract class BaseDialog extends AppCompatDialogFragment
{
@Nullable
protected Habit originalHabit;
@@ -60,6 +60,9 @@ public abstract class BaseDialogFragment extends AppCompatDialogFragment
@Inject
protected HabitList habitList;
+ @Inject
+ protected DialogFactory dialogFactory;
+
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
@@ -83,7 +86,8 @@ public abstract class BaseDialogFragment extends AppCompatDialogFragment
if (position < 0 || position > 4) throw new IllegalArgumentException();
int freqNums[] = { 1, 1, 2, 5, 3 };
int freqDens[] = { 1, 7, 7, 7, 7 };
- modifiedHabit.setFrequency(new Frequency(freqNums[position], freqDens[position]));
+ modifiedHabit.setFrequency(
+ new Frequency(freqNums[position], freqDens[position]));
helper.populateFrequencyFields(modifiedHabit);
}
@@ -169,23 +173,22 @@ public abstract class BaseDialogFragment extends AppCompatDialogFragment
WeekdayPickerDialog dialog = new WeekdayPickerDialog();
dialog.setListener(new OnWeekdaysPickedListener());
- dialog.setSelectedDays(
- DateUtils.unpackWeekdayList(reminder.getDays()));
+ dialog.setSelectedDays(DateUtils.unpackWeekdayList(reminder.getDays()));
dialog.show(getFragmentManager(), "weekdayPicker");
}
@OnClick(R.id.buttonPickColor)
void showColorPicker()
{
- int androidColor =
- ColorUtils.getColor(getContext(), modifiedHabit.getColor());
+ int color = modifiedHabit.getColor();
+ ColorPickerDialog picker = dialogFactory.buildColorPicker(color);
- ColorPickerDialog picker =
- ColorPickerDialog.newInstance(R.string.color_picker_default_title,
- ColorUtils.getPalette(getContext()), androidColor, 4,
- ColorPickerDialog.SIZE_SMALL);
+ picker.setListener(c -> {
+ prefs.setDefaultHabitColor(c);
+ modifiedHabit.setColor(c);
+ helper.populateColor(c);
+ });
- picker.setOnColorSelectedListener(new OnColorSelectedListener());
picker.show(getFragmentManager(), "picker");
}
@@ -198,20 +201,6 @@ public abstract class BaseDialogFragment extends AppCompatDialogFragment
timePicker.show(getFragmentManager(), "timePicker");
}
- private class OnColorSelectedListener
- implements ColorPickerSwatch.OnColorSelectedListener
- {
- @Override
- public void onColorSelected(int androidColor)
- {
- int paletteColor =
- ColorUtils.colorToPaletteIndex(getActivity(), androidColor);
- prefs.setDefaultHabitColor(paletteColor);
- modifiedHabit.setColor(paletteColor);
- helper.populateColor(paletteColor);
- }
- }
-
private class OnTimeSetListener
implements TimePickerDialog.OnTimeSetListener
{
diff --git a/app/src/main/java/org/isoron/uhabits/ui/habits/edit/CreateHabitDialogFragment.java b/app/src/main/java/org/isoron/uhabits/ui/habits/edit/CreateHabitDialog.java
similarity index 95%
rename from app/src/main/java/org/isoron/uhabits/ui/habits/edit/CreateHabitDialogFragment.java
rename to app/src/main/java/org/isoron/uhabits/ui/habits/edit/CreateHabitDialog.java
index 6479dd000..2eeae776d 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/habits/edit/CreateHabitDialogFragment.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/habits/edit/CreateHabitDialog.java
@@ -23,7 +23,7 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
-public class CreateHabitDialogFragment extends BaseDialogFragment
+public class CreateHabitDialog extends BaseDialog
{
@Override
protected int getTitle()
diff --git a/app/src/main/java/org/isoron/uhabits/ui/habits/edit/EditHabitDialogFragment.java b/app/src/main/java/org/isoron/uhabits/ui/habits/edit/EditHabitDialog.java
similarity index 84%
rename from app/src/main/java/org/isoron/uhabits/ui/habits/edit/EditHabitDialogFragment.java
rename to app/src/main/java/org/isoron/uhabits/ui/habits/edit/EditHabitDialog.java
index 478d7d092..19b068c5b 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/habits/edit/EditHabitDialogFragment.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/habits/edit/EditHabitDialog.java
@@ -25,13 +25,16 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
-public class EditHabitDialogFragment extends BaseDialogFragment
+public class EditHabitDialog extends BaseDialog
{
- public static EditHabitDialogFragment newInstance(long habitId)
+ public static EditHabitDialog newInstance(Habit habit)
{
- EditHabitDialogFragment frag = new EditHabitDialogFragment();
+ if(habit.getId() == null)
+ throw new IllegalArgumentException("habit not saved");
+
+ EditHabitDialog frag = new EditHabitDialog();
Bundle args = new Bundle();
- args.putLong("habitId", habitId);
+ args.putLong("habitId", habit.getId());
frag.setArguments(args);
return frag;
}
diff --git a/app/src/main/java/org/isoron/uhabits/ui/habits/list/ListHabitsController.java b/app/src/main/java/org/isoron/uhabits/ui/habits/list/ListHabitsController.java
index ded3f4b8d..4d3e0ff8b 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/habits/list/ListHabitsController.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/habits/list/ListHabitsController.java
@@ -48,7 +48,8 @@ public class ListHabitsController
@NonNull
private final HabitList habitList;
- private HabitCardListAdapter adapter;
+ @NonNull
+ private final HabitCardListAdapter adapter;
@Inject
Preferences prefs;
@@ -81,6 +82,7 @@ public class ListHabitsController
if (filename != null) screen.showSendFileScreen(filename);
else screen.showMessage(R.string.could_not_export);
});
+
task.execute();
}
diff --git a/app/src/main/java/org/isoron/uhabits/ui/habits/list/ListHabitsScreen.java b/app/src/main/java/org/isoron/uhabits/ui/habits/list/ListHabitsScreen.java
index 2440126c9..e3c176308 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/habits/list/ListHabitsScreen.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/habits/list/ListHabitsScreen.java
@@ -20,35 +20,43 @@
package org.isoron.uhabits.ui.habits.list;
import android.content.*;
-import android.net.*;
import android.os.*;
import android.support.annotation.*;
-import android.support.v7.app.*;
-
-import com.android.colorpicker.*;
import org.isoron.uhabits.*;
+import org.isoron.uhabits.intents.*;
+import org.isoron.uhabits.io.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.*;
-import org.isoron.uhabits.ui.about.*;
+import org.isoron.uhabits.ui.common.dialogs.*;
+import org.isoron.uhabits.ui.common.dialogs.ColorPickerDialog.*;
import org.isoron.uhabits.ui.habits.edit.*;
-import org.isoron.uhabits.ui.habits.show.*;
-import org.isoron.uhabits.ui.intro.*;
-import org.isoron.uhabits.ui.settings.*;
import org.isoron.uhabits.utils.*;
import java.io.*;
+import javax.inject.*;
+
public class ListHabitsScreen extends BaseScreen
{
@Nullable
ListHabitsController controller;
+ @Inject
+ protected DialogFactory dialogFactory;
+
+ @Inject
+ protected IntentFactory intentFactory;
+
+ @Inject
+ protected DirFinder dirFinder;
+
public ListHabitsScreen(@NonNull BaseActivity activity,
- ListHabitsRootView rootView)
+ @NonNull ListHabitsRootView rootView)
{
super(activity);
setRootView(rootView);
+ HabitsApplication.getComponent().inject(this);
}
@Override
@@ -83,90 +91,83 @@ public class ListHabitsScreen extends BaseScreen
public void showAboutScreen()
{
- Intent intent = new Intent(activity, AboutActivity.class);
+ Intent intent = intentFactory.startAboutActivity(activity);
activity.startActivity(intent);
}
- public void showColorPicker(Habit habit, OnColorSelectedListener callback)
+ /**
+ * Displays a {@link ColorPickerDialog} to the user.
+ *
+ * The selected color on the dialog is the color of the given habit.
+ *
+ * @param habit the habit
+ * @param callback
+ */
+ public void showColorPicker(@NonNull Habit habit,
+ @NonNull OnColorSelectedListener callback)
{
- int color = ColorUtils.getColor(activity, habit.getColor());
-
ColorPickerDialog picker =
- ColorPickerDialog.newInstance(R.string.color_picker_default_title,
- ColorUtils.getPalette(activity), color, 4,
- ColorPickerDialog.SIZE_SMALL);
-
- picker.setOnColorSelectedListener(c -> {
- c = ColorUtils.colorToPaletteIndex(activity, c);
- callback.onColorSelected(c);
- });
- picker.show(activity.getSupportFragmentManager(), "picker");
+ dialogFactory.buildColorPicker(habit.getColor());
+ picker.setListener(callback);
+ activity.showDialog(picker, "picker");
}
public void showCreateHabitScreen()
{
- showDialog(new CreateHabitDialogFragment(), "editHabit");
+ CreateHabitDialog dialog = dialogFactory.buildCreateHabitDialog();
+ activity.showDialog(dialog, "editHabit");
}
- public void showDeleteConfirmationScreen(Callback callback)
+ public void showDeleteConfirmationScreen(ConfirmDeleteDialog.Callback callback)
{
- new AlertDialog.Builder(activity)
- .setTitle(R.string.delete_habits)
- .setMessage(R.string.delete_habits_message)
- .setPositiveButton(android.R.string.yes,
- (dialog, which) -> callback.run())
- .setNegativeButton(android.R.string.no, null)
- .show();
+ ConfirmDeleteDialog dialog =
+ dialogFactory.buildConfirmDeleteDialog(activity, callback);
+ activity.showDialog(dialog);
}
public void showEditHabitScreen(Habit habit)
{
- BaseDialogFragment frag =
- EditHabitDialogFragment.newInstance(habit.getId());
- frag.show(activity.getSupportFragmentManager(), "editHabit");
+ EditHabitDialog dialog = dialogFactory.buildEditHabitDialog(habit);
+ activity.showDialog(dialog, "editHabit");
}
public void showFAQScreen()
{
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(activity.getString(R.string.helpURL)));
+ Intent intent = intentFactory.viewFAQ(activity);
activity.startActivity(intent);
}
public void showHabitScreen(@NonNull Habit habit)
{
- Intent intent = new Intent(activity, ShowHabitActivity.class);
- intent.setData(
- Uri.parse("content://org.isoron.uhabits/habit/" + habit.getId()));
+ Intent intent = intentFactory.startShowHabitActivity(activity, habit);
activity.startActivity(intent);
}
public void showImportScreen()
{
- if (controller == null) return;
+ File dir = dirFinder.findStorageDir(null);
- File dir = FileUtils.getFilesDir(null);
if (dir == null)
{
- showMessage(R.string.could_not_import);
+ activity.showMessage(R.string.could_not_import);
return;
}
- FilePickerDialog picker = new FilePickerDialog(activity, dir);
- picker.setListener(file -> controller.onImportData(file));
- picker.show();
+ FilePickerDialog picker = dialogFactory.buildFilePicker(activity, dir);
+ if (controller != null)
+ picker.setListener(file -> controller.onImportData(file));
+ activity.showDialog(picker.getDialog());
}
public void showIntroScreen()
{
- Intent intent = new Intent(activity, IntroActivity.class);
+ Intent intent = intentFactory.startIntroActivity(activity);
activity.startActivity(intent);
}
public void showSettingsScreen()
{
- Intent intent = new Intent(activity, SettingsActivity.class);
+ Intent intent = intentFactory.startSettingsActivity(activity);
activity.startActivityForResult(intent, 0);
}
@@ -182,7 +183,7 @@ public class ListHabitsScreen extends BaseScreen
private void refreshTheme()
{
new Handler().postDelayed(() -> {
- Intent intent = new Intent(activity, MainActivity.class);
+ Intent intent = new Intent(activity, ListHabitsScreen.class);
activity.finish();
activity.overridePendingTransition(android.R.anim.fade_in,
@@ -191,14 +192,4 @@ public class ListHabitsScreen extends BaseScreen
}, 500); // HACK: Let the menu disappear first
}
-
- interface Callback
- {
- void run();
- }
-
- public interface OnColorSelectedListener
- {
- void onColorSelected(int color);
- }
}
diff --git a/app/src/main/java/org/isoron/uhabits/ui/habits/show/ShowHabitController.java b/app/src/main/java/org/isoron/uhabits/ui/habits/show/ShowHabitController.java
index d05909f67..b42fa9c48 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/habits/show/ShowHabitController.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/habits/show/ShowHabitController.java
@@ -25,7 +25,7 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
-import org.isoron.uhabits.ui.habits.edit.*;
+import org.isoron.uhabits.ui.common.dialogs.*;
import javax.inject.*;
diff --git a/app/src/main/java/org/isoron/uhabits/ui/habits/show/ShowHabitScreen.java b/app/src/main/java/org/isoron/uhabits/ui/habits/show/ShowHabitScreen.java
index d5f7cf21b..c84288ef9 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/habits/show/ShowHabitScreen.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/habits/show/ShowHabitScreen.java
@@ -20,33 +20,38 @@
package org.isoron.uhabits.ui.habits.show;
import android.support.annotation.*;
-import android.support.v4.app.*;
+import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.*;
+import org.isoron.uhabits.ui.common.dialogs.*;
import org.isoron.uhabits.ui.habits.edit.*;
+import javax.inject.*;
+
public class ShowHabitScreen extends BaseScreen
{
@NonNull
private final Habit habit;
+ @Inject
+ protected DialogFactory dialogFactory;
+
public ShowHabitScreen(@NonNull BaseActivity activity,
@NonNull Habit habit,
ShowHabitRootView view)
{
super(activity);
+ HabitsApplication.getComponent().inject(this);
+
this.habit = habit;
setRootView(view);
}
public void showEditHabitDialog()
{
- Long id = habit.getId();
- if (id == null) throw new RuntimeException("habit not saved");
-
- FragmentManager manager = activity.getSupportFragmentManager();
- EditHabitDialogFragment.newInstance(id).show(manager, "editHabit");
+ EditHabitDialog dialog = dialogFactory.buildEditHabitDialog(habit);
+ activity.showDialog(dialog, "editHabit");
}
public void showEditHistoryDialog(
diff --git a/app/src/main/java/org/isoron/uhabits/ui/intro/IntroActivity.java b/app/src/main/java/org/isoron/uhabits/ui/intro/IntroActivity.java
index 0e6bcdf45..19ce9d321 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/intro/IntroActivity.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/intro/IntroActivity.java
@@ -19,11 +19,11 @@
package org.isoron.uhabits.ui.intro;
-import android.graphics.Color;
-import android.os.Bundle;
+import android.content.*;
+import android.graphics.*;
+import android.os.*;
-import com.github.paolorotolo.appintro.AppIntro2;
-import com.github.paolorotolo.appintro.AppIntroFragment;
+import com.github.paolorotolo.appintro.*;
import org.isoron.uhabits.R;
diff --git a/app/src/main/java/org/isoron/uhabits/ui/settings/SettingsActivity.java b/app/src/main/java/org/isoron/uhabits/ui/settings/SettingsActivity.java
index 24198dc7b..c281f23d8 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/settings/SettingsActivity.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/settings/SettingsActivity.java
@@ -20,9 +20,6 @@
package org.isoron.uhabits.ui.settings;
import android.os.*;
-import android.support.annotation.*;
-import android.support.v4.app.*;
-import android.view.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.ui.*;
diff --git a/app/src/main/java/org/isoron/uhabits/ui/widgets/CheckmarkWidget.java b/app/src/main/java/org/isoron/uhabits/ui/widgets/CheckmarkWidget.java
index 6fcfb1133..14047809c 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/widgets/CheckmarkWidget.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/widgets/CheckmarkWidget.java
@@ -45,8 +45,8 @@ public class CheckmarkWidget extends BaseWidget
@Override
public PendingIntent getOnClickPendingIntent(Context context)
{
- IntentFactory factory = new IntentFactory(context);
- return factory.buildToggleCheckmark(habit, null);
+ PendingIntentFactory factory = new PendingIntentFactory(context);
+ return factory.toggleCheckmark(habit, null);
}
@Override
diff --git a/app/src/main/java/org/isoron/uhabits/ui/widgets/FrequencyWidget.java b/app/src/main/java/org/isoron/uhabits/ui/widgets/FrequencyWidget.java
index 113b01d95..0fe977538 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/widgets/FrequencyWidget.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/widgets/FrequencyWidget.java
@@ -46,8 +46,8 @@ public class FrequencyWidget extends BaseWidget
@Override
public PendingIntent getOnClickPendingIntent(Context context)
{
- IntentFactory factory = new IntentFactory(context);
- return factory.buildViewHabit(habit);
+ PendingIntentFactory factory = new PendingIntentFactory(context);
+ return factory.showHabit(habit);
}
@Override
diff --git a/app/src/main/java/org/isoron/uhabits/ui/widgets/HistoryWidget.java b/app/src/main/java/org/isoron/uhabits/ui/widgets/HistoryWidget.java
index e34586cca..d4ac726b2 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/widgets/HistoryWidget.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/widgets/HistoryWidget.java
@@ -44,8 +44,8 @@ public class HistoryWidget extends BaseWidget
@Override
public PendingIntent getOnClickPendingIntent(Context context)
{
- IntentFactory factory = new IntentFactory(context);
- return factory.buildViewHabit(habit);
+ PendingIntentFactory factory = new PendingIntentFactory(context);
+ return factory.showHabit(habit);
}
@Override
diff --git a/app/src/main/java/org/isoron/uhabits/ui/widgets/ScoreWidget.java b/app/src/main/java/org/isoron/uhabits/ui/widgets/ScoreWidget.java
index fe11f3658..4def1ba49 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/widgets/ScoreWidget.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/widgets/ScoreWidget.java
@@ -47,8 +47,8 @@ public class ScoreWidget extends BaseWidget
@Override
public PendingIntent getOnClickPendingIntent(Context context)
{
- IntentFactory factory = new IntentFactory(context);
- return factory.buildViewHabit(habit);
+ PendingIntentFactory factory = new PendingIntentFactory(context);
+ return factory.showHabit(habit);
}
@Override
diff --git a/app/src/main/java/org/isoron/uhabits/ui/widgets/StreakWidget.java b/app/src/main/java/org/isoron/uhabits/ui/widgets/StreakWidget.java
index 4957867e6..afc536a97 100644
--- a/app/src/main/java/org/isoron/uhabits/ui/widgets/StreakWidget.java
+++ b/app/src/main/java/org/isoron/uhabits/ui/widgets/StreakWidget.java
@@ -49,8 +49,8 @@ public class StreakWidget extends BaseWidget
@Override
public PendingIntent getOnClickPendingIntent(Context context)
{
- IntentFactory factory = new IntentFactory(context);
- return factory.buildViewHabit(habit);
+ PendingIntentFactory factory = new PendingIntentFactory(context);
+ return factory.showHabit(habit);
}
@Override
diff --git a/app/src/main/java/org/isoron/uhabits/utils/FileUtils.java b/app/src/main/java/org/isoron/uhabits/utils/FileUtils.java
index 867dbbcf0..4bc4a5d76 100644
--- a/app/src/main/java/org/isoron/uhabits/utils/FileUtils.java
+++ b/app/src/main/java/org/isoron/uhabits/utils/FileUtils.java
@@ -19,21 +19,15 @@
package org.isoron.uhabits.utils;
-import android.content.Context;
-import android.os.Environment;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.content.ContextCompat;
-import android.util.Log;
-
-import org.isoron.uhabits.HabitsApplication;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import android.content.*;
+import android.os.*;
+import android.support.annotation.*;
+import android.support.v4.content.*;
+import android.util.*;
+
+import org.isoron.uhabits.*;
+
+import java.io.*;
public abstract class FileUtils
{
@@ -60,60 +54,60 @@ public abstract class FileUtils
}
@Nullable
- public static File getSDCardDir(@Nullable String relativePath)
+ private static File getDir(@NonNull File potentialParentDirs[],
+ @Nullable String relativePath)
{
- File parents[] = new File[]{ Environment.getExternalStorageDirectory() };
- return getDir(parents, relativePath);
- }
-
- @Nullable
- public static File getFilesDir(@Nullable String relativePath)
- {
- Context context = HabitsApplication.getContext();
- if(context == null)
- {
- Log.e("DatabaseHelper", "getFilesDir: no application context available");
- return null;
- }
-
- File externalFilesDirs[] = ContextCompat.getExternalFilesDirs(context, null);
-
- if(externalFilesDirs == null)
- {
- Log.e("DatabaseHelper", "getFilesDir: getExternalFilesDirs returned null");
- return null;
- }
-
- return getDir(externalFilesDirs, relativePath);
- }
-
- @Nullable
- private static File getDir(@NonNull File potentialParentDirs[], @Nullable String relativePath)
- {
- if(relativePath == null) relativePath = "";
+ if (relativePath == null) relativePath = "";
File chosenDir = null;
- for(File dir : potentialParentDirs)
+ for (File dir : potentialParentDirs)
{
if (dir == null || !dir.canWrite()) continue;
chosenDir = dir;
break;
}
- if(chosenDir == null)
+ if (chosenDir == null)
{
- Log.e("DatabaseHelper", "getDir: all potential parents are null or non-writable");
+ Log.e("DatabaseHelper",
+ "getDir: all potential parents are null or non-writable");
return null;
}
- File dir = new File(String.format("%s/%s/", chosenDir.getAbsolutePath(), relativePath));
+ File dir = new File(
+ String.format("%s/%s/", chosenDir.getAbsolutePath(), relativePath));
if (!dir.exists() && !dir.mkdirs())
{
- Log.e("DatabaseHelper", "getDir: chosen dir does not exist and cannot be created");
+ Log.e("DatabaseHelper",
+ "getDir: chosen dir does not exist and cannot be created");
return null;
}
return dir;
}
+ @Nullable
+ public static File getFilesDir(@Nullable String relativePath)
+ {
+ Context context = HabitsApplication.getContext();
+ File externalFilesDirs[] =
+ ContextCompat.getExternalFilesDirs(context, null);
+
+ if (externalFilesDirs == null)
+ {
+ Log.e("DatabaseHelper",
+ "getFilesDir: getExternalFilesDirs returned null");
+ return null;
+ }
+
+ return getDir(externalFilesDirs, relativePath);
+ }
+
+ @Nullable
+ public static File getSDCardDir(@Nullable String relativePath)
+ {
+ File parents[] =
+ new File[]{ Environment.getExternalStorageDirectory() };
+ return getDir(parents, relativePath);
+ }
}
diff --git a/app/src/main/java/org/isoron/uhabits/utils/Preferences.java b/app/src/main/java/org/isoron/uhabits/utils/Preferences.java
index 22c631df6..5941a3541 100644
--- a/app/src/main/java/org/isoron/uhabits/utils/Preferences.java
+++ b/app/src/main/java/org/isoron/uhabits/utils/Preferences.java
@@ -24,12 +24,16 @@ import android.preference.*;
import org.isoron.uhabits.*;
+import javax.inject.*;
+
+@Singleton
public class Preferences
{
private Context context;
private SharedPreferences prefs;
+ @Inject
public Preferences()
{
this.context = HabitsApplication.getContext();
diff --git a/app/src/main/java/org/isoron/uhabits/utils/ReminderScheduler.java b/app/src/main/java/org/isoron/uhabits/utils/ReminderScheduler.java
index 19a6bbc82..48bbddacf 100644
--- a/app/src/main/java/org/isoron/uhabits/utils/ReminderScheduler.java
+++ b/app/src/main/java/org/isoron/uhabits/utils/ReminderScheduler.java
@@ -32,20 +32,21 @@ import javax.inject.*;
import static org.isoron.uhabits.utils.DateUtils.*;
+@Singleton
public class ReminderScheduler
{
- private final IntentFactory intentFactory;
+ @Inject
+ protected PendingIntentFactory pendingIntentFactory;
- private final IntentScheduler intentScheduler;
+ @Inject
+ protected IntentScheduler intentScheduler;
@Inject
HabitLogger logger;
- public ReminderScheduler(IntentFactory intentFactory,
- IntentScheduler intentScheduler)
+ @Inject
+ public ReminderScheduler()
{
- this.intentFactory = intentFactory;
- this.intentScheduler = intentScheduler;
HabitsApplication.getComponent().inject(this);
}
@@ -56,7 +57,7 @@ public class ReminderScheduler
if (reminderTime == null) reminderTime = getReminderTime(reminder);
long timestamp = getStartOfDay(toLocalTime(reminderTime));
- PendingIntent intent = intentFactory.buildShowReminder(habit,
+ PendingIntent intent = pendingIntentFactory.showReminder(habit,
reminderTime, timestamp);
intentScheduler.schedule(reminderTime, intent);
logger.logReminderScheduled(habit, reminderTime);
diff --git a/app/src/main/java/org/isoron/uhabits/utils/WidgetPreferences.java b/app/src/main/java/org/isoron/uhabits/utils/WidgetPreferences.java
index 6fac955b5..e0b3e4f5c 100644
--- a/app/src/main/java/org/isoron/uhabits/utils/WidgetPreferences.java
+++ b/app/src/main/java/org/isoron/uhabits/utils/WidgetPreferences.java
@@ -22,17 +22,17 @@ package org.isoron.uhabits.utils;
import android.content.*;
import android.preference.*;
-import org.isoron.uhabits.*;
+import javax.inject.*;
+@Singleton
public class WidgetPreferences
{
- private Context context;
private SharedPreferences prefs;
- public WidgetPreferences()
+ @Inject
+ public WidgetPreferences(Context context)
{
- this.context = HabitsApplication.getContext();
prefs = PreferenceManager.getDefaultSharedPreferences(context);
}
diff --git a/app/src/main/res/layout/edit_habit.xml b/app/src/main/res/layout/edit_habit.xml
index e744f58e5..cf76d7f43 100644
--- a/app/src/main/res/layout/edit_habit.xml
+++ b/app/src/main/res/layout/edit_habit.xml
@@ -22,7 +22,7 @@
style="@style/dialogForm"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
- tools:context=".ui.habits.edit.BaseDialogFragment"
+ tools:context=".ui.habits.edit.BaseDialog"
tools:ignore="MergeRootFrame">
+ *
+ * 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.ui.habits.list;
+
+
+import android.content.*;
+import android.support.v7.app.*;
+
+import org.isoron.uhabits.*;
+import org.isoron.uhabits.models.*;
+import org.isoron.uhabits.ui.*;
+import org.isoron.uhabits.ui.common.dialogs.*;
+import org.isoron.uhabits.ui.common.dialogs.ColorPickerDialog.*;
+import org.isoron.uhabits.ui.habits.edit.*;
+import org.junit.*;
+import org.junit.runner.*;
+import org.junit.runners.*;
+
+import java.io.*;
+
+import static org.mockito.Mockito.*;
+
+@RunWith(JUnit4.class)
+public class ListHabitsScreenTest extends BaseUnitTest
+{
+ private BaseActivity activity;
+
+ private ListHabitsRootView rootView;
+
+ private ListHabitsScreen screen;
+
+ private ListHabitsController controller;
+
+ private Habit habit;
+
+ private Intent intent;
+
+ @Before
+ @Override
+ public void setUp()
+ {
+ super.setUp();
+
+ activity = mock(BaseActivity.class);
+ rootView = mock(ListHabitsRootView.class);
+ controller = mock(ListHabitsController.class);
+ intent = mock(Intent.class);
+
+ habit = new Habit();
+ screen = new ListHabitsScreen(activity, rootView);
+ screen.setController(controller);
+ }
+
+ @Test
+ public void testCreateHabitScreen()
+ {
+ CreateHabitDialog dialog = mock(CreateHabitDialog.class);
+ when(dialogFactory.buildCreateHabitDialog()).thenReturn(dialog);
+
+ screen.showCreateHabitScreen();
+
+ verify(activity).showDialog(eq(dialog), any());
+ }
+
+ @Test
+ public void testOnResult_bugReport()
+ {
+ screen.onResult(0, HabitsApplication.RESULT_BUG_REPORT, null);
+ verify(controller).onSendBugReport();
+ }
+
+ @Test
+ public void testOnResult_exportCSV()
+ {
+ screen.onResult(0, HabitsApplication.RESULT_EXPORT_CSV, null);
+ verify(controller).onExportCSV();
+ }
+
+ @Test
+ public void testOnResult_exportDB()
+ {
+ screen.onResult(0, HabitsApplication.RESULT_EXPORT_DB, null);
+ verify(controller).onExportDB();
+ }
+
+ @Test
+ public void testOnResult_importData()
+ {
+ screen.onResult(0, HabitsApplication.RESULT_IMPORT_DATA, null);
+ testShowImportScreen();
+ }
+
+ @Test
+ public void testShowAboutScreen() throws Exception
+ {
+ when(intentFactory.startAboutActivity(activity)).thenReturn(intent);
+ screen.showAboutScreen();
+ verify(activity).startActivity(eq(intent));
+ }
+
+ @Test
+ public void testShowColorPicker()
+ {
+ habit.setColor(999);
+ ColorPickerDialog picker = mock(ColorPickerDialog.class);
+ when(dialogFactory.buildColorPicker(999)).thenReturn(picker);
+ OnColorSelectedListener callback = mock(OnColorSelectedListener.class);
+
+ screen.showColorPicker(habit, callback);
+
+ verify(activity).showDialog(eq(picker), any());
+ verify(picker).setListener(callback);
+ }
+
+ @Test
+ public void testShowDeleteConfirmationScreen()
+ {
+ ConfirmDeleteDialog.Callback callback;
+ callback = mock(ConfirmDeleteDialog.Callback.class);
+
+ ConfirmDeleteDialog dialog = mock(ConfirmDeleteDialog.class);
+ when(dialogFactory.buildConfirmDeleteDialog(activity,
+ callback)).thenReturn(dialog);
+
+ screen.showDeleteConfirmationScreen(callback);
+
+ verify(activity).showDialog(dialog);
+ }
+
+ @Test
+ public void testShowEditHabitScreen()
+ {
+ EditHabitDialog dialog = mock(EditHabitDialog.class);
+ when(dialogFactory.buildEditHabitDialog(habit)).thenReturn(dialog);
+
+ screen.showEditHabitScreen(habit);
+ verify(activity).showDialog(eq(dialog), any());
+ }
+
+ @Test
+ public void testShowFAQScreen()
+ {
+ when(intentFactory.viewFAQ(activity)).thenReturn(intent);
+ screen.showFAQScreen();
+ verify(activity).startActivity(intent);
+ }
+
+ @Test
+ public void testShowHabitScreen()
+ {
+ when(intentFactory.startShowHabitActivity(activity, habit)).thenReturn(
+ intent);
+ screen.showHabitScreen(habit);
+ verify(activity).startActivity(intent);
+ }
+
+ @Test
+ public void testShowImportScreen()
+ {
+ File dir = mock(File.class);
+ when(dirFinder.findStorageDir(any())).thenReturn(dir);
+
+ FilePickerDialog picker = mock(FilePickerDialog.class);
+ AppCompatDialog dialog = mock(AppCompatDialog.class);
+ when(picker.getDialog()).thenReturn(dialog);
+ when(dialogFactory.buildFilePicker(activity, dir)).thenReturn(picker);
+
+ screen.showImportScreen();
+
+ verify(activity).showDialog(dialog);
+ }
+
+ @Test
+ public void testShowImportScreen_withInvalidPath()
+ {
+ when(dirFinder.findStorageDir(any())).thenReturn(null);
+ screen.showImportScreen();
+ verify(activity).showMessage(R.string.could_not_import);
+ }
+
+ @Test
+ public void testShowIntroScreen()
+ {
+ when(intentFactory.startIntroActivity(activity)).thenReturn(intent);
+ screen.showIntroScreen();
+ verify(activity).startActivity(intent);
+ }
+
+ @Test
+ public void testShowSettingsScreen()
+ {
+ when(intentFactory.startSettingsActivity(activity)).thenReturn(intent);
+ screen.showSettingsScreen();
+ verify(activity).startActivityForResult(eq(intent), anyInt());
+ }
+}
\ No newline at end of file
diff --git a/app/src/test/java/org/isoron/uhabits/utils/ReminderSchedulerTest.java b/app/src/test/java/org/isoron/uhabits/utils/ReminderSchedulerTest.java
index 07cc76311..d6171c7b2 100644
--- a/app/src/test/java/org/isoron/uhabits/utils/ReminderSchedulerTest.java
+++ b/app/src/test/java/org/isoron/uhabits/utils/ReminderSchedulerTest.java
@@ -22,7 +22,6 @@ package org.isoron.uhabits.utils;
import android.app.*;
import org.isoron.uhabits.*;
-import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.models.*;
import org.junit.*;
@@ -31,26 +30,19 @@ import static org.mockito.Mockito.*;
@SuppressWarnings("JavaDoc")
public class ReminderSchedulerTest extends BaseUnitTest
{
- private IntentFactory intentFactory;
-
- private IntentScheduler intentScheduler;
-
- private ReminderScheduler scheduler;
-
private Habit habit;
private PendingIntent intent;
+ private ReminderScheduler reminderScheduler;
+
@Before
@Override
public void setUp()
{
super.setUp();
- intentFactory = mock(IntentFactory.class);
- intentScheduler = mock(IntentScheduler.class);
intent = mock(PendingIntent.class);
-
- scheduler = new ReminderScheduler(intentFactory, intentScheduler);
+ reminderScheduler = new ReminderScheduler();
habit = fixtures.createEmptyHabit();
}
@@ -94,7 +86,7 @@ public class ReminderSchedulerTest extends BaseUnitTest
fixtures.createEmptyHabit();
- scheduler.schedule(habitList);
+ reminderScheduler.schedule(habitList);
verify(intentScheduler).schedule(1422347400000L, null);
verify(intentScheduler).schedule(1422297000000L, null);
@@ -117,7 +109,7 @@ public class ReminderSchedulerTest extends BaseUnitTest
@Test
public void testSchedule_withoutReminder()
{
- scheduler.schedule(habit, null);
+ reminderScheduler.schedule(habit, null);
verifyZeroInteractions(intentScheduler);
}
@@ -125,15 +117,15 @@ public class ReminderSchedulerTest extends BaseUnitTest
long expectedCheckmarkTime,
long expectedReminderTime)
{
- when(intentFactory.buildShowReminder(habit, expectedReminderTime,
- expectedCheckmarkTime)).thenReturn(intent);
+ when(pendingIntentFactory.showReminder(habit, expectedReminderTime,
+ expectedCheckmarkTime)).thenReturn(intent);
- scheduler.schedule(habit, atTime);
+ reminderScheduler.schedule(habit, atTime);
verify(logger).logReminderScheduled(habit, expectedReminderTime);
- verify(intentFactory).buildShowReminder(habit, expectedReminderTime,
- expectedCheckmarkTime);
+ verify(pendingIntentFactory).showReminder(habit, expectedReminderTime,
+ expectedCheckmarkTime);
verify(intentScheduler).schedule(expectedReminderTime, intent);
}
}