|
|
|
@ -3,28 +3,12 @@
|
|
|
|
|
*/
|
|
|
|
|
package com.todoroo.astrid.activity;
|
|
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.LinkedHashSet;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
import org.json.JSONException;
|
|
|
|
|
import org.weloveastrid.rmilk.MilkPreferences;
|
|
|
|
|
import org.weloveastrid.rmilk.MilkUtilities;
|
|
|
|
|
|
|
|
|
|
import android.app.AlertDialog;
|
|
|
|
|
import android.app.ExpandableListActivity;
|
|
|
|
|
import android.app.Notification;
|
|
|
|
|
import android.app.PendingIntent;
|
|
|
|
|
import android.app.PendingIntent.CanceledException;
|
|
|
|
|
import android.app.ProgressDialog;
|
|
|
|
|
import android.app.SearchManager;
|
|
|
|
|
import android.content.BroadcastReceiver;
|
|
|
|
|
import android.content.Context;
|
|
|
|
|
import android.content.DialogInterface;
|
|
|
|
|
import android.content.Intent;
|
|
|
|
|
import android.content.pm.PackageManager;
|
|
|
|
|
import android.content.pm.ResolveInfo;
|
|
|
|
|
import android.graphics.Bitmap;
|
|
|
|
|
import android.graphics.Canvas;
|
|
|
|
|
import android.graphics.Rect;
|
|
|
|
@ -41,7 +25,6 @@ import android.view.View;
|
|
|
|
|
import android.view.View.OnClickListener;
|
|
|
|
|
import android.view.Window;
|
|
|
|
|
import android.view.inputmethod.EditorInfo;
|
|
|
|
|
import android.widget.ArrayAdapter;
|
|
|
|
|
import android.widget.Button;
|
|
|
|
|
import android.widget.EditText;
|
|
|
|
|
import android.widget.ExpandableListView;
|
|
|
|
@ -56,17 +39,9 @@ import com.timsu.astrid.R;
|
|
|
|
|
import com.todoroo.andlib.service.Autowired;
|
|
|
|
|
import com.todoroo.andlib.service.DependencyInjectionService;
|
|
|
|
|
import com.todoroo.andlib.service.ExceptionService;
|
|
|
|
|
import com.todoroo.andlib.service.NotificationManager;
|
|
|
|
|
import com.todoroo.andlib.sql.Functions;
|
|
|
|
|
import com.todoroo.andlib.sql.QueryTemplate;
|
|
|
|
|
import com.todoroo.andlib.utility.AndroidUtilities;
|
|
|
|
|
import com.todoroo.andlib.utility.DateUtilities;
|
|
|
|
|
import com.todoroo.andlib.utility.DialogUtilities;
|
|
|
|
|
import com.todoroo.andlib.utility.Preferences;
|
|
|
|
|
import com.todoroo.astrid.actfm.ActFmPreferences;
|
|
|
|
|
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
|
|
|
|
|
import com.todoroo.astrid.actfm.sync.ActFmSyncService;
|
|
|
|
|
import com.todoroo.astrid.activity.TaskListActivity.IntentWithLabel;
|
|
|
|
|
import com.todoroo.astrid.adapter.FilterAdapter;
|
|
|
|
|
import com.todoroo.astrid.api.AstridApiConstants;
|
|
|
|
|
import com.todoroo.astrid.api.Filter;
|
|
|
|
@ -74,17 +49,14 @@ import com.todoroo.astrid.api.FilterCategory;
|
|
|
|
|
import com.todoroo.astrid.api.FilterListItem;
|
|
|
|
|
import com.todoroo.astrid.api.FilterWithCustomIntent;
|
|
|
|
|
import com.todoroo.astrid.api.IntentFilter;
|
|
|
|
|
import com.todoroo.astrid.api.SyncAction;
|
|
|
|
|
import com.todoroo.astrid.core.CustomFilterActivity;
|
|
|
|
|
import com.todoroo.astrid.core.SearchFilter;
|
|
|
|
|
import com.todoroo.astrid.data.Task;
|
|
|
|
|
import com.todoroo.astrid.helper.MetadataHelper;
|
|
|
|
|
import com.todoroo.astrid.service.StartupService;
|
|
|
|
|
import com.todoroo.astrid.service.StatisticsConstants;
|
|
|
|
|
import com.todoroo.astrid.service.StatisticsService;
|
|
|
|
|
import com.todoroo.astrid.service.ThemeService;
|
|
|
|
|
import com.todoroo.astrid.tags.TagsPlugin;
|
|
|
|
|
import com.todoroo.astrid.utility.Constants;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Activity that displays a user's task lists and allows users
|
|
|
|
@ -102,11 +74,8 @@ public class FilterListActivity extends ExpandableListActivity {
|
|
|
|
|
|
|
|
|
|
private static final int MENU_SEARCH_ID = Menu.FIRST + 0;
|
|
|
|
|
private static final int MENU_HELP_ID = Menu.FIRST + 1;
|
|
|
|
|
private static final int MENU_REFRESH_ID = Menu.FIRST + 2;
|
|
|
|
|
private static final int MENU_NEW_FILTER_ID = Menu.FIRST + 3;
|
|
|
|
|
|
|
|
|
|
private static final String LAST_TAG_REFRESH_KEY = "last_tag_refresh"; //$NON-NLS-1$
|
|
|
|
|
|
|
|
|
|
private static final int CONTEXT_MENU_SHORTCUT = Menu.FIRST + 4;
|
|
|
|
|
private static final int CONTEXT_MENU_INTENT = Menu.FIRST + 5;
|
|
|
|
|
|
|
|
|
@ -117,11 +86,7 @@ public class FilterListActivity extends ExpandableListActivity {
|
|
|
|
|
// --- instance variables
|
|
|
|
|
|
|
|
|
|
@Autowired ExceptionService exceptionService;
|
|
|
|
|
@Autowired ActFmPreferenceService actFmPreferenceService;
|
|
|
|
|
@Autowired ActFmSyncService actFmSyncService;
|
|
|
|
|
|
|
|
|
|
protected SyncActionReceiver syncActionReceiver = new SyncActionReceiver();
|
|
|
|
|
private final LinkedHashSet<SyncAction> syncActions = new LinkedHashSet<SyncAction>();
|
|
|
|
|
protected FilterAdapter adapter = null;
|
|
|
|
|
|
|
|
|
|
/* ======================================================================
|
|
|
|
@ -157,9 +122,7 @@ public class FilterListActivity extends ExpandableListActivity {
|
|
|
|
|
public void onClick(View v) {
|
|
|
|
|
Intent intent = TagsPlugin.newTagDialog(FilterListActivity.this);
|
|
|
|
|
startActivity(intent);
|
|
|
|
|
AndroidUtilities.callApiMethod(5, FilterListActivity.this, "overridePendingTransition",
|
|
|
|
|
new Class<?>[] { Integer.TYPE, Integer.TYPE },
|
|
|
|
|
R.anim.slide_left_in, R.anim.slide_left_out);
|
|
|
|
|
overridePendingTransition(R.anim.slide_left_in, R.anim.slide_left_out);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
@ -169,9 +132,7 @@ public class FilterListActivity extends ExpandableListActivity {
|
|
|
|
|
@Override
|
|
|
|
|
public void finish() {
|
|
|
|
|
super.finish();
|
|
|
|
|
AndroidUtilities.callApiMethod(5, FilterListActivity.this, "overridePendingTransition", //$NON-NLS-1$
|
|
|
|
|
new Class<?>[] { Integer.TYPE, Integer.TYPE },
|
|
|
|
|
R.anim.slide_left_in, R.anim.slide_left_out);
|
|
|
|
|
overridePendingTransition(R.anim.slide_left_in, R.anim.slide_left_out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -197,8 +158,6 @@ public class FilterListActivity extends ExpandableListActivity {
|
|
|
|
|
startActivity(intent);
|
|
|
|
|
} else {
|
|
|
|
|
setUpList();
|
|
|
|
|
if (actFmPreferenceService.isLoggedIn())
|
|
|
|
|
onRefreshRequested(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -252,8 +211,6 @@ public class FilterListActivity extends ExpandableListActivity {
|
|
|
|
|
adapter.registerRecevier();
|
|
|
|
|
|
|
|
|
|
// also load sync actions
|
|
|
|
|
registerReceiver(syncActionReceiver, new android.content.IntentFilter(AstridApiConstants.BROADCAST_SEND_SYNC_ACTIONS));
|
|
|
|
|
syncActions.clear();
|
|
|
|
|
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_REQUEST_SYNC_ACTIONS);
|
|
|
|
|
sendOrderedBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
|
|
|
|
|
}
|
|
|
|
@ -264,7 +221,6 @@ public class FilterListActivity extends ExpandableListActivity {
|
|
|
|
|
super.onPause();
|
|
|
|
|
if(adapter != null)
|
|
|
|
|
adapter.unregisterRecevier();
|
|
|
|
|
unregisterReceiver(syncActionReceiver);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ======================================================================
|
|
|
|
@ -429,12 +385,6 @@ public class FilterListActivity extends ExpandableListActivity {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case MENU_REFRESH_ID: {
|
|
|
|
|
performSyncAction();
|
|
|
|
|
//onRefreshRequested(true);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case MENU_HELP_ID: {
|
|
|
|
|
Intent intent = new Intent(Intent.ACTION_VIEW,
|
|
|
|
|
Uri.parse("http://weloveastrid.com/help-user-guide-astrid-v3/filters/")); //$NON-NLS-1$
|
|
|
|
@ -469,77 +419,6 @@ public class FilterListActivity extends ExpandableListActivity {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Refresh user tags
|
|
|
|
|
*/
|
|
|
|
|
private void onRefreshRequested(final boolean manual) {
|
|
|
|
|
if (!manual) {
|
|
|
|
|
long lastFetchDate = Preferences.getLong(LAST_TAG_REFRESH_KEY, 0);
|
|
|
|
|
if(DateUtilities.now() < lastFetchDate + 300000L) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
final ProgressDialog progressDialog;
|
|
|
|
|
|
|
|
|
|
final NotificationManager nm = new NotificationManager.AndroidNotificationManager(this);
|
|
|
|
|
final Notification notification = new Notification(android.R.drawable.stat_notify_sync, null, System.currentTimeMillis());
|
|
|
|
|
final int notificationId = updateNotification(this, notification);
|
|
|
|
|
notification.flags |= Notification.FLAG_ONGOING_EVENT;
|
|
|
|
|
|
|
|
|
|
if (manual) {
|
|
|
|
|
progressDialog = DialogUtilities.progressDialog(this, getString(R.string.DLG_please_wait));
|
|
|
|
|
} else {
|
|
|
|
|
progressDialog = null;
|
|
|
|
|
nm.notify(notificationId, notification);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
new Thread(new Runnable() {
|
|
|
|
|
@SuppressWarnings("nls")
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
try {
|
|
|
|
|
Preferences.setLong(LAST_TAG_REFRESH_KEY, DateUtilities.now());
|
|
|
|
|
actFmSyncService.fetchTags(0);
|
|
|
|
|
|
|
|
|
|
runOnUiThread(new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
adapter.clear();
|
|
|
|
|
adapter.getLists();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
if (manual)
|
|
|
|
|
exceptionService.displayAndReportError(FilterListActivity.this, "refresh-tags-io", e);
|
|
|
|
|
else
|
|
|
|
|
exceptionService.reportError("refresh-tags-io", e);
|
|
|
|
|
} catch (JSONException e) {
|
|
|
|
|
if (manual)
|
|
|
|
|
exceptionService.displayAndReportError(FilterListActivity.this, "refresh-tags-json", e);
|
|
|
|
|
else
|
|
|
|
|
exceptionService.reportError("refresh-tags-io", e);
|
|
|
|
|
} finally {
|
|
|
|
|
if (manual)
|
|
|
|
|
DialogUtilities.dismissDialog(FilterListActivity.this, progressDialog);
|
|
|
|
|
else
|
|
|
|
|
nm.cancel(notificationId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}).start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int updateNotification(Context context, Notification notification) {
|
|
|
|
|
String notificationTitle = context.getString(R.string.actfm_notification_title);
|
|
|
|
|
Intent intent = new Intent(context, ActFmPreferences.class);
|
|
|
|
|
PendingIntent notificationIntent = PendingIntent.getActivity(context, 0,
|
|
|
|
|
intent, 0);
|
|
|
|
|
notification.setLatestEventInfo(context,
|
|
|
|
|
notificationTitle, context.getString(R.string.SyP_progress),
|
|
|
|
|
notificationIntent);
|
|
|
|
|
return Constants.NOTIFICATION_SYNC;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showCreateShortcutDialog(final Intent shortcutIntent,
|
|
|
|
|
final Filter filter) {
|
|
|
|
|
FrameLayout frameLayout = new FrameLayout(this);
|
|
|
|
@ -593,125 +472,4 @@ public class FilterListActivity extends ExpandableListActivity {
|
|
|
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Receiver which receives sync provider intents
|
|
|
|
|
*
|
|
|
|
|
* @author Tim Su <tim@todoroo.com>
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
protected class SyncActionReceiver extends BroadcastReceiver {
|
|
|
|
|
@Override
|
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
|
if(intent == null || !AstridApiConstants.BROADCAST_SEND_SYNC_ACTIONS.equals(intent.getAction()))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
Bundle extras = intent.getExtras();
|
|
|
|
|
SyncAction syncAction = extras.getParcelable(AstridApiConstants.EXTRAS_RESPONSE);
|
|
|
|
|
syncActions.add(syncAction);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
exceptionService.reportError("receive-sync-action-" + //$NON-NLS-1$
|
|
|
|
|
intent.getStringExtra(AstridApiConstants.EXTRAS_ADDON), e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void performSyncAction() {
|
|
|
|
|
if (syncActions.size() == 0) {
|
|
|
|
|
String desiredCategory = getString(R.string.SyP_label);
|
|
|
|
|
|
|
|
|
|
// Get a list of all sync plugins and bring user to the prefs pane
|
|
|
|
|
// for one of them
|
|
|
|
|
Intent queryIntent = new Intent(AstridApiConstants.ACTION_SETTINGS);
|
|
|
|
|
PackageManager pm = getPackageManager();
|
|
|
|
|
List<ResolveInfo> resolveInfoList = pm.queryIntentActivities(
|
|
|
|
|
queryIntent, PackageManager.GET_META_DATA);
|
|
|
|
|
int length = resolveInfoList.size();
|
|
|
|
|
ArrayList<Intent> syncIntents = new ArrayList<Intent>();
|
|
|
|
|
|
|
|
|
|
// Loop through a list of all packages (including plugins, addons)
|
|
|
|
|
// that have a settings action: filter to sync actions
|
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
|
ResolveInfo resolveInfo = resolveInfoList.get(i);
|
|
|
|
|
Intent intent = new Intent(AstridApiConstants.ACTION_SETTINGS);
|
|
|
|
|
intent.setClassName(resolveInfo.activityInfo.packageName,
|
|
|
|
|
resolveInfo.activityInfo.name);
|
|
|
|
|
|
|
|
|
|
String category = MetadataHelper.resolveActivityCategoryName(resolveInfo, pm);
|
|
|
|
|
if(MilkPreferences.class.getName().equals(resolveInfo.activityInfo.name) &&
|
|
|
|
|
!MilkUtilities.INSTANCE.isLoggedIn())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (category.equals(desiredCategory)) {
|
|
|
|
|
syncIntents.add(new IntentWithLabel(intent,
|
|
|
|
|
resolveInfo.activityInfo.loadLabel(pm).toString()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final Intent[] actions = syncIntents.toArray(new Intent[syncIntents.size()]);
|
|
|
|
|
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(DialogInterface click, int which) {
|
|
|
|
|
startActivity(actions[which]);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
showSyncOptionMenu(actions, listener);
|
|
|
|
|
}
|
|
|
|
|
else if(syncActions.size() == 1) {
|
|
|
|
|
SyncAction syncAction = syncActions.iterator().next();
|
|
|
|
|
try {
|
|
|
|
|
if (actFmPreferenceService.isLoggedIn())
|
|
|
|
|
onRefreshRequested(true);
|
|
|
|
|
else {
|
|
|
|
|
syncAction.intent.send();
|
|
|
|
|
Toast.makeText(this, R.string.SyP_progress_toast,
|
|
|
|
|
Toast.LENGTH_LONG).show();
|
|
|
|
|
}
|
|
|
|
|
} catch (CanceledException e) {
|
|
|
|
|
//
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// We have >1 sync actions, pop up a dialogue so the user can
|
|
|
|
|
// select just one of them (only sync one at a time)
|
|
|
|
|
final SyncAction[] actions = syncActions.toArray(new SyncAction[syncActions.size()]);
|
|
|
|
|
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(DialogInterface click, int which) {
|
|
|
|
|
try {
|
|
|
|
|
SyncAction action = actions[which];
|
|
|
|
|
if (action.label.contains("Astrid"))
|
|
|
|
|
onRefreshRequested(true);
|
|
|
|
|
else {
|
|
|
|
|
action.intent.send();
|
|
|
|
|
Toast.makeText(FilterListActivity.this, R.string.SyP_progress_toast,
|
|
|
|
|
Toast.LENGTH_LONG).show();
|
|
|
|
|
}
|
|
|
|
|
} catch (CanceledException e) {
|
|
|
|
|
//
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
showSyncOptionMenu(actions, listener);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Show menu of sync options. This is shown when you're not logged into any services, or logged into
|
|
|
|
|
* more than one.
|
|
|
|
|
* @param <TYPE>
|
|
|
|
|
* @param items
|
|
|
|
|
* @param listener
|
|
|
|
|
*/
|
|
|
|
|
private <TYPE> void showSyncOptionMenu(TYPE[] items, DialogInterface.OnClickListener listener) {
|
|
|
|
|
ArrayAdapter<TYPE> syncAdapter = new ArrayAdapter<TYPE>(this,
|
|
|
|
|
android.R.layout.simple_spinner_dropdown_item, items);
|
|
|
|
|
|
|
|
|
|
// show a menu of available options
|
|
|
|
|
new AlertDialog.Builder(this)
|
|
|
|
|
.setTitle(R.string.SyP_label)
|
|
|
|
|
.setAdapter(syncAdapter, listener)
|
|
|
|
|
.show().setOwnerActivity(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|