Move UI behavior to uhabits-core

pull/87/merge
Alinson S. Xavier 8 years ago
parent df0cf57984
commit fa4944700c

@ -51,7 +51,7 @@ public class BaseAndroidTest extends TestCase
protected Context targetContext; protected Context targetContext;
protected Preferences prefs; protected AndroidPreferences prefs;
protected HabitList habitList; protected HabitList habitList;

@ -47,7 +47,7 @@ public class ListHabitsControllerTest extends BaseAndroidTest
private ListHabitsScreen screen; private ListHabitsScreen screen;
private Preferences prefs; private AndroidPreferences prefs;
private ReminderScheduler reminderScheduler; private ReminderScheduler reminderScheduler;
@ -69,7 +69,7 @@ public class ListHabitsControllerTest extends BaseAndroidTest
commandRunner = mock(CommandRunner.class); commandRunner = mock(CommandRunner.class);
adapter = mock(HabitCardListAdapter.class); adapter = mock(HabitCardListAdapter.class);
screen = mock(ListHabitsScreen.class); screen = mock(ListHabitsScreen.class);
prefs = mock(Preferences.class); prefs = mock(AndroidPreferences.class);
reminderScheduler = mock(ReminderScheduler.class); reminderScheduler = mock(ReminderScheduler.class);
taskRunner = new SingleThreadTaskRunner(); taskRunner = new SingleThreadTaskRunner();
widgetUpdater = mock(WidgetUpdater.class); widgetUpdater = mock(WidgetUpdater.class);

@ -40,7 +40,7 @@ public class ListHabitsMenuTest extends BaseAndroidTest
private HabitCardListAdapter adapter; private HabitCardListAdapter adapter;
private Preferences preferences; private AndroidPreferences preferences;
private ThemeSwitcher themeSwitcher; private ThemeSwitcher themeSwitcher;
@ -56,7 +56,7 @@ public class ListHabitsMenuTest extends BaseAndroidTest
activity = mock(BaseActivity.class); activity = mock(BaseActivity.class);
screen = mock(ListHabitsScreen.class); screen = mock(ListHabitsScreen.class);
adapter = mock(HabitCardListAdapter.class); adapter = mock(HabitCardListAdapter.class);
preferences = mock(Preferences.class); preferences = mock(AndroidPreferences.class);
themeSwitcher = mock(ThemeSwitcher.class); themeSwitcher = mock(ThemeSwitcher.class);
when(preferences.getShowArchived()).thenReturn(false); when(preferences.getShowArchived()).thenReturn(false);

@ -66,7 +66,7 @@ public class ListHabitsScreenTest extends BaseAndroidTest
private ThemeSwitcher themeSwitcher; private ThemeSwitcher themeSwitcher;
private Preferences prefs; private AndroidPreferences prefs;
private CommandParser commandParser; private CommandParser commandParser;
@ -84,7 +84,7 @@ public class ListHabitsScreenTest extends BaseAndroidTest
confirmDeleteDialogFactory = mock(ConfirmDeleteDialogFactory.class); confirmDeleteDialogFactory = mock(ConfirmDeleteDialogFactory.class);
colorPickerDialogFactory = mock(ColorPickerDialogFactory.class); colorPickerDialogFactory = mock(ColorPickerDialogFactory.class);
dialogFactory = mock(EditHabitDialogFactory.class); dialogFactory = mock(EditHabitDialogFactory.class);
prefs = mock(Preferences.class); prefs = mock(AndroidPreferences.class);
commandParser = mock(CommandParser.class); commandParser = mock(CommandParser.class);
screen = spy(new ListHabitsScreen(activity, commandRunner, rootView, screen = spy(new ListHabitsScreen(activity, commandRunner, rootView,

@ -39,7 +39,7 @@ public class CheckmarkButtonControllerTest extends BaseAndroidTest
private int timestamp; private int timestamp;
private Preferences prefs; private AndroidPreferences prefs;
@Override @Override
@Before @Before
@ -49,7 +49,7 @@ public class CheckmarkButtonControllerTest extends BaseAndroidTest
timestamp = 0; timestamp = 0;
habit = mock(Habit.class); habit = mock(Habit.class);
prefs = mock(Preferences.class); prefs = mock(AndroidPreferences.class);
this.view = mock(CheckmarkButtonView.class); this.view = mock(CheckmarkButtonView.class);
this.listener = mock(CheckmarkButtonController.Listener.class); this.listener = mock(CheckmarkButtonController.Listener.class);

@ -41,7 +41,7 @@ public class HeaderViewTest extends BaseViewTest
private HeaderView view; private HeaderView view;
private Preferences prefs; private AndroidPreferences prefs;
private MidnightTimer midnightTimer; private MidnightTimer midnightTimer;
@ -50,7 +50,7 @@ public class HeaderViewTest extends BaseViewTest
public void setUp() public void setUp()
{ {
super.setUp(); super.setUp();
prefs = mock(Preferences.class); prefs = mock(AndroidPreferences.class);
midnightTimer = mock(MidnightTimer.class); midnightTimer = mock(MidnightTimer.class);
view = new HeaderView(targetContext, prefs, midnightTimer); view = new HeaderView(targetContext, prefs, midnightTimer);
view.setButtonCount(5); view.setButtonCount(5);

@ -1,83 +0,0 @@
/*
* 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.activities.habits.show;
import android.view.*;
import org.isoron.androidbase.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
import org.junit.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
public class ShowHabitsMenuTest extends BaseAndroidTest
{
private ShowHabitActivity activity;
private ShowHabitScreen screen;
private ShowHabitsMenu menu;
private Habit habit;
private ExportCSVTaskFactory exportCSVFactory;
private TaskRunner taskRunner;
private BaseSystem system;
@Override
public void setUp()
{
super.setUp();
activity = mock(ShowHabitActivity.class);
system = mock(BaseSystem.class);
screen = mock(ShowHabitScreen.class);
habit = mock(Habit.class);
exportCSVFactory = mock(ExportCSVTaskFactory.class);
taskRunner = mock(TaskRunner.class);
menu = new ShowHabitsMenu(activity, system, screen, habit,
exportCSVFactory, taskRunner);
}
@Test
public void testOnDownloadHabit()
{
onItemSelected(R.id.export);
verify(taskRunner).execute(any());
}
@Test
public void testOnEditHabit()
{
onItemSelected(R.id.action_edit_habit);
verify(screen).showEditHabitDialog();
}
protected void onItemSelected(int actionId)
{
MenuItem item = mock(MenuItem.class);
when(item.getItemId()).thenReturn(actionId);
menu.onItemSelected(item);
}
}

@ -37,7 +37,7 @@ public class ReminderControllerTest extends BaseAndroidTest
private NotificationTray notificationTray; private NotificationTray notificationTray;
private Preferences preferences; private AndroidPreferences preferences;
@Override @Override
public void setUp() public void setUp()
@ -46,7 +46,7 @@ public class ReminderControllerTest extends BaseAndroidTest
reminderScheduler = mock(ReminderScheduler.class); reminderScheduler = mock(ReminderScheduler.class);
notificationTray = mock(NotificationTray.class); notificationTray = mock(NotificationTray.class);
preferences = mock(Preferences.class); preferences = mock(AndroidPreferences.class);
controller = new ReminderController(reminderScheduler, controller = new ReminderController(reminderScheduler,
notificationTray, preferences); notificationTray, preferences);

@ -48,6 +48,8 @@ public abstract class BaseRootView extends FrameLayout
private final ThemeSwitcher themeSwitcher; private final ThemeSwitcher themeSwitcher;
boolean shouldDisplayHomeAsUp = false;
public BaseRootView(@NonNull Context context) public BaseRootView(@NonNull Context context)
{ {
super(context); super(context);
@ -58,11 +60,23 @@ public abstract class BaseRootView extends FrameLayout
public boolean getDisplayHomeAsUp() public boolean getDisplayHomeAsUp()
{ {
return false; return shouldDisplayHomeAsUp;
}
public void setDisplayHomeAsUp(boolean b)
{
shouldDisplayHomeAsUp = b;
} }
@NonNull @NonNull
public abstract Toolbar getToolbar(); public Toolbar getToolbar()
{
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar == null) throw new RuntimeException(
"Your BaseRootView should have a " +
"toolbar with id R.id.toolbar");
return toolbar;
}
public int getToolbarColor() public int getToolbarColor()
{ {
@ -86,7 +100,7 @@ public abstract class BaseRootView extends FrameLayout
if (view != null) view.setVisibility(GONE); if (view != null) view.setVisibility(GONE);
view = findViewById(R.id.headerShadow); view = findViewById(R.id.headerShadow);
if(view != null) view.setVisibility(GONE); if (view != null) view.setVisibility(GONE);
} }
} }
} }

@ -73,7 +73,7 @@ public interface AppComponent
PendingIntentFactory getPendingIntentFactory(); PendingIntentFactory getPendingIntentFactory();
Preferences getPreferences(); AndroidPreferences getPreferences();
ReminderScheduler getReminderScheduler(); ReminderScheduler getReminderScheduler();

@ -109,7 +109,7 @@ public class HabitsApplication extends Application
notificationTray = component.getNotificationTray(); notificationTray = component.getNotificationTray();
notificationTray.startListening(); notificationTray.startListening();
Preferences prefs = component.getPreferences(); AndroidPreferences prefs = component.getPreferences();
prefs.initialize(); prefs.initialize();
prefs.updateLastAppVersion(); prefs.updateLastAppVersion();

@ -37,11 +37,11 @@ public class ThemeSwitcher
@NonNull @NonNull
private final BaseActivity activity; private final BaseActivity activity;
private Preferences preferences; private AndroidPreferences preferences;
@Inject @Inject
public ThemeSwitcher(@NonNull BaseActivity activity, public ThemeSwitcher(@NonNull BaseActivity activity,
@NonNull Preferences preferences) @NonNull AndroidPreferences preferences)
{ {
this.activity = activity; this.activity = activity;
this.preferences = preferences; this.preferences = preferences;

@ -22,7 +22,8 @@ package org.isoron.uhabits.activities.about;
import android.os.*; import android.os.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.intents.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.ui.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.
@ -34,8 +35,11 @@ public class AboutActivity extends BaseActivity
protected void onCreate(Bundle savedInstanceState) protected void onCreate(Bundle savedInstanceState)
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
AboutRootView rootView = new AboutRootView(this, new IntentFactory()); HabitsApplication app = (HabitsApplication) getApplication();
BaseScreen screen = new BaseScreen(this); AppComponent cmp = app.getComponent();
AboutScreen screen = new AboutScreen(this, cmp.getIntentFactory());
AboutBehavior behavior = new AboutBehavior(cmp.getPreferences(), screen);
AboutRootView rootView = new AboutRootView(this, behavior);
screen.setRootView(rootView); screen.setRootView(rootView);
setScreen(screen); setScreen(screen);
} }

@ -21,15 +21,12 @@ package org.isoron.uhabits.activities.about;
import android.content.*; import android.content.*;
import android.support.annotation.*; import android.support.annotation.*;
import android.support.v7.widget.Toolbar;
import android.widget.*; 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.*;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.intents.*; import org.isoron.uhabits.ui.about.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import butterknife.*; import butterknife.*;
@ -48,47 +45,22 @@ public class AboutRootView extends BaseRootView
@BindView(R.id.tvSource) @BindView(R.id.tvSource)
TextView tvSource; TextView tvSource;
@BindView(R.id.toolbar) @NonNull
Toolbar toolbar; private final AboutBehavior behavior;
int developerCountdown = 10;
@Nullable
Preferences prefs;
private final IntentFactory intents;
public AboutRootView(Context context, IntentFactory intents) public AboutRootView(@NonNull Context context,
@NonNull AboutBehavior behavior)
{ {
super(context); super(context);
this.intents = intents; this.behavior = behavior;
addView(inflate(getContext(), R.layout.about, null)); addView(inflate(getContext(), R.layout.about, null));
ButterKnife.bind(this); ButterKnife.bind(this);
tvVersion.setText( String version = getResources().getString(R.string.version_n);
String.format(getResources().getString(R.string.version_n), tvVersion.setText(String.format(version, BuildConfig.VERSION_NAME));
BuildConfig.VERSION_NAME));
if (context.getApplicationContext() instanceof HabitsApplication) setDisplayHomeAsUp(true);
{
HabitsApplication app =
(HabitsApplication) context.getApplicationContext();
prefs = app.getComponent().getPreferences();
}
}
@Override
public boolean getDisplayHomeAsUp()
{
return true;
}
@NonNull
@Override
public Toolbar getToolbar()
{
return toolbar;
} }
@Override @Override
@ -104,48 +76,37 @@ public class AboutRootView extends BaseRootView
@OnClick(R.id.tvFeedback) @OnClick(R.id.tvFeedback)
public void onClickFeedback() public void onClickFeedback()
{ {
Intent intent = intents.sendFeedback(getContext()); behavior.onSendFeedback();
getContext().startActivity(intent);
} }
@OnClick(R.id.tvVersion) @OnClick(R.id.tvVersion)
public void onClickIcon() public void onClickIcon()
{ {
developerCountdown--; behavior.onPressDeveloperCountdown();
if (developerCountdown <= 0)
{
if (prefs == null) return;
prefs.setDeveloper(true);
String text = "You are now a developer";
Toast.makeText(getContext(), text, Toast.LENGTH_LONG).show();
}
} }
@OnClick(R.id.tvRate) @OnClick(R.id.tvRate)
public void onClickRate() public void onClickRate()
{ {
Intent intent = intents.rateApp(getContext()); behavior.onRateApp();
getContext().startActivity(intent);
} }
@OnClick(R.id.tvSource) @OnClick(R.id.tvSource)
public void onClickSource() public void onClickSource()
{ {
Intent intent = intents.viewSourceCode(getContext()); behavior.onViewSourceCode();
getContext().startActivity(intent);
} }
@OnClick(R.id.tvTranslate) @OnClick(R.id.tvTranslate)
public void onClickTranslate() public void onClickTranslate()
{ {
Intent intent = intents.helpTranslate(getContext()); behavior.onTranslateApp();
getContext().startActivity(intent);
} }
@Override @Override
protected void initToolbar() protected void initToolbar()
{ {
super.initToolbar(); super.initToolbar();
toolbar.setTitle(getResources().getString(R.string.about)); getToolbar().setTitle(getResources().getString(R.string.about));
} }
} }

@ -0,0 +1,73 @@
/*
* 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.activities.about;
import android.support.annotation.*;
import android.widget.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.ui.about.*;
import javax.inject.*;
public class AboutScreen extends BaseScreen implements AboutBehavior.Screen
{
@NonNull
private final IntentFactory intents;
@Inject
public AboutScreen(@NonNull BaseActivity activity,
@NonNull IntentFactory intents)
{
super(activity);
this.intents = intents;
}
@Override
public void showMessage(AboutBehavior.Message message)
{
Toast.makeText(activity, "OK", Toast.LENGTH_LONG).show();
}
@Override
public void showRateAppWebsite()
{
activity.startActivity(intents.rateApp(activity));
}
@Override
public void showSendFeedbackScreen()
{
activity.startActivity(intents.sendFeedback(activity));
}
@Override
public void showSourceCodeWebsite()
{
activity.startActivity(intents.viewSourceCode(activity));
}
@Override
public void showTranslationWebsite()
{
activity.startActivity(intents.helpTranslate(activity));
}
}

@ -49,7 +49,7 @@ public class EditHabitDialog extends AppCompatDialogFragment
protected Habit originalHabit; protected Habit originalHabit;
protected Preferences prefs; protected AndroidPreferences prefs;
protected CommandRunner commandRunner; protected CommandRunner commandRunner;

@ -45,7 +45,7 @@ public class ListHabitsActivity extends BaseActivity
private boolean pureBlack; private boolean pureBlack;
private Preferences prefs; private AndroidPreferences prefs;
private MidnightTimer midnightTimer; private MidnightTimer midnightTimer;

@ -57,7 +57,7 @@ public class ListHabitsController
private final HabitCardListAdapter adapter; private final HabitCardListAdapter adapter;
@NonNull @NonNull
private final Preferences prefs; private final AndroidPreferences prefs;
@NonNull @NonNull
private final CommandRunner commandRunner; private final CommandRunner commandRunner;
@ -81,7 +81,7 @@ public class ListHabitsController
@NonNull HabitList habitList, @NonNull HabitList habitList,
@NonNull HabitCardListAdapter adapter, @NonNull HabitCardListAdapter adapter,
@NonNull ListHabitsScreen screen, @NonNull ListHabitsScreen screen,
@NonNull Preferences prefs, @NonNull AndroidPreferences prefs,
@NonNull ReminderScheduler reminderScheduler, @NonNull ReminderScheduler reminderScheduler,
@NonNull TaskRunner taskRunner, @NonNull TaskRunner taskRunner,
@NonNull WidgetUpdater widgetUpdater, @NonNull WidgetUpdater widgetUpdater,

@ -43,7 +43,7 @@ public class ListHabitsMenu extends BaseMenu
private boolean showCompleted; private boolean showCompleted;
private final Preferences preferences; private final AndroidPreferences preferences;
private ThemeSwitcher themeSwitcher; private ThemeSwitcher themeSwitcher;
@ -51,7 +51,7 @@ public class ListHabitsMenu extends BaseMenu
public ListHabitsMenu(@NonNull BaseActivity activity, public ListHabitsMenu(@NonNull BaseActivity activity,
@NonNull ListHabitsScreen screen, @NonNull ListHabitsScreen screen,
@NonNull HabitCardListAdapter adapter, @NonNull HabitCardListAdapter adapter,
@NonNull Preferences preferences, @NonNull AndroidPreferences preferences,
@NonNull ThemeSwitcher themeSwitcher) @NonNull ThemeSwitcher themeSwitcher)
{ {
super(activity); super(activity);

@ -89,7 +89,7 @@ public class ListHabitsScreen extends BaseScreen
private final ThemeSwitcher themeSwitcher; private final ThemeSwitcher themeSwitcher;
@NonNull @NonNull
private Preferences prefs; private AndroidPreferences prefs;
@NonNull @NonNull
private final CommandParser commandParser; private final CommandParser commandParser;
@ -103,7 +103,7 @@ public class ListHabitsScreen extends BaseScreen
@NonNull ConfirmDeleteDialogFactory confirmDeleteDialogFactory, @NonNull ConfirmDeleteDialogFactory confirmDeleteDialogFactory,
@NonNull ColorPickerDialogFactory colorPickerFactory, @NonNull ColorPickerDialogFactory colorPickerFactory,
@NonNull EditHabitDialogFactory editHabitDialogFactory, @NonNull EditHabitDialogFactory editHabitDialogFactory,
@NonNull Preferences prefs, @NonNull AndroidPreferences prefs,
@NonNull CommandParser commandParser) @NonNull CommandParser commandParser)
{ {
super(activity); super(activity);

@ -37,14 +37,14 @@ public class CheckmarkButtonController
private Listener listener; private Listener listener;
@NonNull @NonNull
private final Preferences prefs; private final AndroidPreferences prefs;
@NonNull @NonNull
private Habit habit; private Habit habit;
private long timestamp; private long timestamp;
public CheckmarkButtonController(@Provided @NonNull Preferences prefs, public CheckmarkButtonController(@Provided @NonNull AndroidPreferences prefs,
@NonNull Habit habit, @NonNull Habit habit,
long timestamp) long timestamp)
{ {

@ -37,14 +37,14 @@ public class NumberButtonController
private Listener listener; private Listener listener;
@NonNull @NonNull
private final Preferences prefs; private final AndroidPreferences prefs;
@NonNull @NonNull
private Habit habit; private Habit habit;
private long timestamp; private long timestamp;
public NumberButtonController(@Provided @NonNull Preferences prefs, public NumberButtonController(@Provided @NonNull AndroidPreferences prefs,
@NonNull Habit habit, @NonNull Habit habit,
long timestamp) long timestamp)
{ {

@ -58,13 +58,13 @@ public class HabitCardListAdapter
private final HabitCardListCache cache; private final HabitCardListCache cache;
@NonNull @NonNull
private Preferences preferences; private AndroidPreferences preferences;
private final MidnightTimer midnightTimer; private final MidnightTimer midnightTimer;
@Inject @Inject
public HabitCardListAdapter(@NonNull HabitCardListCache cache, public HabitCardListAdapter(@NonNull HabitCardListCache cache,
@NonNull Preferences preferences, @NonNull AndroidPreferences preferences,
@NonNull MidnightTimer midnightTimer) @NonNull MidnightTimer midnightTimer)
{ {
this.preferences = preferences; this.preferences = preferences;

@ -33,7 +33,7 @@ import org.isoron.uhabits.utils.*;
@AutoFactory @AutoFactory
public class HintList public class HintList
{ {
private final Preferences prefs; private final AndroidPreferences 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 Preferences prefs, public HintList(@Provided @NonNull AndroidPreferences prefs,
@NonNull String hints[]) @NonNull String hints[])
{ {
this.prefs = prefs; this.prefs = prefs;

@ -39,14 +39,14 @@ import static org.isoron.uhabits.utils.ColorUtils.*;
import static org.isoron.uhabits.utils.InterfaceUtils.getDimension; import static org.isoron.uhabits.utils.InterfaceUtils.getDimension;
public class CheckmarkPanelView extends LinearLayout public class CheckmarkPanelView extends LinearLayout
implements Preferences.Listener implements AndroidPreferences.Listener
{ {
private static final int LEFT_TO_RIGHT = 0; private static final int LEFT_TO_RIGHT = 0;
private static final int RIGHT_TO_LEFT = 1; private static final int RIGHT_TO_LEFT = 1;
@Nullable @Nullable
private Preferences prefs; private AndroidPreferences prefs;
private int values[]; private int values[];

@ -27,7 +27,6 @@ import android.util.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.common.views.*; import org.isoron.uhabits.activities.common.views.*;
import org.isoron.uhabits.activities.habits.list.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
@ -36,13 +35,13 @@ import java.util.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*; import static org.isoron.uhabits.utils.InterfaceUtils.*;
public class HeaderView extends ScrollableChart public class HeaderView extends ScrollableChart
implements Preferences.Listener, MidnightTimer.MidnightListener implements AndroidPreferences.Listener, MidnightTimer.MidnightListener
{ {
private int buttonCount; private int buttonCount;
@Nullable @Nullable
private Preferences prefs; private AndroidPreferences prefs;
@Nullable @Nullable
private MidnightTimer midnightTimer; private MidnightTimer midnightTimer;
@ -52,7 +51,7 @@ public class HeaderView extends ScrollableChart
private RectF rect; private RectF rect;
public HeaderView(@NonNull Context context, public HeaderView(@NonNull Context context,
@NonNull Preferences prefs, @NonNull AndroidPreferences prefs,
@NonNull MidnightTimer midnightTimer) @NonNull MidnightTimer midnightTimer)
{ {
super(context); super(context);

@ -39,14 +39,14 @@ import static org.isoron.uhabits.utils.ColorUtils.*;
import static org.isoron.uhabits.utils.InterfaceUtils.*; import static org.isoron.uhabits.utils.InterfaceUtils.*;
public class NumberPanelView extends LinearLayout public class NumberPanelView extends LinearLayout
implements Preferences.Listener implements AndroidPreferences.Listener
{ {
private static final int LEFT_TO_RIGHT = 0; private static final int LEFT_TO_RIGHT = 0;
private static final int RIGHT_TO_LEFT = 1; private static final int RIGHT_TO_LEFT = 1;
@Nullable @Nullable
private Preferences prefs; private AndroidPreferences prefs;
private double values[]; private double values[];

@ -27,6 +27,9 @@ import android.support.annotation.*;
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.models.*;
import org.isoron.uhabits.ui.habits.show.*;
import java.io.*;
/** /**
* Activity that allows the user to see more information about a single habit. * Activity that allows the user to see more information about a single habit.
@ -34,8 +37,24 @@ import org.isoron.uhabits.models.*;
* Shows all the metadata for the habit, in addition to several charts. * Shows all the metadata for the habit, in addition to several charts.
*/ */
public class ShowHabitActivity extends BaseActivity public class ShowHabitActivity extends BaseActivity
implements ShowHabitMenuBehavior.System
{ {
private HabitList habits; @Nullable
private HabitList habitList;
@Nullable
private AppComponent appComponent;
@Nullable
private ShowHabitScreen screen;
@Override
public File getCSVOutputDir()
{
if(appComponent == null) throw new IllegalStateException();
return appComponent.getBaseSystem().getFilesDir("CSV");
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) protected void onCreate(Bundle savedInstanceState)
@ -43,7 +62,8 @@ public class ShowHabitActivity extends BaseActivity
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
HabitsApplication app = (HabitsApplication) getApplicationContext(); HabitsApplication app = (HabitsApplication) getApplicationContext();
habits = app.getComponent().getHabitList(); appComponent = app.getComponent();
habitList = appComponent.getHabitList();
Habit habit = getHabitFromIntent(); Habit habit = getHabitFromIntent();
ShowHabitComponent component = DaggerShowHabitComponent ShowHabitComponent component = DaggerShowHabitComponent
@ -52,22 +72,30 @@ public class ShowHabitActivity extends BaseActivity
.showHabitModule(new ShowHabitModule(this, habit)) .showHabitModule(new ShowHabitModule(this, habit))
.build(); .build();
ShowHabitRootView rootView = component.getRootView(); screen = component.getScreen();
ShowHabitScreen screen = component.getScreen();
setScreen(screen);
screen.setMenu(component.getMenu()); screen.setMenu(component.getMenu());
screen.setController(component.getController()); screen.setController(component.getController());
rootView.setController(component.getController());
component.getRootView().setController(component.getController());
setScreen(screen);
}
@Override
protected void onResume()
{
if(screen == null) throw new IllegalStateException();
super.onResume();
screen.reattachDialogs(); screen.reattachDialogs();
} }
@NonNull @NonNull
private Habit getHabitFromIntent() private Habit getHabitFromIntent()
{ {
if(habitList == null) throw new IllegalStateException();
Uri data = getIntent().getData(); Uri data = getIntent().getData();
Habit habit = habits.getById(ContentUris.parseId(data)); Habit habit = habitList.getById(ContentUris.parseId(data));
if (habit == null) throw new RuntimeException("habit not found"); if (habit == null) throw new RuntimeException("habit not found");
return habit; return 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.
* *
@ -19,6 +19,8 @@
package org.isoron.uhabits.activities.habits.show; package org.isoron.uhabits.activities.habits.show;
import android.support.annotation.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
@ -29,11 +31,15 @@ import dagger.*;
dependencies = { AppComponent.class }) dependencies = { AppComponent.class })
public interface ShowHabitComponent public interface ShowHabitComponent
{ {
@NonNull
ShowHabitController getController(); ShowHabitController getController();
@NonNull
ShowHabitsMenu getMenu(); ShowHabitsMenu getMenu();
@NonNull
ShowHabitRootView getRootView(); ShowHabitRootView getRootView();
@NonNull
ShowHabitScreen getScreen(); ShowHabitScreen getScreen();
} }

@ -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.
* *
@ -21,50 +21,39 @@ package org.isoron.uhabits.activities.habits.show;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.androidbase.activities.*;
import org.isoron.uhabits.activities.common.dialogs.*; import org.isoron.uhabits.activities.common.dialogs.*;
import org.isoron.uhabits.commands.*; import org.isoron.uhabits.activities.habits.show.views.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.ui.habits.show.*;
import javax.inject.*; import javax.inject.*;
@ActivityScope
public class ShowHabitController public class ShowHabitController
implements ShowHabitRootView.Controller, HistoryEditorDialog.Controller implements HistoryCard.Controller, HistoryEditorDialog.Controller
{ {
@NonNull private ShowHabitBehavior behavior;
private final ShowHabitScreen screen;
@NonNull private ShowHabitScreen screen;
private final Habit habit;
@NonNull
private final CommandRunner commandRunner;
@Inject @Inject
public ShowHabitController(@NonNull ShowHabitScreen screen, public ShowHabitController(@NonNull ShowHabitBehavior behavior,
@NonNull CommandRunner commandRunner, @NonNull ShowHabitScreen screen)
@NonNull Habit habit)
{ {
this.behavior = behavior;
this.screen = screen; this.screen = screen;
this.habit = habit;
this.commandRunner = commandRunner;
} }
@Override @Override
public void onEditHistoryButtonClick() public void onEditHistoryButtonClick()
{ {
screen.showEditHistoryDialog(); behavior.onEditHistory();
} }
@Override @Override
public void onToggleCheckmark(long timestamp) public void onToggleCheckmark(long timestamp)
{ {
commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp), behavior.onToggleCheckmark(timestamp);
null);
} }
@Override
public void onToolbarChanged() public void onToolbarChanged()
{ {
screen.invalidateToolbar(); screen.invalidateToolbar();

@ -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.
* *
@ -19,17 +19,20 @@
package org.isoron.uhabits.activities.habits.show; package org.isoron.uhabits.activities.habits.show;
import android.support.annotation.*;
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 dagger.*; import dagger.*;
@Module @Module
public class ShowHabitModule extends ActivityModule public class ShowHabitModule extends ActivityModule
{ {
private final Habit habit; private Habit habit;
public ShowHabitModule(BaseActivity activity, Habit habit) public ShowHabitModule(@NonNull BaseActivity activity, @NonNull Habit habit)
{ {
super(activity); super(activity);
this.habit = habit; this.habit = habit;
@ -40,4 +43,22 @@ public class ShowHabitModule extends ActivityModule
{ {
return habit; return habit;
} }
@Provides
public ShowHabitBehavior.Screen getScreen(ShowHabitScreen screen)
{
return screen;
}
@Provides
public ShowHabitMenuBehavior.Screen getMenuScreen(ShowHabitScreen screen)
{
return screen;
}
@Provides
public ShowHabitMenuBehavior.System getSystem(BaseActivity activity)
{
return (ShowHabitActivity) activity;
}
} }

@ -65,8 +65,8 @@ public class ShowHabitRootView extends BaseRootView
@BindView(R.id.toolbar) @BindView(R.id.toolbar)
Toolbar toolbar; Toolbar toolbar;
@NonNull @Nullable
private Controller controller; private ShowHabitController controller;
@Inject @Inject
public ShowHabitRootView(@NonNull @ActivityContext Context context, public ShowHabitRootView(@NonNull @ActivityContext Context context,
@ -78,25 +78,11 @@ public class ShowHabitRootView extends BaseRootView
addView(inflate(getContext(), R.layout.show_habit, null)); addView(inflate(getContext(), R.layout.show_habit, null));
ButterKnife.bind(this); ButterKnife.bind(this);
controller = new Controller() {}; setDisplayHomeAsUp(true);
initCards(); initCards();
initToolbar(); initToolbar();
} }
@Override
public boolean getDisplayHomeAsUp()
{
return true;
}
@NonNull
@Override
public Toolbar getToolbar()
{
return toolbar;
}
@Override @Override
public int getToolbarColor() public int getToolbarColor()
{ {
@ -114,10 +100,10 @@ public class ShowHabitRootView extends BaseRootView
toolbar.setTitle(habit.getName()); toolbar.setTitle(habit.getName());
}); });
controller.onToolbarChanged(); if(controller != null) controller.onToolbarChanged();
} }
public void setController(@NonNull Controller controller) public void setController(@NonNull ShowHabitController controller)
{ {
this.controller = controller; this.controller = controller;
historyCard.setController(controller); historyCard.setController(controller);
@ -158,9 +144,4 @@ public class ShowHabitRootView extends BaseRootView
else else
barCard.setVisibility(GONE); barCard.setVisibility(GONE);
} }
public interface Controller extends HistoryCard.Controller
{
default void onToolbarChanged() {}
}
} }

@ -22,14 +22,17 @@ package org.isoron.uhabits.activities.habits.show;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.androidbase.activities.*; import org.isoron.androidbase.activities.*;
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 javax.inject.*; import javax.inject.*;
@ActivityScope @ActivityScope
public class ShowHabitScreen extends BaseScreen public class ShowHabitScreen extends BaseScreen
implements ShowHabitMenuBehavior.Screen, ShowHabitBehavior.Screen
{ {
@NonNull @NonNull
private final Habit habit; private final Habit habit;
@ -44,8 +47,7 @@ public class ShowHabitScreen extends BaseScreen
public ShowHabitScreen(@NonNull BaseActivity activity, public ShowHabitScreen(@NonNull BaseActivity activity,
@NonNull Habit habit, @NonNull Habit habit,
@NonNull ShowHabitRootView view, @NonNull ShowHabitRootView view,
@NonNull @NonNull EditHabitDialogFactory editHabitDialogFactory)
EditHabitDialogFactory editHabitDialogFactory)
{ {
super(activity); super(activity);
setRootView(view); setRootView(view);
@ -53,37 +55,46 @@ public class ShowHabitScreen extends BaseScreen
this.habit = habit; this.habit = habit;
} }
public void setController(@NonNull ShowHabitController controller)
{
this.controller = controller;
}
public void reattachDialogs() public void reattachDialogs()
{ {
if(controller == null) throw new IllegalStateException(); if (controller == null) throw new IllegalStateException();
HistoryEditorDialog historyEditor = (HistoryEditorDialog) activity HistoryEditorDialog historyEditor = (HistoryEditorDialog) activity
.getSupportFragmentManager() .getSupportFragmentManager()
.findFragmentByTag("historyEditor"); .findFragmentByTag("historyEditor");
if (historyEditor != null) if (historyEditor != null) historyEditor.setController(controller);
historyEditor.setController(controller);
} }
public void showEditHabitDialog() public void setController(@NonNull ShowHabitController controller)
{ {
activity.showDialog( this.controller = controller;
editHabitDialogFactory.edit(habit),
"editHabit");
} }
public void showEditHistoryDialog() @Override
public void showEditHabitScreen(@NonNull Habit habit)
{ {
if(controller == null) throw new IllegalStateException(); activity.showDialog(editHabitDialogFactory.edit(habit), "editHabit");
}
@Override
public void showEditHistoryScreen()
{
if (controller == null) throw new IllegalStateException();
HistoryEditorDialog dialog = new HistoryEditorDialog(); HistoryEditorDialog dialog = new HistoryEditorDialog();
dialog.setHabit(habit); dialog.setHabit(habit);
dialog.setController(controller); dialog.setController(controller);
dialog.show(activity.getSupportFragmentManager(), "historyEditor"); dialog.show(activity.getSupportFragmentManager(), "historyEditor");
} }
@Override
public void showMessage(ShowHabitMenuBehavior.Message m)
{
switch (m)
{
case COULD_NOT_EXPORT:
showMessage(R.string.could_not_export);
}
}
} }

@ -22,14 +22,9 @@ package org.isoron.uhabits.activities.habits.show;
import android.support.annotation.*; import android.support.annotation.*;
import android.view.*; import android.view.*;
import org.isoron.androidbase.*;
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.ui.habits.show.*;
import org.isoron.uhabits.tasks.*;
import java.io.*;
import java.util.*;
import javax.inject.*; import javax.inject.*;
@ -37,47 +32,14 @@ import javax.inject.*;
public class ShowHabitsMenu extends BaseMenu public class ShowHabitsMenu extends BaseMenu
{ {
@NonNull @NonNull
private final BaseSystem system; ShowHabitMenuBehavior behavior;
@NonNull
private final ShowHabitScreen screen;
@NonNull
private final Habit habit;
@NonNull
private final TaskRunner taskRunner;
@NonNull
private ExportCSVTaskFactory exportCSVFactory;
@Inject @Inject
public ShowHabitsMenu(@NonNull BaseActivity activity, public ShowHabitsMenu(@NonNull BaseActivity activity,
@NonNull BaseSystem system, @NonNull ShowHabitMenuBehavior behavior)
@NonNull ShowHabitScreen screen,
@NonNull Habit habit,
@NonNull ExportCSVTaskFactory exportCSVFactory,
@NonNull TaskRunner taskRunner)
{ {
super(activity); super(activity);
this.system = system; this.behavior = behavior;
this.screen = screen;
this.habit = habit;
this.taskRunner = taskRunner;
this.exportCSVFactory = exportCSVFactory;
}
public void exportHabit()
{
List<Habit> selected = new LinkedList<>();
selected.add(habit);
File outputDir = system.getFilesDir("CSV");
ExportCSVTask task = exportCSVFactory.create(selected,
outputDir, filename -> {
if (filename != null) screen.showSendFileScreen(filename);
else screen.showMessage(R.string.could_not_export);
});
taskRunner.execute(task);
} }
@Override @Override
@ -86,11 +48,11 @@ public class ShowHabitsMenu extends BaseMenu
switch (item.getItemId()) switch (item.getItemId())
{ {
case R.id.action_edit_habit: case R.id.action_edit_habit:
screen.showEditHabitDialog(); behavior.onEditHabit();
return true; return true;
case R.id.export: case R.id.export:
this.exportHabit(); behavior.onExportCSV();
return true; return true;
default: default:

@ -55,7 +55,7 @@ public class ScoreCard extends HabitCard
private TaskRunner taskRunner; private TaskRunner taskRunner;
@Nullable @Nullable
private Preferences prefs; private AndroidPreferences prefs;
public ScoreCard(Context context) public ScoreCard(Context context)
{ {

@ -41,7 +41,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
private SharedPreferences sharedPrefs; private SharedPreferences sharedPrefs;
@Nullable @Nullable
private Preferences prefs; private AndroidPreferences prefs;
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) public void onActivityResult(int requestCode, int resultCode, Intent data)

@ -44,7 +44,7 @@ import static org.isoron.uhabits.notifications.RingtoneManager.*;
@AppScope @AppScope
public class NotificationTray public class NotificationTray
implements CommandRunner.Listener, Preferences.Listener implements CommandRunner.Listener, AndroidPreferences.Listener
{ {
@NonNull @NonNull
private final Context context; private final Context context;
@ -59,7 +59,7 @@ public class NotificationTray
private final CommandRunner commandRunner; private final CommandRunner commandRunner;
@NonNull @NonNull
private final Preferences preferences; private final AndroidPreferences preferences;
@NonNull @NonNull
private final HashMap<Habit, NotificationData> active; private final HashMap<Habit, NotificationData> active;
@ -69,7 +69,7 @@ public class NotificationTray
@NonNull TaskRunner taskRunner, @NonNull TaskRunner taskRunner,
@NonNull PendingIntentFactory pendingIntents, @NonNull PendingIntentFactory pendingIntents,
@NonNull CommandRunner commandRunner, @NonNull CommandRunner commandRunner,
@NonNull Preferences preferences) @NonNull AndroidPreferences preferences)
{ {
this.context = context; this.context = context;
this.taskRunner = taskRunner; this.taskRunner = taskRunner;

@ -32,8 +32,8 @@ import java.util.*;
import javax.inject.*; import javax.inject.*;
@AppScope @AppScope
public class Preferences public class AndroidPreferences
implements SharedPreferences.OnSharedPreferenceChangeListener implements SharedPreferences.OnSharedPreferenceChangeListener, Preferences
{ {
private final Context context; private final Context context;
@ -44,7 +44,7 @@ public class Preferences
private LinkedList<Listener> listeners; private LinkedList<Listener> listeners;
@Inject @Inject
public Preferences(@AppContext Context context) public AndroidPreferences(@AppContext Context context)
{ {
this.context = context; this.context = context;
listeners = new LinkedList<>(); listeners = new LinkedList<>();
@ -78,26 +78,6 @@ public class Preferences
} }
} }
public String getSyncAddress()
{
return prefs.getString("pref_sync_address", "https://sync.loophabits.org:4000");
}
public String getSyncClientId()
{
String id = prefs.getString("pref_sync_client_id", "");
if(!id.isEmpty()) return id;
id = UUID.randomUUID().toString();
prefs.edit().putString("pref_sync_client_id", id).apply();
return id;
}
public boolean isSyncFeatureEnabled()
{
return prefs.getBoolean("pref_feature_sync", false);
}
public void setDefaultOrder(HabitList.Order order) public void setDefaultOrder(HabitList.Order order)
{ {
prefs.edit().putString("pref_default_order", order.name()).apply(); prefs.edit().putString("pref_default_order", order.name()).apply();
@ -171,6 +151,22 @@ public class Preferences
return Long.parseLong(prefs.getString("pref_snooze_interval", "15")); return Long.parseLong(prefs.getString("pref_snooze_interval", "15"));
} }
public String getSyncAddress()
{
return prefs.getString("pref_sync_address",
"https://sync.loophabits.org:4000");
}
public String getSyncClientId()
{
String id = prefs.getString("pref_sync_client_id", "");
if (!id.isEmpty()) return id;
id = UUID.randomUUID().toString();
prefs.edit().putString("pref_sync_client_id", id).apply();
return id;
}
public String getSyncKey() public String getSyncKey()
{ {
return prefs.getString("pref_sync_key", ""); return prefs.getString("pref_sync_key", "");
@ -232,6 +228,11 @@ public class Preferences
return prefs.getBoolean("pref_short_toggle", false); return prefs.getBoolean("pref_short_toggle", false);
} }
public boolean isSyncFeatureEnabled()
{
return prefs.getBoolean("pref_feature_sync", false);
}
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) String key)

@ -53,7 +53,7 @@ public class PebbleReceiver extends PebbleDataReceiver
private HabitList filteredHabits; private HabitList filteredHabits;
private Preferences prefs; private AndroidPreferences prefs;
public PebbleReceiver() public PebbleReceiver()
{ {

@ -37,12 +37,12 @@ public class ReminderController
@NonNull @NonNull
private final NotificationTray notificationTray; private final NotificationTray notificationTray;
private Preferences preferences; private AndroidPreferences preferences;
@Inject @Inject
public ReminderController(@NonNull ReminderScheduler reminderScheduler, public ReminderController(@NonNull ReminderScheduler reminderScheduler,
@NonNull NotificationTray notificationTray, @NonNull NotificationTray notificationTray,
@NonNull Preferences preferences) @NonNull AndroidPreferences preferences)
{ {
this.reminderScheduler = reminderScheduler; this.reminderScheduler = reminderScheduler;
this.notificationTray = notificationTray; this.notificationTray = notificationTray;

@ -61,7 +61,7 @@ public class WidgetReceiver extends BroadcastReceiver
IntentParser parser = app.getComponent().getIntentParser(); IntentParser parser = app.getComponent().getIntentParser();
WidgetController controller = component.getWidgetController(); WidgetController controller = component.getWidgetController();
Preferences prefs = app.getComponent().getPreferences(); AndroidPreferences prefs = app.getComponent().getPreferences();
if(prefs.isSyncFeatureEnabled()) if(prefs.isSyncFeatureEnabled())
context.startService(new Intent(context, SyncService.class)); context.startService(new Intent(context, SyncService.class));

@ -72,7 +72,7 @@ public class SyncManager implements CommandRunner.Listener
private boolean readyToEmit = false; private boolean readyToEmit = false;
@NonNull @NonNull
private final Preferences prefs; private final AndroidPreferences prefs;
@NonNull @NonNull
private CommandRunner commandRunner; private CommandRunner commandRunner;
@ -86,7 +86,7 @@ public class SyncManager implements CommandRunner.Listener
@Inject @Inject
public SyncManager(@NonNull BaseSystem system, public SyncManager(@NonNull BaseSystem system,
@NonNull Preferences prefs, @NonNull AndroidPreferences prefs,
@NonNull CommandRunner commandRunner, @NonNull CommandRunner commandRunner,
@NonNull CommandParser commandParser) @NonNull CommandParser commandParser)
{ {

@ -29,11 +29,11 @@ import org.isoron.uhabits.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.receivers.*; import org.isoron.uhabits.receivers.*;
public class SyncService extends Service implements Preferences.Listener public class SyncService extends Service implements AndroidPreferences.Listener
{ {
private SyncManager syncManager; private SyncManager syncManager;
private Preferences prefs; private AndroidPreferences prefs;
private ConnectivityReceiver connectivityReceiver; private ConnectivityReceiver connectivityReceiver;

@ -39,7 +39,7 @@ public class ScoreWidget extends BaseWidget
@NonNull @NonNull
private Habit habit; private Habit habit;
private final Preferences prefs; private final AndroidPreferences prefs;
public ScoreWidget(@NonNull Context context, int id, @NonNull Habit habit) public ScoreWidget(@NonNull Context context, int id, @NonNull Habit habit)
{ {

@ -12,6 +12,7 @@ dependencies {
testImplementation 'junit:junit:4+' testImplementation 'junit:junit:4+'
testImplementation 'org.hamcrest:hamcrest-library:1.4-atlassian-1' testImplementation 'org.hamcrest:hamcrest-library:1.4-atlassian-1'
testImplementation 'org.apache.commons:commons-io:1.3.2'
testImplementation 'org.mockito:mockito-core:2.8.9' testImplementation 'org.mockito:mockito-core:2.8.9'
testImplementation 'org.json:json:20160810' testImplementation 'org.json:json:20160810'

@ -0,0 +1,26 @@
/*
* 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.preferences;
public interface Preferences
{
void setDeveloper(boolean isDeveloper);
}

@ -0,0 +1,90 @@
/*
* 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.about;
import android.support.annotation.*;
import org.isoron.uhabits.preferences.*;
public class AboutBehavior
{
private int developerCountdown = 5;
@NonNull
private Preferences prefs;
@NonNull
private Screen screen;
public AboutBehavior(@NonNull Preferences prefs, @NonNull Screen screen)
{
this.prefs = prefs;
this.screen = screen;
}
public void onPressDeveloperCountdown()
{
developerCountdown--;
if (developerCountdown <= 0)
{
prefs.setDeveloper(true);
screen.showMessage(Message.YOU_ARE_NOW_A_DEVELOPER);
}
}
public void onRateApp()
{
screen.showRateAppWebsite();
}
public void onSendFeedback()
{
screen.showSendFeedbackScreen();
}
public void onTranslateApp()
{
screen.showTranslationWebsite();
}
public void onViewSourceCode()
{
screen.showSourceCodeWebsite();
}
public enum Message
{
YOU_ARE_NOW_A_DEVELOPER
}
public interface Screen
{
void showMessage(Message message);
void showRateAppWebsite();
void showSendFeedbackScreen();
void showSourceCodeWebsite();
void showTranslationWebsite();
}
}

@ -0,0 +1,65 @@
/*
* 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.habits.show;
import android.support.annotation.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import javax.inject.*;
public class ShowHabitBehavior
{
@NonNull
private final Habit habit;
@NonNull
private final CommandRunner commandRunner;
@NonNull
private Screen screen;
@Inject
public ShowHabitBehavior(@NonNull CommandRunner commandRunner,
@NonNull Habit habit,
@NonNull Screen screen)
{
this.habit = habit;
this.commandRunner = commandRunner;
this.screen = screen;
}
public void onEditHistory()
{
screen.showEditHistoryScreen();
}
public void onToggleCheckmark(long timestamp)
{
commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp),
null);
}
public interface Screen
{
void showEditHistoryScreen();
}
}

@ -0,0 +1,98 @@
/*
* 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.habits.show;
import android.support.annotation.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
import java.io.*;
import java.util.*;
import javax.inject.*;
public class ShowHabitMenuBehavior
{
private HabitList habitList;
@NonNull
private final Habit habit;
@NonNull
private final TaskRunner taskRunner;
@NonNull
private Screen screen;
@NonNull
private System system;
@Inject
public ShowHabitMenuBehavior(@NonNull HabitList habitList,
@NonNull Habit habit,
@NonNull TaskRunner taskRunner,
@NonNull Screen screen,
@NonNull System system)
{
this.habitList = habitList;
this.habit = habit;
this.taskRunner = taskRunner;
this.screen = screen;
this.system = system;
}
public void onEditHabit()
{
screen.showEditHabitScreen(habit);
}
public void onExportCSV()
{
List<Habit> selected = Collections.singletonList(habit);
File outputDir = system.getCSVOutputDir();
taskRunner.execute(
new ExportCSVTask(habitList, selected, outputDir, filename ->
{
if (filename != null) screen.showSendFileScreen(filename);
else screen.showMessage(Message.COULD_NOT_EXPORT);
}));
}
public enum Message
{
COULD_NOT_EXPORT
}
public interface Screen
{
void showEditHabitScreen(@NonNull Habit habit);
void showMessage(Message m);
void showSendFileScreen(String filename);
}
public interface System
{
File getCSVOutputDir();
}
}

@ -21,6 +21,7 @@ package org.isoron.uhabits;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.models.memory.*; import org.isoron.uhabits.models.memory.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import org.junit.*; import org.junit.*;
@ -34,6 +35,8 @@ public class BaseUnitTest
protected MemoryModelFactory modelFactory; protected MemoryModelFactory modelFactory;
protected SingleThreadTaskRunner taskRunner;
@Before @Before
public void setUp() public void setUp()
{ {
@ -44,6 +47,7 @@ public class BaseUnitTest
modelFactory = new MemoryModelFactory(); modelFactory = new MemoryModelFactory();
habitList = modelFactory.buildHabitList(); habitList = modelFactory.buildHabitList();
fixtures = new HabitFixtures(modelFactory); fixtures = new HabitFixtures(modelFactory);
taskRunner = new SingleThreadTaskRunner();
} }
@After @After

@ -0,0 +1,72 @@
/*
* 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.habits.show;
import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import org.junit.*;
import java.io.*;
import static java.nio.file.Files.*;
import static org.apache.commons.io.FileUtils.*;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.*;
public class ShowHabitMenuBehaviorTest extends BaseUnitTest
{
private ShowHabitMenuBehavior.System system;
private ShowHabitMenuBehavior.Screen screen;
private Habit habit;
private ShowHabitMenuBehavior menu;
@Override
public void setUp()
{
super.setUp();
system = mock(ShowHabitMenuBehavior.System.class);
screen = mock(ShowHabitMenuBehavior.Screen.class);
habit = fixtures.createShortHabit();
menu = new ShowHabitMenuBehavior(habitList, habit, taskRunner, screen,
system);
}
@Test
public void testOnEditHabit()
{
menu.onEditHabit();
verify(screen).showEditHabitScreen(habit);
}
@Test
public void testOnExport() throws Exception
{
File outputDir = createTempDirectory("CSV").toFile();
when(system.getCSVOutputDir()).thenReturn(outputDir);
menu.onExportCSV();
assertThat(listFiles(outputDir, null, false).size(), equalTo(1));
deleteDirectory(outputDir);
}
}
Loading…
Cancel
Save