mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 01:08:50 -06:00
Move ListHabits controllers to uhabits-core
This commit is contained in:
@@ -23,10 +23,10 @@ import android.view.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
import org.isoron.uhabits.activities.habits.list.model.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.preferences.*;
|
||||
import org.isoron.uhabits.ui.*;
|
||||
import org.junit.*;
|
||||
import org.mockito.*;
|
||||
|
||||
@@ -63,7 +63,7 @@ public class ListHabitsMenuTest extends BaseAndroidTest
|
||||
when(preferences.getShowCompleted()).thenReturn(false);
|
||||
when(themeSwitcher.isNightMode()).thenReturn(false);
|
||||
|
||||
menu = new ListHabitsMenu(activity, screen, adapter, preferences,
|
||||
menu = new ListHabitsMenu(activity, preferences,
|
||||
themeSwitcher);
|
||||
|
||||
matcherCaptor = ArgumentCaptor.forClass(HabitMatcher.class);
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.content.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
import org.isoron.uhabits.activities.common.dialogs.*;
|
||||
import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialog.*;
|
||||
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.models.*;
|
||||
import org.isoron.uhabits.preferences.*;
|
||||
import org.isoron.uhabits.ui.*;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.*;
|
||||
import org.junit.runners.*;
|
||||
@@ -89,7 +89,7 @@ public class ListHabitsScreenTest extends BaseAndroidTest
|
||||
|
||||
screen = spy(new ListHabitsScreen(activity, commandRunner, rootView,
|
||||
intentFactory, themeSwitcher, confirmDeleteDialogFactory,
|
||||
colorPickerDialogFactory, dialogFactory, prefs, commandParser));
|
||||
colorPickerDialogFactory, dialogFactory, prefs));
|
||||
|
||||
doNothing().when(screen).showMessage(anyInt());
|
||||
|
||||
@@ -122,7 +122,7 @@ public class ListHabitsScreenTest extends BaseAndroidTest
|
||||
public void testOnCommand()
|
||||
{
|
||||
Command c = mock(Command.class);
|
||||
when(commandParser.getExecuteString(c)).thenReturn(
|
||||
when(getExecuteString(c)).thenReturn(
|
||||
R.string.toast_habit_deleted);
|
||||
screen.onCommandExecuted(c, null);
|
||||
verify(screen).showMessage(R.string.toast_habit_deleted);
|
||||
@@ -251,10 +251,9 @@ public class ListHabitsScreenTest extends BaseAndroidTest
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToggleNightMode()
|
||||
public void testApplyTheme()
|
||||
{
|
||||
screen.toggleNightMode();
|
||||
verify(themeSwitcher).toggleNightMode();
|
||||
screen.applyTheme();
|
||||
verify(activity).restartWithFade(ListHabitsActivity.class);
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,8 @@
|
||||
package org.isoron.uhabits.activities.habits.list.controllers;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.activities.habits.list.model.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.activities.habits.list.views.*;
|
||||
import org.junit.*;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.commands.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.tasks.*;
|
||||
import org.isoron.uhabits.ui.screens.habits.list.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.junit.*;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.support.test.runner.*;
|
||||
import android.test.suitebuilder.annotation.*;
|
||||
|
||||
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.runner.*;
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ReminderControllerTest extends BaseAndroidTest
|
||||
|
||||
private ReminderScheduler reminderScheduler;
|
||||
|
||||
private NotificationTray notificationTray;
|
||||
private AndroidNotificationTray notificationTray;
|
||||
|
||||
private AndroidPreferences preferences;
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ReminderControllerTest extends BaseAndroidTest
|
||||
super.setUp();
|
||||
|
||||
reminderScheduler = mock(ReminderScheduler.class);
|
||||
notificationTray = mock(NotificationTray.class);
|
||||
notificationTray = mock(AndroidNotificationTray.class);
|
||||
preferences = mock(AndroidPreferences.class);
|
||||
|
||||
controller = new ReminderController(reminderScheduler,
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.commands.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.notifications.*;
|
||||
import org.isoron.uhabits.ui.widgets.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.junit.*;
|
||||
|
||||
@@ -33,7 +34,7 @@ import static org.mockito.Mockito.*;
|
||||
|
||||
public class WidgetControllerTest extends BaseAndroidTest
|
||||
{
|
||||
private WidgetController controller;
|
||||
private WidgetBehavior controller;
|
||||
|
||||
private CommandRunner commandRunner;
|
||||
|
||||
@@ -41,7 +42,7 @@ public class WidgetControllerTest extends BaseAndroidTest
|
||||
|
||||
private long today;
|
||||
|
||||
private NotificationTray notificationTray;
|
||||
private AndroidNotificationTray notificationTray;
|
||||
|
||||
@Override
|
||||
public void setUp()
|
||||
@@ -52,8 +53,8 @@ public class WidgetControllerTest extends BaseAndroidTest
|
||||
habit = fixtures.createEmptyHabit();
|
||||
habitList.add(habit);
|
||||
commandRunner = mock(CommandRunner.class);
|
||||
notificationTray = mock(NotificationTray.class);
|
||||
controller = new WidgetController(commandRunner, notificationTray);
|
||||
notificationTray = mock(AndroidNotificationTray.class);
|
||||
controller = new WidgetBehavior(commandRunner, notificationTray);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -28,8 +28,8 @@ import android.view.*;
|
||||
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.ui.habits.list.*;
|
||||
import org.isoron.uhabits.ui.habits.show.*;
|
||||
import org.isoron.uhabits.ui.screens.habits.list.*;
|
||||
import org.isoron.uhabits.ui.screens.habits.show.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
package org.isoron.androidbase.activities;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
import org.isoron.uhabits.activities.common.dialogs.*;
|
||||
import org.isoron.uhabits.ui.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ package org.isoron.androidbase.activities;
|
||||
|
||||
import android.content.*;
|
||||
|
||||
import org.isoron.uhabits.activities.*;
|
||||
import org.isoron.uhabits.ui.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
@Module
|
||||
@@ -45,4 +48,11 @@ public class ActivityModule
|
||||
{
|
||||
return activity;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ActivityScope
|
||||
public static ThemeSwitcher getThemeSwitcher(AndroidThemeSwitcher t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import android.view.*;
|
||||
import android.widget.*;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
import org.isoron.uhabits.ui.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import static android.os.Build.VERSION.*;
|
||||
|
||||
@@ -47,7 +47,7 @@ public class HabitsApplication extends Application
|
||||
|
||||
private ReminderScheduler reminderScheduler;
|
||||
|
||||
private NotificationTray notificationTray;
|
||||
private AndroidNotificationTray notificationTray;
|
||||
|
||||
public HabitsComponent getComponent()
|
||||
{
|
||||
@@ -106,7 +106,7 @@ public class HabitsApplication extends Application
|
||||
reminderScheduler = component.getReminderScheduler();
|
||||
reminderScheduler.startListening();
|
||||
|
||||
notificationTray = component.getNotificationTray();
|
||||
notificationTray = component.getAndroidNotificationTray();
|
||||
notificationTray.startListening();
|
||||
|
||||
AndroidPreferences prefs = component.getPreferences();
|
||||
|
||||
@@ -22,7 +22,6 @@ package org.isoron.uhabits;
|
||||
import android.content.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.uhabits.activities.habits.list.model.*;
|
||||
import org.isoron.uhabits.commands.*;
|
||||
import org.isoron.uhabits.intents.*;
|
||||
import org.isoron.uhabits.io.*;
|
||||
@@ -33,6 +32,8 @@ import org.isoron.uhabits.preferences.*;
|
||||
import org.isoron.uhabits.sync.*;
|
||||
import org.isoron.uhabits.tasks.*;
|
||||
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.widgets.*;
|
||||
|
||||
@@ -47,8 +48,6 @@ import dagger.*;
|
||||
})
|
||||
public interface HabitsComponent
|
||||
{
|
||||
AndroidPreferences getPreferences();
|
||||
|
||||
BaseSystem getBaseSystem();
|
||||
|
||||
CommandRunner getCommandRunner();
|
||||
@@ -56,6 +55,8 @@ public interface HabitsComponent
|
||||
@AppContext
|
||||
Context getContext();
|
||||
|
||||
Preferences getCorePreferences();
|
||||
|
||||
CreateHabitCommandFactory getCreateHabitCommandFactory();
|
||||
|
||||
EditHabitCommandFactory getEditHabitCommandFactory();
|
||||
@@ -80,7 +81,9 @@ public interface HabitsComponent
|
||||
|
||||
PendingIntentFactory getPendingIntentFactory();
|
||||
|
||||
Preferences getCorePreferences();
|
||||
AndroidPreferences getPreferences();
|
||||
|
||||
AndroidNotificationTray getAndroidNotificationTray();
|
||||
|
||||
ReminderScheduler getReminderScheduler();
|
||||
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
|
||||
package org.isoron.uhabits;
|
||||
|
||||
import org.isoron.uhabits.notifications.*;
|
||||
import org.isoron.uhabits.preferences.*;
|
||||
import org.isoron.uhabits.ui.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
@@ -32,4 +34,13 @@ public class HabitsModule
|
||||
{
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* 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 javax.inject.*;
|
||||
|
||||
@ActivityScope
|
||||
public class ThemeSwitcher
|
||||
{
|
||||
public static final int THEME_DARK = 1;
|
||||
|
||||
public static final int THEME_LIGHT = 0;
|
||||
|
||||
@NonNull
|
||||
private final BaseActivity activity;
|
||||
|
||||
private AndroidPreferences preferences;
|
||||
|
||||
@Inject
|
||||
public ThemeSwitcher(@NonNull BaseActivity activity,
|
||||
@NonNull AndroidPreferences preferences)
|
||||
{
|
||||
this.activity = activity;
|
||||
this.preferences = preferences;
|
||||
}
|
||||
|
||||
public void apply()
|
||||
{
|
||||
switch (getTheme())
|
||||
{
|
||||
case THEME_DARK:
|
||||
applyDarkTheme();
|
||||
break;
|
||||
|
||||
case THEME_LIGHT:
|
||||
default:
|
||||
applyLightTheme();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNightMode()
|
||||
{
|
||||
return getTheme() == THEME_DARK;
|
||||
}
|
||||
|
||||
public void refreshTheme()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void toggleNightMode()
|
||||
{
|
||||
if (isNightMode()) setTheme(THEME_LIGHT);
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import android.os.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
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.
|
||||
|
||||
@@ -26,7 +26,7 @@ import android.widget.*;
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.BuildConfig;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.ui.about.*;
|
||||
import org.isoron.uhabits.ui.screens.about.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import butterknife.*;
|
||||
@@ -36,15 +36,6 @@ public class AboutRootView extends BaseRootView
|
||||
@BindView(R.id.tvVersion)
|
||||
TextView tvVersion;
|
||||
|
||||
@BindView(R.id.tvRate)
|
||||
TextView tvRate;
|
||||
|
||||
@BindView(R.id.tvFeedback)
|
||||
TextView tvFeedback;
|
||||
|
||||
@BindView(R.id.tvSource)
|
||||
TextView tvSource;
|
||||
|
||||
@NonNull
|
||||
private final AboutBehavior behavior;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import android.widget.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.intents.*;
|
||||
import org.isoron.uhabits.ui.about.*;
|
||||
import org.isoron.uhabits.ui.screens.about.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package org.isoron.uhabits.activities.common.dialogs;
|
||||
|
||||
import org.isoron.uhabits.ui.callbacks.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
/**
|
||||
@@ -26,16 +27,12 @@ import org.isoron.uhabits.utils.*;
|
||||
*/
|
||||
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);
|
||||
listener.onColorSelected(c);
|
||||
callback.onColorPicked(c);
|
||||
});
|
||||
}
|
||||
|
||||
public interface OnColorSelectedListener
|
||||
{
|
||||
void onColorSelected(int color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,12 +20,14 @@
|
||||
package org.isoron.uhabits.activities.common.dialogs;
|
||||
|
||||
import android.content.*;
|
||||
import android.support.annotation.*;
|
||||
import android.support.v7.app.*;
|
||||
|
||||
import com.google.auto.factory.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.ui.callbacks.*;
|
||||
|
||||
import butterknife.*;
|
||||
|
||||
@@ -45,19 +47,14 @@ public class ConfirmDeleteDialog extends AlertDialog
|
||||
protected String no;
|
||||
|
||||
protected ConfirmDeleteDialog(@Provided @ActivityContext Context context,
|
||||
Callback callback)
|
||||
@NonNull OnConfirmedCallback callback)
|
||||
{
|
||||
super(context);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setTitle(R.string.delete_habits);
|
||||
setMessage(question);
|
||||
setButton(BUTTON_POSITIVE, yes, (dialog, which) -> callback.run());
|
||||
setButton(BUTTON_POSITIVE, yes, (dialog, which) -> callback.onConfirmed());
|
||||
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.uhabits.*;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
import org.isoron.uhabits.activities.habits.list.model.*;
|
||||
import org.isoron.uhabits.preferences.*;
|
||||
import org.isoron.uhabits.sync.*;
|
||||
import org.isoron.uhabits.ui.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
/**
|
||||
@@ -81,6 +81,7 @@ public class ListHabitsActivity extends BaseActivity
|
||||
|
||||
screen.setMenu(menu);
|
||||
screen.setController(controller);
|
||||
screen.setListController(component.getListController());
|
||||
screen.setSelectionMenu(selectionMenu);
|
||||
rootView.setController(controller, selectionMenu);
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ public interface ListHabitsComponent
|
||||
|
||||
ListHabitsController getController();
|
||||
|
||||
HabitCardListController getListController();
|
||||
|
||||
ListHabitsMenu getMenu();
|
||||
|
||||
NumberButtonControllerFactory getNumberButtonControllerFactory();
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.isoron.uhabits.activities.habits.list.model.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.tasks.*;
|
||||
import org.isoron.uhabits.tasks.android.*;
|
||||
import org.isoron.uhabits.ui.habits.list.*;
|
||||
import org.isoron.uhabits.ui.screens.habits.list.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
|
||||
@@ -24,58 +24,44 @@ import android.view.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
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.ui.*;
|
||||
import org.isoron.uhabits.ui.screens.habits.list.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
@ActivityScope
|
||||
public class ListHabitsMenu extends BaseMenu
|
||||
{
|
||||
|
||||
@NonNull
|
||||
private final ListHabitsScreen screen;
|
||||
private final ListHabitsMenuBehavior behavior;
|
||||
|
||||
private final HabitCardListAdapter adapter;
|
||||
|
||||
private boolean showArchived;
|
||||
|
||||
private boolean showCompleted;
|
||||
|
||||
private final AndroidPreferences preferences;
|
||||
private final Preferences preferences;
|
||||
|
||||
private ThemeSwitcher themeSwitcher;
|
||||
|
||||
@Inject
|
||||
public ListHabitsMenu(@NonNull BaseActivity activity,
|
||||
@NonNull ListHabitsScreen screen,
|
||||
@NonNull HabitCardListAdapter adapter,
|
||||
@NonNull AndroidPreferences preferences,
|
||||
@NonNull ThemeSwitcher themeSwitcher)
|
||||
@NonNull Preferences preferences,
|
||||
@NonNull ThemeSwitcher themeSwitcher,
|
||||
@NonNull ListHabitsMenuBehavior behavior)
|
||||
{
|
||||
super(activity);
|
||||
this.screen = screen;
|
||||
this.adapter = adapter;
|
||||
this.preferences = preferences;
|
||||
this.themeSwitcher = themeSwitcher;
|
||||
|
||||
showCompleted = preferences.getShowCompleted();
|
||||
showArchived = preferences.getShowArchived();
|
||||
updateAdapterFilter();
|
||||
this.behavior = behavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@NonNull Menu menu)
|
||||
{
|
||||
MenuItem nightModeItem = menu.findItem(R.id.actionToggleNightMode);
|
||||
nightModeItem.setChecked(themeSwitcher.isNightMode());
|
||||
|
||||
MenuItem hideArchivedItem = menu.findItem(R.id.actionHideArchived);
|
||||
hideArchivedItem.setChecked(!showArchived);
|
||||
|
||||
MenuItem hideCompletedItem = menu.findItem(R.id.actionHideCompleted);
|
||||
hideCompletedItem.setChecked(!showCompleted);
|
||||
nightModeItem.setChecked(themeSwitcher.isNightMode());
|
||||
hideArchivedItem.setChecked(!preferences.getShowArchived());
|
||||
hideCompletedItem.setChecked(!preferences.getShowCompleted());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,49 +70,49 @@ public class ListHabitsMenu extends BaseMenu
|
||||
switch (item.getItemId())
|
||||
{
|
||||
case R.id.actionToggleNightMode:
|
||||
screen.toggleNightMode();
|
||||
behavior.onToggleNightMode();
|
||||
return true;
|
||||
|
||||
case R.id.actionAdd:
|
||||
screen.showCreateHabitScreen();
|
||||
behavior.onCreateHabit();
|
||||
return true;
|
||||
|
||||
case R.id.actionFAQ:
|
||||
screen.showFAQScreen();
|
||||
behavior.onViewFAQ();
|
||||
return true;
|
||||
|
||||
case R.id.actionAbout:
|
||||
screen.showAboutScreen();
|
||||
behavior.onViewAbout();
|
||||
return true;
|
||||
|
||||
case R.id.actionSettings:
|
||||
screen.showSettingsScreen();
|
||||
behavior.onViewSettings();
|
||||
return true;
|
||||
|
||||
case R.id.actionHideArchived:
|
||||
toggleShowArchived();
|
||||
behavior.onToggleShowArchived();
|
||||
invalidate();
|
||||
return true;
|
||||
|
||||
case R.id.actionHideCompleted:
|
||||
toggleShowCompleted();
|
||||
behavior.onToggleShowCompleted();
|
||||
invalidate();
|
||||
return true;
|
||||
|
||||
case R.id.actionSortColor:
|
||||
adapter.setOrder(HabitList.Order.BY_COLOR);
|
||||
behavior.onSortByColor();
|
||||
return true;
|
||||
|
||||
case R.id.actionSortManual:
|
||||
adapter.setOrder(HabitList.Order.BY_POSITION);
|
||||
behavior.onSortByManually();
|
||||
return true;
|
||||
|
||||
case R.id.actionSortName:
|
||||
adapter.setOrder(HabitList.Order.BY_NAME);
|
||||
behavior.onSortByName();
|
||||
return true;
|
||||
|
||||
case R.id.actionSortScore:
|
||||
adapter.setOrder(HabitList.Order.BY_SCORE);
|
||||
behavior.onSortByScore();
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -140,26 +126,4 @@ public class ListHabitsMenu extends BaseMenu
|
||||
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.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.*;
|
||||
|
||||
@@ -34,12 +35,37 @@ public class ListHabitsModule extends ActivityModule
|
||||
super(activity);
|
||||
}
|
||||
|
||||
@Provides
|
||||
ListHabitsMenuBehavior.Adapter getAdapter(HabitCardListAdapter adapter)
|
||||
{
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@Provides
|
||||
ListHabitsMenuBehavior.Screen getMenuScreen(ListHabitsScreen screen)
|
||||
{
|
||||
return screen;
|
||||
}
|
||||
|
||||
@Provides
|
||||
ListHabitsBehavior.Screen getScreen(ListHabitsScreen screen)
|
||||
{
|
||||
return screen;
|
||||
}
|
||||
|
||||
@Provides
|
||||
ListHabitsSelectionMenuBehavior.Adapter getSelMenuAdapter(
|
||||
HabitCardListAdapter adapter)
|
||||
{
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@Provides
|
||||
ListHabitsSelectionMenuBehavior.Screen getSelMenuScreen(ListHabitsScreen screen)
|
||||
{
|
||||
return screen;
|
||||
}
|
||||
|
||||
@Provides
|
||||
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.models.*;
|
||||
import org.isoron.uhabits.tasks.*;
|
||||
import org.isoron.uhabits.ui.screens.habits.list.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import javax.inject.*;
|
||||
@@ -134,7 +135,8 @@ public class ListHabitsRootView extends BaseRootView
|
||||
listController.setSelectionListener(menu);
|
||||
listView.setController(listController);
|
||||
menu.setListController(listController);
|
||||
header.setScrollController(new ScrollableChart.ScrollController() {
|
||||
header.setScrollController(new ScrollableChart.ScrollController()
|
||||
{
|
||||
@Override
|
||||
public void onDataOffsetChanged(int newDataOffset)
|
||||
{
|
||||
@@ -187,7 +189,8 @@ public class ListHabitsRootView extends BaseRootView
|
||||
|
||||
private void updateProgressBar()
|
||||
{
|
||||
postDelayed(() -> {
|
||||
postDelayed(() ->
|
||||
{
|
||||
int activeTaskCount = runner.getActiveTaskCount();
|
||||
int newVisibility = activeTaskCount > 0 ? VISIBLE : GONE;
|
||||
if (progressBar.getVisibility() != newVisibility)
|
||||
|
||||
@@ -31,19 +31,21 @@ import android.widget.*;
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.androidbase.utils.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
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.list.controllers.*;
|
||||
import org.isoron.uhabits.commands.*;
|
||||
import org.isoron.uhabits.intents.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
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 java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
@@ -52,7 +54,9 @@ import static android.view.inputmethod.EditorInfo.*;
|
||||
|
||||
@ActivityScope
|
||||
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;
|
||||
|
||||
@@ -92,8 +96,10 @@ public class ListHabitsScreen extends BaseScreen
|
||||
@NonNull
|
||||
private AndroidPreferences prefs;
|
||||
|
||||
@NonNull
|
||||
private final CommandParser commandParser;
|
||||
@Nullable
|
||||
private HabitCardListController listController;
|
||||
|
||||
private final ListHabitsRootView rootView;
|
||||
|
||||
@Inject
|
||||
public ListHabitsScreen(@NonNull BaseActivity activity,
|
||||
@@ -101,18 +107,14 @@ public class ListHabitsScreen extends BaseScreen
|
||||
@NonNull ListHabitsRootView rootView,
|
||||
@NonNull IntentFactory intentFactory,
|
||||
@NonNull ThemeSwitcher themeSwitcher,
|
||||
@NonNull
|
||||
ConfirmDeleteDialogFactory confirmDeleteDialogFactory,
|
||||
@NonNull
|
||||
ColorPickerDialogFactory colorPickerFactory,
|
||||
@NonNull
|
||||
EditHabitDialogFactory editHabitDialogFactory,
|
||||
@NonNull AndroidPreferences prefs,
|
||||
@NonNull CommandParser commandParser)
|
||||
@NonNull ConfirmDeleteDialogFactory confirmDeleteDialogFactory,
|
||||
@NonNull ColorPickerDialogFactory colorPickerFactory,
|
||||
@NonNull EditHabitDialogFactory editHabitDialogFactory,
|
||||
@NonNull AndroidPreferences prefs)
|
||||
{
|
||||
super(activity);
|
||||
this.commandParser = commandParser;
|
||||
setRootView(rootView);
|
||||
this.rootView = rootView;
|
||||
this.prefs = prefs;
|
||||
this.colorPickerFactory = colorPickerFactory;
|
||||
this.commandRunner = commandRunner;
|
||||
@@ -122,6 +124,35 @@ public class ListHabitsScreen extends BaseScreen
|
||||
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()
|
||||
{
|
||||
commandRunner.addListener(this);
|
||||
@@ -132,7 +163,7 @@ public class ListHabitsScreen extends BaseScreen
|
||||
@Nullable Long refreshKey)
|
||||
{
|
||||
if (command.isRemote()) return;
|
||||
showMessage(commandParser.getExecuteString(command));
|
||||
showMessage(getExecuteString(command));
|
||||
}
|
||||
|
||||
public void onDettached()
|
||||
@@ -154,24 +185,24 @@ public class ListHabitsScreen extends BaseScreen
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTheme()
|
||||
{
|
||||
themeSwitcher.apply();
|
||||
activity.restartWithFade(ListHabitsActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showAboutScreen()
|
||||
{
|
||||
Intent intent = intentFactory.startAboutActivity(activity);
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a {@link ColorPickerDialog} to the user.
|
||||
* <p>
|
||||
* The selected color on the dialog is the color of the given habit.
|
||||
*
|
||||
* @param habit the habit
|
||||
* @param callback
|
||||
*/
|
||||
public void showColorPicker(@NonNull Habit habit,
|
||||
@NonNull OnColorSelectedListener callback)
|
||||
{
|
||||
ColorPickerDialog picker = colorPickerFactory.create(habit.getColor());
|
||||
@Override
|
||||
public void showColorPicker(int defaultColor,
|
||||
@NonNull OnColorPickedCallback callback) {
|
||||
ColorPickerDialog picker = colorPickerFactory.create(defaultColor);
|
||||
picker.setListener(callback);
|
||||
activity.showDialog(picker, "picker");
|
||||
}
|
||||
@@ -183,6 +214,7 @@ public class ListHabitsScreen extends BaseScreen
|
||||
activity.showDialog(dialog, "editHabit");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCreateHabitScreen()
|
||||
{
|
||||
if (!prefs.isNumericalHabitsFeatureEnabled())
|
||||
@@ -203,18 +235,22 @@ public class ListHabitsScreen extends BaseScreen
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public void showDeleteConfirmationScreen(ConfirmDeleteDialog.Callback callback)
|
||||
@Override
|
||||
public void showDeleteConfirmationScreen(
|
||||
@NonNull OnConfirmedCallback callback)
|
||||
{
|
||||
activity.showDialog(confirmDeleteDialogFactory.create(callback));
|
||||
}
|
||||
|
||||
public void showEditHabitScreen(Habit habit)
|
||||
@Override
|
||||
public void showEditHabitsScreen(List<Habit> habits)
|
||||
{
|
||||
EditHabitDialog dialog;
|
||||
dialog = editHabitDialogFactory.edit(habit);
|
||||
dialog = editHabitDialogFactory.edit(habits.get(0));
|
||||
activity.showDialog(dialog, "editNumericalHabit");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showFAQScreen()
|
||||
{
|
||||
Intent intent = intentFactory.viewFAQ(activity);
|
||||
@@ -275,7 +311,8 @@ public class ListHabitsScreen extends BaseScreen
|
||||
@Override
|
||||
public void showNumberPicker(double value,
|
||||
@NonNull String unit,
|
||||
@NonNull ListHabitsBehavior.NumberPickerCallback callback)
|
||||
@NonNull
|
||||
ListHabitsBehavior.NumberPickerCallback callback)
|
||||
{
|
||||
LayoutInflater inflater = activity.getLayoutInflater();
|
||||
View view = inflater.inflate(R.layout.number_picker_dialog, null);
|
||||
@@ -332,18 +369,13 @@ public class ListHabitsScreen extends BaseScreen
|
||||
showSendEmailScreen(to, subject, log);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showSettingsScreen()
|
||||
{
|
||||
Intent intent = intentFactory.startSettingsActivity(activity);
|
||||
activity.startActivityForResult(intent, REQUEST_SETTINGS);
|
||||
}
|
||||
|
||||
public void toggleNightMode()
|
||||
{
|
||||
themeSwitcher.toggleNightMode();
|
||||
activity.restartWithFade(ListHabitsActivity.class);
|
||||
}
|
||||
|
||||
private void onOpenDocumentResult(int resultCode, Intent data)
|
||||
{
|
||||
if (controller == null) return;
|
||||
|
||||
@@ -24,12 +24,10 @@ import android.view.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
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.model.*;
|
||||
|
||||
import java.util.*;
|
||||
import org.isoron.uhabits.commands.*;
|
||||
import org.isoron.uhabits.ui.screens.habits.list.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
@@ -43,25 +41,24 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu
|
||||
@NonNull
|
||||
CommandRunner commandRunner;
|
||||
|
||||
private ListHabitsSelectionMenuBehavior behavior;
|
||||
|
||||
@NonNull
|
||||
private final HabitCardListAdapter listAdapter;
|
||||
|
||||
@Nullable
|
||||
private HabitCardListController listController;
|
||||
|
||||
@NonNull
|
||||
private final HabitList habitList;
|
||||
|
||||
@Inject
|
||||
public ListHabitsSelectionMenu(@NonNull HabitList habitList,
|
||||
@NonNull ListHabitsScreen screen,
|
||||
public ListHabitsSelectionMenu(@NonNull ListHabitsScreen screen,
|
||||
@NonNull HabitCardListAdapter listAdapter,
|
||||
@NonNull CommandRunner commandRunner)
|
||||
@NonNull CommandRunner commandRunner,
|
||||
@NonNull ListHabitsSelectionMenuBehavior behavior)
|
||||
{
|
||||
this.habitList = habitList;
|
||||
this.screen = screen;
|
||||
this.listAdapter = listAdapter;
|
||||
this.commandRunner = commandRunner;
|
||||
this.behavior = behavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,34 +71,26 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu
|
||||
@Override
|
||||
public boolean onItemClicked(@NonNull MenuItem item)
|
||||
{
|
||||
List<Habit> selected = listAdapter.getSelected();
|
||||
if (selected.isEmpty()) return false;
|
||||
|
||||
Habit firstHabit = selected.get(0);
|
||||
|
||||
switch (item.getItemId())
|
||||
{
|
||||
case R.id.action_edit_habit:
|
||||
showEditScreen(firstHabit);
|
||||
finish();
|
||||
behavior.onEditHabits();
|
||||
return true;
|
||||
|
||||
case R.id.action_archive_habit:
|
||||
performArchive(selected);
|
||||
finish();
|
||||
behavior.onArchiveHabits();
|
||||
return true;
|
||||
|
||||
case R.id.action_unarchive_habit:
|
||||
performUnarchive(selected);
|
||||
finish();
|
||||
behavior.onUnarchiveHabits();
|
||||
return true;
|
||||
|
||||
case R.id.action_delete:
|
||||
performDelete(selected);
|
||||
behavior.onDeleteHabits();
|
||||
return true;
|
||||
|
||||
case R.id.action_color:
|
||||
showColorPicker(selected, firstHabit);
|
||||
behavior.onChangeColor();
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -112,28 +101,16 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu
|
||||
@Override
|
||||
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 itemColor = menu.findItem(R.id.action_color);
|
||||
MenuItem itemArchive = menu.findItem(R.id.action_archive_habit);
|
||||
MenuItem itemUnarchive = menu.findItem(R.id.action_unarchive_habit);
|
||||
|
||||
itemColor.setVisible(true);
|
||||
itemEdit.setVisible(showEdit);
|
||||
itemArchive.setVisible(showArchive);
|
||||
itemUnarchive.setVisible(showUnarchive);
|
||||
|
||||
setTitle(Integer.toString(selected.size()));
|
||||
itemEdit.setVisible(behavior.canEdit());
|
||||
itemArchive.setVisible(behavior.canArchive());
|
||||
itemUnarchive.setVisible(behavior.canUnarchive());
|
||||
setTitle(Integer.toString(listAdapter.getSelected().size()));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -166,41 +143,4 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu
|
||||
{
|
||||
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 org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.activities.habits.list.model.*;
|
||||
import org.isoron.uhabits.activities.habits.list.views.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
/**
|
||||
* Controller responsible for receiving and processing the events generated by a
|
||||
* HabitListView. These include selecting and reordering items, toggling
|
||||
* 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();
|
||||
|
||||
@@ -48,10 +53,12 @@ public class HabitCardListController implements HabitCardListView.Controller
|
||||
@NonNull
|
||||
private Mode activeMode;
|
||||
|
||||
@Inject
|
||||
public HabitCardListController(@NonNull HabitCardListAdapter adapter)
|
||||
{
|
||||
this.adapter = adapter;
|
||||
this.activeMode = new NormalMode();
|
||||
adapter.getObservable().addListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,6 +126,16 @@ public class HabitCardListController implements HabitCardListView.Controller
|
||||
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
|
||||
* other than this controller. This happens, for example, when the user
|
||||
@@ -180,7 +197,6 @@ public class HabitCardListController implements HabitCardListView.Controller
|
||||
{
|
||||
adapter.clearSelection();
|
||||
activeMode = new NormalMode();
|
||||
|
||||
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.
|
||||
*
|
||||
@@ -28,6 +28,7 @@ import org.isoron.uhabits.activities.habits.list.*;
|
||||
import org.isoron.uhabits.activities.habits.list.views.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.preferences.*;
|
||||
import org.isoron.uhabits.ui.screens.habits.list.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.util.*;
|
||||
@@ -42,8 +43,11 @@ import javax.inject.*;
|
||||
*/
|
||||
@ActivityScope
|
||||
public class HabitCardListAdapter
|
||||
extends RecyclerView.Adapter<HabitCardViewHolder>
|
||||
implements HabitCardListCache.Listener, MidnightTimer.MidnightListener
|
||||
extends RecyclerView.Adapter<HabitCardViewHolder> implements
|
||||
HabitCardListCache.Listener,
|
||||
MidnightTimer.MidnightListener,
|
||||
ListHabitsMenuBehavior.Adapter,
|
||||
ListHabitsSelectionMenuBehavior.Adapter
|
||||
{
|
||||
@NonNull
|
||||
private ModelObservable observable;
|
||||
@@ -95,10 +99,12 @@ public class HabitCardListAdapter
|
||||
/**
|
||||
* Sets all items as not selected.
|
||||
*/
|
||||
@Override
|
||||
public void clearSelection()
|
||||
{
|
||||
selected.clear();
|
||||
notifyDataSetChanged();
|
||||
observable.notifyListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,6 +139,7 @@ public class HabitCardListAdapter
|
||||
return observable;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public List<Habit> getSelected()
|
||||
{
|
||||
@@ -255,6 +262,7 @@ public class HabitCardListAdapter
|
||||
*
|
||||
* @param habits list of habits to be removed
|
||||
*/
|
||||
@Override
|
||||
public void performRemove(List<Habit> habits)
|
||||
{
|
||||
for (Habit h : habits)
|
||||
@@ -278,11 +286,13 @@ public class HabitCardListAdapter
|
||||
cache.reorder(from, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh()
|
||||
{
|
||||
cache.refreshAllHabits();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilter(HabitMatcher matcher)
|
||||
{
|
||||
cache.setFilter(matcher);
|
||||
@@ -300,6 +310,7 @@ public class HabitCardListAdapter
|
||||
this.listView = listView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrder(HabitList.Order order)
|
||||
{
|
||||
cache.setOrder(order);
|
||||
|
||||
@@ -1,408 +0,0 @@
|
||||
/*
|
||||
* 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.habits.list.model;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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.habits.list.model;
|
||||
|
||||
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 AndroidPreferences prefs;
|
||||
|
||||
@NonNull
|
||||
private final String[] hints;
|
||||
|
||||
/**
|
||||
* Constructs a new list containing the provided hints.
|
||||
*
|
||||
* @param hints initial list of hints
|
||||
*/
|
||||
public HintList(@Provided @NonNull AndroidPreferences 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);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides models that are specific for {@link org.isoron.uhabits.activities.habits.list.ListHabitsActivity}.
|
||||
*/
|
||||
package org.isoron.uhabits.activities.habits.list.model;
|
||||
@@ -29,7 +29,7 @@ import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.support.annotation.*;
|
||||
|
||||
import org.isoron.uhabits.activities.common.dialogs.*;
|
||||
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.*;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import android.support.annotation.*;
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.ui.habits.show.*;
|
||||
import org.isoron.uhabits.ui.screens.habits.show.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.common.dialogs.*;
|
||||
import org.isoron.uhabits.activities.habits.edit.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.ui.habits.show.*;
|
||||
import org.isoron.uhabits.ui.screens.habits.show.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import android.view.*;
|
||||
|
||||
import org.isoron.androidbase.activities.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.ui.habits.show.*;
|
||||
import org.isoron.uhabits.ui.screens.habits.show.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.os.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.receivers.*;
|
||||
import org.isoron.uhabits.ui.widgets.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import dagger.*;
|
||||
@@ -63,7 +64,7 @@ public class FireSettingReceiver extends BroadcastReceiver
|
||||
if (args == null) return;
|
||||
|
||||
long timestamp = DateUtils.getStartOfToday();
|
||||
WidgetController controller = component.getWidgetController();
|
||||
WidgetBehavior controller = component.getWidgetController();
|
||||
|
||||
switch (args.action)
|
||||
{
|
||||
@@ -102,7 +103,7 @@ public class FireSettingReceiver extends BroadcastReceiver
|
||||
@Component(dependencies = HabitsComponent.class)
|
||||
interface ReceiverComponent
|
||||
{
|
||||
WidgetController getWidgetController();
|
||||
WidgetBehavior getWidgetController();
|
||||
}
|
||||
|
||||
private class Arguments
|
||||
|
||||
@@ -43,30 +43,6 @@ public class CommandParser
|
||||
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
|
||||
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.preferences.*;
|
||||
import org.isoron.uhabits.tasks.*;
|
||||
import org.isoron.uhabits.ui.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.util.*;
|
||||
@@ -43,8 +44,9 @@ import static android.graphics.BitmapFactory.*;
|
||||
import static org.isoron.uhabits.notifications.RingtoneManager.*;
|
||||
|
||||
@AppScope
|
||||
public class NotificationTray
|
||||
implements CommandRunner.Listener, AndroidPreferences.Listener
|
||||
public class AndroidNotificationTray
|
||||
implements CommandRunner.Listener, AndroidPreferences.Listener,
|
||||
NotificationTray
|
||||
{
|
||||
@NonNull
|
||||
private final Context context;
|
||||
@@ -65,11 +67,11 @@ public class NotificationTray
|
||||
private final HashMap<Habit, NotificationData> active;
|
||||
|
||||
@Inject
|
||||
public NotificationTray(@AppContext @NonNull Context context,
|
||||
@NonNull TaskRunner taskRunner,
|
||||
@NonNull PendingIntentFactory pendingIntents,
|
||||
@NonNull CommandRunner commandRunner,
|
||||
@NonNull AndroidPreferences preferences)
|
||||
public AndroidNotificationTray(@AppContext @NonNull Context context,
|
||||
@NonNull TaskRunner taskRunner,
|
||||
@NonNull PendingIntentFactory pendingIntents,
|
||||
@NonNull CommandRunner commandRunner,
|
||||
@NonNull AndroidPreferences preferences)
|
||||
{
|
||||
this.context = context;
|
||||
this.taskRunner = taskRunner;
|
||||
@@ -79,6 +81,7 @@ public class NotificationTray
|
||||
this.active = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(@NonNull Habit habit)
|
||||
{
|
||||
int notificationId = getNotificationId(habit);
|
||||
@@ -24,15 +24,13 @@ import android.preference.*;
|
||||
|
||||
import org.isoron.androidbase.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.ui.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
@AppScope
|
||||
public class AndroidPreferences
|
||||
implements SharedPreferences.OnSharedPreferenceChangeListener, Preferences
|
||||
@@ -103,6 +101,7 @@ public class AndroidPreferences
|
||||
*
|
||||
* @return number of last hint shown
|
||||
*/
|
||||
@Override
|
||||
public int getLastHintNumber()
|
||||
{
|
||||
return prefs.getInt("last_hint_number", -1);
|
||||
@@ -113,6 +112,7 @@ public class AndroidPreferences
|
||||
*
|
||||
* @return timestamp of the day the last hint was shown
|
||||
*/
|
||||
@Override
|
||||
public long getLastHintTimestamp()
|
||||
{
|
||||
return prefs.getLong("last_hint_timestamp", -1);
|
||||
@@ -128,21 +128,25 @@ public class AndroidPreferences
|
||||
prefs.edit().putLong("last_sync", timestamp).apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getShowArchived()
|
||||
{
|
||||
return prefs.getBoolean("pref_show_archived", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShowArchived(boolean showArchived)
|
||||
{
|
||||
prefs.edit().putBoolean("pref_show_archived", showArchived).apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getShowCompleted()
|
||||
{
|
||||
return prefs.getBoolean("pref_show_completed", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShowCompleted(boolean showCompleted)
|
||||
{
|
||||
prefs.edit().putBoolean("pref_show_completed", showCompleted).apply();
|
||||
@@ -155,8 +159,7 @@ public class AndroidPreferences
|
||||
|
||||
public String getSyncAddress()
|
||||
{
|
||||
return prefs.getString("pref_sync_address",
|
||||
"https://sync.loophabits.org:4000");
|
||||
return prefs.getString("pref_sync_address", "https://sync.loophabits.org:4000");
|
||||
}
|
||||
|
||||
public String getSyncClientId()
|
||||
@@ -174,16 +177,19 @@ public class AndroidPreferences
|
||||
return prefs.getString("pref_sync_key", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTheme()
|
||||
{
|
||||
return prefs.getInt("pref_theme", ThemeSwitcher.THEME_LIGHT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheme(int theme)
|
||||
{
|
||||
prefs.edit().putInt("pref_theme", theme).apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementLaunchCount()
|
||||
{
|
||||
int count = prefs.getInt("launch_count", 0);
|
||||
@@ -200,16 +206,19 @@ public class AndroidPreferences
|
||||
return prefs.getBoolean("pref_developer", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeveloper(boolean isDeveloper)
|
||||
{
|
||||
prefs.edit().putBoolean("pref_developer", isDeveloper).apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFirstRun()
|
||||
{
|
||||
return prefs.getBoolean("pref_first_run", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFirstRun(boolean isFirstRun)
|
||||
{
|
||||
prefs.edit().putBoolean("pref_first_run", isFirstRun).apply();
|
||||
@@ -220,6 +229,7 @@ public class AndroidPreferences
|
||||
return prefs.getBoolean("pref_feature_numerical_habits", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPureBlackEnabled()
|
||||
{
|
||||
return prefs.getBoolean("pref_pure_black", false);
|
||||
@@ -297,6 +307,7 @@ public class AndroidPreferences
|
||||
* @param number number of the last hint shown
|
||||
* @param timestamp timestamp for the day the last hint was shown
|
||||
*/
|
||||
@Override
|
||||
public void updateLastHint(int number, long timestamp)
|
||||
{
|
||||
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.
|
||||
*
|
||||
@@ -35,13 +35,13 @@ public class ReminderController
|
||||
private final ReminderScheduler reminderScheduler;
|
||||
|
||||
@NonNull
|
||||
private final NotificationTray notificationTray;
|
||||
private final AndroidNotificationTray notificationTray;
|
||||
|
||||
private AndroidPreferences preferences;
|
||||
|
||||
@Inject
|
||||
public ReminderController(@NonNull ReminderScheduler reminderScheduler,
|
||||
@NonNull NotificationTray notificationTray,
|
||||
@NonNull AndroidNotificationTray notificationTray,
|
||||
@NonNull AndroidPreferences preferences)
|
||||
{
|
||||
this.reminderScheduler = reminderScheduler;
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* 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.receivers;
|
||||
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.uhabits.commands.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.notifications.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
@ReceiverScope
|
||||
public class WidgetController
|
||||
{
|
||||
@NonNull
|
||||
private final CommandRunner commandRunner;
|
||||
|
||||
private NotificationTray notificationTray;
|
||||
|
||||
@Inject
|
||||
public WidgetController(@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());
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.intents.*;
|
||||
import org.isoron.uhabits.preferences.*;
|
||||
import org.isoron.uhabits.sync.*;
|
||||
import org.isoron.uhabits.ui.widgets.*;
|
||||
|
||||
import dagger.*;
|
||||
|
||||
@@ -60,7 +61,7 @@ public class WidgetReceiver extends BroadcastReceiver
|
||||
.build();
|
||||
|
||||
IntentParser parser = app.getComponent().getIntentParser();
|
||||
WidgetController controller = component.getWidgetController();
|
||||
WidgetBehavior controller = component.getWidgetController();
|
||||
AndroidPreferences prefs = app.getComponent().getPreferences();
|
||||
|
||||
if(prefs.isSyncFeatureEnabled())
|
||||
@@ -96,6 +97,6 @@ public class WidgetReceiver extends BroadcastReceiver
|
||||
@Component(dependencies = HabitsComponent.class)
|
||||
interface WidgetComponent
|
||||
{
|
||||
WidgetController getWidgetController();
|
||||
WidgetBehavior getWidgetController();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user