Use coroutines in task creator

pull/1055/head
Alex Baker 5 years ago
parent 6e6fb3eada
commit c3c5de1e5c

@ -9,9 +9,10 @@ import com.todoroo.astrid.data.Task
import com.todoroo.astrid.utility.TitleParser import com.todoroo.astrid.utility.TitleParser
import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltAndroidTest
import dagger.hilt.android.testing.UninstallModules import dagger.hilt.android.testing.UninstallModules
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
import org.tasks.data.TagDataDaoBlocking import org.tasks.data.TagDataDao
import org.tasks.injection.InjectingTestCase import org.tasks.injection.InjectingTestCase
import org.tasks.injection.ProductionModule import org.tasks.injection.ProductionModule
import java.util.* import java.util.*
@ -21,7 +22,7 @@ import javax.inject.Inject
@HiltAndroidTest @HiltAndroidTest
class QuickAddMarkupTest : InjectingTestCase() { class QuickAddMarkupTest : InjectingTestCase() {
private val tags = ArrayList<String>() private val tags = ArrayList<String>()
@Inject lateinit var tagDataDao: TagDataDaoBlocking @Inject lateinit var tagDataDao: TagDataDao
private var task: Task? = null private var task: Task? = null
@ -81,7 +82,7 @@ class QuickAddMarkupTest : InjectingTestCase() {
assertEquals(title, task!!.title) assertEquals(title, task!!.title)
} }
private fun whenTitleIs(title: String) { private fun whenTitleIs(title: String) = runBlocking {
task = Task() task = Task()
task!!.title = title task!!.title = title
tags.clear() tags.clear()

@ -11,11 +11,12 @@ import com.todoroo.astrid.data.Task
import com.todoroo.astrid.utility.TitleParser import com.todoroo.astrid.utility.TitleParser
import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltAndroidTest
import dagger.hilt.android.testing.UninstallModules import dagger.hilt.android.testing.UninstallModules
import kotlinx.coroutines.runBlocking
import org.junit.Assert.* import org.junit.Assert.*
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.tasks.R import org.tasks.R
import org.tasks.data.TagDataDaoBlocking import org.tasks.data.TagDataDao
import org.tasks.date.DateTimeUtils import org.tasks.date.DateTimeUtils
import org.tasks.injection.InjectingTestCase import org.tasks.injection.InjectingTestCase
import org.tasks.injection.ProductionModule import org.tasks.injection.ProductionModule
@ -26,7 +27,7 @@ import javax.inject.Inject
@UninstallModules(ProductionModule::class) @UninstallModules(ProductionModule::class)
@HiltAndroidTest @HiltAndroidTest
class TitleParserTest : InjectingTestCase() { class TitleParserTest : InjectingTestCase() {
@Inject lateinit var tagDataDao: TagDataDaoBlocking @Inject lateinit var tagDataDao: TagDataDao
@Inject lateinit var preferences: Preferences @Inject lateinit var preferences: Preferences
@Inject lateinit var taskCreator: TaskCreator @Inject lateinit var taskCreator: TaskCreator
@ -41,7 +42,7 @@ class TitleParserTest : InjectingTestCase() {
* repeat, no lists * repeat, no lists
*/ */
@Test @Test
fun testNoRegexes() { fun testNoRegexes() = runBlocking {
val task = taskCreator.basicQuickAddTask("Jog") val task = taskCreator.basicQuickAddTask("Jog")
val nothing = Task() val nothing = Task()
assertFalse(task.hasDueTime()) assertFalse(task.hasDueTime())
@ -147,13 +148,13 @@ class TitleParserTest : InjectingTestCase() {
} }
} }
private fun insertTitleAddTask(title: String): Task { private fun insertTitleAddTask(title: String): Task = runBlocking {
return taskCreator.createWithValues(title) taskCreator.createWithValues(title)
} }
// ----------------Days begin----------------// // ----------------Days begin----------------//
@Test @Test
fun testDays() { fun testDays() = runBlocking {
val today = Calendar.getInstance() val today = Calendar.getInstance()
var title = "Jog today" var title = "Jog today"
var task = taskCreator.createWithValues(title) var task = taskCreator.createWithValues(title)
@ -182,7 +183,7 @@ class TitleParserTest : InjectingTestCase() {
// ----------------Priority begin----------------// // ----------------Priority begin----------------//
/** tests all words using priority 0 */ /** tests all words using priority 0 */
@Test @Test
fun testPriority0() { fun testPriority0() = runBlocking {
val acceptedStrings = arrayOf("priority 0", "least priority", "lowest priority", "bang 0") val acceptedStrings = arrayOf("priority 0", "least priority", "lowest priority", "bang 0")
for (acceptedString in acceptedStrings) { for (acceptedString in acceptedStrings) {
val title = "Jog $acceptedString" val title = "Jog $acceptedString"
@ -197,7 +198,7 @@ class TitleParserTest : InjectingTestCase() {
} }
@Test @Test
fun testPriority1() { fun testPriority1() = runBlocking {
val acceptedStringsAtEnd = arrayOf("priority 1", "low priority", "bang", "bang 1") val acceptedStringsAtEnd = arrayOf("priority 1", "low priority", "bang", "bang 1")
val acceptedStringsAnywhere = arrayOf("!1", "!") val acceptedStringsAnywhere = arrayOf("!1", "!")
var task: Task var task: Task
@ -222,7 +223,7 @@ class TitleParserTest : InjectingTestCase() {
} }
@Test @Test
fun testPriority2() { fun testPriority2() = runBlocking {
val acceptedStringsAtEnd = arrayOf("priority 2", "high priority", "bang bang", "bang 2") val acceptedStringsAtEnd = arrayOf("priority 2", "high priority", "bang bang", "bang 2")
val acceptedStringsAnywhere = arrayOf("!2", "!!") val acceptedStringsAnywhere = arrayOf("!2", "!!")
for (acceptedStringAtEnd in acceptedStringsAtEnd) { for (acceptedStringAtEnd in acceptedStringsAtEnd) {
@ -244,7 +245,7 @@ class TitleParserTest : InjectingTestCase() {
} }
@Test @Test
fun testPriority3() { fun testPriority3() = runBlocking {
val acceptedStringsAtEnd = arrayOf( val acceptedStringsAtEnd = arrayOf(
"priority 3", "priority 3",
"highest priority", "highest priority",
@ -274,7 +275,7 @@ class TitleParserTest : InjectingTestCase() {
// ----------------Repeats begin----------------// // ----------------Repeats begin----------------//
/** test daily repeat from due date, but with no due date set */ /** test daily repeat from due date, but with no due date set */
@Test @Test
fun testDailyWithNoDueDate() { fun testDailyWithNoDueDate() = runBlocking {
var title = "Jog daily" var title = "Jog daily"
var task = taskCreator.createWithValues(title) var task = taskCreator.createWithValues(title)
val rrule = RRule() val rrule = RRule()
@ -300,7 +301,7 @@ class TitleParserTest : InjectingTestCase() {
/** test weekly repeat from due date, with no due date & time set */ /** test weekly repeat from due date, with no due date & time set */
@Test @Test
fun testWeeklyWithNoDueDate() { fun testWeeklyWithNoDueDate() = runBlocking {
var title = "Jog weekly" var title = "Jog weekly"
var task = taskCreator.createWithValues(title) var task = taskCreator.createWithValues(title)
val rrule = RRule() val rrule = RRule()
@ -326,7 +327,7 @@ class TitleParserTest : InjectingTestCase() {
/** test hourly repeat from due date, with no due date but no time */ /** test hourly repeat from due date, with no due date but no time */
@Test @Test
fun testMonthlyFromNoDueDate() { fun testMonthlyFromNoDueDate() = runBlocking {
var title = "Jog monthly" var title = "Jog monthly"
var task = taskCreator.createWithValues(title) var task = taskCreator.createWithValues(title)
val rrule = RRule() val rrule = RRule()
@ -351,7 +352,7 @@ class TitleParserTest : InjectingTestCase() {
} }
@Test @Test
fun testDailyFromDueDate() { fun testDailyFromDueDate() = runBlocking {
var title = "Jog daily starting from today" var title = "Jog daily starting from today"
var task = taskCreator.createWithValues(title) var task = taskCreator.createWithValues(title)
val rrule = RRule() val rrule = RRule()
@ -373,7 +374,7 @@ class TitleParserTest : InjectingTestCase() {
} }
@Test @Test
fun testWeeklyFromDueDate() { fun testWeeklyFromDueDate() = runBlocking {
var title = "Jog weekly starting from today" var title = "Jog weekly starting from today"
var task = taskCreator.createWithValues(title) var task = taskCreator.createWithValues(title)
val rrule = RRule() val rrule = RRule()
@ -397,7 +398,7 @@ class TitleParserTest : InjectingTestCase() {
// ----------------Tags begin----------------// // ----------------Tags begin----------------//
/** tests all words using priority 0 */ /** tests all words using priority 0 */
@Test @Test
fun testTagsPound() { fun testTagsPound() = runBlocking {
val acceptedStrings = arrayOf("#tag", "#a", "#(a cool tag)", "#(cool)") val acceptedStrings = arrayOf("#tag", "#a", "#(a cool tag)", "#(cool)")
var task: Task var task: Task
for (acceptedString in acceptedStrings) { for (acceptedString in acceptedStrings) {
@ -414,7 +415,7 @@ class TitleParserTest : InjectingTestCase() {
/** tests all words using priority 0 */ /** tests all words using priority 0 */
@Test @Test
fun testTagsAt() { fun testTagsAt() = runBlocking {
val acceptedStrings = arrayOf("@tag", "@a", "@(a cool tag)", "@(cool)") val acceptedStrings = arrayOf("@tag", "@a", "@(a cool tag)", "@(cool)")
var task: Task var task: Task
for (acceptedString in acceptedStrings) { for (acceptedString in acceptedStrings) {

@ -148,7 +148,7 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
navigationDrawer.closeDrawer() navigationDrawer.closeDrawer()
} }
private fun getTaskToLoad(filter: Filter?): Task? { private suspend fun getTaskToLoad(filter: Filter?): Task? {
val intent = intent val intent = intent
if (intent.isFromHistory) { if (intent.isFromHistory) {
return null return null
@ -165,7 +165,7 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
return null return null
} }
private fun openTask(filter: Filter?) { private fun openTask(filter: Filter?) = lifecycleScope.launch {
val task = getTaskToLoad(filter) val task = getTaskToLoad(filter)
when { when {
task != null -> onTaskListItemClicked(task) task != null -> onTaskListItemClicked(task)
@ -344,12 +344,11 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
private val nightMode: Int private val nightMode: Int
get() = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK get() = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
override fun onTaskListItemClicked(task: Task?) { override suspend fun onTaskListItemClicked(task: Task?) {
AndroidUtilities.assertMainThread() AndroidUtilities.assertMainThread()
if (task == null) { if (task == null) {
return return
} }
lifecycleScope.launchWhenResumed {
taskEditFragment?.let { taskEditFragment?.let {
it.editViewModel.cleared.removeObservers(this@MainActivity) it.editViewModel.cleared.removeObservers(this@MainActivity)
it.save() it.save()
@ -368,7 +367,6 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
.commit() .commit()
showDetailFragment() showDetailFragment()
} }
}
override fun onNavigationIconClicked() { override fun onNavigationIconClicked() {
hideKeyboard() hideKeyboard()

@ -4,12 +4,14 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import com.google.common.collect.Lists import com.google.common.collect.Lists
import com.google.common.io.Files import com.google.common.io.Files
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import com.todoroo.astrid.service.TaskCreator import com.todoroo.astrid.service.TaskCreator
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.launch
import org.tasks.Strings.isNullOrEmpty import org.tasks.Strings.isNullOrEmpty
import org.tasks.data.TaskAttachment import org.tasks.data.TaskAttachment
import org.tasks.files.FileHelper import org.tasks.files.FileHelper
@ -35,13 +37,16 @@ class ShareLinkActivity : InjectingAppCompatActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val intent = intent val intent = intent
val action = intent.action val action = intent.action
if (Intent.ACTION_PROCESS_TEXT == action) { when {
Intent.ACTION_PROCESS_TEXT == action -> lifecycleScope.launch {
val text = intent.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT) val text = intent.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT)
if (text != null) { if (text != null) {
val task = taskCreator.createWithValues(text.toString()) val task = taskCreator.createWithValues(text.toString())
editTask(task) editTask(task)
} }
} else if (Intent.ACTION_SEND == action) { finish()
}
Intent.ACTION_SEND == action -> lifecycleScope.launch {
val subject = intent.getStringExtra(Intent.EXTRA_SUBJECT) val subject = intent.getStringExtra(Intent.EXTRA_SUBJECT)
val task = taskCreator.createWithValues(subject) val task = taskCreator.createWithValues(subject)
task.notes = intent.getStringExtra(Intent.EXTRA_TEXT) task.notes = intent.getStringExtra(Intent.EXTRA_TEXT)
@ -49,18 +54,23 @@ class ShareLinkActivity : InjectingAppCompatActivity() {
task.putTransitory(TaskAttachment.KEY, copyAttachment(intent)) task.putTransitory(TaskAttachment.KEY, copyAttachment(intent))
} }
editTask(task) editTask(task)
} else if (Intent.ACTION_SEND_MULTIPLE == action) { finish()
}
Intent.ACTION_SEND_MULTIPLE == action -> lifecycleScope.launch {
val task = taskCreator.createWithValues(intent.getStringExtra(Intent.EXTRA_SUBJECT)) val task = taskCreator.createWithValues(intent.getStringExtra(Intent.EXTRA_SUBJECT))
task.notes = intent.getStringExtra(Intent.EXTRA_TEXT) task.notes = intent.getStringExtra(Intent.EXTRA_TEXT)
if (hasAttachments(intent)) { if (hasAttachments(intent)) {
task.putTransitory(TaskAttachment.KEY, copyMultipleAttachments(intent)) task.putTransitory(TaskAttachment.KEY, copyMultipleAttachments(intent))
} }
editTask(task) editTask(task)
} else { finish()
Timber.e("Unhandled intent: %s", intent)
} }
else -> {
Timber.e("Unhandled intent: %s", intent)
finish() finish()
} }
}
}
private fun editTask(task: Task) { private fun editTask(task: Task) {
val intent = TaskIntents.getEditTaskIntent(this, null, task) val intent = TaskIntents.getEditTaskIntent(this, null, task)

@ -420,11 +420,13 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
@OnClick(R.id.fab) @OnClick(R.id.fab)
fun createNewTask() { fun createNewTask() {
lifecycleScope.launch {
shortcutManager.reportShortcutUsed(ShortcutManager.SHORTCUT_NEW_TASK) shortcutManager.reportShortcutUsed(ShortcutManager.SHORTCUT_NEW_TASK)
onTaskListItemClicked(addTask("")) onTaskListItemClicked(addTask(""))
} }
}
private fun addTask(title: String): Task { private suspend fun addTask(title: String): Task {
return taskCreator.createWithValues(filter, title) return taskCreator.createWithValues(filter, title)
} }
@ -517,6 +519,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) { when (requestCode) {
VOICE_RECOGNITION_REQUEST_CODE -> if (resultCode == Activity.RESULT_OK) { VOICE_RECOGNITION_REQUEST_CODE -> if (resultCode == Activity.RESULT_OK) {
lifecycleScope.launch {
val match: List<String>? = data!!.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS) val match: List<String>? = data!!.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)
if (match != null && match.isNotEmpty() && match[0].isNotEmpty()) { if (match != null && match.isNotEmpty() && match[0].isNotEmpty()) {
var recognizedSpeech = match[0] var recognizedSpeech = match[0]
@ -525,6 +528,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
onTaskListItemClicked(addTask(recognizedSpeech)) onTaskListItemClicked(addTask(recognizedSpeech))
} }
} }
}
REQUEST_MOVE_TASKS -> if (resultCode == Activity.RESULT_OK) { REQUEST_MOVE_TASKS -> if (resultCode == Activity.RESULT_OK) {
lifecycleScope.launch { lifecycleScope.launch {
taskMover.move( taskMover.move(
@ -560,7 +564,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
return onOptionsItemSelected(item) return onOptionsItemSelected(item)
} }
fun onTaskListItemClicked(task: Task?) { fun onTaskListItemClicked(task: Task?) = lifecycleScope.launch {
callbacks.onTaskListItemClicked(task) callbacks.onTaskListItemClicked(task)
} }
@ -712,7 +716,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
} }
interface TaskListFragmentCallbackHandler { interface TaskListFragmentCallbackHandler {
fun onTaskListItemClicked(task: Task?) suspend fun onTaskListItemClicked(task: Task?)
fun onNavigationIconClicked() fun onNavigationIconClicked()
} }

@ -5,7 +5,7 @@ import com.todoroo.astrid.api.CaldavFilter
import com.todoroo.astrid.api.Filter import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.GtasksFilter import com.todoroo.astrid.api.GtasksFilter
import com.todoroo.astrid.api.PermaSql import com.todoroo.astrid.api.PermaSql
import com.todoroo.astrid.dao.TaskDaoBlocking import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import com.todoroo.astrid.data.Task.Companion.createDueDate import com.todoroo.astrid.data.Task.Companion.createDueDate
import com.todoroo.astrid.gcal.GCalHelper import com.todoroo.astrid.gcal.GCalHelper
@ -23,14 +23,15 @@ import javax.inject.Inject
class TaskCreator @Inject constructor( class TaskCreator @Inject constructor(
private val gcalHelper: GCalHelper, private val gcalHelper: GCalHelper,
private val preferences: Preferences, private val preferences: Preferences,
private val tagDataDao: TagDataDaoBlocking, private val tagDataDao: TagDataDao,
private val taskDao: TaskDaoBlocking, private val taskDao: TaskDao,
private val tagDao: TagDaoBlocking, private val tagDao: TagDao,
private val googleTaskDao: GoogleTaskDaoBlocking, private val googleTaskDao: GoogleTaskDao,
private val defaultFilterProvider: DefaultFilterProvider, private val defaultFilterProvider: DefaultFilterProvider,
private val caldavDao: CaldavDaoBlocking, private val caldavDao: CaldavDao,
private val locationDao: LocationDaoBlocking) { private val locationDao: LocationDao) {
fun basicQuickAddTask(title: String): Task {
suspend fun basicQuickAddTask(title: String): Task {
var title = title var title = title
title = title.trim { it <= ' ' } title = title.trim { it <= ' ' }
val task = createWithValues(title) val task = createWithValues(title)
@ -51,7 +52,7 @@ class TaskCreator @Inject constructor(
caldavDao.insert( caldavDao.insert(
task, CaldavTask(task.id, task.getTransitory<String>(CaldavTask.KEY)), addToTop) task, CaldavTask(task.id, task.getTransitory<String>(CaldavTask.KEY)), addToTop)
} else { } else {
val remoteList = defaultFilterProvider.defaultList val remoteList = defaultFilterProvider.getDefaultList()
if (remoteList is GtasksFilter) { if (remoteList is GtasksFilter) {
googleTaskDao.insertAndShift( googleTaskDao.insertAndShift(
GoogleTask(task.id, remoteList.remoteId), addToTop) GoogleTask(task.id, remoteList.remoteId), addToTop)
@ -70,11 +71,11 @@ class TaskCreator @Inject constructor(
return task return task
} }
fun createWithValues(title: String?): Task { suspend fun createWithValues(title: String?): Task {
return create(null, title) return create(null, title)
} }
fun createWithValues(filter: Filter?, title: String?): Task { suspend fun createWithValues(filter: Filter?, title: String?): Task {
return create(filter?.valuesForNewTasks, title) return create(filter?.valuesForNewTasks, title)
} }
@ -82,7 +83,7 @@ class TaskCreator @Inject constructor(
* Create task from the given content values, saving it. This version doesn't need to start with a * Create task from the given content values, saving it. This version doesn't need to start with a
* base task model. * base task model.
*/ */
private fun create(values: Map<String, Any>?, title: String?): Task { private suspend fun create(values: Map<String, Any>?, title: String?): Task {
val task = Task() val task = Task()
task.creationDate = DateUtilities.now() task.creationDate = DateUtilities.now()
task.modificationDate = DateUtilities.now() task.modificationDate = DateUtilities.now()
@ -128,7 +129,7 @@ class TaskCreator @Inject constructor(
return task return task
} }
fun createTags(task: Task) { suspend fun createTags(task: Task) {
for (tag in task.tags) { for (tag in task.tags) {
var tagData = tagDataDao.getTagByName(tag) var tagData = tagDataDao.getTagByName(tag)
if (tagData == null) { if (tagData == null) {

@ -12,14 +12,14 @@ import com.mdimension.jchronic.Chronic
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import com.todoroo.astrid.data.Task.Companion.createDueDate import com.todoroo.astrid.data.Task.Companion.createDueDate
import org.tasks.Strings.isNullOrEmpty import org.tasks.Strings.isNullOrEmpty
import org.tasks.data.TagDataDaoBlocking import org.tasks.data.TagDataDao
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import java.util.regex.Matcher import java.util.regex.Matcher
import java.util.regex.Pattern import java.util.regex.Pattern
object TitleParser { object TitleParser {
fun parse(tagDataDao: TagDataDaoBlocking, task: Task, tags: ArrayList<String>) { suspend fun parse(tagDataDao: TagDataDao, task: Task, tags: ArrayList<String>) {
repeatHelper(task) repeatHelper(task)
listHelper( listHelper(
tagDataDao, tagDataDao,
@ -39,7 +39,7 @@ object TitleParser {
} else pattern } else pattern
} }
fun listHelper(tagDataDao: TagDataDaoBlocking, task: Task, tags: ArrayList<String>) { suspend fun listHelper(tagDataDao: TagDataDao, task: Task, tags: ArrayList<String>) {
var inputText = task.title var inputText = task.title
val tagPattern = Pattern.compile("(\\s|^)#(\\(.*\\)|[^\\s]+)") val tagPattern = Pattern.compile("(\\s|^)#(\\(.*\\)|[^\\s]+)")
val contextPattern = Pattern.compile("(\\s|^)@(\\(.*\\)|[^\\s]+)") val contextPattern = Pattern.compile("(\\s|^)@(\\(.*\\)|[^\\s]+)")

@ -118,8 +118,8 @@ class SubtaskControlSet : TaskEditControlFragment(), SubtaskViewHolder.Callbacks
fun addSubtask() { fun addSubtask() {
if (isGoogleTaskChild) { if (isGoogleTaskChild) {
toaster.longToast(R.string.subtasks_multilevel_google_task) toaster.longToast(R.string.subtasks_multilevel_google_task)
return } else {
} lifecycleScope.launch {
val task = taskCreator.createWithValues("") val task = taskCreator.createWithValues("")
viewModel.newSubtasks.add(task) viewModel.newSubtasks.add(task)
val editText = addSubtask(task) val editText = addSubtask(task)
@ -127,6 +127,8 @@ class SubtaskControlSet : TaskEditControlFragment(), SubtaskViewHolder.Callbacks
val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT) imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT)
} }
}
}
private fun addSubtask(task: Task): EditText { private fun addSubtask(task: Task): EditText {
val view = LayoutInflater.from(activity) val view = LayoutInflater.from(activity)

Loading…
Cancel
Save