Move ListHabits controllers to uhabits-core

This commit is contained in:
2017-05-27 12:11:05 -04:00
parent 94c70485b7
commit 70423ddb0a
60 changed files with 799 additions and 367 deletions

View File

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

View File

@@ -0,0 +1,27 @@
/*
* 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;
import org.isoron.uhabits.models.*;
public interface NotificationTray
{
void cancel(Habit habit);
}

View File

@@ -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.ui;
import android.support.annotation.*;
import org.isoron.uhabits.preferences.*;
public abstract class ThemeSwitcher
{
public static final int THEME_DARK = 1;
public static final int THEME_LIGHT = 0;
private final Preferences preferences;
public ThemeSwitcher(@NonNull Preferences preferences)
{
this.preferences = preferences;
}
public void apply()
{
if (preferences.getTheme() == THEME_DARK)
{
if (preferences.isPureBlackEnabled()) applyPureBlackTheme();
else applyDarkTheme();
}
else
{
applyLightTheme();
}
}
public abstract void applyDarkTheme();
public abstract void applyLightTheme();
public abstract void applyPureBlackTheme();
public boolean isNightMode()
{
return preferences.getTheme() == THEME_DARK;
}
public void setTheme(int theme)
{
preferences.setTheme(theme);
}
public void toggleNightMode()
{
if (isNightMode()) setTheme(THEME_LIGHT);
else setTheme(THEME_DARK);
}
}

View File

@@ -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);
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -17,7 +17,7 @@
* 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.*;

View File

@@ -0,0 +1,408 @@
/*
* 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.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.utils.*;
import java.util.*;
import javax.inject.*;
/**
* A HabitCardListCache fetches and keeps a cache of all the data necessary to
* render a HabitCardListView.
* <p>
* This is needed since performing database lookups during scrolling can make
* the ListView very slow. It also registers itself as an observer of the
* models, in order to update itself automatically.
* <p>
* Note that this class is singleton-scoped, therefore it is shared among all
* activities.
*/
@AppScope
public class HabitCardListCache implements CommandRunner.Listener
{
private int checkmarkCount;
private Task currentFetchTask;
@NonNull
private Listener listener;
@NonNull
private CacheData data;
@NonNull
private HabitList allHabits;
@NonNull
private HabitList filteredHabits;
private final TaskRunner taskRunner;
private final CommandRunner commandRunner;
@Inject
public HabitCardListCache(@NonNull HabitList allHabits,
@NonNull CommandRunner commandRunner,
@NonNull TaskRunner taskRunner)
{
this.allHabits = allHabits;
this.commandRunner = commandRunner;
this.filteredHabits = allHabits;
this.taskRunner = taskRunner;
this.listener = new Listener() {};
data = new CacheData();
}
public void cancelTasks()
{
if (currentFetchTask != null) currentFetchTask.cancel();
}
public int[] getCheckmarks(long habitId)
{
return data.checkmarks.get(habitId);
}
/**
* Returns the habits that occupies a certain position on the list.
*
* @param position the position of the habit
* @return the habit at given position
* @throws IndexOutOfBoundsException if position is not valid
*/
@NonNull
public Habit getHabitByPosition(int position)
{
return data.habits.get(position);
}
public int getHabitCount()
{
return data.habits.size();
}
public HabitList.Order getOrder()
{
return filteredHabits.getOrder();
}
public double getScore(long habitId)
{
return data.scores.get(habitId);
}
public void onAttached()
{
refreshAllHabits();
commandRunner.addListener(this);
}
@Override
public void onCommandExecuted(@NonNull Command command,
@Nullable Long refreshKey)
{
if (refreshKey == null) refreshAllHabits();
else refreshHabit(refreshKey);
}
public void onDetached()
{
commandRunner.removeListener(this);
}
public void refreshAllHabits()
{
if (currentFetchTask != null) currentFetchTask.cancel();
currentFetchTask = new RefreshTask();
taskRunner.execute(currentFetchTask);
}
public void refreshHabit(long id)
{
taskRunner.execute(new RefreshTask(id));
}
public void remove(@NonNull Long id)
{
Habit h = data.id_to_habit.get(id);
if (h == null) return;
int position = data.habits.indexOf(h);
data.habits.remove(position);
data.id_to_habit.remove(id);
data.checkmarks.remove(id);
data.scores.remove(id);
listener.onItemRemoved(position);
}
public void reorder(int from, int to)
{
Habit fromHabit = data.habits.get(from);
data.habits.remove(from);
data.habits.add(to, fromHabit);
listener.onItemMoved(from, to);
}
public void setCheckmarkCount(int checkmarkCount)
{
this.checkmarkCount = checkmarkCount;
}
public void setFilter(HabitMatcher matcher)
{
filteredHabits = allHabits.getFiltered(matcher);
}
public void setListener(@NonNull Listener listener)
{
this.listener = listener;
}
public void setOrder(HabitList.Order order)
{
allHabits.setOrder(order);
filteredHabits.setOrder(order);
refreshAllHabits();
}
/**
* Interface definition for a callback to be invoked when the data on the
* cache has been modified.
*/
public interface Listener
{
default void onItemChanged(int position) {}
default void onItemInserted(int position) {}
default void onItemMoved(int oldPosition, int newPosition) {}
default void onItemRemoved(int position) {}
default void onRefreshFinished() {}
}
private class CacheData
{
@NonNull
public HashMap<Long, Habit> id_to_habit;
@NonNull
public List<Habit> habits;
@NonNull
public HashMap<Long, int[]> checkmarks;
@NonNull
public HashMap<Long, Double> scores;
/**
* Creates a new CacheData without any content.
*/
public CacheData()
{
id_to_habit = new HashMap<>();
habits = new LinkedList<>();
checkmarks = new HashMap<>();
scores = new HashMap<>();
}
public void copyCheckmarksFrom(@NonNull CacheData oldData)
{
int[] empty = new int[checkmarkCount];
for (Long id : id_to_habit.keySet())
{
if (oldData.checkmarks.containsKey(id))
checkmarks.put(id, oldData.checkmarks.get(id));
else checkmarks.put(id, empty);
}
}
public void copyScoresFrom(@NonNull CacheData oldData)
{
for (Long id : id_to_habit.keySet())
{
if (oldData.scores.containsKey(id))
scores.put(id, oldData.scores.get(id));
else scores.put(id, 0.0);
}
}
public void fetchHabits()
{
for (Habit h : filteredHabits)
{
habits.add(h);
id_to_habit.put(h.getId(), h);
}
}
}
private class RefreshTask implements Task
{
@NonNull
private CacheData newData;
@Nullable
private Long targetId;
private boolean isCancelled;
private TaskRunner runner;
public RefreshTask()
{
newData = new CacheData();
targetId = null;
isCancelled = false;
}
public RefreshTask(long targetId)
{
newData = new CacheData();
this.targetId = targetId;
}
@Override
public void cancel()
{
isCancelled = true;
}
@Override
public void doInBackground()
{
newData.fetchHabits();
newData.copyScoresFrom(data);
newData.copyCheckmarksFrom(data);
long day = DateUtils.millisecondsInOneDay;
long dateTo = DateUtils.getStartOfDay(DateUtils.getLocalTime());
long dateFrom = dateTo - (checkmarkCount - 1) * day;
runner.publishProgress(this, -1);
for (int position = 0; position < newData.habits.size(); position++)
{
if (isCancelled) return;
Habit habit = newData.habits.get(position);
Long id = habit.getId();
if (targetId != null && !targetId.equals(id)) continue;
newData.scores.put(id, habit.getScores().getTodayValue());
newData.checkmarks.put(id,
habit.getCheckmarks().getValues(dateFrom, dateTo));
runner.publishProgress(this, position);
}
}
@Override
public void onAttached(@NonNull TaskRunner runner)
{
this.runner = runner;
}
@Override
public void onPostExecute()
{
currentFetchTask = null;
listener.onRefreshFinished();
}
@Override
public void onProgressUpdate(int currentPosition)
{
if (currentPosition < 0) processRemovedHabits();
else processPosition(currentPosition);
}
private void performInsert(Habit habit, int position)
{
Long id = habit.getId();
data.habits.add(position, habit);
data.id_to_habit.put(id, habit);
data.scores.put(id, newData.scores.get(id));
data.checkmarks.put(id, newData.checkmarks.get(id));
listener.onItemInserted(position);
}
private void performMove(Habit habit, int fromPosition, int toPosition)
{
data.habits.remove(fromPosition);
data.habits.add(toPosition, habit);
listener.onItemMoved(fromPosition, toPosition);
}
private void performUpdate(Long id, int position)
{
double oldScore = data.scores.get(id);
int[] oldCheckmarks = data.checkmarks.get(id);
double newScore = newData.scores.get(id);
int[] newCheckmarks = newData.checkmarks.get(id);
boolean unchanged = true;
if (oldScore != newScore) unchanged = false;
if (!Arrays.equals(oldCheckmarks, newCheckmarks)) unchanged = false;
if (unchanged) return;
data.scores.put(id, newScore);
data.checkmarks.put(id, newCheckmarks);
listener.onItemChanged(position);
}
private void processPosition(int currentPosition)
{
Habit habit = newData.habits.get(currentPosition);
Long id = habit.getId();
int prevPosition = data.habits.indexOf(habit);
if (prevPosition < 0) performInsert(habit, currentPosition);
else if (prevPosition == currentPosition)
performUpdate(id, currentPosition);
else performMove(habit, prevPosition, currentPosition);
}
private void processRemovedHabits()
{
Set<Long> before = data.id_to_habit.keySet();
Set<Long> after = newData.id_to_habit.keySet();
Set<Long> removed = new TreeSet<>(before);
removed.removeAll(after);
for (Long id : removed) remove(id);
}
}
}

View File

@@ -0,0 +1,81 @@
/*
* 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 com.google.auto.factory.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.utils.*;
/**
* Provides a list of hints to be shown at the application startup, and takes
* care of deciding when a new hint should be shown.
*/
@AutoFactory
public class HintList
{
private final Preferences prefs;
@NonNull
private final String[] hints;
/**
* Constructs a new list containing the provided hints.
*
* @param hints initial list of hints
*/
public HintList(@Provided @NonNull Preferences prefs,
@NonNull String hints[])
{
this.prefs = prefs;
this.hints = hints;
}
/**
* Returns a new hint to be shown to the user.
* <p>
* The hint returned is marked as read on the list, and will not be returned
* again. In case all hints have already been read, and there is nothing
* left, returns null.
*
* @return the next hint to be shown, or null if none
*/
public String pop()
{
int next = prefs.getLastHintNumber() + 1;
if (next >= hints.length) return null;
prefs.updateLastHint(next, DateUtils.getStartOfToday());
return hints[next];
}
/**
* Returns whether it is time to show a new hint or not.
*
* @return true if hint should be shown, false otherwise
*/
public boolean shouldShow()
{
long lastHintTimestamp = prefs.getLastHintTimestamp();
return (DateUtils.getStartOfToday() > lastHintTimestamp);
}
}

View File

@@ -17,7 +17,7 @@
* 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.*;
@@ -187,11 +187,6 @@ public class ListHabitsBehavior
void onNumberPicked(double newValue);
}
public interface OnFinishedListener
{
void onFinish();
}
public interface Screen
{
void showHabitScreen(@NonNull Habit h);

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -17,7 +17,7 @@
* 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.*;

View File

@@ -17,7 +17,7 @@
* 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.*;

View File

@@ -0,0 +1,70 @@
/*
* 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.widgets;
import android.support.annotation.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.ui.*;
import javax.inject.*;
public class WidgetBehavior
{
@NonNull
private final CommandRunner commandRunner;
private NotificationTray notificationTray;
@Inject
public WidgetBehavior(@NonNull CommandRunner commandRunner,
@NonNull NotificationTray notificationTray)
{
this.commandRunner = commandRunner;
this.notificationTray = notificationTray;
}
public void onAddRepetition(@NonNull Habit habit, long timestamp)
{
Repetition rep = habit.getRepetitions().getByTimestamp(timestamp);
if (rep != null) return;
performToggle(habit, timestamp);
notificationTray.cancel(habit);
}
public void onRemoveRepetition(@NonNull Habit habit, long timestamp)
{
Repetition rep = habit.getRepetitions().getByTimestamp(timestamp);
if (rep == null) return;
performToggle(habit, timestamp);
}
public void onToggleRepetition(@NonNull Habit habit, long timestamp)
{
performToggle(habit, timestamp);
}
private void performToggle(@NonNull Habit habit, long timestamp)
{
commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp),
habit.getId());
}
}

View File

@@ -17,7 +17,7 @@
* 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.models.*;
@@ -30,7 +30,7 @@ import org.mockito.junit.*;
import static junit.framework.TestCase.assertTrue;
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.*;
import static org.mockito.Mockito.*;

View File

@@ -17,7 +17,7 @@
* 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.models.*;