Move ListHabits controllers to uhabits-core

pull/87/merge
Alinson S. Xavier 8 years ago
parent 94c70485b7
commit 70423ddb0a

@ -5,7 +5,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alpha1' classpath 'com.android.tools.build:gradle:3.0.0-alpha2'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.6.4' classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.6.4'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

@ -23,10 +23,10 @@ import android.view.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.habits.list.model.*; import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.*;
import org.junit.*; import org.junit.*;
import org.mockito.*; import org.mockito.*;
@ -63,7 +63,7 @@ public class ListHabitsMenuTest extends BaseAndroidTest
when(preferences.getShowCompleted()).thenReturn(false); when(preferences.getShowCompleted()).thenReturn(false);
when(themeSwitcher.isNightMode()).thenReturn(false); when(themeSwitcher.isNightMode()).thenReturn(false);
menu = new ListHabitsMenu(activity, screen, adapter, preferences, menu = new ListHabitsMenu(activity, preferences,
themeSwitcher); themeSwitcher);
matcherCaptor = ArgumentCaptor.forClass(HabitMatcher.class); matcherCaptor = ArgumentCaptor.forClass(HabitMatcher.class);

@ -24,7 +24,6 @@ import android.content.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.common.dialogs.*; import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialog.*; import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialog.*;
import org.isoron.uhabits.activities.habits.edit.*; import org.isoron.uhabits.activities.habits.edit.*;
@ -32,6 +31,7 @@ import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.intents.*; import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.*;
import org.junit.*; import org.junit.*;
import org.junit.runner.*; import org.junit.runner.*;
import org.junit.runners.*; import org.junit.runners.*;
@ -89,7 +89,7 @@ public class ListHabitsScreenTest extends BaseAndroidTest
screen = spy(new ListHabitsScreen(activity, commandRunner, rootView, screen = spy(new ListHabitsScreen(activity, commandRunner, rootView,
intentFactory, themeSwitcher, confirmDeleteDialogFactory, intentFactory, themeSwitcher, confirmDeleteDialogFactory,
colorPickerDialogFactory, dialogFactory, prefs, commandParser)); colorPickerDialogFactory, dialogFactory, prefs));
doNothing().when(screen).showMessage(anyInt()); doNothing().when(screen).showMessage(anyInt());
@ -122,7 +122,7 @@ public class ListHabitsScreenTest extends BaseAndroidTest
public void testOnCommand() public void testOnCommand()
{ {
Command c = mock(Command.class); Command c = mock(Command.class);
when(commandParser.getExecuteString(c)).thenReturn( when(getExecuteString(c)).thenReturn(
R.string.toast_habit_deleted); R.string.toast_habit_deleted);
screen.onCommandExecuted(c, null); screen.onCommandExecuted(c, null);
verify(screen).showMessage(R.string.toast_habit_deleted); verify(screen).showMessage(R.string.toast_habit_deleted);
@ -251,10 +251,9 @@ public class ListHabitsScreenTest extends BaseAndroidTest
} }
@Test @Test
public void testToggleNightMode() public void testApplyTheme()
{ {
screen.toggleNightMode(); screen.applyTheme();
verify(themeSwitcher).toggleNightMode();
verify(activity).restartWithFade(ListHabitsActivity.class); verify(activity).restartWithFade(ListHabitsActivity.class);
} }
} }

@ -20,8 +20,8 @@
package org.isoron.uhabits.activities.habits.list.controllers; package org.isoron.uhabits.activities.habits.list.controllers;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.activities.habits.list.model.*; import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.activities.habits.list.views.*; import org.isoron.uhabits.activities.habits.list.views.*;
import org.junit.*; import org.junit.*;

@ -23,6 +23,7 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*; import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*; import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import org.junit.*; import org.junit.*;

@ -23,7 +23,7 @@ import android.support.test.runner.*;
import android.test.suitebuilder.annotation.*; import android.test.suitebuilder.annotation.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.habits.list.model.*; import org.isoron.uhabits.ui.screens.habits.list.*;
import org.junit.*; import org.junit.*;
import org.junit.runner.*; import org.junit.runner.*;

@ -35,7 +35,7 @@ public class ReminderControllerTest extends BaseAndroidTest
private ReminderScheduler reminderScheduler; private ReminderScheduler reminderScheduler;
private NotificationTray notificationTray; private AndroidNotificationTray notificationTray;
private AndroidPreferences preferences; private AndroidPreferences preferences;
@ -45,7 +45,7 @@ public class ReminderControllerTest extends BaseAndroidTest
super.setUp(); super.setUp();
reminderScheduler = mock(ReminderScheduler.class); reminderScheduler = mock(ReminderScheduler.class);
notificationTray = mock(NotificationTray.class); notificationTray = mock(AndroidNotificationTray.class);
preferences = mock(AndroidPreferences.class); preferences = mock(AndroidPreferences.class);
controller = new ReminderController(reminderScheduler, controller = new ReminderController(reminderScheduler,

@ -23,6 +23,7 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*; import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.notifications.*; import org.isoron.uhabits.notifications.*;
import org.isoron.uhabits.ui.widgets.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import org.junit.*; import org.junit.*;
@ -33,7 +34,7 @@ import static org.mockito.Mockito.*;
public class WidgetControllerTest extends BaseAndroidTest public class WidgetControllerTest extends BaseAndroidTest
{ {
private WidgetController controller; private WidgetBehavior controller;
private CommandRunner commandRunner; private CommandRunner commandRunner;
@ -41,7 +42,7 @@ public class WidgetControllerTest extends BaseAndroidTest
private long today; private long today;
private NotificationTray notificationTray; private AndroidNotificationTray notificationTray;
@Override @Override
public void setUp() public void setUp()
@ -52,8 +53,8 @@ public class WidgetControllerTest extends BaseAndroidTest
habit = fixtures.createEmptyHabit(); habit = fixtures.createEmptyHabit();
habitList.add(habit); habitList.add(habit);
commandRunner = mock(CommandRunner.class); commandRunner = mock(CommandRunner.class);
notificationTray = mock(NotificationTray.class); notificationTray = mock(AndroidNotificationTray.class);
controller = new WidgetController(commandRunner, notificationTray); controller = new WidgetBehavior(commandRunner, notificationTray);
} }
@Test @Test

@ -28,8 +28,8 @@ import android.view.*;
import org.isoron.androidbase.utils.*; import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.ui.habits.list.*; import org.isoron.uhabits.ui.screens.habits.list.*;
import org.isoron.uhabits.ui.habits.show.*; import org.isoron.uhabits.ui.screens.habits.show.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import java.io.*; import java.io.*;

@ -20,8 +20,8 @@
package org.isoron.androidbase.activities; package org.isoron.androidbase.activities;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.common.dialogs.*; import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.ui.*;
import dagger.*; import dagger.*;

@ -21,6 +21,9 @@ package org.isoron.androidbase.activities;
import android.content.*; import android.content.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.ui.*;
import dagger.*; import dagger.*;
@Module @Module
@ -45,4 +48,11 @@ public class ActivityModule
{ {
return activity; return activity;
} }
@Provides
@ActivityScope
public static ThemeSwitcher getThemeSwitcher(AndroidThemeSwitcher t)
{
return t;
}
} }

@ -27,7 +27,7 @@ import android.view.*;
import android.widget.*; import android.widget.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*; import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import static android.os.Build.VERSION.*; import static android.os.Build.VERSION.*;

@ -47,7 +47,7 @@ public class HabitsApplication extends Application
private ReminderScheduler reminderScheduler; private ReminderScheduler reminderScheduler;
private NotificationTray notificationTray; private AndroidNotificationTray notificationTray;
public HabitsComponent getComponent() public HabitsComponent getComponent()
{ {
@ -106,7 +106,7 @@ public class HabitsApplication extends Application
reminderScheduler = component.getReminderScheduler(); reminderScheduler = component.getReminderScheduler();
reminderScheduler.startListening(); reminderScheduler.startListening();
notificationTray = component.getNotificationTray(); notificationTray = component.getAndroidNotificationTray();
notificationTray.startListening(); notificationTray.startListening();
AndroidPreferences prefs = component.getPreferences(); AndroidPreferences prefs = component.getPreferences();

@ -22,7 +22,6 @@ package org.isoron.uhabits;
import android.content.*; import android.content.*;
import org.isoron.androidbase.*; import org.isoron.androidbase.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.commands.*; import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.intents.*; import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.io.*; import org.isoron.uhabits.io.*;
@ -33,6 +32,8 @@ import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.sync.*; import org.isoron.uhabits.sync.*;
import org.isoron.uhabits.tasks.*; import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.tasks.android.*; import org.isoron.uhabits.tasks.android.*;
import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import org.isoron.uhabits.widgets.*; import org.isoron.uhabits.widgets.*;
@ -47,8 +48,6 @@ import dagger.*;
}) })
public interface HabitsComponent public interface HabitsComponent
{ {
AndroidPreferences getPreferences();
BaseSystem getBaseSystem(); BaseSystem getBaseSystem();
CommandRunner getCommandRunner(); CommandRunner getCommandRunner();
@ -56,6 +55,8 @@ public interface HabitsComponent
@AppContext @AppContext
Context getContext(); Context getContext();
Preferences getCorePreferences();
CreateHabitCommandFactory getCreateHabitCommandFactory(); CreateHabitCommandFactory getCreateHabitCommandFactory();
EditHabitCommandFactory getEditHabitCommandFactory(); EditHabitCommandFactory getEditHabitCommandFactory();
@ -80,7 +81,9 @@ public interface HabitsComponent
PendingIntentFactory getPendingIntentFactory(); PendingIntentFactory getPendingIntentFactory();
Preferences getCorePreferences(); AndroidPreferences getPreferences();
AndroidNotificationTray getAndroidNotificationTray();
ReminderScheduler getReminderScheduler(); ReminderScheduler getReminderScheduler();

@ -19,7 +19,9 @@
package org.isoron.uhabits; package org.isoron.uhabits;
import org.isoron.uhabits.notifications.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.*;
import dagger.*; import dagger.*;
@ -32,4 +34,13 @@ public class HabitsModule
{ {
return preferences; return preferences;
} }
@Provides
@AppScope
public static NotificationTray getTray(AndroidNotificationTray tray)
{
return tray;
}
} }

@ -0,0 +1,63 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.activities;
import android.support.annotation.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.*;
import javax.inject.*;
@ActivityScope
public class AndroidThemeSwitcher extends ThemeSwitcher
{
@NonNull
private final BaseActivity activity;
@Inject
public AndroidThemeSwitcher(@NonNull BaseActivity activity,
@NonNull Preferences preferences)
{
super(preferences);
this.activity = activity;
}
@Override
public void applyDarkTheme()
{
activity.setTheme(R.style.AppBaseThemeDark);
}
@Override
public void applyLightTheme()
{
activity.setTheme(R.style.AppBaseTheme);
}
@Override
public void applyPureBlackTheme()
{
activity.setTheme(R.style.AppBaseThemeDark_PureBlack);
}
}

@ -23,7 +23,7 @@ import android.os.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.ui.about.*; import org.isoron.uhabits.ui.screens.about.*;
/** /**
* Activity that allows the user to see information about the app itself. * Activity that allows the user to see information about the app itself.

@ -26,7 +26,7 @@ import android.widget.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.BuildConfig; import org.isoron.uhabits.BuildConfig;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.ui.about.*; import org.isoron.uhabits.ui.screens.about.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import butterknife.*; import butterknife.*;
@ -36,15 +36,6 @@ public class AboutRootView extends BaseRootView
@BindView(R.id.tvVersion) @BindView(R.id.tvVersion)
TextView tvVersion; TextView tvVersion;
@BindView(R.id.tvRate)
TextView tvRate;
@BindView(R.id.tvFeedback)
TextView tvFeedback;
@BindView(R.id.tvSource)
TextView tvSource;
@NonNull @NonNull
private final AboutBehavior behavior; private final AboutBehavior behavior;

@ -24,7 +24,7 @@ import android.widget.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.intents.*; import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.ui.about.*; import org.isoron.uhabits.ui.screens.about.*;
import javax.inject.*; import javax.inject.*;

@ -19,6 +19,7 @@
package org.isoron.uhabits.activities.common.dialogs; package org.isoron.uhabits.activities.common.dialogs;
import org.isoron.uhabits.ui.callbacks.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
/** /**
@ -26,16 +27,12 @@ import org.isoron.uhabits.utils.*;
*/ */
public class ColorPickerDialog extends com.android.colorpicker.ColorPickerDialog public class ColorPickerDialog extends com.android.colorpicker.ColorPickerDialog
{ {
public void setListener(OnColorSelectedListener listener) public void setListener(OnColorPickedCallback callback)
{
super.setOnColorSelectedListener(c ->
{ {
super.setOnColorSelectedListener(c -> {
c = ColorUtils.colorToPaletteIndex(getContext(), c); c = ColorUtils.colorToPaletteIndex(getContext(), c);
listener.onColorSelected(c); callback.onColorPicked(c);
}); });
} }
public interface OnColorSelectedListener
{
void onColorSelected(int color);
}
} }

@ -20,12 +20,14 @@
package org.isoron.uhabits.activities.common.dialogs; package org.isoron.uhabits.activities.common.dialogs;
import android.content.*; import android.content.*;
import android.support.annotation.*;
import android.support.v7.app.*; import android.support.v7.app.*;
import com.google.auto.factory.*; import com.google.auto.factory.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.ui.callbacks.*;
import butterknife.*; import butterknife.*;
@ -45,19 +47,14 @@ public class ConfirmDeleteDialog extends AlertDialog
protected String no; protected String no;
protected ConfirmDeleteDialog(@Provided @ActivityContext Context context, protected ConfirmDeleteDialog(@Provided @ActivityContext Context context,
Callback callback) @NonNull OnConfirmedCallback callback)
{ {
super(context); super(context);
ButterKnife.bind(this); ButterKnife.bind(this);
setTitle(R.string.delete_habits); setTitle(R.string.delete_habits);
setMessage(question); setMessage(question);
setButton(BUTTON_POSITIVE, yes, (dialog, which) -> callback.run()); setButton(BUTTON_POSITIVE, yes, (dialog, which) -> callback.onConfirmed());
setButton(BUTTON_NEGATIVE, no, (dialog, which) -> {}); setButton(BUTTON_NEGATIVE, no, (dialog, which) -> {});
} }
public interface Callback
{
void run();
}
} }

@ -24,10 +24,10 @@ import android.os.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.habits.list.model.*; import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.sync.*; import org.isoron.uhabits.sync.*;
import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
/** /**
@ -81,6 +81,7 @@ public class ListHabitsActivity extends BaseActivity
screen.setMenu(menu); screen.setMenu(menu);
screen.setController(controller); screen.setController(controller);
screen.setListController(component.getListController());
screen.setSelectionMenu(selectionMenu); screen.setSelectionMenu(selectionMenu);
rootView.setController(controller, selectionMenu); rootView.setController(controller, selectionMenu);

@ -37,6 +37,8 @@ public interface ListHabitsComponent
ListHabitsController getController(); ListHabitsController getController();
HabitCardListController getListController();
ListHabitsMenu getMenu(); ListHabitsMenu getMenu();
NumberButtonControllerFactory getNumberButtonControllerFactory(); NumberButtonControllerFactory getNumberButtonControllerFactory();

@ -28,7 +28,7 @@ import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*; import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.tasks.android.*; import org.isoron.uhabits.tasks.android.*;
import org.isoron.uhabits.ui.habits.list.*; import org.isoron.uhabits.ui.screens.habits.list.*;
import java.io.*; import java.io.*;

@ -24,58 +24,44 @@ import android.view.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import javax.inject.*; import javax.inject.*;
@ActivityScope @ActivityScope
public class ListHabitsMenu extends BaseMenu public class ListHabitsMenu extends BaseMenu
{ {
@NonNull
private final ListHabitsScreen screen;
private final HabitCardListAdapter adapter;
private boolean showArchived;
private boolean showCompleted; @NonNull
private final ListHabitsMenuBehavior behavior;
private final AndroidPreferences preferences; private final Preferences preferences;
private ThemeSwitcher themeSwitcher; private ThemeSwitcher themeSwitcher;
@Inject @Inject
public ListHabitsMenu(@NonNull BaseActivity activity, public ListHabitsMenu(@NonNull BaseActivity activity,
@NonNull ListHabitsScreen screen, @NonNull Preferences preferences,
@NonNull HabitCardListAdapter adapter, @NonNull ThemeSwitcher themeSwitcher,
@NonNull AndroidPreferences preferences, @NonNull ListHabitsMenuBehavior behavior)
@NonNull ThemeSwitcher themeSwitcher)
{ {
super(activity); super(activity);
this.screen = screen;
this.adapter = adapter;
this.preferences = preferences; this.preferences = preferences;
this.themeSwitcher = themeSwitcher; this.themeSwitcher = themeSwitcher;
this.behavior = behavior;
showCompleted = preferences.getShowCompleted();
showArchived = preferences.getShowArchived();
updateAdapterFilter();
} }
@Override @Override
public void onCreate(@NonNull Menu menu) public void onCreate(@NonNull Menu menu)
{ {
MenuItem nightModeItem = menu.findItem(R.id.actionToggleNightMode); MenuItem nightModeItem = menu.findItem(R.id.actionToggleNightMode);
nightModeItem.setChecked(themeSwitcher.isNightMode());
MenuItem hideArchivedItem = menu.findItem(R.id.actionHideArchived); MenuItem hideArchivedItem = menu.findItem(R.id.actionHideArchived);
hideArchivedItem.setChecked(!showArchived);
MenuItem hideCompletedItem = menu.findItem(R.id.actionHideCompleted); MenuItem hideCompletedItem = menu.findItem(R.id.actionHideCompleted);
hideCompletedItem.setChecked(!showCompleted); nightModeItem.setChecked(themeSwitcher.isNightMode());
hideArchivedItem.setChecked(!preferences.getShowArchived());
hideCompletedItem.setChecked(!preferences.getShowCompleted());
} }
@Override @Override
@ -84,49 +70,49 @@ public class ListHabitsMenu extends BaseMenu
switch (item.getItemId()) switch (item.getItemId())
{ {
case R.id.actionToggleNightMode: case R.id.actionToggleNightMode:
screen.toggleNightMode(); behavior.onToggleNightMode();
return true; return true;
case R.id.actionAdd: case R.id.actionAdd:
screen.showCreateHabitScreen(); behavior.onCreateHabit();
return true; return true;
case R.id.actionFAQ: case R.id.actionFAQ:
screen.showFAQScreen(); behavior.onViewFAQ();
return true; return true;
case R.id.actionAbout: case R.id.actionAbout:
screen.showAboutScreen(); behavior.onViewAbout();
return true; return true;
case R.id.actionSettings: case R.id.actionSettings:
screen.showSettingsScreen(); behavior.onViewSettings();
return true; return true;
case R.id.actionHideArchived: case R.id.actionHideArchived:
toggleShowArchived(); behavior.onToggleShowArchived();
invalidate(); invalidate();
return true; return true;
case R.id.actionHideCompleted: case R.id.actionHideCompleted:
toggleShowCompleted(); behavior.onToggleShowCompleted();
invalidate(); invalidate();
return true; return true;
case R.id.actionSortColor: case R.id.actionSortColor:
adapter.setOrder(HabitList.Order.BY_COLOR); behavior.onSortByColor();
return true; return true;
case R.id.actionSortManual: case R.id.actionSortManual:
adapter.setOrder(HabitList.Order.BY_POSITION); behavior.onSortByManually();
return true; return true;
case R.id.actionSortName: case R.id.actionSortName:
adapter.setOrder(HabitList.Order.BY_NAME); behavior.onSortByName();
return true; return true;
case R.id.actionSortScore: case R.id.actionSortScore:
adapter.setOrder(HabitList.Order.BY_SCORE); behavior.onSortByScore();
return true; return true;
default: default:
@ -140,26 +126,4 @@ public class ListHabitsMenu extends BaseMenu
return R.menu.list_habits; return R.menu.list_habits;
} }
private void toggleShowArchived()
{
showArchived = !showArchived;
preferences.setShowArchived(showArchived);
updateAdapterFilter();
}
private void toggleShowCompleted()
{
showCompleted = !showCompleted;
preferences.setShowCompleted(showCompleted);
updateAdapterFilter();
}
private void updateAdapterFilter()
{
adapter.setFilter(new HabitMatcherBuilder()
.setArchivedAllowed(showArchived)
.setCompletedAllowed(showCompleted)
.build());
adapter.refresh();
}
} }

@ -22,7 +22,8 @@ package org.isoron.uhabits.activities.habits.list;
import org.isoron.androidbase.*; import org.isoron.androidbase.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.ui.habits.list.*; import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import dagger.*; import dagger.*;
@ -34,12 +35,37 @@ public class ListHabitsModule extends ActivityModule
super(activity); super(activity);
} }
@Provides
ListHabitsMenuBehavior.Adapter getAdapter(HabitCardListAdapter adapter)
{
return adapter;
}
@Provides
ListHabitsMenuBehavior.Screen getMenuScreen(ListHabitsScreen screen)
{
return screen;
}
@Provides @Provides
ListHabitsBehavior.Screen getScreen(ListHabitsScreen screen) ListHabitsBehavior.Screen getScreen(ListHabitsScreen screen)
{ {
return screen; return screen;
} }
@Provides
ListHabitsSelectionMenuBehavior.Adapter getSelMenuAdapter(
HabitCardListAdapter adapter)
{
return adapter;
}
@Provides
ListHabitsSelectionMenuBehavior.Screen getSelMenuScreen(ListHabitsScreen screen)
{
return screen;
}
@Provides @Provides
ListHabitsBehavior.System getSystem(BaseSystem system) ListHabitsBehavior.System getSystem(BaseSystem system)
{ {

@ -33,6 +33,7 @@ import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.activities.habits.list.views.*; import org.isoron.uhabits.activities.habits.list.views.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*; import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import javax.inject.*; import javax.inject.*;
@ -134,7 +135,8 @@ public class ListHabitsRootView extends BaseRootView
listController.setSelectionListener(menu); listController.setSelectionListener(menu);
listView.setController(listController); listView.setController(listController);
menu.setListController(listController); menu.setListController(listController);
header.setScrollController(new ScrollableChart.ScrollController() { header.setScrollController(new ScrollableChart.ScrollController()
{
@Override @Override
public void onDataOffsetChanged(int newDataOffset) public void onDataOffsetChanged(int newDataOffset)
{ {
@ -187,7 +189,8 @@ public class ListHabitsRootView extends BaseRootView
private void updateProgressBar() private void updateProgressBar()
{ {
postDelayed(() -> { postDelayed(() ->
{
int activeTaskCount = runner.getActiveTaskCount(); int activeTaskCount = runner.getActiveTaskCount();
int newVisibility = activeTaskCount > 0 ? VISIBLE : GONE; int newVisibility = activeTaskCount > 0 ? VISIBLE : GONE;
if (progressBar.getVisibility() != newVisibility) if (progressBar.getVisibility() != newVisibility)

@ -31,19 +31,21 @@ import android.widget.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.androidbase.utils.*; import org.isoron.androidbase.utils.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.activities.common.dialogs.*; import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialog.*;
import org.isoron.uhabits.activities.habits.edit.*; import org.isoron.uhabits.activities.habits.edit.*;
import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.commands.*; import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.intents.*; import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.habits.list.*; import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.ui.callbacks.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import java.io.*; import java.io.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.*;
import javax.inject.*; import javax.inject.*;
@ -52,7 +54,9 @@ import static android.view.inputmethod.EditorInfo.*;
@ActivityScope @ActivityScope
public class ListHabitsScreen extends BaseScreen public class ListHabitsScreen extends BaseScreen
implements CommandRunner.Listener, ListHabitsBehavior.Screen implements CommandRunner.Listener, ListHabitsBehavior.Screen,
ListHabitsMenuBehavior.Screen,
ListHabitsSelectionMenuBehavior.Screen
{ {
public static final int REQUEST_OPEN_DOCUMENT = 6; public static final int REQUEST_OPEN_DOCUMENT = 6;
@ -92,8 +96,10 @@ public class ListHabitsScreen extends BaseScreen
@NonNull @NonNull
private AndroidPreferences prefs; private AndroidPreferences prefs;
@NonNull @Nullable
private final CommandParser commandParser; private HabitCardListController listController;
private final ListHabitsRootView rootView;
@Inject @Inject
public ListHabitsScreen(@NonNull BaseActivity activity, public ListHabitsScreen(@NonNull BaseActivity activity,
@ -101,18 +107,14 @@ public class ListHabitsScreen extends BaseScreen
@NonNull ListHabitsRootView rootView, @NonNull ListHabitsRootView rootView,
@NonNull IntentFactory intentFactory, @NonNull IntentFactory intentFactory,
@NonNull ThemeSwitcher themeSwitcher, @NonNull ThemeSwitcher themeSwitcher,
@NonNull @NonNull ConfirmDeleteDialogFactory confirmDeleteDialogFactory,
ConfirmDeleteDialogFactory confirmDeleteDialogFactory, @NonNull ColorPickerDialogFactory colorPickerFactory,
@NonNull @NonNull EditHabitDialogFactory editHabitDialogFactory,
ColorPickerDialogFactory colorPickerFactory, @NonNull AndroidPreferences prefs)
@NonNull
EditHabitDialogFactory editHabitDialogFactory,
@NonNull AndroidPreferences prefs,
@NonNull CommandParser commandParser)
{ {
super(activity); super(activity);
this.commandParser = commandParser;
setRootView(rootView); setRootView(rootView);
this.rootView = rootView;
this.prefs = prefs; this.prefs = prefs;
this.colorPickerFactory = colorPickerFactory; this.colorPickerFactory = colorPickerFactory;
this.commandRunner = commandRunner; this.commandRunner = commandRunner;
@ -122,6 +124,35 @@ public class ListHabitsScreen extends BaseScreen
this.themeSwitcher = themeSwitcher; this.themeSwitcher = themeSwitcher;
} }
public void setListController(HabitCardListController listController)
{
this.listController = listController;
}
@StringRes
private Integer getExecuteString(@NonNull Command command)
{
if(command instanceof ArchiveHabitsCommand)
return R.string.toast_habit_archived;
if(command instanceof ChangeHabitColorCommand)
return R.string.toast_habit_changed;
if(command instanceof CreateHabitCommand)
return R.string.toast_habit_created;
if(command instanceof DeleteHabitsCommand)
return R.string.toast_habit_deleted;
if(command instanceof EditHabitCommand)
return R.string.toast_habit_changed;
if(command instanceof UnarchiveHabitsCommand)
return R.string.toast_habit_unarchived;
return null;
}
public void onAttached() public void onAttached()
{ {
commandRunner.addListener(this); commandRunner.addListener(this);
@ -132,7 +163,7 @@ public class ListHabitsScreen extends BaseScreen
@Nullable Long refreshKey) @Nullable Long refreshKey)
{ {
if (command.isRemote()) return; if (command.isRemote()) return;
showMessage(commandParser.getExecuteString(command)); showMessage(getExecuteString(command));
} }
public void onDettached() public void onDettached()
@ -154,24 +185,24 @@ public class ListHabitsScreen extends BaseScreen
this.controller = controller; this.controller = controller;
} }
@Override
public void applyTheme()
{
themeSwitcher.apply();
activity.restartWithFade(ListHabitsActivity.class);
}
@Override
public void showAboutScreen() public void showAboutScreen()
{ {
Intent intent = intentFactory.startAboutActivity(activity); Intent intent = intentFactory.startAboutActivity(activity);
activity.startActivity(intent); activity.startActivity(intent);
} }
/** @Override
* Displays a {@link ColorPickerDialog} to the user. public void showColorPicker(int defaultColor,
* <p> @NonNull OnColorPickedCallback callback) {
* The selected color on the dialog is the color of the given habit. ColorPickerDialog picker = colorPickerFactory.create(defaultColor);
*
* @param habit the habit
* @param callback
*/
public void showColorPicker(@NonNull Habit habit,
@NonNull OnColorSelectedListener callback)
{
ColorPickerDialog picker = colorPickerFactory.create(habit.getColor());
picker.setListener(callback); picker.setListener(callback);
activity.showDialog(picker, "picker"); activity.showDialog(picker, "picker");
} }
@ -183,6 +214,7 @@ public class ListHabitsScreen extends BaseScreen
activity.showDialog(dialog, "editHabit"); activity.showDialog(dialog, "editHabit");
} }
@Override
public void showCreateHabitScreen() public void showCreateHabitScreen()
{ {
if (!prefs.isNumericalHabitsFeatureEnabled()) if (!prefs.isNumericalHabitsFeatureEnabled())
@ -203,18 +235,22 @@ public class ListHabitsScreen extends BaseScreen
dialog.show(); dialog.show();
} }
public void showDeleteConfirmationScreen(ConfirmDeleteDialog.Callback callback) @Override
public void showDeleteConfirmationScreen(
@NonNull OnConfirmedCallback callback)
{ {
activity.showDialog(confirmDeleteDialogFactory.create(callback)); activity.showDialog(confirmDeleteDialogFactory.create(callback));
} }
public void showEditHabitScreen(Habit habit) @Override
public void showEditHabitsScreen(List<Habit> habits)
{ {
EditHabitDialog dialog; EditHabitDialog dialog;
dialog = editHabitDialogFactory.edit(habit); dialog = editHabitDialogFactory.edit(habits.get(0));
activity.showDialog(dialog, "editNumericalHabit"); activity.showDialog(dialog, "editNumericalHabit");
} }
@Override
public void showFAQScreen() public void showFAQScreen()
{ {
Intent intent = intentFactory.viewFAQ(activity); Intent intent = intentFactory.viewFAQ(activity);
@ -275,7 +311,8 @@ public class ListHabitsScreen extends BaseScreen
@Override @Override
public void showNumberPicker(double value, public void showNumberPicker(double value,
@NonNull String unit, @NonNull String unit,
@NonNull ListHabitsBehavior.NumberPickerCallback callback) @NonNull
ListHabitsBehavior.NumberPickerCallback callback)
{ {
LayoutInflater inflater = activity.getLayoutInflater(); LayoutInflater inflater = activity.getLayoutInflater();
View view = inflater.inflate(R.layout.number_picker_dialog, null); View view = inflater.inflate(R.layout.number_picker_dialog, null);
@ -332,18 +369,13 @@ public class ListHabitsScreen extends BaseScreen
showSendEmailScreen(to, subject, log); showSendEmailScreen(to, subject, log);
} }
@Override
public void showSettingsScreen() public void showSettingsScreen()
{ {
Intent intent = intentFactory.startSettingsActivity(activity); Intent intent = intentFactory.startSettingsActivity(activity);
activity.startActivityForResult(intent, REQUEST_SETTINGS); activity.startActivityForResult(intent, REQUEST_SETTINGS);
} }
public void toggleNightMode()
{
themeSwitcher.toggleNightMode();
activity.restartWithFade(ListHabitsActivity.class);
}
private void onOpenDocumentResult(int resultCode, Intent data) private void onOpenDocumentResult(int resultCode, Intent data)
{ {
if (controller == null) return; if (controller == null) return;

@ -24,12 +24,10 @@ import android.view.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.activities.habits.list.controllers.*; import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.activities.habits.list.model.*; import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.commands.*;
import java.util.*; import org.isoron.uhabits.ui.screens.habits.list.*;
import javax.inject.*; import javax.inject.*;
@ -43,25 +41,24 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu
@NonNull @NonNull
CommandRunner commandRunner; CommandRunner commandRunner;
private ListHabitsSelectionMenuBehavior behavior;
@NonNull @NonNull
private final HabitCardListAdapter listAdapter; private final HabitCardListAdapter listAdapter;
@Nullable @Nullable
private HabitCardListController listController; private HabitCardListController listController;
@NonNull
private final HabitList habitList;
@Inject @Inject
public ListHabitsSelectionMenu(@NonNull HabitList habitList, public ListHabitsSelectionMenu(@NonNull ListHabitsScreen screen,
@NonNull ListHabitsScreen screen,
@NonNull HabitCardListAdapter listAdapter, @NonNull HabitCardListAdapter listAdapter,
@NonNull CommandRunner commandRunner) @NonNull CommandRunner commandRunner,
@NonNull ListHabitsSelectionMenuBehavior behavior)
{ {
this.habitList = habitList;
this.screen = screen; this.screen = screen;
this.listAdapter = listAdapter; this.listAdapter = listAdapter;
this.commandRunner = commandRunner; this.commandRunner = commandRunner;
this.behavior = behavior;
} }
@Override @Override
@ -74,34 +71,26 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu
@Override @Override
public boolean onItemClicked(@NonNull MenuItem item) public boolean onItemClicked(@NonNull MenuItem item)
{ {
List<Habit> selected = listAdapter.getSelected();
if (selected.isEmpty()) return false;
Habit firstHabit = selected.get(0);
switch (item.getItemId()) switch (item.getItemId())
{ {
case R.id.action_edit_habit: case R.id.action_edit_habit:
showEditScreen(firstHabit); behavior.onEditHabits();
finish();
return true; return true;
case R.id.action_archive_habit: case R.id.action_archive_habit:
performArchive(selected); behavior.onArchiveHabits();
finish();
return true; return true;
case R.id.action_unarchive_habit: case R.id.action_unarchive_habit:
performUnarchive(selected); behavior.onUnarchiveHabits();
finish();
return true; return true;
case R.id.action_delete: case R.id.action_delete:
performDelete(selected); behavior.onDeleteHabits();
return true; return true;
case R.id.action_color: case R.id.action_color:
showColorPicker(selected, firstHabit); behavior.onChangeColor();
return true; return true;
default: default:
@ -112,28 +101,16 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu
@Override @Override
public boolean onPrepare(@NonNull Menu menu) public boolean onPrepare(@NonNull Menu menu)
{ {
List<Habit> selected = listAdapter.getSelected();
boolean showEdit = (selected.size() == 1);
boolean showArchive = true;
boolean showUnarchive = true;
for (Habit h : selected)
{
if (h.isArchived()) showArchive = false;
else showUnarchive = false;
}
MenuItem itemEdit = menu.findItem(R.id.action_edit_habit); MenuItem itemEdit = menu.findItem(R.id.action_edit_habit);
MenuItem itemColor = menu.findItem(R.id.action_color); MenuItem itemColor = menu.findItem(R.id.action_color);
MenuItem itemArchive = menu.findItem(R.id.action_archive_habit); MenuItem itemArchive = menu.findItem(R.id.action_archive_habit);
MenuItem itemUnarchive = menu.findItem(R.id.action_unarchive_habit); MenuItem itemUnarchive = menu.findItem(R.id.action_unarchive_habit);
itemColor.setVisible(true); itemColor.setVisible(true);
itemEdit.setVisible(showEdit); itemEdit.setVisible(behavior.canEdit());
itemArchive.setVisible(showArchive); itemArchive.setVisible(behavior.canArchive());
itemUnarchive.setVisible(showUnarchive); itemUnarchive.setVisible(behavior.canUnarchive());
setTitle(Integer.toString(listAdapter.getSelected().size()));
setTitle(Integer.toString(selected.size()));
return true; return true;
} }
@ -166,41 +143,4 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu
{ {
return R.menu.list_habits_selection; return R.menu.list_habits_selection;
} }
private void performArchive(@NonNull List<Habit> selected)
{
commandRunner.execute(new ArchiveHabitsCommand(habitList, selected),
null);
}
private void performDelete(@NonNull List<Habit> selected)
{
screen.showDeleteConfirmationScreen(() -> {
listAdapter.performRemove(selected);
commandRunner.execute(new DeleteHabitsCommand(habitList, selected),
null);
finish();
});
}
private void performUnarchive(@NonNull List<Habit> selected)
{
commandRunner.execute(new UnarchiveHabitsCommand(habitList, selected),
null);
}
private void showColorPicker(@NonNull List<Habit> selected,
@NonNull Habit firstHabit)
{
screen.showColorPicker(firstHabit, color -> {
commandRunner.execute(
new ChangeHabitColorCommand(habitList, selected, color), null);
finish();
});
}
private void showEditScreen(@NonNull Habit firstHabit)
{
screen.showEditHabitScreen(firstHabit);
}
} }

@ -21,16 +21,21 @@ package org.isoron.uhabits.activities.habits.list.controllers;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.activities.habits.list.model.*; import org.isoron.uhabits.activities.habits.list.model.*;
import org.isoron.uhabits.activities.habits.list.views.*; import org.isoron.uhabits.activities.habits.list.views.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import javax.inject.*;
/** /**
* Controller responsible for receiving and processing the events generated by a * Controller responsible for receiving and processing the events generated by a
* HabitListView. These include selecting and reordering items, toggling * HabitListView. These include selecting and reordering items, toggling
* checkmarks and clicking habits. * checkmarks and clicking habits.
*/ */
public class HabitCardListController implements HabitCardListView.Controller @ActivityScope
public class HabitCardListController implements HabitCardListView.Controller,
ModelObservable.Listener
{ {
private final Mode NORMAL_MODE = new NormalMode(); private final Mode NORMAL_MODE = new NormalMode();
@ -48,10 +53,12 @@ public class HabitCardListController implements HabitCardListView.Controller
@NonNull @NonNull
private Mode activeMode; private Mode activeMode;
@Inject
public HabitCardListController(@NonNull HabitCardListAdapter adapter) public HabitCardListController(@NonNull HabitCardListAdapter adapter)
{ {
this.adapter = adapter; this.adapter = adapter;
this.activeMode = new NormalMode(); this.activeMode = new NormalMode();
adapter.getObservable().addListener(this);
} }
/** /**
@ -119,6 +126,16 @@ public class HabitCardListController implements HabitCardListView.Controller
activeMode.onItemLongClick(position); activeMode.onItemLongClick(position);
} }
@Override
public void onModelChange()
{
if(adapter.isSelectionEmpty())
{
activeMode = new NormalMode();
if (selectionListener != null) selectionListener.onSelectionFinish();
}
}
/** /**
* Called when the selection operation is cancelled externally, by something * Called when the selection operation is cancelled externally, by something
* other than this controller. This happens, for example, when the user * other than this controller. This happens, for example, when the user
@ -180,7 +197,6 @@ public class HabitCardListController implements HabitCardListView.Controller
{ {
adapter.clearSelection(); adapter.clearSelection();
activeMode = new NormalMode(); activeMode = new NormalMode();
if (selectionListener != null) selectionListener.onSelectionFinish(); if (selectionListener != null) selectionListener.onSelectionFinish();
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com> * Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
* *
* This file is part of Loop Habit Tracker. * This file is part of Loop Habit Tracker.
* *
@ -28,6 +28,7 @@ import org.isoron.uhabits.activities.habits.list.*;
import org.isoron.uhabits.activities.habits.list.views.*; import org.isoron.uhabits.activities.habits.list.views.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.screens.habits.list.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import java.util.*; import java.util.*;
@ -42,8 +43,11 @@ import javax.inject.*;
*/ */
@ActivityScope @ActivityScope
public class HabitCardListAdapter public class HabitCardListAdapter
extends RecyclerView.Adapter<HabitCardViewHolder> extends RecyclerView.Adapter<HabitCardViewHolder> implements
implements HabitCardListCache.Listener, MidnightTimer.MidnightListener HabitCardListCache.Listener,
MidnightTimer.MidnightListener,
ListHabitsMenuBehavior.Adapter,
ListHabitsSelectionMenuBehavior.Adapter
{ {
@NonNull @NonNull
private ModelObservable observable; private ModelObservable observable;
@ -95,10 +99,12 @@ public class HabitCardListAdapter
/** /**
* Sets all items as not selected. * Sets all items as not selected.
*/ */
@Override
public void clearSelection() public void clearSelection()
{ {
selected.clear(); selected.clear();
notifyDataSetChanged(); notifyDataSetChanged();
observable.notifyListeners();
} }
/** /**
@ -133,6 +139,7 @@ public class HabitCardListAdapter
return observable; return observable;
} }
@Override
@NonNull @NonNull
public List<Habit> getSelected() public List<Habit> getSelected()
{ {
@ -255,6 +262,7 @@ public class HabitCardListAdapter
* *
* @param habits list of habits to be removed * @param habits list of habits to be removed
*/ */
@Override
public void performRemove(List<Habit> habits) public void performRemove(List<Habit> habits)
{ {
for (Habit h : habits) for (Habit h : habits)
@ -278,11 +286,13 @@ public class HabitCardListAdapter
cache.reorder(from, to); cache.reorder(from, to);
} }
@Override
public void refresh() public void refresh()
{ {
cache.refreshAllHabits(); cache.refreshAllHabits();
} }
@Override
public void setFilter(HabitMatcher matcher) public void setFilter(HabitMatcher matcher)
{ {
cache.setFilter(matcher); cache.setFilter(matcher);
@ -300,6 +310,7 @@ public class HabitCardListAdapter
this.listView = listView; this.listView = listView;
} }
@Override
public void setOrder(HabitList.Order order) public void setOrder(HabitList.Order order)
{ {
cache.setOrder(order); cache.setOrder(order);

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com> * Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
* *
* This file is part of Loop Habit Tracker. * This file is part of Loop Habit Tracker.
* *

@ -29,7 +29,7 @@ import android.widget.FrameLayout;
import android.widget.TextView; import android.widget.TextView;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.habits.list.model.HintList; import org.isoron.uhabits.ui.screens.habits.list.HintList;
import java.util.Random; import java.util.Random;

@ -23,7 +23,7 @@ import android.support.annotation.*;
import org.isoron.uhabits.activities.common.dialogs.*; import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.activities.habits.show.views.*; import org.isoron.uhabits.activities.habits.show.views.*;
import org.isoron.uhabits.ui.habits.show.*; import org.isoron.uhabits.ui.screens.habits.show.*;
import javax.inject.*; import javax.inject.*;

@ -24,7 +24,7 @@ import android.support.annotation.*;
import org.isoron.androidbase.*; import org.isoron.androidbase.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.habits.show.*; import org.isoron.uhabits.ui.screens.habits.show.*;
import dagger.*; import dagger.*;

@ -26,7 +26,7 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.common.dialogs.*; import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.activities.habits.edit.*; import org.isoron.uhabits.activities.habits.edit.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.habits.show.*; import org.isoron.uhabits.ui.screens.habits.show.*;
import javax.inject.*; import javax.inject.*;

@ -24,7 +24,7 @@ import android.view.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.ui.habits.show.*; import org.isoron.uhabits.ui.screens.habits.show.*;
import javax.inject.*; import javax.inject.*;

@ -25,6 +25,7 @@ import android.os.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.receivers.*; import org.isoron.uhabits.receivers.*;
import org.isoron.uhabits.ui.widgets.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import dagger.*; import dagger.*;
@ -63,7 +64,7 @@ public class FireSettingReceiver extends BroadcastReceiver
if (args == null) return; if (args == null) return;
long timestamp = DateUtils.getStartOfToday(); long timestamp = DateUtils.getStartOfToday();
WidgetController controller = component.getWidgetController(); WidgetBehavior controller = component.getWidgetController();
switch (args.action) switch (args.action)
{ {
@ -102,7 +103,7 @@ public class FireSettingReceiver extends BroadcastReceiver
@Component(dependencies = HabitsComponent.class) @Component(dependencies = HabitsComponent.class)
interface ReceiverComponent interface ReceiverComponent
{ {
WidgetController getWidgetController(); WidgetBehavior getWidgetController();
} }
private class Arguments private class Arguments

@ -43,30 +43,6 @@ public class CommandParser
this.modelFactory = modelFactory; this.modelFactory = modelFactory;
} }
@StringRes
public Integer getExecuteString(@NonNull Command command)
{
if(command instanceof ArchiveHabitsCommand)
return R.string.toast_habit_archived;
if(command instanceof ChangeHabitColorCommand)
return R.string.toast_habit_changed;
if(command instanceof CreateHabitCommand)
return R.string.toast_habit_created;
if(command instanceof DeleteHabitsCommand)
return R.string.toast_habit_deleted;
if(command instanceof EditHabitCommand)
return R.string.toast_habit_changed;
if(command instanceof UnarchiveHabitsCommand)
return R.string.toast_habit_unarchived;
return null;
}
@NonNull @NonNull
public Command parse(@NonNull String json) throws JSONException public Command parse(@NonNull String json) throws JSONException
{ {

@ -33,6 +33,7 @@ import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.tasks.*; import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.ui.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import java.util.*; import java.util.*;
@ -43,8 +44,9 @@ import static android.graphics.BitmapFactory.*;
import static org.isoron.uhabits.notifications.RingtoneManager.*; import static org.isoron.uhabits.notifications.RingtoneManager.*;
@AppScope @AppScope
public class NotificationTray public class AndroidNotificationTray
implements CommandRunner.Listener, AndroidPreferences.Listener implements CommandRunner.Listener, AndroidPreferences.Listener,
NotificationTray
{ {
@NonNull @NonNull
private final Context context; private final Context context;
@ -65,7 +67,7 @@ public class NotificationTray
private final HashMap<Habit, NotificationData> active; private final HashMap<Habit, NotificationData> active;
@Inject @Inject
public NotificationTray(@AppContext @NonNull Context context, public AndroidNotificationTray(@AppContext @NonNull Context context,
@NonNull TaskRunner taskRunner, @NonNull TaskRunner taskRunner,
@NonNull PendingIntentFactory pendingIntents, @NonNull PendingIntentFactory pendingIntents,
@NonNull CommandRunner commandRunner, @NonNull CommandRunner commandRunner,
@ -79,6 +81,7 @@ public class NotificationTray
this.active = new HashMap<>(); this.active = new HashMap<>();
} }
@Override
public void cancel(@NonNull Habit habit) public void cancel(@NonNull Habit habit)
{ {
int notificationId = getNotificationId(habit); int notificationId = getNotificationId(habit);

@ -24,15 +24,13 @@ import android.preference.*;
import org.isoron.androidbase.*; import org.isoron.androidbase.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.*;
import java.util.*; import java.util.*;
import javax.inject.*; import javax.inject.*;
import dagger.*;
@AppScope @AppScope
public class AndroidPreferences public class AndroidPreferences
implements SharedPreferences.OnSharedPreferenceChangeListener, Preferences implements SharedPreferences.OnSharedPreferenceChangeListener, Preferences
@ -103,6 +101,7 @@ public class AndroidPreferences
* *
* @return number of last hint shown * @return number of last hint shown
*/ */
@Override
public int getLastHintNumber() public int getLastHintNumber()
{ {
return prefs.getInt("last_hint_number", -1); return prefs.getInt("last_hint_number", -1);
@ -113,6 +112,7 @@ public class AndroidPreferences
* *
* @return timestamp of the day the last hint was shown * @return timestamp of the day the last hint was shown
*/ */
@Override
public long getLastHintTimestamp() public long getLastHintTimestamp()
{ {
return prefs.getLong("last_hint_timestamp", -1); return prefs.getLong("last_hint_timestamp", -1);
@ -128,21 +128,25 @@ public class AndroidPreferences
prefs.edit().putLong("last_sync", timestamp).apply(); prefs.edit().putLong("last_sync", timestamp).apply();
} }
@Override
public boolean getShowArchived() public boolean getShowArchived()
{ {
return prefs.getBoolean("pref_show_archived", false); return prefs.getBoolean("pref_show_archived", false);
} }
@Override
public void setShowArchived(boolean showArchived) public void setShowArchived(boolean showArchived)
{ {
prefs.edit().putBoolean("pref_show_archived", showArchived).apply(); prefs.edit().putBoolean("pref_show_archived", showArchived).apply();
} }
@Override
public boolean getShowCompleted() public boolean getShowCompleted()
{ {
return prefs.getBoolean("pref_show_completed", true); return prefs.getBoolean("pref_show_completed", true);
} }
@Override
public void setShowCompleted(boolean showCompleted) public void setShowCompleted(boolean showCompleted)
{ {
prefs.edit().putBoolean("pref_show_completed", showCompleted).apply(); prefs.edit().putBoolean("pref_show_completed", showCompleted).apply();
@ -155,8 +159,7 @@ public class AndroidPreferences
public String getSyncAddress() public String getSyncAddress()
{ {
return prefs.getString("pref_sync_address", return prefs.getString("pref_sync_address", "https://sync.loophabits.org:4000");
"https://sync.loophabits.org:4000");
} }
public String getSyncClientId() public String getSyncClientId()
@ -174,16 +177,19 @@ public class AndroidPreferences
return prefs.getString("pref_sync_key", ""); return prefs.getString("pref_sync_key", "");
} }
@Override
public int getTheme() public int getTheme()
{ {
return prefs.getInt("pref_theme", ThemeSwitcher.THEME_LIGHT); return prefs.getInt("pref_theme", ThemeSwitcher.THEME_LIGHT);
} }
@Override
public void setTheme(int theme) public void setTheme(int theme)
{ {
prefs.edit().putInt("pref_theme", theme).apply(); prefs.edit().putInt("pref_theme", theme).apply();
} }
@Override
public void incrementLaunchCount() public void incrementLaunchCount()
{ {
int count = prefs.getInt("launch_count", 0); int count = prefs.getInt("launch_count", 0);
@ -200,16 +206,19 @@ public class AndroidPreferences
return prefs.getBoolean("pref_developer", false); return prefs.getBoolean("pref_developer", false);
} }
@Override
public void setDeveloper(boolean isDeveloper) public void setDeveloper(boolean isDeveloper)
{ {
prefs.edit().putBoolean("pref_developer", isDeveloper).apply(); prefs.edit().putBoolean("pref_developer", isDeveloper).apply();
} }
@Override
public boolean isFirstRun() public boolean isFirstRun()
{ {
return prefs.getBoolean("pref_first_run", true); return prefs.getBoolean("pref_first_run", true);
} }
@Override
public void setFirstRun(boolean isFirstRun) public void setFirstRun(boolean isFirstRun)
{ {
prefs.edit().putBoolean("pref_first_run", isFirstRun).apply(); prefs.edit().putBoolean("pref_first_run", isFirstRun).apply();
@ -220,6 +229,7 @@ public class AndroidPreferences
return prefs.getBoolean("pref_feature_numerical_habits", false); return prefs.getBoolean("pref_feature_numerical_habits", false);
} }
@Override
public boolean isPureBlackEnabled() public boolean isPureBlackEnabled()
{ {
return prefs.getBoolean("pref_pure_black", false); return prefs.getBoolean("pref_pure_black", false);
@ -297,6 +307,7 @@ public class AndroidPreferences
* @param number number of the last hint shown * @param number number of the last hint shown
* @param timestamp timestamp for the day the last hint was shown * @param timestamp timestamp for the day the last hint was shown
*/ */
@Override
public void updateLastHint(int number, long timestamp) public void updateLastHint(int number, long timestamp)
{ {
prefs prefs

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com> * Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
* *
* This file is part of Loop Habit Tracker. * This file is part of Loop Habit Tracker.
* *
@ -35,13 +35,13 @@ public class ReminderController
private final ReminderScheduler reminderScheduler; private final ReminderScheduler reminderScheduler;
@NonNull @NonNull
private final NotificationTray notificationTray; private final AndroidNotificationTray notificationTray;
private AndroidPreferences preferences; private AndroidPreferences preferences;
@Inject @Inject
public ReminderController(@NonNull ReminderScheduler reminderScheduler, public ReminderController(@NonNull ReminderScheduler reminderScheduler,
@NonNull NotificationTray notificationTray, @NonNull AndroidNotificationTray notificationTray,
@NonNull AndroidPreferences preferences) @NonNull AndroidPreferences preferences)
{ {
this.reminderScheduler = reminderScheduler; this.reminderScheduler = reminderScheduler;

@ -26,6 +26,7 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.intents.*; import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.sync.*; import org.isoron.uhabits.sync.*;
import org.isoron.uhabits.ui.widgets.*;
import dagger.*; import dagger.*;
@ -60,7 +61,7 @@ public class WidgetReceiver extends BroadcastReceiver
.build(); .build();
IntentParser parser = app.getComponent().getIntentParser(); IntentParser parser = app.getComponent().getIntentParser();
WidgetController controller = component.getWidgetController(); WidgetBehavior controller = component.getWidgetController();
AndroidPreferences prefs = app.getComponent().getPreferences(); AndroidPreferences prefs = app.getComponent().getPreferences();
if(prefs.isSyncFeatureEnabled()) if(prefs.isSyncFeatureEnabled())
@ -96,6 +97,6 @@ public class WidgetReceiver extends BroadcastReceiver
@Component(dependencies = HabitsComponent.class) @Component(dependencies = HabitsComponent.class)
interface WidgetComponent interface WidgetComponent
{ {
WidgetController getWidgetController(); WidgetBehavior getWidgetController();
} }
} }

@ -21,14 +21,31 @@ package org.isoron.uhabits.preferences;
public interface Preferences public interface Preferences
{ {
int getLastHintNumber();
long getLastHintTimestamp();
boolean getShowArchived();
boolean getShowCompleted();
int getTheme();
void incrementLaunchCount(); void incrementLaunchCount();
boolean isFirstRun(); boolean isFirstRun();
boolean isPureBlackEnabled();
void setDeveloper(boolean isDeveloper); void setDeveloper(boolean isDeveloper);
void setFirstRun(boolean b); void setFirstRun(boolean b);
void setShowArchived(boolean showArchived);
void setShowCompleted(boolean showCompleted);
void setTheme(int theme);
void updateLastHint(int i, long startOfToday); void updateLastHint(int i, long startOfToday);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com> * Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
* *
* This file is part of Loop Habit Tracker. * This file is part of Loop Habit Tracker.
* *
@ -17,7 +17,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** package org.isoron.uhabits.ui;
* Provides models that are specific for {@link org.isoron.uhabits.activities.habits.list.ListHabitsActivity}.
*/ import org.isoron.uhabits.models.*;
package org.isoron.uhabits.activities.habits.list.model;
public interface NotificationTray
{
void cancel(Habit habit);
}

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com> * Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
* *
* This file is part of Loop Habit Tracker. * This file is part of Loop Habit Tracker.
* *
@ -17,59 +17,52 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.activities; package org.isoron.uhabits.ui;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import javax.inject.*; public abstract class ThemeSwitcher
@ActivityScope
public class ThemeSwitcher
{ {
public static final int THEME_DARK = 1; public static final int THEME_DARK = 1;
public static final int THEME_LIGHT = 0; public static final int THEME_LIGHT = 0;
@NonNull private final Preferences preferences;
private final BaseActivity activity;
private AndroidPreferences preferences;
@Inject public ThemeSwitcher(@NonNull Preferences preferences)
public ThemeSwitcher(@NonNull BaseActivity activity,
@NonNull AndroidPreferences preferences)
{ {
this.activity = activity;
this.preferences = preferences; this.preferences = preferences;
} }
public void apply() public void apply()
{ {
switch (getTheme()) if (preferences.getTheme() == THEME_DARK)
{
if (preferences.isPureBlackEnabled()) applyPureBlackTheme();
else applyDarkTheme();
}
else
{ {
case THEME_DARK:
applyDarkTheme();
break;
case THEME_LIGHT:
default:
applyLightTheme(); applyLightTheme();
break;
} }
} }
public abstract void applyDarkTheme();
public abstract void applyLightTheme();
public abstract void applyPureBlackTheme();
public boolean isNightMode() public boolean isNightMode()
{ {
return getTheme() == THEME_DARK; return preferences.getTheme() == THEME_DARK;
} }
public void refreshTheme() public void setTheme(int theme)
{ {
preferences.setTheme(theme);
} }
public void toggleNightMode() public void toggleNightMode()
@ -77,26 +70,4 @@ public class ThemeSwitcher
if (isNightMode()) setTheme(THEME_LIGHT); if (isNightMode()) setTheme(THEME_LIGHT);
else setTheme(THEME_DARK); else setTheme(THEME_DARK);
} }
private void applyDarkTheme()
{
if (preferences.isPureBlackEnabled())
activity.setTheme(R.style.AppBaseThemeDark_PureBlack);
else activity.setTheme(R.style.AppBaseThemeDark);
}
private void applyLightTheme()
{
activity.setTheme(R.style.AppBaseTheme);
}
private int getTheme()
{
return preferences.getTheme();
}
public void setTheme(int theme)
{
preferences.setTheme(theme);
}
} }

@ -0,0 +1,25 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.callbacks;
public interface OnColorPickedCallback
{
void onColorPicked(int color);
}

@ -0,0 +1,25 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.callbacks;
public interface OnConfirmedCallback
{
void onConfirmed();
}

@ -0,0 +1,25 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.callbacks;
public interface OnFinishedCallback
{
void onFinish();
}

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.ui.about; package org.isoron.uhabits.ui.screens.about;
import android.support.annotation.*; import android.support.annotation.*;

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com> * Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
* *
* This file is part of Loop Habit Tracker. * This file is part of Loop Habit Tracker.
* *
@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.activities.habits.list.model; package org.isoron.uhabits.ui.screens.habits.list;
import android.support.annotation.*; import android.support.annotation.*;

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com> * Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
* *
* This file is part of Loop Habit Tracker. * This file is part of Loop Habit Tracker.
* *
@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.activities.habits.list.model; package org.isoron.uhabits.ui.screens.habits.list;
import android.support.annotation.*; import android.support.annotation.*;
@ -33,7 +33,7 @@ import org.isoron.uhabits.utils.*;
@AutoFactory @AutoFactory
public class HintList public class HintList
{ {
private final AndroidPreferences prefs; private final Preferences prefs;
@NonNull @NonNull
private final String[] hints; private final String[] hints;
@ -43,7 +43,7 @@ public class HintList
* *
* @param hints initial list of hints * @param hints initial list of hints
*/ */
public HintList(@Provided @NonNull AndroidPreferences prefs, public HintList(@Provided @NonNull Preferences prefs,
@NonNull String hints[]) @NonNull String hints[])
{ {
this.prefs = prefs; this.prefs = prefs;

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.ui.habits.list; package org.isoron.uhabits.ui.screens.habits.list;
import android.support.annotation.*; import android.support.annotation.*;
@ -187,11 +187,6 @@ public class ListHabitsBehavior
void onNumberPicked(double newValue); void onNumberPicked(double newValue);
} }
public interface OnFinishedListener
{
void onFinish();
}
public interface Screen public interface Screen
{ {
void showHabitScreen(@NonNull Habit h); void showHabitScreen(@NonNull Habit h);

@ -0,0 +1,168 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.screens.habits.list;
import android.support.annotation.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.ui.*;
import javax.inject.*;
public class ListHabitsMenuBehavior
{
@NonNull
private final Screen screen;
@NonNull
private final Adapter adapter;
@NonNull
private final Preferences preferences;
@NonNull
private final ThemeSwitcher themeSwitcher;
private boolean showCompleted;
private boolean showArchived;
@Inject
public ListHabitsMenuBehavior(@NonNull Screen screen,
@NonNull Adapter adapter,
@NonNull Preferences preferences,
@NonNull ThemeSwitcher themeSwitcher)
{
this.screen = screen;
this.adapter = adapter;
this.preferences = preferences;
this.themeSwitcher = themeSwitcher;
showCompleted = preferences.getShowCompleted();
showArchived = preferences.getShowArchived();
updateAdapterFilter();
}
public void onCreateHabit()
{
screen.showCreateHabitScreen();
}
public void onViewFAQ()
{
screen.showFAQScreen();
}
public void onViewAbout()
{
screen.showAboutScreen();
}
public void onViewSettings()
{
screen.showSettingsScreen();
}
public void onToggleShowArchived()
{
showArchived = !showArchived;
preferences.setShowArchived(showArchived);
updateAdapterFilter();
}
public void onToggleShowCompleted()
{
showCompleted = !showCompleted;
preferences.setShowCompleted(showCompleted);
updateAdapterFilter();
}
public void onSortByColor()
{
adapter.setOrder(HabitList.Order.BY_COLOR);
}
public void onSortByManually()
{
adapter.setOrder(HabitList.Order.BY_POSITION);
}
public void onSortByScore()
{
adapter.setOrder(HabitList.Order.BY_SCORE);
}
public void onSortByName()
{
adapter.setOrder(HabitList.Order.BY_NAME);
}
public void onToggleNightMode()
{
themeSwitcher.toggleNightMode();
screen.applyTheme();
}
private void toggleShowArchived()
{
showArchived = !showArchived;
preferences.setShowArchived(showArchived);
updateAdapterFilter();
}
private void toggleShowCompleted()
{
showCompleted = !showCompleted;
preferences.setShowCompleted(showCompleted);
updateAdapterFilter();
}
private void updateAdapterFilter()
{
adapter.setFilter(new HabitMatcherBuilder()
.setArchivedAllowed(showArchived)
.setCompletedAllowed(showCompleted)
.build());
adapter.refresh();
}
public interface Adapter
{
void refresh();
void setFilter(HabitMatcher build);
void setOrder(HabitList.Order order);
}
public interface Screen
{
void applyTheme();
void showAboutScreen();
void showCreateHabitScreen();
void showFAQScreen();
void showSettingsScreen();
}
}

@ -0,0 +1,143 @@
/*
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.ui.screens.habits.list;
import android.support.annotation.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.callbacks.*;
import java.util.*;
import javax.inject.*;
public class ListHabitsSelectionMenuBehavior
{
@NonNull
private final Screen screen;
@NonNull
CommandRunner commandRunner;
@NonNull
private final Adapter adapter;
@NonNull
private final HabitList habitList;
@Inject
public ListHabitsSelectionMenuBehavior(@NonNull HabitList habitList,
@NonNull Screen screen,
@NonNull Adapter adapter,
@NonNull CommandRunner commandRunner)
{
this.habitList = habitList;
this.screen = screen;
this.adapter = adapter;
this.commandRunner = commandRunner;
}
public boolean canArchive()
{
for (Habit h : adapter.getSelected())
if (h.isArchived()) return false;
return true;
}
public boolean canEdit()
{
return (adapter.getSelected().size() == 1);
}
public boolean canUnarchive()
{
for (Habit h : adapter.getSelected())
if (!h.isArchived()) return false;
return true;
}
public void onArchiveHabits()
{
commandRunner.execute(
new ArchiveHabitsCommand(habitList, adapter.getSelected()), null);
adapter.clearSelection();
}
public void onChangeColor()
{
List<Habit> selected = adapter.getSelected();
Habit first = selected.get(0);
screen.showColorPicker(first.getColor(), selectedColor ->
{
commandRunner.execute(
new ChangeHabitColorCommand(habitList, selected, selectedColor),
null);
adapter.clearSelection();
});
}
public void onDeleteHabits()
{
List<Habit> selected = adapter.getSelected();
screen.showDeleteConfirmationScreen(() ->
{
adapter.performRemove(selected);
commandRunner.execute(new DeleteHabitsCommand(habitList, selected),
null);
adapter.clearSelection();
});
}
public void onEditHabits()
{
screen.showEditHabitsScreen(adapter.getSelected());
}
public void onUnarchiveHabits()
{
commandRunner.execute(
new UnarchiveHabitsCommand(habitList, adapter.getSelected()), null);
adapter.clearSelection();
}
public interface Adapter
{
void clearSelection();
List<Habit> getSelected();
void performRemove(List<Habit> selected);
}
public interface Screen
{
void showColorPicker(int defaultColor,
@NonNull OnColorPickedCallback callback);
void showDeleteConfirmationScreen(
@NonNull OnConfirmedCallback callback);
void showEditHabitsScreen(@NonNull List<Habit> selected);
}
}

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.ui.habits.show; package org.isoron.uhabits.ui.screens.habits.show;
import android.support.annotation.*; import android.support.annotation.*;

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.ui.habits.show; package org.isoron.uhabits.ui.screens.habits.show;
import android.support.annotation.*; import android.support.annotation.*;

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com> * Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
* *
* This file is part of Loop Habit Tracker. * This file is part of Loop Habit Tracker.
* *
@ -17,18 +17,17 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.receivers; package org.isoron.uhabits.ui.widgets;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.uhabits.commands.*; import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.notifications.*; import org.isoron.uhabits.ui.*;
import javax.inject.*; import javax.inject.*;
@ReceiverScope public class WidgetBehavior
public class WidgetController
{ {
@NonNull @NonNull
private final CommandRunner commandRunner; private final CommandRunner commandRunner;
@ -36,7 +35,7 @@ public class WidgetController
private NotificationTray notificationTray; private NotificationTray notificationTray;
@Inject @Inject
public WidgetController(@NonNull CommandRunner commandRunner, public WidgetBehavior(@NonNull CommandRunner commandRunner,
@NonNull NotificationTray notificationTray) @NonNull NotificationTray notificationTray)
{ {
this.commandRunner = commandRunner; this.commandRunner = commandRunner;

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.ui.habits.list; package org.isoron.uhabits.ui.screens.habits.list;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
@ -30,7 +30,7 @@ import org.mockito.junit.*;
import static junit.framework.TestCase.assertTrue; import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.CoreMatchers.*;
import static org.isoron.uhabits.ui.habits.list.ListHabitsBehavior.Message.*; import static org.isoron.uhabits.ui.screens.habits.list.ListHabitsBehavior.Message.*;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.uhabits.ui.habits.show; package org.isoron.uhabits.ui.screens.habits.show;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
Loading…
Cancel
Save