Add support for multiple google task accounts

pull/685/merge
Alex Baker 8 years ago
parent abfd6051f4
commit 07f9d72219

@ -0,0 +1,903 @@
{
"formatVersion": 1,
"database": {
"version": 59,
"identityHash": "1320507f7cf294e38cdd2d22d1ce4496",
"entities": [
{
"tableName": "notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `type` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "uid",
"columnName": "uid",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "taskId",
"columnName": "task",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"uid"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_notification_task",
"unique": true,
"columnNames": [
"task"
],
"createSql": "CREATE UNIQUE INDEX `index_notification_task` ON `${TABLE_NAME}` (`task`)"
}
],
"foreignKeys": []
},
{
"tableName": "tagdata",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remoteId` TEXT, `name` TEXT, `color` INTEGER, `tagOrdering` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remoteId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "color",
"columnName": "color",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "tagOrdering",
"columnName": "tagOrdering",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "userActivity",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remoteId` TEXT, `message` TEXT, `picture` TEXT, `target_id` TEXT, `created_at` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remoteId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "picture",
"columnName": "picture",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "targetId",
"columnName": "target_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "created",
"columnName": "created_at",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "task_attachments",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remoteId` TEXT, `task_id` TEXT, `name` TEXT, `path` TEXT, `content_type` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remoteId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "taskId",
"columnName": "task_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "path",
"columnName": "path",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "contentType",
"columnName": "content_type",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "task_list_metadata",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `remoteId` TEXT, `tag_uuid` TEXT, `filter` TEXT, `task_ids` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remoteId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "tagUuid",
"columnName": "tag_uuid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "filter",
"columnName": "filter",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "taskIds",
"columnName": "task_ids",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "tasks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `importance` INTEGER, `dueDate` INTEGER, `hideUntil` INTEGER, `created` INTEGER, `modified` INTEGER, `completed` INTEGER, `deleted` INTEGER, `notes` TEXT, `estimatedSeconds` INTEGER, `elapsedSeconds` INTEGER, `timerStart` INTEGER, `notificationFlags` INTEGER, `notifications` INTEGER, `lastNotified` INTEGER, `snoozeTime` INTEGER, `recurrence` TEXT, `repeatUntil` INTEGER, `calendarUri` TEXT, `remoteId` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "priority",
"columnName": "importance",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "dueDate",
"columnName": "dueDate",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "hideUntil",
"columnName": "hideUntil",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "created",
"columnName": "created",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "modified",
"columnName": "modified",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "completed",
"columnName": "completed",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "notes",
"columnName": "notes",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "estimatedSeconds",
"columnName": "estimatedSeconds",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "elapsedSeconds",
"columnName": "elapsedSeconds",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "timerStart",
"columnName": "timerStart",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "notificationFlags",
"columnName": "notificationFlags",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "notifications",
"columnName": "notifications",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "lastNotified",
"columnName": "lastNotified",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "snoozeTime",
"columnName": "snoozeTime",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "recurrence",
"columnName": "recurrence",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "repeatUntil",
"columnName": "repeatUntil",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "calendarUri",
"columnName": "calendarUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remoteId",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [
{
"name": "t_rid",
"unique": true,
"columnNames": [
"remoteId"
],
"createSql": "CREATE UNIQUE INDEX `t_rid` ON `${TABLE_NAME}` (`remoteId`)"
}
],
"foreignKeys": []
},
{
"tableName": "alarms",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `time` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "task",
"columnName": "task",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "time",
"columnName": "time",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "locations",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `name` TEXT, `latitude` REAL NOT NULL, `longitude` REAL NOT NULL, `radius` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "task",
"columnName": "task",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "latitude",
"columnName": "latitude",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "longitude",
"columnName": "longitude",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "radius",
"columnName": "radius",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "tags",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `name` TEXT, `tag_uid` TEXT, `task_uid` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "task",
"columnName": "task",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "tagUid",
"columnName": "tag_uid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "taskUid",
"columnName": "task_uid",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "google_tasks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `remote_id` TEXT, `list_id` TEXT, `parent` INTEGER NOT NULL, `indent` INTEGER NOT NULL, `order` INTEGER NOT NULL, `remote_order` INTEGER NOT NULL, `last_sync` INTEGER NOT NULL, `deleted` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "task",
"columnName": "task",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "remoteId",
"columnName": "remote_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "listId",
"columnName": "list_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "parent",
"columnName": "parent",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "indent",
"columnName": "indent",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "order",
"columnName": "order",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "remoteOrder",
"columnName": "remote_order",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastSync",
"columnName": "last_sync",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "filters",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `sql` TEXT, `values` TEXT, `criterion` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "sql",
"columnName": "sql",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "values",
"columnName": "values",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "criterion",
"columnName": "criterion",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "google_task_lists",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `account` TEXT, `remote_id` TEXT, `title` TEXT, `remote_order` INTEGER NOT NULL, `last_sync` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `color` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "account",
"columnName": "account",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remote_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "remoteOrder",
"columnName": "remote_order",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastSync",
"columnName": "last_sync",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "color",
"columnName": "color",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "caldav_calendar",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `account` TEXT, `uuid` TEXT, `name` TEXT, `color` INTEGER NOT NULL, `ctag` TEXT, `url` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "account",
"columnName": "account",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "uuid",
"columnName": "uuid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "color",
"columnName": "color",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "ctag",
"columnName": "ctag",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "caldav_tasks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task` INTEGER NOT NULL, `calendar` TEXT, `object` TEXT, `remote_id` TEXT, `etag` TEXT, `last_sync` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `vtodo` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "task",
"columnName": "task",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "calendar",
"columnName": "calendar",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "object",
"columnName": "object",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "remoteId",
"columnName": "remote_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "etag",
"columnName": "etag",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "lastSync",
"columnName": "last_sync",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "vtodo",
"columnName": "vtodo",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "caldav_account",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `uuid` TEXT, `name` TEXT, `url` TEXT, `username` TEXT, `password` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "uuid",
"columnName": "uuid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "google_task_accounts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `account` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "account",
"columnName": "account",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"1320507f7cf294e38cdd2d22d1ce4496\")"
]
}
}

@ -11,6 +11,7 @@ import org.tasks.data.GoogleTaskList;
public class GtaskListMaker {
public static final Property<GoogleTaskList, Long> ID = newProperty();
public static final Property<GoogleTaskList, String> ACCOUNT = newProperty();
public static final Property<GoogleTaskList, String> REMOTE_ID = newProperty();
public static final Property<GoogleTaskList, Long> LAST_SYNC = newProperty();
public static final Property<GoogleTaskList, String> NAME = newProperty();
@ -22,6 +23,7 @@ public class GtaskListMaker {
{
setDeleted(0L);
setId(lookup.valueOf(GtaskListMaker.ID, 0L));
setAccount(lookup.valueOf(ACCOUNT, "account"));
setRemoteId(lookup.valueOf(REMOTE_ID, "1"));
setTitle(lookup.valueOf(NAME, "Default"));
setRemoteOrder(lookup.valueOf(ORDER, 0));

@ -18,8 +18,10 @@ import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.data.GoogleTask;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskDao;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
@ -28,6 +30,7 @@ import org.tasks.injection.TestComponent;
public class GtasksIndentActionTest extends InjectingTestCase {
@Inject GtasksListService gtasksListService;
@Inject GoogleTaskListDao googleTaskListDao;
@Inject GtasksTaskListUpdater gtasksTaskListUpdater;
@Inject TaskDao taskDao;
@Inject GoogleTaskDao googleTaskDao;
@ -159,9 +162,11 @@ public class GtasksIndentActionTest extends InjectingTestCase {
list.setId("list");
list.setTitle("Test Tasks");
items.add(list);
gtasksListService.updateLists(items);
GoogleTaskAccount account = new GoogleTaskAccount("account");
googleTaskListDao.insert(account);
gtasksListService.updateLists(account, items);
storeList = gtasksListService.getLists().get(0);
storeList = googleTaskListDao.getActiveLists("account").get(0);
}
@Override
@ -199,4 +204,5 @@ public class GtasksIndentActionTest extends InjectingTestCase {
taskDao.createNew(task);
return task;
}
}

@ -22,6 +22,7 @@ import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.LocalBroadcastManager;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskDao;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
@ -87,7 +88,7 @@ public class GtasksListServiceTest extends InjectingTestCase {
assertEquals(
singletonList(newGtaskList(with(ID, 2L), with(REMOTE_ID, "2"))),
googleTaskListDao.getActiveLists());
googleTaskListDao.getActiveLists("account"));
}
@Test
@ -122,6 +123,8 @@ public class GtasksListServiceTest extends InjectingTestCase {
}
private void setLists(TaskList... list) {
gtasksListService.updateLists(asList(list));
GoogleTaskAccount account = new GoogleTaskAccount("account");
googleTaskListDao.insert(account);
gtasksListService.updateLists(account, asList(list));
}
}

@ -5,17 +5,12 @@
*/
package com.todoroo.astrid.gtasks;
import static android.support.test.InstrumentationRegistry.getTargetContext;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import android.content.Context;
import android.support.test.runner.AndroidJUnit4;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import dagger.Module;
import dagger.Provides;
import dagger.Subcomponent;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -23,7 +18,6 @@ import org.tasks.data.GoogleTask;
import org.tasks.data.GoogleTaskDao;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
import org.tasks.preferences.Preferences;
@SuppressWarnings("nls")
@RunWith(AndroidJUnit4.class)
@ -36,7 +30,7 @@ public class GtasksMetadataServiceTest extends InjectingTestCase {
@Override
protected void inject(TestComponent component) {
component.plus(new GtasksMetadataServiceTestModule(getTargetContext())).inject(this);
component.inject(this);
}
@Test
@ -94,30 +88,4 @@ public class GtasksMetadataServiceTest extends InjectingTestCase {
taskDao.createNew(task);
return task;
}
@Subcomponent(modules = GtasksMetadataServiceTest.GtasksMetadataServiceTestModule.class)
public interface GtasksMetadataServiceTestComponent {
void inject(GtasksMetadataServiceTest gtasksMetadataServiceTest);
}
@Module
public class GtasksMetadataServiceTestModule {
private final GtasksTestPreferenceService service;
public GtasksMetadataServiceTestModule(Context context) {
service = new GtasksTestPreferenceService(new Preferences(context, null));
}
@Provides
public GtasksTestPreferenceService getGtasksTestPreferenceService() {
return service;
}
@Provides
public GtasksPreferenceService getGtasksPreferenceService() {
return service;
}
}
}

@ -19,8 +19,10 @@ import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.data.GoogleTask;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskDao;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
@ -34,6 +36,7 @@ public class GtasksTaskListUpdaterTest extends InjectingTestCase {
@Inject GtasksListService gtasksListService;
@Inject TaskDao taskDao;
@Inject GoogleTaskDao googleTaskDao;
@Inject GoogleTaskListDao googleTaskListDao;
@Test
public void testBasicParentComputation() {
@ -149,7 +152,9 @@ public class GtasksTaskListUpdaterTest extends InjectingTestCase {
list.setId("1");
list.setTitle("Tim's Tasks");
items.add(list);
gtasksListService.updateLists(items);
GoogleTaskAccount account = new GoogleTaskAccount("account");
googleTaskListDao.insert(account);
gtasksListService.updateLists(account, items);
}
@Override
@ -162,7 +167,7 @@ public class GtasksTaskListUpdaterTest extends InjectingTestCase {
}
private void createParentSiblingMaps() {
for (GoogleTaskList list : gtasksListService.getLists()) {
for (GoogleTaskList list : googleTaskListDao.getActiveLists("account")) {
gtasksTaskListUpdater.updateParentSiblingMapsFor(list);
}
}

@ -18,8 +18,10 @@ import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.data.GoogleTask;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskDao;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
@ -33,6 +35,7 @@ public class GtasksTaskMovingTest extends InjectingTestCase {
@Inject GtasksTaskListUpdater gtasksTaskListUpdater;
@Inject TaskDao taskDao;
@Inject GoogleTaskDao googleTaskDao;
@Inject GoogleTaskListDao googleTaskListDao;
private Task A, B, C, D, E, F;
private GoogleTaskList list;
@ -265,9 +268,11 @@ public class GtasksTaskMovingTest extends InjectingTestCase {
taskList.setId("1");
taskList.setTitle("Tim's Tasks");
items.add(taskList);
gtasksListService.updateLists(items);
GoogleTaskAccount account = new GoogleTaskAccount("account");
googleTaskListDao.insert(account);
gtasksListService.updateLists(account, items);
list = gtasksListService.getLists().get(0);
list = googleTaskListDao.getActiveLists("account").get(0);
}
@Override

@ -1,20 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.gtasks;
import org.tasks.preferences.Preferences;
public class GtasksTestPreferenceService extends GtasksPreferenceService {
public GtasksTestPreferenceService(Preferences preferences) {
super(preferences);
}
@Override
public long getLastSyncDate() {
return 0L;
}
}

@ -22,9 +22,6 @@ import org.tasks.jobs.BackupServiceTests;
@Component(modules = TestModule.class)
public interface TestComponent {
GtasksMetadataServiceTest.GtasksMetadataServiceTestComponent plus(
GtasksMetadataServiceTest.GtasksMetadataServiceTestModule gtasksMetadataServiceTestModule);
void inject(GtasksIndentActionTest gtasksIndentActionTest);
void inject(GtasksTaskMovingTest gtasksTaskMovingTest);
@ -54,4 +51,6 @@ public interface TestComponent {
void inject(AlarmJobServiceTest alarmServiceTest);
void inject(RepeatTaskHelperTest repeatTaskHelperTest);
void inject(GtasksMetadataServiceTest gtasksMetadataServiceTest);
}

@ -41,7 +41,6 @@ import com.todoroo.astrid.api.CustomFilter;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.core.BuiltInFilterExposer;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.GtasksSubtaskListFragment;
import com.todoroo.astrid.service.TaskCreator;
import com.todoroo.astrid.service.TaskDeleter;
@ -95,7 +94,6 @@ public class TaskListFragment extends InjectingFragment
@Inject TaskDeleter taskDeleter;
@Inject @ForActivity Context context;
@Inject Preferences preferences;
@Inject GtasksPreferenceService gtasksPreferenceService;
@Inject DialogBuilder dialogBuilder;
@Inject CheckBoxes checkBoxes;
@Inject TaskCreator taskCreator;
@ -414,7 +412,7 @@ public class TaskListFragment extends InjectingFragment
// TODO: compare indents in diff callback, then animate this
loadTaskListContent(!(this instanceof GtasksSubtaskListFragment));
setSyncOngoing(gtasksPreferenceService.isOngoing());
setSyncOngoing(preferences.isSyncOngoing());
}
/*

@ -20,7 +20,6 @@ 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.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -28,11 +27,9 @@ import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.common.base.Strings;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.core.CustomFilterActivity;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
@ -43,6 +40,7 @@ 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;
@ -50,7 +48,6 @@ import org.tasks.filters.NavigationDrawerSeparator;
import org.tasks.filters.NavigationDrawerSubheader;
import org.tasks.locale.Locale;
import org.tasks.preferences.BasicPreferences;
import org.tasks.preferences.Preferences;
import org.tasks.themes.Theme;
import org.tasks.themes.ThemeCache;
import org.tasks.ui.NavigationDrawerFragment;
@ -68,7 +65,6 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
private final Theme theme;
private final Locale locale;
private final Inventory inventory;
private final Preferences preferences;
private final FilterListUpdateReceiver filterListUpdateReceiver = new FilterListUpdateReceiver();
private final List<FilterListItem> items = new ArrayList<>();
private final LayoutInflater inflater;
@ -84,8 +80,7 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
Theme theme,
ThemeCache themeCache,
Locale locale,
Inventory inventory,
Preferences preferences) {
Inventory inventory) {
super(activity, 0);
this.filterProvider = filterProvider;
this.filterCounter = filterCounter;
@ -93,7 +88,6 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
this.theme = theme;
this.locale = locale;
this.inventory = inventory;
this.preferences = preferences;
this.inflater = theme.getLayoutInflater(activity);
this.themeCache = themeCache;
}
@ -230,8 +224,7 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
return getView(position, convertView, parent);
}
private void addSubMenu(
final int titleResource, List<Filter> filters, boolean hideIfEmpty) {
private void addSubMenu(final int titleResource, List<Filter> filters, boolean hideIfEmpty) {
addSubMenu(activity.getResources().getString(titleResource), filters, hideIfEmpty);
}
@ -264,19 +257,12 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
item.icon = R.drawable.ic_cloud_off_black_24dp;
add(item);
String googleTaskTitle = preferences.getStringValue(GtasksPreferenceService.PREF_USER_NAME);
if (Strings.isNullOrEmpty(googleTaskTitle)) {
googleTaskTitle = activity.getResources().getString(R.string.gtasks_GPr_header);
for (Pair<GoogleTaskAccount, List<Filter>> filters : filterProvider.getGoogleTaskFilters()) {
addSubMenu(filters.first.getAccount(), filters.second, true);
}
addSubMenu(googleTaskTitle, filterProvider.getGoogleTaskFilters(), true);
for (Pair<CaldavAccount, List<Filter>> filters : filterProvider.getCaldavFilters()) {
CaldavAccount account = filters.first;
String caldavTitle = account.getName();
if (TextUtils.isEmpty(caldavTitle)) {
caldavTitle = activity.getString(R.string.CalDAV);
}
addSubMenu(caldavTitle, filters.second, true);
addSubMenu(filters.first.getName(), filters.second, true);
}
notifyDataSetChanged();
@ -309,31 +295,24 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
NavigationDrawerFragment.REQUEST_NEW_LIST));
}
List<Filter> googleTaskFilters = filterProvider.getGoogleTaskFilters();
if (!googleTaskFilters.isEmpty()) {
String title = preferences.getStringValue(GtasksPreferenceService.PREF_USER_NAME);
if (Strings.isNullOrEmpty(title)) {
title = activity.getResources().getString(R.string.gtasks_GPr_header);
}
addSubMenu(title, googleTaskFilters, true);
for (Pair<GoogleTaskAccount, List<Filter>> filters : filterProvider.getGoogleTaskFilters()) {
GoogleTaskAccount account = filters.first;
addSubMenu(account.getAccount(), 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),
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;
String title = account.getName();
if (TextUtils.isEmpty(title)) {
title = activity.getString(R.string.CalDAV);
}
addSubMenu(title, filters.second, !navigationDrawer);
addSubMenu(account.getName(), filters.second, !navigationDrawer);
if (navigationDrawer) {
add(

@ -21,6 +21,7 @@ import org.tasks.data.CaldavTask;
import org.tasks.data.Filter;
import org.tasks.data.FilterDao;
import org.tasks.data.GoogleTask;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskDao;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
@ -56,9 +57,10 @@ import timber.log.Timber;
GoogleTaskList.class,
CaldavCalendar.class,
CaldavTask.class,
CaldavAccount.class
CaldavAccount.class,
GoogleTaskAccount.class
},
version = 58
version = 59
)
public abstract class Database extends RoomDatabase {

@ -6,13 +6,18 @@
package com.todoroo.astrid.gtasks;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.transform;
import static java.util.Collections.emptyList;
import android.support.v4.util.Pair;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.GtasksFilter;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.sync.SyncAdapters;
/**
@ -24,22 +29,20 @@ public class GtasksFilterExposer {
private final GtasksListService gtasksListService;
private final SyncAdapters syncAdapters;
private final GoogleTaskListDao googleTaskListDao;
@Inject
public GtasksFilterExposer(GtasksListService gtasksListService, SyncAdapters syncAdapters) {
public GtasksFilterExposer(GtasksListService gtasksListService, SyncAdapters syncAdapters, GoogleTaskListDao googleTaskListDao) {
this.gtasksListService = gtasksListService;
this.syncAdapters = syncAdapters;
this.googleTaskListDao = googleTaskListDao;
}
public List<Filter> getFilters() {
// if we aren't logged in (or we are logged in to astrid.com), don't expose features
if (!syncAdapters.isGoogleTaskSyncEnabled()) {
return emptyList();
}
List<Filter> listFilters = newArrayList();
for (GoogleTaskList list : gtasksListService.getLists()) {
listFilters.add(filterFromList(list));
public List<Pair<GoogleTaskAccount, List<Filter>>> getFilters() {
List<Pair<GoogleTaskAccount, List<Filter>>> listFilters = newArrayList();
for (GoogleTaskAccount account : googleTaskListDao.getAccounts()) {
List<GoogleTaskList> lists = googleTaskListDao.getActiveLists(account.getAccount());
listFilters.add(new Pair<>(account, transform(lists, GtasksFilter::new)));
}
return listFilters;
}

@ -17,6 +17,7 @@ import java.util.List;
import java.util.Set;
import javax.inject.Inject;
import org.tasks.LocalBroadcastManager;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskDao;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
@ -44,10 +45,6 @@ public class GtasksListService {
this.taskDao = taskDao;
}
public List<GoogleTaskList> getLists() {
return googleTaskListDao.getActiveLists();
}
public GoogleTaskList getList(long id) {
return googleTaskListDao.getById(id);
}
@ -57,8 +54,8 @@ public class GtasksListService {
*
* @param remoteLists remote information about your lists
*/
public synchronized void updateLists(List<TaskList> remoteLists) {
List<GoogleTaskList> lists = getLists();
public synchronized void updateLists(GoogleTaskAccount account, List<TaskList> remoteLists) {
List<GoogleTaskList> lists = googleTaskListDao.getActiveLists(account.getAccount());
Set<Long> previousLists = new HashSet<>();
for (GoogleTaskList list : lists) {
@ -79,9 +76,16 @@ public class GtasksListService {
String title = remote.getTitle();
if (local == null) {
Timber.d("Adding new gtask list %s", title);
local = new GoogleTaskList();
local.setRemoteId(id);
GoogleTaskList byRemoteId = googleTaskListDao.findExistingList(id);
if (byRemoteId != null) {
byRemoteId.setAccount(account.getAccount());
local = byRemoteId;
} else {
Timber.d("Adding new gtask list %s", title);
local = new GoogleTaskList();
local.setAccount(account.getAccount());
local.setRemoteId(id);
}
}
local.setTitle(title);
@ -126,11 +130,6 @@ public class GtasksListService {
}
public GoogleTaskList getList(String listId) {
for (GoogleTaskList list : getLists()) {
if (list != null && list.getRemoteId().equals(listId)) {
return list;
}
}
return null;
return googleTaskListDao.getByRemoteId(listId);
}
}

@ -1,55 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* <p>See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.gtasks;
import com.todoroo.andlib.utility.DateUtilities;
import javax.inject.Inject;
import org.tasks.preferences.Preferences;
/**
* Methods for working with GTasks preferences
*
* @author timsu
*/
public class GtasksPreferenceService {
private static final String IDENTIFIER = "gtasks"; // $NON-NLS-1$
public static final String PREF_USER_NAME = IDENTIFIER + "_user"; // $NON-NLS-1$
private static final String PREF_LAST_SYNC = "_last_sync"; // $NON-NLS-1$
private final Preferences preferences;
@Inject
public GtasksPreferenceService(Preferences preferences) {
this.preferences = preferences;
}
public String getUserName() {
return preferences.getStringValue(PREF_USER_NAME);
}
public void setUserName(String userName) {
preferences.setString(PREF_USER_NAME, userName);
}
/** @return Last Successful Sync Date, or 0 */
public long getLastSyncDate() {
return preferences.getLong(IDENTIFIER + PREF_LAST_SYNC, 0);
}
/** Deletes Last Successful Sync Date */
public void clearLastSyncDate() {
preferences.clear(IDENTIFIER + PREF_LAST_SYNC);
}
/** Set Last Successful Sync Date */
public void recordSuccessfulSync() {
preferences.setLong(IDENTIFIER + PREF_LAST_SYNC, DateUtilities.now() + 1000);
}
public boolean isOngoing() {
return preferences.isSyncOngoing();
}
}

@ -58,8 +58,8 @@ public class GtasksTaskListUpdater {
gtasksSyncService.iterateThroughList(listId, iterator, 0, false);
}
private void onMovedOrIndented(GoogleTask googleTask) {
gtasksSyncService.triggerMoveForMetadata(googleTask);
private void onMovedOrIndented(GoogleTaskList googleTaskList, GoogleTask googleTask) {
gtasksSyncService.triggerMoveForMetadata(googleTaskList, googleTask);
}
// --- used during synchronization
@ -176,7 +176,7 @@ public class GtasksTaskListUpdater {
saveAndUpdateModifiedDate(googleTask);
});
onMovedOrIndented(getTaskMetadata(targetTaskId));
onMovedOrIndented(list, getTaskMetadata(targetTaskId));
}
/**
@ -242,7 +242,7 @@ public class GtasksTaskListUpdater {
}
traverseTreeAndWriteValues(list, root, new AtomicLong(0), -1);
onMovedOrIndented(getTaskMetadata(targetTaskId));
onMovedOrIndented(list, getTaskMetadata(targetTaskId));
}
// --- task moving
@ -273,7 +273,7 @@ public class GtasksTaskListUpdater {
}
saveAndUpdateModifiedDate(googleTask);
if (parentChanged) {
onMovedOrIndented(googleTask);
onMovedOrIndented(list, googleTask);
}
}

@ -13,15 +13,12 @@ import com.google.api.services.tasks.TasksScopes;
import com.google.api.services.tasks.model.Task;
import com.google.api.services.tasks.model.TaskList;
import com.google.api.services.tasks.model.TaskLists;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import java.io.IOException;
import java.util.Collections;
import javax.inject.Inject;
import org.tasks.BuildConfig;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.gtasks.GoogleTasksUnsuccessfulResponseHandler;
import org.tasks.gtasks.PlayServices;
import org.tasks.injection.ApplicationScope;
import org.tasks.injection.ForApplication;
import timber.log.Timber;
/**
@ -30,32 +27,23 @@ import timber.log.Timber;
*
* @author Sam Bosley
*/
@ApplicationScope
public class GtasksInvoker {
private final GoogleAccountCredential credential;
private final PlayServices playServices;
private final Tasks service;
@Inject
public GtasksInvoker(
@ForApplication Context context,
GtasksPreferenceService preferenceService,
PlayServices playServices) {
credential =
GoogleAccountCredential.usingOAuth2(context, Collections.singletonList(TasksScopes.TASKS));
public GtasksInvoker(Context context, PlayServices playServices, String account) {
this.playServices = playServices;
setUserName(preferenceService.getUserName());
credential =
GoogleAccountCredential.usingOAuth2(context, Collections.singletonList(TasksScopes.TASKS))
.setSelectedAccountName(account);
service =
new Tasks.Builder(new NetHttpTransport(), new JacksonFactory(), credential)
.setApplicationName(String.format("Tasks/%s", BuildConfig.VERSION_NAME))
.build();
}
public void setUserName(String username) {
credential.setSelectedAccountName(username);
}
public TaskLists allGtaskLists(String pageToken) throws IOException {
return execute(service.tasklists().list().setPageToken(pageToken));
}

@ -10,10 +10,10 @@ import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.gtasks.PlayServices;
@ -30,26 +30,20 @@ public class GtasksLoginActivity extends InjectingAppCompatActivity {
public static final int RC_REQUEST_OAUTH = 10987;
private static final int RC_CHOOSE_ACCOUNT = 10988;
@Inject GtasksPreferenceService gtasksPreferenceService;
@Inject DialogBuilder dialogBuilder;
@Inject GoogleAccountManager accountManager;
@Inject GtasksInvoker gtasksInvoker;
@Inject PlayServices playServices;
@Inject GoogleTaskListDao googleTaskListDao;
private String accountName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final String existingUsername = gtasksPreferenceService.getUserName();
if (existingUsername != null && accountManager.hasAccount(existingUsername)) {
getAuthToken(existingUsername);
} else {
Intent chooseAccountIntent =
android.accounts.AccountManager.newChooseAccountIntent(
null, null, new String[] {"com.google"}, false, null, null, null, null);
startActivityForResult(chooseAccountIntent, RC_CHOOSE_ACCOUNT);
}
Intent chooseAccountIntent =
android.accounts.AccountManager.newChooseAccountIntent(
null, null, new String[] {"com.google"}, false, null, null, null, null);
startActivityForResult(chooseAccountIntent, RC_CHOOSE_ACCOUNT);
}
@Override
@ -71,9 +65,12 @@ public class GtasksLoginActivity extends InjectingAppCompatActivity {
new AuthResultHandler() {
@Override
public void authenticationSuccessful(String accountName) {
gtasksPreferenceService.setUserName(accountName);
gtasksInvoker.setUserName(accountName);
setResult(RESULT_OK);
if (googleTaskListDao.getAccount(accountName) == null) {
GoogleTaskAccount googleTaskAccount = new GoogleTaskAccount();
googleTaskAccount.setAccount(accountName);
googleTaskListDao.insert(googleTaskAccount);
setResult(RESULT_OK);
}
finish();
DialogUtilities.dismissDialog(GtasksLoginActivity.this, pd);
}

@ -5,12 +5,12 @@
*/
package com.todoroo.astrid.gtasks.sync;
import android.content.Context;
import android.text.TextUtils;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.GtasksTaskListUpdater;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import com.todoroo.astrid.gtasks.api.MoveRequest;
@ -24,44 +24,53 @@ import javax.inject.Inject;
import org.tasks.analytics.Tracker;
import org.tasks.data.GoogleTask;
import org.tasks.data.GoogleTaskDao;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.gtasks.GtaskSyncAdapterHelper;
import org.tasks.gtasks.PlayServices;
import org.tasks.injection.ApplicationScope;
import org.tasks.injection.ForApplication;
import org.tasks.preferences.Preferences;
import timber.log.Timber;
@ApplicationScope
public class GtasksSyncService {
private final Context context;
private final TaskDao taskDao;
private final GtasksPreferenceService gtasksPreferenceService;
private final GtasksInvoker gtasksInvoker;
private final Preferences preferences;
private final LinkedBlockingQueue<SyncOnSaveOperation> operationQueue =
new LinkedBlockingQueue<>();
private final GtaskSyncAdapterHelper gtaskSyncAdapterHelper;
private final Tracker tracker;
private final GoogleTaskDao googleTaskDao;
private final PlayServices playServices;
@Inject
public GtasksSyncService(
@ForApplication Context context,
TaskDao taskDao,
GtasksPreferenceService gtasksPreferenceService,
GtasksInvoker gtasksInvoker,
Preferences preferences,
GtaskSyncAdapterHelper gtaskSyncAdapterHelper,
Tracker tracker,
GoogleTaskDao googleTaskDao) {
GoogleTaskDao googleTaskDao,
GoogleTaskListDao googleTaskListDao,
PlayServices playServices) {
this.context = context;
this.taskDao = taskDao;
this.gtasksPreferenceService = gtasksPreferenceService;
this.gtasksInvoker = gtasksInvoker;
this.preferences = preferences;
this.gtaskSyncAdapterHelper = gtaskSyncAdapterHelper;
this.tracker = tracker;
this.googleTaskDao = googleTaskDao;
this.playServices = playServices;
new OperationPushThread(operationQueue).start();
}
public void clearCompleted(String listId) {
operationQueue.offer(new ClearOp(listId));
public void clearCompleted(GoogleTaskList googleTaskList) {
operationQueue.offer(new ClearOp(googleTaskList));
}
public void triggerMoveForMetadata(final GoogleTask googleTask) {
public void triggerMoveForMetadata(GoogleTaskList googleTaskList, GoogleTask googleTask) {
if (googleTask == null) {
return;
}
@ -69,16 +78,14 @@ public class GtasksSyncService {
googleTask.setSuppressSync(false);
return;
}
if (gtasksPreferenceService
.isOngoing()) // Don't try and sync changes that occur during a normal sync
{
if (preferences.isSyncOngoing()) {
return;
}
if (!gtaskSyncAdapterHelper.isEnabled()) {
return;
}
operationQueue.offer(new MoveOp(googleTask));
operationQueue.offer(new MoveOp(googleTaskList, googleTask));
}
private void pushMetadataOnSave(GoogleTask model, GtasksInvoker invoker) throws IOException {
@ -154,34 +161,38 @@ public class GtasksSyncService {
interface SyncOnSaveOperation {
void op(GtasksInvoker invoker) throws IOException;
void op() throws IOException;
}
private class MoveOp implements SyncOnSaveOperation {
private final GoogleTaskList googleTaskList;
final GoogleTask googleTask;
MoveOp(GoogleTask googleTask) {
MoveOp(GoogleTaskList googleTaskList, GoogleTask googleTask) {
this.googleTaskList = googleTaskList;
this.googleTask = googleTask;
}
@Override
public void op(GtasksInvoker invoker) throws IOException {
public void op() throws IOException {
GtasksInvoker invoker = new GtasksInvoker(context, playServices, googleTaskList.getAccount());
pushMetadataOnSave(googleTask, invoker);
}
}
private class ClearOp implements SyncOnSaveOperation {
private final String listId;
private GoogleTaskList googleTaskList;
ClearOp(String listId) {
this.listId = listId;
ClearOp(GoogleTaskList googleTaskList) {
this.googleTaskList = googleTaskList;
}
@Override
public void op(GtasksInvoker invoker) throws IOException {
invoker.clearCompleted(listId);
public void op() throws IOException {
GtasksInvoker invoker = new GtasksInvoker(context, playServices, googleTaskList.getAccount());
invoker.clearCompleted(googleTaskList.getRemoteId());
}
}
@ -205,7 +216,7 @@ public class GtasksSyncService {
continue;
}
try {
op.op(gtasksInvoker);
op.op();
} catch (UserRecoverableAuthIOException ignored) {
} catch (IOException e) {

@ -5,10 +5,11 @@
*/
package com.todoroo.astrid.service;
import static com.google.common.base.Strings.isNullOrEmpty;
import android.content.Context;
import android.database.sqlite.SQLiteException;
import android.os.Environment;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
@ -26,6 +27,7 @@ import org.tasks.analytics.Tracker;
import org.tasks.analytics.Tracking;
import org.tasks.data.Filter;
import org.tasks.data.FilterDao;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.data.Tag;
@ -43,7 +45,8 @@ public class StartupService {
private static final int V4_8_0 = 380;
private static final int V4_9_5 = 434;
private static final int V5_3_0 = 491;
private static final int V5_3_1 = 501;
private static final int V6_0_beta_1 = 522;
private static final int V6_0_beta_2 = 523;
private final Database database;
private final Preferences preferences;
@ -119,9 +122,12 @@ public class StartupService {
if (from < V5_3_0) {
migrateFilters();
}
if (from < V5_3_1) {
if (from < V6_0_beta_1) {
migrateDefaultSyncList();
}
if (from < V6_0_beta_2) {
migrateGoogleTaskAccount();
}
tracker.reportEvent(Tracking.Events.UPGRADE, Integer.toString(from));
}
preferences.setCurrentVersion(to);
@ -166,8 +172,15 @@ public class StartupService {
}
private void migrateDefaultSyncList() {
String account = preferences.getStringValue("gtasks_user");
if (isNullOrEmpty(account)) {
return;
}
String defaultGoogleTaskList = preferences.getStringValue("gtasks_defaultlist");
if (!Strings.isNullOrEmpty(defaultGoogleTaskList)) {
if (isNullOrEmpty(defaultGoogleTaskList)) {
// TODO: look up default list
} else {
GoogleTaskList googleTaskList = googleTaskListDao.getByRemoteId(defaultGoogleTaskList);
if (googleTaskList != null) {
defaultFilterProvider.setDefaultRemoteList(new GtasksFilter(googleTaskList));
@ -175,6 +188,15 @@ public class StartupService {
}
}
private void migrateGoogleTaskAccount() {
String account = preferences.getStringValue("gtasks_user");
if (!isNullOrEmpty(account)) {
GoogleTaskAccount googleTaskAccount = new GoogleTaskAccount();
googleTaskAccount.setAccount(account);
googleTaskListDao.insert(googleTaskAccount);
}
}
private String migrate(String input) {
return input
.replaceAll(

@ -46,7 +46,7 @@ public class SyncV2Service {
() -> {
callback.started();
try {
gtasksSyncService.clearCompleted(list.getRemoteId());
gtasksSyncService.clearCompleted(list);
} finally {
callback.finished();
}

@ -1,7 +1,6 @@
package org.tasks;
import com.jakewharton.threetenabp.AndroidThreeTen;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.service.StartupService;
import javax.inject.Inject;
import org.tasks.analytics.Tracker;
@ -24,7 +23,6 @@ public class Tasks extends InjectingApplication {
@Inject Badger badger;
@Inject JobManager jobManager;
@Inject JobCreator jobCreator;
@Inject GtasksPreferenceService gtasksPreferenceService;
@Override
public void onCreate() {

@ -27,6 +27,7 @@ import javax.inject.Inject;
import org.tasks.R;
import org.tasks.analytics.Tracker;
import org.tasks.analytics.Tracking;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.dialogs.DialogBuilder;
@ -46,6 +47,7 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
DeleteListDialog.DeleteListDialogCallback,
RenameListDialog.RenameListDialogCallback {
public static final String EXTRA_ACCOUNT = "extra_account";
public static final String EXTRA_STORE_DATA = "extra_store_data";
public static final String ACTION_DELETED = "action_deleted";
public static final String ACTION_RELOAD = "action_reload";
@ -82,10 +84,13 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
setContentView(R.layout.activity_google_task_list_settings);
ButterKnife.bind(this);
gtasksList = getIntent().getParcelableExtra(EXTRA_STORE_DATA);
Intent intent = getIntent();
gtasksList = intent.getParcelableExtra(EXTRA_STORE_DATA);
if (gtasksList == null) {
isNewList = true;
gtasksList = new GoogleTaskList();
GoogleTaskAccount account = intent.getParcelableExtra(EXTRA_ACCOUNT);
gtasksList.setAccount(account.getAccount());
}
if (savedInstanceState == null) {
@ -165,9 +170,9 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
}
if (isNewList) {
newCreateListDialog(newName).show(getSupportFragmentManager(), FRAG_TAG_CREATE_LIST_DIALOG);
newCreateListDialog(gtasksList.getAccount(), newName).show(getSupportFragmentManager(), FRAG_TAG_CREATE_LIST_DIALOG);
} else if (nameChanged()) {
newRenameListDialog(gtasksList.getRemoteId(), newName)
newRenameListDialog(gtasksList, newName)
.show(getSupportFragmentManager(), FRAG_TAG_RENAME_LIST_DIALOG);
} else {
if (colorChanged()) {
@ -204,7 +209,7 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
.setPositiveButton(
R.string.delete,
(dialog, which) ->
newDeleteListDialog(gtasksList.getRemoteId())
newDeleteListDialog(gtasksList)
.show(getSupportFragmentManager(), FRAG_TAG_DELETE_LIST_DIALOG))
.setNegativeButton(android.R.string.cancel, null)
.show();

@ -16,7 +16,6 @@ public class Tracking {
TIMER_START(R.string.tracking_category_timer, R.string.tracking_action_start),
GTASK_ENABLED(R.string.tracking_category_google_tasks, R.string.tracking_action_on),
GTASK_DISABLED(R.string.tracking_category_google_tasks, R.string.tracking_action_off),
GTASK_LOGOUT(R.string.tracking_category_google_tasks, R.string.tracking_action_clear),
GTASK_NEW_LIST(R.string.tracking_category_google_tasks, R.string.tracking_action_new_list),
GTASK_RENAME_LIST(
R.string.tracking_category_google_tasks, R.string.tracking_action_rename_list),

@ -7,6 +7,7 @@ import static at.bitfire.dav4android.XmlUtils.NS_WEBDAV;
import static java.util.Arrays.asList;
import at.bitfire.dav4android.BasicDigestAuthHandler;
import at.bitfire.dav4android.DavCalendar;
import at.bitfire.dav4android.DavResource;
import at.bitfire.dav4android.PropertyCollection;
import at.bitfire.dav4android.XmlUtils;
@ -158,18 +159,13 @@ class CaldavClient {
Timber.d("%s does not support tasks", member);
continue;
}
Timber.d("Found %s", member);
urls.add(member);
}
if (urls.isEmpty()) {
throw new DisplayableException(R.string.caldav_no_supported_calendars);
}
return urls;
}
public Completable deleteCollection() {
return Completable.fromAction(() ->
davResource.delete(null))
return Completable.fromAction(() -> davResource.delete(null))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}

@ -0,0 +1,100 @@
package org.tasks.data;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.Ignore;
import android.arch.persistence.room.PrimaryKey;
import android.os.Parcel;
import android.os.Parcelable;
@Entity(tableName = "google_task_accounts")
public class GoogleTaskAccount implements Parcelable {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "_id")
private transient long id;
@ColumnInfo(name = "account")
private String account;
public GoogleTaskAccount() {}
@Ignore
public GoogleTaskAccount(Parcel source) {
id = source.readLong();
account = source.readString();
}
@Ignore
public GoogleTaskAccount(String account) {
this.account = account;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof GoogleTaskAccount)) {
return false;
}
GoogleTaskAccount that = (GoogleTaskAccount) o;
if (id != that.id) {
return false;
}
return account != null ? account.equals(that.account) : that.account == null;
}
@Override
public int hashCode() {
int result = (int) (id ^ (id >>> 32));
result = 31 * result + (account != null ? account.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "GoogleTaskAccount{" + "id=" + id + ", account='" + account + '\'' + '}';
}
public static final Creator<GoogleTaskAccount> CREATOR =
new Creator<GoogleTaskAccount>() {
@Override
public GoogleTaskAccount createFromParcel(Parcel source) {
return new GoogleTaskAccount(source);
}
@Override
public GoogleTaskAccount[] newArray(int size) {
return new GoogleTaskAccount[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(id);
dest.writeString(account);
}
}

@ -49,9 +49,6 @@ public interface GoogleTaskDao {
@Query("SELECT * FROM google_tasks WHERE task = :taskId")
List<GoogleTask> getAllByTaskId(long taskId);
@Query("DELETE FROM google_tasks")
void deleteAll();
@Query("SELECT DISTINCT list_id FROM google_tasks WHERE deleted = 0 AND task IN (:tasks)")
List<String> getLists(List<Long> tasks);
}

@ -27,6 +27,9 @@ public class GoogleTaskList implements Parcelable {
@ColumnInfo(name = "_id")
private transient long id;
@ColumnInfo(name = "account")
private String account;
@ColumnInfo(name = "remote_id")
private String remoteId;
@ -50,6 +53,7 @@ public class GoogleTaskList implements Parcelable {
@Ignore
public GoogleTaskList(Parcel parcel) {
id = parcel.readLong();
account = parcel.readString();
remoteId = parcel.readString();
title = parcel.readString();
remoteOrder = parcel.readInt();
@ -66,6 +70,14 @@ public class GoogleTaskList implements Parcelable {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getRemoteId() {
return remoteId;
}
@ -137,6 +149,9 @@ public class GoogleTaskList implements Parcelable {
if (deleted != that.deleted) {
return false;
}
if (account != null ? !account.equals(that.account) : that.account != null) {
return false;
}
if (remoteId != null ? !remoteId.equals(that.remoteId) : that.remoteId != null) {
return false;
}
@ -149,6 +164,7 @@ public class GoogleTaskList implements Parcelable {
@Override
public int hashCode() {
int result = (int) (id ^ (id >>> 32));
result = 31 * result + (account != null ? account.hashCode() : 0);
result = 31 * result + (remoteId != null ? remoteId.hashCode() : 0);
result = 31 * result + (title != null ? title.hashCode() : 0);
result = 31 * result + remoteOrder;
@ -163,6 +179,9 @@ public class GoogleTaskList implements Parcelable {
return "GoogleTaskList{"
+ "id="
+ id
+ ", account='"
+ account
+ '\''
+ ", remoteId='"
+ remoteId
+ '\''
@ -188,6 +207,7 @@ public class GoogleTaskList implements Parcelable {
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeLong(id);
parcel.writeString(account);
parcel.writeString(remoteId);
parcel.writeString(title);
parcel.writeInt(remoteOrder);

@ -4,29 +4,48 @@ import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query;
import android.arch.persistence.room.Update;
import java.util.List;
@Dao
public interface GoogleTaskListDao {
@Query("SELECT * FROM google_task_accounts")
List<GoogleTaskAccount> getAccounts();
@Query("SELECT * FROM google_task_accounts WHERE account = :account COLLATE NOCASE LIMIT 1")
GoogleTaskAccount getAccount(String account);
@Query("SELECT * FROM google_task_lists WHERE _id = :id")
GoogleTaskList getById(long id);
@Query("SELECT * FROM google_task_lists WHERE deleted = 0 ORDER BY title ASC")
List<GoogleTaskList> getActiveLists();
@Query("SELECT * FROM google_task_lists WHERE account = :account AND deleted = 0 ORDER BY title ASC")
List<GoogleTaskList> getActiveLists(String account);
@Query("SELECT * FROM google_task_lists WHERE remote_id = :remoteId LIMIT 1")
GoogleTaskList getByRemoteId(String remoteId);
@Query("SELECT * FROM google_task_lists WHERE remote_id = :remoteId AND IFNULL(account, '') = '' LIMIT 1")
GoogleTaskList findExistingList(String remoteId);
@Query("SELECT * FROM google_task_lists")
List<GoogleTaskList> getAll();
@Query("SELECT * FROM google_task_lists WHERE deleted = 0")
List<GoogleTaskList> getAllActiveLists();
@Insert(onConflict = OnConflictStrategy.REPLACE)
long insertOrReplace(GoogleTaskList googleTaskList);
@Insert
void insert(GoogleTaskList googleTaskList);
@Insert
void insert(GoogleTaskAccount googleTaskAccount);
@Update
void update(GoogleTaskList googleTaskList);
@Query("DELETE FROM google_task_lists WHERE _id = :id")
void deleteById(long id);
}

@ -192,6 +192,17 @@ public class Migrations {
}
};
private static final Migration MIGRATION_58_59 =
new Migration(58, 59) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL(
"CREATE TABLE IF NOT EXISTS `google_task_accounts` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `account` TEXT)");
database.execSQL(
"ALTER TABLE `google_task_lists` ADD COLUMN `account` TEXT");
}
};
public static final Migration[] MIGRATIONS =
new Migration[] {
MIGRATION_35_36,
@ -207,7 +218,8 @@ public class Migrations {
MIGRATION_51_52,
MIGRATION_52_53,
MIGRATION_53_54,
MIGRATION_54_58
MIGRATION_54_58,
MIGRATION_58_59
};
private static Migration NOOP(int from, int to) {

@ -26,6 +26,7 @@ import javax.inject.Inject;
import org.tasks.R;
import org.tasks.data.GoogleTask;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.data.Tag;
import org.tasks.data.TagData;
import org.tasks.injection.ForApplication;
@ -42,8 +43,8 @@ public class FilterCriteriaProvider {
private final Context context;
private final TagService tagService;
private final GtasksListService gtasksListService;
private final Resources r;
private final GoogleTaskListDao googleTaskListDao;
private final SyncAdapters syncAdapters;
@Inject
@ -51,13 +52,14 @@ public class FilterCriteriaProvider {
@ForApplication Context context,
TagService tagService,
GtasksListService gtasksListService,
SyncAdapters syncAdapters) {
SyncAdapters syncAdapters,
GoogleTaskListDao googleTaskListDao) {
this.context = context;
this.tagService = tagService;
this.gtasksListService = gtasksListService;
this.syncAdapters = syncAdapters;
r = context.getResources();
this.googleTaskListDao = googleTaskListDao;
}
public List<CustomFilterCriterion> getAll() {
@ -186,7 +188,7 @@ public class FilterCriteriaProvider {
}
private CustomFilterCriterion getGtasksFilterCriteria() {
List<GoogleTaskList> lists = gtasksListService.getLists();
List<GoogleTaskList> lists = googleTaskListDao.getAllActiveLists();
String[] listNames = new String[lists.size()];
String[] listIds = new String[lists.size()];

@ -14,6 +14,7 @@ import java.util.Map;
import javax.inject.Inject;
import org.tasks.caldav.CaldavFilterExposer;
import org.tasks.data.CaldavAccount;
import org.tasks.data.GoogleTaskAccount;
public class FilterProvider {
@ -56,7 +57,7 @@ public class FilterProvider {
return tagFilterExposer.getFilters();
}
public List<Filter> getGoogleTaskFilters() {
public List<Pair<GoogleTaskAccount, List<Filter>>> getGoogleTaskFilters() {
return gtasksFilterExposer.getFilters();
}

@ -3,6 +3,7 @@ package org.tasks.gtasks;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
@ -14,21 +15,26 @@ import javax.inject.Inject;
import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.DialogFragmentComponent;
import org.tasks.injection.ForApplication;
import org.tasks.injection.InjectingDialogFragment;
import timber.log.Timber;
public class CreateListDialog extends InjectingDialogFragment {
private static final String EXTRA_ACCOUNT = "extra_account";
private static final String EXTRA_NAME = "extra_name";
@Inject DialogBuilder dialogBuilder;
@Inject GtasksInvoker gtasksInvoker;
@Inject @ForApplication Context context;
@Inject PlayServices playServices;
private CreateListDialogCallback callback;
private ProgressDialog dialog;
private String account;
private String name;
public static CreateListDialog newCreateListDialog(String name) {
public static CreateListDialog newCreateListDialog(String account, String name) {
CreateListDialog dialog = new CreateListDialog();
Bundle args = new Bundle();
args.putString(EXTRA_ACCOUNT, account);
args.putString(EXTRA_NAME, name);
dialog.setArguments(args);
return dialog;
@ -39,6 +45,7 @@ public class CreateListDialog extends InjectingDialogFragment {
super.onCreate(savedInstanceState);
setRetainInstance(true);
Bundle arguments = getArguments();
account = arguments.getString(EXTRA_ACCOUNT);
name = arguments.getString(EXTRA_NAME);
dialog = dialogBuilder.newProgressDialog(R.string.creating_new_list);
execute();
@ -67,7 +74,7 @@ public class CreateListDialog extends InjectingDialogFragment {
@Override
protected TaskList doInBackground(Void... voids) {
try {
return gtasksInvoker.createGtaskList(name);
return new GtasksInvoker(context, playServices, account).createGtaskList(name);
} catch (IOException e) {
Timber.e(e);
return null;

@ -3,6 +3,7 @@ package org.tasks.gtasks;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
@ -11,24 +12,27 @@ import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import java.io.IOException;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.data.GoogleTaskList;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.DialogFragmentComponent;
import org.tasks.injection.ForApplication;
import org.tasks.injection.InjectingDialogFragment;
import timber.log.Timber;
public class DeleteListDialog extends InjectingDialogFragment {
private static final String EXTRA_ID = "extra_id";
private static final String EXTRA_LIST = "extra_list";
@Inject @ForApplication Context context;
@Inject DialogBuilder dialogBuilder;
@Inject GtasksInvoker gtasksInvoker;
@Inject PlayServices playServices;
private DeleteListDialogCallback callback;
private String id;
private GoogleTaskList googleTaskList;
private ProgressDialog dialog;
public static DeleteListDialog newDeleteListDialog(String id) {
public static DeleteListDialog newDeleteListDialog(GoogleTaskList googleTaskList) {
DeleteListDialog dialog = new DeleteListDialog();
Bundle args = new Bundle();
args.putString(EXTRA_ID, id);
args.putParcelable(EXTRA_LIST, googleTaskList);
dialog.setArguments(args);
return dialog;
}
@ -38,7 +42,7 @@ public class DeleteListDialog extends InjectingDialogFragment {
super.onCreate(savedInstanceState);
setRetainInstance(true);
Bundle arguments = getArguments();
id = arguments.getString(EXTRA_ID);
googleTaskList = arguments.getParcelable(EXTRA_LIST);
dialog = dialogBuilder.newProgressDialog(R.string.deleting_list);
execute();
}
@ -66,7 +70,8 @@ public class DeleteListDialog extends InjectingDialogFragment {
@Override
protected Boolean doInBackground(Void... voids) {
try {
gtasksInvoker.deleteGtaskList(id);
new GtasksInvoker(context, playServices, googleTaskList.getAccount())
.deleteGtaskList(googleTaskList.getRemoteId());
return true;
} catch (IOException e) {
Timber.e(e);

@ -7,7 +7,6 @@ import static java.util.Arrays.asList;
import android.accounts.Account;
import android.content.Context;
import com.google.common.base.Strings;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
@ -18,17 +17,14 @@ public class GoogleAccountManager {
private final PermissionChecker permissionChecker;
private final android.accounts.AccountManager accountManager;
private final GtasksPreferenceService gtasksPreferenceService;
@Inject
public GoogleAccountManager(
@ForApplication Context context,
PermissionChecker permissionChecker,
GtasksPreferenceService gtasksPreferenceService) {
PermissionChecker permissionChecker) {
this.permissionChecker = permissionChecker;
accountManager = android.accounts.AccountManager.get(context);
this.gtasksPreferenceService = gtasksPreferenceService;
}
public List<String> getAccounts() {
@ -45,10 +41,6 @@ public class GoogleAccountManager {
: Collections.emptyList();
}
public Account getSelectedAccount() {
return getAccount(gtasksPreferenceService.getUserName());
}
public Account getAccount(final String name) {
if (Strings.isNullOrEmpty(name)) {
return null;

@ -19,7 +19,6 @@ import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.SyncFlags;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gtasks.GtasksListService;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.GtasksTaskListUpdater;
import com.todoroo.astrid.gtasks.api.GtasksApiUtilities;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
@ -35,6 +34,7 @@ import javax.inject.Inject;
import org.tasks.R;
import org.tasks.analytics.Tracker;
import org.tasks.data.GoogleTask;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskDao;
import org.tasks.data.GoogleTaskList;
import org.tasks.data.GoogleTaskListDao;
@ -50,50 +50,47 @@ public class GoogleTaskSynchronizer {
private static final String DEFAULT_LIST = "@default"; // $NON-NLS-1$
private final Context context;
private final GtasksPreferenceService gtasksPreferenceService;
private final GoogleTaskListDao googleTaskListDao;
private final GtasksSyncService gtasksSyncService;
private final GtasksListService gtasksListService;
private final GtasksTaskListUpdater gtasksTaskListUpdater;
private final Preferences preferences;
private final GtasksInvoker gtasksInvoker;
private final TaskDao taskDao;
private final Tracker tracker;
private final NotificationManager notificationManager;
private final GoogleTaskDao googleTaskDao;
private final TaskCreator taskCreator;
private final DefaultFilterProvider defaultFilterProvider;
private final PlayServices playServices;
@Inject
public GoogleTaskSynchronizer(
@ForApplication Context context,
GtasksPreferenceService gtasksPreferenceService,
GoogleTaskListDao googleTaskListDao,
GtasksSyncService gtasksSyncService,
GtasksListService gtasksListService,
GtasksTaskListUpdater gtasksTaskListUpdater,
Preferences preferences,
GtasksInvoker gtasksInvoker,
TaskDao taskDao,
Tracker tracker,
NotificationManager notificationManager,
GoogleTaskDao googleTaskDao,
TaskCreator taskCreator,
DefaultFilterProvider defaultFilterProvider) {
DefaultFilterProvider defaultFilterProvider,
PlayServices playServices) {
this.context = context;
this.gtasksPreferenceService = gtasksPreferenceService;
this.googleTaskListDao = googleTaskListDao;
this.gtasksSyncService = gtasksSyncService;
this.gtasksListService = gtasksListService;
this.gtasksTaskListUpdater = gtasksTaskListUpdater;
this.preferences = preferences;
this.gtasksInvoker = gtasksInvoker;
this.taskDao = taskDao;
this.tracker = tracker;
this.notificationManager = notificationManager;
this.googleTaskDao = googleTaskDao;
this.taskCreator = taskCreator;
this.defaultFilterProvider = defaultFilterProvider;
this.playServices = playServices;
}
public static void mergeDates(long remoteDueDate, Task local) {
@ -112,23 +109,20 @@ public class GoogleTaskSynchronizer {
}
public void sync() {
String account = gtasksPreferenceService.getUserName();
if (TextUtils.isEmpty(account)) {
return;
}
Timber.d("%s: start sync", account);
try {
synchronize();
gtasksPreferenceService.recordSuccessfulSync();
} catch (UserRecoverableAuthIOException e) {
Timber.e(e);
sendNotification(context, e.getIntent());
} catch (IOException e) {
Timber.e(e);
} catch (Exception e) {
tracker.reportException(e);
} finally {
Timber.d("%s: end sync", account);
for (GoogleTaskAccount account : googleTaskListDao.getAccounts()) {
Timber.d("%s: start sync", account);
try {
synchronize(account);
} catch (UserRecoverableAuthIOException e) {
Timber.e(e);
sendNotification(context, e.getIntent());
} catch (IOException e) {
Timber.e(e);
} catch (Exception e) {
tracker.reportException(e);
} finally {
Timber.d("%s: end sync", account);
}
}
}
@ -150,8 +144,9 @@ public class GoogleTaskSynchronizer {
notificationManager.notify(Constants.NOTIFICATION_SYNC_ERROR, builder, true, false, false);
}
private void synchronize() throws IOException {
pushLocalChanges();
private void synchronize(GoogleTaskAccount account) throws IOException {
GtasksInvoker gtasksInvoker = new GtasksInvoker(context, playServices, account.getAccount());
pushLocalChanges(gtasksInvoker);
List<TaskList> gtaskLists = new ArrayList<>();
String nextPageToken = null;
@ -166,7 +161,7 @@ public class GoogleTaskSynchronizer {
}
nextPageToken = remoteLists.getNextPageToken();
} while (nextPageToken != null);
gtasksListService.updateLists(gtaskLists);
gtasksListService.updateLists(account, gtaskLists);
Filter defaultRemoteList = defaultFilterProvider.getDefaultRemoteList();
if (defaultRemoteList instanceof GtasksFilter) {
GoogleTaskList list =
@ -176,11 +171,11 @@ public class GoogleTaskSynchronizer {
}
}
for (final GoogleTaskList list : gtasksListService.getListsToUpdate(gtaskLists)) {
fetchAndApplyRemoteChanges(list);
fetchAndApplyRemoteChanges(gtasksInvoker, list);
}
}
private void pushLocalChanges() throws UserRecoverableAuthIOException {
private void pushLocalChanges(GtasksInvoker gtasksInvoker) throws UserRecoverableAuthIOException {
List<Task> tasks = taskDao.getGoogleTasksToPush();
for (Task task : tasks) {
try {
@ -193,7 +188,7 @@ public class GoogleTaskSynchronizer {
}
}
private void pushTask(Task task, GtasksInvoker invoker) throws IOException {
private void pushTask(Task task, GtasksInvoker gtasksInvoker) throws IOException {
for (GoogleTask deleted : googleTaskDao.getDeletedByTaskId(task.getId())) {
gtasksInvoker.deleteGtask(deleted.getListId(), deleted.getRemoteId());
googleTaskDao.delete(deleted);
@ -257,7 +252,7 @@ public class GoogleTaskSynchronizer {
if (!newlyCreated) {
try {
invoker.updateGtask(listId, remoteModel);
gtasksInvoker.updateGtask(listId, remoteModel);
} catch (HttpNotFoundException e) {
Timber.e(e);
googleTaskDao.delete(gtasksMetadata);
@ -268,7 +263,7 @@ public class GoogleTaskSynchronizer {
String priorSibling = gtasksSyncService.getRemoteSiblingId(listId, gtasksMetadata);
com.google.api.services.tasks.model.Task created =
invoker.createGtask(listId, remoteModel, parent, priorSibling);
gtasksInvoker.createGtask(listId, remoteModel, parent, priorSibling);
if (created != null) {
// Update the metadata for the newly created task
@ -290,7 +285,7 @@ public class GoogleTaskSynchronizer {
taskDao.save(task);
}
private synchronized void fetchAndApplyRemoteChanges(GoogleTaskList list)
private synchronized void fetchAndApplyRemoteChanges(GtasksInvoker gtasksInvoker, GoogleTaskList list)
throws UserRecoverableAuthIOException {
String listId = list.getRemoteId();
long lastSyncDate = list.getLastSync();

@ -1,20 +1,19 @@
package org.tasks.gtasks;
import android.accounts.Account;
import android.app.Activity;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.analytics.Tracker;
import org.tasks.analytics.Tracking;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.preferences.Preferences;
public class GtaskSyncAdapterHelper {
private static final String AUTHORITY = "org.tasks";
private final GoogleAccountManager accountManager;
private final Preferences preferences;
private final PlayServices playServices;
private final GoogleTaskListDao googleTaskListDao;
private final Tracker tracker;
@Inject
@ -22,25 +21,25 @@ public class GtaskSyncAdapterHelper {
GoogleAccountManager accountManager,
Preferences preferences,
PlayServices playServices,
GoogleTaskListDao googleTaskListDao,
Tracker tracker) {
this.accountManager = accountManager;
this.preferences = preferences;
this.playServices = playServices;
this.googleTaskListDao = googleTaskListDao;
this.tracker = tracker;
}
public boolean isEnabled() {
return preferences.getBoolean(R.string.sync_gtasks, false)
&& playServices.isPlayServicesAvailable()
&& getAccount() != null;
return hasAccounts() && playServices.isPlayServicesAvailable();
}
private Account getAccount() {
return accountManager.getSelectedAccount();
private boolean hasAccounts() {
return !googleTaskListDao.getAccounts().isEmpty();
}
public void checkPlayServices(Activity activity) {
if (preferences.getBoolean(R.string.sync_gtasks, false)
if (hasAccounts()
&& !playServices.refreshAndCheck()
&& !preferences.getBoolean(R.string.warned_play_services, false)) {
preferences.setBoolean(R.string.warned_play_services, true);

@ -3,6 +3,7 @@ package org.tasks.gtasks;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
@ -12,26 +13,29 @@ import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import java.io.IOException;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.data.GoogleTaskList;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.DialogFragmentComponent;
import org.tasks.injection.ForApplication;
import org.tasks.injection.InjectingDialogFragment;
import timber.log.Timber;
public class RenameListDialog extends InjectingDialogFragment {
private static final String EXTRA_NAME = "extra_name";
private static final String EXTRA_ID = "extra_id";
private static final String EXTRA_LIST = "extra_list";
@Inject @ForApplication Context context;
@Inject DialogBuilder dialogBuilder;
@Inject GtasksInvoker gtasksInvoker;
@Inject PlayServices playServices;
private RenameListDialogCallback callback;
private ProgressDialog dialog;
private String id;
private GoogleTaskList googleTaskList;
private String name;
public static RenameListDialog newRenameListDialog(String id, String name) {
public static RenameListDialog newRenameListDialog(GoogleTaskList googleTaskList, String name) {
RenameListDialog dialog = new RenameListDialog();
Bundle args = new Bundle();
args.putString(EXTRA_ID, id);
args.putParcelable(EXTRA_LIST, googleTaskList);
args.putString(EXTRA_NAME, name);
dialog.setArguments(args);
return dialog;
@ -42,7 +46,7 @@ public class RenameListDialog extends InjectingDialogFragment {
super.onCreate(savedInstanceState);
setRetainInstance(true);
Bundle arguments = getArguments();
id = arguments.getString(EXTRA_ID);
googleTaskList = arguments.getParcelable(EXTRA_LIST);
name = arguments.getString(EXTRA_NAME);
dialog = dialogBuilder.newProgressDialog(R.string.renaming_list);
execute();
@ -71,7 +75,8 @@ public class RenameListDialog extends InjectingDialogFragment {
@Override
protected TaskList doInBackground(Void... voids) {
try {
return gtasksInvoker.renameGtaskList(id, name);
return new GtasksInvoker(context, playServices, googleTaskList.getAccount())
.renameGtaskList(googleTaskList.getRemoteId(), name);
} catch (IOException e) {
Timber.e(e);
return null;

@ -12,6 +12,7 @@ import javax.annotation.Nullable;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.data.CaldavDao;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.injection.ApplicationScope;
import org.tasks.preferences.Preferences;
import timber.log.Timber;
@ -30,15 +31,18 @@ public class JobManager {
private final com.evernote.android.job.JobManager jobManager;
private final Preferences preferences;
private final CaldavDao caldavDao;
private final GoogleTaskListDao googleTaskListDao;
@Inject
public JobManager(
com.evernote.android.job.JobManager jobManager,
Preferences preferences,
CaldavDao caldavDao) {
CaldavDao caldavDao,
GoogleTaskListDao googleTaskListDao) {
this.jobManager = jobManager;
this.preferences = preferences;
this.caldavDao = caldavDao;
this.googleTaskListDao = googleTaskListDao;
}
public void scheduleNotification(long time) {
@ -81,8 +85,7 @@ public class JobManager {
: forceBackgroundEnabled;
boolean accountsPresent =
forceAccountPresent == null
? (preferences.getBoolean(R.string.sync_gtasks, false)
|| caldavDao.getAccounts().size() > 0)
? (googleTaskListDao.getAccounts().size() > 0 || caldavDao.getAccounts().size() > 0)
: forceAccountPresent;
boolean onlyOnWifi =
forceOnlyOnUnmetered == null

@ -9,12 +9,9 @@ import static org.tasks.PermissionUtil.verifyPermissions;
import android.content.Intent;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.support.annotation.NonNull;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity;
import javax.inject.Inject;
import org.tasks.R;
@ -25,7 +22,9 @@ import org.tasks.billing.PurchaseActivity;
import org.tasks.caldav.CaldavAccountSettingsActivity;
import org.tasks.data.CaldavAccount;
import org.tasks.data.CaldavDao;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskDao;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.gtasks.GtaskSyncAdapterHelper;
@ -37,14 +36,17 @@ import org.tasks.preferences.ActivityPermissionRequestor;
import org.tasks.preferences.PermissionChecker;
import org.tasks.preferences.PermissionRequestor;
import org.tasks.preferences.Preferences;
import timber.log.Timber;
public class SynchronizationPreferences extends InjectingPreferenceActivity {
private static final String KEY_ADD_GOOGLE_TASKS = "add_google_tasks";
private static final String KEY_ADD_CALDAV = "add_caldav";
private static final int REQUEST_LOGIN = 0;
private static final int REQUEST_CALDAV_SETTINGS = 101;
private static final int REQUEST_CALDAV_SUBSCRIBE = 102;
private static final int REQUEST_GOOGLE_TASKS_SUBSCRIBE = 103;
@Inject GtasksPreferenceService gtasksPreferenceService;
@Inject ActivityPermissionRequestor permissionRequestor;
@Inject PermissionChecker permissionChecker;
@Inject Tracker tracker;
@ -53,6 +55,7 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity {
@Inject DialogBuilder dialogBuilder;
@Inject SyncAdapters syncAdapters;
@Inject GoogleTaskDao googleTaskDao;
@Inject GoogleTaskListDao googleTaskListDao;
@Inject GoogleAccountManager googleAccountManager;
@Inject Preferences preferences;
@Inject JobManager jobManager;
@ -65,49 +68,52 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity {
addPreferencesFromResource(R.xml.preferences_synchronization);
PreferenceCategory caldavPreferences = (PreferenceCategory) findPreference(getString(R.string.CalDAV));
PreferenceCategory caldavPreferences =
(PreferenceCategory) findPreference(getString(R.string.CalDAV));
for (CaldavAccount caldavAccount : caldavDao.getAccounts()) {
Preference accountPreferences = new Preference(this);
accountPreferences.setTitle(caldavAccount.getName());
accountPreferences.setSummary(caldavAccount.getUrl());
accountPreferences.setOnPreferenceClickListener(preference -> {
Intent intent = new Intent(this, CaldavAccountSettingsActivity.class);
intent.putExtra(CaldavAccountSettingsActivity.EXTRA_CALDAV_DATA, caldavAccount);
startActivityForResult(intent, REQUEST_CALDAV_SETTINGS);
return false;
});
accountPreferences.setOnPreferenceClickListener(
preference -> {
Intent intent = new Intent(this, CaldavAccountSettingsActivity.class);
intent.putExtra(CaldavAccountSettingsActivity.EXTRA_CALDAV_DATA, caldavAccount);
startActivityForResult(intent, REQUEST_CALDAV_SETTINGS);
return false;
});
caldavPreferences.addPreference(accountPreferences);
}
Preference addCaldavAccount = new Preference(this);
addCaldavAccount.setKey(getString(R.string.add_account));
addCaldavAccount.setKey(KEY_ADD_CALDAV);
addCaldavAccount.setTitle(R.string.add_account);
caldavPreferences.addPreference(addCaldavAccount);
final CheckBoxPreference gtaskPreference =
(CheckBoxPreference) findPreference(getString(R.string.sync_gtasks));
gtaskPreference.setChecked(syncAdapters.isGoogleTaskSyncEnabled());
gtaskPreference.setOnPreferenceChangeListener(
(preference, newValue) -> {
if ((boolean) newValue) {
PreferenceCategory googleTaskPreferences =
(PreferenceCategory) findPreference(getString(R.string.gtasks_GPr_header));
for (GoogleTaskAccount googleTaskAccount : googleTaskListDao.getAccounts()) {
String account = googleTaskAccount.getAccount();
if (googleAccountManager.getAccount(account) == null) {
Timber.e("Can't access %s", account);
continue;
}
Preference accountPreferences = new Preference(this);
accountPreferences.setTitle(account);
accountPreferences.setOnPreferenceClickListener(
preference -> {
if (!playServices.refreshAndCheck()) {
playServices.resolve(SynchronizationPreferences.this);
} else if (permissionRequestor.requestAccountPermissions()) {
requestLogin();
}
return false;
} else {
jobManager.updateBackgroundSync();
tracker.reportEvent(Tracking.Events.GTASK_DISABLED);
return true;
}
});
if (gtasksPreferenceService.getLastSyncDate() > 0) {
gtaskPreference.setSummary(
getString(
R.string.sync_status_success,
DateUtilities.getDateStringWithTime(
SynchronizationPreferences.this, gtasksPreferenceService.getLastSyncDate())));
});
googleTaskPreferences.addPreference(accountPreferences);
}
Preference addGoogleTaskAccount = new Preference(this);
addGoogleTaskAccount.setKey(KEY_ADD_GOOGLE_TASKS);
addGoogleTaskAccount.setTitle(R.string.add_account);
googleTaskPreferences.addPreference(addGoogleTaskAccount);
findPreference(getString(R.string.p_background_sync_unmetered_only))
.setOnPreferenceChangeListener(
(preference, o) -> {
@ -120,24 +126,6 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity {
jobManager.updateBackgroundSync(null, (Boolean) o, null);
return true;
});
findPreference(getString(R.string.sync_SPr_forget_key))
.setOnPreferenceClickListener(
preference -> {
dialogBuilder
.newMessageDialog(R.string.sync_forget_confirm)
.setPositiveButton(
android.R.string.ok,
(dialog, which) -> {
gtasksPreferenceService.clearLastSyncDate();
gtasksPreferenceService.setUserName(null);
googleTaskDao.deleteAll();
tracker.reportEvent(Tracking.Events.GTASK_LOGOUT);
gtaskPreference.setChecked(false);
})
.setNegativeButton(android.R.string.cancel, null)
.show();
return true;
});
}
private void requestLogin() {
@ -149,28 +137,55 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity {
protected void onResume() {
super.onResume();
Preference addCaldavAccount = findPreference(R.string.add_account);
Preference addCaldavAccount = findPreference(KEY_ADD_CALDAV);
Preference addGoogleTasks = findPreference(KEY_ADD_GOOGLE_TASKS);
if (inventory.hasPro()) {
addCaldavAccount.setSummary(null);
addCaldavAccount.setOnPreferenceClickListener(preference -> {
addCaldavAccount();
return false;
});
addGoogleTasks.setSummary(null);
addCaldavAccount.setOnPreferenceClickListener(
preference -> {
addCaldavAccount();
return false;
});
addGoogleTasks.setOnPreferenceClickListener(
preference -> {
requestLogin();
return false;
});
} else {
addCaldavAccount.setSummary(R.string.requires_pro_subscription);
addCaldavAccount.setOnPreferenceClickListener(preference -> {
startActivityForResult(new Intent(this, PurchaseActivity.class), REQUEST_CALDAV_SUBSCRIBE);
return false;
});
addCaldavAccount.setOnPreferenceClickListener(
preference -> {
startActivityForResult(
new Intent(this, PurchaseActivity.class), REQUEST_CALDAV_SUBSCRIBE);
return false;
});
if (googleTaskListDao.getAccounts().isEmpty()) {
addGoogleTasks.setSummary(null);
addGoogleTasks.setOnPreferenceClickListener(
preference -> {
requestLogin();
return false;
});
} else {
addGoogleTasks.setSummary(R.string.requires_pro_subscription);
addGoogleTasks.setOnPreferenceClickListener(
preference -> {
startActivityForResult(
new Intent(this, PurchaseActivity.class), REQUEST_GOOGLE_TASKS_SUBSCRIBE);
return false;
});
}
}
if (!permissionChecker.canAccessAccounts()) {
((CheckBoxPreference) findPreference(getString(R.string.sync_gtasks))).setChecked(false);
// TODO: clear google task preference category
}
}
private void addCaldavAccount() {
startActivityForResult(new Intent(this, CaldavAccountSettingsActivity.class), REQUEST_CALDAV_SETTINGS);
startActivityForResult(
new Intent(this, CaldavAccountSettingsActivity.class), REQUEST_CALDAV_SETTINGS);
}
@Override
@ -180,24 +195,32 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity {
if (enabled) {
tracker.reportEvent(Tracking.Events.GTASK_ENABLED);
jobManager.updateBackgroundSync();
restart();
}
((CheckBoxPreference) findPreference(getString(R.string.sync_gtasks))).setChecked(enabled);
} else if (requestCode == REQUEST_CALDAV_SETTINGS) {
if (resultCode == RESULT_OK) {
jobManager.updateBackgroundSync();
Intent intent = getIntent();
finish();
startActivity(intent);
restart();
}
} else if (requestCode == REQUEST_CALDAV_SUBSCRIBE) {
if (inventory.hasPro()) {
addCaldavAccount();
}
} else if (requestCode == REQUEST_GOOGLE_TASKS_SUBSCRIBE) {
if (inventory.hasPro()) {
requestLogin();
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
private void restart() {
Intent intent = getIntent();
finish();
startActivity(intent);
}
@Override
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

@ -129,10 +129,7 @@
<string name="tmrw">غدا</string>
<string name="yest">أمس</string>
<string name="DLG_wait">إنتظر من فضلك...</string>
<string name="sync_status_success">آخر تحيين:\n%s</string>
<string name="sync_SPr_interval_title">تحيين في الخلفية</string>
<string name="sync_SPr_forget">خروج</string>
<string name="sync_forget_confirm">تسجيل الخروج/ مسح معلومات المزامنه؟</string>
<string name="widget_show_due_date">أظهر تواريخ الإستحقاق</string>
<string name="widget_show_checkboxes">إظهار مربعات التعليم</string>
<string name="widget_show_header">إظهار الهايدر</string>

@ -300,11 +300,7 @@
<string name="tmrw">Утре</string>
<string name="yest">Вчера</string>
<string name="DLG_wait">Моля, изчакайте...</string>
<string name="sync_status_success">Последна синхронизация:\n%s</string>
<string name="sync_SPr_interval_title">Синхронзиране във фонов режим</string>
<string name="sync_SPr_forget">Излизане</string>
<string name="sync_SPr_forget_description">Изчистване на всички данни от синхронзация</string>
<string name="sync_forget_confirm">Изход/изчистване на данните от синхронизация?</string>
<string name="widget_show_due_date">Покажи крайните дати</string>
<string name="widget_show_checkboxes">Покажи отметки</string>
<string name="widget_show_header">Покажи хедър</string>

@ -110,11 +110,7 @@
<string name="tomorrow">Demà</string>
<string name="yesterday">Ahir</string>
<string name="DLG_wait">Si us plau, espera...</string>
<string name="sync_status_success">Última sincronització:\n%s</string>
<string name="sync_SPr_interval_title">Sincronitzar en segon pla</string>
<string name="sync_SPr_forget">Surt</string>
<string name="sync_SPr_forget_description">Esborra tota la informació de sincronització</string>
<string name="sync_forget_confirm">Tancar sessió / esborra la informació de sincronització?</string>
<string name="source_code">Codi font</string>
<string name="translations">Contribuir traduccions</string>
<string name="contact_developer">Contacta amb el desenvolupador</string>

@ -207,11 +207,7 @@
<string name="tmrw">Zítra</string>
<string name="yest">Včera</string>
<string name="DLG_wait">Čekejte prosím...</string>
<string name="sync_status_success">Poslední synchronizace:\n%s</string>
<string name="sync_SPr_interval_title">Synchronizace na pozadí</string>
<string name="sync_SPr_forget">Odhlásit se</string>
<string name="sync_SPr_forget_description">Smazat všechny synchronizační data</string>
<string name="sync_forget_confirm">Odhlásit se / vymazat synchronizační data?</string>
<string name="widget_show_due_date">Ukázat data splnění</string>
<string name="widget_show_checkboxes">Ukázat zaškrtávací políčka</string>
<string name="widget_show_header">Zobraz záhlaví</string>

@ -93,7 +93,5 @@
<string name="yesterday">I går</string>
<string name="DLG_wait">Vent venligst...</string>
<string name="sync_SPr_interval_title">Baggrunds Synk</string>
<string name="sync_SPr_forget">Log af</string>
<string name="sync_SPr_forget_description">Sletter al synkroniserings data</string>
<string name="source_code">Kildekode</string>
</resources>

@ -293,11 +293,7 @@
<string name="tmrw">Morg.</string>
<string name="yest">Gest.</string>
<string name="DLG_wait">Bitte warten...</string>
<string name="sync_status_success">Letzte Synchronisierung:\n%s</string>
<string name="sync_SPr_interval_title">Hintergrund-Synchronisierung</string>
<string name="sync_SPr_forget">Abmelden</string>
<string name="sync_SPr_forget_description">Alle Synchronisationsdaten löschen</string>
<string name="sync_forget_confirm">Ausloggen / Synchronisierte Daten löschen?</string>
<string name="widget_show_due_date">Zeige Fälligkeitsdaten</string>
<string name="widget_show_checkboxes">Checkboxen anzeigen</string>
<string name="widget_show_header">Kopf anzeigen</string>

@ -181,8 +181,6 @@
<string name="tmrw">Αύριο</string>
<string name="yest">Χθές</string>
<string name="DLG_wait">Παρακαλώ περιμένετε...</string>
<string name="sync_status_success">Τελευταίος συγχρονισμός:\n%s</string>
<string name="sync_SPr_interval_title">Συγχρονισμός παρασκηνίου</string>
<string name="sync_SPr_forget">Αποσύνδεση</string>
<string name="TLA_menu_donate">Δωρίστε</string>
</resources>

@ -296,11 +296,7 @@
<string name="tmrw">Mñna</string>
<string name="yest">Ayer</string>
<string name="DLG_wait">Por favor, espere...</string>
<string name="sync_status_success">Ultima sincronización:\n%s</string>
<string name="sync_SPr_interval_title">Sincronización en segundo plano</string>
<string name="sync_SPr_forget">Cerrar sesión</string>
<string name="sync_SPr_forget_description">Limpia todos los datos de la sincronización</string>
<string name="sync_forget_confirm">Cerrar sesión/Limpiar datos de sincronización?</string>
<string name="widget_show_due_date">Mostrar fechas de vencimiento</string>
<string name="widget_show_checkboxes">Mostrar casillas de verificación</string>
<string name="widget_show_header">Mostrar encabezado</string>

@ -194,7 +194,6 @@
<string name="yest">دیروز</string>
<string name="DLG_wait">لطفا منتظر بمانید...</string>
<string name="sync_SPr_interval_title">سینک پیش زمینه</string>
<string name="sync_SPr_forget">خروج از حساب کاربری</string>
<string name="widget_show_due_date">نمایش تاریخ موعود</string>
<string name="widget_show_checkboxes">نمایش محل تیک</string>
<string name="widget_show_header">نمایش سربرگ</string>

@ -301,11 +301,7 @@
<string name="tmrw">Huominen</string>
<string name="yest">Eilinen</string>
<string name="DLG_wait">Ole hyvä ja odota...</string>
<string name="sync_status_success">Viimeisin synkronointi:\n%s</string>
<string name="sync_SPr_interval_title">Tausta synkronointi</string>
<string name="sync_SPr_forget">Kirjaudu ulos</string>
<string name="sync_SPr_forget_description">Tyhjennä kaikki synkronointidata</string>
<string name="sync_forget_confirm">Kirjaudu ulos/tyhjennä synkronointidata</string>
<string name="widget_show_due_date">Näytä määräpäivät</string>
<string name="widget_show_checkboxes">Näytä valintaruudut</string>
<string name="widget_show_header">Näytä otsikot</string>

@ -286,11 +286,7 @@
<string name="tmrw">Demain</string>
<string name="yest">Hier</string>
<string name="DLG_wait">Veuillez patienter...</string>
<string name="sync_status_success">Dernière synchro. :\n%s</string>
<string name="sync_SPr_interval_title">Synchro. en arrière-plan</string>
<string name="sync_SPr_forget">Se déconnecter</string>
<string name="sync_SPr_forget_description">Supprimer définitivement toutes les données de synchronisation</string>
<string name="sync_forget_confirm">Se déconnecter/supprimer définitivement toutes les données de synchronisation ?</string>
<string name="widget_show_due_date">Montrer les dates échéantes</string>
<string name="widget_show_checkboxes">Montrer les cases à cocher</string>
<string name="widget_show_header">Montrer l\'en-tête</string>

@ -223,11 +223,7 @@
<string name="tmrw">Mñna</string>
<string name="yest">Ayer</string>
<string name="DLG_wait">Por favor, espere...</string>
<string name="sync_status_success">Ultima sincronización:\n%s</string>
<string name="sync_SPr_interval_title">Sincronización en segundo plano</string>
<string name="sync_SPr_forget">Cerrar sesión</string>
<string name="sync_SPr_forget_description">Limpia todos los datos de la sincronización</string>
<string name="sync_forget_confirm">Cerrar sesión/Limpiar datos de sincronización?</string>
<string name="widget_show_due_date">Mostrar fechas de vencimiento</string>
<string name="widget_show_checkboxes">Mostrar casillas de verificación</string>
<string name="widget_show_header">Mostrar encabezado</string>

@ -300,11 +300,7 @@
<string name="tmrw">Holn</string>
<string name="yest">Tegn</string>
<string name="DLG_wait">Kérlek, várj...</string>
<string name="sync_status_success">Utolsó szinkronizáció:\n%s</string>
<string name="sync_SPr_interval_title">Szinkronizáció a háttérben</string>
<string name="sync_SPr_forget">Kijelentkezés</string>
<string name="sync_SPr_forget_description">Az összes szinkronizációs adat törlése</string>
<string name="sync_forget_confirm">Kijelentkezés és szinkronizációs adatok törlése?</string>
<string name="widget_show_due_date">Határidők megjelenítése</string>
<string name="widget_show_checkboxes">Jelölőnégyzetek megjelenítése</string>
<string name="widget_show_header">Fejléc megjelenítése</string>

@ -297,11 +297,7 @@
<string name="tmrw">Domani</string>
<string name="yest">Ieri</string>
<string name="DLG_wait">Attendi...</string>
<string name="sync_status_success">Ultima Sincronizzazione:\n%s</string>
<string name="sync_SPr_interval_title">Sincronizzazione eseguita in background</string>
<string name="sync_SPr_forget">Esci</string>
<string name="sync_SPr_forget_description">Cancella tutti i dati di sincronizzazione</string>
<string name="sync_forget_confirm">Esci / cancella i file di sincronizzazione?</string>
<string name="widget_show_due_date">Mostra scadenze</string>
<string name="widget_show_checkboxes">Mostra caselle selezione</string>
<string name="widget_show_header">Mostra intestazione</string>

@ -248,11 +248,7 @@
<string name="tmrw">מחר</string>
<string name="yest">אתמול</string>
<string name="DLG_wait">אנא המתן...</string>
<string name="sync_status_success">סנכרון אחרון:\n%s</string>
<string name="sync_SPr_interval_title">סנכרון ברקע</string>
<string name="sync_SPr_forget">התנתק</string>
<string name="sync_SPr_forget_description">מסיר את כל נתוני הסנכרון</string>
<string name="sync_forget_confirm">צא מהחשבון \\ הסר נתוני סנכרון?</string>
<string name="widget_show_due_date">הצג תאריכי יעד</string>
<string name="widget_show_checkboxes">הצג תיבות סימון</string>
<string name="widget_show_header">הצג כותרת</string>

@ -298,11 +298,7 @@
<string name="tmrw">明日</string>
<string name="yest">昨日</string>
<string name="DLG_wait">お待ちください</string>
<string name="sync_status_success">前回の同期:\n%s</string>
<string name="sync_SPr_interval_title">バックグラウンド同期</string>
<string name="sync_SPr_forget">ログアウト</string>
<string name="sync_SPr_forget_description">すべての同期データを消去します</string>
<string name="sync_forget_confirm">ログアウトと同期データを消去しますか?</string>
<string name="widget_show_due_date">期限を表示</string>
<string name="widget_show_checkboxes">チェックボックスを表示</string>
<string name="widget_show_header">ヘッダーを表示</string>

@ -302,11 +302,7 @@
<string name="tmrw">내일</string>
<string name="yest">어제</string>
<string name="DLG_wait">잠시 기다리세요...</string>
<string name="sync_status_success">마지막 동기화: \n%s</string>
<string name="sync_SPr_interval_title">백그라운드 동기화</string>
<string name="sync_SPr_forget">로그아웃</string>
<string name="sync_SPr_forget_description">모든 동기화 자료 삭제</string>
<string name="sync_forget_confirm">로그아웃 / 모든 동기화 데이터 삭제?</string>
<string name="widget_show_due_date">완료 예정일 표시</string>
<string name="widget_show_checkboxes">체크박스 표시</string>
<string name="widget_show_header">헤더 표시</string>

@ -297,11 +297,7 @@
<string name="tmrw">Ryt</string>
<string name="yest">Vakar</string>
<string name="DLG_wait">Prašome palaukti...</string>
<string name="sync_status_success">Paskutinė sinchronizacija:\n%s</string>
<string name="sync_SPr_interval_title">Foninis sinchronizavimas</string>
<string name="sync_SPr_forget">Atsijungti</string>
<string name="sync_SPr_forget_description">Išvalo visą sinchronizacijos informaciją</string>
<string name="sync_forget_confirm">Atsijungti/išvalyti sinchronizacijos informaciją?</string>
<string name="widget_show_due_date">Rodyti pabaigos terminus</string>
<string name="widget_show_checkboxes">Rodyti žymimus kvadratėlius</string>
<string name="widget_show_header">Rodyti antraštę</string>

@ -133,11 +133,7 @@
<string name="tomorrow">I morgen</string>
<string name="yesterday">I går</string>
<string name="DLG_wait">Vennligst vent...</string>
<string name="sync_status_success">Siste synkronisering:\n%s</string>
<string name="sync_SPr_interval_title">Bakgrunnssynkronisering</string>
<string name="sync_SPr_forget">Logg ut</string>
<string name="sync_SPr_forget_description">Sletter all synkroniseringsdata</string>
<string name="sync_forget_confirm">Logg ut / slett synkroniseringsdata?</string>
<string name="widget_show_due_date">Vis tidsfrister</string>
<string name="widget_show_checkboxes">Vis avmerkingsbokser</string>
<string name="widget_show_settings">Vis innstillinger</string>

@ -296,11 +296,7 @@
<string name="tmrw">mrgn</string>
<string name="yest">gisteren</string>
<string name="DLG_wait">Even geduld a.u.b.</string>
<string name="sync_status_success">Vorige:\n%s</string>
<string name="sync_SPr_interval_title">Achtergrond synchronisatie</string>
<string name="sync_SPr_forget">Afmelden</string>
<string name="sync_SPr_forget_description">Alle synchronisatie gegevens verwijderen</string>
<string name="sync_forget_confirm">Afmelden / synchronisatie gegevens verwijderen?</string>
<string name="widget_show_due_date">Toon eind datums</string>
<string name="widget_show_checkboxes">Toon vinkboxjes</string>
<string name="widget_show_header">Toon titel</string>

@ -276,11 +276,7 @@
<string name="tmrw">jtr</string>
<string name="yest">wcz</string>
<string name="DLG_wait">Proszę czekać...</string>
<string name="sync_status_success">Ostatnia synchronizacja:\n%s</string>
<string name="sync_SPr_interval_title">Synchronizacja w tle</string>
<string name="sync_SPr_forget">Wyloguj</string>
<string name="sync_SPr_forget_description">Czyści wszystkie dane synchronizacji</string>
<string name="sync_forget_confirm">Wyloguj / wyczyść dane synchronizacji?</string>
<string name="widget_show_due_date">Pokaż terminy</string>
<string name="widget_show_checkboxes">Pokaż przyciski wyboru</string>
<string name="widget_show_header">Pokaż nagłówek</string>

@ -220,11 +220,7 @@
<string name="tmrw">amanhã</string>
<string name="yest">ontem</string>
<string name="DLG_wait">Por favor, aguarde...</string>
<string name="sync_status_success">Última sincronização:\n%s</string>
<string name="sync_SPr_interval_title">Sincronização em segundo plano</string>
<string name="sync_SPr_forget">Desconectar</string>
<string name="sync_SPr_forget_description">Limpar todos os dados de sincronização</string>
<string name="sync_forget_confirm">Desconectar / limpar dados de sincronização?</string>
<string name="widget_show_due_date">Mostrar vencimentos</string>
<string name="widget_show_checkboxes">Mostrar tarefas ocultas</string>
<string name="widget_show_header">Mostrar ocultas</string>

@ -298,11 +298,7 @@
<string name="tmrw">Amanhã</string>
<string name="yest">Ontem</string>
<string name="DLG_wait">Por favor aguarde...</string>
<string name="sync_status_success">Última sincronização:\n%s</string>
<string name="sync_SPr_interval_title">Sincronização em segundo plano</string>
<string name="sync_SPr_forget">Sair</string>
<string name="sync_SPr_forget_description">Remove todos os dados de sincronização</string>
<string name="sync_forget_confirm">Sair/limpar dados de sincronização?</string>
<string name="widget_show_due_date">Mostrar datas limite</string>
<string name="widget_show_checkboxes">Mostrar caixas de seleção</string>
<string name="widget_show_header">Mostrar cabeçalho</string>

@ -298,11 +298,7 @@
<string name="tmrw">Завт</string>
<string name="yest">Вчера</string>
<string name="DLG_wait">Пожалуйста, подождите…</string>
<string name="sync_status_success">Последняя синхр.:\n%s</string>
<string name="sync_SPr_interval_title">Фоновая синхр.</string>
<string name="sync_SPr_forget">Выйти</string>
<string name="sync_SPr_forget_description">Очищает все данные синхронизации</string>
<string name="sync_forget_confirm">Выйти и очистить данные синхронизации?</string>
<string name="widget_show_due_date">Показать даты</string>
<string name="widget_show_checkboxes">Показать флажки</string>
<string name="widget_show_header">Показать заголовок</string>

@ -298,11 +298,7 @@
<string name="tmrw">Zajtra</string>
<string name="yest">Včera</string>
<string name="DLG_wait">Prosím čakaj...</string>
<string name="sync_status_success">Posledná synchronizácia:\n%s</string>
<string name="sync_SPr_interval_title">Synchronizácia na pozadí</string>
<string name="sync_SPr_forget">Odhlásiť sa</string>
<string name="sync_SPr_forget_description">Vymaže všetky údaje synchronizácie</string>
<string name="sync_forget_confirm">Odhlásiť sa/vymazať údaje synchronizácie?</string>
<string name="widget_show_due_date">Ukázať dátumy vypršania </string>
<string name="widget_show_checkboxes">Ukázať zaškrtávacie políčka </string>
<string name="widget_show_header">Ukázať záhlavia </string>

@ -187,10 +187,6 @@
<string name="tmrw">Jutr</string>
<string name="yest">Včer</string>
<string name="DLG_wait">Prosimo, počakajte...</string>
<string name="sync_status_success">Najnovejše usklajevanje:\n%s</string>
<string name="sync_SPr_interval_title">Usklajevanje v ozadju</string>
<string name="sync_SPr_forget">Odjava</string>
<string name="sync_SPr_forget_description">Zbriše vse usklajene podatke</string>
<string name="sync_forget_confirm">Odjava/brisanje usklajenih podatkov?</string>
<string name="TLA_menu_donate">Donirajte</string>
</resources>

@ -223,11 +223,7 @@
<string name="tmrw">imorn</string>
<string name="yest">Igår</string>
<string name="DLG_wait">Var god vänta...</string>
<string name="sync_status_success">Synkroniserades senast:\n%s</string>
<string name="sync_SPr_interval_title">Bakgrundssynkronisering</string>
<string name="sync_SPr_forget">Logga ut</string>
<string name="sync_SPr_forget_description">Rensar alla synkroniseringsdata</string>
<string name="sync_forget_confirm">Logga ut / rensa synkroniseringsdata?</string>
<string name="widget_show_due_date">Visa förfallodatum</string>
<string name="widget_show_checkboxes">Visa kryssrutor</string>
<string name="widget_show_header">Visa rubrik</string>

@ -302,11 +302,7 @@
<string name="tmrw">Yarın</string>
<string name="yest">Dün</string>
<string name="DLG_wait">Lütfen bekleyin...</string>
<string name="sync_status_success">Son eşzamanlama:\n%s</string>
<string name="sync_SPr_interval_title">Arka planda eşzamanla</string>
<string name="sync_SPr_forget">Çıkış Yap</string>
<string name="sync_SPr_forget_description">Tüm eşzamanlama verilerini temizle</string>
<string name="sync_forget_confirm">Çıkış yap/eşzamanlama verisini temizle?</string>
<string name="widget_show_due_date">Bitiş tarihlerini göster</string>
<string name="widget_show_checkboxes">Onay kutularını göster</string>
<string name="widget_show_header">Başlığı göster</string>

@ -226,11 +226,7 @@
<string name="tmrw">Звтр</string>
<string name="yest">Вчр</string>
<string name="DLG_wait">Будь ласка, зачекайте...</string>
<string name="sync_status_success">Остання синхр.:\n%s</string>
<string name="sync_SPr_interval_title">Фонова синхронізація</string>
<string name="sync_SPr_forget">Вийти</string>
<string name="sync_SPr_forget_description">Очищує всю синхронізовану інформацію</string>
<string name="sync_forget_confirm">Вийти/очистити синхронізовану інофрмацію?</string>
<string name="widget_show_due_date">Показувати дату виконання</string>
<string name="widget_show_checkboxes">Показати галочки</string>
<string name="widget_show_header">Показати заголовок</string>

@ -297,11 +297,7 @@
<string name="tmrw">明天</string>
<string name="yest">昨天</string>
<string name="DLG_wait">请稍候...</string>
<string name="sync_status_success">上次同步:\n%s</string>
<string name="sync_SPr_interval_title">后台同步</string>
<string name="sync_SPr_forget">登出</string>
<string name="sync_SPr_forget_description">清除所有同步资料</string>
<string name="sync_forget_confirm">登出/清除同步资料?</string>
<string name="widget_show_due_date">显示截止日期</string>
<string name="widget_show_checkboxes">显示复选框</string>
<string name="widget_show_header">显示标题</string>

@ -189,11 +189,7 @@
<string name="tmrw">明天</string>
<string name="yest">昨天</string>
<string name="DLG_wait">請稍候...</string>
<string name="sync_status_success">上次同步:\n%s</string>
<string name="sync_SPr_interval_title">後台同步</string>
<string name="sync_SPr_forget">登出</string>
<string name="sync_SPr_forget_description">清除所有同步資料</string>
<string name="sync_forget_confirm">登出/清除同步資料?</string>
<string name="widget_show_due_date">顯示到期日</string>
<string name="widget_show_checkboxes">顯示核取方塊</string>
<string name="widget_show_header">顯示標頭</string>

@ -149,10 +149,6 @@
<!-- on calendar end at dealline if true, start at deadline if false -->
<string name="p_end_at_deadline">p_end_at_deadline</string>
<!-- ============================================================ SYNC == -->
<string name="sync_SPr_forget_key">sync_forget</string>
<!-- ============================================================ OTHER == -->
<!-- Default Calendar Preference Key (do not translate) -->
@ -187,7 +183,6 @@
<string name="TEA_ctrl_comments">TEA_ctrl_comments</string>
<string name="TEA_ctrl_gcal">TEA_ctrl_gcal</string>
<string name="TEA_ctrl_google_task_list">TEA_ctrl_gtask</string>
<string name="sync_gtasks">sync_gtasks</string>
<string name="p_geofence_radius">geolocation_radius</string>
<string name="p_geofence_responsiveness">geofence_responsiveness</string>
<string name="p_show_hidden_tasks">show_hidden_tasks</string>
@ -242,7 +237,6 @@
<string name="tracking_action_delete_list">Delete List</string>
<string name="tracking_action_on">On</string>
<string name="tracking_action_off">Off</string>
<string name="tracking_action_clear">Clear</string>
<string name="tracking_action_clear_completed">Clear completed</string>
<string name="tracking_action_custom">Custom</string>
<string name="tracking_action_preset">Preset</string>

@ -669,20 +669,9 @@ File %1$s contained %2$s.\n\n
<!-- ================================================== SyncPreferences == -->
<!-- Sync Status: success status (%s -> last sync date). Keep it short!-->
<string name="sync_status_success">Last sync:\n%s</string>
<!-- Preference: Synchronization Interval Title -->
<string name="sync_SPr_interval_title">Background sync</string>
<!-- Sync: Clear Data Title -->
<string name="sync_SPr_forget">Log out</string>
<!-- Sync: Clear Data Description -->
<string name="sync_SPr_forget_description">Clears all synchronization data</string>
<!-- confirmation dialog for sync log out -->
<string name="sync_forget_confirm">Log out/clear synchronization data?</string>
<string name="widget_show_due_date">Show due dates</string>
<string name="widget_show_checkboxes">Show checkboxes</string>
<string name="widget_show_header">Show header</string>
@ -877,7 +866,6 @@ File %1$s contained %2$s.\n\n
<string name="tasker_list_notification">List notification</string>
<string name="help">Help</string>
<string name="caldav_home_set_not_found">Home set not found</string>
<string name="caldav_no_supported_calendars">Could not find any calendars with VTODO support</string>
<string name="network_error">Connection failed</string>
<string name="background_sync_unmetered_only">Only on unmetered connections</string>
<string name="upgrade">Upgrade</string>

@ -6,21 +6,9 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/synchronization">
<PreferenceCategory android:title="@string/gtasks_GPr_header">
<com.todoroo.astrid.ui.MultilineCheckboxPreference
android:defaultValue="false"
android:key="@string/sync_gtasks"
android:title="@string/enabled"/>
<com.todoroo.astrid.ui.MultilinePreference
android:dependency="@string/sync_gtasks"
android:key="@string/sync_SPr_forget_key"
android:summary="@string/sync_SPr_forget_description"
android:title="@string/sync_SPr_forget">
</com.todoroo.astrid.ui.MultilinePreference>
</PreferenceCategory>
<PreferenceCategory
android:key="@string/gtasks_GPr_header"
android:title="@string/gtasks_GPr_header"/>
<PreferenceCategory
android:key="@string/CalDAV"

Loading…
Cancel
Save