Alert popup for when magic has happened via quickadd markup

pull/14/head
Sam Bosley 14 years ago
parent aa4359ac7a
commit 5658f820de

@ -195,7 +195,7 @@ public class DateUtilities {
/**
* @return yesterday, today, tomorrow, or null
*/
public static String getRelativeDay(Context context, long date) {
public static String getRelativeDay(Context context, long date, boolean abbreviated) {
long today = clearTime(new Date());
long input = clearTime(new Date(date));
@ -203,18 +203,25 @@ public class DateUtilities {
return context.getString(R.string.today).toLowerCase();
if(today + ONE_DAY == input)
return context.getString(R.string.tmrw).toLowerCase();
return context.getString(abbreviated ? R.string.tmrw : R.string.tomorrow).toLowerCase();
if(today == input + ONE_DAY)
return context.getString(R.string.yest).toLowerCase();
return context.getString(abbreviated ? R.string.yest : R.string.yesterday).toLowerCase();
if(today + DateUtilities.ONE_WEEK >= input &&
today - DateUtilities.ONE_WEEK <= input)
return DateUtilities.getWeekdayShort(new Date(date));
return abbreviated ? DateUtilities.getWeekdayShort(new Date(date)) : DateUtilities.getWeekday(new Date(date));
return DateUtilities.getDateStringHideYear(context, new Date(date));
}
/**
* Calls getRelativeDay with abbreviated parameter defaulted to true
*/
public static String getRelativeDay(Context context, long date) {
return DateUtilities.getRelativeDay(context, date, true);
}
private static long clearTime(Date date) {
date.setTime(date.getTime() / 1000L * 1000);
date.setHours(0);

@ -32,44 +32,7 @@
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginLeft="2dip"
android:layout_marginRight="5dip"
android:layout_marginBottom="10dip"
android:gravity="bottom">
<ImageView
android:id="@+id/astridIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip"
android:src="@drawable/icon"
android:scaleType="fitCenter"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"/>
<LinearLayout
android:id="@+id/speech_bubble_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="5dip"
android:layout_marginBottom="5dip"
android:minHeight="60dip"
android:layout_alignParentBottom="true"
android:gravity="center_vertical"
android:background="@drawable/speech_bubble_reminder"
android:layout_toRightOf="@id/astridIcon">
<TextView
android:id="@+id/reminder_message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/TextAppearance.TLA_Reminder"
android:gravity="center_vertical"/>
</LinearLayout>
</LinearLayout>
<include layout="@layout/astrid_speech_bubble"/>
<Button
android:id="@+id/reminder_edit"

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<merge>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginLeft="2dip"
android:layout_marginRight="5dip"
android:layout_marginBottom="10dip"
android:gravity="bottom">
<ImageView
android:id="@+id/astridIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip"
android:src="@drawable/icon"
android:scaleType="fitCenter"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"/>
<LinearLayout
android:id="@+id/speech_bubble_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="5dip"
android:layout_marginBottom="5dip"
android:minHeight="60dip"
android:layout_alignParentBottom="true"
android:gravity="center_vertical"
android:background="@drawable/speech_bubble_reminder"
android:layout_toRightOf="@id/astridIcon">
<TextView
android:id="@+id/reminder_message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/TextAppearance.TLA_Reminder"
android:gravity="center_vertical"/>
</LinearLayout>
</LinearLayout>
</merge>

@ -147,6 +147,24 @@
<item>Hidden</item>
</string-array>
<!-- Title for confirmation dialog after quick add markup -->
<string name="TLA_quickadd_confirm_title">You said, \"%s\"</string>
<!-- Text for speech bubble in dialog after quick add markup -->
<!-- First string is task title, second is due date, third is priority -->
<string name="TLA_quickadd_confirm_speech_bubble">I created a task called \"%1$s\" %2$s at %3$s</string>
<string name="TLA_quickadd_confirm_speech_bubble_date">for %s</string>
<string-array name="TLA_priority_strings">
<item>highest priority</item>
<item>high priority</item>
<item>medium priority</item>
<item>low priority</item>
</string-array>
<!-- ====================================================== TaskAdapter == -->
<!-- Format string to indicate task is hidden (%s => task name) -->

@ -344,7 +344,6 @@ public final class TaskEditFragment extends Fragment implements
Preferences.setBoolean(R.string.p_showed_tap_task_help, true);
overrideFinishAnim = false;
Activity a = getActivity();
if (activity != null) {
if (activity.getIntent() != null)
overrideFinishAnim = activity.getIntent().getBooleanExtra(

@ -13,6 +13,7 @@ import org.weloveastrid.rmilk.MilkUtilities;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.PendingIntent.CanceledException;
import android.app.SearchManager;
import android.content.BroadcastReceiver;
@ -113,6 +114,7 @@ import com.todoroo.astrid.service.SyncV2Service.SyncV2Provider;
import com.todoroo.astrid.service.TagDataService;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.service.UpgradeService;
import com.todoroo.astrid.ui.QuickAddMarkupDialog;
import com.todoroo.astrid.utility.AstridPreferences;
import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.utility.Flags;
@ -169,6 +171,8 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
public static final String TOKEN_OVERRIDE_ANIM = "finishAnim"; //$NON-NLS-1$
private static final String QUICK_ADD_MARKUP = "markup"; //$NON-NLS-1$
// --- instance variables
@Autowired
@ -1122,6 +1126,9 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
if (selectNewTask) {
loadTaskListContent(true);
selectCustomId(task.getId());
if (task.getTransitory(QUICK_ADD_MARKUP) != null) {
showAlertForMarkupTask((AstridActivity) getActivity(), task, title);
}
}
StatisticsService.reportEvent(StatisticsConstants.TASK_CREATED_TASKLIST);
@ -1168,16 +1175,25 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
}
task.mergeWith(forTask);
}
taskService.quickAdd(task);
boolean markup = taskService.quickAdd(task);
if (markup)
task.putTransitory(QUICK_ADD_MARKUP, true);
if (forMetadata != null && forMetadata.size() > 0) {
Metadata metadata = new Metadata();
metadata.setValue(Metadata.TASK, task.getId());
metadata.mergeWith(forMetadata);
metadataService.save(metadata);
}
return task;
}
private static void showAlertForMarkupTask(AstridActivity activity, Task task, String originalText) {
Dialog d = QuickAddMarkupDialog.createQuickAddMarkupDialog(activity, task, originalText);
d.show();
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {

@ -336,10 +336,11 @@ public class TaskService {
* <li>@context - add the tag "@context"
* <li>!4 - set priority to !!!!
*/
public void quickAdd(Task task) {
public boolean quickAdd(Task task) {
ArrayList<String> tags = new ArrayList<String>();
boolean quickAddMarkup = false;
try {
parseQuickAddMarkup(task, tags);
quickAddMarkup = parseQuickAddMarkup(task, tags);
} catch (Throwable e) {
exceptionService.reportError("parse-quick-add", e); //$NON-NLS-1$
}
@ -352,10 +353,11 @@ public class TaskService {
metadata.setValue(TagService.TAG, tag);
metadataDao.createNew(metadata);
}
return quickAddMarkup;
}
public static void parseQuickAddMarkup(Task task, ArrayList<String> tags) {
new TitleParser(task, tags).parse();
public static boolean parseQuickAddMarkup(Task task, ArrayList<String> tags) {
return new TitleParser(task, tags).parse();
}

@ -0,0 +1,132 @@
package com.todoroo.astrid.ui;
import java.text.ParseException;
import java.util.Date;
import android.app.Dialog;
import android.content.Context;
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import com.google.ical.values.Frequency;
import com.google.ical.values.RRule;
import com.timsu.astrid.R;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.activity.AstridActivity;
import com.todoroo.astrid.data.Task;
/**
* Helper class that creates a dialog to confirm the results of a quick add markup
* @author Sam
*
*/
public class QuickAddMarkupDialog {
public static Dialog createQuickAddMarkupDialog(final AstridActivity activity, Task task, String originalText) {
final Dialog d = new Dialog(activity, R.style.ReminderDialog);
final long taskId = task.getId();
d.setContentView(R.layout.astrid_reminder_view);
d.findViewById(R.id.reminder_snooze).setVisibility(View.GONE);
((Button) d.findViewById(R.id.reminder_complete)).setText(R.string.DLG_ok);
((TextView) d.findViewById(R.id.reminder_title)).setText(activity.getString(R.string.TLA_quickadd_confirm_title, originalText));
Spanned speechBubbleText = constructSpeechBubbleText(activity, task);
((TextView) d.findViewById(R.id.reminder_message)).setText(speechBubbleText, TextView.BufferType.SPANNABLE);
d.findViewById(R.id.reminder_complete).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
d.dismiss();
}
});
d.findViewById(R.id.dismiss).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
d.dismiss();
}
});
d.findViewById(R.id.reminder_edit).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
d.dismiss();
activity.onTaskListItemClicked(taskId);
}
});
return d;
}
@SuppressWarnings("nls")
private static Spanned constructSpeechBubbleText(Context context, Task task) {
String[] priorityStrings = context.getResources().getStringArray(R.array.TLA_priority_strings);
int[] colorsArray = new int[] { R.color.importance_1, R.color.importance_2, R.color.importance_3, R.color.importance_4 };
String title = task.getValue(Task.TITLE);
long date = task.getValue(Task.DUE_DATE);
String dueDate = "";
if (!TextUtils.isEmpty(task.getValue(Task.RECURRENCE))) {
dueDate = getRecurrenceString(context, task);
}
if (TextUtils.isEmpty(dueDate)) {
dueDate = task.getValue(Task.DUE_DATE) > 0 ? DateUtilities.getRelativeDay(context, date, false) : "";
if(Task.hasDueTime(date))
dueDate = String.format("%s at %s", dueDate, //$NON-NLS-1$
DateUtilities.getTimeString(context, new Date(date)));
}
if (!TextUtils.isEmpty(dueDate))
dueDate = context.getString(R.string.TLA_quickadd_confirm_speech_bubble_date, dueDate);
int priority = task.getValue(Task.IMPORTANCE);
if (priority >= priorityStrings.length)
priority = priorityStrings.length - 1;
String priorityString = priorityStrings[priority];
int color = context.getResources().getColor(colorsArray[priority]) - 0xff000000;
priorityString = String.format("<font color=\"#%s\">%s</font>", Integer.toHexString(color), priorityString);
String fullString = context.getString(R.string.TLA_quickadd_confirm_speech_bubble, title, dueDate, priorityString);
return Html.fromHtml(fullString);
}
private static String getRecurrenceString(Context context, Task task) {
try {
RRule rrule = new RRule(task.getValue(Task.RECURRENCE));
String[] dateAbbrev = context.getResources().getStringArray(
R.array.repeat_interval);
String frequency = "";
Frequency freq = rrule.getFreq();
if (freq == Frequency.DAILY) {
frequency = dateAbbrev[0].toLowerCase();
} else if (freq == Frequency.WEEKLY) {
frequency = dateAbbrev[1].toLowerCase();
} else if (freq == Frequency.MONTHLY) {
frequency = dateAbbrev[2].toLowerCase();
} else if (freq == Frequency.HOURLY) {
frequency = dateAbbrev[3].toLowerCase();
} else if (freq == Frequency.MINUTELY) {
frequency = dateAbbrev[4].toLowerCase();
} else if (freq == Frequency.YEARLY) {
frequency = dateAbbrev[5].toLowerCase();
}
if (!TextUtils.isEmpty(frequency)) {
String date = String.format("%s %s", rrule.getInterval(), frequency); //$NON-NLS-1$
return String.format(context.getString(R.string.repeat_detail_duedate), date).toLowerCase(); // Every freq int
}
} catch (ParseException e) {
// Eh
}
return "";
}
}

@ -22,11 +22,13 @@ public class TitleParser {
this.tags = tags;
}
public void parse(){
repeatHelper(task);
dayHelper(task);
listHelper(task,tags);
priorityHelper(task);
public boolean parse() {
boolean markup = false;
markup = repeatHelper(task) || markup;
markup = dayHelper(task) || markup;
markup = listHelper(task,tags) || markup;
markup = priorityHelper(task) || markup;
return markup;
}
public static String[] trimParenthesisAndSplit(String pattern){
@ -39,14 +41,16 @@ public class TitleParser {
}
return new String[] { pattern };
}
public static void listHelper(Task task, ArrayList<String> tags) {
public static boolean listHelper(Task task, ArrayList<String> tags) {
String inputText = task.getValue(Task.TITLE);
Pattern tagPattern = Pattern.compile("(\\s|^)#(\\(.*\\)|[^\\s]+)");
Pattern contextPattern = Pattern.compile("(\\s|^)@(\\(.*\\)|[^\\s]+)");
boolean result = false;
while(true) {
Matcher m = tagPattern.matcher(inputText);
if(m.find()) {
result = true;
String[] splitTags = TitleParser.trimParenthesisAndSplit(m.group(2));
if (splitTags != null) {
for (String tag : splitTags)
@ -55,6 +59,7 @@ public class TitleParser {
} else {
m = contextPattern.matcher(inputText);
if(m.find()) {
result = true;
String[] splitTags = TitleParser.trimParenthesisAndSplit(m.group(2));
if (splitTags != null) {
for (String tag : splitTags)
@ -67,6 +72,7 @@ public class TitleParser {
inputText = inputText.substring(0, m.start()) + inputText.substring(m.end());
}
task.setValue(Task.TITLE, inputText.trim());
return result;
}
//helper method for priorityHelper. converts the string to a Task Importance
@ -84,7 +90,7 @@ public class TitleParser {
}
//priorityHelper parses the string and sets the Task's importance
private static void priorityHelper(Task task) {
private static boolean priorityHelper(Task task) {
String inputText = task.getValue(Task.TITLE);
String[] importanceStrings = {
"()((^|[^\\w!])!+|(^|[^\\w!])!\\d)($|[^\\w!])",
@ -93,11 +99,13 @@ public class TitleParser {
"(?i)(\\sbang\\s?(\\d)$)",
"(?i)()(\\shigh(est)?|\\slow(est)?|\\stop|\\sleast) ?priority$"
};
boolean result = false;
for (String importanceString:importanceStrings){
Pattern importancePattern = Pattern.compile(importanceString);
while (true){
Matcher m = importancePattern.matcher(inputText);
if(m.find()) {
result = true;
task.setValue(Task.IMPORTANCE, str_to_priority(m.group(2).trim()));
int start = m.start() == 0 ? 0 : m.start() + 1;
inputText = inputText.substring(0, start) + inputText.substring(m.end());
@ -107,6 +115,7 @@ public class TitleParser {
}
}
task.setValue(Task.TITLE, inputText.trim());
return result;
}
//helper for dayHelper. Converts am/pm to an int 0/1.
@ -127,7 +136,7 @@ public class TitleParser {
//Handles setting the task's date.
//Day of week (e.g. Monday, Tuesday,..) is overridden by a set date (e.g. October 23 2013).
//Vague times (e.g. breakfast, night) are overridden by a set time (9 am, at 10, 17:00)
private static void dayHelper(Task task ) {
private static boolean dayHelper(Task task ) {
String inputText = task.getValue(Task.TITLE);
Calendar cal = null;
Boolean containsSpecificTime = false;
@ -319,12 +328,14 @@ public class TitleParser {
} else {
task.setValue(Task.DUE_DATE, Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, cal.getTime().getTime()));
}
return true;
}
return false;
}
//---------------------DATE--------------------------
//Parses through the text and sets the frequency of the task.
private static void repeatHelper(Task task) {
private static boolean repeatHelper(Task task) {
String inputText = task.getValue(Task.TITLE);
HashMap<String, Frequency> repeatTimes = new HashMap<String, Frequency>();
repeatTimes.put("(?i)\\bevery ?\\w{0,6} days?\\b" , Frequency.DAILY);
@ -354,7 +365,7 @@ public class TitleParser {
rrule.setFreq(rtime);
rrule.setInterval(findInterval(inputText));
task.setValue(Task.RECURRENCE, rrule.toIcal());
return;
return true;
}
}
@ -368,9 +379,10 @@ public class TitleParser {
rrule.setInterval(1);
String thing = rrule.toIcal();
task.setValue(Task.RECURRENCE, thing);
return;
return true;
}
}
return false;
}
//helper method for repeatHelper.

Loading…
Cancel
Save