Improve habit positioning and reordering

pull/30/head
Alinson S. Xavier 10 years ago
parent 322650345c
commit eefc738ee2

@ -87,6 +87,7 @@ public class ListHabitsFragment extends Fragment
private boolean isShortToggleEnabled; private boolean isShortToggleEnabled;
private HabitListLoader loader; private HabitListLoader loader;
boolean showArchived;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -130,7 +131,7 @@ public class ListHabitsFragment extends Fragment
((TextView) view.findViewById(R.id.tvStarEmpty)).setTypeface(fontawesome); ((TextView) view.findViewById(R.id.tvStarEmpty)).setTypeface(fontawesome);
llEmpty = view.findViewById(R.id.llEmpty); llEmpty = view.findViewById(R.id.llEmpty);
loader.updateAllHabits(); loader.updateAllHabits(true);
setHasOptionsMenu(true); setHasOptionsMenu(true);
return view; return view;
@ -152,7 +153,7 @@ public class ListHabitsFragment extends Fragment
Long timestamp = loader.getLastLoadTimestamp(); Long timestamp = loader.getLastLoadTimestamp();
if (timestamp != null && timestamp != DateHelper.getStartOfToday()) if (timestamp != null && timestamp != DateHelper.getStartOfToday())
loader.updateAllHabits(); loader.updateAllHabits(true);
updateEmptyMessage(); updateEmptyMessage();
updateHeader(); updateHeader();
@ -199,7 +200,7 @@ public class ListHabitsFragment extends Fragment
inflater.inflate(R.menu.list_habits_options, menu); inflater.inflate(R.menu.list_habits_options, menu);
MenuItem showArchivedItem = menu.findItem(R.id.action_show_archived); MenuItem showArchivedItem = menu.findItem(R.id.action_show_archived);
showArchivedItem.setChecked(Habit.isIncludeArchived()); showArchivedItem.setChecked(showArchived);
} }
@Override @Override
@ -230,8 +231,9 @@ public class ListHabitsFragment extends Fragment
case R.id.action_show_archived: case R.id.action_show_archived:
{ {
Habit.setIncludeArchived(!Habit.isIncludeArchived()); showArchived = !showArchived;
loader.updateAllHabits(); loader.setIncludeArchived(showArchived);
loader.updateAllHabits(true);
activity.invalidateOptionsMenu(); activity.invalidateOptionsMenu();
return true; return true;
} }
@ -279,7 +281,7 @@ public class ListHabitsFragment extends Fragment
{ {
if (new Date().getTime() - lastLongClick < 1000) return; if (new Date().getTime() - lastLongClick < 1000) return;
Habit habit = loader.positionToHabit.get(position); Habit habit = loader.habitsList.get(position);
habitClickListener.onHabitClicked(habit); habitClickListener.onHabitClicked(habit);
} }
@ -347,13 +349,9 @@ public class ListHabitsFragment extends Fragment
@Override @Override
public void drop(int from, int to) public void drop(int from, int to)
{ {
Habit fromHabit = loader.positionToHabit.get(from); loader.reorder(from, to);
Habit toHabit = loader.positionToHabit.get(to);
loader.positionToHabit.put(to, fromHabit);
loader.positionToHabit.put(from, toHabit);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
loader.updateAllHabits(false);
Habit.reorder(from, to);
} }
@Override @Override
@ -389,7 +387,7 @@ public class ListHabitsFragment extends Fragment
@Override @Override
public Object getItem(int position) public Object getItem(int position)
{ {
return loader.positionToHabit.get(position); return loader.habitsList.get(position);
} }
@Override @Override
@ -401,7 +399,7 @@ public class ListHabitsFragment extends Fragment
@Override @Override
public View getView(int position, View view, ViewGroup parent) public View getView(int position, View view, ViewGroup parent)
{ {
final Habit habit = loader.positionToHabit.get(position); final Habit habit = loader.habitsList.get(position);
if (view == null || if (view == null ||
(Long) view.getTag(R.id.KEY_TIMESTAMP) != DateHelper.getStartOfToday()) (Long) view.getTag(R.id.KEY_TIMESTAMP) != DateHelper.getStartOfToday())
@ -448,15 +446,16 @@ public class ListHabitsFragment extends Fragment
private void updateCheckmarkButtons(Habit habit, LinearLayout llButtons) private void updateCheckmarkButtons(Habit habit, LinearLayout llButtons)
{ {
int activeColor = getActiveColor(habit); int activeColor = getActiveColor(habit);
int m = llButtons.getChildCount(); int m = llButtons.getChildCount();
int isChecked[] = loader.checkmarks.get(habit.getId()); Long habitId = habit.getId();
int isChecked[] = loader.checkmarks.get(habitId);
for (int i = 0; i < m; i++) for (int i = 0; i < m; i++)
{ {
TextView tvCheck = (TextView) llButtons.getChildAt(i); TextView tvCheck = (TextView) llButtons.getChildAt(i);
tvCheck.setTag(R.string.habit_key, habit.getId()); tvCheck.setTag(R.string.habit_key, habitId);
tvCheck.setTag(R.string.offset_key, i); tvCheck.setTag(R.string.offset_key, i);
updateCheckmark(activeColor, tvCheck, isChecked[i]); updateCheckmark(activeColor, tvCheck, isChecked[i]);
} }
@ -529,7 +528,7 @@ public class ListHabitsFragment extends Fragment
public void onPostExecuteCommand(Long refreshKey) public void onPostExecuteCommand(Long refreshKey)
{ {
if (refreshKey == null) loader.updateAllHabits(); if (refreshKey == null) loader.updateAllHabits(true);
else loader.updateHabit(refreshKey); else loader.updateHabit(refreshKey);
} }
} }

@ -28,6 +28,7 @@ import org.isoron.helpers.DateHelper;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Habit;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
public class HabitListLoader public class HabitListLoader
{ {
@ -44,10 +45,17 @@ public class HabitListLoader
private Long lastLoadTimestamp; private Long lastLoadTimestamp;
public HashMap<Long, Habit> habits; public HashMap<Long, Habit> habits;
public HashMap<Integer, Habit> positionToHabit; public List<Habit> habitsList;
public HashMap<Long, int[]> checkmarks; public HashMap<Long, int[]> checkmarks;
public HashMap<Long, Integer> scores; public HashMap<Long, Integer> scores;
boolean includeArchived;
public void setIncludeArchived(boolean includeArchived)
{
this.includeArchived = includeArchived;
}
public void setProgressBar(ProgressBar progressBar) public void setProgressBar(ProgressBar progressBar)
{ {
this.progressBar = progressBar; this.progressBar = progressBar;
@ -71,58 +79,88 @@ public class HabitListLoader
public HabitListLoader() public HabitListLoader()
{ {
habits = new HashMap<>(); habits = new HashMap<>();
positionToHabit = new HashMap<>();
checkmarks = new HashMap<>(); checkmarks = new HashMap<>();
scores = new HashMap<>(); scores = new HashMap<>();
} }
private void resetData() public void reorder(int from, int to)
{ {
habits.clear(); Habit fromHabit = habitsList.get(from);
positionToHabit.clear(); Habit toHabit = habitsList.get(to);
checkmarks.clear();
scores.clear(); habitsList.remove(from);
habitsList.add(to, fromHabit);
Habit.reorder(fromHabit, toHabit);
} }
public void updateAllHabits() public void updateAllHabits(final boolean updateScoresAndCheckmarks)
{ {
if (currentFetchTask != null) currentFetchTask.cancel(true); if (currentFetchTask != null) currentFetchTask.cancel(true);
currentFetchTask = new AsyncTask<Void, Integer, Void>() currentFetchTask = new AsyncTask<Void, Integer, Void>()
{ {
public HashMap<Long, Habit> newHabits;
public HashMap<Long, int[]> newCheckmarks;
public HashMap<Long, Integer> newScores;
public List<Habit> newHabitList;
@Override @Override
protected Void doInBackground(Void... params) protected Void doInBackground(Void... params)
{ {
resetData(); newHabits = new HashMap<>();
newCheckmarks = new HashMap<>();
habits = Habit.getAll(); newScores = new HashMap<>();
newHabitList = Habit.getAll(includeArchived);
long dateTo = DateHelper.getStartOfDay(DateHelper.getLocalTime()); long dateTo = DateHelper.getStartOfDay(DateHelper.getLocalTime());
long dateFrom = dateTo - (checkmarkCount - 1) * DateHelper.millisecondsInOneDay; long dateFrom = dateTo - (checkmarkCount - 1) * DateHelper.millisecondsInOneDay;
int[] empty = new int[checkmarkCount]; int[] empty = new int[checkmarkCount];
for (Habit h : habits.values()) for(Habit h : newHabitList)
{ {
scores.put(h.getId(), 0); Long id = h.getId();
positionToHabit.put(h.position, h);
checkmarks.put(h.getId(), empty); newHabits.put(id, h);
if(checkmarks.containsKey(id))
newCheckmarks.put(id, checkmarks.get(id));
else
newCheckmarks.put(id, empty);
if(scores.containsKey(id))
newScores.put(id, scores.get(id));
else
newScores.put(id, 0);
} }
commit();
if(!updateScoresAndCheckmarks) return null;
int current = 0; int current = 0;
for (int i = 0; i < habits.size(); i++) for (Habit h : newHabitList)
{ {
if (isCancelled()) return null; if (isCancelled()) return null;
Habit h = positionToHabit.get(i); Long id = h.getId();
scores.put(h.getId(), h.getScore()); newScores.put(id, h.getScore());
checkmarks.put(h.getId(), h.getCheckmarks(dateFrom, dateTo)); newCheckmarks.put(id, h.getCheckmarks(dateFrom, dateTo));
publishProgress(current++, habits.size()); publishProgress(current++, newHabits.size());
} }
return null; return null;
} }
private void commit()
{
habits = newHabits;
scores = newScores;
checkmarks = newCheckmarks;
habitsList = newHabitList;
}
@Override @Override
protected void onPreExecute() protected void onPreExecute()
{ {
@ -137,10 +175,7 @@ public class HabitListLoader
progressBar.setMax(values[1]); progressBar.setMax(values[1]);
progressBar.setProgress(values[0]); progressBar.setProgress(values[0]);
if (lastLoadTimestamp == null) if(listener != null) listener.onLoadFinished();
{
listener.onLoadFinished();
}
} }
@Override @Override
@ -151,6 +186,8 @@ public class HabitListLoader
progressBar.setVisibility(View.INVISIBLE); progressBar.setVisibility(View.INVISIBLE);
lastLoadTimestamp = DateHelper.getStartOfToday(); lastLoadTimestamp = DateHelper.getStartOfToday();
currentFetchTask = null; currentFetchTask = null;
if(listener != null) listener.onLoadFinished();
} }
}; };

@ -37,7 +37,6 @@ import org.isoron.helpers.DateHelper;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
@Table(name = "Habits") @Table(name = "Habits")
@ -48,8 +47,6 @@ public class Habit extends Model
public static final int FULL_STAR_CUTOFF = 12973000; public static final int FULL_STAR_CUTOFF = 12973000;
public static final int MAX_SCORE = 19259500; public static final int MAX_SCORE = 19259500;
private static boolean includeArchived = false;
@Column(name = "name") @Column(name = "name")
public String name; public String name;
@ -100,17 +97,10 @@ public class Habit extends Model
return Habit.load(Habit.class, id); return Habit.load(Habit.class, id);
} }
public static HashMap<Long, Habit> getAll() public static List<Habit> getAll(boolean includeArchive)
{
List<Habit> habits = select().execute();
HashMap<Long, Habit> map = new HashMap<>();
for (Habit h : habits)
{ {
map.put(h.getId(), h); if(includeArchive) return selectWithArchived().execute();
} else return select().execute();
return map;
} }
@SuppressLint("DefaultLocale") @SuppressLint("DefaultLocale")
@ -121,19 +111,12 @@ public class Habit extends Model
protected static From select() protected static From select()
{ {
if (includeArchived) return new Select().from(Habit.class).orderBy("position"); return new Select().from(Habit.class).where("archived = 0").orderBy("position");
else return new Select().from(Habit.class).where("archived = 0").orderBy("position");
} }
public static void setIncludeArchived(boolean includeArchived) public static From selectWithArchived()
{ {
Habit.includeArchived = includeArchived; return new Select().from(Habit.class).orderBy("position");
rebuildOrder();
}
public static boolean isIncludeArchived()
{
return Habit.includeArchived;
} }
public static int getCount() public static int getCount()
@ -141,16 +124,6 @@ public class Habit extends Model
return select().count(); return select().count();
} }
public static Habit getByPosition(int position)
{
return select().offset(position).executeSingle();
}
public static java.util.List<Habit> getHabits()
{
return select().execute();
}
public static java.util.List<Habit> getHighlightedHabits() public static java.util.List<Habit> getHighlightedHabits()
{ {
return select().where("highlight = 1") return select().where("highlight = 1")
@ -163,25 +136,30 @@ public class Habit extends Model
return select().where("reminder_hour is not null").execute(); return select().where("reminder_hour is not null").execute();
} }
public static void reorder(int from, int to) public static void reorder(Habit from, Habit to)
{ {
if(from == to) return; if(from == to) return;
Habit h = Habit.getByPosition(from); if (to.position < from.position)
if (to < from) new Update(Habit.class).set("position = position + 1") {
.where("position >= ? and position < ?", to, from) new Update(Habit.class).set("position = position + 1")
.where("position >= ? and position < ?", to.position, from.position)
.execute(); .execute();
else new Update(Habit.class).set("position = position - 1") }
.where("position > ? and position <= ?", from, to) else
{
new Update(Habit.class).set("position = position - 1")
.where("position > ? and position <= ?", from.position, to.position)
.execute(); .execute();
}
h.position = to; from.position = to.position;
h.save(); from.save();
} }
public static void rebuildOrder() public static void rebuildOrder()
{ {
List<Habit> habits = select().execute(); List<Habit> habits = selectWithArchived().execute();
ActiveAndroid.beginTransaction(); ActiveAndroid.beginTransaction();
try try
@ -412,10 +390,7 @@ public class Habit extends Model
public void archive() public void archive()
{ {
archived = 1; archived = 1;
position = 9999;
save(); save();
Habit.rebuildOrder();
} }
public void unarchive() public void unarchive()

Loading…
Cancel
Save