mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Make models observable, refactor ShowHabitFragment
This commit is contained in:
@@ -36,6 +36,8 @@ import android.support.v4.app.NotificationCompat;
|
|||||||
import android.support.v4.app.TaskStackBuilder;
|
import android.support.v4.app.TaskStackBuilder;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.commands.CommandRunner;
|
||||||
|
import org.isoron.uhabits.commands.ToggleRepetitionCommand;
|
||||||
import org.isoron.uhabits.utils.DateUtils;
|
import org.isoron.uhabits.utils.DateUtils;
|
||||||
import org.isoron.uhabits.utils.ReminderUtils;
|
import org.isoron.uhabits.utils.ReminderUtils;
|
||||||
import org.isoron.uhabits.models.Checkmark;
|
import org.isoron.uhabits.models.Checkmark;
|
||||||
@@ -115,9 +117,12 @@ public class HabitBroadcastReceiver extends BroadcastReceiver
|
|||||||
long habitId = ContentUris.parseId(data);
|
long habitId = ContentUris.parseId(data);
|
||||||
Habit habit = Habit.get(habitId);
|
Habit habit = Habit.get(habitId);
|
||||||
if(habit != null)
|
if(habit != null)
|
||||||
habit.repetitions.toggle(timestamp);
|
{
|
||||||
dismissNotification(context, habitId);
|
ToggleRepetitionCommand command = new ToggleRepetitionCommand(habit, timestamp);
|
||||||
|
CommandRunner.getInstance().execute(command, habitId);
|
||||||
|
}
|
||||||
|
|
||||||
|
dismissNotification(context, habitId);
|
||||||
sendRefreshBroadcast(context);
|
sendRefreshBroadcast(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package org.isoron.uhabits;
|
package org.isoron.uhabits;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -31,21 +30,18 @@ import android.support.v7.app.ActionBar;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import org.isoron.uhabits.models.Checkmark;
|
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
import org.isoron.uhabits.tasks.BaseTask;
|
|
||||||
import org.isoron.uhabits.tasks.ProgressBar;
|
import org.isoron.uhabits.tasks.ProgressBar;
|
||||||
import org.isoron.uhabits.ui.about.AboutActivity;
|
|
||||||
import org.isoron.uhabits.ui.AndroidProgressBar;
|
import org.isoron.uhabits.ui.AndroidProgressBar;
|
||||||
import org.isoron.uhabits.ui.BaseActivity;
|
import org.isoron.uhabits.ui.BaseActivity;
|
||||||
import org.isoron.uhabits.ui.intro.IntroActivity;
|
import org.isoron.uhabits.ui.about.AboutActivity;
|
||||||
import org.isoron.uhabits.ui.habits.list.ListHabitsFragment;
|
import org.isoron.uhabits.ui.habits.list.ListHabitsFragment;
|
||||||
|
import org.isoron.uhabits.ui.habits.show.ShowHabitActivity;
|
||||||
|
import org.isoron.uhabits.ui.intro.IntroActivity;
|
||||||
import org.isoron.uhabits.ui.settings.FilePickerDialog;
|
import org.isoron.uhabits.ui.settings.FilePickerDialog;
|
||||||
import org.isoron.uhabits.ui.settings.SettingsActivity;
|
import org.isoron.uhabits.ui.settings.SettingsActivity;
|
||||||
import org.isoron.uhabits.ui.habits.show.ShowHabitActivity;
|
|
||||||
import org.isoron.uhabits.utils.FileUtils;
|
import org.isoron.uhabits.utils.FileUtils;
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||||
import org.isoron.uhabits.widgets.WidgetManager;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@@ -196,31 +192,6 @@ public class MainActivity extends BaseActivity
|
|||||||
showHabitScreen(habit);
|
showHabitScreen(habit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPostExecuteCommand(Long refreshKey)
|
|
||||||
{
|
|
||||||
listHabitsFragment.onPostExecuteCommand(refreshKey);
|
|
||||||
|
|
||||||
new BaseTask()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected void doInBackground()
|
|
||||||
{
|
|
||||||
dismissNotifications(MainActivity.this);
|
|
||||||
WidgetManager.updateWidgets(MainActivity.this);
|
|
||||||
}
|
|
||||||
}.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dismissNotifications(Context context)
|
|
||||||
{
|
|
||||||
for(Habit h : Habit.getHabitsWithReminder())
|
|
||||||
{
|
|
||||||
if(h.checkmarks.getTodayValue() != Checkmark.UNCHECKED)
|
|
||||||
HabitBroadcastReceiver.dismissNotification(context, h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showHabitScreen(Habit habit)
|
private void showHabitScreen(Habit habit)
|
||||||
{
|
{
|
||||||
Intent intent = new Intent(this, ShowHabitActivity.class);
|
Intent intent = new Intent(this, ShowHabitActivity.class);
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* 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.commands;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.tasks.BaseTask;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
public class CommandRunner
|
||||||
|
{
|
||||||
|
public interface Listener
|
||||||
|
{
|
||||||
|
void onCommandExecuted(Command command, Long refreshKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CommandRunner singleton;
|
||||||
|
private LinkedList<Listener> listeners;
|
||||||
|
|
||||||
|
private CommandRunner()
|
||||||
|
{
|
||||||
|
listeners = new LinkedList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CommandRunner getInstance()
|
||||||
|
{
|
||||||
|
if(singleton == null) singleton = new CommandRunner();
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute(final Command command, final Long refreshKey)
|
||||||
|
{
|
||||||
|
new BaseTask()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void doInBackground()
|
||||||
|
{
|
||||||
|
command.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void aVoid)
|
||||||
|
{
|
||||||
|
for(Listener l : listeners)
|
||||||
|
l.onCommandExecuted(command, refreshKey);
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addListener(Listener l)
|
||||||
|
{
|
||||||
|
listeners.add(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeListener(Listener l)
|
||||||
|
{
|
||||||
|
listeners.remove(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,6 +41,7 @@ import java.util.List;
|
|||||||
public class CheckmarkList
|
public class CheckmarkList
|
||||||
{
|
{
|
||||||
private Habit habit;
|
private Habit habit;
|
||||||
|
public ModelObservable observable = new ModelObservable();
|
||||||
|
|
||||||
public CheckmarkList(Habit habit)
|
public CheckmarkList(Habit habit)
|
||||||
{
|
{
|
||||||
@@ -59,6 +60,8 @@ public class CheckmarkList
|
|||||||
.where("habit = ?", habit.getId())
|
.where("habit = ?", habit.getId())
|
||||||
.and("timestamp >= ?", timestamp)
|
.and("timestamp >= ?", timestamp)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
|
observable.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -147,6 +147,8 @@ public class Habit extends Model
|
|||||||
@NonNull
|
@NonNull
|
||||||
public CheckmarkList checkmarks;
|
public CheckmarkList checkmarks;
|
||||||
|
|
||||||
|
public ModelObservable observable = new ModelObservable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a habit with the same attributes as the specified habit.
|
* Constructs a habit with the same attributes as the specified habit.
|
||||||
*
|
*
|
||||||
@@ -348,6 +350,8 @@ public class Habit extends Model
|
|||||||
this.reminderDays = model.reminderDays;
|
this.reminderDays = model.reminderDays;
|
||||||
this.highlight = model.highlight;
|
this.highlight = model.highlight;
|
||||||
this.archived = model.archived;
|
this.archived = model.archived;
|
||||||
|
|
||||||
|
observable.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -424,6 +428,8 @@ public class Habit extends Model
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
ActiveAndroid.endTransaction();
|
ActiveAndroid.endTransaction();
|
||||||
|
for(Habit h : habits)
|
||||||
|
h.observable.notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,6 +462,8 @@ public class Habit extends Model
|
|||||||
public static void setColor(@NonNull List<Habit> habits, int color)
|
public static void setColor(@NonNull List<Habit> habits, int color)
|
||||||
{
|
{
|
||||||
updateAttributes(habits, color, null);
|
updateAttributes(habits, color, null);
|
||||||
|
for(Habit h : habits)
|
||||||
|
h.observable.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -476,6 +484,7 @@ public class Habit extends Model
|
|||||||
reminderHour = null;
|
reminderHour = null;
|
||||||
reminderMin = null;
|
reminderMin = null;
|
||||||
reminderDays = DateUtils.ALL_WEEK_DAYS;
|
reminderDays = DateUtils.ALL_WEEK_DAYS;
|
||||||
|
observable.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ public class RepetitionList
|
|||||||
{
|
{
|
||||||
@NonNull
|
@NonNull
|
||||||
private Habit habit;
|
private Habit habit;
|
||||||
|
public ModelObservable observable = new ModelObservable();
|
||||||
|
|
||||||
public RepetitionList(@NonNull Habit habit)
|
public RepetitionList(@NonNull Habit habit)
|
||||||
{
|
{
|
||||||
@@ -105,6 +106,7 @@ public class RepetitionList
|
|||||||
habit.scores.invalidateNewerThan(timestamp);
|
habit.scores.invalidateNewerThan(timestamp);
|
||||||
habit.checkmarks.deleteNewerThan(timestamp);
|
habit.checkmarks.deleteNewerThan(timestamp);
|
||||||
habit.streaks.deleteNewerThan(timestamp);
|
habit.streaks.deleteNewerThan(timestamp);
|
||||||
|
observable.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insert(long timestamp)
|
private void insert(long timestamp)
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public class ScoreList
|
|||||||
{
|
{
|
||||||
@NonNull
|
@NonNull
|
||||||
private Habit habit;
|
private Habit habit;
|
||||||
|
public ModelObservable observable = new ModelObservable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new ScoreList associated with the given habit.
|
* Constructs a new ScoreList associated with the given habit.
|
||||||
@@ -75,6 +76,8 @@ public class ScoreList
|
|||||||
.where("habit = ?", habit.getId())
|
.where("habit = ?", habit.getId())
|
||||||
.and("timestamp >= ?", timestamp)
|
.and("timestamp >= ?", timestamp)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
|
observable.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import java.util.List;
|
|||||||
public class StreakList
|
public class StreakList
|
||||||
{
|
{
|
||||||
private Habit habit;
|
private Habit habit;
|
||||||
|
public ModelObservable observable = new ModelObservable();
|
||||||
|
|
||||||
public StreakList(Habit habit)
|
public StreakList(Habit habit)
|
||||||
{
|
{
|
||||||
@@ -156,5 +157,7 @@ public class StreakList
|
|||||||
.where("habit = ?", habit.getId())
|
.where("habit = ?", habit.getId())
|
||||||
.and("end >= ?", timestamp - DateUtils.millisecondsInOneDay)
|
.and("end >= ?", timestamp - DateUtils.millisecondsInOneDay)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
|
observable.notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
package org.isoron.uhabits.tasks;
|
package org.isoron.uhabits.tasks;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.commands.CommandRunner;
|
||||||
|
import org.isoron.uhabits.commands.ToggleRepetitionCommand;
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
|
|
||||||
public class ToggleRepetitionTask extends BaseTask
|
public class ToggleRepetitionTask extends BaseTask
|
||||||
@@ -40,7 +42,8 @@ public class ToggleRepetitionTask extends BaseTask
|
|||||||
@Override
|
@Override
|
||||||
protected void doInBackground()
|
protected void doInBackground()
|
||||||
{
|
{
|
||||||
habit.repetitions.toggle(timestamp);
|
ToggleRepetitionCommand command = new ToggleRepetitionCommand(habit, timestamp);
|
||||||
|
CommandRunner.getInstance().execute(command, habit.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -20,9 +20,9 @@
|
|||||||
package org.isoron.uhabits.ui;
|
package org.isoron.uhabits.ui;
|
||||||
|
|
||||||
import android.app.backup.BackupManager;
|
import android.app.backup.BackupManager;
|
||||||
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
@@ -31,20 +31,21 @@ import android.support.v7.widget.Toolbar;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.HabitBroadcastReceiver;
|
||||||
import org.isoron.uhabits.HabitsApplication;
|
import org.isoron.uhabits.HabitsApplication;
|
||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.R;
|
||||||
import org.isoron.uhabits.commands.Command;
|
import org.isoron.uhabits.commands.Command;
|
||||||
|
import org.isoron.uhabits.commands.CommandRunner;
|
||||||
|
import org.isoron.uhabits.models.Checkmark;
|
||||||
|
import org.isoron.uhabits.models.Habit;
|
||||||
|
import org.isoron.uhabits.tasks.BaseTask;
|
||||||
import org.isoron.uhabits.utils.ColorUtils;
|
import org.isoron.uhabits.utils.ColorUtils;
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||||
|
import org.isoron.uhabits.widgets.WidgetManager;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
abstract public class BaseActivity extends AppCompatActivity implements Thread.UncaughtExceptionHandler,
|
||||||
|
CommandRunner.Listener
|
||||||
abstract public class BaseActivity extends AppCompatActivity implements Thread.UncaughtExceptionHandler
|
|
||||||
{
|
{
|
||||||
private static int MAX_UNDO_LEVEL = 15;
|
|
||||||
|
|
||||||
private LinkedList<Command> undoList;
|
|
||||||
private LinkedList<Command> redoList;
|
|
||||||
private Toast toast;
|
private Toast toast;
|
||||||
|
|
||||||
Thread.UncaughtExceptionHandler androidExceptionHandler;
|
Thread.UncaughtExceptionHandler androidExceptionHandler;
|
||||||
@@ -58,39 +59,20 @@ abstract public class BaseActivity extends AppCompatActivity implements Thread.U
|
|||||||
|
|
||||||
androidExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
|
androidExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
|
||||||
Thread.setDefaultUncaughtExceptionHandler(this);
|
Thread.setDefaultUncaughtExceptionHandler(this);
|
||||||
|
|
||||||
undoList = new LinkedList<>();
|
|
||||||
redoList = new LinkedList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeCommand(Command command, Long refreshKey)
|
@Override
|
||||||
|
protected void onResume()
|
||||||
{
|
{
|
||||||
executeCommand(command, false, refreshKey);
|
super.onResume();
|
||||||
|
CommandRunner.getInstance().addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void undo()
|
@Override
|
||||||
|
protected void onPause()
|
||||||
{
|
{
|
||||||
if (undoList.isEmpty())
|
CommandRunner.getInstance().removeListener(this);
|
||||||
{
|
super.onPause();
|
||||||
showMessage(R.string.toast_nothing_to_undo);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Command last = undoList.pop();
|
|
||||||
redoList.push(last);
|
|
||||||
last.undo();
|
|
||||||
showMessage(last.getUndoStringId());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void redo()
|
|
||||||
{
|
|
||||||
if (redoList.isEmpty())
|
|
||||||
{
|
|
||||||
showMessage(R.string.toast_nothing_to_redo);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Command last = redoList.pop();
|
|
||||||
executeCommand(last, false, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showMessage(Integer stringId)
|
public void showMessage(Integer stringId)
|
||||||
@@ -101,34 +83,6 @@ abstract public class BaseActivity extends AppCompatActivity implements Thread.U
|
|||||||
toast.show();
|
toast.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeCommand(final Command command, Boolean clearRedoStack, final Long refreshKey)
|
|
||||||
{
|
|
||||||
undoList.push(command);
|
|
||||||
|
|
||||||
if (undoList.size() > MAX_UNDO_LEVEL) undoList.removeLast();
|
|
||||||
if (clearRedoStack) redoList.clear();
|
|
||||||
|
|
||||||
new AsyncTask<Void, Void, Void>()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Void... params)
|
|
||||||
{
|
|
||||||
command.execute();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Void aVoid)
|
|
||||||
{
|
|
||||||
BaseActivity.this.onPostExecuteCommand(refreshKey);
|
|
||||||
BackupManager.dataChanged("org.isoron.uhabits");
|
|
||||||
}
|
|
||||||
}.execute();
|
|
||||||
|
|
||||||
|
|
||||||
showMessage(command.getExecuteStringId());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setupSupportActionBar(boolean homeButtonEnabled)
|
protected void setupSupportActionBar(boolean homeButtonEnabled)
|
||||||
{
|
{
|
||||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
@@ -146,10 +100,6 @@ abstract public class BaseActivity extends AppCompatActivity implements Thread.U
|
|||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPostExecuteCommand(Long refreshKey)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void uncaughtException(Thread thread, Throwable ex)
|
public void uncaughtException(Thread thread, Throwable ex)
|
||||||
{
|
{
|
||||||
@@ -203,4 +153,29 @@ abstract public class BaseActivity extends AppCompatActivity implements Thread.U
|
|||||||
view = findViewById(R.id.headerShadow);
|
view = findViewById(R.id.headerShadow);
|
||||||
if(view != null) view.setVisibility(View.GONE);
|
if(view != null) view.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void dismissNotifications(Context context)
|
||||||
|
{
|
||||||
|
for(Habit h : Habit.getHabitsWithReminder())
|
||||||
|
{
|
||||||
|
if(h.checkmarks.getTodayValue() != Checkmark.UNCHECKED)
|
||||||
|
HabitBroadcastReceiver.dismissNotification(context, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCommandExecuted(Command command, Long refreshKey)
|
||||||
|
{
|
||||||
|
showMessage(command.getExecuteStringId());
|
||||||
|
new BaseTask()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void doInBackground()
|
||||||
|
{
|
||||||
|
dismissNotifications(BaseActivity.this);
|
||||||
|
BackupManager.dataChanged("org.isoron.uhabits");
|
||||||
|
WidgetManager.updateWidgets(BaseActivity.this);
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,12 +42,12 @@ import com.android.datetimepicker.time.TimePickerDialog;
|
|||||||
|
|
||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.R;
|
||||||
import org.isoron.uhabits.commands.Command;
|
import org.isoron.uhabits.commands.Command;
|
||||||
|
import org.isoron.uhabits.commands.CommandRunner;
|
||||||
import org.isoron.uhabits.commands.CreateHabitCommand;
|
import org.isoron.uhabits.commands.CreateHabitCommand;
|
||||||
import org.isoron.uhabits.commands.EditHabitCommand;
|
import org.isoron.uhabits.commands.EditHabitCommand;
|
||||||
import org.isoron.uhabits.utils.DateUtils;
|
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
import org.isoron.uhabits.utils.ColorUtils;
|
import org.isoron.uhabits.utils.ColorUtils;
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
import org.isoron.uhabits.utils.DateUtils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -59,8 +59,6 @@ public class EditHabitDialogFragment extends AppCompatDialogFragment
|
|||||||
static final int EDIT_MODE = 0;
|
static final int EDIT_MODE = 0;
|
||||||
static final int CREATE_MODE = 1;
|
static final int CREATE_MODE = 1;
|
||||||
|
|
||||||
private InterfaceUtils.OnSavedListener onSavedListener;
|
|
||||||
|
|
||||||
private Habit originalHabit;
|
private Habit originalHabit;
|
||||||
private Habit modifiedHabit;
|
private Habit modifiedHabit;
|
||||||
|
|
||||||
@@ -202,11 +200,6 @@ public class EditHabitDialogFragment extends AppCompatDialogFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnSavedListener(InterfaceUtils.OnSavedListener onSavedListener)
|
|
||||||
{
|
|
||||||
this.onSavedListener = onSavedListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v)
|
public void onClick(View v)
|
||||||
{
|
{
|
||||||
@@ -264,21 +257,17 @@ public class EditHabitDialogFragment extends AppCompatDialogFragment
|
|||||||
|
|
||||||
if (!validate()) return;
|
if (!validate()) return;
|
||||||
|
|
||||||
Command command = null;
|
|
||||||
Habit savedHabit = null;
|
|
||||||
|
|
||||||
if (mode == EDIT_MODE)
|
if (mode == EDIT_MODE)
|
||||||
{
|
{
|
||||||
command = new EditHabitCommand(originalHabit, modifiedHabit);
|
Command command = new EditHabitCommand(originalHabit, modifiedHabit);
|
||||||
savedHabit = originalHabit;
|
CommandRunner.getInstance().execute(command, originalHabit.getId());
|
||||||
}
|
}
|
||||||
else if (mode == CREATE_MODE)
|
else if (mode == CREATE_MODE)
|
||||||
{
|
{
|
||||||
command = new CreateHabitCommand(modifiedHabit);
|
Command command = new CreateHabitCommand(modifiedHabit);
|
||||||
|
CommandRunner.getInstance().execute(command, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onSavedListener != null) onSavedListener.onSaved(command, savedHabit);
|
|
||||||
|
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ package org.isoron.uhabits.ui.habits.list;
|
|||||||
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.commands.Command;
|
||||||
|
import org.isoron.uhabits.commands.CommandRunner;
|
||||||
import org.isoron.uhabits.utils.DateUtils;
|
import org.isoron.uhabits.utils.DateUtils;
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
import org.isoron.uhabits.tasks.BaseTask;
|
import org.isoron.uhabits.tasks.BaseTask;
|
||||||
@@ -28,7 +30,7 @@ import org.isoron.uhabits.tasks.BaseTask;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class HabitListLoader
|
public class HabitListLoader implements CommandRunner.Listener
|
||||||
{
|
{
|
||||||
public interface Listener
|
public interface Listener
|
||||||
{
|
{
|
||||||
@@ -201,4 +203,21 @@ public class HabitListLoader
|
|||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onResume()
|
||||||
|
{
|
||||||
|
CommandRunner.getInstance().addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPause()
|
||||||
|
{
|
||||||
|
CommandRunner.getInstance().removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCommandExecuted(Command command, Long refreshKey)
|
||||||
|
{
|
||||||
|
if(refreshKey == null) updateAllHabits(true);
|
||||||
|
else updateHabit(refreshKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ import com.android.colorpicker.ColorPickerSwatch;
|
|||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.R;
|
||||||
import org.isoron.uhabits.commands.ArchiveHabitsCommand;
|
import org.isoron.uhabits.commands.ArchiveHabitsCommand;
|
||||||
import org.isoron.uhabits.commands.ChangeHabitColorCommand;
|
import org.isoron.uhabits.commands.ChangeHabitColorCommand;
|
||||||
|
import org.isoron.uhabits.commands.CommandRunner;
|
||||||
import org.isoron.uhabits.commands.DeleteHabitsCommand;
|
import org.isoron.uhabits.commands.DeleteHabitsCommand;
|
||||||
import org.isoron.uhabits.commands.UnarchiveHabitsCommand;
|
import org.isoron.uhabits.commands.UnarchiveHabitsCommand;
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
import org.isoron.uhabits.ui.BaseActivity;
|
import org.isoron.uhabits.ui.BaseActivity;
|
||||||
import org.isoron.uhabits.ui.habits.edit.EditHabitDialogFragment;
|
import org.isoron.uhabits.ui.habits.edit.EditHabitDialogFragment;
|
||||||
import org.isoron.uhabits.utils.ColorUtils;
|
import org.isoron.uhabits.utils.ColorUtils;
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -48,7 +48,6 @@ public class HabitListSelectionCallback implements ActionMode.Callback
|
|||||||
private List<Integer> selectedPositions;
|
private List<Integer> selectedPositions;
|
||||||
private BaseActivity activity;
|
private BaseActivity activity;
|
||||||
private Listener listener;
|
private Listener listener;
|
||||||
private InterfaceUtils.OnSavedListener onSavedListener;
|
|
||||||
|
|
||||||
public interface Listener
|
public interface Listener
|
||||||
{
|
{
|
||||||
@@ -67,11 +66,6 @@ public class HabitListSelectionCallback implements ActionMode.Callback
|
|||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnSavedListener(InterfaceUtils.OnSavedListener onSavedListener)
|
|
||||||
{
|
|
||||||
this.onSavedListener = onSavedListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSelectedPositions(List<Integer> selectedPositions)
|
public void setSelectedPositions(List<Integer> selectedPositions)
|
||||||
{
|
{
|
||||||
this.selectedPositions = selectedPositions;
|
this.selectedPositions = selectedPositions;
|
||||||
@@ -134,64 +128,33 @@ public class HabitListSelectionCallback implements ActionMode.Callback
|
|||||||
switch (item.getItemId())
|
switch (item.getItemId())
|
||||||
{
|
{
|
||||||
case R.id.action_archive_habit:
|
case R.id.action_archive_habit:
|
||||||
activity.executeCommand(new ArchiveHabitsCommand(selectedHabits), null);
|
archiveHabits(selectedHabits);
|
||||||
mode.finish();
|
mode.finish();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.action_unarchive_habit:
|
case R.id.action_unarchive_habit:
|
||||||
activity.executeCommand(new UnarchiveHabitsCommand(selectedHabits), null);
|
unarchiveHabits(selectedHabits);
|
||||||
mode.finish();
|
mode.finish();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.action_edit_habit:
|
case R.id.action_edit_habit:
|
||||||
{
|
{
|
||||||
EditHabitDialogFragment
|
editHabit(firstHabit);
|
||||||
frag = EditHabitDialogFragment.editSingleHabitFragment(firstHabit.getId());
|
mode.finish();
|
||||||
frag.setOnSavedListener(onSavedListener);
|
|
||||||
frag.show(activity.getSupportFragmentManager(), "editHabit");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case R.id.action_color:
|
case R.id.action_color:
|
||||||
{
|
{
|
||||||
int originalAndroidColor = ColorUtils.getColor(activity, firstHabit.color);
|
showColorPicker(mode, selectedHabits, firstHabit);
|
||||||
|
mode.finish();
|
||||||
ColorPickerDialog picker = ColorPickerDialog.newInstance(
|
|
||||||
R.string.color_picker_default_title, ColorUtils.getPalette(activity),
|
|
||||||
originalAndroidColor, 4, ColorPickerDialog.SIZE_SMALL);
|
|
||||||
|
|
||||||
picker.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener()
|
|
||||||
{
|
|
||||||
public void onColorSelected(int androidColor)
|
|
||||||
{
|
|
||||||
int paletteColor = ColorUtils.colorToPaletteIndex(activity,
|
|
||||||
androidColor);
|
|
||||||
activity.executeCommand(new ChangeHabitColorCommand(selectedHabits,
|
|
||||||
paletteColor), null);
|
|
||||||
mode.finish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
picker.show(activity.getSupportFragmentManager(), "picker");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case R.id.action_delete:
|
case R.id.action_delete:
|
||||||
{
|
{
|
||||||
new AlertDialog.Builder(activity).setTitle(R.string.delete_habits)
|
deleteHabits(mode, selectedHabits);
|
||||||
.setMessage(R.string.delete_habits_message)
|
mode.finish();
|
||||||
.setPositiveButton(android.R.string.yes,
|
|
||||||
new DialogInterface.OnClickListener()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which)
|
|
||||||
{
|
|
||||||
activity.executeCommand(
|
|
||||||
new DeleteHabitsCommand(selectedHabits), null);
|
|
||||||
mode.finish();
|
|
||||||
}
|
|
||||||
}).setNegativeButton(android.R.string.no, null)
|
|
||||||
.show();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,6 +162,64 @@ public class HabitListSelectionCallback implements ActionMode.Callback
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void deleteHabits(final ActionMode mode, final LinkedList<Habit> selectedHabits)
|
||||||
|
{
|
||||||
|
new AlertDialog.Builder(activity).setTitle(R.string.delete_habits)
|
||||||
|
.setMessage(R.string.delete_habits_message)
|
||||||
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which)
|
||||||
|
{
|
||||||
|
CommandRunner.getInstance()
|
||||||
|
.execute(new DeleteHabitsCommand(selectedHabits), null);
|
||||||
|
mode.finish();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(android.R.string.no, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showColorPicker(final ActionMode mode, final LinkedList<Habit> selectedHabits,
|
||||||
|
Habit firstHabit)
|
||||||
|
{
|
||||||
|
int originalAndroidColor = ColorUtils.getColor(activity, firstHabit.color);
|
||||||
|
|
||||||
|
ColorPickerDialog picker =
|
||||||
|
ColorPickerDialog.newInstance(R.string.color_picker_default_title,
|
||||||
|
ColorUtils.getPalette(activity), originalAndroidColor, 4,
|
||||||
|
ColorPickerDialog.SIZE_SMALL);
|
||||||
|
|
||||||
|
picker.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener()
|
||||||
|
{
|
||||||
|
public void onColorSelected(int androidColor)
|
||||||
|
{
|
||||||
|
int paletteColor = ColorUtils.colorToPaletteIndex(activity, androidColor);
|
||||||
|
CommandRunner.getInstance()
|
||||||
|
.execute(new ChangeHabitColorCommand(selectedHabits, paletteColor), null);
|
||||||
|
mode.finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
picker.show(activity.getSupportFragmentManager(), "picker");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void editHabit(Habit habit)
|
||||||
|
{
|
||||||
|
EditHabitDialogFragment
|
||||||
|
frag = EditHabitDialogFragment.editSingleHabitFragment(habit.getId());
|
||||||
|
frag.show(activity.getSupportFragmentManager(), "editHabit");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unarchiveHabits(LinkedList<Habit> selectedHabits)
|
||||||
|
{
|
||||||
|
CommandRunner.getInstance().execute(new UnarchiveHabitsCommand(selectedHabits), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void archiveHabits(LinkedList<Habit> selectedHabits)
|
||||||
|
{
|
||||||
|
CommandRunner.getInstance().execute(new ArchiveHabitsCommand(selectedHabits), null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyActionMode(ActionMode mode)
|
public void onDestroyActionMode(ActionMode mode)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,17 +35,15 @@ import android.widget.ProgressBar;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.R;
|
||||||
import org.isoron.uhabits.commands.Command;
|
import org.isoron.uhabits.commands.CommandRunner;
|
||||||
import org.isoron.uhabits.commands.ToggleRepetitionCommand;
|
import org.isoron.uhabits.commands.ToggleRepetitionCommand;
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
import org.isoron.uhabits.ui.BaseActivity;
|
import org.isoron.uhabits.ui.BaseActivity;
|
||||||
import org.isoron.uhabits.ui.HintManager;
|
import org.isoron.uhabits.ui.HintManager;
|
||||||
import org.isoron.uhabits.ui.habits.edit.EditHabitDialogFragment;
|
import org.isoron.uhabits.ui.habits.edit.EditHabitDialogFragment;
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils.OnSavedListener;
|
|
||||||
import org.isoron.uhabits.utils.ReminderUtils;
|
|
||||||
|
|
||||||
public class ListHabitsFragment extends Fragment implements OnSavedListener, OnClickListener,
|
public class ListHabitsFragment extends Fragment implements OnClickListener,
|
||||||
HabitListSelectionCallback.Listener, ListHabitsController.Screen
|
HabitListSelectionCallback.Listener, ListHabitsController.Screen
|
||||||
{
|
{
|
||||||
private ActionMode actionMode;
|
private ActionMode actionMode;
|
||||||
@@ -84,7 +82,6 @@ public class ListHabitsFragment extends Fragment implements OnSavedListener, OnC
|
|||||||
{
|
{
|
||||||
EditHabitDialogFragment frag = (EditHabitDialogFragment) getFragmentManager()
|
EditHabitDialogFragment frag = (EditHabitDialogFragment) getFragmentManager()
|
||||||
.findFragmentByTag("editHabit");
|
.findFragmentByTag("editHabit");
|
||||||
if(frag != null) frag.setOnSavedListener(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
@@ -104,12 +101,20 @@ public class ListHabitsFragment extends Fragment implements OnSavedListener, OnC
|
|||||||
{
|
{
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
|
listView.getLoader().onResume();
|
||||||
listView.refreshData(null);
|
listView.refreshData(null);
|
||||||
helper.updateEmptyMessage(llEmpty);
|
helper.updateEmptyMessage(llEmpty);
|
||||||
helper.updateHeader(llButtonsHeader);
|
helper.updateHeader(llButtonsHeader);
|
||||||
hintManager.showHintIfAppropriate();
|
hintManager.showHintIfAppropriate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause()
|
||||||
|
{
|
||||||
|
listView.getLoader().onPause();
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
|
||||||
{
|
{
|
||||||
@@ -146,7 +151,6 @@ public class ListHabitsFragment extends Fragment implements OnSavedListener, OnC
|
|||||||
private void showCreateHabitScreen()
|
private void showCreateHabitScreen()
|
||||||
{
|
{
|
||||||
EditHabitDialogFragment frag = EditHabitDialogFragment.createHabitFragment();
|
EditHabitDialogFragment frag = EditHabitDialogFragment.createHabitFragment();
|
||||||
frag.setOnSavedListener(this);
|
|
||||||
frag.show(getFragmentManager(), "editHabit");
|
frag.show(getFragmentManager(), "editHabit");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +159,6 @@ public class ListHabitsFragment extends Fragment implements OnSavedListener, OnC
|
|||||||
HabitListSelectionCallback callback =
|
HabitListSelectionCallback callback =
|
||||||
new HabitListSelectionCallback(activity, listView.getLoader());
|
new HabitListSelectionCallback(activity, listView.getLoader());
|
||||||
callback.setSelectedPositions(listView.getSelectedPositions());
|
callback.setSelectedPositions(listView.getSelectedPositions());
|
||||||
callback.setOnSavedListener(this);
|
|
||||||
callback.setListener(this);
|
callback.setListener(this);
|
||||||
actionMode = activity.startSupportActionMode(callback);
|
actionMode = activity.startSupportActionMode(callback);
|
||||||
}
|
}
|
||||||
@@ -172,26 +175,6 @@ public class ListHabitsFragment extends Fragment implements OnSavedListener, OnC
|
|||||||
listView.cancelSelection();
|
listView.cancelSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaved(Command command, Object savedObject)
|
|
||||||
{
|
|
||||||
Habit h = (Habit) savedObject;
|
|
||||||
|
|
||||||
if (h == null) activity.executeCommand(command, null);
|
|
||||||
else activity.executeCommand(command, h.getId());
|
|
||||||
|
|
||||||
listView.refreshData(null);
|
|
||||||
|
|
||||||
ReminderUtils.createReminderAlarms(activity);
|
|
||||||
|
|
||||||
finishActionMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeCommand(Command c, Long refreshKey)
|
|
||||||
{
|
|
||||||
activity.executeCommand(c, refreshKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v)
|
public void onClick(View v)
|
||||||
{
|
{
|
||||||
@@ -199,11 +182,6 @@ public class ListHabitsFragment extends Fragment implements OnSavedListener, OnC
|
|||||||
hintManager.dismissHint();
|
hintManager.dismissHint();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPostExecuteCommand(Long refreshKey)
|
|
||||||
{
|
|
||||||
listView.refreshData(refreshKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProgressBar getProgressBar()
|
public ProgressBar getProgressBar()
|
||||||
{
|
{
|
||||||
return progressBar;
|
return progressBar;
|
||||||
@@ -224,7 +202,8 @@ public class ListHabitsFragment extends Fragment implements OnSavedListener, OnC
|
|||||||
@Override
|
@Override
|
||||||
public void onToggleCheckmark(Habit habit, long timestamp)
|
public void onToggleCheckmark(Habit habit, long timestamp)
|
||||||
{
|
{
|
||||||
executeCommand(new ToggleRepetitionCommand(habit, timestamp), habit.getId());
|
CommandRunner.getInstance().execute(new ToggleRepetitionCommand(habit, timestamp),
|
||||||
|
habit.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -42,12 +42,11 @@ public class ShowHabitActivity extends BaseActivity
|
|||||||
habit = Habit.get(ContentUris.parseId(data));
|
habit = Habit.get(ContentUris.parseId(data));
|
||||||
|
|
||||||
setContentView(R.layout.show_habit_activity);
|
setContentView(R.layout.show_habit_activity);
|
||||||
|
|
||||||
setupSupportActionBar(true);
|
setupSupportActionBar(true);
|
||||||
setupHabitActionBar();
|
setupHabitActionBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupHabitActionBar()
|
public void setupHabitActionBar()
|
||||||
{
|
{
|
||||||
if(habit == null) return;
|
if(habit == null) return;
|
||||||
|
|
||||||
@@ -55,7 +54,6 @@ public class ShowHabitActivity extends BaseActivity
|
|||||||
if(actionBar == null) return;
|
if(actionBar == null) return;
|
||||||
|
|
||||||
actionBar.setTitle(habit.name);
|
actionBar.setTitle(habit.name);
|
||||||
|
|
||||||
setupActionBarColor(ColorUtils.getColor(this, habit.color));
|
setupActionBarColor(ColorUtils.getColor(this, habit.color));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,60 +31,42 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import org.isoron.uhabits.HabitBroadcastReceiver;
|
|
||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.R;
|
||||||
import org.isoron.uhabits.commands.Command;
|
import org.isoron.uhabits.models.Habit;
|
||||||
|
import org.isoron.uhabits.models.ModelObservable;
|
||||||
|
import org.isoron.uhabits.tasks.BaseTask;
|
||||||
import org.isoron.uhabits.ui.habits.edit.EditHabitDialogFragment;
|
import org.isoron.uhabits.ui.habits.edit.EditHabitDialogFragment;
|
||||||
import org.isoron.uhabits.ui.habits.edit.HistoryEditorDialog;
|
import org.isoron.uhabits.ui.habits.edit.HistoryEditorDialog;
|
||||||
import org.isoron.uhabits.utils.ColorUtils;
|
|
||||||
import org.isoron.uhabits.utils.DateUtils;
|
import org.isoron.uhabits.utils.DateUtils;
|
||||||
import org.isoron.uhabits.utils.ReminderUtils;
|
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||||
import org.isoron.uhabits.models.Habit;
|
|
||||||
import org.isoron.uhabits.models.Score;
|
|
||||||
import org.isoron.uhabits.tasks.BaseTask;
|
|
||||||
import org.isoron.uhabits.views.HabitDataView;
|
import org.isoron.uhabits.views.HabitDataView;
|
||||||
import org.isoron.uhabits.views.HabitFrequencyView;
|
import org.isoron.uhabits.views.HabitFrequencyView;
|
||||||
import org.isoron.uhabits.views.HabitHistoryView;
|
import org.isoron.uhabits.views.HabitHistoryView;
|
||||||
import org.isoron.uhabits.views.HabitScoreView;
|
import org.isoron.uhabits.views.HabitScoreView;
|
||||||
import org.isoron.uhabits.views.HabitStreakView;
|
import org.isoron.uhabits.views.HabitStreakView;
|
||||||
import org.isoron.uhabits.views.RingView;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ShowHabitFragment extends Fragment
|
public class ShowHabitFragment extends Fragment
|
||||||
implements InterfaceUtils.OnSavedListener, HistoryEditorDialog.Listener,
|
implements Spinner.OnItemSelectedListener, ModelObservable.Listener
|
||||||
Spinner.OnItemSelectedListener
|
|
||||||
{
|
{
|
||||||
@Nullable
|
|
||||||
protected ShowHabitActivity activity;
|
protected ShowHabitActivity activity;
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private Habit habit;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private List<HabitDataView> dataViews;
|
private List<HabitDataView> dataViews;
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private HabitScoreView scoreView;
|
|
||||||
|
|
||||||
private int previousScoreInterval;
|
private int previousScoreInterval;
|
||||||
|
|
||||||
private float todayScore;
|
Habit habit;
|
||||||
private float lastMonthScore;
|
|
||||||
private float lastYearScore;
|
|
||||||
|
|
||||||
private int activeColor;
|
float todayScore;
|
||||||
private int inactiveColor;
|
float lastMonthScore;
|
||||||
|
float lastYearScore;
|
||||||
|
int activeColor;
|
||||||
|
int inactiveColor;
|
||||||
|
|
||||||
@Override
|
private ShowHabitHelper helper;
|
||||||
public void onStart()
|
|
||||||
{
|
|
||||||
super.onStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
@@ -92,37 +74,32 @@ public class ShowHabitFragment extends Fragment
|
|||||||
{
|
{
|
||||||
View view = inflater.inflate(R.layout.show_habit, container, false);
|
View view = inflater.inflate(R.layout.show_habit, container, false);
|
||||||
activity = (ShowHabitActivity) getActivity();
|
activity = (ShowHabitActivity) getActivity();
|
||||||
|
helper = new ShowHabitHelper(this);
|
||||||
|
|
||||||
habit = activity.getHabit();
|
habit = activity.getHabit();
|
||||||
activeColor = ColorUtils.getColor(getContext(), habit.color);
|
helper.updateColors();
|
||||||
inactiveColor = InterfaceUtils.getStyledColor(getContext(), R.attr.mediumContrastTextColor);
|
helper.updateMainHeader(view);
|
||||||
|
|
||||||
updateHeader(view);
|
|
||||||
|
|
||||||
dataViews = new LinkedList<>();
|
|
||||||
|
|
||||||
Button btEditHistory = (Button) view.findViewById(R.id.btEditHistory);
|
|
||||||
Spinner sStrengthInterval = (Spinner) view.findViewById(R.id.sStrengthInterval);
|
|
||||||
|
|
||||||
scoreView = (HabitScoreView) view.findViewById(R.id.scoreView);
|
|
||||||
|
|
||||||
int defaultScoreInterval = InterfaceUtils.getDefaultScoreInterval(getContext());
|
int defaultScoreInterval = InterfaceUtils.getDefaultScoreInterval(getContext());
|
||||||
previousScoreInterval = defaultScoreInterval;
|
previousScoreInterval = defaultScoreInterval;
|
||||||
setScoreBucketSize(defaultScoreInterval);
|
setScoreBucketSize(defaultScoreInterval);
|
||||||
|
|
||||||
|
Spinner sStrengthInterval = (Spinner) view.findViewById(R.id.sStrengthInterval);
|
||||||
sStrengthInterval.setSelection(defaultScoreInterval);
|
sStrengthInterval.setSelection(defaultScoreInterval);
|
||||||
sStrengthInterval.setOnItemSelectedListener(this);
|
sStrengthInterval.setOnItemSelectedListener(this);
|
||||||
|
|
||||||
dataViews.add((HabitScoreView) view.findViewById(R.id.scoreView));
|
createDataViews(view);
|
||||||
dataViews.add((HabitHistoryView) view.findViewById(R.id.historyView));
|
helper.updateCardHeaders(view);
|
||||||
dataViews.add((HabitFrequencyView) view.findViewById(R.id.punchcardView));
|
|
||||||
dataViews.add((HabitStreakView) view.findViewById(R.id.streakView));
|
|
||||||
|
|
||||||
updateHeaders(view);
|
bindButtontEditHistory(view);
|
||||||
|
setHasOptionsMenu(true);
|
||||||
|
|
||||||
for(HabitDataView dataView : dataViews)
|
return view;
|
||||||
dataView.setHabit(habit);
|
}
|
||||||
|
|
||||||
|
private void bindButtontEditHistory(View view)
|
||||||
|
{
|
||||||
|
Button btEditHistory = (Button) view.findViewById(R.id.btEditHistory);
|
||||||
btEditHistory.setOnClickListener(new View.OnClickListener()
|
btEditHistory.setOnClickListener(new View.OnClickListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
@@ -130,75 +107,21 @@ public class ShowHabitFragment extends Fragment
|
|||||||
{
|
{
|
||||||
HistoryEditorDialog frag = new HistoryEditorDialog();
|
HistoryEditorDialog frag = new HistoryEditorDialog();
|
||||||
frag.setHabit(habit);
|
frag.setHabit(habit);
|
||||||
frag.setListener(ShowHabitFragment.this);
|
|
||||||
frag.show(getFragmentManager(), "historyEditor");
|
frag.show(getFragmentManager(), "historyEditor");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(savedInstanceState != null)
|
|
||||||
{
|
|
||||||
EditHabitDialogFragment fragEdit = (EditHabitDialogFragment) getFragmentManager()
|
|
||||||
.findFragmentByTag("editHabit");
|
|
||||||
HistoryEditorDialog fragEditor = (HistoryEditorDialog) getFragmentManager()
|
|
||||||
.findFragmentByTag("historyEditor");
|
|
||||||
|
|
||||||
if(fragEdit != null) fragEdit.setOnSavedListener(this);
|
|
||||||
if(fragEditor != null) fragEditor.setListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
setHasOptionsMenu(true);
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateHeader(View view)
|
private void createDataViews(View view)
|
||||||
{
|
{
|
||||||
if(habit == null) return;
|
dataViews = new LinkedList<>();
|
||||||
|
dataViews.add((HabitScoreView) view.findViewById(R.id.scoreView));
|
||||||
|
dataViews.add((HabitHistoryView) view.findViewById(R.id.historyView));
|
||||||
|
dataViews.add((HabitFrequencyView) view.findViewById(R.id.punchcardView));
|
||||||
|
dataViews.add((HabitStreakView) view.findViewById(R.id.streakView));
|
||||||
|
|
||||||
TextView questionLabel = (TextView) view.findViewById(R.id.questionLabel);
|
for(HabitDataView dataView : dataViews)
|
||||||
questionLabel.setTextColor(activeColor);
|
dataView.setHabit(habit);
|
||||||
questionLabel.setText(habit.description);
|
|
||||||
|
|
||||||
TextView reminderLabel = (TextView) view.findViewById(R.id.reminderLabel);
|
|
||||||
if(habit.hasReminder())
|
|
||||||
reminderLabel.setText(DateUtils.formatTime(getActivity(), habit.reminderHour,
|
|
||||||
habit.reminderMin));
|
|
||||||
else
|
|
||||||
reminderLabel.setText(getResources().getString(R.string.reminder_off));
|
|
||||||
|
|
||||||
TextView frequencyLabel = (TextView) view.findViewById(R.id.frequencyLabel);
|
|
||||||
frequencyLabel.setText(getFreqText());
|
|
||||||
|
|
||||||
if(habit.description.isEmpty())
|
|
||||||
questionLabel.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getFreqText()
|
|
||||||
{
|
|
||||||
if(habit == null)
|
|
||||||
return "";
|
|
||||||
|
|
||||||
if(habit.freqNum.equals(habit.freqDen))
|
|
||||||
return getResources().getString(R.string.every_day);
|
|
||||||
|
|
||||||
if(habit.freqNum == 1)
|
|
||||||
{
|
|
||||||
if (habit.freqDen == 7)
|
|
||||||
return getResources().getString(R.string.every_week);
|
|
||||||
|
|
||||||
if (habit.freqDen % 7 == 0)
|
|
||||||
return getResources().getString(R.string.every_x_weeks, habit.freqDen / 7);
|
|
||||||
|
|
||||||
return getResources().getString(R.string.every_x_days, habit.freqDen);
|
|
||||||
}
|
|
||||||
|
|
||||||
String times_every = getResources().getString(R.string.times_every);
|
|
||||||
|
|
||||||
if(habit.freqNum == 1)
|
|
||||||
times_every = getResources().getString(R.string.time_every);
|
|
||||||
|
|
||||||
return String.format("%d %s %d %s", habit.freqNum, times_every, habit.freqDen,
|
|
||||||
getResources().getString(R.string.days));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -208,55 +131,6 @@ public class ShowHabitFragment extends Fragment
|
|||||||
refreshData();
|
refreshData();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateScore(View view)
|
|
||||||
{
|
|
||||||
if(habit == null) return;
|
|
||||||
if(view == null) return;
|
|
||||||
|
|
||||||
float todayPercentage = todayScore / Score.MAX_VALUE;
|
|
||||||
float monthDiff = todayPercentage - (lastMonthScore / Score.MAX_VALUE);
|
|
||||||
float yearDiff = todayPercentage - (lastYearScore / Score.MAX_VALUE);
|
|
||||||
|
|
||||||
RingView scoreRing = (RingView) view.findViewById(R.id.scoreRing);
|
|
||||||
int androidColor = ColorUtils.getColor(getActivity(), habit.color);
|
|
||||||
scoreRing.setColor(androidColor);
|
|
||||||
scoreRing.setPercentage(todayPercentage);
|
|
||||||
|
|
||||||
TextView scoreLabel = (TextView) view.findViewById(R.id.scoreLabel);
|
|
||||||
TextView monthDiffLabel = (TextView) view.findViewById(R.id.monthDiffLabel);
|
|
||||||
TextView yearDiffLabel = (TextView) view.findViewById(R.id.yearDiffLabel);
|
|
||||||
|
|
||||||
scoreLabel.setText(String.format("%.0f%%", todayPercentage * 100));
|
|
||||||
|
|
||||||
String minus = "\u2212";
|
|
||||||
monthDiffLabel.setText(String.format("%s%.0f%%", (monthDiff >= 0 ? "+" : minus),
|
|
||||||
Math.abs(monthDiff) * 100));
|
|
||||||
yearDiffLabel.setText(
|
|
||||||
String.format("%s%.0f%%", (yearDiff >= 0 ? "+" : minus), Math.abs(yearDiff) * 100));
|
|
||||||
|
|
||||||
monthDiffLabel.setTextColor(monthDiff >= 0 ? activeColor : inactiveColor);
|
|
||||||
yearDiffLabel.setTextColor(yearDiff >= 0 ? activeColor : inactiveColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateHeaders(View view)
|
|
||||||
{
|
|
||||||
updateColor(view, R.id.tvHistory);
|
|
||||||
updateColor(view, R.id.tvOverview);
|
|
||||||
updateColor(view, R.id.tvStrength);
|
|
||||||
updateColor(view, R.id.tvStreaks);
|
|
||||||
updateColor(view, R.id.tvWeekdayFreq);
|
|
||||||
updateColor(view, R.id.scoreLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateColor(View view, int viewId)
|
|
||||||
{
|
|
||||||
if(habit == null || activity == null) return;
|
|
||||||
|
|
||||||
TextView textView = (TextView) view.findViewById(viewId);
|
|
||||||
int androidColor = ColorUtils.getColor(activity, habit.color);
|
|
||||||
textView.setTextColor(androidColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
|
||||||
{
|
{
|
||||||
@@ -266,80 +140,24 @@ public class ShowHabitFragment extends Fragment
|
|||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item)
|
public boolean onOptionsItemSelected(MenuItem item)
|
||||||
{
|
{
|
||||||
if(habit == null) return false;
|
if (item.getItemId() == R.id.action_edit_habit)
|
||||||
|
return showEditHabitDialog();
|
||||||
switch (item.getItemId())
|
|
||||||
{
|
|
||||||
case R.id.action_edit_habit:
|
|
||||||
{
|
|
||||||
EditHabitDialogFragment
|
|
||||||
frag = EditHabitDialogFragment.editSingleHabitFragment(habit.getId());
|
|
||||||
frag.setOnSavedListener(this);
|
|
||||||
frag.show(getFragmentManager(), "editHabit");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private boolean showEditHabitDialog()
|
||||||
public void onSaved(Command command, Object savedObject)
|
|
||||||
{
|
{
|
||||||
if(activity == null) return;
|
if(habit == null) return false;
|
||||||
Habit h = (Habit) savedObject;
|
|
||||||
|
|
||||||
if (h == null) activity.executeCommand(command, null);
|
EditHabitDialogFragment frag = EditHabitDialogFragment.editSingleHabitFragment(habit.getId());
|
||||||
else activity.executeCommand(command, h.getId());
|
frag.show(getFragmentManager(), "editHabit");
|
||||||
|
return true;
|
||||||
ReminderUtils.createReminderAlarms(activity);
|
|
||||||
HabitBroadcastReceiver.sendRefreshBroadcast(getActivity());
|
|
||||||
|
|
||||||
activity.recreate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onHistoryEditorClosed()
|
|
||||||
{
|
|
||||||
refreshData();
|
|
||||||
HabitBroadcastReceiver.sendRefreshBroadcast(getActivity());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshData()
|
public void refreshData()
|
||||||
{
|
{
|
||||||
new BaseTask()
|
new RefreshTask().execute();
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected void doInBackground()
|
|
||||||
{
|
|
||||||
if(habit == null) return;
|
|
||||||
if(dataViews == null) return;
|
|
||||||
|
|
||||||
long today = DateUtils.getStartOfToday();
|
|
||||||
long lastMonth = today - 30 * DateUtils.millisecondsInOneDay;
|
|
||||||
long lastYear = today - 365 * DateUtils.millisecondsInOneDay;
|
|
||||||
|
|
||||||
todayScore = (float) habit.scores.getTodayValue();
|
|
||||||
lastMonthScore = (float) habit.scores.getValue(lastMonth);
|
|
||||||
lastYearScore = (float) habit.scores.getValue(lastYear);
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
for(HabitDataView view : dataViews)
|
|
||||||
{
|
|
||||||
view.refreshData();
|
|
||||||
publishProgress(count++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onProgressUpdate(Integer... values)
|
|
||||||
{
|
|
||||||
updateScore(getView());
|
|
||||||
if(dataViews == null) return;
|
|
||||||
dataViews.get(values[0]).postInvalidate();
|
|
||||||
}
|
|
||||||
}.execute();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -351,15 +169,13 @@ public class ShowHabitFragment extends Fragment
|
|||||||
|
|
||||||
private void setScoreBucketSize(int position)
|
private void setScoreBucketSize(int position)
|
||||||
{
|
{
|
||||||
if(scoreView == null) return;
|
if(getView() == null) return;
|
||||||
|
|
||||||
|
HabitScoreView scoreView = (HabitScoreView) getView().findViewById(R.id.scoreView);
|
||||||
scoreView.setBucketSize(HabitScoreView.DEFAULT_BUCKET_SIZES[position]);
|
scoreView.setBucketSize(HabitScoreView.DEFAULT_BUCKET_SIZES[position]);
|
||||||
|
|
||||||
if(position != previousScoreInterval)
|
if(position != previousScoreInterval)
|
||||||
{
|
|
||||||
refreshData();
|
refreshData();
|
||||||
HabitBroadcastReceiver.sendRefreshBroadcast(getActivity());
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceUtils.setDefaultScoreInterval(getContext(), position);
|
InterfaceUtils.setDefaultScoreInterval(getContext(), position);
|
||||||
previousScoreInterval = position;
|
previousScoreInterval = position;
|
||||||
@@ -368,6 +184,61 @@ public class ShowHabitFragment extends Fragment
|
|||||||
@Override
|
@Override
|
||||||
public void onNothingSelected(AdapterView<?> parent)
|
public void onNothingSelected(AdapterView<?> parent)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onModelChange()
|
||||||
|
{
|
||||||
|
refreshData();
|
||||||
|
activity.runOnUiThread(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
helper.updateColors();
|
||||||
|
helper.updateMainHeader(getView());
|
||||||
|
helper.updateCardHeaders(getView());
|
||||||
|
if(activity != null) activity.setupHabitActionBar();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RefreshTask extends BaseTask
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void doInBackground()
|
||||||
|
{
|
||||||
|
if(habit == null) return;
|
||||||
|
if(dataViews == null) return;
|
||||||
|
|
||||||
|
long today = DateUtils.getStartOfToday();
|
||||||
|
long lastMonth = today - 30 * DateUtils.millisecondsInOneDay;
|
||||||
|
long lastYear = today - 365 * DateUtils.millisecondsInOneDay;
|
||||||
|
|
||||||
|
todayScore = (float) habit.scores.getTodayValue();
|
||||||
|
lastMonthScore = (float) habit.scores.getValue(lastMonth);
|
||||||
|
lastYearScore = (float) habit.scores.getValue(lastYear);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void aVoid)
|
||||||
|
{
|
||||||
|
helper.updateScore(getView());
|
||||||
|
super.onPostExecute(aVoid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart()
|
||||||
|
{
|
||||||
|
super.onStart();
|
||||||
|
habit.observable.addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause()
|
||||||
|
{
|
||||||
|
habit.observable.removeListener(this);
|
||||||
|
super.onPause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* 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.ui.habits.show;
|
||||||
|
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.R;
|
||||||
|
import org.isoron.uhabits.models.Score;
|
||||||
|
import org.isoron.uhabits.utils.ColorUtils;
|
||||||
|
import org.isoron.uhabits.utils.DateUtils;
|
||||||
|
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||||
|
import org.isoron.uhabits.views.RingView;
|
||||||
|
|
||||||
|
public class ShowHabitHelper
|
||||||
|
{
|
||||||
|
private ShowHabitFragment fragment;
|
||||||
|
|
||||||
|
public ShowHabitHelper(ShowHabitFragment fragment)
|
||||||
|
{
|
||||||
|
this.fragment = fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getFreqText()
|
||||||
|
{
|
||||||
|
if(fragment.habit == null) return "";
|
||||||
|
|
||||||
|
Resources resources = fragment.getResources();
|
||||||
|
Integer freqNum = fragment.habit.freqNum;
|
||||||
|
Integer freqDen = fragment.habit.freqDen;
|
||||||
|
|
||||||
|
if (freqNum.equals(freqDen)) return resources.getString(R.string.every_day);
|
||||||
|
|
||||||
|
if (freqNum == 1)
|
||||||
|
{
|
||||||
|
if (freqDen == 7) return resources.getString(R.string.every_week);
|
||||||
|
if (freqDen % 7 == 0) return resources.getString(R.string.every_x_weeks, freqDen / 7);
|
||||||
|
return resources.getString(R.string.every_x_days, freqDen);
|
||||||
|
}
|
||||||
|
|
||||||
|
String times_every = resources.getString(R.string.time_every);
|
||||||
|
return String.format("%d %s %d %s", freqNum, times_every, freqDen,
|
||||||
|
resources.getString(R.string.days));
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateScore(View view)
|
||||||
|
{
|
||||||
|
if (fragment.habit == null) return;
|
||||||
|
if (view == null) return;
|
||||||
|
|
||||||
|
float todayPercentage = fragment.todayScore / Score.MAX_VALUE;
|
||||||
|
float monthDiff = todayPercentage - (fragment.lastMonthScore / Score.MAX_VALUE);
|
||||||
|
float yearDiff = todayPercentage - (fragment.lastYearScore / Score.MAX_VALUE);
|
||||||
|
|
||||||
|
RingView scoreRing = (RingView) view.findViewById(R.id.scoreRing);
|
||||||
|
int androidColor = ColorUtils.getColor(fragment.getActivity(), fragment.habit.color);
|
||||||
|
scoreRing.setColor(androidColor);
|
||||||
|
scoreRing.setPercentage(todayPercentage);
|
||||||
|
|
||||||
|
TextView scoreLabel = (TextView) view.findViewById(R.id.scoreLabel);
|
||||||
|
TextView monthDiffLabel = (TextView) view.findViewById(R.id.monthDiffLabel);
|
||||||
|
TextView yearDiffLabel = (TextView) view.findViewById(R.id.yearDiffLabel);
|
||||||
|
|
||||||
|
scoreLabel.setText(String.format("%.0f%%", todayPercentage * 100));
|
||||||
|
|
||||||
|
String minus = "\u2212";
|
||||||
|
monthDiffLabel.setText(String.format("%s%.0f%%", (monthDiff >= 0 ? "+" : minus),
|
||||||
|
Math.abs(monthDiff) * 100));
|
||||||
|
yearDiffLabel.setText(
|
||||||
|
String.format("%s%.0f%%", (yearDiff >= 0 ? "+" : minus), Math.abs(yearDiff) * 100));
|
||||||
|
|
||||||
|
monthDiffLabel.setTextColor(monthDiff >= 0 ? fragment.activeColor : fragment.inactiveColor);
|
||||||
|
yearDiffLabel.setTextColor(yearDiff >= 0 ? fragment.activeColor : fragment.inactiveColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateMainHeader(View view)
|
||||||
|
{
|
||||||
|
if (fragment.habit == null) return;
|
||||||
|
|
||||||
|
TextView questionLabel = (TextView) view.findViewById(R.id.questionLabel);
|
||||||
|
questionLabel.setTextColor(fragment.activeColor);
|
||||||
|
questionLabel.setText(fragment.habit.description);
|
||||||
|
|
||||||
|
TextView reminderLabel = (TextView) view.findViewById(R.id.reminderLabel);
|
||||||
|
if (fragment.habit.hasReminder()) reminderLabel.setText(
|
||||||
|
DateUtils.formatTime(fragment.getActivity(), fragment.habit.reminderHour,
|
||||||
|
fragment.habit.reminderMin));
|
||||||
|
else reminderLabel.setText(fragment.getResources().getString(R.string.reminder_off));
|
||||||
|
|
||||||
|
TextView frequencyLabel = (TextView) view.findViewById(R.id.frequencyLabel);
|
||||||
|
frequencyLabel.setText(getFreqText());
|
||||||
|
|
||||||
|
if (fragment.habit.description.isEmpty()) questionLabel.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateCardHeaders(View view)
|
||||||
|
{
|
||||||
|
updateColor(view, R.id.tvHistory);
|
||||||
|
updateColor(view, R.id.tvOverview);
|
||||||
|
updateColor(view, R.id.tvStrength);
|
||||||
|
updateColor(view, R.id.tvStreaks);
|
||||||
|
updateColor(view, R.id.tvWeekdayFreq);
|
||||||
|
updateColor(view, R.id.scoreLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateColor(View view, int viewId)
|
||||||
|
{
|
||||||
|
if(fragment.habit == null || fragment.activity == null) return;
|
||||||
|
|
||||||
|
TextView textView = (TextView) view.findViewById(viewId);
|
||||||
|
int androidColor = ColorUtils.getColor(fragment.activity, fragment.habit.color);
|
||||||
|
textView.setTextColor(androidColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateColors()
|
||||||
|
{
|
||||||
|
fragment.activeColor = ColorUtils.getColor(fragment.getContext(), fragment.habit.color);
|
||||||
|
fragment.inactiveColor = InterfaceUtils.getStyledColor(fragment.getContext(),
|
||||||
|
R.attr.mediumContrastTextColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,6 @@ import android.util.TypedValue;
|
|||||||
|
|
||||||
import org.isoron.uhabits.HabitsApplication;
|
import org.isoron.uhabits.HabitsApplication;
|
||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.R;
|
||||||
import org.isoron.uhabits.commands.Command;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@@ -55,11 +54,6 @@ public abstract class InterfaceUtils
|
|||||||
InterfaceUtils.fixedTheme = fixedTheme;
|
InterfaceUtils.fixedTheme = fixedTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnSavedListener
|
|
||||||
{
|
|
||||||
void onSaved(Command command, Object savedObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Typeface getFontAwesome(Context context)
|
public static Typeface getFontAwesome(Context context)
|
||||||
{
|
{
|
||||||
if(fontAwesome == null)
|
if(fontAwesome == null)
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import android.graphics.RectF;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.R;
|
||||||
|
import org.isoron.uhabits.models.ModelObservable;
|
||||||
|
import org.isoron.uhabits.tasks.BaseTask;
|
||||||
import org.isoron.uhabits.utils.ColorUtils;
|
import org.isoron.uhabits.utils.ColorUtils;
|
||||||
import org.isoron.uhabits.utils.DateUtils;
|
import org.isoron.uhabits.utils.DateUtils;
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||||
@@ -38,9 +40,8 @@ import java.util.GregorianCalendar;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class HabitFrequencyView extends ScrollableDataView implements HabitDataView
|
public class HabitFrequencyView extends ScrollableDataView implements HabitDataView, ModelObservable.Listener
|
||||||
{
|
{
|
||||||
|
|
||||||
private Paint pGrid;
|
private Paint pGrid;
|
||||||
private float em;
|
private float em;
|
||||||
private Habit habit;
|
private Habit habit;
|
||||||
@@ -173,10 +174,12 @@ public class HabitFrequencyView extends ScrollableDataView implements HabitDataV
|
|||||||
|
|
||||||
public void refreshData()
|
public void refreshData()
|
||||||
{
|
{
|
||||||
if(isInEditMode())
|
if(isInEditMode()) generateRandomData();
|
||||||
generateRandomData();
|
|
||||||
else if(habit != null)
|
else if(habit != null)
|
||||||
|
{
|
||||||
frequency = habit.repetitions.getWeekdayFrequency();
|
frequency = habit.repetitions.getWeekdayFrequency();
|
||||||
|
createColors();
|
||||||
|
}
|
||||||
|
|
||||||
postInvalidate();
|
postInvalidate();
|
||||||
}
|
}
|
||||||
@@ -297,4 +300,35 @@ public class HabitFrequencyView extends ScrollableDataView implements HabitDataV
|
|||||||
this.isBackgroundTransparent = isBackgroundTransparent;
|
this.isBackgroundTransparent = isBackgroundTransparent;
|
||||||
createColors();
|
createColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow()
|
||||||
|
{
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
new BaseTask()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void doInBackground()
|
||||||
|
{
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
habit.observable.addListener(this);
|
||||||
|
habit.checkmarks.observable.addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDetachedFromWindow()
|
||||||
|
{
|
||||||
|
habit.checkmarks.observable.removeListener(this);
|
||||||
|
habit.observable.removeListener(this);
|
||||||
|
super.onDetachedFromWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onModelChange()
|
||||||
|
{
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,12 +30,13 @@ import android.view.HapticFeedbackConstants;
|
|||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.R;
|
||||||
|
import org.isoron.uhabits.models.Habit;
|
||||||
|
import org.isoron.uhabits.models.ModelObservable;
|
||||||
|
import org.isoron.uhabits.tasks.BaseTask;
|
||||||
|
import org.isoron.uhabits.tasks.ToggleRepetitionTask;
|
||||||
import org.isoron.uhabits.utils.ColorUtils;
|
import org.isoron.uhabits.utils.ColorUtils;
|
||||||
import org.isoron.uhabits.utils.DateUtils;
|
import org.isoron.uhabits.utils.DateUtils;
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||||
import org.isoron.uhabits.models.Habit;
|
|
||||||
import org.isoron.uhabits.tasks.BaseTask;
|
|
||||||
import org.isoron.uhabits.tasks.ToggleRepetitionTask;
|
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
@@ -43,7 +44,7 @@ import java.util.GregorianCalendar;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class HabitHistoryView extends ScrollableDataView implements HabitDataView,
|
public class HabitHistoryView extends ScrollableDataView implements HabitDataView,
|
||||||
ToggleRepetitionTask.Listener
|
ToggleRepetitionTask.Listener, ModelObservable.Listener
|
||||||
{
|
{
|
||||||
private Habit habit;
|
private Habit habit;
|
||||||
private int[] checkmarks;
|
private int[] checkmarks;
|
||||||
@@ -216,6 +217,7 @@ public class HabitHistoryView extends ScrollableDataView implements HabitDataVie
|
|||||||
{
|
{
|
||||||
if(habit == null) return;
|
if(habit == null) return;
|
||||||
checkmarks = habit.checkmarks.getAllValues();
|
checkmarks = habit.checkmarks.getAllValues();
|
||||||
|
createColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDate();
|
updateDate();
|
||||||
@@ -409,4 +411,34 @@ public class HabitHistoryView extends ScrollableDataView implements HabitDataVie
|
|||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow()
|
||||||
|
{
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
new BaseTask()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void doInBackground()
|
||||||
|
{
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
habit.observable.addListener(this);
|
||||||
|
habit.checkmarks.observable.addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDetachedFromWindow()
|
||||||
|
{
|
||||||
|
habit.checkmarks.observable.removeListener(this);
|
||||||
|
habit.observable.removeListener(this);
|
||||||
|
super.onDetachedFromWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onModelChange()
|
||||||
|
{
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,18 +31,21 @@ import android.support.annotation.Nullable;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.R;
|
||||||
|
import org.isoron.uhabits.models.Habit;
|
||||||
|
import org.isoron.uhabits.models.ModelObservable;
|
||||||
|
import org.isoron.uhabits.models.Score;
|
||||||
|
import org.isoron.uhabits.tasks.BaseTask;
|
||||||
import org.isoron.uhabits.utils.ColorUtils;
|
import org.isoron.uhabits.utils.ColorUtils;
|
||||||
import org.isoron.uhabits.utils.DateUtils;
|
import org.isoron.uhabits.utils.DateUtils;
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||||
import org.isoron.uhabits.models.Habit;
|
|
||||||
import org.isoron.uhabits.models.Score;
|
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class HabitScoreView extends ScrollableDataView implements HabitDataView
|
public class HabitScoreView extends ScrollableDataView
|
||||||
|
implements HabitDataView, ModelObservable.Listener
|
||||||
{
|
{
|
||||||
public static final PorterDuffXfermode XFERMODE_CLEAR =
|
public static final PorterDuffXfermode XFERMODE_CLEAR =
|
||||||
new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
|
new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
|
||||||
@@ -195,6 +198,7 @@ public class HabitScoreView extends ScrollableDataView implements HabitDataView
|
|||||||
{
|
{
|
||||||
if (habit == null) return;
|
if (habit == null) return;
|
||||||
scores = habit.scores.getAllValues(bucketSize);
|
scores = habit.scores.getAllValues(bucketSize);
|
||||||
|
createColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
postInvalidate();
|
postInvalidate();
|
||||||
@@ -434,4 +438,34 @@ public class HabitScoreView extends ScrollableDataView implements HabitDataView
|
|||||||
|
|
||||||
return maxDayWidth;
|
return maxDayWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow()
|
||||||
|
{
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
new BaseTask()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void doInBackground()
|
||||||
|
{
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
habit.observable.addListener(this);
|
||||||
|
habit.scores.observable.addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDetachedFromWindow()
|
||||||
|
{
|
||||||
|
habit.scores.observable.removeListener(this);
|
||||||
|
habit.observable.removeListener(this);
|
||||||
|
super.onDetachedFromWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onModelChange()
|
||||||
|
{
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ import android.util.AttributeSet;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.R;
|
||||||
|
import org.isoron.uhabits.models.ModelObservable;
|
||||||
|
import org.isoron.uhabits.tasks.BaseTask;
|
||||||
import org.isoron.uhabits.utils.ColorUtils;
|
import org.isoron.uhabits.utils.ColorUtils;
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
@@ -39,7 +41,7 @@ import java.util.Date;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
public class HabitStreakView extends View implements HabitDataView
|
public class HabitStreakView extends View implements HabitDataView, ModelObservable.Listener
|
||||||
{
|
{
|
||||||
private Habit habit;
|
private Habit habit;
|
||||||
private Paint paint;
|
private Paint paint;
|
||||||
@@ -151,6 +153,7 @@ public class HabitStreakView extends View implements HabitDataView
|
|||||||
{
|
{
|
||||||
if(habit == null) return;
|
if(habit == null) return;
|
||||||
streaks = habit.streaks.getAll(maxStreakCount);
|
streaks = habit.streaks.getAll(maxStreakCount);
|
||||||
|
createColors();
|
||||||
updateMaxMin();
|
updateMaxMin();
|
||||||
postInvalidate();
|
postInvalidate();
|
||||||
}
|
}
|
||||||
@@ -246,4 +249,35 @@ public class HabitStreakView extends View implements HabitDataView
|
|||||||
this.isBackgroundTransparent = isBackgroundTransparent;
|
this.isBackgroundTransparent = isBackgroundTransparent;
|
||||||
createColors();
|
createColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow()
|
||||||
|
{
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
new BaseTask()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void doInBackground()
|
||||||
|
{
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
habit.observable.addListener(this);
|
||||||
|
habit.streaks.observable.addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDetachedFromWindow()
|
||||||
|
{
|
||||||
|
habit.streaks.observable.removeListener(this);
|
||||||
|
habit.observable.removeListener(this);
|
||||||
|
super.onDetachedFromWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onModelChange()
|
||||||
|
{
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user