Made internal api task details way faster to load

pull/14/head
Tim Su 14 years ago
parent 5beb935b32
commit ebe6249852

@ -186,12 +186,6 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="com.todoroo.astrid.tags.TagDetailExposer">
<intent-filter>
<action android:name="com.todoroo.astrid.REQUEST_DETAILS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<!-- repeats -->
<receiver android:name="com.todoroo.astrid.repeats.RepeatsPlugin">
@ -206,20 +200,8 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="com.todoroo.astrid.repeats.RepeatDetailExposer">
<intent-filter>
<action android:name="com.todoroo.astrid.REQUEST_DETAILS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<!-- notes -->
<receiver android:name="com.todoroo.astrid.notes.NoteDetailExposer">
<intent-filter>
<action android:name="com.todoroo.astrid.REQUEST_DETAILS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<!-- reminders -->
<activity android:name="com.todoroo.astrid.reminders.ReminderPreferences"
@ -245,12 +227,6 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="com.todoroo.astrid.rmilk.MilkDetailExposer">
<intent-filter>
<action android:name="com.todoroo.astrid.REQUEST_DETAILS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity android:name="com.todoroo.astrid.rmilk.MilkLoginActivity"
android:theme="@style/Theme" />
<activity android:name="com.todoroo.astrid.rmilk.MilkPreferences"

@ -1,6 +1,9 @@
package com.todoroo.andlib.utility;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@ -209,4 +212,28 @@ public class AndroidUtilities {
return a.equals(b);
}
/**
* Copy a file from one place to another
* @param in
* @param out
* @throws Exception
*/
public static void copyFile(File in, File out) throws Exception {
FileInputStream fis = new FileInputStream(in);
FileOutputStream fos = new FileOutputStream(out);
try {
byte[] buf = new byte[1024];
int i = 0;
while ((i = fis.read(buf)) != -1) {
fos.write(buf, 0, i);
}
}
catch (Exception e) {
throw e;
}
finally {
if (fis != null) fis.close();
if (fos != null) fos.close();
}
}
}

@ -10,6 +10,7 @@ import android.content.Intent;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.DetailExposer;
import com.todoroo.astrid.api.TaskDetail;
import com.todoroo.astrid.model.Task;
import com.todoroo.astrid.service.TaskService;
@ -20,12 +21,12 @@ import com.todoroo.astrid.service.TaskService;
* @author Tim Su <tim@todoroo.com>
*
*/
public class NoteDetailExposer extends BroadcastReceiver {
public class NoteDetailExposer extends BroadcastReceiver implements DetailExposer {
private static TaskService staticTaskService = null;
private static TaskService staticTaskService;
@Autowired
TaskService taskService;
private TaskService taskService;
@Override
public void onReceive(Context context, Intent intent) {
@ -34,27 +35,37 @@ public class NoteDetailExposer extends BroadcastReceiver {
if(taskId == -1)
return;
if(staticTaskService == null) {
DependencyInjectionService.getInstance().inject(this);
staticTaskService = taskService;
} else {
taskService = staticTaskService;
}
Task task = taskService.fetchById(taskId, Task.NOTES);
if(task == null)
return;
String notes = task.getValue(Task.NOTES);
if(notes.length() == 0)
TaskDetail taskDetail = getTaskDetails(context, taskId);
if(taskDetail == null)
return;
TaskDetail taskDetail = new TaskDetail(notes);
// transmit
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_DETAILS);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, NotesPlugin.IDENTIFIER);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, taskDetail);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId);
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
}
@Override
public TaskDetail getTaskDetails(Context context, long id) {
synchronized(NoteDetailExposer.class) {
if(staticTaskService == null) {
DependencyInjectionService.getInstance().inject(this);
staticTaskService = taskService;
} else {
taskService = staticTaskService;
}
}
Task task = taskService.fetchById(id, Task.NOTES);
if(task == null)
return null;
String notes = task.getValue(Task.NOTES);
if(notes.length() == 0)
return null;
return new TaskDetail(notes);
}
}

@ -19,6 +19,7 @@ import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.DetailExposer;
import com.todoroo.astrid.api.TaskDetail;
import com.todoroo.astrid.model.Task;
import com.todoroo.astrid.service.TaskService;
@ -29,7 +30,9 @@ import com.todoroo.astrid.service.TaskService;
* @author Tim Su <tim@todoroo.com>
*
*/
public class RepeatDetailExposer extends BroadcastReceiver {
public class RepeatDetailExposer extends BroadcastReceiver implements DetailExposer {
private static TaskService staticTaskService = null;
@Autowired
TaskService taskService;
@ -41,11 +44,32 @@ public class RepeatDetailExposer extends BroadcastReceiver {
if(taskId == -1)
return;
DependencyInjectionService.getInstance().inject(this);
Task task = taskService.fetchById(taskId, Task.FLAGS, Task.RECURRENCE);
if(task == null)
TaskDetail taskDetail = getTaskDetails(context, taskId);
if(taskDetail == null)
return;
// transmit
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_DETAILS);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, RepeatsPlugin.IDENTIFIER);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, taskDetail);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId);
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
}
public TaskDetail getTaskDetails(Context context, long id) {
synchronized(RepeatDetailExposer.class) {
if(staticTaskService == null) {
DependencyInjectionService.getInstance().inject(this);
staticTaskService = taskService;
} else {
taskService = staticTaskService;
}
}
Task task = taskService.fetchById(id, Task.FLAGS, Task.RECURRENCE);
if(task == null)
return null;
Resources r = context.getResources();
String recurrence = task.getValue(Task.RECURRENCE);
@ -54,7 +78,7 @@ public class RepeatDetailExposer extends BroadcastReceiver {
try {
rrule = new RRule(recurrence);
} catch (ParseException e) {
return;
return null;
}
String interval;
switch(rrule.getFreq()) {
@ -96,23 +120,15 @@ public class RepeatDetailExposer extends BroadcastReceiver {
}
}
String detail;
if(task.getFlag(Task.FLAGS, Task.FLAG_REPEAT_AFTER_COMPLETION))
detail = context.getString(R.string.repeat_detail_completion, interval);
else
detail = context.getString(R.string.repeat_detail_duedate, interval);
TaskDetail taskDetail = new TaskDetail(detail);
// transmit
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_DETAILS);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, taskDetail);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId);
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
return new TaskDetail(detail);
}
return null;
}
}

@ -10,6 +10,7 @@ import android.content.Intent;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.DetailExposer;
import com.todoroo.astrid.api.TaskDetail;
import com.todoroo.astrid.model.Metadata;
import com.todoroo.astrid.rmilk.data.MilkDataService;
@ -25,7 +26,7 @@ import com.todoroo.astrid.rmilk.data.MilkTask;
* @author Tim Su <tim@todoroo.com>
*
*/
public class MilkDetailExposer extends BroadcastReceiver {
public class MilkDetailExposer extends BroadcastReceiver implements DetailExposer{
@Override
public void onReceive(Context context, Intent intent) {
@ -37,43 +38,49 @@ public class MilkDetailExposer extends BroadcastReceiver {
if(taskId == -1)
return;
Metadata metadata = MilkDataService.getInstance().getTaskMetadata(taskId);
if(metadata == null)
TaskDetail taskDetail = getTaskDetails(context, taskId);
if(taskDetail == null)
return;
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_DETAILS);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, Utilities.IDENTIFIER);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, taskDetail);
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
}
@Override
public TaskDetail getTaskDetails(Context context, long id) {
Metadata metadata = MilkDataService.getInstance().getTaskMetadata(id);
if(metadata == null)
return null;
StringBuilder builder = new StringBuilder();
long listId = metadata.getValue(MilkTask.LIST_ID);
if(listId > 0) {
TaskDetail detail = new TaskDetail(context.getString(R.string.rmilk_TLA_list,
MilkDataService.getInstance().getListName(listId)));
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, detail);
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
builder.append(context.getString(R.string.rmilk_TLA_list,
MilkDataService.getInstance().getListName(listId))).append('\n');
}
int repeat = metadata.getValue(MilkTask.REPEATING);
if(repeat != 0) {
TaskDetail detail = new TaskDetail(context.getString(R.string.rmilk_TLA_repeat));
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, detail);
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
builder.append(context.getString(R.string.rmilk_TLA_repeat)).append('\n');
}
TodorooCursor<Metadata> notesCursor = MilkDataService.getInstance().getTaskNotesCursor(taskId);
TodorooCursor<Metadata> notesCursor = MilkDataService.getInstance().getTaskNotesCursor(id);
try {
if(notesCursor.getCount() == 0)
return;
for(notesCursor.moveToFirst(); !notesCursor.isAfterLast(); notesCursor.moveToNext()) {
metadata.readFromCursor(notesCursor);
TaskDetail detail = new TaskDetail(MilkNote.toTaskDetail(metadata));
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, detail);
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
builder.append(MilkNote.toTaskDetail(metadata)).append('\n');
}
} finally {
notesCursor.close();
}
if(builder.length() == 0)
return null;
else
return new TaskDetail(builder.toString().trim());
}
}

@ -9,6 +9,7 @@ import android.content.Intent;
import com.timsu.astrid.R;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.DetailExposer;
import com.todoroo.astrid.api.TaskDetail;
/**
@ -17,9 +18,7 @@ import com.todoroo.astrid.api.TaskDetail;
* @author Tim Su <tim@todoroo.com>
*
*/
public class TagDetailExposer extends BroadcastReceiver {
private static TagService tagService = null;
public class TagDetailExposer extends BroadcastReceiver implements DetailExposer {
@Override
public void onReceive(Context context, Intent intent) {
@ -28,20 +27,26 @@ public class TagDetailExposer extends BroadcastReceiver {
if(taskId == -1)
return;
if(tagService == null)
tagService = new TagService();
String tagList = tagService.getTagsAsString(taskId);
if(tagList.length() == 0)
TaskDetail taskDetail = getTaskDetails(context, taskId);
if(taskDetail == null)
return;
TaskDetail taskDetail = new TaskDetail(context.getString(R.string.tag_TLA_detail, tagList));
// transmit
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_DETAILS);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, TagsPlugin.IDENTIFIER);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, taskDetail);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId);
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
}
@Override
public TaskDetail getTaskDetails(Context context, long id) {
String tagList = TagService.getInstance().getTagsAsString(id);
if(tagList.length() == 0)
return null;
return new TaskDetail(context.getString(R.string.tag_TLA_detail, tagList));
}
}

@ -58,7 +58,7 @@ public class TagFilterExposer extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
tagService = new TagService();
tagService = TagService.getInstance();
Tag[] tagsByAlpha = tagService.getGroupedTags(TagService.GROUPED_TAGS_BY_ALPHA);
// If user does not have any tags, don't show this section at all

@ -2,9 +2,9 @@ package com.todoroo.astrid.tags;
import java.util.ArrayList;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.data.Property.CountProperty;
import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Criterion;
@ -26,22 +26,32 @@ import com.todoroo.astrid.model.Task;
*
*/
@SuppressWarnings("nls")
public class TagService {
public final class TagService {
// --- public constants
/** Metadata key for tag data */
public static final String KEY = "tags";
public static final String KEY = "tags-tag";
/** Property for reading tag values */
public static final StringProperty TAG = Metadata.VALUE1;
// --- singleton
private static TagService instance = null;
public static synchronized TagService getInstance() {
if(instance == null)
instance = new TagService();
return instance;
}
// --- implementation details
@Autowired
private MetadataDao metadataDao;
public TagService() {
private TagService() {
DependencyInjectionService.getInstance().inject(this);
}
@ -95,7 +105,7 @@ public class TagService {
* @return empty array if no tags, otherwise array
*/
public Tag[] getGroupedTags(Order order) {
Query query = Query.select(TAG, COUNT).
Query query = Query.select(TAG.as(TAG.name), COUNT).
join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))).
where(Criterion.and(TaskCriteria.isActive(), MetadataCriteria.withKey(KEY))).
orderBy(order).groupBy(TAG);

@ -35,7 +35,7 @@ public final class TagsControlSet implements TaskEditControlSet {
// --- instance variables
private final TagService tagService = new TagService();
private final TagService tagService = TagService.getInstance();
private final Tag[] allTags;
private final LinearLayout tagsContainer;
private final Activity activity;

@ -1,70 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- See the file "LICENSE" for the full license governing this code. -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@android:drawable/list_selector_background"
android:paddingLeft="4dip"
android:paddingRight="6dip"
android:paddingTop="4dip"
android:paddingBottom="4dip"
android:minHeight="48dip"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:background="@android:drawable/list_selector_background"
android:orientation="vertical">
<!-- completion check-box -->
<CheckBox android:id="@+id/completeBox"
android:layout_width="34dip"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:paddingLeft="5dip"
android:button="@drawable/btn_check"/>
<LinearLayout android:id="@+id/details"
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:minHeight="38dip"
android:paddingLeft="40dip"
android:paddingLeft="4dip"
android:paddingRight="6dip"
android:orientation="vertical">
<!-- task name -->
<TextView android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="22sp"
style="@style/TextAppearance.TAd_ItemTitle"
android:gravity="center_vertical"/>
android:paddingTop="4dip"
android:paddingBottom="4dip"
android:minHeight="48dip"
android:orientation="horizontal">
<!-- due date -->
<TextView android:id="@+id/dueDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"/>
<!-- completion check-box -->
<CheckBox android:id="@+id/completeBox"
android:layout_width="34dip"
android:layout_height="fill_parent"
android:layout_weight="1"
android:paddingLeft="5dip"
android:button="@drawable/btn_check"/>
<LinearLayout android:id="@+id/details"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="100"
android:minHeight="38dip"
android:paddingLeft="40dip"
android:paddingRight="6dip"
android:orientation="vertical">
<!-- task name -->
<TextView android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="22sp"
style="@style/TextAppearance.TAd_ItemTitle"
android:gravity="center_vertical"/>
<!-- due date -->
<TextView android:id="@+id/dueDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"/>
<!-- other details go here -->
</LinearLayout>
<!-- other details go here -->
<!-- importance -->
<View android:id="@+id/importance"
android:layout_width="2dip"
android:layout_height="fill_parent"/>
</LinearLayout>
</LinearLayout>
<LinearLayout android:id="@+id/actions"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/details"
android:background="#4499bbcc"
android:visibility="gone"
android:paddingTop="4dip"
android:paddingLeft="6dip"
android:paddingRight="6dip"
android:orientation="horizontal" />
<!-- importance -->
<View android:id="@+id/importance"
android:layout_width="2dip"
android:layout_height="fill_parent"
android:minHeight="38dip"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
</LinearLayout>

@ -40,7 +40,7 @@
</style>
<style name="TextAppearance.TaskList_Detail">
<item name="android:textSize">12sp</item>
<item name="android:textSize">10sp</item>
<item name="android:textColor">@color/taskList_details</item>
</style>

@ -19,13 +19,17 @@ import android.os.Bundle;
import android.os.Parcelable;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
import com.flurry.android.FlurryAgent;
@ -339,6 +343,9 @@ public class FilterListActivity extends ExpandableListActivity {
* @param label
*/
private void createShortcut(Filter filter, Intent shortcutIntent, String label) {
if(label.length() == 0)
return;
Bitmap emblem = filter.listingIcon;
if(emblem == null)
emblem = ((BitmapDrawable) getResources().getDrawable(
@ -399,6 +406,24 @@ public class FilterListActivity extends ExpandableListActivity {
FrameLayout.LayoutParams.FILL_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT));
final Runnable createShortcut = new Runnable() {
@Override
public void run() {
String label = editText.getText().toString();
createShortcut(filter, shortcutIntent, label);
}
};
editText.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_NULL) {
createShortcut.run();
return true;
}
return false;
}
});
new AlertDialog.Builder(this)
.setTitle(R.string.FLA_shortcut_dialog_title)
.setMessage(R.string.FLA_shortcut_dialog)
@ -406,8 +431,7 @@ public class FilterListActivity extends ExpandableListActivity {
.setIcon(android.R.drawable.ic_dialog_info)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String label = editText.getText().toString();
createShortcut(filter, shortcutIntent, label);
createShortcut.run();
}
})
.setNegativeButton(android.R.string.cancel, null)

@ -157,12 +157,12 @@ public class TaskListActivity extends ListActivity implements OnScrollListener {
if(database == null)
return;
if(Constants.DEBUG)
filter.title = "[D] " + filter.title; //$NON-NLS-1$
database.openForWriting();
setUpUiComponents();
setUpTaskList();
if(Constants.DEBUG)
setTitle("[D] " + filter.title); //$NON-NLS-1$
// cache some stuff
new Thread(new Runnable() {

@ -1,8 +1,8 @@
package com.todoroo.astrid.adapter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashSet;
import android.app.Activity;
import android.content.Context;
@ -11,20 +11,21 @@ import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Paint;
import android.text.Html;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CursorAdapter;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.Property;
@ -37,9 +38,14 @@ import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.astrid.activity.TaskEditActivity;
import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.DetailExposer;
import com.todoroo.astrid.api.TaskDetail;
import com.todoroo.astrid.model.Task;
import com.todoroo.astrid.notes.NoteDetailExposer;
import com.todoroo.astrid.repeats.RepeatDetailExposer;
import com.todoroo.astrid.rmilk.MilkDetailExposer;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.tags.TagDetailExposer;
import com.todoroo.astrid.utility.Preferences;
/**
@ -67,6 +73,14 @@ public class TaskAdapter extends CursorAdapter {
Task.DELETION_DATE,
};
/** Internal Task Detail exposers */
public static final DetailExposer[] EXPOSERS = new DetailExposer[] {
new TagDetailExposer(),
new RepeatDetailExposer(),
new NoteDetailExposer(),
new MilkDetailExposer(),
};
private static int[] IMPORTANCE_COLORS = null;
// --- instance variables
@ -85,7 +99,7 @@ public class TaskAdapter extends CursorAdapter {
protected final Activity activity;
protected final HashMap<Long, Boolean> completedItems;
protected final HashMap<Long, ArrayList<TaskDetail>> detailCache;
protected final HashMap<Long, LinkedHashSet<TaskDetail>> detailCache;
public boolean isFling = false;
private final int resource;
private final LayoutInflater inflater;
@ -119,7 +133,7 @@ public class TaskAdapter extends CursorAdapter {
this.onCompletedTaskListener = onCompletedTaskListener;
completedItems = new HashMap<Long, Boolean>();
detailCache = new HashMap<Long, ArrayList<TaskDetail>>();
detailCache = new HashMap<Long, LinkedHashSet<TaskDetail>>();
fontSize = Preferences.getIntegerFromString(R.string.p_fontSize);
IMPORTANCE_COLORS = Task.getImportanceColors(activity.getResources());
@ -251,15 +265,12 @@ public class TaskAdapter extends CursorAdapter {
if(!isFling) {
detailsView.removeViews(2, detailsView.getChildCount() - 2);
if(detailCache.containsKey(task.getId())) {
ArrayList<TaskDetail> details = detailCache.get(task.getId());
int length = details.size();
for(int i = 0; i < length; i++)
detailsView.addView(detailToView(details.get(i)));
Log.e("DRAWING DETAILS", "Drawing DETAILS suckaaa");
LinkedHashSet<TaskDetail> details = detailCache.get(task.getId());
for(TaskDetail detail : details)
detailsView.addView(detailToView(detail));
} else {
detailCache.put(task.getId(), new ArrayList<TaskDetail>());
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_REQUEST_DETAILS);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, task.getId());
activity.sendOrderedBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
retrieveDetails(detailsView, task.getId());
}
}
@ -270,6 +281,33 @@ public class TaskAdapter extends CursorAdapter {
}
}
/**
* Retrieve task details
*/
private void retrieveDetails(final LinearLayout view, final long taskId) {
final LinkedHashSet<TaskDetail> details = new LinkedHashSet<TaskDetail>();
detailCache.put(taskId, details);
// read internal details directly
new Thread() {
@Override
public void run() {
for(DetailExposer exposer : EXPOSERS) {
TaskDetail detail = exposer.getTaskDetails(activity, taskId);
if(detail == null || details.contains(detail))
continue;
Log.e("ADDING DETAIL", "ADDING DETAIL 1 " + detail.text + ", cache was " + details);
details.add(detail);
view.addView(detailToView(detail));
}
}
}.start();
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_REQUEST_DETAILS);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId);
activity.sendOrderedBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
}
/**
* Called to tell the cache to be cleared
*/
@ -286,12 +324,14 @@ public class TaskAdapter extends CursorAdapter {
if(detail == null)
return;
ArrayList<TaskDetail> details = detailCache.get(taskId);
if(details.contains(detail))
LinkedHashSet<TaskDetail> details = detailCache.get(taskId);
if(details == null || details.contains(detail))
return;
details.add(detail);
Log.e("ADDING DETAIL", "ADDING DETAIL X " + detail.text + ", cache was " + details);
// update view if it is visible
int length = list.getChildCount();
for(int i = 0; i < length; i++) {
@ -300,10 +340,6 @@ public class TaskAdapter extends CursorAdapter {
continue;
TextView newView = detailToView(detail);
for(int j = 0; j < viewHolder.details.getChildCount(); j++) {
if(newView.getText().equals(((TextView)viewHolder.details.getChildAt(j)).getText()))
return;
}
viewHolder.details.addView(newView);
break;
}
@ -314,10 +350,11 @@ public class TaskAdapter extends CursorAdapter {
*
* @param detail
*/
@SuppressWarnings("nls")
private TextView detailToView(TaskDetail detail) {
TextView textView = new TextView(activity);
textView.setTextAppearance(activity, R.style.TextAppearance_TAd_ItemDetails);
textView.setText(Html.fromHtml(detail.text));
textView.setText(Html.fromHtml(detail.text.replace("\n", "<br>")));
if(detail.color != 0)
textView.setTextColor(detail.color);
return textView;

@ -0,0 +1,19 @@
package com.todoroo.astrid.api;
import android.content.Context;
/**
* Internal API for Task Details
*
* @author Tim Su <tim@todoroo.com>
*
*/
public interface DetailExposer {
/**
* @param id
* @return null if no details, or task details
*/
public TaskDetail getTaskDetails(Context context, long id);
}
Loading…
Cancel
Save