mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 17:18:52 -06:00
Refactor tasks; break progress bars
This commit is contained in:
@@ -60,6 +60,9 @@ public class BaseAndroidTest
|
||||
@Inject
|
||||
protected CommandRunner commandRunner;
|
||||
|
||||
@Inject
|
||||
protected TaskRunner taskRunner;
|
||||
|
||||
@Inject
|
||||
protected HabitLogger logger;
|
||||
|
||||
@@ -139,7 +142,7 @@ public class BaseAndroidTest
|
||||
return;
|
||||
}
|
||||
|
||||
BaseTask.waitForTasks(10000);
|
||||
taskRunner.waitForTasks(10000);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -40,6 +40,7 @@ import static org.hamcrest.core.IsNot.not;
|
||||
public class ExportCSVTaskTest extends BaseAndroidTest
|
||||
{
|
||||
@Before
|
||||
@Override
|
||||
public void setUp()
|
||||
{
|
||||
super.setUp();
|
||||
@@ -48,20 +49,20 @@ public class ExportCSVTaskTest extends BaseAndroidTest
|
||||
@Test
|
||||
public void testExportCSV() throws Throwable
|
||||
{
|
||||
fixtures.purgeHabits(habitList);
|
||||
fixtures.createShortHabit();
|
||||
|
||||
List<Habit> selected = new LinkedList<>();
|
||||
for(Habit h : habitList) selected.add(h);
|
||||
for (Habit h : habitList) selected.add(h);
|
||||
|
||||
ExportCSVTask task = new ExportCSVTask(habitList, selected, null);
|
||||
task.setListener(archiveFilename -> {
|
||||
taskRunner.execute(
|
||||
new ExportCSVTask(habitList, selected, archiveFilename -> {
|
||||
assertThat(archiveFilename, is(not(nullValue())));
|
||||
|
||||
File f = new File(archiveFilename);
|
||||
assertTrue(f.exists());
|
||||
assertTrue(f.canRead());
|
||||
});
|
||||
}));
|
||||
|
||||
task.execute();
|
||||
waitForAsyncTasks();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,20 +19,18 @@
|
||||
|
||||
package org.isoron.uhabits.tasks;
|
||||
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.support.test.runner.*;
|
||||
import android.test.suitebuilder.annotation.*;
|
||||
|
||||
import org.isoron.uhabits.BaseAndroidTest;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.*;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static junit.framework.Assert.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.core.IsNot.not;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@@ -48,21 +46,15 @@ public class ExportDBTaskTest extends BaseAndroidTest
|
||||
@Test
|
||||
public void testExportCSV() throws Throwable
|
||||
{
|
||||
ExportDBTask task = new ExportDBTask(null);
|
||||
task.setListener(new ExportDBTask.Listener()
|
||||
{
|
||||
@Override
|
||||
public void onExportDBFinished(String filename)
|
||||
{
|
||||
ExportDBTask task = new ExportDBTask(filename -> {
|
||||
assertThat(filename, is(not(nullValue())));
|
||||
|
||||
File f = new File(filename);
|
||||
assertTrue(f.exists());
|
||||
assertTrue(f.canRead());
|
||||
}
|
||||
});
|
||||
|
||||
task.execute();
|
||||
taskRunner.execute(task);
|
||||
waitForAsyncTasks();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,23 +19,18 @@
|
||||
|
||||
package org.isoron.uhabits.tasks;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.support.test.runner.*;
|
||||
import android.test.suitebuilder.annotation.*;
|
||||
|
||||
import org.isoron.uhabits.BaseAndroidTest;
|
||||
import org.isoron.uhabits.utils.FileUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.*;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@MediumTest
|
||||
@@ -49,38 +44,7 @@ public class ImportDataTaskTest extends BaseAndroidTest
|
||||
super.setUp();
|
||||
|
||||
baseDir = FileUtils.getFilesDir("Backups");
|
||||
if(baseDir == null) fail("baseDir should not be null");
|
||||
}
|
||||
|
||||
private void copyAssetToFile(String assetPath, File dst) throws IOException
|
||||
{
|
||||
InputStream in = testContext.getAssets().open(assetPath);
|
||||
FileUtils.copy(in, dst);
|
||||
}
|
||||
|
||||
private void assertTaskResult(final int expectedResult, String assetFilename) throws Throwable
|
||||
{
|
||||
ImportDataTask task = createTask(assetFilename);
|
||||
|
||||
task.setListener(new ImportDataTask.Listener()
|
||||
{
|
||||
@Override
|
||||
public void onImportDataFinished(int result)
|
||||
{
|
||||
assertThat(result, equalTo(expectedResult));
|
||||
}
|
||||
});
|
||||
|
||||
task.execute();
|
||||
waitForAsyncTasks();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private ImportDataTask createTask(String assetFilename) throws IOException
|
||||
{
|
||||
File file = new File(String.format("%s/%s", baseDir.getPath(), assetFilename));
|
||||
copyAssetToFile(assetFilename, file);
|
||||
return new ImportDataTask(habitList, file, null);
|
||||
if (baseDir == null) fail("baseDir should not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -94,4 +58,22 @@ public class ImportDataTaskTest extends BaseAndroidTest
|
||||
{
|
||||
assertTaskResult(ImportDataTask.SUCCESS, "loop.db");
|
||||
}
|
||||
|
||||
private void assertTaskResult(final int expectedResult,
|
||||
String assetFilename) throws Throwable
|
||||
{
|
||||
File file = new File(baseDir.getPath() + "/" + assetFilename);
|
||||
copyAssetToFile(assetFilename, file);
|
||||
|
||||
taskRunner.execute(new ImportDataTask(habitList, file,
|
||||
(result) -> assertThat(result, equalTo(expectedResult))));
|
||||
|
||||
waitForAsyncTasks();
|
||||
}
|
||||
|
||||
private void copyAssetToFile(String assetPath, File dst) throws IOException
|
||||
{
|
||||
InputStream in = testContext.getAssets().open(assetPath);
|
||||
FileUtils.copy(in, dst);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,18 +42,22 @@ import org.isoron.uhabits.widgets.*;
|
||||
*/
|
||||
public interface BaseComponent
|
||||
{
|
||||
CommandRunner getCommandRunner();
|
||||
|
||||
HabitList getHabitList();
|
||||
|
||||
IntentFactory getIntentFactory();
|
||||
|
||||
ReminderScheduler getReminderScheduler();
|
||||
|
||||
TaskRunner getTaskRunner();
|
||||
|
||||
void inject(CheckmarkButtonController checkmarkButtonController);
|
||||
|
||||
void inject(ListHabitsController listHabitsController);
|
||||
|
||||
void inject(CheckmarkPanelView checkmarkPanelView);
|
||||
|
||||
void inject(ToggleRepetitionTask toggleRepetitionTask);
|
||||
|
||||
void inject(HabitCardListCache habitCardListCache);
|
||||
|
||||
void inject(WidgetReceiver widgetReceiver);
|
||||
|
||||
void inject(ListHabitsSelectionMenu listHabitsSelectionMenu);
|
||||
@@ -84,8 +88,6 @@ public interface BaseComponent
|
||||
|
||||
void inject(BaseSystem baseSystem);
|
||||
|
||||
void inject(HistoryEditorDialog historyEditorDialog);
|
||||
|
||||
void inject(HabitsApplication application);
|
||||
|
||||
void inject(Habit habit);
|
||||
@@ -110,8 +112,6 @@ public interface BaseComponent
|
||||
|
||||
void inject(ReceiverActions receiverActions);
|
||||
|
||||
void inject(ReminderReceiver reminderReceiver);
|
||||
|
||||
void inject(ReminderScheduler reminderScheduler);
|
||||
|
||||
void inject(ListHabitsScreen listHabitsScreen);
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
|
||||
package org.isoron.uhabits.commands;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.uhabits.tasks.BaseTask;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.tasks.*;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
@@ -37,19 +37,17 @@ import javax.inject.*;
|
||||
@Singleton
|
||||
public class CommandRunner
|
||||
{
|
||||
private TaskRunner taskRunner;
|
||||
|
||||
private LinkedList<Listener> listeners;
|
||||
|
||||
@Inject
|
||||
public CommandRunner()
|
||||
{
|
||||
taskRunner = HabitsApplication.getComponent().getTaskRunner();
|
||||
listeners = new LinkedList<>();
|
||||
}
|
||||
|
||||
private static CommandRunner getInstance()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addListener(Listener l)
|
||||
{
|
||||
listeners.add(l);
|
||||
@@ -57,23 +55,21 @@ public class CommandRunner
|
||||
|
||||
public void execute(final Command command, final Long refreshKey)
|
||||
{
|
||||
new BaseTask()
|
||||
taskRunner.execute(new Task()
|
||||
{
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
public void doInBackground()
|
||||
{
|
||||
command.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
public void onPostExecute()
|
||||
{
|
||||
for (Listener l : listeners)
|
||||
l.onCommandExecuted(command, refreshKey);
|
||||
|
||||
super.onPostExecute(null);
|
||||
}
|
||||
}.execute();
|
||||
});
|
||||
}
|
||||
|
||||
public void removeListener(Listener l)
|
||||
|
||||
@@ -46,7 +46,10 @@ public class PebbleReceiver extends PebbleDataReceiver
|
||||
protected HabitList allHabits;
|
||||
|
||||
@Inject
|
||||
protected CommandRunner runner;
|
||||
protected CommandRunner commandRunner;
|
||||
|
||||
@Inject
|
||||
protected TaskRunner taskRunner;
|
||||
|
||||
protected HabitList filteredHabits;
|
||||
|
||||
@@ -74,7 +77,7 @@ public class PebbleReceiver extends PebbleDataReceiver
|
||||
PebbleKit.sendAckToPebble(context, transactionId);
|
||||
Log.d("PebbleReceiver", "<-- " + data.getString(0));
|
||||
|
||||
new SimpleTask(() -> {
|
||||
taskRunner.execute(() -> {
|
||||
switch (data.getString(0))
|
||||
{
|
||||
case "COUNT":
|
||||
@@ -89,7 +92,7 @@ public class PebbleReceiver extends PebbleDataReceiver
|
||||
processToggle(data);
|
||||
break;
|
||||
}
|
||||
}).execute();
|
||||
});
|
||||
}
|
||||
|
||||
private void processFetch(@NonNull PebbleDictionary dict)
|
||||
@@ -113,7 +116,8 @@ public class PebbleReceiver extends PebbleDataReceiver
|
||||
if (habit == null) return;
|
||||
|
||||
long today = DateUtils.getStartOfToday();
|
||||
runner.execute(new ToggleRepetitionCommand(habit, today), habitId);
|
||||
commandRunner.execute(new ToggleRepetitionCommand(habit, today),
|
||||
habitId);
|
||||
|
||||
sendOK();
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.support.annotation.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.commands.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.tasks.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
@@ -54,9 +53,7 @@ public class ReceiverActions
|
||||
|
||||
public void toggle_repetition(@NonNull Habit habit, long timestamp)
|
||||
{
|
||||
new SimpleTask(() -> {
|
||||
commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp),
|
||||
habit.getId());
|
||||
}).execute();
|
||||
commandRunner.execute(
|
||||
new ToggleRepetitionCommand(habit, timestamp), habit.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,6 @@ import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
/**
|
||||
* The Android BroadcastReceiver for Loop Habit Tracker.
|
||||
* <p>
|
||||
@@ -56,16 +54,20 @@ public class ReminderReceiver extends BroadcastReceiver
|
||||
|
||||
private static final String TAG = "ReminderReceiver";
|
||||
|
||||
@Inject
|
||||
HabitList habits;
|
||||
private final HabitList habits;
|
||||
|
||||
@Inject
|
||||
ReminderScheduler reminderScheduler;
|
||||
private final TaskRunner taskRunner;
|
||||
|
||||
private final ReminderScheduler reminderScheduler;
|
||||
|
||||
public ReminderReceiver()
|
||||
{
|
||||
super();
|
||||
HabitsApplication.getComponent().inject(this);
|
||||
|
||||
BaseComponent component = HabitsApplication.getComponent();
|
||||
habits = component.getHabitList();
|
||||
taskRunner = component.getTaskRunner();
|
||||
reminderScheduler = component.getReminderScheduler();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,25 +117,25 @@ public class ReminderReceiver extends BroadcastReceiver
|
||||
{
|
||||
final Uri data = intent.getData();
|
||||
final Habit habit = habits.getById(ContentUris.parseId(data));
|
||||
final Long timestamp = intent.getLongExtra("timestamp",
|
||||
DateUtils.getStartOfToday());
|
||||
final Long reminderTime = intent.getLongExtra("reminderTime",
|
||||
DateUtils.getStartOfToday());
|
||||
final Long timestamp =
|
||||
intent.getLongExtra("timestamp", DateUtils.getStartOfToday());
|
||||
final Long reminderTime =
|
||||
intent.getLongExtra("reminderTime", DateUtils.getStartOfToday());
|
||||
|
||||
if (habit == null) return;
|
||||
|
||||
new BaseTask()
|
||||
taskRunner.execute(new Task()
|
||||
{
|
||||
int todayValue;
|
||||
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
public void doInBackground()
|
||||
{
|
||||
todayValue = habit.getCheckmarks().getTodayValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
public void onPostExecute()
|
||||
{
|
||||
if (todayValue != Checkmark.UNCHECKED) return;
|
||||
if (!shouldShowReminderToday(intent, habit)) return;
|
||||
@@ -141,15 +143,16 @@ public class ReminderReceiver extends BroadcastReceiver
|
||||
|
||||
Intent contentIntent = new Intent(context, MainActivity.class);
|
||||
contentIntent.setData(data);
|
||||
PendingIntent contentPendingIntent = PendingIntent.getActivity(
|
||||
context, 0, contentIntent,
|
||||
PendingIntent contentPendingIntent =
|
||||
PendingIntent.getActivity(context, 0, contentIntent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
|
||||
PendingIntentFactory
|
||||
pendingIntentFactory = new PendingIntentFactory(context);
|
||||
PendingIntentFactory pendingIntentFactory =
|
||||
new PendingIntentFactory(context);
|
||||
|
||||
PendingIntent dismissPendingIntent;
|
||||
dismissPendingIntent = pendingIntentFactory.dismissNotification();
|
||||
dismissPendingIntent =
|
||||
pendingIntentFactory.dismissNotification();
|
||||
PendingIntent checkIntentPending =
|
||||
pendingIntentFactory.addCheckmark(habit, timestamp);
|
||||
PendingIntent snoozeIntentPending =
|
||||
@@ -159,12 +162,11 @@ public class ReminderReceiver extends BroadcastReceiver
|
||||
|
||||
NotificationCompat.WearableExtender wearableExtender =
|
||||
new NotificationCompat.WearableExtender().setBackground(
|
||||
BitmapFactory.decodeResource(
|
||||
context.getResources(),
|
||||
BitmapFactory.decodeResource(context.getResources(),
|
||||
R.drawable.stripe));
|
||||
|
||||
Notification notification = new NotificationCompat.Builder(
|
||||
context)
|
||||
Notification notification =
|
||||
new NotificationCompat.Builder(context)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setContentTitle(habit.getName())
|
||||
.setContentText(habit.getDescription())
|
||||
@@ -190,10 +192,8 @@ public class ReminderReceiver extends BroadcastReceiver
|
||||
|
||||
int notificationId = (int) (habit.getId() % Integer.MAX_VALUE);
|
||||
notificationManager.notify(notificationId, notification);
|
||||
|
||||
super.onPostExecute(aVoid);
|
||||
}
|
||||
}.execute();
|
||||
});
|
||||
}
|
||||
|
||||
private void createReminderAlarmsDelayed()
|
||||
@@ -216,10 +216,10 @@ public class ReminderReceiver extends BroadcastReceiver
|
||||
private void onActionSnoozeReminder(Context context, Intent intent)
|
||||
{
|
||||
Uri data = intent.getData();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
|
||||
context);
|
||||
long delayMinutes = Long.parseLong(
|
||||
prefs.getString("pref_snooze_interval", "15"));
|
||||
SharedPreferences prefs =
|
||||
PreferenceManager.getDefaultSharedPreferences(context);
|
||||
long delayMinutes =
|
||||
Long.parseLong(prefs.getString("pref_snooze_interval", "15"));
|
||||
|
||||
long habitId = ContentUris.parseId(data);
|
||||
Habit habit = habits.getById(habitId);
|
||||
@@ -238,11 +238,11 @@ public class ReminderReceiver extends BroadcastReceiver
|
||||
if (!habit.hasReminder()) return false;
|
||||
Reminder reminder = habit.getReminder();
|
||||
|
||||
Long timestamp = intent.getLongExtra("timestamp",
|
||||
DateUtils.getStartOfToday());
|
||||
Long timestamp =
|
||||
intent.getLongExtra("timestamp", DateUtils.getStartOfToday());
|
||||
|
||||
boolean reminderDays[] = DateUtils.unpackWeekdayList(
|
||||
reminder.getDays());
|
||||
boolean reminderDays[] =
|
||||
DateUtils.unpackWeekdayList(reminder.getDays());
|
||||
int weekday = DateUtils.getWeekday(timestamp);
|
||||
|
||||
return reminderDays[weekday];
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.uhabits.tasks;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.*;
|
||||
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
public abstract class BaseTask extends AsyncTask<Void, Integer, Void>
|
||||
{
|
||||
private static int activeTaskCount;
|
||||
|
||||
@CallSuper
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
{
|
||||
super.onPreExecute();
|
||||
activeTaskCount++;
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
{
|
||||
activeTaskCount--;
|
||||
super.onPostExecute(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final Void doInBackground(Void... params)
|
||||
{
|
||||
doInBackground();
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract void doInBackground();
|
||||
|
||||
public static void waitForTasks(long timeout)
|
||||
throws TimeoutException, InterruptedException
|
||||
{
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
|
||||
throw new UnsupportedOperationException("waitForTasks requires API 16+");
|
||||
|
||||
int poolInterval = 100;
|
||||
|
||||
while(timeout > 0)
|
||||
{
|
||||
if(activeTaskCount == 0) return;
|
||||
|
||||
timeout -= poolInterval;
|
||||
Thread.sleep(poolInterval);
|
||||
}
|
||||
|
||||
throw new TimeoutException();
|
||||
}
|
||||
}
|
||||
@@ -28,43 +28,38 @@ import org.isoron.uhabits.utils.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ExportCSVTask extends BaseTask
|
||||
public class ExportCSVTask implements Task
|
||||
{
|
||||
private ProgressBar progressBar;
|
||||
|
||||
private final List<Habit> selectedHabits;
|
||||
|
||||
private String archiveFilename;
|
||||
|
||||
private ExportCSVTask.Listener listener;
|
||||
@NonNull
|
||||
private final List<Habit> selectedHabits;
|
||||
|
||||
@NonNull
|
||||
private final ExportCSVTask.Listener listener;
|
||||
|
||||
@NonNull
|
||||
private final HabitList habitList;
|
||||
|
||||
public ExportCSVTask(HabitList habitList,
|
||||
List<Habit> selectedHabits,
|
||||
ProgressBar progressBar)
|
||||
{
|
||||
this.habitList = habitList;
|
||||
this.selectedHabits = selectedHabits;
|
||||
this.progressBar = progressBar;
|
||||
}
|
||||
|
||||
public void setListener(Listener listener)
|
||||
public ExportCSVTask(@NonNull HabitList habitList,
|
||||
@NonNull List<Habit> selectedHabits,
|
||||
@NonNull Listener listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
this.habitList = habitList;
|
||||
this.selectedHabits = selectedHabits;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
public void doInBackground()
|
||||
{
|
||||
try
|
||||
{
|
||||
File dir = FileUtils.getFilesDir("CSV");
|
||||
if (dir == null) return;
|
||||
|
||||
HabitsCSVExporter exporter =
|
||||
new HabitsCSVExporter(habitList, selectedHabits, dir);
|
||||
HabitsCSVExporter exporter;
|
||||
exporter = new HabitsCSVExporter(habitList, selectedHabits, dir);
|
||||
archiveFilename = exporter.writeArchive();
|
||||
}
|
||||
catch (IOException e)
|
||||
@@ -74,19 +69,9 @@ public class ExportCSVTask extends BaseTask
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
public void onPostExecute()
|
||||
{
|
||||
if (listener != null) listener.onExportCSVFinished(archiveFilename);
|
||||
|
||||
if (progressBar != null) progressBar.hide();
|
||||
super.onPostExecute(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
{
|
||||
super.onPreExecute();
|
||||
if (progressBar != null) progressBar.show();
|
||||
listener.onExportCSVFinished(archiveFilename);
|
||||
}
|
||||
|
||||
public interface Listener
|
||||
|
||||
@@ -19,65 +19,50 @@
|
||||
|
||||
package org.isoron.uhabits.tasks;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.uhabits.utils.DatabaseUtils;
|
||||
import org.isoron.uhabits.utils.FileUtils;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
|
||||
public class ExportDBTask extends BaseTask
|
||||
public class ExportDBTask implements Task
|
||||
{
|
||||
public interface Listener
|
||||
{
|
||||
void onExportDBFinished(@Nullable String filename);
|
||||
}
|
||||
|
||||
private ProgressBar progressBar;
|
||||
private String filename;
|
||||
private Listener listener;
|
||||
|
||||
public ExportDBTask(ProgressBar progressBar)
|
||||
{
|
||||
this.progressBar = progressBar;
|
||||
}
|
||||
@NonNull
|
||||
private final Listener listener;
|
||||
|
||||
public void setListener(Listener listener)
|
||||
public ExportDBTask(@NonNull Listener listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
{
|
||||
super.onPreExecute();
|
||||
if(progressBar != null) progressBar.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
{
|
||||
if(listener != null) listener.onExportDBFinished(filename);
|
||||
if(progressBar != null) progressBar.hide();
|
||||
super.onPostExecute(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
public void doInBackground()
|
||||
{
|
||||
filename = null;
|
||||
|
||||
try
|
||||
{
|
||||
File dir = FileUtils.getFilesDir("Backups");
|
||||
if(dir == null) return;
|
||||
if (dir == null) return;
|
||||
|
||||
filename = DatabaseUtils.saveDatabaseCopy(dir);
|
||||
}
|
||||
catch(IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostExecute()
|
||||
{
|
||||
listener.onExportDBFinished(filename);
|
||||
}
|
||||
|
||||
public interface Listener
|
||||
{
|
||||
void onExportDBFinished(@Nullable String filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.isoron.uhabits.models.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class ImportDataTask extends BaseTask
|
||||
public class ImportDataTask implements Task
|
||||
{
|
||||
public static final int FAILED = 3;
|
||||
|
||||
@@ -34,36 +34,28 @@ public class ImportDataTask extends BaseTask
|
||||
|
||||
public static final int SUCCESS = 1;
|
||||
|
||||
@Nullable
|
||||
private final ProgressBar progressBar;
|
||||
int result;
|
||||
|
||||
@NonNull
|
||||
private final File file;
|
||||
|
||||
@Nullable
|
||||
private Listener listener;
|
||||
|
||||
int result;
|
||||
@NonNull
|
||||
private final Listener listener;
|
||||
|
||||
@NonNull
|
||||
private HabitList habits;
|
||||
private final HabitList habits;
|
||||
|
||||
public ImportDataTask(@NonNull HabitList habits,
|
||||
@NonNull File file,
|
||||
@Nullable ProgressBar progressBar)
|
||||
{
|
||||
this.habits = habits;
|
||||
this.file = file;
|
||||
this.progressBar = progressBar;
|
||||
}
|
||||
|
||||
public void setListener(@Nullable Listener listener)
|
||||
@NonNull Listener listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
this.habits = habits;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
public void doInBackground()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -86,19 +78,9 @@ public class ImportDataTask extends BaseTask
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
public void onPostExecute()
|
||||
{
|
||||
if (progressBar != null) progressBar.hide();
|
||||
if (listener != null) listener.onImportDataFinished(result);
|
||||
super.onPostExecute(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
{
|
||||
super.onPreExecute();
|
||||
|
||||
if (progressBar != null) progressBar.show();
|
||||
listener.onImportDataFinished(result);
|
||||
}
|
||||
|
||||
public interface Listener
|
||||
|
||||
@@ -19,24 +19,19 @@
|
||||
|
||||
package org.isoron.uhabits.tasks;
|
||||
|
||||
public class SimpleTask
|
||||
import android.support.annotation.*;
|
||||
|
||||
public interface Task
|
||||
{
|
||||
private final BaseTask baseTask;
|
||||
default void cancel() {}
|
||||
|
||||
public SimpleTask(Runnable runnable)
|
||||
{
|
||||
this.baseTask = new BaseTask()
|
||||
{
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
{
|
||||
runnable.run();
|
||||
}
|
||||
};
|
||||
}
|
||||
void doInBackground();
|
||||
|
||||
public void execute()
|
||||
{
|
||||
baseTask.execute();
|
||||
}
|
||||
default void onAttached(@NonNull TaskRunner runner) {}
|
||||
|
||||
default void onPostExecute() {}
|
||||
|
||||
default void onPreExecute() {}
|
||||
|
||||
default void onProgressUpdate(int value) {}
|
||||
}
|
||||
117
app/src/main/java/org/isoron/uhabits/tasks/TaskRunner.java
Normal file
117
app/src/main/java/org/isoron/uhabits/tasks/TaskRunner.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.tasks;
|
||||
|
||||
import android.os.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
@Singleton
|
||||
public class TaskRunner
|
||||
{
|
||||
private final LinkedList<CustomAsyncTask> activeTasks;
|
||||
|
||||
@Inject
|
||||
public TaskRunner()
|
||||
{
|
||||
activeTasks = new LinkedList<>();
|
||||
}
|
||||
|
||||
public void execute(Task task)
|
||||
{
|
||||
task.onAttached(this);
|
||||
new CustomAsyncTask(task).execute();
|
||||
}
|
||||
|
||||
public void setCurrentProgress(Task task, int progress)
|
||||
{
|
||||
for (CustomAsyncTask asyncTask : activeTasks)
|
||||
if (asyncTask.getTask() == task) asyncTask.publish(progress);
|
||||
}
|
||||
|
||||
public void waitForTasks(long timeout)
|
||||
throws TimeoutException, InterruptedException
|
||||
{
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
|
||||
throw new UnsupportedOperationException("waitForTasks requires API 16+");
|
||||
|
||||
int poolInterval = 100;
|
||||
|
||||
while(timeout > 0)
|
||||
{
|
||||
if(activeTasks.isEmpty()) return;
|
||||
|
||||
timeout -= poolInterval;
|
||||
Thread.sleep(poolInterval);
|
||||
}
|
||||
|
||||
throw new TimeoutException();
|
||||
}
|
||||
|
||||
private class CustomAsyncTask extends AsyncTask<Void, Integer, Void>
|
||||
{
|
||||
private final Task task;
|
||||
|
||||
public CustomAsyncTask(Task task)
|
||||
{
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public Task getTask()
|
||||
{
|
||||
return task;
|
||||
}
|
||||
|
||||
public void publish(int progress)
|
||||
{
|
||||
publishProgress(progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params)
|
||||
{
|
||||
task.doInBackground();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
{
|
||||
task.onPostExecute();
|
||||
activeTasks.remove(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Integer... values)
|
||||
{
|
||||
task.onProgressUpdate(values[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
{
|
||||
activeTasks.add(this);
|
||||
task.onPreExecute();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,49 +19,51 @@
|
||||
|
||||
package org.isoron.uhabits.tasks;
|
||||
|
||||
import org.isoron.uhabits.HabitsApplication;
|
||||
import org.isoron.uhabits.commands.CommandRunner;
|
||||
import org.isoron.uhabits.commands.ToggleRepetitionCommand;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
import android.support.annotation.*;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.commands.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
|
||||
public class ToggleRepetitionTask extends BaseTask
|
||||
public class ToggleRepetitionTask implements Task
|
||||
{
|
||||
@Inject
|
||||
CommandRunner commandRunner;
|
||||
@NonNull
|
||||
private final CommandRunner commandRunner;
|
||||
|
||||
public interface Listener {
|
||||
@NonNull
|
||||
private final Listener listener;
|
||||
|
||||
@NonNull
|
||||
private final Habit habit;
|
||||
|
||||
private final long timestamp;
|
||||
|
||||
public ToggleRepetitionTask(@NonNull Habit habit,
|
||||
long timestamp,
|
||||
@NonNull Listener listener)
|
||||
{
|
||||
this.habit = habit;
|
||||
this.timestamp = timestamp;
|
||||
this.listener = listener;
|
||||
|
||||
commandRunner = HabitsApplication.getComponent().getCommandRunner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInBackground()
|
||||
{
|
||||
commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp),
|
||||
habit.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostExecute()
|
||||
{
|
||||
listener.onToggleRepetitionFinished();
|
||||
}
|
||||
|
||||
public interface Listener
|
||||
{
|
||||
void onToggleRepetitionFinished();
|
||||
}
|
||||
|
||||
private Listener listener;
|
||||
private final Habit habit;
|
||||
private final Long timestamp;
|
||||
|
||||
public ToggleRepetitionTask(Habit habit, Long timestamp)
|
||||
{
|
||||
this.timestamp = timestamp;
|
||||
this.habit = habit;
|
||||
HabitsApplication.getComponent().inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
{
|
||||
ToggleRepetitionCommand command = new ToggleRepetitionCommand(habit, timestamp);
|
||||
commandRunner.execute(command, habit.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
{
|
||||
if(listener != null) listener.onToggleRepetitionFinished();
|
||||
super.onPostExecute(null);
|
||||
}
|
||||
|
||||
public void setListener(Listener listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
}
|
||||
}
|
||||
@@ -134,14 +134,6 @@ public class BaseSystem
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recreates all application reminders.
|
||||
*/
|
||||
public void scheduleReminders()
|
||||
{
|
||||
new SimpleTask(() -> reminderScheduler.schedule(habitList)).execute();
|
||||
}
|
||||
|
||||
private String getDeviceInfo()
|
||||
{
|
||||
if (context == null) return "null context\n";
|
||||
|
||||
@@ -33,8 +33,6 @@ import org.isoron.uhabits.tasks.*;
|
||||
import org.isoron.uhabits.ui.common.views.*;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
public class HistoryEditorDialog extends AppCompatDialogFragment
|
||||
implements DialogInterface.OnClickListener, ModelObservable.Listener
|
||||
{
|
||||
@@ -44,15 +42,18 @@ public class HistoryEditorDialog extends AppCompatDialogFragment
|
||||
@Nullable
|
||||
HistoryChart historyChart;
|
||||
|
||||
@Inject
|
||||
HabitList habitList;
|
||||
|
||||
@NonNull
|
||||
private Controller controller;
|
||||
|
||||
private HabitList habitList;
|
||||
|
||||
private TaskRunner taskRunner;
|
||||
|
||||
public HistoryEditorDialog()
|
||||
{
|
||||
this.controller = new Controller() {};
|
||||
habitList = HabitsApplication.getComponent().getHabitList();
|
||||
taskRunner = HabitsApplication.getComponent().getTaskRunner();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,7 +67,6 @@ public class HistoryEditorDialog extends AppCompatDialogFragment
|
||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
Context context = getActivity();
|
||||
HabitsApplication.getComponent().inject(this);
|
||||
historyChart = new HistoryChart(context);
|
||||
historyChart.setController(controller);
|
||||
|
||||
@@ -141,28 +141,27 @@ public class HistoryEditorDialog extends AppCompatDialogFragment
|
||||
private void refreshData()
|
||||
{
|
||||
if (habit == null) return;
|
||||
new RefreshTask().execute();
|
||||
taskRunner.execute(new RefreshTask());
|
||||
}
|
||||
|
||||
public interface Controller extends HistoryChart.Controller {}
|
||||
|
||||
private class RefreshTask extends BaseTask
|
||||
private class RefreshTask implements Task
|
||||
{
|
||||
public int[] checkmarks;
|
||||
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
public void doInBackground()
|
||||
{
|
||||
checkmarks = habit.getCheckmarks().getAllValues();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
public void onPostExecute()
|
||||
{
|
||||
int color = ColorUtils.getColor(getContext(), habit.getColor());
|
||||
historyChart.setColor(color);
|
||||
historyChart.setCheckmarks(checkmarks);
|
||||
super.onPostExecute(aVoid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import java.util.*;
|
||||
import javax.inject.*;
|
||||
|
||||
public class ListHabitsController
|
||||
implements ImportDataTask.Listener, HabitCardListController.HabitListener
|
||||
implements HabitCardListController.HabitListener
|
||||
{
|
||||
@NonNull
|
||||
private final ListHabitsScreen screen;
|
||||
@@ -57,6 +57,12 @@ public class ListHabitsController
|
||||
@Inject
|
||||
CommandRunner commandRunner;
|
||||
|
||||
@Inject
|
||||
ReminderScheduler reminderScheduler;
|
||||
|
||||
@Inject
|
||||
TaskRunner taskRuner;
|
||||
|
||||
public ListHabitsController(@NonNull HabitList habitList,
|
||||
@NonNull ListHabitsScreen screen,
|
||||
@NonNull BaseSystem system,
|
||||
@@ -74,26 +80,18 @@ public class ListHabitsController
|
||||
List<Habit> selected = new LinkedList<>();
|
||||
for (Habit h : habitList) selected.add(h);
|
||||
|
||||
ProgressBar progressBar = screen.getProgressBar();
|
||||
ExportCSVTask task =
|
||||
new ExportCSVTask(habitList, selected, progressBar);
|
||||
|
||||
task.setListener(filename -> {
|
||||
taskRuner.execute(new ExportCSVTask(habitList, selected, filename -> {
|
||||
if (filename != null) screen.showSendFileScreen(filename);
|
||||
else screen.showMessage(R.string.could_not_export);
|
||||
});
|
||||
|
||||
task.execute();
|
||||
}));
|
||||
}
|
||||
|
||||
public void onExportDB()
|
||||
{
|
||||
ExportDBTask task = new ExportDBTask(screen.getProgressBar());
|
||||
task.setListener(filename -> {
|
||||
taskRuner.execute(new ExportDBTask(filename -> {
|
||||
if (filename != null) screen.showSendFileScreen(filename);
|
||||
else screen.showMessage(R.string.could_not_export);
|
||||
});
|
||||
task.execute();
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,20 +103,12 @@ public class ListHabitsController
|
||||
@Override
|
||||
public void onHabitReorder(@NonNull Habit from, @NonNull Habit to)
|
||||
{
|
||||
new SimpleTask(() -> habitList.reorder(from, to)).execute();
|
||||
taskRuner.execute(() -> habitList.reorder(from, to));
|
||||
}
|
||||
|
||||
public void onImportData(@NonNull File file)
|
||||
{
|
||||
ProgressBar bar = screen.getProgressBar();
|
||||
ImportDataTask task = new ImportDataTask(habitList, file, bar);
|
||||
task.setListener(this);
|
||||
task.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImportDataFinished(int result)
|
||||
{
|
||||
taskRuner.execute(new ImportDataTask(habitList, file, result -> {
|
||||
switch (result)
|
||||
{
|
||||
case ImportDataTask.SUCCESS:
|
||||
@@ -134,8 +124,10 @@ public class ListHabitsController
|
||||
screen.showMessage(R.string.could_not_import);
|
||||
break;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onInvalidToggle()
|
||||
{
|
||||
@@ -177,7 +169,7 @@ public class ListHabitsController
|
||||
if (prefs.isFirstRun()) onFirstRun();
|
||||
|
||||
new Handler().postDelayed(() -> {
|
||||
system.scheduleReminders();
|
||||
taskRuner.execute(() -> reminderScheduler.schedule(habitList));
|
||||
HabitsApplication.getWidgetUpdater().updateWidgets();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
package org.isoron.uhabits.ui.habits.list.model;
|
||||
|
||||
import android.os.*;
|
||||
import android.support.annotation.*;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
@@ -30,8 +29,6 @@ import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
/**
|
||||
* A HabitCardListCache fetches and keeps a cache of all the data necessary to
|
||||
* render a HabitCardListView.
|
||||
@@ -44,7 +41,7 @@ public class HabitCardListCache implements CommandRunner.Listener
|
||||
{
|
||||
private int checkmarkCount;
|
||||
|
||||
private BaseTask currentFetchTask;
|
||||
private Task currentFetchTask;
|
||||
|
||||
@Nullable
|
||||
private Listener listener;
|
||||
@@ -52,30 +49,30 @@ public class HabitCardListCache implements CommandRunner.Listener
|
||||
@NonNull
|
||||
private CacheData data;
|
||||
|
||||
@Inject
|
||||
CommandRunner commandRunner;
|
||||
|
||||
@NonNull
|
||||
private HabitList allHabits;
|
||||
|
||||
@NonNull
|
||||
private HabitList filteredHabits;
|
||||
|
||||
@NonNull
|
||||
private ProgressBar progressBar;
|
||||
private final TaskRunner taskRunner;
|
||||
|
||||
private final CommandRunner commandRunner;
|
||||
|
||||
public HabitCardListCache(@NonNull HabitList allHabits)
|
||||
{
|
||||
this.allHabits = allHabits;
|
||||
this.filteredHabits = allHabits;
|
||||
this.progressBar = new ProgressBar() {};
|
||||
data = new CacheData();
|
||||
HabitsApplication.getComponent().inject(this);
|
||||
|
||||
BaseComponent component = HabitsApplication.getComponent();
|
||||
commandRunner = component.getCommandRunner();
|
||||
taskRunner = component.getTaskRunner();
|
||||
}
|
||||
|
||||
public void cancelTasks()
|
||||
{
|
||||
if (currentFetchTask != null) currentFetchTask.cancel(true);
|
||||
if (currentFetchTask != null) currentFetchTask.cancel();
|
||||
}
|
||||
|
||||
public int[] getCheckmarks(long habitId)
|
||||
@@ -127,14 +124,28 @@ public class HabitCardListCache implements CommandRunner.Listener
|
||||
|
||||
public void refreshAllHabits()
|
||||
{
|
||||
if (currentFetchTask != null) currentFetchTask.cancel(true);
|
||||
if (currentFetchTask != null) currentFetchTask.cancel();
|
||||
currentFetchTask = new RefreshTask();
|
||||
currentFetchTask.execute();
|
||||
taskRunner.execute(currentFetchTask);
|
||||
}
|
||||
|
||||
public void refreshHabit(long id)
|
||||
{
|
||||
new RefreshTask(id).execute();
|
||||
taskRunner.execute(new RefreshTask(id));
|
||||
}
|
||||
|
||||
public void remove(@NonNull Long id)
|
||||
{
|
||||
Habit h = data.id_to_habit.get(id);
|
||||
if (h == null) return;
|
||||
|
||||
int position = data.habits.indexOf(h);
|
||||
data.habits.remove(position);
|
||||
data.id_to_habit.remove(id);
|
||||
data.checkmarks.remove(id);
|
||||
data.scores.remove(id);
|
||||
|
||||
if (listener != null) listener.onItemRemoved(position);
|
||||
}
|
||||
|
||||
public void reorder(int from, int to)
|
||||
@@ -162,21 +173,7 @@ public class HabitCardListCache implements CommandRunner.Listener
|
||||
|
||||
public void setProgressBar(@NonNull ProgressBar progressBar)
|
||||
{
|
||||
this.progressBar = progressBar;
|
||||
}
|
||||
|
||||
public void remove(@NonNull Long id)
|
||||
{
|
||||
Habit h = data.id_to_habit.get(id);
|
||||
if(h == null) return;
|
||||
|
||||
int position = data.habits.indexOf(h);
|
||||
data.habits.remove(position);
|
||||
data.id_to_habit.remove(id);
|
||||
data.checkmarks.remove(id);
|
||||
data.scores.remove(id);
|
||||
|
||||
if (listener != null) listener.onItemRemoved(position);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -251,7 +248,7 @@ public class HabitCardListCache implements CommandRunner.Listener
|
||||
}
|
||||
}
|
||||
|
||||
private class RefreshTask extends BaseTask
|
||||
private class RefreshTask implements Task
|
||||
{
|
||||
@NonNull
|
||||
private CacheData newData;
|
||||
@@ -259,10 +256,15 @@ public class HabitCardListCache implements CommandRunner.Listener
|
||||
@Nullable
|
||||
private Long targetId;
|
||||
|
||||
private boolean isCancelled;
|
||||
|
||||
private TaskRunner runner;
|
||||
|
||||
public RefreshTask()
|
||||
{
|
||||
newData = new CacheData();
|
||||
targetId = null;
|
||||
isCancelled = false;
|
||||
}
|
||||
|
||||
public RefreshTask(Long targetId)
|
||||
@@ -272,7 +274,13 @@ public class HabitCardListCache implements CommandRunner.Listener
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
public void cancel()
|
||||
{
|
||||
isCancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInBackground()
|
||||
{
|
||||
newData.fetchHabits();
|
||||
newData.copyScoresFrom(data);
|
||||
@@ -282,11 +290,11 @@ public class HabitCardListCache implements CommandRunner.Listener
|
||||
long day = DateUtils.millisecondsInOneDay;
|
||||
long dateFrom = dateTo - (checkmarkCount - 1) * day;
|
||||
|
||||
publishProgress(-1);
|
||||
runner.setCurrentProgress(this, -1);
|
||||
|
||||
for (int position = 0; position < newData.habits.size(); position++)
|
||||
{
|
||||
if (isCancelled()) return;
|
||||
if (isCancelled) return;
|
||||
|
||||
Habit habit = newData.habits.get(position);
|
||||
Long id = habit.getId();
|
||||
@@ -296,44 +304,27 @@ public class HabitCardListCache implements CommandRunner.Listener
|
||||
newData.checkmarks.put(id,
|
||||
habit.getCheckmarks().getValues(dateFrom, dateTo));
|
||||
|
||||
publishProgress(position);
|
||||
runner.setCurrentProgress(this, position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
public void onAttached(@NonNull TaskRunner runner)
|
||||
{
|
||||
this.runner = runner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostExecute()
|
||||
{
|
||||
currentFetchTask = null;
|
||||
progressBar.hide();
|
||||
super.onPostExecute(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
public void onProgressUpdate(int currentPosition)
|
||||
{
|
||||
super.onPreExecute();
|
||||
progressBar.setTotal(0);
|
||||
|
||||
new Handler().postDelayed(() -> {
|
||||
if (getStatus() == Status.RUNNING) progressBar.show();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Integer... values)
|
||||
{
|
||||
int currentPosition = values[0];
|
||||
|
||||
if (currentPosition < 0)
|
||||
{
|
||||
progressBar.setTotal(newData.habits.size() - 1);
|
||||
processRemovedHabits();
|
||||
}
|
||||
else
|
||||
{
|
||||
progressBar.setCurrent(currentPosition);
|
||||
processPosition(currentPosition);
|
||||
}
|
||||
if (currentPosition < 0) processRemovedHabits();
|
||||
else processPosition(currentPosition);
|
||||
}
|
||||
|
||||
private void performInsert(Habit habit, int position)
|
||||
@@ -358,8 +349,7 @@ public class HabitCardListCache implements CommandRunner.Listener
|
||||
{
|
||||
data.scores.put(id, newData.scores.get(id));
|
||||
data.checkmarks.put(id, newData.checkmarks.get(id));
|
||||
if(listener != null)
|
||||
listener.onItemChanged(position);
|
||||
if (listener != null) listener.onItemChanged(position);
|
||||
}
|
||||
|
||||
private void processPosition(int currentPosition)
|
||||
|
||||
@@ -24,13 +24,12 @@ import android.support.annotation.*;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.commands.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.tasks.*;
|
||||
import org.isoron.uhabits.ui.common.dialogs.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
public class ShowHabitController implements ShowHabitRootView.Controller,
|
||||
HistoryEditorDialog.Controller
|
||||
public class ShowHabitController
|
||||
implements ShowHabitRootView.Controller, HistoryEditorDialog.Controller
|
||||
{
|
||||
@NonNull
|
||||
private final ShowHabitScreen screen;
|
||||
@@ -49,12 +48,6 @@ public class ShowHabitController implements ShowHabitRootView.Controller,
|
||||
this.habit = habit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onToolbarChanged()
|
||||
{
|
||||
screen.invalidateToolbar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEditHistoryButtonClick()
|
||||
{
|
||||
@@ -64,10 +57,13 @@ public class ShowHabitController implements ShowHabitRootView.Controller,
|
||||
@Override
|
||||
public void onToggleCheckmark(long timestamp)
|
||||
{
|
||||
new SimpleTask(() -> {
|
||||
ToggleRepetitionCommand command;
|
||||
command = new ToggleRepetitionCommand(habit, timestamp);
|
||||
commandRunner.execute(command, null);
|
||||
}).execute();
|
||||
commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp),
|
||||
null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onToolbarChanged()
|
||||
{
|
||||
screen.invalidateToolbar();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ public class FrequencyCard extends HabitCard
|
||||
@BindView(R.id.frequencyChart)
|
||||
FrequencyChart chart;
|
||||
|
||||
private TaskRunner taskRunner;
|
||||
|
||||
public FrequencyCard(Context context)
|
||||
{
|
||||
super(context);
|
||||
@@ -56,13 +58,14 @@ public class FrequencyCard extends HabitCard
|
||||
@Override
|
||||
protected void refreshData()
|
||||
{
|
||||
new RefreshTask().execute();
|
||||
taskRunner.execute(new RefreshTask());
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
inflate(getContext(), R.layout.show_habit_frequency, this);
|
||||
ButterKnife.bind(this);
|
||||
taskRunner = HabitsApplication.getComponent().getTaskRunner();
|
||||
|
||||
if (isInEditMode()) initEditMode();
|
||||
}
|
||||
@@ -75,10 +78,10 @@ public class FrequencyCard extends HabitCard
|
||||
chart.populateWithRandomData();
|
||||
}
|
||||
|
||||
private class RefreshTask extends BaseTask
|
||||
private class RefreshTask implements Task
|
||||
{
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
public void doInBackground()
|
||||
{
|
||||
RepetitionList reps = getHabit().getRepetitions();
|
||||
HashMap<Long, Integer[]> frequency = reps.getWeekdayFrequency();
|
||||
@@ -86,11 +89,10 @@ public class FrequencyCard extends HabitCard
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
public void onPreExecute()
|
||||
{
|
||||
super.onPreExecute();
|
||||
int color =
|
||||
ColorUtils.getColor(getContext(), getHabit().getColor());
|
||||
int paletteColor = getHabit().getColor();
|
||||
int color = ColorUtils.getColor(getContext(), paletteColor);
|
||||
title.setTextColor(color);
|
||||
chart.setColor(color);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ public class HistoryCard extends HabitCard
|
||||
@NonNull
|
||||
private Controller controller;
|
||||
|
||||
private TaskRunner taskRunner;
|
||||
|
||||
public HistoryCard(Context context)
|
||||
{
|
||||
super(context);
|
||||
@@ -70,32 +72,14 @@ public class HistoryCard extends HabitCard
|
||||
@Override
|
||||
protected void refreshData()
|
||||
{
|
||||
Habit habit = getHabit();
|
||||
|
||||
new BaseTask()
|
||||
{
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
{
|
||||
int checkmarks[] = habit.getCheckmarks().getAllValues();
|
||||
chart.setCheckmarks(checkmarks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
{
|
||||
super.onPreExecute();
|
||||
int color = ColorUtils.getColor(getContext(), habit.getColor());
|
||||
title.setTextColor(color);
|
||||
chart.setColor(color);
|
||||
}
|
||||
}.execute();
|
||||
taskRunner.execute(new RefreshTask(getHabit()));
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
inflate(getContext(), R.layout.show_habit_history, this);
|
||||
ButterKnife.bind(this);
|
||||
taskRunner = HabitsApplication.getComponent().getTaskRunner();
|
||||
controller = new Controller() {};
|
||||
if (isInEditMode()) initEditMode();
|
||||
}
|
||||
@@ -112,4 +96,26 @@ public class HistoryCard extends HabitCard
|
||||
{
|
||||
default void onEditHistoryButtonClick() {}
|
||||
}
|
||||
|
||||
private class RefreshTask implements Task
|
||||
{
|
||||
private final Habit habit;
|
||||
|
||||
public RefreshTask(Habit habit) {this.habit = habit;}
|
||||
|
||||
@Override
|
||||
public void doInBackground()
|
||||
{
|
||||
int checkmarks[] = habit.getCheckmarks().getAllValues();
|
||||
chart.setCheckmarks(checkmarks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreExecute()
|
||||
{
|
||||
int color = ColorUtils.getColor(getContext(), habit.getColor());
|
||||
title.setTextColor(color);
|
||||
chart.setColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,8 @@ public class OverviewCard extends HabitCard
|
||||
|
||||
private int color;
|
||||
|
||||
private TaskRunner taskRunner;
|
||||
|
||||
public OverviewCard(Context context)
|
||||
{
|
||||
super(context);
|
||||
@@ -69,7 +71,7 @@ public class OverviewCard extends HabitCard
|
||||
@Override
|
||||
protected void refreshData()
|
||||
{
|
||||
new RefreshTask().execute();
|
||||
taskRunner.execute(new RefreshTask());
|
||||
}
|
||||
|
||||
private String formatPercentageDiff(float percentageDiff)
|
||||
@@ -80,6 +82,7 @@ public class OverviewCard extends HabitCard
|
||||
|
||||
private void init()
|
||||
{
|
||||
taskRunner = HabitsApplication.getComponent().getTaskRunner();
|
||||
inflate(getContext(), R.layout.show_habit_overview, this);
|
||||
ButterKnife.bind(this);
|
||||
cache = new Cache();
|
||||
@@ -136,10 +139,10 @@ public class OverviewCard extends HabitCard
|
||||
public float lastYearScore;
|
||||
}
|
||||
|
||||
private class RefreshTask extends BaseTask
|
||||
private class RefreshTask implements Task
|
||||
{
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
public void doInBackground()
|
||||
{
|
||||
ScoreList scores = getHabit().getScores();
|
||||
|
||||
@@ -153,16 +156,14 @@ public class OverviewCard extends HabitCard
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
public void onPostExecute()
|
||||
{
|
||||
refreshScore();
|
||||
super.onPostExecute(aVoid);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
public void onPreExecute()
|
||||
{
|
||||
super.onPreExecute();
|
||||
color = ColorUtils.getColor(getContext(), getHabit().getColor());
|
||||
refreshColors();
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ public class ScoreCard extends HabitCard
|
||||
|
||||
private int bucketSize;
|
||||
|
||||
private TaskRunner taskRunner;
|
||||
|
||||
public ScoreCard(Context context)
|
||||
{
|
||||
super(context);
|
||||
@@ -86,7 +88,7 @@ public class ScoreCard extends HabitCard
|
||||
@Override
|
||||
protected void refreshData()
|
||||
{
|
||||
new RefreshTask().execute();
|
||||
taskRunner.execute(new RefreshTask());
|
||||
}
|
||||
|
||||
private int getDefaultSpinnerPosition()
|
||||
@@ -97,6 +99,8 @@ public class ScoreCard extends HabitCard
|
||||
|
||||
private void init()
|
||||
{
|
||||
taskRunner = HabitsApplication.getComponent().getTaskRunner();
|
||||
|
||||
inflate(getContext(), R.layout.show_habit_score, this);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
@@ -121,10 +125,10 @@ public class ScoreCard extends HabitCard
|
||||
bucketSize = BUCKET_SIZES[position];
|
||||
}
|
||||
|
||||
private class RefreshTask extends BaseTask
|
||||
private class RefreshTask implements Task
|
||||
{
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
public void doInBackground()
|
||||
{
|
||||
List<Score> scores;
|
||||
ScoreList scoreList = getHabit().getScores();
|
||||
@@ -137,9 +141,8 @@ public class ScoreCard extends HabitCard
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
public void onPreExecute()
|
||||
{
|
||||
super.onPreExecute();
|
||||
int color =
|
||||
ColorUtils.getColor(getContext(), getHabit().getColor());
|
||||
title.setTextColor(color);
|
||||
|
||||
@@ -43,6 +43,8 @@ public class StreakCard extends HabitCard
|
||||
@BindView(R.id.streakChart)
|
||||
StreakChart streakChart;
|
||||
|
||||
private TaskRunner taskRunner;
|
||||
|
||||
public StreakCard(Context context)
|
||||
{
|
||||
super(context);
|
||||
@@ -58,11 +60,12 @@ public class StreakCard extends HabitCard
|
||||
@Override
|
||||
protected void refreshData()
|
||||
{
|
||||
new RefreshTask().execute();
|
||||
taskRunner.execute(new RefreshTask());
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
taskRunner = HabitsApplication.getComponent().getTaskRunner();
|
||||
inflate(getContext(), R.layout.show_habit_streak, this);
|
||||
ButterKnife.bind(this);
|
||||
setOrientation(VERTICAL);
|
||||
@@ -77,28 +80,26 @@ public class StreakCard extends HabitCard
|
||||
streakChart.populateWithRandomData();
|
||||
}
|
||||
|
||||
private class RefreshTask extends BaseTask
|
||||
private class RefreshTask implements Task
|
||||
{
|
||||
public List<Streak> bestStreaks;
|
||||
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
public void doInBackground()
|
||||
{
|
||||
StreakList streaks = getHabit().getStreaks();
|
||||
bestStreaks = streaks.getBest(NUM_STREAKS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
public void onPostExecute()
|
||||
{
|
||||
streakChart.setStreaks(bestStreaks);
|
||||
super.onPostExecute(aVoid);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
public void onPreExecute()
|
||||
{
|
||||
super.onPreExecute();
|
||||
int color =
|
||||
ColorUtils.getColor(getContext(), getHabit().getColor());
|
||||
title.setTextColor(color);
|
||||
|
||||
Reference in New Issue
Block a user