mirror of https://github.com/tasks/tasks
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
428 lines
14 KiB
Java
428 lines
14 KiB
Java
/**
|
|
* Copyright (c) 2012 Todoroo Inc
|
|
*
|
|
* <p>See the file "LICENSE" for the full license governing this code.
|
|
*/
|
|
package com.todoroo.astrid.adapter;
|
|
|
|
import static android.support.v4.content.ContextCompat.getColor;
|
|
import static com.google.common.base.Strings.isNullOrEmpty;
|
|
import static com.todoroo.andlib.utility.AndroidUtilities.preLollipop;
|
|
import static org.tasks.caldav.CaldavCalendarSettingsActivity.EXTRA_CALDAV_ACCOUNT;
|
|
|
|
import android.app.Activity;
|
|
import android.content.BroadcastReceiver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.res.ColorStateList;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.support.annotation.NonNull;
|
|
import android.support.v4.content.ContextCompat;
|
|
import android.support.v4.content.res.ResourcesCompat;
|
|
import android.support.v4.graphics.drawable.DrawableCompat;
|
|
import android.support.v4.util.Pair;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.ArrayAdapter;
|
|
import android.widget.CheckedTextView;
|
|
import android.widget.ImageView;
|
|
import android.widget.TextView;
|
|
import com.todoroo.astrid.api.Filter;
|
|
import com.todoroo.astrid.api.FilterListItem;
|
|
import com.todoroo.astrid.core.CustomFilterActivity;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import javax.inject.Inject;
|
|
import org.tasks.R;
|
|
import org.tasks.activities.GoogleTaskListSettingsActivity;
|
|
import org.tasks.activities.TagSettingsActivity;
|
|
import org.tasks.billing.Inventory;
|
|
import org.tasks.billing.PurchaseActivity;
|
|
import org.tasks.caldav.CaldavCalendarSettingsActivity;
|
|
import org.tasks.data.CaldavAccount;
|
|
import org.tasks.data.GoogleTaskAccount;
|
|
import org.tasks.filters.FilterCounter;
|
|
import org.tasks.filters.FilterProvider;
|
|
import org.tasks.filters.NavigationDrawerAction;
|
|
import org.tasks.filters.NavigationDrawerSeparator;
|
|
import org.tasks.filters.NavigationDrawerSubheader;
|
|
import org.tasks.locale.Locale;
|
|
import org.tasks.preferences.BasicPreferences;
|
|
import org.tasks.sync.SynchronizationPreferences;
|
|
import org.tasks.themes.Theme;
|
|
import org.tasks.themes.ThemeCache;
|
|
import org.tasks.ui.NavigationDrawerFragment;
|
|
|
|
public class FilterAdapter extends ArrayAdapter<FilterListItem> {
|
|
|
|
public static final int REQUEST_SETTINGS = 10123;
|
|
public static final int REQUEST_PURCHASE = 10124;
|
|
|
|
// --- instance variables
|
|
private static final int VIEW_TYPE_COUNT = FilterListItem.Type.values().length;
|
|
private final FilterProvider filterProvider;
|
|
private final FilterCounter filterCounter;
|
|
private final Activity activity;
|
|
private final Theme theme;
|
|
private final Locale locale;
|
|
private final Inventory inventory;
|
|
private final FilterListUpdateReceiver filterListUpdateReceiver = new FilterListUpdateReceiver();
|
|
private final List<FilterListItem> items = new ArrayList<>();
|
|
private final LayoutInflater inflater;
|
|
private final ThemeCache themeCache;
|
|
private boolean navigationDrawer;
|
|
private Filter selected;
|
|
|
|
@Inject
|
|
public FilterAdapter(
|
|
FilterProvider filterProvider,
|
|
FilterCounter filterCounter,
|
|
Activity activity,
|
|
Theme theme,
|
|
ThemeCache themeCache,
|
|
Locale locale,
|
|
Inventory inventory) {
|
|
super(activity, 0);
|
|
this.filterProvider = filterProvider;
|
|
this.filterCounter = filterCounter;
|
|
this.activity = activity;
|
|
this.theme = theme;
|
|
this.locale = locale;
|
|
this.inventory = inventory;
|
|
this.inflater = theme.getLayoutInflater(activity);
|
|
this.themeCache = themeCache;
|
|
}
|
|
|
|
public void setNavigationDrawer() {
|
|
navigationDrawer = true;
|
|
}
|
|
|
|
public FilterListUpdateReceiver getFilterListUpdateReceiver() {
|
|
return filterListUpdateReceiver;
|
|
}
|
|
|
|
@Override
|
|
public boolean hasStableIds() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void add(FilterListItem item) {
|
|
super.add(item);
|
|
|
|
items.add(item);
|
|
|
|
if (navigationDrawer && item instanceof Filter) {
|
|
filterCounter.registerFilter((Filter) item);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void notifyDataSetChanged() {
|
|
activity.runOnUiThread(FilterAdapter.super::notifyDataSetChanged);
|
|
}
|
|
|
|
public void refreshFilterCount() {
|
|
filterCounter.refreshFilterCounts(this::notifyDataSetChanged);
|
|
}
|
|
|
|
/** Create or reuse a view */
|
|
private View newView(View convertView, ViewGroup parent, FilterListItem.Type viewType) {
|
|
if (convertView == null) {
|
|
ViewHolder viewHolder = new ViewHolder();
|
|
switch (viewType) {
|
|
case ITEM:
|
|
convertView = inflater.inflate(R.layout.filter_adapter_row, parent, false);
|
|
viewHolder.name = convertView.findViewById(R.id.name);
|
|
if (navigationDrawer) {
|
|
viewHolder.name.setCheckMarkDrawable(null);
|
|
} else if (preLollipop()) {
|
|
ColorStateList tintList =
|
|
new ColorStateList(
|
|
new int[][] {
|
|
new int[] {-android.R.attr.state_checked},
|
|
new int[] {android.R.attr.state_checked}
|
|
},
|
|
new int[] {
|
|
ResourcesCompat.getColor(
|
|
activity.getResources(), android.R.color.transparent, null),
|
|
theme.getThemeAccent().getAccentColor()
|
|
});
|
|
Drawable original = ContextCompat.getDrawable(activity, R.drawable.ic_check_black_24dp);
|
|
Drawable wrapped = DrawableCompat.wrap(original.mutate());
|
|
DrawableCompat.setTintList(wrapped, tintList);
|
|
viewHolder.name.setCheckMarkDrawable(wrapped);
|
|
}
|
|
viewHolder.icon = convertView.findViewById(R.id.icon);
|
|
viewHolder.size = convertView.findViewById(R.id.size);
|
|
break;
|
|
case SEPARATOR:
|
|
convertView = inflater.inflate(R.layout.filter_adapter_separator, parent, false);
|
|
break;
|
|
case SUBHEADER:
|
|
convertView = inflater.inflate(R.layout.filter_adapter_subheader, parent, false);
|
|
viewHolder.name = convertView.findViewById(R.id.subheader_text);
|
|
viewHolder.icon = convertView.findViewById(R.id.subheader_icon);
|
|
viewHolder.icon.setOnClickListener(
|
|
v -> activity.startActivity(new Intent(activity, SynchronizationPreferences.class)));
|
|
break;
|
|
}
|
|
viewHolder.view = convertView;
|
|
convertView.setTag(viewHolder);
|
|
}
|
|
return convertView;
|
|
}
|
|
|
|
public Filter getSelected() {
|
|
return selected;
|
|
}
|
|
|
|
public void setSelected(Filter selected) {
|
|
this.selected = selected;
|
|
}
|
|
|
|
public int indexOf(FilterListItem item, int defaultValue) {
|
|
int index = items.indexOf(item);
|
|
return index == -1 ? defaultValue : index;
|
|
}
|
|
|
|
@NonNull
|
|
@Override
|
|
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
|
|
FilterListItem item = getItem(position);
|
|
|
|
convertView = newView(convertView, parent, item.getItemType());
|
|
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
|
|
viewHolder.item = getItem(position);
|
|
switch (item.getItemType()) {
|
|
case ITEM:
|
|
populateItem(viewHolder);
|
|
break;
|
|
case SUBHEADER:
|
|
populateHeader(viewHolder);
|
|
break;
|
|
case SEPARATOR:
|
|
break;
|
|
}
|
|
|
|
return convertView;
|
|
}
|
|
|
|
@Override
|
|
public int getViewTypeCount() {
|
|
return VIEW_TYPE_COUNT;
|
|
}
|
|
|
|
@Override
|
|
public boolean isEnabled(int position) {
|
|
return getItem(position).getItemType() == FilterListItem.Type.ITEM;
|
|
}
|
|
|
|
@Override
|
|
public int getItemViewType(int position) {
|
|
return getItem(position).getItemType().ordinal();
|
|
}
|
|
|
|
@Override
|
|
public View getDropDownView(int position, View convertView, @NonNull ViewGroup parent) {
|
|
return getView(position, convertView, parent);
|
|
}
|
|
|
|
private void addSubMenu(
|
|
final int titleResource, boolean error, List<Filter> filters, boolean hideIfEmpty) {
|
|
addSubMenu(activity.getResources().getString(titleResource), error, filters, hideIfEmpty);
|
|
}
|
|
|
|
/* ======================================================================
|
|
* ============================================================= receiver
|
|
* ====================================================================== */
|
|
|
|
private void addSubMenu(String title, boolean error, List<Filter> filters, boolean hideIfEmpty) {
|
|
if (hideIfEmpty && filters.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
add(new NavigationDrawerSubheader(title, error));
|
|
|
|
for (FilterListItem filterListItem : filters) {
|
|
add(filterListItem);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void clear() {
|
|
super.clear();
|
|
items.clear();
|
|
}
|
|
|
|
public void populateRemoteListPicker() {
|
|
clear();
|
|
|
|
Filter item = new Filter(activity.getString(R.string.dont_sync), null);
|
|
item.icon = R.drawable.ic_cloud_off_black_24dp;
|
|
add(item);
|
|
|
|
for (Pair<GoogleTaskAccount, List<Filter>> filters : filterProvider.getGoogleTaskFilters()) {
|
|
GoogleTaskAccount account = filters.first;
|
|
addSubMenu(account.getAccount(), !isNullOrEmpty(account.getError()), filters.second, true);
|
|
}
|
|
|
|
for (Pair<CaldavAccount, List<Filter>> filters : filterProvider.getCaldavFilters()) {
|
|
CaldavAccount account = filters.first;
|
|
addSubMenu(account.getName(), !isNullOrEmpty(account.getError()), filters.second, true);
|
|
}
|
|
|
|
notifyDataSetChanged();
|
|
}
|
|
|
|
public void populateList() {
|
|
clear();
|
|
|
|
add(filterProvider.getMyTasksFilter());
|
|
|
|
addSubMenu(R.string.filters, false, filterProvider.getFilters(), false);
|
|
|
|
if (navigationDrawer) {
|
|
add(
|
|
new NavigationDrawerAction(
|
|
activity.getResources().getString(R.string.FLA_new_filter),
|
|
R.drawable.ic_add_24dp,
|
|
new Intent(activity, CustomFilterActivity.class),
|
|
NavigationDrawerFragment.ACTIVITY_REQUEST_NEW_FILTER));
|
|
}
|
|
|
|
addSubMenu(R.string.tags, false, filterProvider.getTags(), false);
|
|
|
|
if (navigationDrawer) {
|
|
add(
|
|
new NavigationDrawerAction(
|
|
activity.getResources().getString(R.string.new_tag),
|
|
R.drawable.ic_add_24dp,
|
|
new Intent(activity, TagSettingsActivity.class),
|
|
NavigationDrawerFragment.REQUEST_NEW_LIST));
|
|
}
|
|
|
|
for (Pair<GoogleTaskAccount, List<Filter>> filters : filterProvider.getGoogleTaskFilters()) {
|
|
GoogleTaskAccount account = filters.first;
|
|
addSubMenu(
|
|
account.getAccount(),
|
|
!isNullOrEmpty(account.getError()),
|
|
filters.second,
|
|
!navigationDrawer);
|
|
|
|
if (navigationDrawer) {
|
|
add(
|
|
new NavigationDrawerAction(
|
|
activity.getResources().getString(R.string.new_list),
|
|
R.drawable.ic_add_24dp,
|
|
new Intent(activity, GoogleTaskListSettingsActivity.class)
|
|
.putExtra(GoogleTaskListSettingsActivity.EXTRA_ACCOUNT, account),
|
|
NavigationDrawerFragment.REQUEST_NEW_GTASK_LIST));
|
|
}
|
|
}
|
|
|
|
for (Pair<CaldavAccount, List<Filter>> filters : filterProvider.getCaldavFilters()) {
|
|
CaldavAccount account = filters.first;
|
|
addSubMenu(
|
|
account.getName(), !isNullOrEmpty(account.getError()), filters.second, !navigationDrawer);
|
|
|
|
if (navigationDrawer) {
|
|
add(
|
|
new NavigationDrawerAction(
|
|
activity.getString(R.string.caldav_create_new_collection),
|
|
R.drawable.ic_add_24dp,
|
|
new Intent(activity, CaldavCalendarSettingsActivity.class)
|
|
.putExtra(EXTRA_CALDAV_ACCOUNT, account),
|
|
NavigationDrawerFragment.REQUEST_NEW_CALDAV_COLLECTION));
|
|
}
|
|
}
|
|
|
|
if (navigationDrawer) {
|
|
add(new NavigationDrawerSeparator());
|
|
|
|
if (!inventory.hasPro()) {
|
|
add(
|
|
new NavigationDrawerAction(
|
|
activity.getResources().getString(R.string.upgrade_to_pro),
|
|
R.drawable.ic_attach_money_black_24dp,
|
|
new Intent(activity, PurchaseActivity.class),
|
|
REQUEST_PURCHASE));
|
|
}
|
|
|
|
add(
|
|
new NavigationDrawerAction(
|
|
activity.getResources().getString(R.string.TLA_menu_settings),
|
|
R.drawable.ic_settings_24dp,
|
|
new Intent(activity, BasicPreferences.class),
|
|
REQUEST_SETTINGS));
|
|
}
|
|
|
|
notifyDataSetChanged();
|
|
|
|
filterCounter.refreshFilterCounts(this::notifyDataSetChanged);
|
|
}
|
|
|
|
private void populateItem(ViewHolder viewHolder) {
|
|
FilterListItem filter = viewHolder.item;
|
|
if (filter == null) {
|
|
return;
|
|
}
|
|
|
|
if (selected != null && selected.equals(filter)) {
|
|
viewHolder.view.setBackgroundColor(getColor(activity, R.color.drawer_color_selected));
|
|
} else {
|
|
viewHolder.view.setBackgroundResource(0);
|
|
}
|
|
|
|
viewHolder.icon.setImageResource(filter.icon);
|
|
viewHolder.icon.setColorFilter(
|
|
filter.tint >= 0
|
|
? themeCache.getThemeColor(filter.tint).getPrimaryColor()
|
|
: getColor(activity, R.color.text_primary));
|
|
|
|
String title = filter.listingTitle;
|
|
if (!title.equals(viewHolder.name.getText())) {
|
|
viewHolder.name.setText(title);
|
|
}
|
|
|
|
int countInt = 0;
|
|
if (filterCounter.containsKey(filter)) {
|
|
countInt = filterCounter.get(filter);
|
|
viewHolder.size.setText(locale.formatNumber(countInt));
|
|
}
|
|
viewHolder.size.setVisibility(countInt > 0 ? View.VISIBLE : View.GONE);
|
|
}
|
|
|
|
private void populateHeader(ViewHolder viewHolder) {
|
|
NavigationDrawerSubheader filter = (NavigationDrawerSubheader) viewHolder.item;
|
|
if (filter == null) {
|
|
return;
|
|
}
|
|
|
|
viewHolder.name.setText(filter.listingTitle);
|
|
viewHolder.icon.setVisibility(filter.error ? View.VISIBLE : View.GONE);
|
|
}
|
|
|
|
/* ======================================================================
|
|
* ================================================================ views
|
|
* ====================================================================== */
|
|
|
|
static class ViewHolder {
|
|
|
|
FilterListItem item;
|
|
CheckedTextView name;
|
|
ImageView icon;
|
|
TextView size;
|
|
View view;
|
|
}
|
|
|
|
public class FilterListUpdateReceiver extends BroadcastReceiver {
|
|
|
|
@Override
|
|
public void onReceive(Context context, Intent intent) {
|
|
notifyDataSetChanged();
|
|
}
|
|
}
|
|
}
|