Add location chip to task list

pull/848/head
Alex Baker 7 years ago
parent 76bb10c40d
commit 4feec7e39f

@ -1,16 +1,22 @@
package org.tasks.data; package org.tasks.data;
import static org.tasks.data.Geofence.TABLE_NAME;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.room.ColumnInfo; import androidx.room.ColumnInfo;
import androidx.room.Entity; import androidx.room.Entity;
import androidx.room.Ignore; import androidx.room.Ignore;
import androidx.room.PrimaryKey; import androidx.room.PrimaryKey;
import com.todoroo.andlib.data.Table;
import java.io.Serializable; import java.io.Serializable;
@Entity(tableName = "geofences") @Entity(tableName = TABLE_NAME)
public class Geofence implements Serializable, Parcelable { public class Geofence implements Serializable, Parcelable {
public static final String TABLE_NAME = "geofences";
public static final Table TABLE = new Table(TABLE_NAME);
public static final Parcelable.Creator<Geofence> CREATOR = public static final Parcelable.Creator<Geofence> CREATOR =
new Parcelable.Creator<Geofence>() { new Parcelable.Creator<Geofence>() {
@Override @Override

@ -1,6 +1,7 @@
package org.tasks.data; package org.tasks.data;
import static com.mapbox.api.geocoding.v5.GeocodingCriteria.TYPE_ADDRESS; import static com.mapbox.api.geocoding.v5.GeocodingCriteria.TYPE_ADDRESS;
import static org.tasks.data.Place.TABLE_NAME;
import android.location.Location; import android.location.Location;
import android.net.Uri; import android.net.Uri;
@ -12,6 +13,7 @@ import androidx.room.Ignore;
import androidx.room.PrimaryKey; import androidx.room.PrimaryKey;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.mapbox.api.geocoding.v5.models.CarmenFeature; import com.mapbox.api.geocoding.v5.models.CarmenFeature;
import com.todoroo.andlib.data.Table;
import com.todoroo.astrid.helper.UUIDHelper; import com.todoroo.astrid.helper.UUIDHelper;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
@ -19,9 +21,12 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.tasks.location.MapPosition; import org.tasks.location.MapPosition;
@Entity(tableName = "places") @Entity(tableName = TABLE_NAME)
public class Place implements Serializable, Parcelable { public class Place implements Serializable, Parcelable {
public static final String TABLE_NAME = "places";
public static final Table TABLE = new Table(TABLE_NAME);
public static final Creator<Place> CREATOR = public static final Creator<Place> CREATOR =
new Creator<Place>() { new Creator<Place>() {
@Override @Override

@ -6,6 +6,7 @@ import com.todoroo.astrid.data.Task;
public class TaskContainer { public class TaskContainer {
@Embedded public Task task; @Embedded public Task task;
@Embedded public GoogleTask googletask; @Embedded public GoogleTask googletask;
@Embedded public Location location;
public String tags; public String tags;
public String caldav; public String caldav;
public int children; public int children;
@ -130,6 +131,9 @@ public class TaskContainer {
if (googletask != null ? !googletask.equals(that.googletask) : that.googletask != null) { if (googletask != null ? !googletask.equals(that.googletask) : that.googletask != null) {
return false; return false;
} }
if (location != null ? !location.equals(that.location) : that.location != null) {
return false;
}
if (tags != null ? !tags.equals(that.tags) : that.tags != null) { if (tags != null ? !tags.equals(that.tags) : that.tags != null) {
return false; return false;
} }
@ -140,6 +144,7 @@ public class TaskContainer {
public int hashCode() { public int hashCode() {
int result = task != null ? task.hashCode() : 0; int result = task != null ? task.hashCode() : 0;
result = 31 * result + (googletask != null ? googletask.hashCode() : 0); result = 31 * result + (googletask != null ? googletask.hashCode() : 0);
result = 31 * result + (location != null ? location.hashCode() : 0);
result = 31 * result + (tags != null ? tags.hashCode() : 0); result = 31 * result + (tags != null ? tags.hashCode() : 0);
result = 31 * result + (caldav != null ? caldav.hashCode() : 0); result = 31 * result + (caldav != null ? caldav.hashCode() : 0);
result = 31 * result + children; result = 31 * result + children;
@ -158,6 +163,8 @@ public class TaskContainer {
+ task + task
+ ", googletask=" + ", googletask="
+ googletask + googletask
+ ", location="
+ location
+ ", tags='" + ", tags='"
+ tags + tags
+ '\'' + '\''
@ -207,11 +214,19 @@ public class TaskContainer {
return googletask; return googletask;
} }
public int getTargetIndent() {
return targetIndent;
}
public void setTargetIndent(int indent) { public void setTargetIndent(int indent) {
targetIndent = indent; targetIndent = indent;
} }
public int getTargetIndent() { public boolean hasLocation() {
return targetIndent; return location != null;
}
public Location getLocation() {
return location;
} }
} }

@ -8,7 +8,9 @@ import static com.todoroo.andlib.utility.DateUtilities.getAbbreviatedRelativeDat
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.graphics.Paint; import android.graphics.Paint;
import android.net.Uri;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -28,6 +30,7 @@ import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.ui.CheckableImageView; import com.todoroo.astrid.ui.CheckableImageView;
import java.util.List; import java.util.List;
import org.tasks.R; import org.tasks.R;
import org.tasks.data.Location;
import org.tasks.data.TaskContainer; import org.tasks.data.TaskContainer;
import org.tasks.dialogs.Linkify; import org.tasks.dialogs.Linkify;
import org.tasks.locale.Locale; import org.tasks.locale.Locale;
@ -70,6 +73,9 @@ public class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.completeBox) @BindView(R.id.completeBox)
CheckableImageView completeBox; CheckableImageView completeBox;
@BindView(R.id.location_chip)
Chip locationChip;
@BindView(R.id.chip_group) @BindView(R.id.chip_group)
ChipGroup chipGroup; ChipGroup chipGroup;
@ -140,8 +146,9 @@ public class ViewHolder extends RecyclerView.ViewHolder {
dueDate.setTextSize(fontSizeDetails); dueDate.setTextSize(fontSizeDetails);
if (atLeastJellybeanMR1()) { if (atLeastJellybeanMR1()) {
chipGroup.setLayoutDirection( int direction = locale.isRtl() ? View.LAYOUT_DIRECTION_LTR : View.LAYOUT_DIRECTION_RTL;
locale.isRtl() ? View.LAYOUT_DIRECTION_LTR : View.LAYOUT_DIRECTION_RTL); chipGroup.setLayoutDirection(direction);
locationChip.setLayoutDirection(direction);
} else { } else {
MarginLayoutParams lp = (MarginLayoutParams) chipGroup.getLayoutParams(); MarginLayoutParams lp = (MarginLayoutParams) chipGroup.getLayoutParams();
lp.setMargins(lp.rightMargin, lp.topMargin, lp.leftMargin, lp.bottomMargin); lp.setMargins(lp.rightMargin, lp.topMargin, lp.leftMargin, lp.bottomMargin);
@ -206,6 +213,7 @@ public class ViewHolder extends RecyclerView.ViewHolder {
setupTitleAndCheckbox(); setupTitleAndCheckbox();
setupDueDate(); setupDueDate();
if (preferences.getBoolean(R.string.p_show_list_indicators, true)) { if (preferences.getBoolean(R.string.p_show_list_indicators, true)) {
setupLocation();
setupTags(); setupTags();
} }
if (preferences.getBoolean(R.string.p_show_description, true)) { if (preferences.getBoolean(R.string.p_show_description, true)) {
@ -252,6 +260,22 @@ public class ViewHolder extends RecyclerView.ViewHolder {
} }
} }
private void setupLocation() {
if (task.hasLocation()) {
locationChip.setText(task.getLocation().getDisplayName());
locationChip.setTag(task.getLocation());
locationChip.setOnClickListener(v -> {
Location location = (Location) v.getTag();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(location.getGeoUri()));
context.startActivity(intent);
});
locationChip.setVisibility(View.VISIBLE);
} else {
locationChip.setVisibility(View.GONE);
}
}
private void setupTags() { private void setupTags() {
String tags = task.getTagsString(); String tags = task.getTagsString();
List<String> tagUuids = tags != null ? newArrayList(tags.split(",")) : Lists.newArrayList(); List<String> tagUuids = tags != null ? newArrayList(tags.split(",")) : Lists.newArrayList();

@ -39,7 +39,9 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import org.tasks.data.CaldavTask; import org.tasks.data.CaldavTask;
import org.tasks.data.Geofence;
import org.tasks.data.GoogleTask; import org.tasks.data.GoogleTask;
import org.tasks.data.Place;
import org.tasks.data.Tag; import org.tasks.data.Tag;
import org.tasks.data.TaskContainer; import org.tasks.data.TaskContainer;
import org.tasks.preferences.Preferences; import org.tasks.preferences.Preferences;
@ -52,6 +54,8 @@ public class TaskListViewModel extends ViewModel implements Observer<PagedList<T
private static final Field TASKS = field("tasks.*"); private static final Field TASKS = field("tasks.*");
private static final Field GTASK = field(GTASK_METADATA_JOIN + ".*"); private static final Field GTASK = field(GTASK_METADATA_JOIN + ".*");
private static final Field GEOFENCE = field("geofences.*");
private static final Field PLACE = field("places.*");
private static final StringProperty CALDAV = private static final StringProperty CALDAV =
new StringProperty(null, CALDAV_METADATA_JOIN + ".calendar").as("caldav"); new StringProperty(null, CALDAV_METADATA_JOIN + ".calendar").as("caldav");
private static final Field CHILDREN = field("children"); private static final Field CHILDREN = field("children");
@ -86,7 +90,7 @@ public class TaskListViewModel extends ViewModel implements Observer<PagedList<T
} }
private String getQuery(Filter filter) { private String getQuery(Filter filter) {
List<Field> fields = Lists.newArrayList(TASKS, TAGS, GTASK, CALDAV); List<Field> fields = Lists.newArrayList(TASKS, TAGS, GTASK, CALDAV, GEOFENCE, PLACE);
Criterion tagsJoinCriterion = Criterion.and(Task.ID.eq(field(TAGS_METADATA_JOIN + ".task"))); Criterion tagsJoinCriterion = Criterion.and(Task.ID.eq(field(TAGS_METADATA_JOIN + ".task")));
Criterion gtaskJoinCriterion = Criterion gtaskJoinCriterion =
@ -118,9 +122,11 @@ public class TaskListViewModel extends ViewModel implements Observer<PagedList<T
// Eventually, we might consider restructuring things so that this query is constructed // Eventually, we might consider restructuring things so that this query is constructed
// elsewhere. // elsewhere.
String joinedQuery = String joinedQuery =
Join.left(Tag.TABLE.as(TAGS_METADATA_JOIN), tagsJoinCriterion).toString() // $NON-NLS-1$ Join.left(Tag.TABLE.as(TAGS_METADATA_JOIN), tagsJoinCriterion).toString()
+ Join.left(GoogleTask.TABLE.as(GTASK_METADATA_JOIN), gtaskJoinCriterion).toString() + Join.left(GoogleTask.TABLE.as(GTASK_METADATA_JOIN), gtaskJoinCriterion)
+ Join.left(CaldavTask.TABLE.as(CALDAV_METADATA_JOIN), caldavJoinCriterion).toString() + Join.left(CaldavTask.TABLE.as(CALDAV_METADATA_JOIN), caldavJoinCriterion)
+ Join.left(Geofence.TABLE, field(Geofence.TABLE_NAME + ".task").eq(Task.ID))
+ Join.left(Place.TABLE, field(Place.TABLE_NAME + ".uid").eq(field("geofences.place")))
+ filter.getSqlQuery(); + filter.getSqlQuery();
String query = String query =

@ -90,6 +90,27 @@
android:textColor="@color/text_secondary" android:textColor="@color/text_secondary"
android:visibility="gone"/> android:visibility="gone"/>
<com.google.android.material.chip.Chip
android:id="@+id/location_chip"
style="@style/ChipStyle"
android:layout_marginTop="@dimen/task_list_item_spacing"
android:layout_marginStart="@dimen/keyline_content_inset"
android:layout_marginEnd="@dimen/keyline_first"
android:layout_marginLeft="@dimen/keyline_content_inset"
android:layout_marginRight="@dimen/keyline_first"
android:layout_gravity="center_vertical|end"
android:textAlignment="center"
android:textColor="@color/text_secondary"
android:visibility="gone"
app:chipBackgroundColor="?attr/asContentBackground"
app:chipIcon="@drawable/ic_outline_place_24px"
app:chipIconTint="@color/icon_tint"
app:chipStrokeColor="@color/text_secondary"
app:chipStrokeWidth="@dimen/chip_stroke"
app:iconEndPadding="0dp"
app:iconStartPadding="@dimen/chip_text_padding"
/>
<com.google.android.material.chip.ChipGroup <com.google.android.material.chip.ChipGroup
android:id="@+id/chip_group" android:id="@+id/chip_group"
android:layout_width="match_parent" android:layout_width="match_parent"

Loading…
Cancel
Save