mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
@@ -25,6 +25,7 @@ import org.isoron.uhabits.*;
|
|||||||
import org.isoron.uhabits.activities.*;
|
import org.isoron.uhabits.activities.*;
|
||||||
import org.isoron.uhabits.activities.habits.list.model.*;
|
import org.isoron.uhabits.activities.habits.list.model.*;
|
||||||
import org.isoron.uhabits.preferences.*;
|
import org.isoron.uhabits.preferences.*;
|
||||||
|
import org.isoron.uhabits.utils.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity that allows the user to see and modify the list of habits.
|
* Activity that allows the user to see and modify the list of habits.
|
||||||
@@ -43,6 +44,8 @@ public class ListHabitsActivity extends BaseActivity
|
|||||||
|
|
||||||
private Preferences prefs;
|
private Preferences prefs;
|
||||||
|
|
||||||
|
private MidnightTimer midnightTimer;
|
||||||
|
|
||||||
public ListHabitsComponent getListHabitsComponent()
|
public ListHabitsComponent getListHabitsComponent()
|
||||||
{
|
{
|
||||||
return component;
|
return component;
|
||||||
@@ -77,6 +80,8 @@ public class ListHabitsActivity extends BaseActivity
|
|||||||
screen.setSelectionMenu(selectionMenu);
|
screen.setSelectionMenu(selectionMenu);
|
||||||
rootView.setController(controller, selectionMenu);
|
rootView.setController(controller, selectionMenu);
|
||||||
|
|
||||||
|
midnightTimer = component.getMidnightTimer();
|
||||||
|
|
||||||
setScreen(screen);
|
setScreen(screen);
|
||||||
controller.onStartup();
|
controller.onStartup();
|
||||||
}
|
}
|
||||||
@@ -84,6 +89,7 @@ public class ListHabitsActivity extends BaseActivity
|
|||||||
@Override
|
@Override
|
||||||
protected void onPause()
|
protected void onPause()
|
||||||
{
|
{
|
||||||
|
midnightTimer.onPause();
|
||||||
screen.onDettached();
|
screen.onDettached();
|
||||||
adapter.cancelRefresh();
|
adapter.cancelRefresh();
|
||||||
super.onPause();
|
super.onPause();
|
||||||
@@ -95,6 +101,7 @@ public class ListHabitsActivity extends BaseActivity
|
|||||||
adapter.refresh();
|
adapter.refresh();
|
||||||
screen.onAttached();
|
screen.onAttached();
|
||||||
rootView.postInvalidate();
|
rootView.postInvalidate();
|
||||||
|
midnightTimer.onResume();
|
||||||
|
|
||||||
if (prefs.getTheme() == ThemeSwitcher.THEME_DARK &&
|
if (prefs.getTheme() == ThemeSwitcher.THEME_DARK &&
|
||||||
prefs.isPureBlackEnabled() != pureBlack)
|
prefs.isPureBlackEnabled() != pureBlack)
|
||||||
|
|||||||
@@ -23,13 +23,14 @@ import org.isoron.uhabits.*;
|
|||||||
import org.isoron.uhabits.activities.*;
|
import org.isoron.uhabits.activities.*;
|
||||||
import org.isoron.uhabits.activities.habits.list.controllers.*;
|
import org.isoron.uhabits.activities.habits.list.controllers.*;
|
||||||
import org.isoron.uhabits.activities.habits.list.model.*;
|
import org.isoron.uhabits.activities.habits.list.model.*;
|
||||||
|
import org.isoron.uhabits.utils.*;
|
||||||
|
|
||||||
import dagger.*;
|
import dagger.*;
|
||||||
|
|
||||||
@ActivityScope
|
@ActivityScope
|
||||||
@Component(modules = { ActivityModule.class },
|
@Component(modules = { ActivityModule.class },
|
||||||
dependencies = { AppComponent.class })
|
dependencies = { AppComponent.class })
|
||||||
public interface ListHabitsComponent extends ActivityComponent
|
public interface ListHabitsComponent
|
||||||
{
|
{
|
||||||
CheckmarkButtonControllerFactory getCheckmarkButtonControllerFactory();
|
CheckmarkButtonControllerFactory getCheckmarkButtonControllerFactory();
|
||||||
|
|
||||||
@@ -44,4 +45,6 @@ public interface ListHabitsComponent extends ActivityComponent
|
|||||||
ListHabitsScreen getScreen();
|
ListHabitsScreen getScreen();
|
||||||
|
|
||||||
ListHabitsSelectionMenu getSelectionMenu();
|
ListHabitsSelectionMenu getSelectionMenu();
|
||||||
|
|
||||||
|
MidnightTimer getMidnightTimer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.isoron.uhabits.activities.habits.list.*;
|
|||||||
import org.isoron.uhabits.activities.habits.list.views.*;
|
import org.isoron.uhabits.activities.habits.list.views.*;
|
||||||
import org.isoron.uhabits.models.*;
|
import org.isoron.uhabits.models.*;
|
||||||
import org.isoron.uhabits.preferences.*;
|
import org.isoron.uhabits.preferences.*;
|
||||||
|
import org.isoron.uhabits.utils.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ import javax.inject.*;
|
|||||||
@ActivityScope
|
@ActivityScope
|
||||||
public class HabitCardListAdapter
|
public class HabitCardListAdapter
|
||||||
extends RecyclerView.Adapter<HabitCardViewHolder>
|
extends RecyclerView.Adapter<HabitCardViewHolder>
|
||||||
implements HabitCardListCache.Listener
|
implements HabitCardListCache.Listener, MidnightTimer.MidnightListener
|
||||||
{
|
{
|
||||||
@NonNull
|
@NonNull
|
||||||
private ModelObservable observable;
|
private ModelObservable observable;
|
||||||
@@ -59,15 +60,20 @@ public class HabitCardListAdapter
|
|||||||
@NonNull
|
@NonNull
|
||||||
private Preferences preferences;
|
private Preferences preferences;
|
||||||
|
|
||||||
|
private final MidnightTimer midnightTimer;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public HabitCardListAdapter(@NonNull HabitCardListCache cache,
|
public HabitCardListAdapter(@NonNull HabitCardListCache cache,
|
||||||
@NonNull Preferences preferences)
|
@NonNull Preferences preferences,
|
||||||
|
@NonNull MidnightTimer midnightTimer)
|
||||||
{
|
{
|
||||||
this.preferences = preferences;
|
this.preferences = preferences;
|
||||||
this.selected = new LinkedList<>();
|
this.selected = new LinkedList<>();
|
||||||
this.observable = new ModelObservable();
|
this.observable = new ModelObservable();
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
|
|
||||||
|
this.midnightTimer = midnightTimer;
|
||||||
|
|
||||||
cache.setListener(this);
|
cache.setListener(this);
|
||||||
cache.setCheckmarkCount(ListHabitsRootView.MAX_CHECKMARK_COUNT);
|
cache.setCheckmarkCount(ListHabitsRootView.MAX_CHECKMARK_COUNT);
|
||||||
cache.setOrder(preferences.getDefaultOrder());
|
cache.setOrder(preferences.getDefaultOrder());
|
||||||
@@ -75,6 +81,12 @@ public class HabitCardListAdapter
|
|||||||
setHasStableIds(true);
|
setHasStableIds(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void atMidnight()
|
||||||
|
{
|
||||||
|
cache.refreshAllHabits();
|
||||||
|
}
|
||||||
|
|
||||||
public void cancelRefresh()
|
public void cancelRefresh()
|
||||||
{
|
{
|
||||||
cache.cancelTasks();
|
cache.cancelTasks();
|
||||||
@@ -148,6 +160,7 @@ public class HabitCardListAdapter
|
|||||||
public void onAttached()
|
public void onAttached()
|
||||||
{
|
{
|
||||||
cache.onAttached();
|
cache.onAttached();
|
||||||
|
midnightTimer.addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -180,6 +193,7 @@ public class HabitCardListAdapter
|
|||||||
public void onDetached()
|
public void onDetached()
|
||||||
{
|
{
|
||||||
cache.onDetached();
|
cache.onDetached();
|
||||||
|
midnightTimer.removeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -26,12 +26,14 @@ import android.view.*;
|
|||||||
import android.widget.*;
|
import android.widget.*;
|
||||||
|
|
||||||
import org.isoron.uhabits.*;
|
import org.isoron.uhabits.*;
|
||||||
|
import org.isoron.uhabits.activities.habits.list.*;
|
||||||
import org.isoron.uhabits.preferences.*;
|
import org.isoron.uhabits.preferences.*;
|
||||||
import org.isoron.uhabits.utils.*;
|
import org.isoron.uhabits.utils.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class HeaderView extends LinearLayout implements Preferences.Listener
|
public class HeaderView extends LinearLayout
|
||||||
|
implements Preferences.Listener, MidnightTimer.MidnightListener
|
||||||
{
|
{
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
@@ -40,6 +42,9 @@ public class HeaderView extends LinearLayout implements Preferences.Listener
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Preferences prefs;
|
private Preferences prefs;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private MidnightTimer midnightTimer;
|
||||||
|
|
||||||
public HeaderView(Context context, AttributeSet attrs)
|
public HeaderView(Context context, AttributeSet attrs)
|
||||||
{
|
{
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
@@ -56,6 +61,18 @@ public class HeaderView extends LinearLayout implements Preferences.Listener
|
|||||||
HabitsApplication app = (HabitsApplication) appContext;
|
HabitsApplication app = (HabitsApplication) appContext;
|
||||||
prefs = app.getComponent().getPreferences();
|
prefs = app.getComponent().getPreferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context instanceof ListHabitsActivity)
|
||||||
|
{
|
||||||
|
ListHabitsActivity activity = (ListHabitsActivity) context;
|
||||||
|
midnightTimer = activity.getListHabitsComponent().getMidnightTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void atMidnight()
|
||||||
|
{
|
||||||
|
post(() -> createButtons());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -75,11 +92,13 @@ public class HeaderView extends LinearLayout implements Preferences.Listener
|
|||||||
{
|
{
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
if (prefs != null) prefs.addListener(this);
|
if (prefs != null) prefs.addListener(this);
|
||||||
|
if (midnightTimer != null) midnightTimer.addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDetachedFromWindow()
|
protected void onDetachedFromWindow()
|
||||||
{
|
{
|
||||||
|
if (midnightTimer != null) midnightTimer.removeListener(this);
|
||||||
if (prefs != null) prefs.removeListener(this);
|
if (prefs != null) prefs.removeListener(this);
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,6 +187,11 @@ public abstract class DateUtils
|
|||||||
return getStartOfDay(DateUtils.getLocalTime());
|
return getStartOfDay(DateUtils.getLocalTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long millisecondsUntilTomorrow()
|
||||||
|
{
|
||||||
|
return getStartOfToday() + millisecondsInOneDay - getLocalTime();
|
||||||
|
}
|
||||||
|
|
||||||
public static GregorianCalendar getStartOfTodayCalendar()
|
public static GregorianCalendar getStartOfTodayCalendar()
|
||||||
{
|
{
|
||||||
return getCalendar(getStartOfToday());
|
return getCalendar(getStartOfToday());
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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.utils;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.activities.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
|
import javax.inject.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that emits events when a new day starts.
|
||||||
|
*/
|
||||||
|
@ActivityScope
|
||||||
|
public class MidnightTimer
|
||||||
|
{
|
||||||
|
private final List<MidnightListener> listeners;
|
||||||
|
|
||||||
|
private ScheduledExecutorService executor;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public MidnightTimer()
|
||||||
|
{
|
||||||
|
this.listeners = new LinkedList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void addListener(MidnightListener listener)
|
||||||
|
{
|
||||||
|
this.listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void onPause()
|
||||||
|
{
|
||||||
|
executor.shutdownNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void onResume()
|
||||||
|
{
|
||||||
|
executor = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
executor.scheduleAtFixedRate(() -> notifyListeners(),
|
||||||
|
DateUtils.millisecondsUntilTomorrow() + 1000,
|
||||||
|
DateUtils.millisecondsInOneDay, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void removeListener(MidnightListener listener)
|
||||||
|
{
|
||||||
|
this.listeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void notifyListeners()
|
||||||
|
{
|
||||||
|
for (MidnightListener l : listeners) l.atMidnight();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface MidnightListener
|
||||||
|
{
|
||||||
|
void atMidnight();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user