diff --git a/app/src/main/java/com/todoroo/astrid/activity/MainActivity.java b/app/src/main/java/com/todoroo/astrid/activity/MainActivity.java index d260ecd5f..1632c739e 100644 --- a/app/src/main/java/com/todoroo/astrid/activity/MainActivity.java +++ b/app/src/main/java/com/todoroo/astrid/activity/MainActivity.java @@ -12,8 +12,10 @@ import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop; import static com.todoroo.andlib.utility.AndroidUtilities.atLeastNougat; import static com.todoroo.astrid.activity.TaskEditFragment.newTaskEditFragment; import static com.todoroo.astrid.activity.TaskListFragment.newTaskListFragment; +import static org.tasks.location.LocationPickerActivity.EXTRA_PLACE; import static org.tasks.tasklist.ActionUtils.applySupportActionModeColor; import static org.tasks.ui.NavigationDrawerFragment.REQUEST_NEW_LIST; +import static org.tasks.ui.NavigationDrawerFragment.REQUEST_NEW_PLACE; import android.annotation.SuppressLint; import android.content.Intent; @@ -43,8 +45,10 @@ import org.tasks.LocalBroadcastManager; import org.tasks.R; import org.tasks.activities.TagSettingsActivity; import org.tasks.billing.Inventory; +import org.tasks.data.Place; import org.tasks.databinding.TaskListActivityBinding; import org.tasks.dialogs.SortDialog; +import org.tasks.filters.PlaceFilter; import org.tasks.fragments.CommentBarFragment; import org.tasks.gtasks.PlayServices; import org.tasks.injection.ActivityComponent; @@ -151,6 +155,13 @@ public class MainActivity extends InjectingAppCompatActivity startActivity(TaskIntents.getTaskListIntent(this, filter)); } } + } else if (requestCode == REQUEST_NEW_PLACE) { + if (resultCode == RESULT_OK && data != null) { + Place place = data.getParcelableExtra(EXTRA_PLACE); + if (place != null) { + startActivity(TaskIntents.getTaskListIntent(this, new PlaceFilter(place))); + } + } } else { super.onActivityResult(requestCode, resultCode, data); } diff --git a/app/src/main/java/com/todoroo/astrid/tags/TagFilterExposer.java b/app/src/main/java/com/todoroo/astrid/tags/TagFilterExposer.java deleted file mode 100644 index 364a22185..000000000 --- a/app/src/main/java/com/todoroo/astrid/tags/TagFilterExposer.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2012 Todoroo Inc - * - * See the file "LICENSE" for the full license governing this code. - */ - -package com.todoroo.astrid.tags; - -import static com.google.common.collect.Lists.newArrayList; -import static com.google.common.collect.Lists.transform; -import static com.todoroo.andlib.utility.DateUtilities.now; - -import com.google.common.base.Strings; -import com.todoroo.astrid.api.Filter; -import com.todoroo.astrid.api.TagFilter; -import java.util.Collections; -import java.util.List; -import javax.inject.Inject; -import org.tasks.data.TagData; -import org.tasks.data.TagDataDao; -import org.tasks.filters.AlphanumComparator; -import org.tasks.filters.TagFilters; - -/** - * Exposes filters based on tags - * - * @author Tim Su - */ -public class TagFilterExposer { - - private final TagDataDao tagDataDao; - - @Inject - public TagFilterExposer(TagDataDao tagDataDao) { - this.tagDataDao = tagDataDao; - } - - /** Create filter from new tag object */ - private static TagFilter filterFromTag(TagData tag) { - if (tag == null || Strings.isNullOrEmpty(tag.getName())) { - return null; - } - return new TagFilter(tag); - } - - public List getFilters() { - List tags = - newArrayList(transform(tagDataDao.getTagFilters(now()), TagFilters::toTagFilter)); - Collections.sort(tags, new AlphanumComparator<>(AlphanumComparator.FILTER)); - return tags; - } - - public Filter getFilterByUuid(String uuid) { - return filterFromTag(tagDataDao.getByUuid(uuid)); - } -} diff --git a/app/src/main/java/org/tasks/data/LocationDao.java b/app/src/main/java/org/tasks/data/LocationDao.java index 20a457f91..df212f801 100644 --- a/app/src/main/java/org/tasks/data/LocationDao.java +++ b/app/src/main/java/org/tasks/data/LocationDao.java @@ -77,11 +77,9 @@ public interface LocationDao { Place findPlace(String latitude, String longitude); @Query("SELECT places.*, COUNT(tasks._id) AS count FROM places " - + " INNER JOIN geofences ON geofences.place = places.uid " - + " INNER JOIN tasks ON geofences.task = tasks._id" - + " WHERE tasks.completed = 0 AND tasks.deleted = 0" - + " AND tasks.hideUntil < :now" + + " LEFT JOIN geofences ON geofences.place = places.uid " + + " LEFT JOIN tasks ON geofences.task = tasks._id AND tasks.completed = 0 AND tasks.deleted = 0 AND tasks.hideUntil < :now" + " GROUP BY places.uid" - + " ORDER BY count DESC") + + " ORDER BY count DESC, name COLLATE NOCASE ASC") List getPlaceFilters(long now); } diff --git a/app/src/main/java/org/tasks/filters/FilterProvider.java b/app/src/main/java/org/tasks/filters/FilterProvider.java index b2ba1727a..487b44edd 100644 --- a/app/src/main/java/org/tasks/filters/FilterProvider.java +++ b/app/src/main/java/org/tasks/filters/FilterProvider.java @@ -7,6 +7,7 @@ import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.transform; import static com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread; import static com.todoroo.andlib.utility.DateUtilities.now; +import static java.util.Collections.emptyList; import static org.tasks.caldav.CaldavCalendarSettingsActivity.EXTRA_CALDAV_ACCOUNT; import static org.tasks.ui.NavigationDrawerFragment.REQUEST_DONATE; import static org.tasks.ui.NavigationDrawerFragment.REQUEST_PURCHASE; @@ -21,7 +22,6 @@ import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.core.BuiltInFilterExposer; import com.todoroo.astrid.core.CustomFilterActivity; import com.todoroo.astrid.core.CustomFilterExposer; -import com.todoroo.astrid.tags.TagFilterExposer; import com.todoroo.astrid.timers.TimerFilterExposer; import java.util.ArrayList; import java.util.Collections; @@ -43,9 +43,11 @@ import org.tasks.data.CaldavDao; import org.tasks.data.GoogleTaskAccount; import org.tasks.data.GoogleTaskListDao; import org.tasks.data.LocationDao; +import org.tasks.data.TagDataDao; import org.tasks.etesync.EteSyncCalendarSettingsActivity; import org.tasks.filters.NavigationDrawerSubheader.SubheaderType; import org.tasks.injection.ForApplication; +import org.tasks.location.LocationPickerActivity; import org.tasks.preferences.HelpAndFeedback; import org.tasks.preferences.MainPreferences; import org.tasks.preferences.Preferences; @@ -58,7 +60,7 @@ public class FilterProvider { private final BuiltInFilterExposer builtInFilterExposer; private final TimerFilterExposer timerFilterExposer; private final CustomFilterExposer customFilterExposer; - private final TagFilterExposer tagFilterExposer; + private final TagDataDao tagDataDao; private final GoogleTaskListDao googleTaskListDao; private final CaldavDao caldavDao; private final Preferences preferences; @@ -71,7 +73,7 @@ public class FilterProvider { BuiltInFilterExposer builtInFilterExposer, TimerFilterExposer timerFilterExposer, CustomFilterExposer customFilterExposer, - TagFilterExposer tagFilterExposer, + TagDataDao tagDataDao, GoogleTaskListDao googleTaskListDao, CaldavDao caldavDao, Preferences preferences, @@ -81,7 +83,7 @@ public class FilterProvider { this.builtInFilterExposer = builtInFilterExposer; this.timerFilterExposer = timerFilterExposer; this.customFilterExposer = customFilterExposer; - this.tagFilterExposer = tagFilterExposer; + this.tagDataDao = tagDataDao; this.googleTaskListDao = googleTaskListDao; this.caldavDao = caldavDao; this.preferences = preferences; @@ -126,12 +128,10 @@ public class FilterProvider { return items; } - public List getItems(boolean navigationDrawer) { - assertNotMainThread(); - - List items = new ArrayList<>(); - - items.add(builtInFilterExposer.getMyTasksFilter()); + private void addFilters(List items, boolean navigationDrawer) { + if (!preferences.getBoolean(R.string.p_filters_enabled, true)) { + return; + } items.addAll(getSubmenu(R.string.filters, R.string.p_collapse_filters, this::getFilters)); @@ -143,24 +143,32 @@ public class FilterProvider { new Intent(context, CustomFilterActivity.class), NavigationDrawerFragment.REQUEST_NEW_LIST)); } + } - items.addAll( - getSubmenu(R.string.tags, R.string.p_collapse_tags, tagFilterExposer::getFilters)); + private void addTags(List items, boolean navigationDrawer) { + if (!preferences.getBoolean(R.string.p_tags_enabled, true)) { + return; + } - if (navigationDrawer) { - boolean collapsed = preferences.getBoolean(R.string.p_collapse_locations, false); - items.addAll( - getSubmenu( - context.getString(R.string.places), - false, - collapsed ? Collections.emptyList() : getLocationFilters(), - true, - collapsed, - SubheaderType.PREFERENCE, - R.string.p_collapse_locations)); + boolean collapsed = preferences.getBoolean(R.string.p_collapse_tags, false); + Iterable filters = collapsed ? emptyList() : tagDataDao.getTagFilters(now()); + if (preferences.getBoolean(R.string.p_tags_hide_unused, false)) { + filters = filter(filters, f -> f.count > 0); } + List tags = newArrayList(Iterables.transform(filters, TagFilters::toTagFilter)); + Collections.sort(tags, new AlphanumComparator<>(AlphanumComparator.FILTER)); - if (navigationDrawer && !preferences.getBoolean(R.string.p_collapse_tags, false)) { + items.addAll( + getSubmenu( + context.getString(R.string.tags), + false, + tags, + false, + collapsed, + SubheaderType.PREFERENCE, + R.string.p_collapse_tags)); + + if (navigationDrawer && !collapsed) { items.add( new NavigationDrawerAction( context.getString(R.string.new_tag), @@ -168,6 +176,51 @@ public class FilterProvider { new Intent(context, TagSettingsActivity.class), NavigationDrawerFragment.REQUEST_NEW_LIST)); } + } + + private void addPlaces(List items, boolean navigationDrawer) { + if (!preferences.getBoolean(R.string.p_places_enabled, true)) { + return; + } + + boolean collapsed = preferences.getBoolean(R.string.p_collapse_locations, false); + Iterable filters = collapsed ? emptyList() : locationDao.getPlaceFilters(now()); + if (preferences.getBoolean(R.string.p_places_hide_unused, false)) { + filters = filter(filters, f -> f.count > 0); + } + + items.addAll( + getSubmenu( + context.getString(R.string.places), + false, + newArrayList(Iterables.transform(filters, LocationFilters::toLocationFilter)), + false, + collapsed, + SubheaderType.PREFERENCE, + R.string.p_collapse_locations)); + + if (navigationDrawer && !collapsed) { + items.add( + new NavigationDrawerAction( + context.getString(R.string.add_place), + R.drawable.ic_outline_add_24px, + new Intent(context, LocationPickerActivity.class), + NavigationDrawerFragment.REQUEST_NEW_PLACE)); + } + } + + public List getItems(boolean navigationDrawer) { + assertNotMainThread(); + + List items = new ArrayList<>(); + + items.add(builtInFilterExposer.getMyTasksFilter()); + + addFilters(items, navigationDrawer); + + addTags(items, navigationDrawer); + + addPlaces(items, navigationDrawer); for (Map.Entry> filters : getGoogleTaskFilters()) { GoogleTaskAccount account = filters.getKey(); @@ -255,12 +308,6 @@ public class FilterProvider { return items; } - private List getLocationFilters() { - List filters = locationDao.getPlaceFilters(now()); - return newArrayList( - Iterables.transform(filter(filters, f -> f.count > 0), LocationFilters::toLocationFilter)); - } - private List getFilters() { ArrayList filters = new ArrayList<>(); filters.addAll(builtInFilterExposer.getFilters()); @@ -276,7 +323,7 @@ public class FilterProvider { filters.put( account, account.isCollapsed() - ? Collections.emptyList() + ? emptyList() : newArrayList( transform( googleTaskListDao.getGoogleTaskFilters(account.getId(), now()), @@ -295,7 +342,7 @@ public class FilterProvider { filters.put( account, account.isCollapsed() - ? Collections.emptyList() + ? emptyList() : newArrayList( transform( caldavDao.getCaldavFilters(account.getId(), now()), @@ -314,7 +361,7 @@ public class FilterProvider { ImmutableList.of( new NavigationDrawerSubheader( context.getString(title), false, collapsed, SubheaderType.PREFERENCE, prefId)), - collapsed ? Collections.emptyList() : getFilters.call())); + collapsed ? emptyList() : getFilters.call())); } private List getSubmenu( diff --git a/app/src/main/java/org/tasks/injection/FragmentComponent.java b/app/src/main/java/org/tasks/injection/FragmentComponent.java index 4a9affde0..edfadb061 100644 --- a/app/src/main/java/org/tasks/injection/FragmentComponent.java +++ b/app/src/main/java/org/tasks/injection/FragmentComponent.java @@ -19,6 +19,7 @@ import org.tasks.preferences.fragments.Debug; import org.tasks.preferences.fragments.HelpAndFeedback; import org.tasks.preferences.fragments.LookAndFeel; import org.tasks.preferences.fragments.MainSettingsFragment; +import org.tasks.preferences.fragments.NavigationDrawer; import org.tasks.preferences.fragments.Notifications; import org.tasks.preferences.fragments.ScrollableWidget; import org.tasks.preferences.fragments.Synchronization; @@ -101,4 +102,6 @@ public interface FragmentComponent { void inject(@NonNull TaskerListNotification taskerListNotification); void inject(EmptyTaskEditFragment emptyTaskEditFragment); + + void inject(NavigationDrawer navigationDrawer); } diff --git a/app/src/main/java/org/tasks/preferences/DefaultFilterProvider.java b/app/src/main/java/org/tasks/preferences/DefaultFilterProvider.java index bdac3c4d3..fd5bcb5be 100644 --- a/app/src/main/java/org/tasks/preferences/DefaultFilterProvider.java +++ b/app/src/main/java/org/tasks/preferences/DefaultFilterProvider.java @@ -19,7 +19,6 @@ import com.todoroo.astrid.api.GtasksFilter; import com.todoroo.astrid.api.TagFilter; import com.todoroo.astrid.core.BuiltInFilterExposer; import com.todoroo.astrid.core.CustomFilterExposer; -import com.todoroo.astrid.tags.TagFilterExposer; import javax.inject.Inject; import org.tasks.R; import org.tasks.data.CaldavCalendar; @@ -28,6 +27,8 @@ import org.tasks.data.GoogleTaskList; import org.tasks.data.GoogleTaskListDao; import org.tasks.data.LocationDao; import org.tasks.data.Place; +import org.tasks.data.TagData; +import org.tasks.data.TagDataDao; import org.tasks.filters.PlaceFilter; import org.tasks.injection.ForApplication; import timber.log.Timber; @@ -49,7 +50,7 @@ public class DefaultFilterProvider { private final Context context; private final Preferences preferences; private final CustomFilterExposer customFilterExposer; - private final TagFilterExposer tagFilterExposer; + private final TagDataDao tagDataDao; private final GoogleTaskListDao googleTaskListDao; private final CaldavDao caldavDao; private final LocationDao locationDao; @@ -59,14 +60,14 @@ public class DefaultFilterProvider { @ForApplication Context context, Preferences preferences, CustomFilterExposer customFilterExposer, - TagFilterExposer tagFilterExposer, + TagDataDao tagDataDao, GoogleTaskListDao googleTaskListDao, CaldavDao caldavDao, LocationDao locationDao) { this.context = context; this.preferences = preferences; this.customFilterExposer = customFilterExposer; - this.tagFilterExposer = tagFilterExposer; + this.tagDataDao = tagDataDao; this.googleTaskListDao = googleTaskListDao; this.caldavDao = caldavDao; this.locationDao = locationDao; @@ -136,7 +137,8 @@ public class DefaultFilterProvider { case TYPE_CUSTOM_FILTER: return customFilterExposer.getFilter(Long.parseLong(split[1])); case TYPE_TAG: - return tagFilterExposer.getFilterByUuid(split[1]); + TagData tag = tagDataDao.getByUuid(split[1]); + return tag == null || isNullOrEmpty(tag.getName()) ? null : new TagFilter(tag); case TYPE_GOOGLE_TASKS: GoogleTaskList list = googleTaskListDao.getById(Long.parseLong(split[1])); return list == null ? null : new GtasksFilter(list); diff --git a/app/src/main/java/org/tasks/preferences/fragments/NavigationDrawer.kt b/app/src/main/java/org/tasks/preferences/fragments/NavigationDrawer.kt new file mode 100644 index 000000000..c9cee29b0 --- /dev/null +++ b/app/src/main/java/org/tasks/preferences/fragments/NavigationDrawer.kt @@ -0,0 +1,17 @@ +package org.tasks.preferences.fragments + +import android.os.Bundle +import org.tasks.R +import org.tasks.injection.FragmentComponent +import org.tasks.injection.InjectingPreferenceFragment + +class NavigationDrawer : InjectingPreferenceFragment() { + + override fun getPreferenceXml() = R.xml.preferences_navigation_drawer + + override fun setupPreferences(savedInstanceState: Bundle?) { + + } + + override fun inject(component: FragmentComponent) = component.inject(this) +} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/ui/NavigationDrawerFragment.java b/app/src/main/java/org/tasks/ui/NavigationDrawerFragment.java index cf62c1529..5acb88cf8 100644 --- a/app/src/main/java/org/tasks/ui/NavigationDrawerFragment.java +++ b/app/src/main/java/org/tasks/ui/NavigationDrawerFragment.java @@ -51,6 +51,7 @@ public class NavigationDrawerFragment extends InjectingFragment { public static final int REQUEST_SETTINGS = 10101; public static final int REQUEST_PURCHASE = 10102; public static final int REQUEST_DONATE = 10103; + public static final int REQUEST_NEW_PLACE = 10104; private final RefreshReceiver refreshReceiver = new RefreshReceiver(); @Inject LocalBroadcastManager localBroadcastManager; diff --git a/app/src/main/res/values/keys.xml b/app/src/main/res/values/keys.xml index b87f20ff9..e379e7d19 100644 --- a/app/src/main/res/values/keys.xml +++ b/app/src/main/res/values/keys.xml @@ -54,10 +54,16 @@ p_calendar_reminder + drawer_filters_enabled p_show_today_f p_show_recently_modified_f p_show_no_list_f + drawer_tags_enabled + drawer_tags_hide_unused + drawer_places_enabled + drawer_places_hide_unused + p_show_task_edit_comments diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3e8a48aee..8caff509a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -568,4 +568,8 @@ File %1$s contained %2$s.\n\n Colors will not be desaturated in dark themes Places Place settings + Navigation drawer + Hide unused tags + Hide unused places + Add place diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index b076f924a..fbfce1aea 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -22,6 +22,11 @@ app:icon="@drawable/ic_outline_edit_24px" app:title="@string/task_defaults" /> + + - - - - - - - - - - diff --git a/app/src/main/res/xml/preferences_navigation_drawer.xml b/app/src/main/res/xml/preferences_navigation_drawer.xml new file mode 100644 index 000000000..09b63bc8c --- /dev/null +++ b/app/src/main/res/xml/preferences_navigation_drawer.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file