Remove ButterKnife

pull/1442/head
Alex Baker 5 years ago
parent f03135cbeb
commit 2fc38d0089

@ -188,9 +188,6 @@ dependencies {
implementation("androidx.paging:paging-runtime:2.1.2") implementation("androidx.paging:paging-runtime:2.1.2")
implementation("io.noties.markwon:core:${Versions.markwon}") implementation("io.noties.markwon:core:${Versions.markwon}")
kapt("com.jakewharton:butterknife-compiler:${Versions.butterknife}")
implementation("com.jakewharton:butterknife:${Versions.butterknife}")
debugImplementation("com.facebook.flipper:flipper:${Versions.flipper}") debugImplementation("com.facebook.flipper:flipper:${Versions.flipper}")
debugImplementation("com.facebook.flipper:flipper-network-plugin:${Versions.flipper}") debugImplementation("com.facebook.flipper:flipper-network-plugin:${Versions.flipper}")
debugImplementation("com.facebook.soloader:soloader:0.10.1") debugImplementation("com.facebook.soloader:soloader:0.10.1")
@ -246,7 +243,6 @@ dependencies {
androidTestImplementation("com.google.dagger:hilt-android-testing:${Versions.hilt}") androidTestImplementation("com.google.dagger:hilt-android-testing:${Versions.hilt}")
kaptAndroidTest("com.google.dagger:hilt-compiler:${Versions.hilt}") kaptAndroidTest("com.google.dagger:hilt-compiler:${Versions.hilt}")
kaptAndroidTest("androidx.hilt:hilt-compiler:${Versions.hilt_androidx}") kaptAndroidTest("androidx.hilt:hilt-compiler:${Versions.hilt_androidx}")
kaptAndroidTest("com.jakewharton:butterknife-compiler:${Versions.butterknife}")
androidTestImplementation("org.mockito:mockito-android:${Versions.mockito}") androidTestImplementation("org.mockito:mockito-android:${Versions.mockito}")
androidTestImplementation("com.natpryce:make-it-easy:${Versions.make_it_easy}") androidTestImplementation("com.natpryce:make-it-easy:${Versions.make_it_easy}")
androidTestImplementation("androidx.test:runner:${Versions.androidx_test}") androidTestImplementation("androidx.test:runner:${Versions.androidx_test}")

@ -383,18 +383,6 @@
license: The Apache Software License, Version 2.0 license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://kotlinlang.org/ url: https://kotlinlang.org/
- artifact: com.jakewharton:butterknife:+
name: ButterKnife
copyrightHolder: Jake Wharton
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/JakeWharton/butterknife/
- artifact: com.jakewharton:butterknife-annotations:+
name: ButterKnife Annotations
copyrightHolder: Jake Wharton
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/JakeWharton/butterknife/
- artifact: com.squareup.okhttp3:logging-interceptor:+ - artifact: com.squareup.okhttp3:logging-interceptor:+
name: OkHttp Logging Interceptor name: OkHttp Logging Interceptor
copyrightHolder: Square, Inc. copyrightHolder: Square, Inc.
@ -406,12 +394,6 @@
license: The Apache Software License, Version 2.0 license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://kotlinlang.org/ url: https://kotlinlang.org/
- artifact: com.jakewharton:butterknife-runtime:+
name: ButterKnife Runtime
copyrightHolder: Jake Wharton
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/JakeWharton/butterknife/
- artifact: io.grpc:grpc-context:+ - artifact: io.grpc:grpc-context:+
name: io.grpc:grpc-context name: io.grpc:grpc-context
copyrightHolder: The gRPC Authors copyrightHolder: The gRPC Authors

6
app/proguard.pro vendored

@ -9,12 +9,6 @@
public static *** i(...); public static *** i(...);
} }
# https://github.com/JakeWharton/butterknife/blob/581666a28022796fdd62caaf3420e621215abfda/butterknife/proguard-rules.txt
-keep public class * implements butterknife.Unbinder { public <init>(**, android.view.View); }
-keep class butterknife.*
-keepclasseswithmembernames class * { @butterknife.* <methods>; }
-keepclasseswithmembernames class * { @butterknife.* <fields>; }
# guava # guava
-dontwarn sun.misc.Unsafe -dontwarn sun.misc.Unsafe
-dontwarn java.lang.ClassValue -dontwarn java.lang.ClassValue

@ -912,34 +912,6 @@
"url": "https://kotlinlang.org/", "url": "https://kotlinlang.org/",
"libraryName": "org.jetbrains.kotlin:kotlin-stdlib-common" "libraryName": "org.jetbrains.kotlin:kotlin-stdlib-common"
}, },
{
"artifactId": {
"name": "butterknife",
"group": "com.jakewharton",
"version": "+"
},
"copyrightHolder": "Jake Wharton",
"copyrightStatement": "Copyright &copy; Jake Wharton. All rights reserved.",
"license": "The Apache Software License, Version 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt",
"normalizedLicense": "apache2",
"url": "https://github.com/JakeWharton/butterknife/",
"libraryName": "ButterKnife"
},
{
"artifactId": {
"name": "butterknife-annotations",
"group": "com.jakewharton",
"version": "+"
},
"copyrightHolder": "Jake Wharton",
"copyrightStatement": "Copyright &copy; Jake Wharton. All rights reserved.",
"license": "The Apache Software License, Version 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt",
"normalizedLicense": "apache2",
"url": "https://github.com/JakeWharton/butterknife/",
"libraryName": "ButterKnife Annotations"
},
{ {
"artifactId": { "artifactId": {
"name": "logging-interceptor", "name": "logging-interceptor",
@ -967,20 +939,6 @@
"url": "https://kotlinlang.org/", "url": "https://kotlinlang.org/",
"libraryName": "org.jetbrains.kotlin:kotlin-stdlib-jdk7" "libraryName": "org.jetbrains.kotlin:kotlin-stdlib-jdk7"
}, },
{
"artifactId": {
"name": "butterknife-runtime",
"group": "com.jakewharton",
"version": "+"
},
"copyrightHolder": "Jake Wharton",
"copyrightStatement": "Copyright &copy; Jake Wharton. All rights reserved.",
"license": "The Apache Software License, Version 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt",
"normalizedLicense": "apache2",
"url": "https://github.com/JakeWharton/butterknife/",
"libraryName": "ButterKnife Runtime"
},
{ {
"artifactId": { "artifactId": {
"name": "grpc-context", "name": "grpc-context",

@ -6,27 +6,31 @@
package com.todoroo.astrid.activity; package com.todoroo.astrid.activity;
import static java.util.Arrays.asList;
import static org.tasks.Strings.isNullOrEmpty; import static org.tasks.Strings.isNullOrEmpty;
import static java.util.Arrays.asList;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.view.MenuItem; import android.view.MenuItem;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import dagger.hilt.android.AndroidEntryPoint;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
import org.tasks.R; import org.tasks.R;
import org.tasks.databinding.BeastModePrefActivityBinding;
import org.tasks.injection.ThemedInjectingAppCompatActivity; import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.preferences.Preferences; import org.tasks.preferences.Preferences;
import org.tasks.preferences.beast.BeastModeRecyclerAdapter; import org.tasks.preferences.beast.BeastModeRecyclerAdapter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint;
@AndroidEntryPoint @AndroidEntryPoint
public class BeastModePreferences extends ThemedInjectingAppCompatActivity public class BeastModePreferences extends ThemedInjectingAppCompatActivity
implements Toolbar.OnMenuItemClickListener { implements Toolbar.OnMenuItemClickListener {
@ -34,12 +38,6 @@ public class BeastModePreferences extends ThemedInjectingAppCompatActivity
private static final String BEAST_MODE_ORDER_PREF = "beast_mode_order_v6"; // $NON-NLS-1$ private static final String BEAST_MODE_ORDER_PREF = "beast_mode_order_v6"; // $NON-NLS-1$
private static final String BEAST_MODE_PREF_ITEM_SEPARATOR = ";"; private static final String BEAST_MODE_PREF_ITEM_SEPARATOR = ";";
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.recycler_view)
RecyclerView recyclerView;
@Inject Preferences preferences; @Inject Preferences preferences;
private BeastModeRecyclerAdapter adapter; private BeastModeRecyclerAdapter adapter;
@ -87,8 +85,10 @@ public class BeastModePreferences extends ThemedInjectingAppCompatActivity
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.beast_mode_pref_activity); BeastModePrefActivityBinding binding = BeastModePrefActivityBinding.inflate(getLayoutInflater());
ButterKnife.bind(this); Toolbar toolbar = binding.toolbar.toolbar;
RecyclerView recyclerView = binding.recyclerView;
setContentView(binding.getRoot());
toolbar.setNavigationIcon( toolbar.setNavigationIcon(
getDrawable(R.drawable.ic_outline_arrow_back_24px)); getDrawable(R.drawable.ic_outline_arrow_back_24px));

@ -28,9 +28,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
@ -61,6 +58,7 @@ import org.tasks.caldav.BaseCaldavCalendarSettingsActivity
import org.tasks.data.CaldavDao import org.tasks.data.CaldavDao
import org.tasks.data.TagDataDao import org.tasks.data.TagDataDao
import org.tasks.data.TaskContainer import org.tasks.data.TaskContainer
import org.tasks.databinding.FragmentTaskListBinding
import org.tasks.db.SuspendDbUtils.chunkedMap import org.tasks.db.SuspendDbUtils.chunkedMap
import org.tasks.dialogs.DateTimePicker.Companion.newDateTimePicker import org.tasks.dialogs.DateTimePicker.Companion.newDateTimePicker
import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.DialogBuilder
@ -118,20 +116,11 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
@Inject lateinit var locale: Locale @Inject lateinit var locale: Locale
@Inject lateinit var firebase: Firebase @Inject lateinit var firebase: Firebase
@BindView(R.id.swipe_layout) private lateinit var swipeRefreshLayout: SwipeRefreshLayout
lateinit var swipeRefreshLayout: SwipeRefreshLayout private lateinit var emptyRefreshLayout: SwipeRefreshLayout
private lateinit var toolbar: Toolbar
@BindView(R.id.swipe_layout_empty) private lateinit var coordinatorLayout: CoordinatorLayout
lateinit var emptyRefreshLayout: SwipeRefreshLayout private lateinit var recyclerView: RecyclerView
@BindView(R.id.toolbar)
lateinit var toolbar: Toolbar
@BindView(R.id.task_list_coordinator)
lateinit var coordinatorLayout: CoordinatorLayout
@BindView(R.id.recycler_view)
lateinit var recyclerView: RecyclerView
private val listViewModel: TaskListViewModel by viewModels() private val listViewModel: TaskListViewModel by viewModels()
private lateinit var taskAdapter: TaskAdapter private lateinit var taskAdapter: TaskAdapter
@ -186,8 +175,15 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val parent = inflater.inflate(R.layout.fragment_task_list, container, false) val binding = FragmentTaskListBinding.inflate(inflater, container, false)
ButterKnife.bind(this, parent) with (binding) {
swipeRefreshLayout = bodyStandard.swipeLayout
emptyRefreshLayout = bodyEmpty.swipeLayoutEmpty
this@TaskListFragment.toolbar = toolbar.toolbar
coordinatorLayout = taskListCoordinator
recyclerView = bodyStandard.recyclerView
fab.setOnClickListener { createNewTask() }
}
filter = getFilter() filter = getFilter()
themeColor = if (filter.tint != 0) colorProvider.getThemeColor(filter.tint, true) else defaultThemeColor themeColor = if (filter.tint != 0) colorProvider.getThemeColor(filter.tint, true) else defaultThemeColor
filter.setFilterQueryOverride(null) filter.setFilterQueryOverride(null)
@ -218,7 +214,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
toolbar.setNavigationOnClickListener { callbacks.onNavigationIconClicked() } toolbar.setNavigationOnClickListener { callbacks.onNavigationIconClicked() }
toolbar.setOnMenuItemClickListener(this) toolbar.setOnMenuItemClickListener(this)
setupMenu() setupMenu()
return parent return binding.root
} }
private fun submitList(tasks: List<TaskContainer>) { private fun submitList(tasks: List<TaskContainer>) {
@ -423,8 +419,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
context?.toast(R.string.delete_multiple_tasks_confirmation, locale.formatNumber(count)) context?.toast(R.string.delete_multiple_tasks_confirmation, locale.formatNumber(count))
} }
@OnClick(R.id.fab) private fun createNewTask() {
fun createNewTask() {
lifecycleScope.launch { lifecycleScope.launch {
shortcutManager.reportShortcutUsed(ShortcutManager.SHORTCUT_NEW_TASK) shortcutManager.reportShortcutUsed(ShortcutManager.SHORTCUT_NEW_TASK)
onTaskListItemClicked(addTask("")) onTaskListItemClicked(addTask(""))

@ -5,10 +5,8 @@ import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.ButterKnife
import com.todoroo.astrid.api.FilterListItem import com.todoroo.astrid.api.FilterListItem
import org.tasks.R import org.tasks.databinding.FilterAdapterActionBinding
import org.tasks.themes.DrawableUtil import org.tasks.themes.DrawableUtil
class ActionViewHolder internal constructor( class ActionViewHolder internal constructor(
@ -16,17 +14,16 @@ class ActionViewHolder internal constructor(
itemView: View, itemView: View,
private val onClick: ((FilterListItem?) -> Unit)?) : RecyclerView.ViewHolder(itemView) { private val onClick: ((FilterListItem?) -> Unit)?) : RecyclerView.ViewHolder(itemView) {
@BindView(R.id.row) private val row: View
lateinit var row: View private val text: TextView
private val icon: ImageView
@BindView(R.id.text)
lateinit var text: TextView
@BindView(R.id.icon)
lateinit var icon: ImageView
init { init {
ButterKnife.bind(this, itemView) FilterAdapterActionBinding.bind(itemView).let {
row = it.row
text = it.text
icon = it.icon
}
} }
fun bind(filter: FilterListItem) { fun bind(filter: FilterListItem) {

@ -7,8 +7,6 @@ import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.ButterKnife
import com.todoroo.astrid.api.CaldavFilter import com.todoroo.astrid.api.CaldavFilter
import com.todoroo.astrid.api.CustomFilter import com.todoroo.astrid.api.CustomFilter
import com.todoroo.astrid.api.FilterListItem import com.todoroo.astrid.api.FilterListItem
@ -16,6 +14,7 @@ import com.todoroo.astrid.api.GtasksFilter
import com.todoroo.astrid.api.TagFilter import com.todoroo.astrid.api.TagFilter
import org.tasks.R import org.tasks.R
import org.tasks.billing.Inventory import org.tasks.billing.Inventory
import org.tasks.databinding.FilterAdapterRowBinding
import org.tasks.filters.PlaceFilter import org.tasks.filters.PlaceFilter
import org.tasks.locale.Locale import org.tasks.locale.Locale
import org.tasks.themes.ColorProvider import org.tasks.themes.ColorProvider
@ -31,25 +30,22 @@ class FilterViewHolder internal constructor(
private val colorProvider: ColorProvider, private val colorProvider: ColorProvider,
private val onClick: ((FilterListItem?) -> Unit)?) : RecyclerView.ViewHolder(itemView) { private val onClick: ((FilterListItem?) -> Unit)?) : RecyclerView.ViewHolder(itemView) {
@BindView(R.id.row) private val row: View
lateinit var row: View private val text: CheckedTextView
private val icon: ImageView
@BindView(R.id.text) private val size: TextView
lateinit var text: CheckedTextView private val shareIndicator: ImageView
@BindView(R.id.icon)
lateinit var icon: ImageView
@BindView(R.id.size)
lateinit var size: TextView
@BindView(R.id.share_indicator)
lateinit var shareIndicator: ImageView
lateinit var filter: FilterListItem lateinit var filter: FilterListItem
init { init {
ButterKnife.bind(this, itemView) FilterAdapterRowBinding.bind(itemView).let {
row = it.row
text = it.text
icon = it.icon
size = it.size
shareIndicator = it.shareIndicator
}
if (navigationDrawer) { if (navigationDrawer) {
text.checkMarkDrawable = null text.checkMarkDrawable = null
} }

@ -8,14 +8,12 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.tasks.LocalBroadcastManager import org.tasks.LocalBroadcastManager
import org.tasks.R import org.tasks.R
import org.tasks.data.CaldavDao import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskDao import org.tasks.data.GoogleTaskDao
import org.tasks.databinding.FilterAdapterSubheaderBinding
import org.tasks.filters.NavigationDrawerSubheader import org.tasks.filters.NavigationDrawerSubheader
import org.tasks.filters.NavigationDrawerSubheader.SubheaderType import org.tasks.filters.NavigationDrawerSubheader.SubheaderType
import org.tasks.preferences.MainPreferences import org.tasks.preferences.MainPreferences
@ -31,16 +29,12 @@ internal class SubheaderViewHolder(
private val localBroadcastManager: LocalBroadcastManager) private val localBroadcastManager: LocalBroadcastManager)
: RecyclerView.ViewHolder(itemView) { : RecyclerView.ViewHolder(itemView) {
@BindView(R.id.text) private val text: TextView
lateinit var text: TextView private val errorIcon: ImageView
@BindView(R.id.icon_error)
lateinit var errorIcon: ImageView
private lateinit var subheader: NavigationDrawerSubheader private lateinit var subheader: NavigationDrawerSubheader
@OnClick(R.id.subheader_row) private fun onClick() {
fun onClick() {
activity.lifecycleScope.launch { activity.lifecycleScope.launch {
val collapsed = !subheader.isCollapsed val collapsed = !subheader.isCollapsed
when (subheader.subheaderType) { when (subheader.subheaderType) {
@ -74,7 +68,11 @@ internal class SubheaderViewHolder(
} }
init { init {
ButterKnife.bind(this, itemView) FilterAdapterSubheaderBinding.bind(itemView).let {
text = it.text
errorIcon = it.iconError
it.subheaderRow.setOnClickListener { onClick() }
}
errorIcon.setOnClickListener { errorIcon.setOnClickListener {
activity.startActivity(Intent(activity, MainPreferences::class.java)) activity.startActivity(Intent(activity, MainPreferences::class.java))
} }

@ -5,10 +5,8 @@ import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import org.tasks.R import org.tasks.R
import org.tasks.databinding.CustomFilterRowBinding
import org.tasks.locale.Locale import org.tasks.locale.Locale
import org.tasks.preferences.ResourceResolver import org.tasks.preferences.ResourceResolver
@ -19,25 +17,23 @@ class CriterionViewHolder(
private val onClick: (String) -> Unit) private val onClick: (String) -> Unit)
: RecyclerView.ViewHolder(itemView) { : RecyclerView.ViewHolder(itemView) {
@BindView(R.id.divider) private val divider: View
lateinit var divider: View private val icon: ImageView
private val name: TextView
@BindView(R.id.icon) private val filterCount: TextView
lateinit var icon: ImageView private val row: View
@BindView(R.id.name)
lateinit var name: TextView
@BindView(R.id.filter_count)
lateinit var filterCount: TextView
@BindView(R.id.row)
lateinit var row: View
private lateinit var criterion: CriterionInstance private lateinit var criterion: CriterionInstance
init { init {
ButterKnife.bind(this, itemView) CustomFilterRowBinding.bind(itemView).let {
divider = it.divider
icon = it.icon
name = it.name
filterCount = it.filterCount
row = it.row
}
row.setOnClickListener { onClick(criterion.id) }
} }
fun bind(criterion: CriterionInstance) { fun bind(criterion: CriterionInstance) {
@ -71,9 +67,6 @@ class CriterionViewHolder(
row.isClickable = criterion.type != CriterionInstance.TYPE_UNIVERSE row.isClickable = criterion.type != CriterionInstance.TYPE_UNIVERSE
} }
@OnClick(R.id.row)
fun onClick() = onClick(criterion.id)
fun setMoving(moving: Boolean) { fun setMoving(moving: Boolean) {
if (moving) { if (moving) {
row.setBackgroundColor(ResourceResolver.getData(context, R.attr.colorControlHighlight)) row.setBackgroundColor(ResourceResolver.getData(context, R.attr.colorControlHighlight))

@ -11,11 +11,10 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import butterknife.BindView
import butterknife.OnClick
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -23,6 +22,7 @@ import kotlinx.coroutines.withContext
import org.tasks.R import org.tasks.R
import org.tasks.data.TaskAttachment import org.tasks.data.TaskAttachment
import org.tasks.data.TaskAttachmentDao import org.tasks.data.TaskAttachmentDao
import org.tasks.databinding.ControlSetFilesBinding
import org.tasks.dialogs.AddAttachmentDialog import org.tasks.dialogs.AddAttachmentDialog
import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.DialogBuilder
import org.tasks.files.FileHelper import org.tasks.files.FileHelper
@ -38,11 +38,8 @@ class FilesControlSet : TaskEditControlFragment() {
@Inject lateinit var dialogBuilder: DialogBuilder @Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var preferences: Preferences @Inject lateinit var preferences: Preferences
@BindView(R.id.attachment_container) private lateinit var attachmentContainer: LinearLayout
lateinit var attachmentContainer: LinearLayout private lateinit var addAttachment: TextView
@BindView(R.id.add_attachment)
lateinit var addAttachment: TextView
override fun createView(savedInstanceState: Bundle?) { override fun createView(savedInstanceState: Bundle?) {
val task = viewModel.task!! val task = viewModel.task!!
@ -61,12 +58,18 @@ class FilesControlSet : TaskEditControlFragment() {
} }
} }
@OnClick(R.id.add_attachment) private fun addAttachment() {
fun addAttachment() {
AddAttachmentDialog.newAddAttachmentDialog(this).show(parentFragmentManager, FRAG_TAG_ADD_ATTACHMENT_DIALOG) AddAttachmentDialog.newAddAttachmentDialog(this).show(parentFragmentManager, FRAG_TAG_ADD_ATTACHMENT_DIALOG)
} }
override val layout = R.layout.control_set_files override fun bind(parent: ViewGroup?) =
ControlSetFilesBinding.inflate(layoutInflater, parent, true).let {
attachmentContainer = it.attachmentContainer
addAttachment = it.addAttachment.apply {
setOnClickListener { addAttachment() }
}
it.root
}
override val icon = R.drawable.ic_outline_attachment_24px override val icon = R.drawable.ic_outline_attachment_24px

@ -15,13 +15,12 @@ import android.widget.AdapterView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.Spinner import android.widget.Spinner
import android.widget.TextView import android.widget.TextView
import butterknife.BindView
import butterknife.OnItemSelected
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import net.fortuna.ical4j.model.Recur import net.fortuna.ical4j.model.Recur
import net.fortuna.ical4j.model.WeekDay import net.fortuna.ical4j.model.WeekDay
import org.tasks.R import org.tasks.R
import org.tasks.analytics.Firebase import org.tasks.analytics.Firebase
import org.tasks.databinding.ControlSetRepeatDisplayBinding
import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.DialogBuilder
import org.tasks.repeats.BasicRecurrenceDialog import org.tasks.repeats.BasicRecurrenceDialog
import org.tasks.repeats.RecurrenceUtils.newRecur import org.tasks.repeats.RecurrenceUtils.newRecur
@ -30,6 +29,7 @@ import org.tasks.themes.Theme
import org.tasks.time.DateTime import org.tasks.time.DateTime
import org.tasks.time.DateTimeUtils.currentTimeMillis import org.tasks.time.DateTimeUtils.currentTimeMillis
import org.tasks.ui.HiddenTopArrayAdapter import org.tasks.ui.HiddenTopArrayAdapter
import org.tasks.ui.OnItemSelected
import org.tasks.ui.TaskEditControlFragment import org.tasks.ui.TaskEditControlFragment
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
@ -49,14 +49,9 @@ class RepeatControlSet : TaskEditControlFragment() {
@Inject lateinit var firebase: Firebase @Inject lateinit var firebase: Firebase
@Inject lateinit var repeatRuleToString: RepeatRuleToString @Inject lateinit var repeatRuleToString: RepeatRuleToString
@BindView(R.id.display_row_edit) private lateinit var displayView: TextView
lateinit var displayView: TextView private lateinit var typeSpinner: Spinner
private lateinit var repeatTypeContainer: LinearLayout
@BindView(R.id.repeatType)
lateinit var typeSpinner: Spinner
@BindView(R.id.repeatTypeContainer)
lateinit var repeatTypeContainer: LinearLayout
private lateinit var typeAdapter: HiddenTopArrayAdapter<String> private lateinit var typeAdapter: HiddenTopArrayAdapter<String>
@ -118,8 +113,7 @@ class RepeatControlSet : TaskEditControlFragment() {
refreshDisplayView() refreshDisplayView()
} }
@OnItemSelected(R.id.repeatType) private fun onRepeatTypeChanged(position: Int) {
fun onRepeatTypeChanged(position: Int) {
viewModel.repeatAfterCompletion = position == TYPE_COMPLETION_DATE viewModel.repeatAfterCompletion = position == TYPE_COMPLETION_DATE
repeatTypes[0] = if (viewModel.repeatAfterCompletion!!) repeatTypes[2] else repeatTypes[1] repeatTypes[0] = if (viewModel.repeatAfterCompletion!!) repeatTypes[2] else repeatTypes[1]
typeAdapter.notifyDataSetChanged() typeAdapter.notifyDataSetChanged()
@ -136,7 +130,19 @@ class RepeatControlSet : TaskEditControlFragment() {
override val isClickable = true override val isClickable = true
override val layout = R.layout.control_set_repeat_display override fun bind(parent: ViewGroup?) =
ControlSetRepeatDisplayBinding.inflate(layoutInflater, parent, true).let {
displayView = it.displayRowEdit
typeSpinner = it.repeatType.apply {
onItemSelectedListener = object : OnItemSelected() {
override fun onItemSelected(position: Int) {
onRepeatTypeChanged(position)
}
}
}
repeatTypeContainer = it.repeatTypeContainer
it.root
}
override val icon = R.drawable.ic_outline_repeat_24px override val icon = R.drawable.ic_outline_repeat_24px

@ -9,12 +9,13 @@ import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import butterknife.BindView
import com.google.android.material.chip.ChipGroup import com.google.android.material.chip.ChipGroup
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.data.TagData import org.tasks.data.TagData
import org.tasks.databinding.ControlSetTagsBinding
import org.tasks.tags.TagPickerActivity import org.tasks.tags.TagPickerActivity
import org.tasks.ui.ChipProvider import org.tasks.ui.ChipProvider
import org.tasks.ui.TaskEditControlFragment import org.tasks.ui.TaskEditControlFragment
@ -29,11 +30,8 @@ import javax.inject.Inject
class TagsControlSet : TaskEditControlFragment() { class TagsControlSet : TaskEditControlFragment() {
@Inject lateinit var chipProvider: ChipProvider @Inject lateinit var chipProvider: ChipProvider
@BindView(R.id.no_tags) private lateinit var tagsDisplay: TextView
lateinit var tagsDisplay: TextView private lateinit var chipGroup: ChipGroup
@BindView(R.id.chip_group)
lateinit var chipGroup: ChipGroup
override fun createView(savedInstanceState: Bundle?) { override fun createView(savedInstanceState: Bundle?) {
refreshDisplayView() refreshDisplayView()
@ -45,7 +43,12 @@ class TagsControlSet : TaskEditControlFragment() {
startActivityForResult(intent, REQUEST_TAG_PICKER_ACTIVITY) startActivityForResult(intent, REQUEST_TAG_PICKER_ACTIVITY)
} }
override val layout = R.layout.control_set_tags override fun bind(parent: ViewGroup?) =
ControlSetTagsBinding.inflate(layoutInflater, parent, true).let {
tagsDisplay = it.noTags
chipGroup = it.chipGroup
it.root
}
override val isClickable = true override val isClickable = true

@ -11,14 +11,13 @@ import android.os.SystemClock
import android.text.format.DateFormat import android.text.format.DateFormat
import android.text.format.DateUtils import android.text.format.DateUtils
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.Chronometer import android.widget.Chronometer
import android.widget.Chronometer.OnChronometerTickListener import android.widget.Chronometer.OnChronometerTickListener
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import butterknife.BindView
import butterknife.OnClick
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import com.todoroo.astrid.ui.TimeDurationControlSet import com.todoroo.astrid.ui.TimeDurationControlSet
@ -26,6 +25,7 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.tasks.R import org.tasks.R
import org.tasks.Strings.isNullOrEmpty import org.tasks.Strings.isNullOrEmpty
import org.tasks.databinding.ControlSetTimersBinding
import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.DialogBuilder
import org.tasks.themes.Theme import org.tasks.themes.Theme
import org.tasks.ui.TaskEditControlFragment import org.tasks.ui.TaskEditControlFragment
@ -42,14 +42,9 @@ class TimerControlSet : TaskEditControlFragment() {
@Inject lateinit var dialogBuilder: DialogBuilder @Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var theme: Theme @Inject lateinit var theme: Theme
@BindView(R.id.display_row_edit) private lateinit var displayEdit: TextView
lateinit var displayEdit: TextView private lateinit var chronometer: Chronometer
private lateinit var timerButton: ImageView
@BindView(R.id.timer)
lateinit var chronometer: Chronometer
@BindView(R.id.timer_button)
lateinit var timerButton: ImageView
private lateinit var estimated: TimeDurationControlSet private lateinit var estimated: TimeDurationControlSet
private lateinit var elapsed: TimeDurationControlSet private lateinit var elapsed: TimeDurationControlSet
@ -87,8 +82,7 @@ class TimerControlSet : TaskEditControlFragment() {
.create() .create()
} }
@OnClick(R.id.timer_container) private fun timerClicked() {
fun timerClicked() {
lifecycleScope.launch { lifecycleScope.launch {
if (timerActive()) { if (timerActive()) {
val task = callback.stopTimer() val task = callback.stopTimer()
@ -105,7 +99,14 @@ class TimerControlSet : TaskEditControlFragment() {
} }
} }
override val layout = R.layout.control_set_timers override fun bind(parent: ViewGroup?) =
ControlSetTimersBinding.inflate(layoutInflater, parent, true).let {
displayEdit = it.displayRowEdit
chronometer = it.timer
timerButton = it.timerButton
it.timerContainer.setOnClickListener { timerClicked() }
it.root
}
override val icon = R.drawable.ic_outline_timer_24px override val icon = R.drawable.ic_outline_timer_24px

@ -11,16 +11,15 @@ import android.content.Intent
import android.graphics.Paint import android.graphics.Paint
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.annotation.StringRes import androidx.annotation.StringRes
import butterknife.BindView
import butterknife.OnClick
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.alarms.AlarmService
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.activities.DateAndTimePickerActivity import org.tasks.activities.DateAndTimePickerActivity
import org.tasks.databinding.ControlSetRemindersBinding
import org.tasks.date.DateTimeUtils import org.tasks.date.DateTimeUtils
import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.DialogBuilder
import org.tasks.dialogs.MyTimePickerDialog import org.tasks.dialogs.MyTimePickerDialog
@ -38,15 +37,11 @@ import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class ReminderControlSet : TaskEditControlFragment() { class ReminderControlSet : TaskEditControlFragment() {
@Inject lateinit var activity: Activity @Inject lateinit var activity: Activity
@Inject lateinit var alarmService: AlarmService
@Inject lateinit var locale: Locale @Inject lateinit var locale: Locale
@Inject lateinit var dialogBuilder: DialogBuilder @Inject lateinit var dialogBuilder: DialogBuilder
@BindView(R.id.alert_container) private lateinit var alertContainer: LinearLayout
lateinit var alertContainer: LinearLayout private lateinit var mode: TextView
@BindView(R.id.reminder_alarm)
lateinit var mode: TextView
private var randomControlSet: RandomReminderControlSet? = null private var randomControlSet: RandomReminderControlSet? = null
@ -69,8 +64,7 @@ class ReminderControlSet : TaskEditControlFragment() {
viewModel.selectedAlarms?.forEach(this::addAlarmRow) viewModel.selectedAlarms?.forEach(this::addAlarmRow)
} }
@OnClick(R.id.reminder_alarm) private fun onClickRingType() {
fun onClickRingType() {
val modes = resources.getStringArray(R.array.reminder_ring_modes) val modes = resources.getStringArray(R.array.reminder_ring_modes)
val ringMode = when { val ringMode = when {
viewModel.ringNonstop == true -> 2 viewModel.ringNonstop == true -> 2
@ -110,8 +104,7 @@ class ReminderControlSet : TaskEditControlFragment() {
} }
} }
@OnClick(R.id.alarms_add) private fun addAlarm() {
fun addAlarm() {
val options = options val options = options
if (options.size == 1) { if (options.size == 1) {
addNewAlarm() addNewAlarm()
@ -126,7 +119,15 @@ class ReminderControlSet : TaskEditControlFragment() {
} }
} }
override val layout = R.layout.control_set_reminders override fun bind(parent: ViewGroup?) =
ControlSetRemindersBinding.inflate(layoutInflater, parent, true).let {
alertContainer = it.alertContainer
mode = it.reminderAlarm.apply {
setOnClickListener { onClickRingType() }
}
it.alarmsAdd.setOnClickListener { addAlarm() }
it.root
}
override val icon = R.drawable.ic_outline_notifications_24px override val icon = R.drawable.ic_outline_notifications_24px

@ -3,13 +3,14 @@ package com.todoroo.astrid.ui
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import butterknife.BindView
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.andlib.utility.DateUtilities.now import com.todoroo.andlib.utility.DateUtilities.now
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.databinding.ControlSetHideBinding
import org.tasks.date.DateTimeUtils.newDateTime import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.date.DateTimeUtils.toDateTime import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.dialogs.StartDatePicker import org.tasks.dialogs.StartDatePicker
@ -35,8 +36,7 @@ class StartDateControlSet : TaskEditControlFragment() {
@Inject lateinit var preferences: Preferences @Inject lateinit var preferences: Preferences
@Inject lateinit var locale: Locale @Inject lateinit var locale: Locale
@BindView(R.id.start_date) private lateinit var startDate: TextView
lateinit var startDate: TextView
private val dueDateTime private val dueDateTime
get() = viewModel.dueDate!! get() = viewModel.dueDate!!
@ -95,7 +95,11 @@ class StartDateControlSet : TaskEditControlFragment() {
applySelectionToHideUntil() applySelectionToHideUntil()
} }
override val layout = R.layout.control_set_hide override fun bind(parent: ViewGroup?) =
ControlSetHideBinding.inflate(layoutInflater, parent, true).let {
startDate = it.startDate
it.root
}
override val icon = R.drawable.ic_pending_actions_24px override val icon = R.drawable.ic_pending_actions_24px

@ -5,12 +5,10 @@ import android.graphics.drawable.LayerDrawable
import android.os.Bundle import android.os.Bundle
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.tasks.R import org.tasks.R
import org.tasks.dialogs.ColorPalettePicker import org.tasks.dialogs.ColorPalettePicker
@ -34,22 +32,26 @@ abstract class BaseListSettingsActivity : ThemedInjectingAppCompatActivity(), Ic
protected var selectedColor = 0 protected var selectedColor = 0
protected var selectedIcon = -1 protected var selectedIcon = -1
@BindView(R.id.clear) private lateinit var clear: View
lateinit var clear: View private lateinit var color: TextView
private lateinit var icon: TextView
@BindView(R.id.color) protected lateinit var toolbar: Toolbar
lateinit var color: TextView protected lateinit var colorRow: ViewGroup
@BindView(R.id.icon)
lateinit var icon: TextView
@BindView(R.id.toolbar)
lateinit var toolbar: Toolbar
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(layout) val view = bind()
ButterKnife.bind(this) setContentView(view)
clear = findViewById<View>(R.id.clear).apply {
setOnClickListener { clearColor() }
}
color = findViewById(R.id.color)
colorRow = findViewById<ViewGroup>(R.id.color_row).apply {
setOnClickListener { showThemePicker() }
}
icon = findViewById(R.id.icon)
findViewById<View>(R.id.icon_row).setOnClickListener { showIconPicker() }
toolbar = view.findViewById(R.id.toolbar)
if (savedInstanceState != null) { if (savedInstanceState != null) {
selectedColor = savedInstanceState.getInt(EXTRA_SELECTED_THEME) selectedColor = savedInstanceState.getInt(EXTRA_SELECTED_THEME)
selectedIcon = savedInstanceState.getInt(EXTRA_SELECTED_ICON) selectedIcon = savedInstanceState.getInt(EXTRA_SELECTED_ICON)
@ -73,12 +75,12 @@ abstract class BaseListSettingsActivity : ThemedInjectingAppCompatActivity(), Ic
discard() discard()
} }
protected abstract val layout: Int
protected abstract fun hasChanges(): Boolean protected abstract fun hasChanges(): Boolean
protected abstract suspend fun save() protected abstract suspend fun save()
protected abstract val isNew: Boolean protected abstract val isNew: Boolean
protected abstract val toolbarTitle: String? protected abstract val toolbarTitle: String?
protected abstract suspend fun delete() protected abstract suspend fun delete()
protected abstract fun bind(): View
protected open fun discard() { protected open fun discard() {
if (!hasChanges()) { if (!hasChanges()) {
finish() finish()
@ -91,19 +93,16 @@ abstract class BaseListSettingsActivity : ThemedInjectingAppCompatActivity(), Ic
} }
} }
@OnClick(R.id.clear) private fun clearColor() {
fun clearColor() {
onColorPicked(0) onColorPicked(0)
} }
@OnClick(R.id.color_row) private fun showThemePicker() {
fun showThemePicker() {
newColorPalette(null, 0, selectedColor, Palette.COLORS) newColorPalette(null, 0, selectedColor, Palette.COLORS)
.show(supportFragmentManager, FRAG_TAG_COLOR_PICKER) .show(supportFragmentManager, FRAG_TAG_COLOR_PICKER)
} }
@OnClick(R.id.icon_row) private fun showIconPicker() {
fun showIconPicker() {
IconPickerDialog.newIconPicker(selectedIcon).show(supportFragmentManager, FRAG_TAG_ICON_PICKER) IconPickerDialog.newIconPicker(selectedIcon).show(supportFragmentManager, FRAG_TAG_ICON_PICKER)
} }

@ -9,13 +9,11 @@ import android.view.MenuItem
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.EditText import android.widget.EditText
import android.widget.FrameLayout import android.widget.FrameLayout
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.OnClick
import butterknife.OnTextChanged
import com.google.android.material.button.MaterialButtonToggleGroup import com.google.android.material.button.MaterialButtonToggleGroup
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
@ -26,7 +24,12 @@ import com.todoroo.andlib.sql.UnaryCriterion
import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.astrid.activity.MainActivity import com.todoroo.astrid.activity.MainActivity
import com.todoroo.astrid.activity.TaskListFragment import com.todoroo.astrid.activity.TaskListFragment
import com.todoroo.astrid.api.* import com.todoroo.astrid.api.BooleanCriterion
import com.todoroo.astrid.api.CustomFilter
import com.todoroo.astrid.api.CustomFilterCriterion
import com.todoroo.astrid.api.MultipleSelectCriterion
import com.todoroo.astrid.api.PermaSql
import com.todoroo.astrid.api.TextInputCriterion
import com.todoroo.astrid.core.CriterionInstance import com.todoroo.astrid.core.CriterionInstance
import com.todoroo.astrid.core.CustomFilterAdapter import com.todoroo.astrid.core.CustomFilterAdapter
import com.todoroo.astrid.core.CustomFilterItemTouchHelper import com.todoroo.astrid.core.CustomFilterItemTouchHelper
@ -39,6 +42,7 @@ import org.tasks.Strings
import org.tasks.data.Filter import org.tasks.data.Filter
import org.tasks.data.FilterDao import org.tasks.data.FilterDao
import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible
import org.tasks.databinding.FilterSettingsActivityBinding
import org.tasks.db.QueryUtils import org.tasks.db.QueryUtils
import org.tasks.extensions.Context.openUri import org.tasks.extensions.Context.openUri
import org.tasks.filters.FilterCriteriaProvider import org.tasks.filters.FilterCriteriaProvider
@ -54,17 +58,10 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
@Inject lateinit var database: Database @Inject lateinit var database: Database
@Inject lateinit var filterCriteriaProvider: FilterCriteriaProvider @Inject lateinit var filterCriteriaProvider: FilterCriteriaProvider
@BindView(R.id.name) private lateinit var name: TextInputEditText
lateinit var name: TextInputEditText private lateinit var nameLayout: TextInputLayout
private lateinit var recyclerView: RecyclerView
@BindView(R.id.name_layout) private lateinit var fab: ExtendedFloatingActionButton
lateinit var nameLayout: TextInputLayout
@BindView(R.id.recycler_view)
lateinit var recyclerView: RecyclerView
@BindView(R.id.fab)
lateinit var fab: ExtendedFloatingActionButton
private var filter: CustomFilter? = null private var filter: CustomFilter? = null
private lateinit var adapter: CustomFilterAdapter private lateinit var adapter: CustomFilterAdapter
@ -162,8 +159,7 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
else -> CriterionInstance.TYPE_INTERSECT else -> CriterionInstance.TYPE_INTERSECT
} }
@OnClick(R.id.fab) private fun addCriteria() {
fun addCriteria() {
AndroidUtilities.hideKeyboard(this) AndroidUtilities.hideKeyboard(this)
fab.shrink() fab.shrink()
lifecycleScope.launch { lifecycleScope.launch {
@ -230,11 +226,6 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
override val toolbarTitle: String? override val toolbarTitle: String?
get() = if (isNew) getString(R.string.FLA_new_filter) else filter!!.listingTitle get() = if (isNew) getString(R.string.FLA_new_filter) else filter!!.listingTitle
@OnTextChanged(R.id.name)
fun onTextChanged() {
nameLayout.error = null
}
override suspend fun save() { override suspend fun save() {
val newName = newName val newName = newName
if (Strings.isNullOrEmpty(newName)) { if (Strings.isNullOrEmpty(newName)) {
@ -290,8 +281,19 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
super.finish() super.finish()
} }
override val layout: Int override fun bind() = FilterSettingsActivityBinding.inflate(layoutInflater).let {
get() = R.layout.filter_settings_activity name = it.name.apply {
addTextChangedListener(
onTextChanged = { _, _, _, _ -> nameLayout.error = null }
)
}
nameLayout = it.nameLayout
recyclerView = it.recyclerView
fab = it.fab.apply {
setOnClickListener { addCriteria() }
}
it.root
}
override suspend fun delete() { override suspend fun delete() {
filterDao.delete(filter!!.id) filterDao.delete(filter!!.id)

@ -8,7 +8,6 @@ import android.view.View
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.ProgressBar import android.widget.ProgressBar
import androidx.activity.viewModels import androidx.activity.viewModels
import butterknife.BindView
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.google.api.services.tasks.model.TaskList import com.google.api.services.tasks.model.TaskList
import com.todoroo.astrid.activity.MainActivity import com.todoroo.astrid.activity.MainActivity
@ -21,6 +20,7 @@ import org.tasks.Strings.isNullOrEmpty
import org.tasks.data.GoogleTaskAccount import org.tasks.data.GoogleTaskAccount
import org.tasks.data.GoogleTaskList import org.tasks.data.GoogleTaskList
import org.tasks.data.GoogleTaskListDao import org.tasks.data.GoogleTaskListDao
import org.tasks.databinding.ActivityGoogleTaskListSettingsBinding
import org.tasks.extensions.Context.toast import org.tasks.extensions.Context.toast
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -30,11 +30,8 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() {
@Inject lateinit var googleTaskListDao: GoogleTaskListDao @Inject lateinit var googleTaskListDao: GoogleTaskListDao
@Inject lateinit var taskDeleter: TaskDeleter @Inject lateinit var taskDeleter: TaskDeleter
@BindView(R.id.name) private lateinit var name: TextInputEditText
lateinit var name: TextInputEditText private lateinit var progressView: ProgressBar
@BindView(R.id.progress_bar)
lateinit var progressView: ProgressBar
private var isNewList = false private var isNewList = false
private lateinit var gtasksList: GoogleTaskList private lateinit var gtasksList: GoogleTaskList
@ -126,8 +123,11 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() {
super.finish() super.finish()
} }
override val layout: Int override fun bind() = ActivityGoogleTaskListSettingsBinding.inflate(layoutInflater).let {
get() = R.layout.activity_google_task_list_settings name = it.name
progressView = it.progressBar.progressBar
it.root
}
override fun promptDelete() { override fun promptDelete() {
if (!requestInProgress()) { if (!requestInProgress()) {
@ -174,7 +174,7 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() {
finish() finish()
} }
private suspend fun onListDeleted(deleted: Boolean) { private fun onListDeleted(deleted: Boolean) {
if (deleted) { if (deleted) {
taskDeleter.delete(gtasksList) taskDeleter.delete(gtasksList)
setResult(Activity.RESULT_OK, Intent(TaskListFragment.ACTION_DELETED)) setResult(Activity.RESULT_OK, Intent(TaskListFragment.ACTION_DELETED))

@ -3,8 +3,7 @@ package org.tasks.activities
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import butterknife.BindView import androidx.core.widget.addTextChangedListener
import butterknife.OnTextChanged
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import com.todoroo.astrid.activity.MainActivity import com.todoroo.astrid.activity.MainActivity
@ -14,6 +13,7 @@ import org.tasks.R
import org.tasks.Strings.isNullOrEmpty import org.tasks.Strings.isNullOrEmpty
import org.tasks.data.LocationDao import org.tasks.data.LocationDao
import org.tasks.data.Place import org.tasks.data.Place
import org.tasks.databinding.ActivityLocationSettingsBinding
import org.tasks.filters.PlaceFilter import org.tasks.filters.PlaceFilter
import org.tasks.location.MapFragment import org.tasks.location.MapFragment
import org.tasks.preferences.Preferences import org.tasks.preferences.Preferences
@ -26,8 +26,8 @@ class PlaceSettingsActivity : BaseListSettingsActivity(), MapFragment.MapFragmen
const val EXTRA_PLACE = "extra_place" const val EXTRA_PLACE = "extra_place"
} }
@BindView(R.id.name) lateinit var name: TextInputEditText private lateinit var name: TextInputEditText
@BindView(R.id.name_layout) lateinit var nameLayout: TextInputLayout private lateinit var nameLayout: TextInputLayout
@Inject lateinit var locationDao: LocationDao @Inject lateinit var locationDao: LocationDao
@Inject lateinit var map: MapFragment @Inject lateinit var map: MapFragment
@ -64,18 +64,20 @@ class PlaceSettingsActivity : BaseListSettingsActivity(), MapFragment.MapFragmen
updateTheme() updateTheme()
} }
override val layout: Int override fun bind() = ActivityLocationSettingsBinding.inflate(layoutInflater).let {
get() = R.layout.activity_location_settings name = it.name.apply {
addTextChangedListener(
onTextChanged = { _, _, _, _ -> nameLayout.error = null }
)
}
nameLayout = it.nameLayout
it.root
}
override fun hasChanges() = name.text.toString() != place.displayName override fun hasChanges() = name.text.toString() != place.displayName
|| selectedColor != place.color || selectedColor != place.color
|| selectedIcon != place.getIcon()!! || selectedIcon != place.getIcon()!!
@OnTextChanged(R.id.name)
fun onNameChanged() {
nameLayout.error = null
}
override suspend fun save() { override suspend fun save() {
val newName: String = name.text.toString() val newName: String = name.text.toString()

@ -10,8 +10,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import butterknife.BindView import androidx.core.widget.addTextChangedListener
import butterknife.OnTextChanged
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import com.todoroo.astrid.activity.MainActivity import com.todoroo.astrid.activity.MainActivity
@ -24,6 +23,7 @@ import org.tasks.Strings.isNullOrEmpty
import org.tasks.data.TagDao import org.tasks.data.TagDao
import org.tasks.data.TagData import org.tasks.data.TagData
import org.tasks.data.TagDataDao import org.tasks.data.TagDataDao
import org.tasks.databinding.ActivityTagSettingsBinding
import javax.inject.Inject import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
@ -31,11 +31,8 @@ class TagSettingsActivity : BaseListSettingsActivity() {
@Inject lateinit var tagDataDao: TagDataDao @Inject lateinit var tagDataDao: TagDataDao
@Inject lateinit var tagDao: TagDao @Inject lateinit var tagDao: TagDao
@BindView(R.id.name) private lateinit var name: TextInputEditText
lateinit var name: TextInputEditText private lateinit var nameLayout: TextInputLayout
@BindView(R.id.name_layout)
lateinit var nameLayout: TextInputLayout
private var isNewTag = false private var isNewTag = false
private lateinit var tagData: TagData private lateinit var tagData: TagData
@ -70,11 +67,6 @@ class TagSettingsActivity : BaseListSettingsActivity() {
override val toolbarTitle: String override val toolbarTitle: String
get() = if (isNew) getString(R.string.new_tag) else tagData.name!! get() = if (isNew) getString(R.string.new_tag) else tagData.name!!
@OnTextChanged(R.id.name)
fun onTextChanged() {
nameLayout.error = null
}
private val newName: String private val newName: String
get() = name.text.toString().trim { it <= ' ' } get() = name.text.toString().trim { it <= ' ' }
@ -129,8 +121,15 @@ class TagSettingsActivity : BaseListSettingsActivity() {
super.finish() super.finish()
} }
override val layout: Int override fun bind() = ActivityTagSettingsBinding.inflate(layoutInflater).let {
get() = R.layout.activity_tag_settings name = it.name.apply {
addTextChangedListener(
onTextChanged = { _, _, _, _ -> nameLayout.error = null }
)
}
nameLayout = it.nameLayout
it.root
}
override suspend fun delete() { override suspend fun delete() {
val uuid = tagData.remoteId val uuid = tagData.remoteId

@ -2,7 +2,6 @@ package org.tasks.activities.attribution
import android.os.Bundle import android.os.Bundle
import androidx.activity.viewModels import androidx.activity.viewModels
import butterknife.ButterKnife
import com.google.android.material.composethemeadapter.MdcTheme import com.google.android.material.composethemeadapter.MdcTheme
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
@ -18,7 +17,6 @@ class AttributionActivity : ThemedInjectingAppCompatActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val binding = ActivityAttributionsBinding.inflate(layoutInflater) val binding = ActivityAttributionsBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
ButterKnife.bind(this)
with(binding.toolbar.toolbar) { with(binding.toolbar.toolbar) {
setTitle(R.string.third_party_licenses) setTitle(R.string.third_party_licenses)
setNavigationIcon(R.drawable.ic_outline_arrow_back_24px) setNavigationIcon(R.drawable.ic_outline_arrow_back_24px)

@ -12,11 +12,9 @@ import android.view.inputmethod.InputMethodManager
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import at.bitfire.dav4jvm.exception.HttpException import at.bitfire.dav4jvm.exception.HttpException
import butterknife.ButterKnife
import butterknife.OnFocusChange
import butterknife.OnTextChanged
import com.google.android.material.snackbar.BaseTransientBottomBar import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
@ -59,7 +57,6 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityCaldavAccountSettingsBinding.inflate(layoutInflater) binding = ActivityCaldavAccountSettingsBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
ButterKnife.bind(this)
caldavAccount = if (savedInstanceState == null) intent.getParcelableExtra(EXTRA_CALDAV_DATA) else savedInstanceState.getParcelable(EXTRA_CALDAV_DATA) caldavAccount = if (savedInstanceState == null) intent.getParcelableExtra(EXTRA_CALDAV_DATA) else savedInstanceState.getParcelable(EXTRA_CALDAV_DATA)
if (caldavAccount == null || caldavAccount!!.id == Task.NO_ID) { if (caldavAccount == null || caldavAccount!!.id == Task.NO_ID) {
binding.nameLayout.visibility = View.GONE binding.nameLayout.visibility = View.GONE
@ -108,6 +105,19 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv
} }
.show() .show()
} }
binding.name.addTextChangedListener(
onTextChanged = { _, _, _, _ -> binding.nameLayout.error = null }
)
binding.url.addTextChangedListener(
onTextChanged = { _, _, _, _ -> binding.urlLayout.error = null }
)
binding.user.addTextChangedListener(
onTextChanged = { _, _, _, _ -> binding.userLayout.error = null }
)
binding.password.addTextChangedListener(
onTextChanged = { _, _, _, _ -> binding.passwordLayout.error = null }
)
binding.password.setOnFocusChangeListener { _, hasFocus -> onPasswordFocused(hasFocus) }
} }
@get:StringRes @get:StringRes
@ -132,28 +142,7 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv
return binding.progressBar.progressBar.visibility == View.VISIBLE return binding.progressBar.progressBar.visibility == View.VISIBLE
} }
@OnTextChanged(R.id.name) private fun onPasswordFocused(hasFocus: Boolean) {
fun onNameChanged() {
binding.nameLayout.error = null
}
@OnTextChanged(R.id.url)
fun onUrlChanged() {
binding.urlLayout.error = null
}
@OnTextChanged(R.id.user)
fun onUserChanged() {
binding.userLayout.error = null
}
@OnTextChanged(R.id.password)
fun onPasswordChanged() {
binding.passwordLayout.error = null
}
@OnFocusChange(R.id.password)
fun onPasswordFocused(hasFocus: Boolean) {
if (hasFocus) { if (hasFocus) {
if (PASSWORD_MASK == binding.password.text.toString()) { if (PASSWORD_MASK == binding.password.text.toString()) {
binding.password.setText("") binding.password.setText("")

@ -8,9 +8,8 @@ import android.view.View
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.ProgressBar import android.widget.ProgressBar
import androidx.core.widget.addTextChangedListener
import at.bitfire.dav4jvm.exception.HttpException import at.bitfire.dav4jvm.exception.HttpException
import butterknife.BindView
import butterknife.OnTextChanged
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
@ -26,6 +25,7 @@ import org.tasks.activities.BaseListSettingsActivity
import org.tasks.data.CaldavAccount import org.tasks.data.CaldavAccount
import org.tasks.data.CaldavCalendar import org.tasks.data.CaldavCalendar
import org.tasks.data.CaldavDao import org.tasks.data.CaldavDao
import org.tasks.databinding.ActivityCaldavCalendarSettingsBinding
import org.tasks.ui.DisplayableException import org.tasks.ui.DisplayableException
import java.net.ConnectException import java.net.ConnectException
import javax.inject.Inject import javax.inject.Inject
@ -34,24 +34,26 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() {
@Inject lateinit var caldavDao: CaldavDao @Inject lateinit var caldavDao: CaldavDao
@Inject lateinit var taskDeleter: TaskDeleter @Inject lateinit var taskDeleter: TaskDeleter
@BindView(R.id.root_layout) private lateinit var root: LinearLayout
lateinit var root: LinearLayout private lateinit var name: TextInputEditText
protected lateinit var nameLayout: TextInputLayout
@BindView(R.id.name) protected lateinit var progressView: ProgressBar
lateinit var name: TextInputEditText
@BindView(R.id.name_layout)
lateinit var nameLayout: TextInputLayout
@BindView(R.id.progress_bar)
lateinit var progressView: ProgressBar
protected var caldavCalendar: CaldavCalendar? = null protected var caldavCalendar: CaldavCalendar? = null
protected lateinit var caldavAccount: CaldavAccount protected lateinit var caldavAccount: CaldavAccount
override val layout: Int override fun bind() = ActivityCaldavCalendarSettingsBinding.inflate(layoutInflater).let {
get() = R.layout.activity_caldav_calendar_settings root = it.rootLayout
name = it.name.apply {
addTextChangedListener(
onTextChanged = { _, _, _, _ -> nameLayout.error = null }
)
}
nameLayout = it.nameLayout
progressView = it.progressBar.progressBar
it.root
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
val intent = intent val intent = intent
@ -83,11 +85,6 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() {
override val toolbarTitle: String override val toolbarTitle: String
get() = if (isNew) getString(R.string.new_list) else caldavCalendar!!.name ?: "" get() = if (isNew) getString(R.string.new_list) else caldavCalendar!!.name ?: ""
@OnTextChanged(R.id.name)
fun onNameChanged() {
nameLayout.error = null
}
override suspend fun save() { override suspend fun save() {
if (requestInProgress()) { if (requestInProgress()) {
return return

@ -34,8 +34,6 @@ class CaldavCalendarSettingsActivity : BaseCaldavCalendarSettingsActivity() {
private val viewModel: CaldavCalendarViewModel by viewModels() private val viewModel: CaldavCalendarViewModel by viewModels()
override val layout = R.layout.activity_caldav_calendar_settings
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

@ -11,9 +11,6 @@ import org.tasks.data.CaldavDao
@AndroidEntryPoint @AndroidEntryPoint
class LocalListSettingsActivity : BaseCaldavCalendarSettingsActivity() { class LocalListSettingsActivity : BaseCaldavCalendarSettingsActivity() {
override val layout: Int
get() = R.layout.activity_caldav_calendar_settings
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

@ -10,13 +10,11 @@ import android.os.Parcelable
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.ButterKnife
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.billing.Inventory import org.tasks.billing.Inventory
import org.tasks.billing.PurchaseActivity import org.tasks.billing.PurchaseActivity
import org.tasks.databinding.DialogIconPickerBinding
import org.tasks.dialogs.ColorPickerAdapter.Palette import org.tasks.dialogs.ColorPickerAdapter.Palette
import org.tasks.dialogs.ColorWheelPicker.Companion.newColorWheel import org.tasks.dialogs.ColorWheelPicker.Companion.newColorWheel
import org.tasks.themes.ColorProvider import org.tasks.themes.ColorProvider
@ -68,16 +66,12 @@ class ColorPalettePicker : DialogFragment() {
@Inject lateinit var inventory: Inventory @Inject lateinit var inventory: Inventory
@Inject lateinit var colorProvider: ColorProvider @Inject lateinit var colorProvider: ColorProvider
@BindView(R.id.icons) lateinit var recyclerView: RecyclerView
private lateinit var colors: List<Pickable> private lateinit var colors: List<Pickable>
private lateinit var palette: Palette private lateinit var palette: Palette
var callback: ColorPickedCallback? = null var callback: ColorPickedCallback? = null
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val inflater = LayoutInflater.from(context) val binding = DialogIconPickerBinding.inflate(LayoutInflater.from(context))
val view = inflater.inflate(R.layout.dialog_icon_picker, null)
ButterKnife.bind(this, view)
palette = requireArguments().getSerializable(EXTRA_PALETTE) as Palette palette = requireArguments().getSerializable(EXTRA_PALETTE) as Palette
colors = when (palette) { colors = when (palette) {
Palette.COLORS -> colorProvider.getThemeColors() Palette.COLORS -> colorProvider.getThemeColors()
@ -89,13 +83,15 @@ class ColorPalettePicker : DialogFragment() {
} }
val iconPickerAdapter = ColorPickerAdapter(requireActivity(), inventory, this::onSelected) val iconPickerAdapter = ColorPickerAdapter(requireActivity(), inventory, this::onSelected)
recyclerView.layoutManager = IconLayoutManager(context) with(binding.icons) {
recyclerView.adapter = iconPickerAdapter layoutManager = IconLayoutManager(context)
adapter = iconPickerAdapter
}
iconPickerAdapter.submitList(colors) iconPickerAdapter.submitList(colors)
val builder = val builder =
dialogBuilder dialogBuilder
.newDialog() .newDialog()
.setView(view) .setView(binding.root)
if (palette == Palette.COLORS || palette == Palette.WIDGET) { if (palette == Palette.COLORS || palette == Palette.WIDGET) {
builder.setNeutralButton(R.string.color_wheel) { _, _ -> builder.setNeutralButton(R.string.color_wheel) { _, _ ->
val selected = arguments?.getInt(EXTRA_SELECTED) ?: 0 val selected = arguments?.getInt(EXTRA_SELECTED) ?: 0

@ -6,6 +6,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import org.tasks.R import org.tasks.R
import org.tasks.billing.Inventory import org.tasks.billing.Inventory
import org.tasks.databinding.DialogIconPickerCellBinding
import org.tasks.dialogs.ColorPalettePicker.Pickable import org.tasks.dialogs.ColorPalettePicker.Pickable
class ColorPickerAdapter( class ColorPickerAdapter(
@ -21,10 +22,12 @@ class ColorPickerAdapter(
WIDGET WIDGET
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IconPickerHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
val view = activity.layoutInflater.inflate(R.layout.dialog_icon_picker_cell, parent, false) IconPickerHolder(
return IconPickerHolder(activity, view, onSelected) activity,
} DialogIconPickerCellBinding.inflate(activity.layoutInflater, parent, false),
onSelected
)
override fun onBindViewHolder(holder: IconPickerHolder, position: Int) { override fun onBindViewHolder(holder: IconPickerHolder, position: Int) {
val pickable = getItem(position) val pickable = getItem(position)

@ -9,8 +9,6 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import butterknife.ButterKnife
import butterknife.OnClick
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
@ -93,20 +91,33 @@ class DateTimePicker : BaseDateTimePicker() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = DialogDateTimePickerBinding.inflate(theme.getLayoutInflater(requireContext())) binding = DialogDateTimePickerBinding.inflate(theme.getLayoutInflater(requireContext()))
setupShortcutsAndCalendar() setupShortcutsAndCalendar()
ButterKnife.bind(this, binding.root) with (binding.shortcuts) {
binding.shortcuts.nextWeekButton.text = nextWeekButton.text =
getString( getString(
when (newDateTime().plusWeeks(1).dayOfWeek) { when (newDateTime().plusWeeks(1).dayOfWeek) {
SUNDAY -> R.string.next_sunday SUNDAY -> R.string.next_sunday
MONDAY -> R.string.next_monday MONDAY -> R.string.next_monday
TUESDAY -> R.string.next_tuesday TUESDAY -> R.string.next_tuesday
WEDNESDAY -> R.string.next_wednesday WEDNESDAY -> R.string.next_wednesday
THURSDAY -> R.string.next_thursday THURSDAY -> R.string.next_thursday
FRIDAY -> R.string.next_friday FRIDAY -> R.string.next_friday
SATURDAY -> R.string.next_saturday SATURDAY -> R.string.next_saturday
else -> throw IllegalArgumentException() else -> throw IllegalArgumentException()
} }
) )
noDateButton.setOnClickListener { clearDate() }
noTime.setOnClickListener { clearTime() }
todayButton.setOnClickListener { setToday() }
tomorrowButton.setOnClickListener { setTomorrow() }
nextWeekButton.setOnClickListener { setNextWeek() }
morningButton.setOnClickListener { setMorning() }
afternoonButton.setOnClickListener { setAfternoon() }
eveningButton.setOnClickListener { setEvening() }
nightButton.setOnClickListener { setNight() }
currentDateSelection.setOnClickListener { currentDate() }
currentTimeSelection.setOnClickListener { currentTime() }
pickTimeButton.setOnClickListener { pickTime() }
}
binding.calendarView.setOnDateChangeListener { _, y, m, d -> binding.calendarView.setOnDateChangeListener { _, y, m, d ->
returnDate(day = DateTime(y, m + 1, d).millis) returnDate(day = DateTime(y, m + 1, d).millis)
refreshButtons() refreshButtons()
@ -163,40 +174,18 @@ class DateTimePicker : BaseDateTimePicker() {
} }
} }
@OnClick(R.id.no_date_button) private fun clearDate() = returnDate(day = 0, time = 0)
fun clearDate() = returnDate(day = 0, time = 0) private fun clearTime() = returnDate(time = 0)
private fun setToday() = returnDate(day = today.startOfDay().millis)
@OnClick(R.id.no_time) private fun setTomorrow() = returnDate(day = tomorrow.startOfDay().millis)
fun clearTime() = returnDate(time = 0) private fun setNextWeek() = returnDate(day = nextWeek.startOfDay().millis)
private fun setMorning() = returnSelectedTime(morning)
@OnClick(R.id.today_button) private fun setAfternoon() = returnSelectedTime(afternoon)
fun setToday() = returnDate(day = today.startOfDay().millis) private fun setEvening() = returnSelectedTime(evening)
private fun setNight() = returnSelectedTime(night)
@OnClick(R.id.tomorrow_button) private fun currentDate() = returnDate(day = customDate)
fun setTomorrow() = returnDate(day = tomorrow.startOfDay().millis) private fun currentTime() = returnSelectedTime(customTime)
@OnClick(R.id.next_week_button)
fun setNextWeek() = returnDate(day = nextWeek.startOfDay().millis)
@OnClick(R.id.morning_button)
fun setMorning() = returnSelectedTime(morning)
@OnClick(R.id.afternoon_button)
fun setAfternoon() = returnSelectedTime(afternoon)
@OnClick(R.id.evening_button)
fun setEvening() = returnSelectedTime(evening)
@OnClick(R.id.night_button)
fun setNight() = returnSelectedTime(night)
@OnClick(R.id.current_date_selection)
fun currentDate() = returnDate(day = customDate)
@OnClick(R.id.current_time_selection)
fun currentTime() = returnSelectedTime(customTime)
@OnClick(R.id.pick_time_button)
fun pickTime() { fun pickTime() {
val time = if (selectedTime == MULTIPLE_TIMES val time = if (selectedTime == MULTIPLE_TIMES
|| !Task.hasDueTime(today.withMillisOfDay(selectedTime).millis)) { || !Task.hasDueTime(today.withMillisOfDay(selectedTime).millis)) {

@ -9,22 +9,25 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.google.android.material.slider.Slider; import com.google.android.material.slider.Slider;
import com.google.android.material.switchmaterial.SwitchMaterial; import com.google.android.material.switchmaterial.SwitchMaterial;
import dagger.hilt.android.AndroidEntryPoint;
import javax.inject.Inject;
import org.tasks.R; import org.tasks.R;
import org.tasks.data.Geofence; import org.tasks.data.Geofence;
import org.tasks.data.Location; import org.tasks.data.Location;
import org.tasks.databinding.LocationDetailsBinding;
import org.tasks.locale.Locale; import org.tasks.locale.Locale;
import org.tasks.preferences.PermissionChecker; import org.tasks.preferences.PermissionChecker;
import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint;
@AndroidEntryPoint @AndroidEntryPoint
public class GeofenceDialog extends DialogFragment { public class GeofenceDialog extends DialogFragment {
@ -39,14 +42,9 @@ public class GeofenceDialog extends DialogFragment {
@Inject Locale locale; @Inject Locale locale;
@Inject PermissionChecker permissionChecker; @Inject PermissionChecker permissionChecker;
@BindView(R.id.location_arrival) private SwitchMaterial arrivalView;
SwitchMaterial arrivalView; private SwitchMaterial departureView;
private Slider slider;
@BindView(R.id.location_departure)
SwitchMaterial departureView;
@BindView(R.id.slider)
Slider slider;
public static GeofenceDialog newGeofenceDialog(Location location) { public static GeofenceDialog newGeofenceDialog(Location location) {
GeofenceDialog dialog = new GeofenceDialog(); GeofenceDialog dialog = new GeofenceDialog();
@ -66,8 +64,10 @@ public class GeofenceDialog extends DialogFragment {
: savedInstanceState.getParcelable(EXTRA_GEOFENCE); : savedInstanceState.getParcelable(EXTRA_GEOFENCE);
LayoutInflater layoutInflater = LayoutInflater.from(context); LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.location_details, null); LocationDetailsBinding binding = LocationDetailsBinding.inflate(layoutInflater);
ButterKnife.bind(this, view); arrivalView = binding.locationArrival;
departureView = binding.locationDeparture;
slider = binding.slider;
arrivalView.setChecked(geofence.isArrival()); arrivalView.setChecked(geofence.isArrival());
departureView.setChecked(geofence.isDeparture()); departureView.setChecked(geofence.isDeparture());
slider.setLabelFormatter( slider.setLabelFormatter(
@ -79,7 +79,7 @@ public class GeofenceDialog extends DialogFragment {
slider.setValue(Math.round((geofence.getRadius() / STEP) * STEP)); slider.setValue(Math.round((geofence.getRadius() / STEP) * STEP));
return dialogBuilder return dialogBuilder
.newDialog(original.getDisplayName()) .newDialog(original.getDisplayName())
.setView(view) .setView(binding.getRoot())
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.setOnCancelListener(this::sendResult) .setOnCancelListener(this::sendResult)
.setPositiveButton(R.string.ok, this::sendResult) .setPositiveButton(R.string.ok, this::sendResult)

@ -4,13 +4,16 @@ import static org.tasks.preferences.ResourceResolver.getData;
import android.app.Activity; import android.app.Activity;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat; import androidx.core.content.res.ResourcesCompat;
import androidx.recyclerview.widget.DiffUtil.ItemCallback; import androidx.recyclerview.widget.DiffUtil.ItemCallback;
import androidx.recyclerview.widget.ListAdapter; import androidx.recyclerview.widget.ListAdapter;
import org.tasks.Callback; import org.tasks.Callback;
import org.tasks.R; import org.tasks.R;
import org.tasks.billing.Inventory; import org.tasks.billing.Inventory;
import org.tasks.databinding.DialogIconPickerCellBinding;
import org.tasks.themes.CustomIcons; import org.tasks.themes.CustomIcons;
class IconPickerAdapter extends ListAdapter<Integer, IconPickerHolder> { class IconPickerAdapter extends ListAdapter<Integer, IconPickerHolder> {
@ -34,7 +37,7 @@ class IconPickerAdapter extends ListAdapter<Integer, IconPickerHolder> {
public IconPickerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public IconPickerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new IconPickerHolder( return new IconPickerHolder(
activity, activity,
activity.getLayoutInflater().inflate(R.layout.dialog_icon_picker_cell, parent, false), DialogIconPickerCellBinding.inflate(activity.getLayoutInflater(), parent, false),
onSelected); onSelected);
} }

@ -6,7 +6,6 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -16,12 +15,11 @@ import androidx.recyclerview.widget.RecyclerView;
import org.tasks.R; import org.tasks.R;
import org.tasks.billing.Inventory; import org.tasks.billing.Inventory;
import org.tasks.billing.PurchaseActivity; import org.tasks.billing.PurchaseActivity;
import org.tasks.databinding.DialogIconPickerBinding;
import org.tasks.themes.CustomIcons; import org.tasks.themes.CustomIcons;
import javax.inject.Inject; import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import dagger.hilt.android.AndroidEntryPoint; import dagger.hilt.android.AndroidEntryPoint;
@AndroidEntryPoint @AndroidEntryPoint
@ -29,9 +27,6 @@ public class IconPickerDialog extends DialogFragment {
private static final String EXTRA_CURRENT = "extra_current"; private static final String EXTRA_CURRENT = "extra_current";
@BindView(R.id.icons)
RecyclerView recyclerView;
@Inject DialogBuilder dialogBuilder; @Inject DialogBuilder dialogBuilder;
@Inject Activity context; @Inject Activity context;
@Inject Inventory inventory; @Inject Inventory inventory;
@ -48,23 +43,23 @@ public class IconPickerDialog extends DialogFragment {
@NonNull @NonNull
@Override @Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(context); DialogIconPickerBinding binding = DialogIconPickerBinding.inflate(LayoutInflater.from(context));
View view = inflater.inflate(R.layout.dialog_icon_picker, null);
ButterKnife.bind(this, view);
Bundle arguments = getArguments(); Bundle arguments = getArguments();
int current = arguments.getInt(EXTRA_CURRENT); int current = arguments.getInt(EXTRA_CURRENT);
IconPickerAdapter iconPickerAdapter = IconPickerAdapter iconPickerAdapter =
new IconPickerAdapter((Activity) context, inventory, current, this::onSelected); new IconPickerAdapter(context, inventory, current, this::onSelected);
RecyclerView recyclerView = binding.icons;
recyclerView.setLayoutManager(new IconLayoutManager(context)); recyclerView.setLayoutManager(new IconLayoutManager(context));
recyclerView.setAdapter(iconPickerAdapter); recyclerView.setAdapter(iconPickerAdapter);
iconPickerAdapter.submitList(CustomIcons.getIconList()); iconPickerAdapter.submitList(CustomIcons.getIconList());
AlertDialogBuilder builder = AlertDialogBuilder builder =
dialogBuilder.newDialog().setNegativeButton(R.string.cancel, null).setView(view); dialogBuilder
.newDialog()
.setNegativeButton(R.string.cancel, null)
.setView(binding.getRoot());
if (!inventory.getHasPro()) { if (!inventory.getHasPro()) {
builder.setPositiveButton( builder.setPositiveButton(
R.string.upgrade_to_pro, R.string.upgrade_to_pro,

@ -1,40 +1,36 @@
package org.tasks.dialogs; package org.tasks.dialogs;
import android.content.Context; import android.content.Context;
import android.view.View;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.AppCompatImageView;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import org.tasks.Callback; import org.tasks.Callback;
import org.tasks.R; import org.tasks.R;
import org.tasks.databinding.DialogIconPickerCellBinding;
import org.tasks.themes.DrawableUtil; import org.tasks.themes.DrawableUtil;
public class IconPickerHolder extends RecyclerView.ViewHolder { public class IconPickerHolder extends RecyclerView.ViewHolder {
private final Context context; private final Context context;
private final Callback<Integer> onClick; private final Callback<Integer> onClick;
private final AppCompatImageView imageView;
@BindView(R.id.icon)
AppCompatImageView imageView;
private int index; private int index;
private boolean isEnabled; private boolean isEnabled;
IconPickerHolder(Context context, @NonNull View view, Callback<Integer> onClick) { IconPickerHolder(Context context, DialogIconPickerCellBinding binding, Callback<Integer> onClick) {
super(view); super(binding.getRoot());
ButterKnife.bind(this, view); imageView = binding.icon;
imageView.setOnClickListener(v -> onClick());
this.context = context; this.context = context;
this.onClick = onClick; this.onClick = onClick;
} }
@OnClick(R.id.icon) private void onClick() {
void onClick() {
if (isEnabled) { if (isEnabled) {
onClick.call(index); onClick.call(index);
} else { } else {

@ -8,27 +8,29 @@ import android.content.DialogInterface;
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 android.view.LayoutInflater;
import android.view.View;
import android.widget.Chronometer; import android.widget.Chronometer;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import com.todoroo.astrid.voice.AACRecorder; import com.todoroo.astrid.voice.AACRecorder;
import dagger.hilt.android.AndroidEntryPoint;
import java.io.IOException;
import javax.inject.Inject;
import org.tasks.R; import org.tasks.R;
import org.tasks.databinding.AacRecordActivityBinding;
import org.tasks.preferences.FragmentPermissionRequestor; import org.tasks.preferences.FragmentPermissionRequestor;
import org.tasks.preferences.PermissionChecker; import org.tasks.preferences.PermissionChecker;
import org.tasks.preferences.PermissionRequestor; import org.tasks.preferences.PermissionRequestor;
import org.tasks.preferences.Preferences; import org.tasks.preferences.Preferences;
import org.tasks.themes.Theme; import org.tasks.themes.Theme;
import java.io.IOException;
import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint;
@AndroidEntryPoint @AndroidEntryPoint
public class RecordAudioDialog extends DialogFragment implements AACRecorder.AACRecorderCallbacks { public class RecordAudioDialog extends DialogFragment implements AACRecorder.AACRecorderCallbacks {
@ -38,9 +40,7 @@ public class RecordAudioDialog extends DialogFragment implements AACRecorder.AAC
@Inject FragmentPermissionRequestor permissionRequestor; @Inject FragmentPermissionRequestor permissionRequestor;
@Inject PermissionChecker permissionChecker; @Inject PermissionChecker permissionChecker;
@BindView(R.id.timer) private Chronometer timer;
Chronometer timer;
private AACRecorder recorder; private AACRecorder recorder;
static RecordAudioDialog newRecordAudioDialog(Fragment target, int requestCode) { static RecordAudioDialog newRecordAudioDialog(Fragment target, int requestCode) {
@ -52,10 +52,10 @@ public class RecordAudioDialog extends DialogFragment implements AACRecorder.AAC
@NonNull @NonNull
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater layoutInflater = theme.getLayoutInflater(getContext()); AacRecordActivityBinding binding =
View view = layoutInflater.inflate(R.layout.aac_record_activity, null); AacRecordActivityBinding.inflate(theme.getLayoutInflater(getContext()));
ButterKnife.bind(this, view); timer = binding.timer;
binding.stopRecording.setOnClickListener(v -> stopRecording());
recorder = new ViewModelProvider(this).get(AACRecorder.class); recorder = new ViewModelProvider(this).get(AACRecorder.class);
recorder.init(this, preferences); recorder.init(this, preferences);
@ -67,7 +67,7 @@ public class RecordAudioDialog extends DialogFragment implements AACRecorder.AAC
return dialogBuilder return dialogBuilder
.newDialog(R.string.audio_recording_title) .newDialog(R.string.audio_recording_title)
.setView(view) .setView(binding.getRoot())
.create(); .create();
} }
@ -88,8 +88,7 @@ public class RecordAudioDialog extends DialogFragment implements AACRecorder.AAC
stopRecording(); stopRecording();
} }
@OnClick(R.id.stop_recording) private void stopRecording() {
void stopRecording() {
recorder.stopRecording(); recorder.stopRecording();
timer.stop(); timer.stop();
} }

@ -8,8 +8,6 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import butterknife.ButterKnife
import butterknife.OnClick
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
@ -71,7 +69,6 @@ class StartDatePicker : BaseDateTimePicker() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = DialogStartDatePickerBinding.inflate(theme.getLayoutInflater(requireContext())) binding = DialogStartDatePickerBinding.inflate(theme.getLayoutInflater(requireContext()))
setupShortcutsAndCalendar() setupShortcutsAndCalendar()
ButterKnife.bind(this, binding.root)
binding.calendarView.setOnDateChangeListener { _, y, m, d -> binding.calendarView.setOnDateChangeListener { _, y, m, d ->
returnDate(day = DateTime(y, m + 1, d).millis) returnDate(day = DateTime(y, m + 1, d).millis)
refreshButtons() refreshButtons()
@ -82,7 +79,21 @@ class StartDatePicker : BaseDateTimePicker() {
?: requireArguments().getInt(EXTRA_TIME) ?: requireArguments().getInt(EXTRA_TIME)
.takeIf { Task.hasDueTime(it.toLong()) } .takeIf { Task.hasDueTime(it.toLong()) }
?: NO_TIME ?: NO_TIME
with(binding.shortcuts) {
noDateButton.setOnClickListener { clearDate() }
noTime.setOnClickListener { clearTime() }
dueDateButton.setOnClickListener { setToday() }
dayBeforeDueButton.setOnClickListener { setTomorrow() }
weekBeforeDueButton.setOnClickListener { setNextWeek() }
morningButton.setOnClickListener { setMorning() }
afternoonButton.setOnClickListener { setAfternoon() }
eveningButton.setOnClickListener { setEvening() }
nightButton.setOnClickListener { setNight() }
dueTimeButton.setOnClickListener { setDueTime() }
currentDateSelection.setOnClickListener { currentDate() }
currentTimeSelection.setOnClickListener { currentTime() }
pickTimeButton.setOnClickListener { pickTime() }
}
return binding.root return binding.root
} }
@ -128,50 +139,25 @@ class StartDatePicker : BaseDateTimePicker() {
} }
} }
@OnClick(R.id.no_date_button) private fun clearDate() = returnDate(day = 0, time = 0)
fun clearDate() = returnDate(day = 0, time = 0) private fun clearTime() = returnDate(
@OnClick(R.id.no_time)
fun clearTime() = returnDate(
day = when (selectedDay) { day = when (selectedDay) {
DUE_TIME -> DUE_DATE DUE_TIME -> DUE_DATE
else -> selectedDay else -> selectedDay
}, },
time = 0 time = 0
) )
private fun setToday() = returnDate(day = DUE_DATE)
@OnClick(R.id.due_date_button) private fun setTomorrow() = returnDate(day = DAY_BEFORE_DUE)
fun setToday() = returnDate(day = DUE_DATE) private fun setNextWeek() = returnDate(day = WEEK_BEFORE_DUE)
private fun setMorning() = returnSelectedTime(morning)
@OnClick(R.id.day_before_due_button) private fun setAfternoon() = returnSelectedTime(afternoon)
fun setTomorrow() = returnDate(day = DAY_BEFORE_DUE) private fun setEvening() = returnSelectedTime(evening)
private fun setNight() = returnSelectedTime(night)
@OnClick(R.id.week_before_due_button) private fun setDueTime() = returnDate(day = DUE_TIME, time = NO_TIME)
fun setNextWeek() = returnDate(day = WEEK_BEFORE_DUE) private fun currentDate() = returnDate(day = customDate)
private fun currentTime() = returnSelectedTime(customTime)
@OnClick(R.id.morning_button) private fun pickTime() {
fun setMorning() = returnSelectedTime(morning)
@OnClick(R.id.afternoon_button)
fun setAfternoon() = returnSelectedTime(afternoon)
@OnClick(R.id.evening_button)
fun setEvening() = returnSelectedTime(evening)
@OnClick(R.id.night_button)
fun setNight() = returnSelectedTime(night)
@OnClick(R.id.due_time_button)
fun setDueTime() = returnDate(day = DUE_TIME, time = NO_TIME)
@OnClick(R.id.current_date_selection)
fun currentDate() = returnDate(day = customDate)
@OnClick(R.id.current_time_selection)
fun currentTime() = returnSelectedTime(customTime)
@OnClick(R.id.pick_time_button)
fun pickTime() {
val time = if (selectedTime < 0 || !Task.hasDueTime(today.withMillisOfDay(selectedTime).millis)) { val time = if (selectedTime < 0 || !Task.hasDueTime(today.withMillisOfDay(selectedTime).millis)) {
today.noon().millisOfDay today.noon().millisOfDay
} else { } else {

@ -5,7 +5,6 @@ import android.os.Bundle
import android.view.View import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import butterknife.OnCheckedChanged
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import com.todoroo.astrid.helper.UUIDHelper import com.todoroo.astrid.helper.UUIDHelper
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@ -28,6 +27,9 @@ class EtebaseAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding.repeat.visibility = View.GONE binding.repeat.visibility = View.GONE
binding.showAdvanced.visibility = View.VISIBLE binding.showAdvanced.visibility = View.VISIBLE
binding.showAdvanced.setOnCheckedChangeListener { _, _ ->
updateUrlVisibility()
}
updateUrlVisibility() updateUrlVisibility()
} }
@ -71,11 +73,6 @@ class EtebaseAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool
saveAccountAndFinish() saveAccountAndFinish()
} }
@OnCheckedChanged(R.id.show_advanced)
fun toggleUrl() {
updateUrlVisibility()
}
private fun updateUrlVisibility() { private fun updateUrlVisibility() {
binding.urlLayout.visibility = if (binding.showAdvanced.isChecked) View.VISIBLE else View.GONE binding.urlLayout.visibility = if (binding.showAdvanced.isChecked) View.VISIBLE else View.GONE
} }

@ -7,10 +7,9 @@ import android.view.MenuItem
import android.view.View import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import at.bitfire.dav4jvm.exception.HttpException import at.bitfire.dav4jvm.exception.HttpException
import butterknife.ButterKnife
import butterknife.OnTextChanged
import com.etesync.journalmanager.Constants.Companion.CURRENT_VERSION import com.etesync.journalmanager.Constants.Companion.CURRENT_VERSION
import com.etesync.journalmanager.Crypto.CryptoManager import com.etesync.journalmanager.Crypto.CryptoManager
import com.etesync.journalmanager.Crypto.deriveKey import com.etesync.journalmanager.Crypto.deriveKey
@ -45,7 +44,6 @@ class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.O
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityEtesyncEncryptionSettingsBinding.inflate(layoutInflater) binding = ActivityEtesyncEncryptionSettingsBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
ButterKnife.bind(this)
val intent = intent val intent = intent
caldavAccount = intent.getParcelableExtra(EXTRA_ACCOUNT) caldavAccount = intent.getParcelableExtra(EXTRA_ACCOUNT)
userInfo = intent.getSerializableExtra(EXTRA_USER_INFO) as UserInfoManager.UserInfo userInfo = intent.getSerializableExtra(EXTRA_USER_INFO) as UserInfoManager.UserInfo
@ -64,6 +62,12 @@ class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.O
if (createUserInfoViewModel.inProgress) { if (createUserInfoViewModel.inProgress) {
showProgressIndicator() showProgressIndicator()
} }
binding.repeatEncryptionPassword.addTextChangedListener(
onTextChanged = { _, _, _, _ -> onRepeatEncryptionPasswordChanged() }
)
binding.encryptionPassword.addTextChangedListener(
onTextChanged = { _, _, _, _ -> onEncryptionPasswordChanged() }
)
} }
private fun showProgressIndicator() { private fun showProgressIndicator() {
@ -153,13 +157,11 @@ class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.O
return snackbar return snackbar
} }
@OnTextChanged(R.id.repeat_encryption_password) private fun onRepeatEncryptionPasswordChanged() {
fun onRpeatEncryptionPasswordChanged() {
binding.repeatEncryptionPasswordLayout.error = null binding.repeatEncryptionPasswordLayout.error = null
} }
@OnTextChanged(R.id.encryption_password) private fun onEncryptionPasswordChanged() {
fun onEncryptionPasswordChanged() {
binding.encryptionPasswordLayout.error = null binding.encryptionPasswordLayout.error = null
} }

@ -9,7 +9,6 @@ import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.util.Pair import androidx.core.util.Pair
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import butterknife.OnCheckedChanged
import com.etesync.journalmanager.Crypto.CryptoManager import com.etesync.journalmanager.Crypto.CryptoManager
import com.etesync.journalmanager.Exceptions.IntegrityException import com.etesync.journalmanager.Exceptions.IntegrityException
import com.etesync.journalmanager.Exceptions.VersionTooNewException import com.etesync.journalmanager.Exceptions.VersionTooNewException
@ -41,6 +40,7 @@ class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool
binding.description.visibility = View.VISIBLE binding.description.visibility = View.VISIBLE
binding.description.setTextColor(ContextCompat.getColor(this, R.color.overdue)) binding.description.setTextColor(ContextCompat.getColor(this, R.color.overdue))
binding.description.setText(description) binding.description.setText(description)
binding.showAdvanced.setOnCheckedChangeListener { _, _ -> updateUrlVisibility() }
updateUrlVisibility() updateUrlVisibility()
} }
@ -108,11 +108,6 @@ class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool
return false return false
} }
@OnCheckedChanged(R.id.show_advanced)
fun toggleUrl() {
updateUrlVisibility()
}
private fun updateUrlVisibility() { private fun updateUrlVisibility() {
binding.urlLayout.visibility = if (binding.showAdvanced.isChecked) View.VISIBLE else View.GONE binding.urlLayout.visibility = if (binding.showAdvanced.isChecked) View.VISIBLE else View.GONE
} }

@ -14,12 +14,13 @@ import android.view.inputmethod.EditorInfo
import android.widget.EditText import android.widget.EditText
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import butterknife.* import androidx.core.widget.addTextChangedListener
import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.AndroidUtilities
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.Strings.isNullOrEmpty import org.tasks.Strings.isNullOrEmpty
import org.tasks.activities.CameraActivity import org.tasks.activities.CameraActivity
import org.tasks.databinding.FragmentCommentBarBinding
import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.DialogBuilder
import org.tasks.files.ImageHelper import org.tasks.files.ImageHelper
import org.tasks.preferences.Device import org.tasks.preferences.Device
@ -37,18 +38,10 @@ class CommentBarFragment : TaskEditControlFragment() {
@Inject lateinit var preferences: Preferences @Inject lateinit var preferences: Preferences
@Inject lateinit var themeColor: ThemeColor @Inject lateinit var themeColor: ThemeColor
@BindView(R.id.commentButton) private lateinit var commentButton: View
lateinit var commentButton: View private lateinit var commentField: EditText
private lateinit var pictureButton: ImageView
@BindView(R.id.commentField) private lateinit var commentBar: LinearLayout
lateinit var commentField: EditText
@BindView(R.id.picture)
lateinit var pictureButton: ImageView
@BindView(R.id.updatesFooter)
lateinit var commentBar: LinearLayout
private lateinit var callback: CommentBarFragmentCallback private lateinit var callback: CommentBarFragmentCallback
private var pendingCommentPicture: Uri? = null private var pendingCommentPicture: Uri? = null
@ -59,8 +52,7 @@ class CommentBarFragment : TaskEditControlFragment() {
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(layout, container, false) val view = bind(container)
ButterKnife.bind(this, view)
createView(savedInstanceState) createView(savedInstanceState)
return view return view
} }
@ -83,19 +75,33 @@ class CommentBarFragment : TaskEditControlFragment() {
resetPictureButton() resetPictureButton()
} }
override val layout = R.layout.fragment_comment_bar override fun bind(parent: ViewGroup?) =
FragmentCommentBarBinding.inflate(layoutInflater, parent, false).let {
commentButton = it.commentButton.apply {
setOnClickListener { addClicked() }
}
commentField = it.commentField.apply {
addTextChangedListener(
onTextChanged = { text, _, _, _ -> onTextChanged(text?.toString()) }
)
setOnEditorActionListener { _, _, event -> onEditorAction(event) }
}
pictureButton = it.picture.apply {
setOnClickListener { onClickPicture() }
}
commentBar = it.updatesFooter
it.root
}
override val icon = 0 override val icon = 0
override fun controlId() = TAG override fun controlId() = TAG
@OnTextChanged(R.id.commentField) private fun onTextChanged(s: String?) {
fun onTextChanged(s: CharSequence) {
commentButton.visibility = if (pendingCommentPicture == null && isNullOrEmpty(s.toString())) View.GONE else View.VISIBLE commentButton.visibility = if (pendingCommentPicture == null && isNullOrEmpty(s.toString())) View.GONE else View.VISIBLE
} }
@OnEditorAction(R.id.commentField) private fun onEditorAction(key: KeyEvent?): Boolean {
fun onEditorAction(key: KeyEvent?): Boolean {
val actionId = key?.action ?: 0 val actionId = key?.action ?: 0
if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_NULL) { if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_NULL) {
if (commentField.text.isNotEmpty() || pendingCommentPicture != null) { if (commentField.text.isNotEmpty() || pendingCommentPicture != null) {
@ -106,8 +112,7 @@ class CommentBarFragment : TaskEditControlFragment() {
return false return false
} }
@OnClick(R.id.commentButton) private fun addClicked() {
fun addClicked() {
addComment() addComment()
} }
@ -119,8 +124,7 @@ class CommentBarFragment : TaskEditControlFragment() {
} }
} }
@OnClick(R.id.picture) private fun onClickPicture() {
fun onClickPicture() {
if (pendingCommentPicture == null) { if (pendingCommentPicture == null) {
showPictureLauncher(null) showPictureLauncher(null)
} else { } else {

@ -16,9 +16,6 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.AppBarLayout.Behavior.DragCallback import com.google.android.material.appbar.AppBarLayout.Behavior.DragCallback
import com.google.android.material.appbar.AppBarLayout.OnOffsetChangedListener import com.google.android.material.appbar.AppBarLayout.OnOffsetChangedListener
@ -41,6 +38,7 @@ import org.tasks.data.LocationDao
import org.tasks.data.Place import org.tasks.data.Place
import org.tasks.data.Place.Companion.newPlace import org.tasks.data.Place.Companion.newPlace
import org.tasks.data.PlaceUsage import org.tasks.data.PlaceUsage
import org.tasks.databinding.ActivityLocationPickerBinding
import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.DialogBuilder
import org.tasks.extensions.Context.toast import org.tasks.extensions.Context.toast
import org.tasks.injection.InjectingAppCompatActivity import org.tasks.injection.InjectingAppCompatActivity
@ -60,29 +58,14 @@ import kotlin.math.abs
@AndroidEntryPoint @AndroidEntryPoint
class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemClickListener, MapFragmentCallback, OnLocationPicked, SearchView.OnQueryTextListener, OnPredictionPicked, MenuItem.OnActionExpandListener { class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemClickListener, MapFragmentCallback, OnLocationPicked, SearchView.OnQueryTextListener, OnPredictionPicked, MenuItem.OnActionExpandListener {
@BindView(R.id.toolbar) private lateinit var toolbar: Toolbar
lateinit var toolbar: Toolbar private lateinit var appBarLayout: AppBarLayout
private lateinit var toolbarLayout: CollapsingToolbarLayout
@BindView(R.id.app_bar_layout) private lateinit var coordinatorLayout: CoordinatorLayout
lateinit var appBarLayout: AppBarLayout private lateinit var searchView: View
private lateinit var loadingIndicator: ContentLoadingProgressBar
@BindView(R.id.collapsing_toolbar_layout) private lateinit var chooseRecentLocation: View
lateinit var toolbarLayout: CollapsingToolbarLayout private lateinit var recyclerView: RecyclerView
@BindView(R.id.coordinator)
lateinit var coordinatorLayout: CoordinatorLayout
@BindView(R.id.search)
lateinit var searchView: View
@BindView(R.id.loading_indicator)
lateinit var loadingIndicator: ContentLoadingProgressBar
@BindView(R.id.choose_recent_location)
lateinit var chooseRecentLocation: View
@BindView(R.id.recent_locations)
lateinit var recyclerView: RecyclerView
@Inject lateinit var theme: Theme @Inject lateinit var theme: Theme
@Inject lateinit var locationDao: LocationDao @Inject lateinit var locationDao: LocationDao
@ -110,8 +93,18 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
theme.applyTheme(this) theme.applyTheme(this)
setContentView(R.layout.activity_location_picker) val binding = ActivityLocationPickerBinding.inflate(layoutInflater)
ButterKnife.bind(this) setContentView(binding.root)
toolbar = binding.toolbar
appBarLayout = binding.appBarLayout
toolbarLayout = binding.collapsingToolbarLayout
coordinatorLayout = binding.coordinator
searchView = binding.search.apply {
setOnClickListener { searchPlace() }
}
loadingIndicator = binding.loadingIndicator
chooseRecentLocation = binding.chooseRecentLocation
recyclerView = binding.recentLocations
val configuration = resources.configuration val configuration = resources.configuration
if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
&& configuration.smallestScreenWidthDp < 480) { && configuration.smallestScreenWidthDp < 480) {
@ -180,6 +173,9 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC
recentsAdapter!!.setHasStableIds(true) recentsAdapter!!.setHasStableIds(true)
recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = if (search.isActionViewExpanded) searchAdapter else recentsAdapter recyclerView.adapter = if (search.isActionViewExpanded) searchAdapter else recentsAdapter
binding.currentLocation.setOnClickListener { currentLocation() }
binding.selectThisLocation.setOnClickListener { selectLocation() }
} }
override fun onMapReady(mapFragment: MapFragment) { override fun onMapReady(mapFragment: MapFragment) {
@ -211,8 +207,7 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC
returnPlace(place) returnPlace(place)
} }
@OnClick(R.id.current_location) private fun currentLocation() {
fun onClick() {
if (permissionRequestor.requestForegroundLocation()) { if (permissionRequestor.requestForegroundLocation()) {
moveToCurrentLocation(true) moveToCurrentLocation(true)
} }
@ -236,8 +231,7 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC
} }
} }
@OnClick(R.id.select_this_location) private fun selectLocation() {
fun selectLocation() {
val mapPosition = map.mapPosition ?: return val mapPosition = map.mapPosition ?: return
loadingIndicator.visibility = View.VISIBLE loadingIndicator.visibility = View.VISIBLE
lifecycleScope.launch { lifecycleScope.launch {
@ -251,8 +245,7 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC
} }
} }
@OnClick(R.id.search) private fun searchPlace() {
fun searchPlace() {
mapPosition = map.mapPosition mapPosition = map.mapPosition
expandToolbar(true) expandToolbar(true)
search.expandActionView() search.expandActionView()

@ -2,8 +2,6 @@ package org.tasks.opentasks
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.widget.RelativeLayout
import butterknife.BindView
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.caldav.BaseCaldavCalendarSettingsActivity import org.tasks.caldav.BaseCaldavCalendarSettingsActivity
@ -13,9 +11,6 @@ import org.tasks.data.CaldavCalendar
@AndroidEntryPoint @AndroidEntryPoint
class OpenTasksListSettingsActivity : BaseCaldavCalendarSettingsActivity() { class OpenTasksListSettingsActivity : BaseCaldavCalendarSettingsActivity() {
@BindView(R.id.color_row)
lateinit var colorRow: RelativeLayout
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

@ -3,15 +3,18 @@ package org.tasks.preferences.beast;
import android.content.Context; import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.tasks.R;
import org.tasks.databinding.PreferenceDraggableRowBinding;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import org.tasks.R;
public class BeastModeRecyclerAdapter extends RecyclerView.Adapter<BeastModeViewHolder> { public class BeastModeRecyclerAdapter extends RecyclerView.Adapter<BeastModeViewHolder> {
@ -42,10 +45,10 @@ public class BeastModeRecyclerAdapter extends RecyclerView.Adapter<BeastModeView
@Override @Override
public BeastModeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public BeastModeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = return new BeastModeViewHolder(
LayoutInflater.from(parent.getContext()) PreferenceDraggableRowBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false),
.inflate(R.layout.preference_draggable_row, parent, false); itemTouchHelper
return new BeastModeViewHolder(view, itemTouchHelper); );
} }
@Override @Override

@ -3,33 +3,30 @@ package org.tasks.preferences.beast;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import androidx.core.view.MotionEventCompat; import androidx.core.view.MotionEventCompat;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife; import org.tasks.databinding.PreferenceDraggableRowBinding;
import butterknife.OnTouch;
import org.tasks.R;
class BeastModeViewHolder extends RecyclerView.ViewHolder { class BeastModeViewHolder extends RecyclerView.ViewHolder {
private final ItemTouchHelper itemTouchHelper; private final ItemTouchHelper itemTouchHelper;
private final TextView textView;
@BindView(R.id.text) BeastModeViewHolder(PreferenceDraggableRowBinding binding, ItemTouchHelper itemTouchHelper) {
TextView textView; super(binding.getRoot());
BeastModeViewHolder(View itemView, ItemTouchHelper itemTouchHelper) {
super(itemView);
this.itemTouchHelper = itemTouchHelper; this.itemTouchHelper = itemTouchHelper;
ButterKnife.bind(this, itemView); textView = binding.text;
binding.grabber.setOnTouchListener(this::onTouch);
} }
void setText(String text) { void setText(String text) {
textView.setText(text); textView.setText(text);
} }
@OnTouch(R.id.grabber) private boolean onTouch(View v, MotionEvent event) {
boolean onTouch(MotionEvent event) {
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) { if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
itemTouchHelper.startDrag(this); itemTouchHelper.startDrag(this);
} }

@ -2,7 +2,6 @@ package org.tasks.repeats;
import static android.app.Activity.RESULT_OK; import static android.app.Activity.RESULT_OK;
import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.newArrayList;
import static java.util.Arrays.asList;
import static net.fortuna.ical4j.model.Recur.Frequency.DAILY; import static net.fortuna.ical4j.model.Recur.Frequency.DAILY;
import static net.fortuna.ical4j.model.Recur.Frequency.HOURLY; import static net.fortuna.ical4j.model.Recur.Frequency.HOURLY;
import static net.fortuna.ical4j.model.Recur.Frequency.MINUTELY; import static net.fortuna.ical4j.model.Recur.Frequency.MINUTELY;
@ -14,6 +13,7 @@ import static org.tasks.dialogs.MyDatePickerDialog.newDatePicker;
import static org.tasks.repeats.BasicRecurrenceDialog.EXTRA_RRULE; import static org.tasks.repeats.BasicRecurrenceDialog.EXTRA_RRULE;
import static org.tasks.repeats.RecurrenceUtils.newRecur; import static org.tasks.repeats.RecurrenceUtils.newRecur;
import static org.tasks.time.DateTimeUtils.currentTimeMillis; import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import static java.util.Arrays.asList;
import android.app.Activity; import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
@ -39,31 +39,39 @@ import android.widget.RadioGroup;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.ToggleButton; import android.widget.ToggleButton;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatSpinner;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnItemSelected;
import butterknife.OnTextChanged;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import dagger.hilt.android.AndroidEntryPoint;
import java.text.DateFormatSymbols;
import java.time.format.FormatStyle;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.inject.Inject;
import net.fortuna.ical4j.model.Recur; import net.fortuna.ical4j.model.Recur;
import net.fortuna.ical4j.model.Recur.Frequency; import net.fortuna.ical4j.model.Recur.Frequency;
import net.fortuna.ical4j.model.WeekDay; import net.fortuna.ical4j.model.WeekDay;
import org.tasks.R; import org.tasks.R;
import org.tasks.databinding.ControlSetRepeatBinding;
import org.tasks.databinding.WeekButtonsBinding;
import org.tasks.dialogs.DialogBuilder; import org.tasks.dialogs.DialogBuilder;
import org.tasks.dialogs.MyDatePickerDialog; import org.tasks.dialogs.MyDatePickerDialog;
import org.tasks.locale.Locale; import org.tasks.locale.Locale;
import org.tasks.preferences.ResourceResolver; import org.tasks.preferences.ResourceResolver;
import org.tasks.time.DateTime; import org.tasks.time.DateTime;
import org.tasks.ui.OnItemSelected;
import org.tasks.ui.OnTextChanged;
import java.text.DateFormatSymbols;
import java.time.format.FormatStyle;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint;
import timber.log.Timber; import timber.log.Timber;
@AndroidEntryPoint @AndroidEntryPoint
@ -79,63 +87,16 @@ public class CustomRecurrenceDialog extends DialogFragment {
@Inject DialogBuilder dialogBuilder; @Inject DialogBuilder dialogBuilder;
@Inject Locale locale; @Inject Locale locale;
@BindView(R.id.weekGroup) private LinearLayout weekGroup1;
LinearLayout weekGroup1; @Nullable private LinearLayout weekGroup2;
private RadioGroup monthGroup;
@BindView(R.id.weekGroup2) private RadioButton repeatMonthlyDayOfNthWeek;
@Nullable private RadioButton repeatMonthlyDayOfLastWeek;
LinearLayout weekGroup2; private Spinner repeatUntilSpinner;
private EditText intervalEditText;
@BindView(R.id.week_day_1) private TextView intervalTextView;
ToggleButton day1; private EditText repeatTimes;
private TextView repeatTimesText;
@BindView(R.id.week_day_2)
ToggleButton day2;
@BindView(R.id.week_day_3)
ToggleButton day3;
@BindView(R.id.week_day_4)
ToggleButton day4;
@BindView(R.id.week_day_5)
ToggleButton day5;
@BindView(R.id.week_day_6)
ToggleButton day6;
@BindView(R.id.week_day_7)
ToggleButton day7;
@BindView(R.id.month_group)
RadioGroup monthGroup;
@BindView(R.id.repeat_monthly_same_day)
RadioButton repeatMonthlySameDay;
@BindView(R.id.repeat_monthly_day_of_nth_week)
RadioButton repeatMonthlyDayOfNthWeek;
@BindView(R.id.repeat_monthly_day_of_last_week)
RadioButton repeatMonthlyDayOfLastWeek;
@BindView(R.id.repeat_until)
Spinner repeatUntilSpinner;
@BindView(R.id.frequency)
Spinner frequencySpinner;
@BindView(R.id.intervalValue)
EditText intervalEditText;
@BindView(R.id.intervalText)
TextView intervalTextView;
@BindView(R.id.repeatTimesValue)
EditText repeatTimes;
@BindView(R.id.repeatTimesText)
TextView repeatTimesText;
private ArrayAdapter<String> repeatUntilAdapter; private ArrayAdapter<String> repeatUntilAdapter;
private ToggleButton[] weekButtons; private ToggleButton[] weekButtons;
@ -159,7 +120,8 @@ public class CustomRecurrenceDialog extends DialogFragment {
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(context); LayoutInflater inflater = LayoutInflater.from(context);
View dialogView = inflater.inflate(R.layout.control_set_repeat, null); ControlSetRepeatBinding binding = ControlSetRepeatBinding.inflate(inflater);
WeekButtonsBinding weekBinding = WeekButtonsBinding.bind(binding.getRoot());
Bundle arguments = getArguments(); Bundle arguments = getArguments();
dueDate = arguments.getLong(EXTRA_DATE, currentTimeMillis()); dueDate = arguments.getLong(EXTRA_DATE, currentTimeMillis());
@ -183,7 +145,45 @@ public class CustomRecurrenceDialog extends DialogFragment {
DateFormatSymbols dfs = new DateFormatSymbols(locale.getLocale()); DateFormatSymbols dfs = new DateFormatSymbols(locale.getLocale());
String[] shortWeekdays = dfs.getShortWeekdays(); String[] shortWeekdays = dfs.getShortWeekdays();
ButterKnife.bind(this, dialogView); weekGroup1 = weekBinding.weekGroup;
weekGroup2 = weekBinding.weekGroup2;
monthGroup = binding.monthGroup;
repeatMonthlyDayOfNthWeek = binding.repeatMonthlyDayOfNthWeek;
repeatMonthlyDayOfLastWeek = binding.repeatMonthlyDayOfLastWeek;
repeatUntilSpinner = binding.repeatUntil;
repeatUntilSpinner.setOnItemSelectedListener(new OnItemSelected() {
@Override
public void onItemSelected(int position) {
onRepeatUntilChanged(position);
}
});
intervalEditText = binding.intervalValue;
intervalEditText.addTextChangedListener(new OnTextChanged() {
@Override
public void onTextChanged(@Nullable CharSequence text) {
if (text != null) {
onRepeatValueChanged(text);
}
}
});
intervalTextView = binding.intervalText;
repeatTimes = binding.repeatTimesValue;
repeatTimes.addTextChangedListener(new OnTextChanged() {
@Override
public void onTextChanged(@Nullable CharSequence text) {
if (text != null) {
onRepeatTimesValueChanged(text);
}
}
});
repeatTimesText = binding.repeatTimesText;
AppCompatSpinner frequency = binding.frequency;
frequency.setOnItemSelectedListener(new OnItemSelected() {
@Override
public void onItemSelected(int position) {
onFrequencyChanged(position);
}
});
Calendar dayOfMonthCalendar = Calendar.getInstance(locale.getLocale()); Calendar dayOfMonthCalendar = Calendar.getInstance(locale.getLocale());
dayOfMonthCalendar.setTimeInMillis(dueDate); dayOfMonthCalendar.setTimeInMillis(dueDate);
@ -233,14 +233,14 @@ public class CustomRecurrenceDialog extends DialogFragment {
} }
if (monthGroup.getCheckedRadioButtonId() != R.id.repeat_monthly_day_of_last_week if (monthGroup.getCheckedRadioButtonId() != R.id.repeat_monthly_day_of_last_week
&& monthGroup.getCheckedRadioButtonId() != R.id.repeat_monthly_day_of_nth_week) { && monthGroup.getCheckedRadioButtonId() != R.id.repeat_monthly_day_of_nth_week) {
repeatMonthlySameDay.setChecked(true); binding.repeatMonthlySameDay.setChecked(true);
} }
ArrayAdapter<CharSequence> frequencyAdapter = ArrayAdapter<CharSequence> frequencyAdapter =
ArrayAdapter.createFromResource(context, R.array.repeat_frequency, R.layout.frequency_item); ArrayAdapter.createFromResource(context, R.array.repeat_frequency, R.layout.frequency_item);
frequencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); frequencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
frequencySpinner.setAdapter(frequencyAdapter); frequency.setAdapter(frequencyAdapter);
frequencySpinner.setSelection(FREQUENCIES.indexOf(rrule.getFrequency())); frequency.setSelection(FREQUENCIES.indexOf(rrule.getFrequency()));
intervalEditText.setText(locale.formatNumber(rrule.getInterval())); intervalEditText.setText(locale.formatNumber(rrule.getInterval()));
@ -273,7 +273,15 @@ public class CustomRecurrenceDialog extends DialogFragment {
repeatUntilSpinner.setAdapter(repeatUntilAdapter); repeatUntilSpinner.setAdapter(repeatUntilAdapter);
updateRepeatUntilOptions(); updateRepeatUntilOptions();
weekButtons = new ToggleButton[] {day1, day2, day3, day4, day5, day6, day7}; weekButtons = new ToggleButton[]{
weekBinding.weekDay1.button,
weekBinding.weekDay2.button,
weekBinding.weekDay3.button,
weekBinding.weekDay4.button,
weekBinding.weekDay5.button,
weekBinding.weekDay6.button,
weekBinding.weekDay7.button
};
// set up days of week // set up days of week
Calendar dayOfWeekCalendar = Calendar.getInstance(locale.getLocale()); Calendar dayOfWeekCalendar = Calendar.getInstance(locale.getLocale());
@ -336,7 +344,7 @@ public class CustomRecurrenceDialog extends DialogFragment {
return dialogBuilder return dialogBuilder
.newDialog() .newDialog()
.setView(dialogView) .setView(binding.getRoot())
.setPositiveButton(R.string.ok, this::onRuleSelected) .setPositiveButton(R.string.ok, this::onRuleSelected)
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.show(); .show();
@ -448,8 +456,7 @@ public class CustomRecurrenceDialog extends DialogFragment {
} }
} }
@OnItemSelected(R.id.repeat_until) private void onRepeatUntilChanged(int position) {
public void onRepeatUntilChanged(int position) {
if (repeatUntilOptions.size() == 4) { if (repeatUntilOptions.size() == 4) {
position--; position--;
} }
@ -466,8 +473,7 @@ public class CustomRecurrenceDialog extends DialogFragment {
} }
} }
@OnItemSelected(R.id.frequency) private void onFrequencyChanged(int position) {
public void onFrequencyChanged(int position) {
Frequency frequency = FREQUENCIES.get(position); Frequency frequency = FREQUENCIES.get(position);
rrule.setFrequency(frequency.name()); rrule.setFrequency(frequency.name());
int weekVisibility = frequency == WEEKLY ? View.VISIBLE : View.GONE; int weekVisibility = frequency == WEEKLY ? View.VISIBLE : View.GONE;
@ -479,8 +485,7 @@ public class CustomRecurrenceDialog extends DialogFragment {
updateIntervalTextView(); updateIntervalTextView();
} }
@OnTextChanged(R.id.intervalValue) private void onRepeatValueChanged(CharSequence text) {
public void onRepeatValueChanged(CharSequence text) {
Integer value = locale.parseInteger(text.toString()); Integer value = locale.parseInteger(text.toString());
if (value == null) { if (value == null) {
return; return;
@ -492,8 +497,7 @@ public class CustomRecurrenceDialog extends DialogFragment {
} }
} }
@OnTextChanged(R.id.repeatTimesValue) private void onRepeatTimesValueChanged(CharSequence text) {
public void onRepeatTimesValueChanged(CharSequence text) {
Integer value = locale.parseInteger(text.toString()); Integer value = locale.parseInteger(text.toString());
if (value == null) { if (value == null) {
return; return;

@ -5,20 +5,17 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.widget.EditText import android.widget.EditText
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.Toolbar import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnTextChanged
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.tasks.R import org.tasks.R
import org.tasks.Strings.isNullOrEmpty import org.tasks.Strings.isNullOrEmpty
import org.tasks.billing.Inventory import org.tasks.billing.Inventory
import org.tasks.data.TagData import org.tasks.data.TagData
import org.tasks.databinding.ActivityTagPickerBinding
import org.tasks.injection.ThemedInjectingAppCompatActivity import org.tasks.injection.ThemedInjectingAppCompatActivity
import org.tasks.themes.ColorProvider import org.tasks.themes.ColorProvider
import org.tasks.themes.Theme import org.tasks.themes.Theme
@ -27,19 +24,13 @@ import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class TagPickerActivity : ThemedInjectingAppCompatActivity() { class TagPickerActivity : ThemedInjectingAppCompatActivity() {
@BindView(R.id.toolbar)
lateinit var toolbar: Toolbar
@BindView(R.id.recycler_view)
lateinit var recyclerView: RecyclerView
@BindView(R.id.search_input)
lateinit var editText: EditText
@Inject lateinit var theme: Theme @Inject lateinit var theme: Theme
@Inject lateinit var inventory: Inventory @Inject lateinit var inventory: Inventory
@Inject lateinit var colorProvider: ColorProvider @Inject lateinit var colorProvider: ColorProvider
private val viewModel: TagPickerViewModel by viewModels() private val viewModel: TagPickerViewModel by viewModels()
private var taskIds: ArrayList<Long>? = null private var taskIds: ArrayList<Long>? = null
private lateinit var editText: EditText
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -53,8 +44,14 @@ class TagPickerActivity : ThemedInjectingAppCompatActivity() {
) )
} }
} }
setContentView(R.layout.activity_tag_picker) val binding = ActivityTagPickerBinding.inflate(layoutInflater)
ButterKnife.bind(this) editText = binding.searchInput.apply {
addTextChangedListener(
onTextChanged = { text, _, _, _ -> onSearch(text) }
)
}
setContentView(binding.root)
val toolbar = binding.toolbar
toolbar.setNavigationIcon(R.drawable.ic_outline_arrow_back_24px) toolbar.setNavigationIcon(R.drawable.ic_outline_arrow_back_24px)
toolbar.setNavigationOnClickListener { onBackPressed() } toolbar.setNavigationOnClickListener { onBackPressed() }
val themeColor = theme.themeColor val themeColor = theme.themeColor
@ -64,6 +61,7 @@ class TagPickerActivity : ThemedInjectingAppCompatActivity() {
val recyclerAdapter = TagRecyclerAdapter(this, viewModel, inventory, colorProvider) { tagData, vh -> val recyclerAdapter = TagRecyclerAdapter(this, viewModel, inventory, colorProvider) { tagData, vh ->
onToggle(tagData, vh) onToggle(tagData, vh)
} }
val recyclerView = binding.recyclerView
recyclerView.adapter = recyclerAdapter recyclerView.adapter = recyclerAdapter
(recyclerView.itemAnimator as DefaultItemAnimator?)!!.supportsChangeAnimations = false (recyclerView.itemAnimator as DefaultItemAnimator?)!!.supportsChangeAnimations = false
recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.layoutManager = LinearLayoutManager(this)
@ -80,9 +78,8 @@ class TagPickerActivity : ThemedInjectingAppCompatActivity() {
} }
} }
@OnTextChanged(R.id.search_input) private fun onSearch(text: CharSequence?) {
fun onSearch(text: CharSequence) { viewModel.search(text?.toString() ?: "")
viewModel.search(text.toString())
} }
override fun onBackPressed() { override fun onBackPressed() {

@ -4,34 +4,27 @@ import android.content.Context
import android.view.View import android.view.View
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnCheckedChanged
import butterknife.OnClick
import org.tasks.R import org.tasks.R
import org.tasks.data.TagData import org.tasks.data.TagData
import org.tasks.tags.CheckBoxTriStates import org.tasks.databinding.RowTagPickerBinding
import org.tasks.themes.DrawableUtil import org.tasks.themes.DrawableUtil
class TagPickerViewHolder internal constructor( class TagPickerViewHolder internal constructor(
private val context: Context, private val context: Context,
view: View, binding: RowTagPickerBinding,
private val callback: (TagData, TagPickerViewHolder) -> Unit private val callback: (TagData, TagPickerViewHolder) -> Unit
) : RecyclerView.ViewHolder(view) { ) : RecyclerView.ViewHolder(binding.root) {
val isChecked: Boolean val isChecked: Boolean
get() = checkBox.isChecked get() = checkBox.isChecked
@BindView(R.id.text) private val text: TextView = binding.text
lateinit var text: TextView private val checkBox: CheckBoxTriStates = binding.checkbox.apply {
setOnCheckedChangeListener { _, _ -> onCheckedChanged() }
@BindView(R.id.checkbox) }
lateinit var checkBox: CheckBoxTriStates
private var tagData: TagData? = null private var tagData: TagData? = null
@OnClick(R.id.tag_row) private fun onClickRow() {
fun onClickRow() {
if (tagData!!.id == null) { if (tagData!!.id == null) {
callback(tagData!!, this) callback(tagData!!, this)
} else { } else {
@ -39,8 +32,7 @@ class TagPickerViewHolder internal constructor(
} }
} }
@OnCheckedChanged(R.id.checkbox) private fun onCheckedChanged() {
fun onCheckedChanged() {
callback(tagData!!, this) callback(tagData!!, this)
} }
@ -73,6 +65,6 @@ class TagPickerViewHolder internal constructor(
} }
init { init {
ButterKnife.bind(this, view) binding.tagRow.setOnClickListener { onClickRow() }
} }
} }

@ -8,6 +8,7 @@ import androidx.recyclerview.widget.RecyclerView
import org.tasks.R import org.tasks.R
import org.tasks.billing.Inventory import org.tasks.billing.Inventory
import org.tasks.data.TagData import org.tasks.data.TagData
import org.tasks.databinding.RowTagPickerBinding
import org.tasks.themes.ColorProvider import org.tasks.themes.ColorProvider
import org.tasks.themes.CustomIcons.getIconResId import org.tasks.themes.CustomIcons.getIconResId
@ -21,10 +22,12 @@ internal class TagRecyclerAdapter(
private val differ: AsyncListDiffer<TagData> = AsyncListDiffer(this, TagDiffCallback()) private val differ: AsyncListDiffer<TagData> = AsyncListDiffer(this, TagDiffCallback())
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TagPickerViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
val view = LayoutInflater.from(context).inflate(R.layout.row_tag_picker, parent, false) TagPickerViewHolder(
return TagPickerViewHolder(context, view, callback) context,
} RowTagPickerBinding.inflate(LayoutInflater.from(context), parent, false),
callback
)
override fun onBindViewHolder(holder: TagPickerViewHolder, position: Int) { override fun onBindViewHolder(holder: TagPickerViewHolder, position: Int) {
val tagData = differ.currentList[position] val tagData = differ.currentList[position]

@ -6,16 +6,16 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams; import android.view.ViewGroup.MarginLayoutParams;
import android.widget.TextView; import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import com.google.android.material.chip.Chip; import com.google.android.material.chip.Chip;
import com.google.android.material.chip.ChipGroup; import com.google.android.material.chip.ChipGroup;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.ui.CheckableImageView; import com.todoroo.astrid.ui.CheckableImageView;
import org.tasks.R;
import org.tasks.data.TaskContainer; import org.tasks.data.TaskContainer;
import org.tasks.databinding.SubtaskAdapterRowBodyBinding;
import org.tasks.ui.CheckBoxProvider; import org.tasks.ui.CheckBoxProvider;
import org.tasks.ui.ChipProvider; import org.tasks.ui.ChipProvider;
@ -28,31 +28,32 @@ public class SubtaskViewHolder extends RecyclerView.ViewHolder {
private TaskContainer task; private TaskContainer task;
@BindView(R.id.rowBody) private final ViewGroup rowBody;
ViewGroup rowBody; private final TextView nameView;
private final CheckableImageView completeBox;
@BindView(R.id.title) private final ChipGroup chipGroup;
TextView nameView;
@BindView(R.id.completeBox)
CheckableImageView completeBox;
@BindView(R.id.chip_group)
ChipGroup chipGroup;
SubtaskViewHolder( SubtaskViewHolder(
ViewGroup view, SubtaskAdapterRowBodyBinding binding,
Callbacks callbacks, Callbacks callbacks,
DisplayMetrics metrics, DisplayMetrics metrics,
ChipProvider chipProvider, ChipProvider chipProvider,
CheckBoxProvider checkBoxProvider) { CheckBoxProvider checkBoxProvider) {
super(view); super(binding.getRoot());
this.callbacks = callbacks; this.callbacks = callbacks;
this.metrics = metrics; this.metrics = metrics;
this.chipProvider = chipProvider; this.chipProvider = chipProvider;
this.checkBoxProvider = checkBoxProvider; this.checkBoxProvider = checkBoxProvider;
ButterKnife.bind(this, view);
rowBody = binding.rowBody;
nameView = binding.title;
completeBox = binding.completeBox;
chipGroup = binding.chipGroup;
nameView.setOnClickListener(v -> openSubtask());
completeBox.setOnClickListener(v -> onCompleteBoxClick());
ViewGroup view = binding.getRoot();
view.setTag(this); view.setTag(this);
for (int i = 0; i < view.getChildCount(); i++) { for (int i = 0; i < view.getChildCount(); i++) {
view.getChildAt(i).setTag(this); view.getChildAt(i).setTag(this);
@ -98,13 +99,11 @@ public class SubtaskViewHolder extends RecyclerView.ViewHolder {
completeBox.invalidate(); completeBox.invalidate();
} }
@OnClick(R.id.title) private void openSubtask() {
void openSubtask() {
callbacks.openSubtask(task.getTask()); callbacks.openSubtask(task.getTask());
} }
@OnClick(R.id.completeBox) private void onCompleteBoxClick() {
void onCompleteBoxClick() {
if (task == null) { if (task == null) {
return; return;
} }

@ -4,19 +4,22 @@ import android.app.Activity;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.recyclerview.widget.AsyncDifferConfig; import androidx.recyclerview.widget.AsyncDifferConfig;
import androidx.recyclerview.widget.AsyncListDiffer; import androidx.recyclerview.widget.AsyncListDiffer;
import androidx.recyclerview.widget.ListUpdateCallback; import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import org.tasks.R;
import org.tasks.data.TaskContainer; import org.tasks.data.TaskContainer;
import org.tasks.databinding.SubtaskAdapterRowBodyBinding;
import org.tasks.tasklist.SubtaskViewHolder.Callbacks; import org.tasks.tasklist.SubtaskViewHolder.Callbacks;
import org.tasks.ui.CheckBoxProvider; import org.tasks.ui.CheckBoxProvider;
import org.tasks.ui.ChipProvider; import org.tasks.ui.ChipProvider;
import java.util.List;
public class SubtasksRecyclerAdapter extends RecyclerView.Adapter<SubtaskViewHolder> public class SubtasksRecyclerAdapter extends RecyclerView.Adapter<SubtaskViewHolder>
implements ListUpdateCallback { implements ListUpdateCallback {
@ -46,10 +49,13 @@ public class SubtasksRecyclerAdapter extends RecyclerView.Adapter<SubtaskViewHol
@NonNull @NonNull
@Override @Override
public SubtaskViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public SubtaskViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ViewGroup view = return new SubtaskViewHolder(
(ViewGroup) SubtaskAdapterRowBodyBinding.inflate(LayoutInflater.from(activity), parent, false),
LayoutInflater.from(activity).inflate(R.layout.subtask_adapter_row_body, parent, false); callbacks,
return new SubtaskViewHolder(view, callbacks, metrics, chipProvider, checkBoxProvider); metrics,
chipProvider,
checkBoxProvider
);
} }
@Override @Override

@ -8,10 +8,6 @@ import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams import android.view.ViewGroup.MarginLayoutParams
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import butterknife.OnLongClick
import com.google.android.material.chip.ChipGroup import com.google.android.material.chip.ChipGroup
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.api.Filter import com.todoroo.astrid.api.Filter
@ -20,6 +16,7 @@ import com.todoroo.astrid.core.SortHelper.SORT_START
import com.todoroo.astrid.ui.CheckableImageView import com.todoroo.astrid.ui.CheckableImageView
import org.tasks.R import org.tasks.R
import org.tasks.data.TaskContainer import org.tasks.data.TaskContainer
import org.tasks.databinding.TaskAdapterRowBinding
import org.tasks.date.DateTimeUtils.newDateTime import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.dialogs.Linkify import org.tasks.dialogs.Linkify
import org.tasks.preferences.Preferences import org.tasks.preferences.Preferences
@ -32,42 +29,37 @@ import kotlin.math.max
import kotlin.math.roundToInt import kotlin.math.roundToInt
class TaskViewHolder internal constructor( class TaskViewHolder internal constructor(
private val context: Activity, private val context: Activity,
view: ViewGroup, binding: TaskAdapterRowBinding,
private val preferences: Preferences, private val preferences: Preferences,
fontSize: Int, fontSize: Int,
private val chipProvider: ChipProvider, private val chipProvider: ChipProvider,
private val checkBoxProvider: CheckBoxProvider, private val checkBoxProvider: CheckBoxProvider,
private val textColorOverdue: Int, private val textColorOverdue: Int,
private val textColorSecondary: Int, private val textColorSecondary: Int,
private val callback: ViewHolderCallbacks, private val callback: ViewHolderCallbacks,
private val metrics: DisplayMetrics, private val metrics: DisplayMetrics,
private val background: Int, private val background: Int,
private val selectedColor: Int, private val selectedColor: Int,
private val rowPadding: Int, private val rowPadding: Int,
private val linkify: Linkify, private val linkify: Linkify,
private val locale: Locale) : RecyclerView.ViewHolder(view) { private val locale: Locale
) : RecyclerView.ViewHolder(binding.root) {
@BindView(R.id.row)
lateinit var row: ViewGroup private val row: ViewGroup = binding.row
private val dueDate: TextView = binding.dueDate.apply {
@BindView(R.id.due_date) setOnClickListener { changeDueDate() }
lateinit var dueDate: TextView }
private val rowBody: ViewGroup = binding.rowBody.apply {
@BindView(R.id.rowBody) setOnClickListener { onRowBodyClick() }
lateinit var rowBody: ViewGroup setOnLongClickListener { onRowBodyLongClick() }
}
@BindView(R.id.title) private val nameView: TextView = binding.title
lateinit var nameView: TextView private val description: TextView = binding.description
private val completeBox: CheckableImageView = binding.completeBox.apply {
@BindView(R.id.description) setOnClickListener { onCompleteBoxClick() }
lateinit var description: TextView }
private val chipGroup: ChipGroup = binding.chipGroup
@BindView(R.id.completeBox)
lateinit var completeBox: CheckableImageView
@BindView(R.id.chip_group)
lateinit var chipGroup: ChipGroup
lateinit var task: TaskContainer lateinit var task: TaskContainer
@ -226,14 +218,11 @@ class TaskViewHolder internal constructor(
} }
} }
@OnClick(R.id.rowBody) private fun onRowBodyClick() = callback.onClick(this)
fun onRowBodyClick() = callback.onClick(this)
@OnLongClick(R.id.rowBody) private fun onRowBodyLongClick(): Boolean = callback.onLongPress(this)
fun onRowBodyLongClick(): Boolean = callback.onLongPress(this)
@OnClick(R.id.completeBox) private fun onCompleteBoxClick() {
fun onCompleteBoxClick() {
val newState = completeBox.isChecked val newState = completeBox.isChecked
if (newState != task.isCompleted) { if (newState != task.isCompleted) {
callback.onCompletedTask(task, newState) callback.onCompletedTask(task, newState)
@ -243,8 +232,7 @@ class TaskViewHolder internal constructor(
setupTitleAndCheckbox() setupTitleAndCheckbox()
} }
@OnClick(R.id.due_date) private fun changeDueDate() {
fun changeDueDate() {
callback.onChangeDueDate(task) callback.onChangeDueDate(task)
} }
@ -258,7 +246,6 @@ class TaskViewHolder internal constructor(
} }
init { init {
ButterKnife.bind(this, view)
if (preferences.getBoolean(R.string.p_fullTaskTitle, false)) { if (preferences.getBoolean(R.string.p_fullTaskTitle, false)) {
nameView.maxLines = Int.MAX_VALUE nameView.maxLines = Int.MAX_VALUE
nameView.isSingleLine = false nameView.isSingleLine = false
@ -275,9 +262,11 @@ class TaskViewHolder internal constructor(
description.textSize = fontSize.toFloat() description.textSize = fontSize.toFloat()
val fontSizeDetails = max(10, fontSize - 2) val fontSizeDetails = max(10, fontSize - 2)
dueDate.textSize = fontSizeDetails.toFloat() dueDate.textSize = fontSizeDetails.toFloat()
view.tag = this with(binding.root) {
for (i in 0 until view.childCount) { tag = this@TaskViewHolder
view.getChildAt(i).tag = this for (i in 0 until childCount) {
getChildAt(i).tag = this@TaskViewHolder
}
} }
} }
} }

@ -8,6 +8,7 @@ import android.view.ViewGroup
import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.AndroidUtilities
import dagger.hilt.android.qualifiers.ActivityContext import dagger.hilt.android.qualifiers.ActivityContext
import org.tasks.R import org.tasks.R
import org.tasks.databinding.TaskAdapterRowBinding
import org.tasks.dialogs.Linkify import org.tasks.dialogs.Linkify
import org.tasks.preferences.Preferences import org.tasks.preferences.Preferences
import org.tasks.preferences.ResourceResolver import org.tasks.preferences.ResourceResolver
@ -42,7 +43,7 @@ class ViewHolderFactory @Inject constructor(
fun newViewHolder(parent: ViewGroup?, callbacks: ViewHolderCallbacks) = fun newViewHolder(parent: ViewGroup?, callbacks: ViewHolderCallbacks) =
TaskViewHolder( TaskViewHolder(
context as Activity, context as Activity,
LayoutInflater.from(context).inflate(R.layout.task_adapter_row, parent, false) as ViewGroup, TaskAdapterRowBinding.inflate(LayoutInflater.from(context), parent, false),
preferences, preferences,
fontSize, fontSize,
chipProvider, chipProvider,

@ -5,19 +5,18 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import android.provider.CalendarContract import android.provider.CalendarContract
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import android.widget.Toast.LENGTH_SHORT import android.widget.Toast.LENGTH_SHORT
import butterknife.BindView
import butterknife.OnClick
import com.todoroo.astrid.gcal.GCalHelper import com.todoroo.astrid.gcal.GCalHelper
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.PermissionUtil.verifyPermissions import org.tasks.PermissionUtil.verifyPermissions
import org.tasks.R import org.tasks.R
import org.tasks.Strings.isNullOrEmpty import org.tasks.Strings.isNullOrEmpty
import org.tasks.analytics.Firebase import org.tasks.analytics.Firebase
import org.tasks.calendars.CalendarEventProvider
import org.tasks.calendars.CalendarPicker import org.tasks.calendars.CalendarPicker
import org.tasks.calendars.CalendarProvider import org.tasks.calendars.CalendarProvider
import org.tasks.databinding.ControlSetGcalDisplayBinding
import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.DialogBuilder
import org.tasks.extensions.Context.toast import org.tasks.extensions.Context.toast
import org.tasks.preferences.FragmentPermissionRequestor import org.tasks.preferences.FragmentPermissionRequestor
@ -29,11 +28,8 @@ import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class CalendarControlSet : TaskEditControlFragment() { class CalendarControlSet : TaskEditControlFragment() {
@BindView(R.id.clear) private lateinit var cancelButton: View
lateinit var cancelButton: View private lateinit var calendar: TextView
@BindView(R.id.calendar_display_which)
lateinit var calendar: TextView
@Inject lateinit var activity: Activity @Inject lateinit var activity: Activity
@Inject lateinit var gcalHelper: GCalHelper @Inject lateinit var gcalHelper: GCalHelper
@ -44,7 +40,6 @@ class CalendarControlSet : TaskEditControlFragment() {
@Inject lateinit var firebase: Firebase @Inject lateinit var firebase: Firebase
@Inject lateinit var dialogBuilder: DialogBuilder @Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var themeBase: ThemeBase @Inject lateinit var themeBase: ThemeBase
@Inject lateinit var calendarEventProvider: CalendarEventProvider
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
@ -62,7 +57,14 @@ class CalendarControlSet : TaskEditControlFragment() {
refreshDisplayView() refreshDisplayView()
} }
override val layout = R.layout.control_set_gcal_display override fun bind(parent: ViewGroup?) =
ControlSetGcalDisplayBinding.inflate(layoutInflater, parent, true).let {
cancelButton = it.clear.clear.apply {
setOnClickListener { clearCalendar() }
}
calendar = it.calendarDisplayWhich
it.root
}
override val icon = R.drawable.ic_outline_event_24px override val icon = R.drawable.ic_outline_event_24px
@ -70,8 +72,7 @@ class CalendarControlSet : TaskEditControlFragment() {
override val isClickable = true override val isClickable = true
@OnClick(R.id.clear) private fun clearCalendar() {
fun clearCalendar() {
if (viewModel.eventUri.isNullOrBlank()) { if (viewModel.eventUri.isNullOrBlank()) {
clear() clear()
} else { } else {

@ -3,12 +3,13 @@ package org.tasks.ui
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import butterknife.BindView
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.data.Task.Companion.hasDueTime import com.todoroo.astrid.data.Task.Companion.hasDueTime
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.databinding.ControlSetDeadlineBinding
import org.tasks.date.DateTimeUtils import org.tasks.date.DateTimeUtils
import org.tasks.dialogs.DateTimePicker import org.tasks.dialogs.DateTimePicker
import org.tasks.dialogs.DateTimePicker.Companion.newDateTimePicker import org.tasks.dialogs.DateTimePicker.Companion.newDateTimePicker
@ -23,9 +24,7 @@ class DeadlineControlSet : TaskEditControlFragment() {
@Inject lateinit var locale: Locale @Inject lateinit var locale: Locale
@Inject lateinit var preferences: Preferences @Inject lateinit var preferences: Preferences
@BindView(R.id.due_date) private lateinit var dueDate: TextView
lateinit var dueDate: TextView
private lateinit var callback: DueDateChangeListener private lateinit var callback: DueDateChangeListener
override fun onAttach(activity: Activity) { override fun onAttach(activity: Activity) {
@ -51,7 +50,11 @@ class DeadlineControlSet : TaskEditControlFragment() {
override val isClickable = true override val isClickable = true
override val layout = R.layout.control_set_deadline override fun bind(parent: ViewGroup?) =
ControlSetDeadlineBinding.inflate(layoutInflater, parent, true).let {
dueDate = it.dueDate
it.root
}
override val icon = R.drawable.ic_outline_schedule_24px override val icon = R.drawable.ic_outline_schedule_24px

@ -1,11 +1,12 @@
package org.tasks.ui package org.tasks.ui
import android.os.Bundle import android.os.Bundle
import android.view.ViewGroup
import android.widget.EditText import android.widget.EditText
import butterknife.BindView import androidx.core.widget.addTextChangedListener
import butterknife.OnTextChanged
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.databinding.ControlSetDescriptionBinding
import org.tasks.dialogs.Linkify import org.tasks.dialogs.Linkify
import org.tasks.preferences.Preferences import org.tasks.preferences.Preferences
import javax.inject.Inject import javax.inject.Inject
@ -15,8 +16,7 @@ class DescriptionControlSet : TaskEditControlFragment() {
@Inject lateinit var linkify: Linkify @Inject lateinit var linkify: Linkify
@Inject lateinit var preferences: Preferences @Inject lateinit var preferences: Preferences
@BindView(R.id.notes) private lateinit var editText: EditText
lateinit var editText: EditText
override fun createView(savedInstanceState: Bundle?) { override fun createView(savedInstanceState: Bundle?) {
viewModel.description?.let(editText::setTextKeepState) viewModel.description?.let(editText::setTextKeepState)
@ -25,15 +25,22 @@ class DescriptionControlSet : TaskEditControlFragment() {
} }
} }
override val layout = R.layout.control_set_description override fun bind(parent: ViewGroup?) =
ControlSetDescriptionBinding.inflate(layoutInflater, parent, true).let {
editText = it.notes.apply {
addTextChangedListener(
onTextChanged = { text, _, _, _ -> textChanged(text) }
)
}
it.root
}
override val icon = R.drawable.ic_outline_notes_24px override val icon = R.drawable.ic_outline_notes_24px
override fun controlId() = TAG override fun controlId() = TAG
@OnTextChanged(R.id.notes) private fun textChanged(text: CharSequence?) {
fun textChanged(text: CharSequence) { viewModel.description = text?.toString()?.trim { it <= ' ' }
viewModel.description = text.toString().trim { it <= ' ' }
} }
companion object { companion object {

@ -3,21 +3,20 @@ package org.tasks.ui
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import butterknife.BindView import android.view.ViewGroup
import com.google.android.material.chip.ChipGroup import com.google.android.material.chip.ChipGroup
import com.todoroo.astrid.api.CaldavFilter 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.service.TaskMover
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.activities.ListPicker import org.tasks.activities.ListPicker
import org.tasks.databinding.ControlSetRemoteListBinding
import javax.inject.Inject import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class ListFragment : TaskEditControlFragment() { class ListFragment : TaskEditControlFragment() {
@BindView(R.id.chip_group) private lateinit var chipGroup: ChipGroup
lateinit var chipGroup: ChipGroup
@Inject lateinit var chipProvider: ChipProvider @Inject lateinit var chipProvider: ChipProvider
@ -42,7 +41,11 @@ class ListFragment : TaskEditControlFragment() {
callback.onListChanged(filter) callback.onListChanged(filter)
} }
override val layout = R.layout.control_set_remote_list override fun bind(parent: ViewGroup?) =
ControlSetRemoteListBinding.inflate(layoutInflater, parent, true).let {
chipGroup = it.chipGroup
it.root
}
override val icon = R.drawable.ic_list_24px override val icon = R.drawable.ic_list_24px

@ -8,17 +8,17 @@ import android.text.SpannableString
import android.text.Spanned import android.text.Spanned
import android.text.style.ClickableSpan import android.text.style.ClickableSpan
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.core.util.Pair import androidx.core.util.Pair
import butterknife.BindView
import butterknife.OnClick
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.Strings.isNullOrEmpty import org.tasks.Strings.isNullOrEmpty
import org.tasks.data.Geofence import org.tasks.data.Geofence
import org.tasks.data.Location import org.tasks.data.Location
import org.tasks.data.Place import org.tasks.data.Place
import org.tasks.databinding.LocationRowBinding
import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.DialogBuilder
import org.tasks.dialogs.GeofenceDialog import org.tasks.dialogs.GeofenceDialog
import org.tasks.extensions.Context.openUri import org.tasks.extensions.Context.openUri
@ -39,14 +39,9 @@ class LocationControlSet : TaskEditControlFragment() {
@Inject lateinit var permissionRequestor: FragmentPermissionRequestor @Inject lateinit var permissionRequestor: FragmentPermissionRequestor
@Inject lateinit var permissionChecker: PermissionChecker @Inject lateinit var permissionChecker: PermissionChecker
@BindView(R.id.location_name) private lateinit var locationName: TextView
lateinit var locationName: TextView private lateinit var locationAddress: TextView
private lateinit var geofenceOptions: ImageView
@BindView(R.id.location_address)
lateinit var locationAddress: TextView
@BindView(R.id.geofence_options)
lateinit var geofenceOptions: ImageView
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
@ -123,8 +118,7 @@ class LocationControlSet : TaskEditControlFragment() {
startActivityForResult(intent, REQUEST_LOCATION_REMINDER) startActivityForResult(intent, REQUEST_LOCATION_REMINDER)
} }
@OnClick(R.id.geofence_options) private fun geofenceOptions() {
fun geofenceOptions() {
if (permissionChecker.canAccessBackgroundLocation()) { if (permissionChecker.canAccessBackgroundLocation()) {
showGeofenceOptions() showGeofenceOptions()
} else { } else {
@ -139,7 +133,15 @@ class LocationControlSet : TaskEditControlFragment() {
dialog.show(parentFragmentManager, FRAG_TAG_LOCATION_DIALOG) dialog.show(parentFragmentManager, FRAG_TAG_LOCATION_DIALOG)
} }
override val layout = R.layout.location_row override fun bind(parent: ViewGroup?) =
LocationRowBinding.inflate(layoutInflater, parent, true).let {
locationName = it.locationName
locationAddress = it.locationAddress
geofenceOptions = it.geofenceOptions.apply {
setOnClickListener { geofenceOptions() }
}
it.root
}
override val icon = R.drawable.ic_outline_place_24px override val icon = R.drawable.ic_outline_place_24px

@ -0,0 +1,12 @@
package org.tasks.ui
import android.view.View
import android.widget.AdapterView
abstract class OnItemSelected : AdapterView.OnItemSelectedListener {
final override fun onNothingSelected(parent: AdapterView<*>?) {}
final override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) =
onItemSelected(position)
abstract fun onItemSelected(position: Int)
}

@ -0,0 +1,13 @@
package org.tasks.ui
import android.text.Editable
import android.text.TextWatcher
abstract class OnTextChanged : TextWatcher {
final override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
final override fun afterTextChanged(s: Editable?) {}
final override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) =
onTextChanged(s)
abstract fun onTextChanged(text: CharSequence?)
}

@ -2,12 +2,12 @@ package org.tasks.ui
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.os.Bundle import android.os.Bundle
import android.view.ViewGroup
import androidx.appcompat.widget.AppCompatRadioButton import androidx.appcompat.widget.AppCompatRadioButton
import butterknife.BindView
import butterknife.OnClick
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.databinding.ControlSetPriorityBinding
import org.tasks.themes.ColorProvider import org.tasks.themes.ColorProvider
import javax.inject.Inject import javax.inject.Inject
@ -15,20 +15,12 @@ import javax.inject.Inject
class PriorityControlSet : TaskEditControlFragment() { class PriorityControlSet : TaskEditControlFragment() {
@Inject lateinit var colorProvider: ColorProvider @Inject lateinit var colorProvider: ColorProvider
@BindView(R.id.priority_high) private lateinit var priorityHigh: AppCompatRadioButton
lateinit var priorityHigh: AppCompatRadioButton private lateinit var priorityMedium: AppCompatRadioButton
private lateinit var priorityLow: AppCompatRadioButton
private lateinit var priorityNone: AppCompatRadioButton
@BindView(R.id.priority_medium) private fun onPriorityChanged() {
lateinit var priorityMedium: AppCompatRadioButton
@BindView(R.id.priority_low)
lateinit var priorityLow: AppCompatRadioButton
@BindView(R.id.priority_none)
lateinit var priorityNone: AppCompatRadioButton
@OnClick(R.id.priority_high, R.id.priority_medium, R.id.priority_low, R.id.priority_none)
fun onPriorityChanged() {
viewModel.priority = getPriority() viewModel.priority = getPriority()
} }
@ -45,7 +37,22 @@ class PriorityControlSet : TaskEditControlFragment() {
tintRadioButton(priorityNone, 3) tintRadioButton(priorityNone, 3)
} }
override val layout = R.layout.control_set_priority override fun bind(parent: ViewGroup?) =
ControlSetPriorityBinding.inflate(layoutInflater, parent, true).let {
priorityHigh = it.priorityHigh.apply {
setOnClickListener { onPriorityChanged() }
}
priorityMedium = it.priorityMedium.apply {
setOnClickListener { onPriorityChanged() }
}
priorityLow = it.priorityLow.apply {
setOnClickListener { onPriorityChanged() }
}
priorityNone = it.priorityNone.apply {
setOnClickListener { onPriorityChanged() }
}
it.root
}
override val icon = R.drawable.ic_outline_flag_24px override val icon = R.drawable.ic_outline_flag_24px

@ -20,8 +20,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.OnClick
import com.todoroo.andlib.sql.Criterion import com.todoroo.andlib.sql.Criterion
import com.todoroo.andlib.sql.Join import com.todoroo.andlib.sql.Join
import com.todoroo.andlib.sql.QueryTemplate import com.todoroo.andlib.sql.QueryTemplate
@ -40,6 +38,7 @@ import org.tasks.LocalBroadcastManager
import org.tasks.R import org.tasks.R
import org.tasks.data.* import org.tasks.data.*
import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible
import org.tasks.databinding.ControlSetSubtasksBinding
import org.tasks.extensions.Context.toast import org.tasks.extensions.Context.toast
import org.tasks.locale.Locale import org.tasks.locale.Locale
import org.tasks.tasklist.SubtaskViewHolder import org.tasks.tasklist.SubtaskViewHolder
@ -48,11 +47,8 @@ import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class SubtaskControlSet : TaskEditControlFragment(), SubtaskViewHolder.Callbacks { class SubtaskControlSet : TaskEditControlFragment(), SubtaskViewHolder.Callbacks {
@BindView(R.id.recycler_view) private lateinit var recyclerView: RecyclerView
lateinit var recyclerView: RecyclerView private lateinit var newSubtaskContainer: LinearLayout
@BindView(R.id.new_subtasks)
lateinit var newSubtaskContainer: LinearLayout
@Inject lateinit var activity: Activity @Inject lateinit var activity: Activity
@Inject lateinit var taskCompleter: TaskCompleter @Inject lateinit var taskCompleter: TaskCompleter
@ -89,7 +85,13 @@ class SubtaskControlSet : TaskEditControlFragment(), SubtaskViewHolder.Callbacks
} }
} }
override val layout = R.layout.control_set_subtasks override fun bind(parent: ViewGroup?) =
ControlSetSubtasksBinding.inflate(layoutInflater, parent, true).let {
recyclerView = it.recyclerView
newSubtaskContainer = it.newSubtasks
it.addSubtask.setOnClickListener { addSubtask() }
it.root
}
override val icon = R.drawable.ic_subdirectory_arrow_right_black_24dp override val icon = R.drawable.ic_subdirectory_arrow_right_black_24dp
@ -111,8 +113,7 @@ class SubtaskControlSet : TaskEditControlFragment(), SubtaskViewHolder.Callbacks
localBroadcastManager.unregisterReceiver(refreshReceiver) localBroadcastManager.unregisterReceiver(refreshReceiver)
} }
@OnClick(R.id.add_subtask) private fun addSubtask() {
fun addSubtask() {
if (isGoogleTaskChild) { if (isGoogleTaskChild) {
context?.toast(R.string.subtasks_multilevel_google_task) context?.toast(R.string.subtasks_multilevel_google_task)
} else { } else {

@ -8,7 +8,6 @@ import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import butterknife.ButterKnife
import org.tasks.R import org.tasks.R
abstract class TaskEditControlFragment : Fragment() { abstract class TaskEditControlFragment : Fragment() {
@ -19,13 +18,12 @@ abstract class TaskEditControlFragment : Fragment() {
val view = inflater.inflate(R.layout.control_set_template, null) val view = inflater.inflate(R.layout.control_set_template, null)
viewModel = ViewModelProvider(requireParentFragment()).get(TaskEditViewModel::class.java) viewModel = ViewModelProvider(requireParentFragment()).get(TaskEditViewModel::class.java)
val content = view.findViewById<LinearLayout>(R.id.content) val content = view.findViewById<LinearLayout>(R.id.content)
inflater.inflate(layout, content) bind(content)
val icon = view.findViewById<ImageView>(R.id.icon) val icon = view.findViewById<ImageView>(R.id.icon)
icon.setImageResource(this.icon) icon.setImageResource(this.icon)
if (isClickable) { if (isClickable) {
content.setOnClickListener { onRowClick() } content.setOnClickListener { onRowClick() }
} }
ButterKnife.bind(this, view)
createView(savedInstanceState) createView(savedInstanceState)
@ -38,7 +36,7 @@ abstract class TaskEditControlFragment : Fragment() {
protected open val isClickable: Boolean protected open val isClickable: Boolean
get() = false get() = false
protected abstract val layout: Int
protected abstract val icon: Int protected abstract val icon: Int
abstract fun controlId(): Int abstract fun controlId(): Int
protected abstract fun bind(parent: ViewGroup?): View
} }

@ -8,16 +8,13 @@ import android.os.Parcelable
import android.view.View import android.view.View
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import butterknife.OnFocusChange
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.todoroo.astrid.api.Filter import com.todoroo.astrid.api.Filter
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.Strings.isNullOrEmpty import org.tasks.Strings.isNullOrEmpty
import org.tasks.activities.FilterSelectionActivity import org.tasks.activities.FilterSelectionActivity
import org.tasks.databinding.ActivityWidgetShortcutLayoutBinding
import org.tasks.dialogs.ColorPalettePicker import org.tasks.dialogs.ColorPalettePicker
import org.tasks.dialogs.ColorPalettePicker.Companion.newColorPalette import org.tasks.dialogs.ColorPalettePicker.Companion.newColorPalette
import org.tasks.dialogs.ColorPickerAdapter.Palette import org.tasks.dialogs.ColorPickerAdapter.Palette
@ -32,29 +29,31 @@ import javax.inject.Inject
class ShortcutConfigActivity : ThemedInjectingAppCompatActivity(), ColorPalettePicker.ColorPickedCallback { class ShortcutConfigActivity : ThemedInjectingAppCompatActivity(), ColorPalettePicker.ColorPickedCallback {
@Inject lateinit var defaultFilterProvider: DefaultFilterProvider @Inject lateinit var defaultFilterProvider: DefaultFilterProvider
@BindView(R.id.toolbar) private lateinit var toolbar: Toolbar
lateinit var toolbar: Toolbar private lateinit var shortcutList: TextInputEditText
private lateinit var shortcutName: TextInputEditText
@BindView(R.id.shortcut_list) private lateinit var colorIcon: TextView
lateinit var shortcutList: TextInputEditText private lateinit var clear: View
@BindView(R.id.shortcut_name)
lateinit var shortcutName: TextInputEditText
@BindView(R.id.color)
lateinit var colorIcon: TextView
@BindView(R.id.clear)
lateinit var clear: View
private var selectedFilter: Filter? = null private var selectedFilter: Filter? = null
private var selectedTheme = 0 private var selectedTheme = 0
public override fun onCreate(savedInstanceState: Bundle?) { public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val binding = ActivityWidgetShortcutLayoutBinding.inflate(layoutInflater)
binding.let {
toolbar = it.toolbar.toolbar
shortcutList = it.body.shortcutList.apply {
setOnClickListener { showListPicker() }
setOnFocusChangeListener { _, hasFocus -> onListFocusChange(hasFocus) }
}
shortcutName = it.body.shortcutName
colorIcon = it.body.color.color
clear = it.body.color.clear.clear
it.body.color.colorRow.setOnClickListener { showThemePicker() }
}
setContentView(binding.root)
setContentView(R.layout.activity_widget_shortcut_layout)
ButterKnife.bind(this)
toolbar.setTitle(R.string.FSA_label) toolbar.setTitle(R.string.FSA_label)
toolbar.navigationIcon = getDrawable(R.drawable.ic_outline_save_24px) toolbar.navigationIcon = getDrawable(R.drawable.ic_outline_save_24px)
toolbar.setNavigationOnClickListener { save() } toolbar.setNavigationOnClickListener { save() }
@ -88,24 +87,21 @@ class ShortcutConfigActivity : ThemedInjectingAppCompatActivity(), ColorPaletteP
outState.putInt(EXTRA_THEME, selectedTheme) outState.putInt(EXTRA_THEME, selectedTheme)
} }
@OnFocusChange(R.id.shortcut_list) private fun onListFocusChange(focused: Boolean) {
fun onListFocusChange(focused: Boolean) {
if (focused) { if (focused) {
shortcutList.clearFocus() shortcutList.clearFocus()
showListPicker() showListPicker()
} }
} }
@OnClick(R.id.shortcut_list) private fun showListPicker() {
fun showListPicker() {
val intent = Intent(this, FilterSelectionActivity::class.java) val intent = Intent(this, FilterSelectionActivity::class.java)
intent.putExtra(FilterSelectionActivity.EXTRA_FILTER, selectedFilter) intent.putExtra(FilterSelectionActivity.EXTRA_FILTER, selectedFilter)
intent.putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true) intent.putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true)
startActivityForResult(intent, REQUEST_FILTER) startActivityForResult(intent, REQUEST_FILTER)
} }
@OnClick(R.id.color_row) private fun showThemePicker() {
fun showThemePicker() {
newColorPalette(null, 0, Palette.LAUNCHERS) newColorPalette(null, 0, Palette.LAUNCHERS)
.show(supportFragmentManager, FRAG_TAG_COLOR_PICKER) .show(supportFragmentManager, FRAG_TAG_COLOR_PICKER)
} }

@ -11,7 +11,9 @@
<include layout="@layout/toolbar"/> <include layout="@layout/toolbar"/>
<include layout="@layout/progress_view"/> <include
android:id="@+id/progress_bar"
layout="@layout/progress_view" />
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"

@ -6,7 +6,9 @@
<include layout="@layout/toolbar"/> <include layout="@layout/toolbar"/>
<include layout="@layout/progress_view"/> <include
android:id="@+id/progress_bar"
layout="@layout/progress_view"/>
<ScrollView <ScrollView
android:layout_width="fill_parent" android:layout_width="fill_parent"

@ -12,7 +12,9 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/shortcut_name_layout"> app:layout_constraintTop_toBottomOf="@+id/shortcut_name_layout">
<include layout="@layout/list_settings_color" /> <include
android:id="@+id/color"
layout="@layout/list_settings_color" />
</LinearLayout> </LinearLayout>

@ -7,13 +7,17 @@
android:focusableInTouchMode="true" android:focusableInTouchMode="true"
android:orientation="vertical"> android:orientation="vertical">
<include layout="@layout/toolbar"/> <include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
<ScrollView <ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<include layout="@layout/activity_widget_shortcut_content"/> <include
android:id="@+id/body"
layout="@layout/activity_widget_shortcut_content" />
</ScrollView> </ScrollView>

@ -4,7 +4,9 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<include layout="@layout/toolbar"/> <include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view" android:id="@+id/recycler_view"

@ -19,6 +19,8 @@
android:hint="@string/dont_add_to_calendar" android:hint="@string/dont_add_to_calendar"
android:textAlignment="viewStart"/> android:textAlignment="viewStart"/>
<include layout="@layout/control_set_clear_button"/> <include
android:id="@+id/clear"
layout="@layout/control_set_clear_button" />
</LinearLayout> </LinearLayout>

@ -18,7 +18,9 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<include layout="@layout/toolbar"/> <include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -31,9 +33,13 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="100"> android:layout_weight="100">
<include layout="@layout/task_list_body_standard"/> <include
android:id="@+id/body_standard"
layout="@layout/task_list_body_standard" />
<include layout="@layout/task_list_body_empty"/> <include
android:id="@+id/body_empty"
layout="@layout/task_list_body_empty" />
</FrameLayout> </FrameLayout>

@ -5,7 +5,9 @@
style="@style/TagSettingsRow" style="@style/TagSettingsRow"
android:background="?attr/selectableItemBackground"> android:background="?attr/selectableItemBackground">
<include layout="@layout/control_set_clear_button" /> <include
android:id="@+id/clear"
layout="@layout/control_set_clear_button" />
<TextView <TextView
android:id="@+id/color" android:id="@+id/color"

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ToggleButton <ToggleButton
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/button"
android:layout_width="60dp" android:layout_width="60dp"
android:layout_height="60dp" android:layout_height="60dp"
android:background="@null" android:background="@null"

@ -2,7 +2,6 @@ object Versions {
const val kotlin = "1.4.31" const val kotlin = "1.4.31"
const val targetSdk = 30 const val targetSdk = 30
const val minSdk = 24 const val minSdk = 24
const val butterknife = "10.2.3"
const val work = "2.5.0" const val work = "2.5.0"
const val leakcanary = "2.7" const val leakcanary = "2.7"
const val room = "2.2.6" const val room = "2.2.6"

@ -292,11 +292,6 @@
++--- io.noties.markwon:core:4.6.2 ++--- io.noties.markwon:core:4.6.2
+| +--- androidx.annotation:annotation:1.1.0 -> 1.2.0 +| +--- androidx.annotation:annotation:1.1.0 -> 1.2.0
+| \--- com.atlassian.commonmark:commonmark:0.13.0 +| \--- com.atlassian.commonmark:commonmark:0.13.0
++--- com.jakewharton:butterknife:10.2.3
+| \--- com.jakewharton:butterknife-runtime:10.2.3
+| +--- com.jakewharton:butterknife-annotations:10.2.3
+| | \--- androidx.annotation:annotation:1.0.0 -> 1.2.0
+| \--- androidx.core:core:1.0.0 -> 1.5.0-rc01 (*)
++--- org.jetbrains.kotlin:kotlin-stdlib:1.4.31 (*) ++--- org.jetbrains.kotlin:kotlin-stdlib:1.4.31 (*)
++--- org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.3 ++--- org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.3
+| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.0 -> 1.4.31 (*) +| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.0 -> 1.4.31 (*)

@ -406,11 +406,6 @@
++--- io.noties.markwon:core:4.6.2 ++--- io.noties.markwon:core:4.6.2
+| +--- androidx.annotation:annotation:1.1.0 -> 1.2.0 +| +--- androidx.annotation:annotation:1.1.0 -> 1.2.0
+| \--- com.atlassian.commonmark:commonmark:0.13.0 +| \--- com.atlassian.commonmark:commonmark:0.13.0
++--- com.jakewharton:butterknife:10.2.3
+| \--- com.jakewharton:butterknife-runtime:10.2.3
+| +--- com.jakewharton:butterknife-annotations:10.2.3
+| | \--- androidx.annotation:annotation:1.0.0 -> 1.2.0
+| \--- androidx.core:core:1.0.0 -> 1.5.0-rc01 (*)
++--- org.jetbrains.kotlin:kotlin-stdlib:1.4.31 (*) ++--- org.jetbrains.kotlin:kotlin-stdlib:1.4.31 (*)
++--- org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.3 ++--- org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.3
+| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.0 -> 1.4.31 (*) +| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.0 -> 1.4.31 (*)

Loading…
Cancel
Save