mirror of https://github.com/tasks/tasks
Convert SubtasksHelper to Kotlin
parent
3d917fda62
commit
8487526171
@ -1,165 +0,0 @@
|
|||||||
package com.todoroo.astrid.subtasks;
|
|
||||||
|
|
||||||
import static org.tasks.Strings.isNullOrEmpty;
|
|
||||||
import static org.tasks.db.QueryUtils.showHiddenAndCompleted;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import com.todoroo.astrid.api.Filter;
|
|
||||||
import com.todoroo.astrid.core.BuiltInFilterExposer;
|
|
||||||
import com.todoroo.astrid.dao.TaskDaoBlocking;
|
|
||||||
import com.todoroo.astrid.data.Task;
|
|
||||||
import com.todoroo.astrid.subtasks.SubtasksFilterUpdater.Node;
|
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import org.tasks.data.TagData;
|
|
||||||
import org.tasks.data.TagDataDaoBlocking;
|
|
||||||
import org.tasks.data.TaskListMetadata;
|
|
||||||
import org.tasks.data.TaskListMetadataDaoBlocking;
|
|
||||||
import org.tasks.preferences.Preferences;
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
public class SubtasksHelper {
|
|
||||||
|
|
||||||
private final Context context;
|
|
||||||
private final Preferences preferences;
|
|
||||||
private final TaskDaoBlocking taskDao;
|
|
||||||
private final TagDataDaoBlocking tagDataDao;
|
|
||||||
private final TaskListMetadataDaoBlocking taskListMetadataDao;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public SubtasksHelper(
|
|
||||||
@ApplicationContext Context context,
|
|
||||||
Preferences preferences,
|
|
||||||
TaskDaoBlocking taskDao,
|
|
||||||
TagDataDaoBlocking tagDataDao,
|
|
||||||
TaskListMetadataDaoBlocking taskListMetadataDao) {
|
|
||||||
this.context = context;
|
|
||||||
this.preferences = preferences;
|
|
||||||
this.taskDao = taskDao;
|
|
||||||
this.tagDataDao = tagDataDao;
|
|
||||||
this.taskListMetadataDao = taskListMetadataDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
private static List<Long> getIdList(String serializedTree) {
|
|
||||||
ArrayList<Long> ids = new ArrayList<>();
|
|
||||||
String[] digitsOnly =
|
|
||||||
serializedTree.split("[\\[\\],\\s]"); // Split on [ ] , or whitespace chars
|
|
||||||
for (String idString : digitsOnly) {
|
|
||||||
try {
|
|
||||||
if (!isNullOrEmpty(idString)) {
|
|
||||||
ids.add(Long.parseLong(idString));
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
Timber.e(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
static String[] getStringIdArray(String serializedTree) {
|
|
||||||
ArrayList<String> ids = new ArrayList<>();
|
|
||||||
String[] values = serializedTree.split("[\\[\\],\"\\s]"); // Split on [ ] , or whitespace chars
|
|
||||||
for (String idString : values) {
|
|
||||||
if (!isNullOrEmpty(idString)) {
|
|
||||||
ids.add(idString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ids.toArray(new String[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Takes a subtasks string containing local ids and remaps it to one containing UUIDs */
|
|
||||||
public static String convertTreeToRemoteIds(TaskDaoBlocking taskDao, String localTree) {
|
|
||||||
List<Long> localIds = getIdList(localTree);
|
|
||||||
Map<Long, String> idMap = getIdMap(taskDao, localIds);
|
|
||||||
idMap.put(-1L, "-1"); // $NON-NLS-1$
|
|
||||||
|
|
||||||
Node tree = SubtasksFilterUpdater.buildTreeModel(localTree, null);
|
|
||||||
remapLocalTreeToRemote(tree, idMap);
|
|
||||||
return SubtasksFilterUpdater.serializeTree(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void remapTree(Node root, Map<Long, String> idMap, TreeRemapHelper helper) {
|
|
||||||
ArrayList<Node> children = root.children;
|
|
||||||
for (int i = 0; i < children.size(); i++) {
|
|
||||||
Node child = children.get(i);
|
|
||||||
Long key = helper.getKeyFromOldUuid(child.uuid);
|
|
||||||
String uuid = idMap.get(key);
|
|
||||||
if (!Task.isValidUuid(uuid)) {
|
|
||||||
children.remove(i);
|
|
||||||
children.addAll(i, child.children);
|
|
||||||
i--;
|
|
||||||
} else {
|
|
||||||
child.uuid = uuid;
|
|
||||||
remapTree(child, idMap, helper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void remapLocalTreeToRemote(Node root, Map<Long, String> idMap) {
|
|
||||||
remapTree(
|
|
||||||
root,
|
|
||||||
idMap,
|
|
||||||
uuid -> {
|
|
||||||
long localId = -1L;
|
|
||||||
try {
|
|
||||||
localId = Long.parseLong(uuid);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
Timber.e(e);
|
|
||||||
}
|
|
||||||
return localId;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<Long, String> getIdMap(TaskDaoBlocking taskDao, List<Long> keys) {
|
|
||||||
List<Task> tasks = taskDao.fetch(keys);
|
|
||||||
Map<Long, String> map = new HashMap<>();
|
|
||||||
for (Task task : tasks) {
|
|
||||||
map.put(task.getId(), task.getUuid());
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String applySubtasksToWidgetFilter(Filter filter, String query) {
|
|
||||||
if (filter.supportsAstridSorting() && preferences.isAstridSort()) {
|
|
||||||
TagData tagData = tagDataDao.getTagByName(filter.listingTitle);
|
|
||||||
TaskListMetadata tlm = null;
|
|
||||||
if (tagData != null) {
|
|
||||||
tlm = taskListMetadataDao.fetchByTagOrFilter(tagData.getRemoteId());
|
|
||||||
} else if (BuiltInFilterExposer.isInbox(context, filter)) {
|
|
||||||
tlm = taskListMetadataDao.fetchByTagOrFilter(TaskListMetadata.FILTER_ID_ALL);
|
|
||||||
} else if (BuiltInFilterExposer.isTodayFilter(context, filter)) {
|
|
||||||
tlm = taskListMetadataDao.fetchByTagOrFilter(TaskListMetadata.FILTER_ID_TODAY);
|
|
||||||
}
|
|
||||||
if (tlm != null) {
|
|
||||||
query = query.replaceAll("ORDER BY .*", "");
|
|
||||||
query = query + String.format(" ORDER BY %s", getOrderString(tagData, tlm));
|
|
||||||
query = showHiddenAndCompleted(query);
|
|
||||||
filter.setFilterQueryOverride(query);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getOrderString(TagData tagData, TaskListMetadata tlm) {
|
|
||||||
String serialized;
|
|
||||||
if (tlm != null) {
|
|
||||||
serialized = tlm.getTaskIds();
|
|
||||||
} else if (tagData != null) {
|
|
||||||
serialized = convertTreeToRemoteIds(taskDao, tagData.getTagOrdering());
|
|
||||||
} else {
|
|
||||||
serialized = "[]"; // $NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
return SubtasksFilterUpdater.buildOrderString(getStringIdArray(serialized));
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TreeRemapHelper {
|
|
||||||
|
|
||||||
Long getKeyFromOldUuid(String uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,139 @@
|
|||||||
|
package com.todoroo.astrid.subtasks
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.todoroo.astrid.api.Filter
|
||||||
|
import com.todoroo.astrid.core.BuiltInFilterExposer.Companion.isInbox
|
||||||
|
import com.todoroo.astrid.core.BuiltInFilterExposer.Companion.isTodayFilter
|
||||||
|
import com.todoroo.astrid.dao.TaskDaoBlocking
|
||||||
|
import com.todoroo.astrid.data.Task.Companion.isValidUuid
|
||||||
|
import com.todoroo.astrid.subtasks.SubtasksFilterUpdater.Companion.buildOrderString
|
||||||
|
import com.todoroo.astrid.subtasks.SubtasksFilterUpdater.Companion.buildTreeModel
|
||||||
|
import com.todoroo.astrid.subtasks.SubtasksFilterUpdater.Companion.serializeTree
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import org.tasks.Strings.isNullOrEmpty
|
||||||
|
import org.tasks.data.TagData
|
||||||
|
import org.tasks.data.TagDataDaoBlocking
|
||||||
|
import org.tasks.data.TaskListMetadata
|
||||||
|
import org.tasks.data.TaskListMetadataDaoBlocking
|
||||||
|
import org.tasks.db.QueryUtils.showHiddenAndCompleted
|
||||||
|
import org.tasks.preferences.Preferences
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class SubtasksHelper @Inject constructor(
|
||||||
|
@param:ApplicationContext private val context: Context,
|
||||||
|
private val preferences: Preferences,
|
||||||
|
private val taskDao: TaskDaoBlocking,
|
||||||
|
private val tagDataDao: TagDataDaoBlocking,
|
||||||
|
private val taskListMetadataDao: TaskListMetadataDaoBlocking) {
|
||||||
|
fun applySubtasksToWidgetFilter(filter: Filter, query: String): String {
|
||||||
|
var query = query
|
||||||
|
if (filter.supportsAstridSorting() && preferences.isAstridSort) {
|
||||||
|
val tagData = tagDataDao.getTagByName(filter.listingTitle)
|
||||||
|
var tlm: TaskListMetadata? = null
|
||||||
|
if (tagData != null) {
|
||||||
|
tlm = taskListMetadataDao.fetchByTagOrFilter(tagData.remoteId!!)
|
||||||
|
} else if (isInbox(context, filter)) {
|
||||||
|
tlm = taskListMetadataDao.fetchByTagOrFilter(TaskListMetadata.FILTER_ID_ALL)
|
||||||
|
} else if (isTodayFilter(context, filter)) {
|
||||||
|
tlm = taskListMetadataDao.fetchByTagOrFilter(TaskListMetadata.FILTER_ID_TODAY)
|
||||||
|
}
|
||||||
|
if (tlm != null) {
|
||||||
|
query = query.replace("ORDER BY .*".toRegex(), "")
|
||||||
|
query += " ORDER BY ${getOrderString(tagData, tlm)}"
|
||||||
|
query = showHiddenAndCompleted(query)
|
||||||
|
filter.setFilterQueryOverride(query)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getOrderString(tagData: TagData?, tlm: TaskListMetadata?): String {
|
||||||
|
val serialized: String? = when {
|
||||||
|
tlm != null -> tlm.taskIds
|
||||||
|
tagData != null -> convertTreeToRemoteIds(taskDao, tagData.tagOrdering)
|
||||||
|
else -> "[]"
|
||||||
|
}
|
||||||
|
return buildOrderString(getStringIdArray(serialized))
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Deprecated("")
|
||||||
|
private fun getIdList(serializedTree: String?): List<Long> {
|
||||||
|
val ids = ArrayList<Long>()
|
||||||
|
val digitsOnly = serializedTree!!.split("[\\[\\],\\s]".toRegex()).toTypedArray() // Split on [ ] , or whitespace chars
|
||||||
|
for (idString in digitsOnly) {
|
||||||
|
try {
|
||||||
|
if (!isNullOrEmpty(idString)) {
|
||||||
|
ids.add(idString.toLong())
|
||||||
|
}
|
||||||
|
} catch (e: NumberFormatException) {
|
||||||
|
Timber.e(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ids
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getStringIdArray(serializedTree: String?): Array<String> {
|
||||||
|
val ids = ArrayList<String>()
|
||||||
|
val values = serializedTree!!.split("[\\[\\],\"\\s]".toRegex()).toTypedArray() // Split on [ ] , or whitespace chars
|
||||||
|
for (idString in values) {
|
||||||
|
if (!isNullOrEmpty(idString)) {
|
||||||
|
ids.add(idString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ids.toTypedArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Takes a subtasks string containing local ids and remaps it to one containing UUIDs */
|
||||||
|
fun convertTreeToRemoteIds(taskDao: TaskDaoBlocking, localTree: String?): String {
|
||||||
|
val localIds = getIdList(localTree)
|
||||||
|
val idMap = getIdMap(taskDao, localIds)
|
||||||
|
idMap[-1L] = "-1" // $NON-NLS-1$
|
||||||
|
val tree = buildTreeModel(localTree, null)
|
||||||
|
remapLocalTreeToRemote(tree, idMap)
|
||||||
|
return serializeTree(tree)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun remapTree(root: SubtasksFilterUpdater.Node, idMap: Map<Long, String>, helper: (String) -> Long) {
|
||||||
|
val children = root.children
|
||||||
|
var i = 0
|
||||||
|
while (i < children.size) {
|
||||||
|
val child = children[i]
|
||||||
|
val key = helper.invoke(child.uuid)
|
||||||
|
val uuid = idMap[key]
|
||||||
|
if (!isValidUuid(uuid!!)) {
|
||||||
|
children.removeAt(i)
|
||||||
|
children.addAll(i, child.children)
|
||||||
|
i--
|
||||||
|
} else {
|
||||||
|
child.uuid = uuid
|
||||||
|
remapTree(child, idMap, helper)
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun remapLocalTreeToRemote(root: SubtasksFilterUpdater.Node, idMap: Map<Long, String>) {
|
||||||
|
remapTree(root, idMap) { uuid: String ->
|
||||||
|
var localId = -1L
|
||||||
|
try {
|
||||||
|
localId = uuid.toLong()
|
||||||
|
} catch (e: NumberFormatException) {
|
||||||
|
Timber.e(e)
|
||||||
|
}
|
||||||
|
localId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getIdMap(taskDao: TaskDaoBlocking, keys: List<Long>): MutableMap<Long, String> {
|
||||||
|
val tasks = taskDao.fetch(keys)
|
||||||
|
val map: MutableMap<Long, String> = HashMap()
|
||||||
|
for (task in tasks) {
|
||||||
|
map[task.id] = task.uuid
|
||||||
|
}
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue