mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 01:08:50 -06:00
Split Habit class into several smaller classes
This commit is contained in:
@@ -100,7 +100,7 @@ public class HabitBroadcastReceiver extends BroadcastReceiver
|
||||
Long timestamp = intent.getLongExtra("timestamp", DateHelper.getStartOfToday());
|
||||
|
||||
Habit habit = Habit.get(ContentUris.parseId(data));
|
||||
habit.toggleRepetition(timestamp);
|
||||
habit.repetitions.toggle(timestamp);
|
||||
habit.save();
|
||||
dismissNotification(context, habit);
|
||||
|
||||
@@ -137,7 +137,7 @@ public class HabitBroadcastReceiver extends BroadcastReceiver
|
||||
Long timestamp = intent.getLongExtra("timestamp", DateHelper.getStartOfToday());
|
||||
Long reminderTime = intent.getLongExtra("reminderTime", DateHelper.getStartOfToday());
|
||||
|
||||
if (habit.hasImplicitRepToday()) return;
|
||||
if (habit.repetitions.hasImplicitRepToday()) return;
|
||||
|
||||
habit.highlight = 1;
|
||||
habit.save();
|
||||
|
||||
@@ -44,9 +44,9 @@ public class EditHabitCommand extends Command
|
||||
habit.save();
|
||||
if (hasIntervalChanged)
|
||||
{
|
||||
habit.deleteCheckmarksNewerThan(0);
|
||||
habit.deleteStreaksNewerThan(0);
|
||||
habit.deleteScoresNewerThan(0);
|
||||
habit.checkmarks.deleteNewerThan(0);
|
||||
habit.streaks.deleteNewerThan(0);
|
||||
habit.scores.deleteNewerThan(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,9 +57,9 @@ public class EditHabitCommand extends Command
|
||||
habit.save();
|
||||
if (hasIntervalChanged)
|
||||
{
|
||||
habit.deleteCheckmarksNewerThan(0);
|
||||
habit.deleteStreaksNewerThan(0);
|
||||
habit.deleteScoresNewerThan(0);
|
||||
habit.checkmarks.deleteNewerThan(0);
|
||||
habit.streaks.deleteNewerThan(0);
|
||||
habit.scores.deleteNewerThan(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class ToggleRepetitionCommand extends Command
|
||||
@Override
|
||||
public void execute()
|
||||
{
|
||||
habit.toggleRepetition(offset);
|
||||
habit.repetitions.toggle(offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -75,6 +75,7 @@ import org.isoron.uhabits.helpers.ReminderHelper;
|
||||
import org.isoron.uhabits.io.CSVExporter;
|
||||
import org.isoron.uhabits.loaders.HabitListLoader;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
import org.isoron.uhabits.models.Score;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Date;
|
||||
@@ -741,12 +742,12 @@ public class ListHabitsFragment extends Fragment
|
||||
{
|
||||
int score = loader.scores.get(habit.getId());
|
||||
|
||||
if (score < Habit.HALF_STAR_CUTOFF)
|
||||
if (score < Score.HALF_STAR_CUTOFF)
|
||||
{
|
||||
tvStar.setText(getString(R.string.fa_star_o));
|
||||
tvStar.setTextColor(INACTIVE_COLOR);
|
||||
}
|
||||
else if (score < Habit.FULL_STAR_CUTOFF)
|
||||
else if (score < Score.FULL_STAR_CUTOFF)
|
||||
{
|
||||
tvStar.setText(getString(R.string.fa_star_half_o));
|
||||
tvStar.setTextColor(INACTIVE_COLOR);
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.ShowHabitActivity;
|
||||
import org.isoron.uhabits.helpers.ReminderHelper;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
import org.isoron.uhabits.models.Score;
|
||||
import org.isoron.uhabits.views.HabitHistoryView;
|
||||
import org.isoron.uhabits.views.HabitScoreView;
|
||||
import org.isoron.uhabits.views.HabitStreakView;
|
||||
@@ -58,7 +59,7 @@ public class ShowHabitFragment extends Fragment implements DialogHelper.OnSavedL
|
||||
activity = (ShowHabitActivity) getActivity();
|
||||
habit = activity.habit;
|
||||
|
||||
habit.updateCheckmarks();
|
||||
habit.checkmarks.rebuild();
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= 21)
|
||||
{
|
||||
@@ -81,7 +82,7 @@ public class ShowHabitFragment extends Fragment implements DialogHelper.OnSavedL
|
||||
tvStreaks.setTextColor(habit.color);
|
||||
|
||||
scoreRing.setColor(habit.color);
|
||||
scoreRing.setPercentage((float) habit.getScore() / Habit.MAX_SCORE);
|
||||
scoreRing.setPercentage((float) habit.scores.getNewestValue() / Score.MAX_SCORE);
|
||||
streakView.setHabit(habit);
|
||||
scoreView.setHabit(habit);
|
||||
historyView.setHabit(habit);
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.activeandroid.Cache;
|
||||
|
||||
import org.isoron.helpers.DateHelper;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
import org.isoron.uhabits.models.Score;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@@ -54,7 +55,7 @@ public class CSVExporter
|
||||
|
||||
public String formatScore(int score)
|
||||
{
|
||||
return String.format("%.2f", ((float) score) / Habit.MAX_SCORE);
|
||||
return String.format("%.2f", ((float) score) / Score.MAX_SCORE);
|
||||
}
|
||||
|
||||
private void writeScores(String dirPath, Habit habit) throws IOException
|
||||
|
||||
@@ -144,8 +144,8 @@ public class HabitListLoader
|
||||
if (isCancelled()) return null;
|
||||
|
||||
Long id = h.getId();
|
||||
newScores.put(id, h.getScore());
|
||||
newCheckmarks.put(id, h.getCheckmarks(dateFrom, dateTo));
|
||||
newScores.put(id, h.scores.getNewestValue());
|
||||
newCheckmarks.put(id, h.checkmarks.getValues(dateFrom, dateTo));
|
||||
|
||||
publishProgress(current++, newHabits.size());
|
||||
}
|
||||
@@ -213,8 +213,8 @@ public class HabitListLoader
|
||||
|
||||
Habit h = Habit.get(id);
|
||||
habits.put(id, h);
|
||||
scores.put(id, h.getScore());
|
||||
checkmarks.put(id, h.getCheckmarks(dateFrom, dateTo));
|
||||
scores.put(id, h.scores.getNewestValue());
|
||||
checkmarks.put(id, h.checkmarks.getValues(dateFrom, dateTo));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
175
app/src/main/java/org/isoron/uhabits/models/CheckmarkList.java
Normal file
175
app/src/main/java/org/isoron/uhabits/models/CheckmarkList.java
Normal file
@@ -0,0 +1,175 @@
|
||||
/* Copyright (C) 2016 Alinson Santos Xavier
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.models;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import com.activeandroid.ActiveAndroid;
|
||||
import com.activeandroid.Cache;
|
||||
import com.activeandroid.query.Delete;
|
||||
import com.activeandroid.query.Select;
|
||||
|
||||
import org.isoron.helpers.DateHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CheckmarkList
|
||||
{
|
||||
private Habit habit;
|
||||
|
||||
public CheckmarkList(Habit habit)
|
||||
{
|
||||
this.habit = habit;
|
||||
}
|
||||
|
||||
public void deleteNewerThan(long timestamp)
|
||||
{
|
||||
new Delete().from(Checkmark.class)
|
||||
.where("habit = ?", habit.getId())
|
||||
.and("timestamp >= ?", timestamp)
|
||||
.execute();
|
||||
}
|
||||
|
||||
public int[] getValues(Long fromTimestamp, Long toTimestamp)
|
||||
{
|
||||
rebuild();
|
||||
|
||||
if(fromTimestamp > toTimestamp) return new int[0];
|
||||
|
||||
String query = "select value, timestamp from Checkmarks where " +
|
||||
"habit = ? and timestamp >= ? and timestamp <= ?";
|
||||
|
||||
SQLiteDatabase db = Cache.openDatabase();
|
||||
String args[] = { habit.getId().toString(), fromTimestamp.toString(),
|
||||
toTimestamp.toString() };
|
||||
Cursor cursor = db.rawQuery(query, args);
|
||||
|
||||
long day = DateHelper.millisecondsInOneDay;
|
||||
int nDays = (int) ((toTimestamp - fromTimestamp) / day) + 1;
|
||||
int[] checks = new int[nDays];
|
||||
|
||||
if (cursor.moveToFirst())
|
||||
{
|
||||
do
|
||||
{
|
||||
long timestamp = cursor.getLong(1);
|
||||
int offset = (int) ((timestamp - fromTimestamp) / day);
|
||||
checks[nDays - offset - 1] = cursor.getInt(0);
|
||||
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
return checks;
|
||||
}
|
||||
|
||||
public int[] getAllValues()
|
||||
{
|
||||
Repetition oldestRep = habit.repetitions.getOldest();
|
||||
if(oldestRep == null) return new int[0];
|
||||
|
||||
Long toTimestamp = DateHelper.getStartOfToday();
|
||||
Long fromTimestamp = oldestRep.timestamp;
|
||||
return getValues(fromTimestamp, toTimestamp);
|
||||
}
|
||||
|
||||
public void rebuild()
|
||||
{
|
||||
long beginning;
|
||||
long today = DateHelper.getStartOfToday();
|
||||
long day = DateHelper.millisecondsInOneDay;
|
||||
|
||||
Checkmark newestCheckmark = getNewest();
|
||||
if (newestCheckmark == null)
|
||||
{
|
||||
Repetition oldestRep = habit.repetitions.getOldest();
|
||||
if (oldestRep == null) return;
|
||||
|
||||
beginning = oldestRep.timestamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
beginning = newestCheckmark.timestamp + day;
|
||||
}
|
||||
|
||||
if (beginning > today) return;
|
||||
|
||||
long beginningExtended = beginning - (long) (habit.freqDen) * day;
|
||||
List<Repetition> reps = habit.repetitions.selectFromTo(beginningExtended, today).execute();
|
||||
|
||||
int nDays = (int) ((today - beginning) / day) + 1;
|
||||
int nDaysExtended = (int) ((today - beginningExtended) / day) + 1;
|
||||
|
||||
int checks[] = new int[nDaysExtended];
|
||||
|
||||
// explicit checks
|
||||
for (Repetition rep : reps)
|
||||
{
|
||||
int offset = (int) ((rep.timestamp - beginningExtended) / day);
|
||||
checks[nDaysExtended - offset - 1] = 2;
|
||||
}
|
||||
|
||||
// implicit checks
|
||||
for (int i = 0; i < nDays; i++)
|
||||
{
|
||||
int counter = 0;
|
||||
|
||||
for (int j = 0; j < habit.freqDen; j++)
|
||||
if (checks[i + j] == 2) counter++;
|
||||
|
||||
if (counter >= habit.freqNum) checks[i] = Math.max(checks[i], 1);
|
||||
}
|
||||
|
||||
ActiveAndroid.beginTransaction();
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < nDays; i++)
|
||||
{
|
||||
Checkmark c = new Checkmark();
|
||||
c.habit = habit;
|
||||
c.timestamp = today - i * day;
|
||||
c.value = checks[i];
|
||||
c.save();
|
||||
}
|
||||
|
||||
ActiveAndroid.setTransactionSuccessful();
|
||||
} finally
|
||||
{
|
||||
ActiveAndroid.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
public Checkmark getNewest()
|
||||
{
|
||||
return new Select().from(Checkmark.class)
|
||||
.where("habit = ?", habit.getId())
|
||||
.orderBy("timestamp desc")
|
||||
.limit(1)
|
||||
.executeSingle();
|
||||
}
|
||||
|
||||
public int getCurrentValue()
|
||||
{
|
||||
rebuild();
|
||||
Checkmark c = getNewest();
|
||||
|
||||
if(c != null) return c.value;
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
@@ -17,12 +17,9 @@
|
||||
package org.isoron.uhabits.models;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.activeandroid.ActiveAndroid;
|
||||
import com.activeandroid.Cache;
|
||||
import com.activeandroid.Model;
|
||||
import com.activeandroid.annotation.Column;
|
||||
import com.activeandroid.annotation.Table;
|
||||
@@ -33,21 +30,12 @@ import com.activeandroid.query.Update;
|
||||
import com.activeandroid.util.SQLiteUtils;
|
||||
|
||||
import org.isoron.helpers.ColorHelper;
|
||||
import org.isoron.helpers.Command;
|
||||
import org.isoron.helpers.DateHelper;
|
||||
import org.isoron.uhabits.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Table(name = "Habits")
|
||||
public class Habit extends Model
|
||||
{
|
||||
|
||||
public static final int HALF_STAR_CUTOFF = 9629750;
|
||||
public static final int FULL_STAR_CUTOFF = 15407600;
|
||||
public static final int MAX_SCORE = 19259500;
|
||||
|
||||
@Column(name = "name")
|
||||
public String name;
|
||||
|
||||
@@ -81,20 +69,35 @@ public class Habit extends Model
|
||||
@Column(name = "archived")
|
||||
public Integer archived;
|
||||
|
||||
public StreakList streaks;
|
||||
public ScoreList scores;
|
||||
public RepetitionList repetitions;
|
||||
public CheckmarkList checkmarks;
|
||||
|
||||
public Habit(Habit model)
|
||||
{
|
||||
copyAttributes(model);
|
||||
initializeLists();
|
||||
}
|
||||
|
||||
public Habit()
|
||||
{
|
||||
this.color = ColorHelper.palette[5];
|
||||
this.position = Habit.getCount();
|
||||
this.position = Habit.count();
|
||||
this.highlight = 0;
|
||||
this.archived = 0;
|
||||
this.freqDen = 7;
|
||||
this.freqNum = 3;
|
||||
this.reminderDays = 127;
|
||||
initializeLists();
|
||||
}
|
||||
|
||||
private void initializeLists()
|
||||
{
|
||||
streaks = new StreakList(this);
|
||||
scores = new ScoreList(this);
|
||||
repetitions = new RepetitionList(this);
|
||||
checkmarks = new CheckmarkList(this);
|
||||
}
|
||||
|
||||
public static Habit get(Long id)
|
||||
@@ -124,7 +127,7 @@ public class Habit extends Model
|
||||
return new Select().from(Habit.class).orderBy("position");
|
||||
}
|
||||
|
||||
public static int getCount()
|
||||
public static int count()
|
||||
{
|
||||
return select().count();
|
||||
}
|
||||
@@ -177,7 +180,8 @@ public class Habit extends Model
|
||||
}
|
||||
|
||||
ActiveAndroid.setTransactionSuccessful();
|
||||
} finally
|
||||
}
|
||||
finally
|
||||
{
|
||||
ActiveAndroid.endTransaction();
|
||||
}
|
||||
@@ -205,22 +209,6 @@ public class Habit extends Model
|
||||
Habit.updateId(getId(), id);
|
||||
}
|
||||
|
||||
protected From selectReps()
|
||||
{
|
||||
return new Select().from(Repetition.class).where("habit = ?", getId()).orderBy("timestamp");
|
||||
}
|
||||
|
||||
protected From selectRepsFromTo(long timeFrom, long timeTo)
|
||||
{
|
||||
return selectReps().and("timestamp >= ?", timeFrom).and("timestamp <= ?", timeTo);
|
||||
}
|
||||
|
||||
public boolean hasRep(long timestamp)
|
||||
{
|
||||
int count = selectReps().where("timestamp = ?", timestamp).count();
|
||||
return (count > 0);
|
||||
}
|
||||
|
||||
public void cascadeDelete()
|
||||
{
|
||||
Long id = getId();
|
||||
@@ -242,209 +230,6 @@ public class Habit extends Model
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteReps(long timestamp)
|
||||
{
|
||||
new Delete().from(Repetition.class)
|
||||
.where("habit = ?", getId())
|
||||
.and("timestamp = ?", timestamp)
|
||||
.execute();
|
||||
}
|
||||
|
||||
public void deleteCheckmarksNewerThan(long timestamp)
|
||||
{
|
||||
new Delete().from(Checkmark.class)
|
||||
.where("habit = ?", getId())
|
||||
.and("timestamp >= ?", timestamp)
|
||||
.execute();
|
||||
}
|
||||
|
||||
public void deleteStreaksNewerThan(long timestamp)
|
||||
{
|
||||
new Delete().from(Streak.class)
|
||||
.where("habit = ?", getId())
|
||||
.and("end >= ?", timestamp - DateHelper.millisecondsInOneDay)
|
||||
.execute();
|
||||
}
|
||||
|
||||
public int[] getCheckmarks(Long fromTimestamp, Long toTimestamp)
|
||||
{
|
||||
updateCheckmarks();
|
||||
|
||||
if(fromTimestamp > toTimestamp) return new int[0];
|
||||
|
||||
String query = "select value, timestamp from Checkmarks where " +
|
||||
"habit = ? and timestamp >= ? and timestamp <= ?";
|
||||
|
||||
SQLiteDatabase db = Cache.openDatabase();
|
||||
String args[] = {getId().toString(), fromTimestamp.toString(), toTimestamp.toString()};
|
||||
Cursor cursor = db.rawQuery(query, args);
|
||||
|
||||
long day = DateHelper.millisecondsInOneDay;
|
||||
int nDays = (int) ((toTimestamp - fromTimestamp) / day) + 1;
|
||||
int[] checks = new int[nDays];
|
||||
|
||||
if (cursor.moveToFirst())
|
||||
{
|
||||
do
|
||||
{
|
||||
long timestamp = cursor.getLong(1);
|
||||
int offset = (int) ((timestamp - fromTimestamp) / day);
|
||||
checks[nDays - offset - 1] = cursor.getInt(0);
|
||||
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
return checks;
|
||||
}
|
||||
|
||||
public int[] getAllCheckmarks()
|
||||
{
|
||||
Repetition oldestRep = getOldestRep();
|
||||
if(oldestRep == null) return new int[0];
|
||||
|
||||
Long toTimestamp = DateHelper.getStartOfToday();
|
||||
Long fromTimestamp = oldestRep.timestamp;
|
||||
return getCheckmarks(fromTimestamp, toTimestamp);
|
||||
}
|
||||
|
||||
public void updateCheckmarks()
|
||||
{
|
||||
long beginning;
|
||||
long today = DateHelper.getStartOfToday();
|
||||
long day = DateHelper.millisecondsInOneDay;
|
||||
|
||||
Checkmark newestCheckmark = getNewestCheckmark();
|
||||
if (newestCheckmark == null)
|
||||
{
|
||||
Repetition oldestRep = getOldestRep();
|
||||
if (oldestRep == null) return;
|
||||
|
||||
beginning = oldestRep.timestamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
beginning = newestCheckmark.timestamp + day;
|
||||
}
|
||||
|
||||
if (beginning > today) return;
|
||||
|
||||
long beginningExtended = beginning - (long) (freqDen) * day;
|
||||
List<Repetition> reps = selectRepsFromTo(beginningExtended, today).execute();
|
||||
|
||||
int nDays = (int) ((today - beginning) / day) + 1;
|
||||
int nDaysExtended = (int) ((today - beginningExtended) / day) + 1;
|
||||
|
||||
int checks[] = new int[nDaysExtended];
|
||||
|
||||
// explicit checks
|
||||
for (Repetition rep : reps)
|
||||
{
|
||||
int offset = (int) ((rep.timestamp - beginningExtended) / day);
|
||||
checks[nDaysExtended - offset - 1] = 2;
|
||||
}
|
||||
|
||||
// implicit checks
|
||||
for (int i = 0; i < nDays; i++)
|
||||
{
|
||||
int counter = 0;
|
||||
|
||||
for (int j = 0; j < freqDen; j++)
|
||||
if (checks[i + j] == 2) counter++;
|
||||
|
||||
if (counter >= freqNum) checks[i] = Math.max(checks[i], 1);
|
||||
}
|
||||
|
||||
ActiveAndroid.beginTransaction();
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < nDays; i++)
|
||||
{
|
||||
Checkmark c = new Checkmark();
|
||||
c.habit = this;
|
||||
c.timestamp = today - i * day;
|
||||
c.value = checks[i];
|
||||
c.save();
|
||||
}
|
||||
|
||||
ActiveAndroid.setTransactionSuccessful();
|
||||
} finally
|
||||
{
|
||||
ActiveAndroid.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
public Checkmark getNewestCheckmark()
|
||||
{
|
||||
return new Select().from(Checkmark.class)
|
||||
.where("habit = ?", getId())
|
||||
.orderBy("timestamp desc")
|
||||
.limit(1)
|
||||
.executeSingle();
|
||||
}
|
||||
|
||||
public int getCurrentCheckmarkStatus()
|
||||
{
|
||||
updateCheckmarks();
|
||||
Checkmark c = getNewestCheckmark();
|
||||
|
||||
if(c != null) return c.value;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
public int getCurrentStarStatus()
|
||||
{
|
||||
int score = getScore();
|
||||
|
||||
if(score >= FULL_STAR_CUTOFF) return 2;
|
||||
else if(score >= HALF_STAR_CUTOFF) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
public int getRepsCount(int days)
|
||||
{
|
||||
long timeTo = DateHelper.getStartOfToday();
|
||||
long timeFrom = timeTo - DateHelper.millisecondsInOneDay * days;
|
||||
return selectRepsFromTo(timeFrom, timeTo).count();
|
||||
}
|
||||
|
||||
public boolean hasImplicitRepToday()
|
||||
{
|
||||
long today = DateHelper.getStartOfToday();
|
||||
int reps[] = getCheckmarks(today - DateHelper.millisecondsInOneDay, today);
|
||||
return (reps[0] > 0);
|
||||
}
|
||||
|
||||
public Repetition getOldestRep()
|
||||
{
|
||||
return (Repetition) selectReps().limit(1).executeSingle();
|
||||
}
|
||||
|
||||
public Repetition getOldestRepNewerThan(long timestamp)
|
||||
{
|
||||
return selectReps().where("timestamp > ?", timestamp).limit(1).executeSingle();
|
||||
}
|
||||
|
||||
public void toggleRepetition(long timestamp)
|
||||
{
|
||||
if (hasRep(timestamp))
|
||||
{
|
||||
deleteReps(timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
Repetition rep = new Repetition();
|
||||
rep.habit = this;
|
||||
rep.timestamp = timestamp;
|
||||
rep.save();
|
||||
}
|
||||
|
||||
deleteScoresNewerThan(timestamp);
|
||||
deleteCheckmarksNewerThan(timestamp);
|
||||
deleteStreaksNewerThan(timestamp);
|
||||
}
|
||||
|
||||
public Uri getUri()
|
||||
{
|
||||
return Uri.parse(String.format("content://org.isoron.uhabits/habit/%d", getId()));
|
||||
@@ -466,204 +251,4 @@ public class Habit extends Model
|
||||
{
|
||||
return archived != 0;
|
||||
}
|
||||
|
||||
public void toggleRepetitionToday()
|
||||
{
|
||||
toggleRepetition(DateHelper.getStartOfToday());
|
||||
}
|
||||
|
||||
public Score getNewestScore()
|
||||
{
|
||||
return new Select().from(Score.class)
|
||||
.where("habit = ?", getId())
|
||||
.orderBy("timestamp desc")
|
||||
.limit(1)
|
||||
.executeSingle();
|
||||
}
|
||||
|
||||
public void deleteScoresNewerThan(long timestamp)
|
||||
{
|
||||
new Delete().from(Score.class)
|
||||
.where("habit = ?", getId())
|
||||
.and("timestamp >= ?", timestamp)
|
||||
.execute();
|
||||
}
|
||||
|
||||
public Integer getScore()
|
||||
{
|
||||
int beginningScore;
|
||||
long beginningTime;
|
||||
|
||||
long today = DateHelper.getStartOfDay(DateHelper.getLocalTime());
|
||||
long day = DateHelper.millisecondsInOneDay;
|
||||
|
||||
double freq = ((double) freqNum) / freqDen;
|
||||
double multiplier = Math.pow(0.5, 1.0 / (14.0 / freq - 1));
|
||||
|
||||
Score newestScore = getNewestScore();
|
||||
if (newestScore == null)
|
||||
{
|
||||
Repetition oldestRep = getOldestRep();
|
||||
if (oldestRep == null) return 0;
|
||||
beginningTime = oldestRep.timestamp;
|
||||
beginningScore = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
beginningTime = newestScore.timestamp + day;
|
||||
beginningScore = newestScore.score;
|
||||
}
|
||||
|
||||
long nDays = (today - beginningTime) / day;
|
||||
if (nDays < 0) return newestScore.score;
|
||||
|
||||
int reps[] = getCheckmarks(beginningTime, today);
|
||||
|
||||
ActiveAndroid.beginTransaction();
|
||||
int lastScore = beginningScore;
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < reps.length; i++)
|
||||
{
|
||||
Score s = new Score();
|
||||
s.habit = this;
|
||||
s.timestamp = beginningTime + day * i;
|
||||
s.score = (int) (lastScore * multiplier);
|
||||
if (reps[reps.length - i - 1] == 2)
|
||||
{
|
||||
s.score += 1000000;
|
||||
s.score = Math.min(s.score, MAX_SCORE);
|
||||
}
|
||||
s.save();
|
||||
|
||||
lastScore = s.score;
|
||||
}
|
||||
|
||||
ActiveAndroid.setTransactionSuccessful();
|
||||
} finally
|
||||
{
|
||||
ActiveAndroid.endTransaction();
|
||||
}
|
||||
|
||||
return lastScore;
|
||||
}
|
||||
|
||||
public int[] getScores(Long fromTimestamp, Long toTimestamp, Integer divisor, Long offset)
|
||||
{
|
||||
String query = "select score from Score where habit = ? and timestamp > ? and " +
|
||||
"timestamp <= ? and (timestamp - ?) % ? = 0 order by timestamp desc";
|
||||
|
||||
String params[] = {getId().toString(), fromTimestamp.toString(), toTimestamp.toString(),
|
||||
offset.toString(), divisor.toString()};
|
||||
|
||||
SQLiteDatabase db = Cache.openDatabase();
|
||||
Cursor cursor = db.rawQuery(query, params);
|
||||
|
||||
if(!cursor.moveToFirst()) return new int[0];
|
||||
|
||||
int k = 0;
|
||||
int[] scores = new int[cursor.getCount()];
|
||||
|
||||
do
|
||||
{
|
||||
scores[k++] = cursor.getInt(0);
|
||||
}
|
||||
while (cursor.moveToNext());
|
||||
|
||||
cursor.close();
|
||||
return scores;
|
||||
|
||||
}
|
||||
|
||||
public int[] getAllScores(int divisor)
|
||||
{
|
||||
Repetition oldestRep = getOldestRep();
|
||||
if(oldestRep == null) return new int[0];
|
||||
|
||||
long fromTimestamp = oldestRep.timestamp;
|
||||
long toTimestamp = DateHelper.getStartOfToday();
|
||||
return getScores(fromTimestamp, toTimestamp, divisor, toTimestamp);
|
||||
}
|
||||
|
||||
public List<Streak> getStreaks()
|
||||
{
|
||||
updateStreaks();
|
||||
|
||||
return new Select().from(Streak.class)
|
||||
.where("habit = ?", getId())
|
||||
.orderBy("end asc")
|
||||
.execute();
|
||||
}
|
||||
|
||||
public Streak getNewestStreak()
|
||||
{
|
||||
return new Select().from(Streak.class)
|
||||
.where("habit = ?", getId())
|
||||
.orderBy("end desc")
|
||||
.limit(1)
|
||||
.executeSingle();
|
||||
}
|
||||
|
||||
public void updateStreaks()
|
||||
{
|
||||
long beginning;
|
||||
long today = DateHelper.getStartOfToday();
|
||||
long day = DateHelper.millisecondsInOneDay;
|
||||
|
||||
Streak newestStreak = getNewestStreak();
|
||||
if (newestStreak == null)
|
||||
{
|
||||
Repetition oldestRep = getOldestRep();
|
||||
if (oldestRep == null) return;
|
||||
|
||||
beginning = oldestRep.timestamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
Repetition oldestRep = getOldestRepNewerThan(newestStreak.end);
|
||||
if (oldestRep == null) return;
|
||||
|
||||
beginning = oldestRep.timestamp;
|
||||
}
|
||||
|
||||
if (beginning > today) return;
|
||||
|
||||
int checks[] = getCheckmarks(beginning, today);
|
||||
ArrayList<Long> list = new ArrayList<>();
|
||||
|
||||
long current = beginning;
|
||||
list.add(current);
|
||||
|
||||
for (int i = 1; i < checks.length; i++)
|
||||
{
|
||||
current += day;
|
||||
int j = checks.length - i - 1;
|
||||
|
||||
if ((checks[j + 1] == 0 && checks[j] > 0)) list.add(current);
|
||||
if ((checks[j + 1] > 0 && checks[j] == 0)) list.add(current - day);
|
||||
}
|
||||
|
||||
if (list.size() % 2 == 1) list.add(current);
|
||||
|
||||
ActiveAndroid.beginTransaction();
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < list.size(); i += 2)
|
||||
{
|
||||
Streak streak = new Streak();
|
||||
streak.habit = this;
|
||||
streak.start = list.get(i);
|
||||
streak.end = list.get(i + 1);
|
||||
streak.length = (streak.end - streak.start) / day + 1;
|
||||
streak.save();
|
||||
}
|
||||
|
||||
ActiveAndroid.setTransactionSuccessful();
|
||||
} finally
|
||||
{
|
||||
ActiveAndroid.endTransaction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/* Copyright (C) 2016 Alinson Santos Xavier
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.models;
|
||||
|
||||
import com.activeandroid.query.Delete;
|
||||
import com.activeandroid.query.From;
|
||||
import com.activeandroid.query.Select;
|
||||
|
||||
import org.isoron.helpers.DateHelper;
|
||||
|
||||
public class RepetitionList
|
||||
{
|
||||
|
||||
private Habit habit;
|
||||
|
||||
public RepetitionList(Habit habit)
|
||||
{
|
||||
this.habit = habit;
|
||||
}
|
||||
|
||||
protected From select()
|
||||
{
|
||||
return new Select().from(Repetition.class)
|
||||
.where("habit = ?", habit.getId())
|
||||
.orderBy("timestamp");
|
||||
}
|
||||
|
||||
protected From selectFromTo(long timeFrom, long timeTo)
|
||||
{
|
||||
return select().and("timestamp >= ?", timeFrom).and("timestamp <= ?", timeTo);
|
||||
}
|
||||
|
||||
public boolean contains(long timestamp)
|
||||
{
|
||||
int count = select().where("timestamp = ?", timestamp).count();
|
||||
return (count > 0);
|
||||
}
|
||||
|
||||
public void delete(long timestamp)
|
||||
{
|
||||
new Delete().from(Repetition.class)
|
||||
.where("habit = ?", habit.getId())
|
||||
.and("timestamp = ?", timestamp)
|
||||
.execute();
|
||||
}
|
||||
|
||||
public Repetition getOldestNewerThan(long timestamp)
|
||||
{
|
||||
return select().where("timestamp > ?", timestamp).limit(1).executeSingle();
|
||||
}
|
||||
|
||||
public void toggle(long timestamp)
|
||||
{
|
||||
if (contains(timestamp))
|
||||
{
|
||||
delete(timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
Repetition rep = new Repetition();
|
||||
rep.habit = habit;
|
||||
rep.timestamp = timestamp;
|
||||
rep.save();
|
||||
}
|
||||
|
||||
habit.scores.deleteNewerThan(timestamp);
|
||||
habit.checkmarks.deleteNewerThan(timestamp);
|
||||
habit.streaks.deleteNewerThan(timestamp);
|
||||
}
|
||||
|
||||
public Repetition getOldest()
|
||||
{
|
||||
return (Repetition) select().limit(1).executeSingle();
|
||||
}
|
||||
|
||||
public boolean hasImplicitRepToday()
|
||||
{
|
||||
long today = DateHelper.getStartOfToday();
|
||||
int reps[] = habit.checkmarks.getValues(today - DateHelper.millisecondsInOneDay, today);
|
||||
return (reps[0] > 0);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,10 @@ import com.activeandroid.annotation.Table;
|
||||
@Table(name = "Score")
|
||||
public class Score extends Model
|
||||
{
|
||||
public static final int HALF_STAR_CUTOFF = 9629750;
|
||||
public static final int FULL_STAR_CUTOFF = 15407600;
|
||||
public static final int MAX_SCORE = 19259500;
|
||||
|
||||
@Column(name = "habit")
|
||||
public Habit habit;
|
||||
|
||||
|
||||
160
app/src/main/java/org/isoron/uhabits/models/ScoreList.java
Normal file
160
app/src/main/java/org/isoron/uhabits/models/ScoreList.java
Normal file
@@ -0,0 +1,160 @@
|
||||
/* Copyright (C) 2016 Alinson Santos Xavier
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.models;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import com.activeandroid.ActiveAndroid;
|
||||
import com.activeandroid.Cache;
|
||||
import com.activeandroid.query.Delete;
|
||||
import com.activeandroid.query.Select;
|
||||
|
||||
import org.isoron.helpers.DateHelper;
|
||||
|
||||
public class ScoreList
|
||||
{
|
||||
private Habit habit;
|
||||
|
||||
public ScoreList(Habit habit)
|
||||
{
|
||||
this.habit = habit;
|
||||
}
|
||||
|
||||
public int getCurrentStarStatus()
|
||||
{
|
||||
int score = getNewestValue();
|
||||
|
||||
if(score >= Score.FULL_STAR_CUTOFF) return 2;
|
||||
else if(score >= Score.HALF_STAR_CUTOFF) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
public Score getNewest()
|
||||
{
|
||||
return new Select().from(Score.class)
|
||||
.where("habit = ?", habit.getId())
|
||||
.orderBy("timestamp desc")
|
||||
.limit(1)
|
||||
.executeSingle();
|
||||
}
|
||||
|
||||
public void deleteNewerThan(long timestamp)
|
||||
{
|
||||
new Delete().from(Score.class)
|
||||
.where("habit = ?", habit.getId())
|
||||
.and("timestamp >= ?", timestamp)
|
||||
.execute();
|
||||
}
|
||||
|
||||
public Integer getNewestValue()
|
||||
{
|
||||
int beginningScore;
|
||||
long beginningTime;
|
||||
|
||||
long today = DateHelper.getStartOfDay(DateHelper.getLocalTime());
|
||||
long day = DateHelper.millisecondsInOneDay;
|
||||
|
||||
double freq = ((double) habit.freqNum) / habit.freqDen;
|
||||
double multiplier = Math.pow(0.5, 1.0 / (14.0 / freq - 1));
|
||||
|
||||
Score newestScore = getNewest();
|
||||
if (newestScore == null)
|
||||
{
|
||||
Repetition oldestRep = habit.repetitions.getOldest();
|
||||
if (oldestRep == null) return 0;
|
||||
beginningTime = oldestRep.timestamp;
|
||||
beginningScore = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
beginningTime = newestScore.timestamp + day;
|
||||
beginningScore = newestScore.score;
|
||||
}
|
||||
|
||||
long nDays = (today - beginningTime) / day;
|
||||
if (nDays < 0) return newestScore.score;
|
||||
|
||||
int reps[] = habit.checkmarks.getValues(beginningTime, today);
|
||||
|
||||
ActiveAndroid.beginTransaction();
|
||||
int lastScore = beginningScore;
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < reps.length; i++)
|
||||
{
|
||||
Score s = new Score();
|
||||
s.habit = habit;
|
||||
s.timestamp = beginningTime + day * i;
|
||||
s.score = (int) (lastScore * multiplier);
|
||||
if (reps[reps.length - i - 1] == 2)
|
||||
{
|
||||
s.score += 1000000;
|
||||
s.score = Math.min(s.score, Score.MAX_SCORE);
|
||||
}
|
||||
s.save();
|
||||
|
||||
lastScore = s.score;
|
||||
}
|
||||
|
||||
ActiveAndroid.setTransactionSuccessful();
|
||||
} finally
|
||||
{
|
||||
ActiveAndroid.endTransaction();
|
||||
}
|
||||
|
||||
return lastScore;
|
||||
}
|
||||
|
||||
public int[] getAllValues(Long fromTimestamp, Long toTimestamp, Integer divisor, Long offset)
|
||||
{
|
||||
String query = "select score from Score where habit = ? and timestamp > ? and " +
|
||||
"timestamp <= ? and (timestamp - ?) % ? = 0 order by timestamp desc";
|
||||
|
||||
String params[] = { habit.getId().toString(), fromTimestamp.toString(),
|
||||
toTimestamp.toString(), offset.toString(), divisor.toString()};
|
||||
|
||||
SQLiteDatabase db = Cache.openDatabase();
|
||||
Cursor cursor = db.rawQuery(query, params);
|
||||
|
||||
if(!cursor.moveToFirst()) return new int[0];
|
||||
|
||||
int k = 0;
|
||||
int[] scores = new int[cursor.getCount()];
|
||||
|
||||
do
|
||||
{
|
||||
scores[k++] = cursor.getInt(0);
|
||||
}
|
||||
while (cursor.moveToNext());
|
||||
|
||||
cursor.close();
|
||||
return scores;
|
||||
|
||||
}
|
||||
|
||||
public int[] getAllValues(int divisor)
|
||||
{
|
||||
Repetition oldestRep = habit.repetitions.getOldest();
|
||||
if(oldestRep == null) return new int[0];
|
||||
|
||||
long fromTimestamp = oldestRep.timestamp;
|
||||
long toTimestamp = DateHelper.getStartOfToday();
|
||||
return getAllValues(fromTimestamp, toTimestamp, divisor, toTimestamp);
|
||||
}
|
||||
}
|
||||
127
app/src/main/java/org/isoron/uhabits/models/StreakList.java
Normal file
127
app/src/main/java/org/isoron/uhabits/models/StreakList.java
Normal file
@@ -0,0 +1,127 @@
|
||||
/* Copyright (C) 2016 Alinson Santos Xavier
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.models;
|
||||
|
||||
import com.activeandroid.ActiveAndroid;
|
||||
import com.activeandroid.query.Delete;
|
||||
import com.activeandroid.query.Select;
|
||||
|
||||
import org.isoron.helpers.DateHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class StreakList
|
||||
{
|
||||
private Habit habit;
|
||||
|
||||
public StreakList(Habit habit)
|
||||
{
|
||||
this.habit = habit;
|
||||
}
|
||||
|
||||
public List<Streak> getAll()
|
||||
{
|
||||
rebuild();
|
||||
|
||||
return new Select().from(Streak.class)
|
||||
.where("habit = ?", habit.getId())
|
||||
.orderBy("end asc")
|
||||
.execute();
|
||||
}
|
||||
|
||||
public Streak getNewest()
|
||||
{
|
||||
return new Select().from(Streak.class)
|
||||
.where("habit = ?", habit.getId())
|
||||
.orderBy("end desc")
|
||||
.limit(1)
|
||||
.executeSingle();
|
||||
}
|
||||
|
||||
public void rebuild()
|
||||
{
|
||||
long beginning;
|
||||
long today = DateHelper.getStartOfToday();
|
||||
long day = DateHelper.millisecondsInOneDay;
|
||||
|
||||
Streak newestStreak = getNewest();
|
||||
if (newestStreak == null)
|
||||
{
|
||||
Repetition oldestRep = habit.repetitions.getOldest();
|
||||
if (oldestRep == null) return;
|
||||
|
||||
beginning = oldestRep.timestamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
Repetition oldestRep = habit.repetitions.getOldestNewerThan(newestStreak.end);
|
||||
if (oldestRep == null) return;
|
||||
|
||||
beginning = oldestRep.timestamp;
|
||||
}
|
||||
|
||||
if (beginning > today) return;
|
||||
|
||||
int checks[] = habit.checkmarks.getValues(beginning, today);
|
||||
ArrayList<Long> list = new ArrayList<>();
|
||||
|
||||
long current = beginning;
|
||||
list.add(current);
|
||||
|
||||
for (int i = 1; i < checks.length; i++)
|
||||
{
|
||||
current += day;
|
||||
int j = checks.length - i - 1;
|
||||
|
||||
if ((checks[j + 1] == 0 && checks[j] > 0)) list.add(current);
|
||||
if ((checks[j + 1] > 0 && checks[j] == 0)) list.add(current - day);
|
||||
}
|
||||
|
||||
if (list.size() % 2 == 1) list.add(current);
|
||||
|
||||
ActiveAndroid.beginTransaction();
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < list.size(); i += 2)
|
||||
{
|
||||
Streak streak = new Streak();
|
||||
streak.habit = habit;
|
||||
streak.start = list.get(i);
|
||||
streak.end = list.get(i + 1);
|
||||
streak.length = (streak.end - streak.start) / day + 1;
|
||||
streak.save();
|
||||
}
|
||||
|
||||
ActiveAndroid.setTransactionSuccessful();
|
||||
}
|
||||
finally
|
||||
{
|
||||
ActiveAndroid.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void deleteNewerThan(long timestamp)
|
||||
{
|
||||
new Delete().from(Streak.class)
|
||||
.where("habit = ?", habit.getId())
|
||||
.and("end >= ?", timestamp - DateHelper.millisecondsInOneDay)
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,6 @@ import android.text.Layout;
|
||||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import org.isoron.helpers.ColorHelper;
|
||||
@@ -112,8 +111,8 @@ public class CheckmarkView extends View
|
||||
|
||||
public void setHabit(Habit habit)
|
||||
{
|
||||
this.check_status = habit.getCurrentCheckmarkStatus();
|
||||
this.star_status = habit.getCurrentStarStatus();
|
||||
this.check_status = habit.checkmarks.getCurrentValue();
|
||||
this.star_status = habit.scores.getCurrentStarStatus();
|
||||
this.primaryColor = Color.argb(230, Color.red(habit.color), Color.green(habit.color), Color.blue(habit.color));
|
||||
this.label = habit.name;
|
||||
updateLabel();
|
||||
|
||||
@@ -23,7 +23,6 @@ import android.graphics.Paint;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import org.isoron.helpers.ColorHelper;
|
||||
import org.isoron.helpers.DateHelper;
|
||||
@@ -189,7 +188,7 @@ public class HabitHistoryView extends ScrollableDataView
|
||||
return;
|
||||
}
|
||||
|
||||
checkmarks = habit.getAllCheckmarks();
|
||||
checkmarks = habit.checkmarks.getAllValues();
|
||||
}
|
||||
|
||||
updateDate();
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.util.AttributeSet;
|
||||
import org.isoron.helpers.ColorHelper;
|
||||
import org.isoron.helpers.DateHelper;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
import org.isoron.uhabits.models.Score;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Locale;
|
||||
@@ -168,7 +169,7 @@ public class HabitScoreView extends ScrollableDataView
|
||||
return;
|
||||
}
|
||||
|
||||
scores = habit.getAllScores(BUCKET_SIZE * DateHelper.millisecondsInOneDay);
|
||||
scores = habit.scores.getAllValues(BUCKET_SIZE * DateHelper.millisecondsInOneDay);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -177,13 +178,13 @@ public class HabitScoreView extends ScrollableDataView
|
||||
{
|
||||
Random random = new Random();
|
||||
scores = new int[100];
|
||||
scores[0] = Habit.MAX_SCORE / 2;
|
||||
scores[0] = Score.MAX_SCORE / 2;
|
||||
|
||||
for(int i = 1; i < 100; i++)
|
||||
{
|
||||
int step = Habit.MAX_SCORE / 10;
|
||||
int step = Score.MAX_SCORE / 10;
|
||||
scores[i] = scores[i - 1] + random.nextInt(step * 2) - step;
|
||||
scores[i] = Math.max(0, Math.min(Habit.MAX_SCORE, scores[i]));
|
||||
scores[i] = Math.max(0, Math.min(Score.MAX_SCORE, scores[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +221,7 @@ public class HabitScoreView extends ScrollableDataView
|
||||
int offset = nColumns - k - 1 + getDataOffset();
|
||||
if(offset < scores.length) score = scores[offset];
|
||||
|
||||
double sRelative = ((double) score) / Habit.MAX_SCORE;
|
||||
double sRelative = ((double) score) / Score.MAX_SCORE;
|
||||
int height = (int) (columnHeight * sRelative);
|
||||
|
||||
rect.set(0, 0, baseSize, baseSize);
|
||||
|
||||
@@ -166,7 +166,7 @@ public class HabitStreakView extends ScrollableDataView
|
||||
return;
|
||||
}
|
||||
|
||||
List<Streak> streaks = habit.getStreaks();
|
||||
List<Streak> streaks = habit.streaks.getAll();
|
||||
int size = streaks.size();
|
||||
|
||||
startTimes = new long[size];
|
||||
|
||||
Reference in New Issue
Block a user