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("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-network-plugin:${Versions.flipper}")
debugImplementation("com.facebook.soloader:soloader:0.10.1")
@ -246,7 +243,6 @@ dependencies {
androidTestImplementation("com.google.dagger:hilt-android-testing:${Versions.hilt}")
kaptAndroidTest("com.google.dagger:hilt-compiler:${Versions.hilt}")
kaptAndroidTest("androidx.hilt:hilt-compiler:${Versions.hilt_androidx}")
kaptAndroidTest("com.jakewharton:butterknife-compiler:${Versions.butterknife}")
androidTestImplementation("org.mockito:mockito-android:${Versions.mockito}")
androidTestImplementation("com.natpryce:make-it-easy:${Versions.make_it_easy}")
androidTestImplementation("androidx.test:runner:${Versions.androidx_test}")

@ -383,18 +383,6 @@
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
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:+
name: OkHttp Logging Interceptor
copyrightHolder: Square, Inc.
@ -406,12 +394,6 @@
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
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:+
name: io.grpc:grpc-context
copyrightHolder: The gRPC Authors

6
app/proguard.pro vendored

@ -9,12 +9,6 @@
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
-dontwarn sun.misc.Unsafe
-dontwarn java.lang.ClassValue

@ -912,34 +912,6 @@
"url": "https://kotlinlang.org/",
"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": {
"name": "logging-interceptor",
@ -967,20 +939,6 @@
"url": "https://kotlinlang.org/",
"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": {
"name": "grpc-context",

@ -6,27 +6,31 @@
package com.todoroo.astrid.activity;
import static java.util.Arrays.asList;
import static org.tasks.Strings.isNullOrEmpty;
import static java.util.Arrays.asList;
import android.content.Context;
import android.os.Bundle;
import android.view.MenuItem;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
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.databinding.BeastModePrefActivityBinding;
import org.tasks.injection.ThemedInjectingAppCompatActivity;
import org.tasks.preferences.Preferences;
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
public class BeastModePreferences extends ThemedInjectingAppCompatActivity
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_PREF_ITEM_SEPARATOR = ";";
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.recycler_view)
RecyclerView recyclerView;
@Inject Preferences preferences;
private BeastModeRecyclerAdapter adapter;
@ -87,8 +85,10 @@ public class BeastModePreferences extends ThemedInjectingAppCompatActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.beast_mode_pref_activity);
ButterKnife.bind(this);
BeastModePrefActivityBinding binding = BeastModePrefActivityBinding.inflate(getLayoutInflater());
Toolbar toolbar = binding.toolbar.toolbar;
RecyclerView recyclerView = binding.recyclerView;
setContentView(binding.getRoot());
toolbar.setNavigationIcon(
getDrawable(R.drawable.ic_outline_arrow_back_24px));

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

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

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

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

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

@ -11,11 +11,10 @@ import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import butterknife.BindView
import butterknife.OnClick
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch
@ -23,6 +22,7 @@ import kotlinx.coroutines.withContext
import org.tasks.R
import org.tasks.data.TaskAttachment
import org.tasks.data.TaskAttachmentDao
import org.tasks.databinding.ControlSetFilesBinding
import org.tasks.dialogs.AddAttachmentDialog
import org.tasks.dialogs.DialogBuilder
import org.tasks.files.FileHelper
@ -38,11 +38,8 @@ class FilesControlSet : TaskEditControlFragment() {
@Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var preferences: Preferences
@BindView(R.id.attachment_container)
lateinit var attachmentContainer: LinearLayout
@BindView(R.id.add_attachment)
lateinit var addAttachment: TextView
private lateinit var attachmentContainer: LinearLayout
private lateinit var addAttachment: TextView
override fun createView(savedInstanceState: Bundle?) {
val task = viewModel.task!!
@ -61,12 +58,18 @@ class FilesControlSet : TaskEditControlFragment() {
}
}
@OnClick(R.id.add_attachment)
fun addAttachment() {
private fun addAttachment() {
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

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

@ -9,12 +9,13 @@ import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import butterknife.BindView
import com.google.android.material.chip.ChipGroup
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.data.TagData
import org.tasks.databinding.ControlSetTagsBinding
import org.tasks.tags.TagPickerActivity
import org.tasks.ui.ChipProvider
import org.tasks.ui.TaskEditControlFragment
@ -29,11 +30,8 @@ import javax.inject.Inject
class TagsControlSet : TaskEditControlFragment() {
@Inject lateinit var chipProvider: ChipProvider
@BindView(R.id.no_tags)
lateinit var tagsDisplay: TextView
@BindView(R.id.chip_group)
lateinit var chipGroup: ChipGroup
private lateinit var tagsDisplay: TextView
private lateinit var chipGroup: ChipGroup
override fun createView(savedInstanceState: Bundle?) {
refreshDisplayView()
@ -45,7 +43,12 @@ class TagsControlSet : TaskEditControlFragment() {
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

@ -11,14 +11,13 @@ import android.os.SystemClock
import android.text.format.DateFormat
import android.text.format.DateUtils
import android.view.View
import android.view.ViewGroup
import android.widget.Chronometer
import android.widget.Chronometer.OnChronometerTickListener
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.lifecycleScope
import butterknife.BindView
import butterknife.OnClick
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.ui.TimeDurationControlSet
@ -26,6 +25,7 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.tasks.R
import org.tasks.Strings.isNullOrEmpty
import org.tasks.databinding.ControlSetTimersBinding
import org.tasks.dialogs.DialogBuilder
import org.tasks.themes.Theme
import org.tasks.ui.TaskEditControlFragment
@ -42,14 +42,9 @@ class TimerControlSet : TaskEditControlFragment() {
@Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var theme: Theme
@BindView(R.id.display_row_edit)
lateinit var displayEdit: TextView
@BindView(R.id.timer)
lateinit var chronometer: Chronometer
@BindView(R.id.timer_button)
lateinit var timerButton: ImageView
private lateinit var displayEdit: TextView
private lateinit var chronometer: Chronometer
private lateinit var timerButton: ImageView
private lateinit var estimated: TimeDurationControlSet
private lateinit var elapsed: TimeDurationControlSet
@ -87,8 +82,7 @@ class TimerControlSet : TaskEditControlFragment() {
.create()
}
@OnClick(R.id.timer_container)
fun timerClicked() {
private fun timerClicked() {
lifecycleScope.launch {
if (timerActive()) {
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

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

@ -3,13 +3,14 @@ package com.todoroo.astrid.ui
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.ViewGroup
import android.widget.TextView
import butterknife.BindView
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.andlib.utility.DateUtilities.now
import com.todoroo.astrid.data.Task
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.databinding.ControlSetHideBinding
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.dialogs.StartDatePicker
@ -35,8 +36,7 @@ class StartDateControlSet : TaskEditControlFragment() {
@Inject lateinit var preferences: Preferences
@Inject lateinit var locale: Locale
@BindView(R.id.start_date)
lateinit var startDate: TextView
private lateinit var startDate: TextView
private val dueDateTime
get() = viewModel.dueDate!!
@ -95,7 +95,11 @@ class StartDateControlSet : TaskEditControlFragment() {
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

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

@ -9,13 +9,11 @@ import android.view.MenuItem
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.FrameLayout
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
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.floatingactionbutton.ExtendedFloatingActionButton
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.astrid.activity.MainActivity
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.CustomFilterAdapter
import com.todoroo.astrid.core.CustomFilterItemTouchHelper
@ -39,6 +42,7 @@ import org.tasks.Strings
import org.tasks.data.Filter
import org.tasks.data.FilterDao
import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible
import org.tasks.databinding.FilterSettingsActivityBinding
import org.tasks.db.QueryUtils
import org.tasks.extensions.Context.openUri
import org.tasks.filters.FilterCriteriaProvider
@ -54,17 +58,10 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
@Inject lateinit var database: Database
@Inject lateinit var filterCriteriaProvider: FilterCriteriaProvider
@BindView(R.id.name)
lateinit var name: TextInputEditText
@BindView(R.id.name_layout)
lateinit var nameLayout: TextInputLayout
@BindView(R.id.recycler_view)
lateinit var recyclerView: RecyclerView
@BindView(R.id.fab)
lateinit var fab: ExtendedFloatingActionButton
private lateinit var name: TextInputEditText
private lateinit var nameLayout: TextInputLayout
private lateinit var recyclerView: RecyclerView
private lateinit var fab: ExtendedFloatingActionButton
private var filter: CustomFilter? = null
private lateinit var adapter: CustomFilterAdapter
@ -162,8 +159,7 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
else -> CriterionInstance.TYPE_INTERSECT
}
@OnClick(R.id.fab)
fun addCriteria() {
private fun addCriteria() {
AndroidUtilities.hideKeyboard(this)
fab.shrink()
lifecycleScope.launch {
@ -230,11 +226,6 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
override val toolbarTitle: String?
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() {
val newName = newName
if (Strings.isNullOrEmpty(newName)) {
@ -290,8 +281,19 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
super.finish()
}
override val layout: Int
get() = R.layout.filter_settings_activity
override fun bind() = FilterSettingsActivityBinding.inflate(layoutInflater).let {
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() {
filterDao.delete(filter!!.id)

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

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

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

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

@ -12,11 +12,9 @@ import android.view.inputmethod.InputMethodManager
import androidx.annotation.StringRes
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope
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.Snackbar
import com.todoroo.astrid.data.Task
@ -59,7 +57,6 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv
super.onCreate(savedInstanceState)
binding = ActivityCaldavAccountSettingsBinding.inflate(layoutInflater)
setContentView(binding.root)
ButterKnife.bind(this)
caldavAccount = if (savedInstanceState == null) intent.getParcelableExtra(EXTRA_CALDAV_DATA) else savedInstanceState.getParcelable(EXTRA_CALDAV_DATA)
if (caldavAccount == null || caldavAccount!!.id == Task.NO_ID) {
binding.nameLayout.visibility = View.GONE
@ -108,6 +105,19 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv
}
.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
@ -132,28 +142,7 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv
return binding.progressBar.progressBar.visibility == View.VISIBLE
}
@OnTextChanged(R.id.name)
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) {
private fun onPasswordFocused(hasFocus: Boolean) {
if (hasFocus) {
if (PASSWORD_MASK == binding.password.text.toString()) {
binding.password.setText("")

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

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

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

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

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

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

@ -9,22 +9,25 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.google.android.material.slider.Slider;
import com.google.android.material.switchmaterial.SwitchMaterial;
import dagger.hilt.android.AndroidEntryPoint;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.data.Geofence;
import org.tasks.data.Location;
import org.tasks.databinding.LocationDetailsBinding;
import org.tasks.locale.Locale;
import org.tasks.preferences.PermissionChecker;
import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint;
@AndroidEntryPoint
public class GeofenceDialog extends DialogFragment {
@ -39,14 +42,9 @@ public class GeofenceDialog extends DialogFragment {
@Inject Locale locale;
@Inject PermissionChecker permissionChecker;
@BindView(R.id.location_arrival)
SwitchMaterial arrivalView;
@BindView(R.id.location_departure)
SwitchMaterial departureView;
@BindView(R.id.slider)
Slider slider;
private SwitchMaterial arrivalView;
private SwitchMaterial departureView;
private Slider slider;
public static GeofenceDialog newGeofenceDialog(Location location) {
GeofenceDialog dialog = new GeofenceDialog();
@ -66,8 +64,10 @@ public class GeofenceDialog extends DialogFragment {
: savedInstanceState.getParcelable(EXTRA_GEOFENCE);
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.location_details, null);
ButterKnife.bind(this, view);
LocationDetailsBinding binding = LocationDetailsBinding.inflate(layoutInflater);
arrivalView = binding.locationArrival;
departureView = binding.locationDeparture;
slider = binding.slider;
arrivalView.setChecked(geofence.isArrival());
departureView.setChecked(geofence.isDeparture());
slider.setLabelFormatter(
@ -79,7 +79,7 @@ public class GeofenceDialog extends DialogFragment {
slider.setValue(Math.round((geofence.getRadius() / STEP) * STEP));
return dialogBuilder
.newDialog(original.getDisplayName())
.setView(view)
.setView(binding.getRoot())
.setNegativeButton(R.string.cancel, null)
.setOnCancelListener(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.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;
import androidx.recyclerview.widget.DiffUtil.ItemCallback;
import androidx.recyclerview.widget.ListAdapter;
import org.tasks.Callback;
import org.tasks.R;
import org.tasks.billing.Inventory;
import org.tasks.databinding.DialogIconPickerCellBinding;
import org.tasks.themes.CustomIcons;
class IconPickerAdapter extends ListAdapter<Integer, IconPickerHolder> {
@ -34,7 +37,7 @@ class IconPickerAdapter extends ListAdapter<Integer, IconPickerHolder> {
public IconPickerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new IconPickerHolder(
activity,
activity.getLayoutInflater().inflate(R.layout.dialog_icon_picker_cell, parent, false),
DialogIconPickerCellBinding.inflate(activity.getLayoutInflater(), parent, false),
onSelected);
}

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

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

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

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

@ -5,7 +5,6 @@ import android.os.Bundle
import android.view.View
import androidx.activity.viewModels
import androidx.appcompat.widget.Toolbar
import butterknife.OnCheckedChanged
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.helper.UUIDHelper
import dagger.hilt.android.AndroidEntryPoint
@ -28,6 +27,9 @@ class EtebaseAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool
super.onCreate(savedInstanceState)
binding.repeat.visibility = View.GONE
binding.showAdvanced.visibility = View.VISIBLE
binding.showAdvanced.setOnCheckedChangeListener { _, _ ->
updateUrlVisibility()
}
updateUrlVisibility()
}
@ -71,11 +73,6 @@ class EtebaseAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool
saveAccountAndFinish()
}
@OnCheckedChanged(R.id.show_advanced)
fun toggleUrl() {
updateUrlVisibility()
}
private fun updateUrlVisibility() {
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 androidx.activity.viewModels
import androidx.appcompat.widget.Toolbar
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope
import at.bitfire.dav4jvm.exception.HttpException
import butterknife.ButterKnife
import butterknife.OnTextChanged
import com.etesync.journalmanager.Constants.Companion.CURRENT_VERSION
import com.etesync.journalmanager.Crypto.CryptoManager
import com.etesync.journalmanager.Crypto.deriveKey
@ -45,7 +44,6 @@ class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.O
super.onCreate(savedInstanceState)
binding = ActivityEtesyncEncryptionSettingsBinding.inflate(layoutInflater)
setContentView(binding.root)
ButterKnife.bind(this)
val intent = intent
caldavAccount = intent.getParcelableExtra(EXTRA_ACCOUNT)
userInfo = intent.getSerializableExtra(EXTRA_USER_INFO) as UserInfoManager.UserInfo
@ -64,6 +62,12 @@ class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.O
if (createUserInfoViewModel.inProgress) {
showProgressIndicator()
}
binding.repeatEncryptionPassword.addTextChangedListener(
onTextChanged = { _, _, _, _ -> onRepeatEncryptionPasswordChanged() }
)
binding.encryptionPassword.addTextChangedListener(
onTextChanged = { _, _, _, _ -> onEncryptionPasswordChanged() }
)
}
private fun showProgressIndicator() {
@ -153,13 +157,11 @@ class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.O
return snackbar
}
@OnTextChanged(R.id.repeat_encryption_password)
fun onRpeatEncryptionPasswordChanged() {
private fun onRepeatEncryptionPasswordChanged() {
binding.repeatEncryptionPasswordLayout.error = null
}
@OnTextChanged(R.id.encryption_password)
fun onEncryptionPasswordChanged() {
private fun onEncryptionPasswordChanged() {
binding.encryptionPasswordLayout.error = null
}

@ -9,7 +9,6 @@ import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import androidx.core.util.Pair
import androidx.lifecycle.lifecycleScope
import butterknife.OnCheckedChanged
import com.etesync.journalmanager.Crypto.CryptoManager
import com.etesync.journalmanager.Exceptions.IntegrityException
import com.etesync.journalmanager.Exceptions.VersionTooNewException
@ -41,6 +40,7 @@ class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool
binding.description.visibility = View.VISIBLE
binding.description.setTextColor(ContextCompat.getColor(this, R.color.overdue))
binding.description.setText(description)
binding.showAdvanced.setOnCheckedChangeListener { _, _ -> updateUrlVisibility() }
updateUrlVisibility()
}
@ -108,11 +108,6 @@ class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool
return false
}
@OnCheckedChanged(R.id.show_advanced)
fun toggleUrl() {
updateUrlVisibility()
}
private fun updateUrlVisibility() {
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.ImageView
import android.widget.LinearLayout
import butterknife.*
import androidx.core.widget.addTextChangedListener
import com.todoroo.andlib.utility.AndroidUtilities
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.Strings.isNullOrEmpty
import org.tasks.activities.CameraActivity
import org.tasks.databinding.FragmentCommentBarBinding
import org.tasks.dialogs.DialogBuilder
import org.tasks.files.ImageHelper
import org.tasks.preferences.Device
@ -37,18 +38,10 @@ class CommentBarFragment : TaskEditControlFragment() {
@Inject lateinit var preferences: Preferences
@Inject lateinit var themeColor: ThemeColor
@BindView(R.id.commentButton)
lateinit var commentButton: View
@BindView(R.id.commentField)
lateinit var commentField: EditText
@BindView(R.id.picture)
lateinit var pictureButton: ImageView
@BindView(R.id.updatesFooter)
lateinit var commentBar: LinearLayout
private lateinit var commentButton: View
private lateinit var commentField: EditText
private lateinit var pictureButton: ImageView
private lateinit var commentBar: LinearLayout
private lateinit var callback: CommentBarFragmentCallback
private var pendingCommentPicture: Uri? = null
@ -59,8 +52,7 @@ class CommentBarFragment : TaskEditControlFragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(layout, container, false)
ButterKnife.bind(this, view)
val view = bind(container)
createView(savedInstanceState)
return view
}
@ -83,19 +75,33 @@ class CommentBarFragment : TaskEditControlFragment() {
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 fun controlId() = TAG
@OnTextChanged(R.id.commentField)
fun onTextChanged(s: CharSequence) {
private fun onTextChanged(s: String?) {
commentButton.visibility = if (pendingCommentPicture == null && isNullOrEmpty(s.toString())) View.GONE else View.VISIBLE
}
@OnEditorAction(R.id.commentField)
fun onEditorAction(key: KeyEvent?): Boolean {
private fun onEditorAction(key: KeyEvent?): Boolean {
val actionId = key?.action ?: 0
if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_NULL) {
if (commentField.text.isNotEmpty() || pendingCommentPicture != null) {
@ -106,8 +112,7 @@ class CommentBarFragment : TaskEditControlFragment() {
return false
}
@OnClick(R.id.commentButton)
fun addClicked() {
private fun addClicked() {
addComment()
}
@ -119,8 +124,7 @@ class CommentBarFragment : TaskEditControlFragment() {
}
}
@OnClick(R.id.picture)
fun onClickPicture() {
private fun onClickPicture() {
if (pendingCommentPicture == null) {
showPictureLauncher(null)
} else {

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

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

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

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

@ -2,7 +2,6 @@ package org.tasks.repeats;
import static android.app.Activity.RESULT_OK;
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.HOURLY;
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.RecurrenceUtils.newRecur;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import static java.util.Arrays.asList;
import android.app.Activity;
import android.app.Dialog;
@ -39,31 +39,39 @@ import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.ToggleButton;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatSpinner;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnItemSelected;
import butterknife.OnTextChanged;
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.Frequency;
import net.fortuna.ical4j.model.WeekDay;
import org.tasks.R;
import org.tasks.databinding.ControlSetRepeatBinding;
import org.tasks.databinding.WeekButtonsBinding;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.dialogs.MyDatePickerDialog;
import org.tasks.locale.Locale;
import org.tasks.preferences.ResourceResolver;
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;
@AndroidEntryPoint
@ -79,63 +87,16 @@ public class CustomRecurrenceDialog extends DialogFragment {
@Inject DialogBuilder dialogBuilder;
@Inject Locale locale;
@BindView(R.id.weekGroup)
LinearLayout weekGroup1;
@BindView(R.id.weekGroup2)
@Nullable
LinearLayout weekGroup2;
@BindView(R.id.week_day_1)
ToggleButton day1;
@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 LinearLayout weekGroup1;
@Nullable private LinearLayout weekGroup2;
private RadioGroup monthGroup;
private RadioButton repeatMonthlyDayOfNthWeek;
private RadioButton repeatMonthlyDayOfLastWeek;
private Spinner repeatUntilSpinner;
private EditText intervalEditText;
private TextView intervalTextView;
private EditText repeatTimes;
private TextView repeatTimesText;
private ArrayAdapter<String> repeatUntilAdapter;
private ToggleButton[] weekButtons;
@ -159,7 +120,8 @@ public class CustomRecurrenceDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
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();
dueDate = arguments.getLong(EXTRA_DATE, currentTimeMillis());
@ -183,7 +145,45 @@ public class CustomRecurrenceDialog extends DialogFragment {
DateFormatSymbols dfs = new DateFormatSymbols(locale.getLocale());
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());
dayOfMonthCalendar.setTimeInMillis(dueDate);
@ -233,14 +233,14 @@ public class CustomRecurrenceDialog extends DialogFragment {
}
if (monthGroup.getCheckedRadioButtonId() != R.id.repeat_monthly_day_of_last_week
&& monthGroup.getCheckedRadioButtonId() != R.id.repeat_monthly_day_of_nth_week) {
repeatMonthlySameDay.setChecked(true);
binding.repeatMonthlySameDay.setChecked(true);
}
ArrayAdapter<CharSequence> frequencyAdapter =
ArrayAdapter.createFromResource(context, R.array.repeat_frequency, R.layout.frequency_item);
frequencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
frequencySpinner.setAdapter(frequencyAdapter);
frequencySpinner.setSelection(FREQUENCIES.indexOf(rrule.getFrequency()));
frequency.setAdapter(frequencyAdapter);
frequency.setSelection(FREQUENCIES.indexOf(rrule.getFrequency()));
intervalEditText.setText(locale.formatNumber(rrule.getInterval()));
@ -273,7 +273,15 @@ public class CustomRecurrenceDialog extends DialogFragment {
repeatUntilSpinner.setAdapter(repeatUntilAdapter);
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
Calendar dayOfWeekCalendar = Calendar.getInstance(locale.getLocale());
@ -336,7 +344,7 @@ public class CustomRecurrenceDialog extends DialogFragment {
return dialogBuilder
.newDialog()
.setView(dialogView)
.setView(binding.getRoot())
.setPositiveButton(R.string.ok, this::onRuleSelected)
.setNegativeButton(R.string.cancel, null)
.show();
@ -448,8 +456,7 @@ public class CustomRecurrenceDialog extends DialogFragment {
}
}
@OnItemSelected(R.id.repeat_until)
public void onRepeatUntilChanged(int position) {
private void onRepeatUntilChanged(int position) {
if (repeatUntilOptions.size() == 4) {
position--;
}
@ -466,8 +473,7 @@ public class CustomRecurrenceDialog extends DialogFragment {
}
}
@OnItemSelected(R.id.frequency)
public void onFrequencyChanged(int position) {
private void onFrequencyChanged(int position) {
Frequency frequency = FREQUENCIES.get(position);
rrule.setFrequency(frequency.name());
int weekVisibility = frequency == WEEKLY ? View.VISIBLE : View.GONE;
@ -479,8 +485,7 @@ public class CustomRecurrenceDialog extends DialogFragment {
updateIntervalTextView();
}
@OnTextChanged(R.id.intervalValue)
public void onRepeatValueChanged(CharSequence text) {
private void onRepeatValueChanged(CharSequence text) {
Integer value = locale.parseInteger(text.toString());
if (value == null) {
return;
@ -492,8 +497,7 @@ public class CustomRecurrenceDialog extends DialogFragment {
}
}
@OnTextChanged(R.id.repeatTimesValue)
public void onRepeatTimesValueChanged(CharSequence text) {
private void onRepeatTimesValueChanged(CharSequence text) {
Integer value = locale.parseInteger(text.toString());
if (value == null) {
return;

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

@ -4,34 +4,27 @@ import android.content.Context
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnCheckedChanged
import butterknife.OnClick
import org.tasks.R
import org.tasks.data.TagData
import org.tasks.tags.CheckBoxTriStates
import org.tasks.databinding.RowTagPickerBinding
import org.tasks.themes.DrawableUtil
class TagPickerViewHolder internal constructor(
private val context: Context,
view: View,
private val callback: (TagData, TagPickerViewHolder) -> Unit
) : RecyclerView.ViewHolder(view) {
private val context: Context,
binding: RowTagPickerBinding,
private val callback: (TagData, TagPickerViewHolder) -> Unit
) : RecyclerView.ViewHolder(binding.root) {
val isChecked: Boolean
get() = checkBox.isChecked
@BindView(R.id.text)
lateinit var text: TextView
@BindView(R.id.checkbox)
lateinit var checkBox: CheckBoxTriStates
private val text: TextView = binding.text
private val checkBox: CheckBoxTriStates = binding.checkbox.apply {
setOnCheckedChangeListener { _, _ -> onCheckedChanged() }
}
private var tagData: TagData? = null
@OnClick(R.id.tag_row)
fun onClickRow() {
private fun onClickRow() {
if (tagData!!.id == null) {
callback(tagData!!, this)
} else {
@ -39,8 +32,7 @@ class TagPickerViewHolder internal constructor(
}
}
@OnCheckedChanged(R.id.checkbox)
fun onCheckedChanged() {
private fun onCheckedChanged() {
callback(tagData!!, this)
}
@ -73,6 +65,6 @@ class TagPickerViewHolder internal constructor(
}
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.billing.Inventory
import org.tasks.data.TagData
import org.tasks.databinding.RowTagPickerBinding
import org.tasks.themes.ColorProvider
import org.tasks.themes.CustomIcons.getIconResId
@ -21,10 +22,12 @@ internal class TagRecyclerAdapter(
private val differ: AsyncListDiffer<TagData> = AsyncListDiffer(this, TagDiffCallback())
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TagPickerViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.row_tag_picker, parent, false)
return TagPickerViewHolder(context, view, callback)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
TagPickerViewHolder(
context,
RowTagPickerBinding.inflate(LayoutInflater.from(context), parent, false),
callback
)
override fun onBindViewHolder(holder: TagPickerViewHolder, position: Int) {
val tagData = differ.currentList[position]

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

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

@ -8,10 +8,6 @@ import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.widget.TextView
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.todoroo.andlib.utility.DateUtilities
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 org.tasks.R
import org.tasks.data.TaskContainer
import org.tasks.databinding.TaskAdapterRowBinding
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.dialogs.Linkify
import org.tasks.preferences.Preferences
@ -32,42 +29,37 @@ import kotlin.math.max
import kotlin.math.roundToInt
class TaskViewHolder internal constructor(
private val context: Activity,
view: ViewGroup,
private val preferences: Preferences,
fontSize: Int,
private val chipProvider: ChipProvider,
private val checkBoxProvider: CheckBoxProvider,
private val textColorOverdue: Int,
private val textColorSecondary: Int,
private val callback: ViewHolderCallbacks,
private val metrics: DisplayMetrics,
private val background: Int,
private val selectedColor: Int,
private val rowPadding: Int,
private val linkify: Linkify,
private val locale: Locale) : RecyclerView.ViewHolder(view) {
private val context: Activity,
binding: TaskAdapterRowBinding,
private val preferences: Preferences,
fontSize: Int,
private val chipProvider: ChipProvider,
private val checkBoxProvider: CheckBoxProvider,
private val textColorOverdue: Int,
private val textColorSecondary: Int,
private val callback: ViewHolderCallbacks,
private val metrics: DisplayMetrics,
private val background: Int,
private val selectedColor: Int,
private val rowPadding: Int,
private val linkify: Linkify,
private val locale: Locale
) : RecyclerView.ViewHolder(binding.root) {
@BindView(R.id.row)
lateinit var row: ViewGroup
@BindView(R.id.due_date)
lateinit var dueDate: TextView
@BindView(R.id.rowBody)
lateinit var rowBody: ViewGroup
@BindView(R.id.title)
lateinit var nameView: TextView
@BindView(R.id.description)
lateinit var description: TextView
@BindView(R.id.completeBox)
lateinit var completeBox: CheckableImageView
@BindView(R.id.chip_group)
lateinit var chipGroup: ChipGroup
private val row: ViewGroup = binding.row
private val dueDate: TextView = binding.dueDate.apply {
setOnClickListener { changeDueDate() }
}
private val rowBody: ViewGroup = binding.rowBody.apply {
setOnClickListener { onRowBodyClick() }
setOnLongClickListener { onRowBodyLongClick() }
}
private val nameView: TextView = binding.title
private val description: TextView = binding.description
private val completeBox: CheckableImageView = binding.completeBox.apply {
setOnClickListener { onCompleteBoxClick() }
}
private val chipGroup: ChipGroup = binding.chipGroup
lateinit var task: TaskContainer
@ -226,14 +218,11 @@ class TaskViewHolder internal constructor(
}
}
@OnClick(R.id.rowBody)
fun onRowBodyClick() = callback.onClick(this)
private fun onRowBodyClick() = callback.onClick(this)
@OnLongClick(R.id.rowBody)
fun onRowBodyLongClick(): Boolean = callback.onLongPress(this)
private fun onRowBodyLongClick(): Boolean = callback.onLongPress(this)
@OnClick(R.id.completeBox)
fun onCompleteBoxClick() {
private fun onCompleteBoxClick() {
val newState = completeBox.isChecked
if (newState != task.isCompleted) {
callback.onCompletedTask(task, newState)
@ -243,8 +232,7 @@ class TaskViewHolder internal constructor(
setupTitleAndCheckbox()
}
@OnClick(R.id.due_date)
fun changeDueDate() {
private fun changeDueDate() {
callback.onChangeDueDate(task)
}
@ -258,7 +246,6 @@ class TaskViewHolder internal constructor(
}
init {
ButterKnife.bind(this, view)
if (preferences.getBoolean(R.string.p_fullTaskTitle, false)) {
nameView.maxLines = Int.MAX_VALUE
nameView.isSingleLine = false
@ -275,9 +262,11 @@ class TaskViewHolder internal constructor(
description.textSize = fontSize.toFloat()
val fontSizeDetails = max(10, fontSize - 2)
dueDate.textSize = fontSizeDetails.toFloat()
view.tag = this
for (i in 0 until view.childCount) {
view.getChildAt(i).tag = this
with(binding.root) {
tag = this@TaskViewHolder
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 dagger.hilt.android.qualifiers.ActivityContext
import org.tasks.R
import org.tasks.databinding.TaskAdapterRowBinding
import org.tasks.dialogs.Linkify
import org.tasks.preferences.Preferences
import org.tasks.preferences.ResourceResolver
@ -42,7 +43,7 @@ class ViewHolderFactory @Inject constructor(
fun newViewHolder(parent: ViewGroup?, callbacks: ViewHolderCallbacks) =
TaskViewHolder(
context as Activity,
LayoutInflater.from(context).inflate(R.layout.task_adapter_row, parent, false) as ViewGroup,
TaskAdapterRowBinding.inflate(LayoutInflater.from(context), parent, false),
preferences,
fontSize,
chipProvider,

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

@ -3,12 +3,13 @@ package org.tasks.ui
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.ViewGroup
import android.widget.TextView
import butterknife.BindView
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.data.Task.Companion.hasDueTime
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.databinding.ControlSetDeadlineBinding
import org.tasks.date.DateTimeUtils
import org.tasks.dialogs.DateTimePicker
import org.tasks.dialogs.DateTimePicker.Companion.newDateTimePicker
@ -23,9 +24,7 @@ class DeadlineControlSet : TaskEditControlFragment() {
@Inject lateinit var locale: Locale
@Inject lateinit var preferences: Preferences
@BindView(R.id.due_date)
lateinit var dueDate: TextView
private lateinit var dueDate: TextView
private lateinit var callback: DueDateChangeListener
override fun onAttach(activity: Activity) {
@ -51,7 +50,11 @@ class DeadlineControlSet : TaskEditControlFragment() {
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

@ -1,11 +1,12 @@
package org.tasks.ui
import android.os.Bundle
import android.view.ViewGroup
import android.widget.EditText
import butterknife.BindView
import butterknife.OnTextChanged
import androidx.core.widget.addTextChangedListener
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.databinding.ControlSetDescriptionBinding
import org.tasks.dialogs.Linkify
import org.tasks.preferences.Preferences
import javax.inject.Inject
@ -15,8 +16,7 @@ class DescriptionControlSet : TaskEditControlFragment() {
@Inject lateinit var linkify: Linkify
@Inject lateinit var preferences: Preferences
@BindView(R.id.notes)
lateinit var editText: EditText
private lateinit var editText: EditText
override fun createView(savedInstanceState: Bundle?) {
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 fun controlId() = TAG
@OnTextChanged(R.id.notes)
fun textChanged(text: CharSequence) {
viewModel.description = text.toString().trim { it <= ' ' }
private fun textChanged(text: CharSequence?) {
viewModel.description = text?.toString()?.trim { it <= ' ' }
}
companion object {

@ -3,21 +3,20 @@ package org.tasks.ui
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import butterknife.BindView
import android.view.ViewGroup
import com.google.android.material.chip.ChipGroup
import com.todoroo.astrid.api.CaldavFilter
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.GtasksFilter
import com.todoroo.astrid.service.TaskMover
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.activities.ListPicker
import org.tasks.databinding.ControlSetRemoteListBinding
import javax.inject.Inject
@AndroidEntryPoint
class ListFragment : TaskEditControlFragment() {
@BindView(R.id.chip_group)
lateinit var chipGroup: ChipGroup
private lateinit var chipGroup: ChipGroup
@Inject lateinit var chipProvider: ChipProvider
@ -42,7 +41,11 @@ class ListFragment : TaskEditControlFragment() {
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

@ -8,17 +8,17 @@ import android.text.SpannableString
import android.text.Spanned
import android.text.style.ClickableSpan
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.util.Pair
import butterknife.BindView
import butterknife.OnClick
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.Strings.isNullOrEmpty
import org.tasks.data.Geofence
import org.tasks.data.Location
import org.tasks.data.Place
import org.tasks.databinding.LocationRowBinding
import org.tasks.dialogs.DialogBuilder
import org.tasks.dialogs.GeofenceDialog
import org.tasks.extensions.Context.openUri
@ -39,14 +39,9 @@ class LocationControlSet : TaskEditControlFragment() {
@Inject lateinit var permissionRequestor: FragmentPermissionRequestor
@Inject lateinit var permissionChecker: PermissionChecker
@BindView(R.id.location_name)
lateinit var locationName: TextView
@BindView(R.id.location_address)
lateinit var locationAddress: TextView
@BindView(R.id.geofence_options)
lateinit var geofenceOptions: ImageView
private lateinit var locationName: TextView
private lateinit var locationAddress: TextView
private lateinit var geofenceOptions: ImageView
override fun onResume() {
super.onResume()
@ -123,8 +118,7 @@ class LocationControlSet : TaskEditControlFragment() {
startActivityForResult(intent, REQUEST_LOCATION_REMINDER)
}
@OnClick(R.id.geofence_options)
fun geofenceOptions() {
private fun geofenceOptions() {
if (permissionChecker.canAccessBackgroundLocation()) {
showGeofenceOptions()
} else {
@ -139,7 +133,15 @@ class LocationControlSet : TaskEditControlFragment() {
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

@ -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.os.Bundle
import android.view.ViewGroup
import androidx.appcompat.widget.AppCompatRadioButton
import butterknife.BindView
import butterknife.OnClick
import com.todoroo.astrid.data.Task
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.databinding.ControlSetPriorityBinding
import org.tasks.themes.ColorProvider
import javax.inject.Inject
@ -15,20 +15,12 @@ import javax.inject.Inject
class PriorityControlSet : TaskEditControlFragment() {
@Inject lateinit var colorProvider: ColorProvider
@BindView(R.id.priority_high)
lateinit var priorityHigh: AppCompatRadioButton
private lateinit var priorityHigh: AppCompatRadioButton
private lateinit var priorityMedium: AppCompatRadioButton
private lateinit var priorityLow: AppCompatRadioButton
private lateinit var priorityNone: AppCompatRadioButton
@BindView(R.id.priority_medium)
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() {
private fun onPriorityChanged() {
viewModel.priority = getPriority()
}
@ -45,7 +37,22 @@ class PriorityControlSet : TaskEditControlFragment() {
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

@ -20,8 +20,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.OnClick
import com.todoroo.andlib.sql.Criterion
import com.todoroo.andlib.sql.Join
import com.todoroo.andlib.sql.QueryTemplate
@ -40,6 +38,7 @@ import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.data.*
import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible
import org.tasks.databinding.ControlSetSubtasksBinding
import org.tasks.extensions.Context.toast
import org.tasks.locale.Locale
import org.tasks.tasklist.SubtaskViewHolder
@ -48,11 +47,8 @@ import javax.inject.Inject
@AndroidEntryPoint
class SubtaskControlSet : TaskEditControlFragment(), SubtaskViewHolder.Callbacks {
@BindView(R.id.recycler_view)
lateinit var recyclerView: RecyclerView
@BindView(R.id.new_subtasks)
lateinit var newSubtaskContainer: LinearLayout
private lateinit var recyclerView: RecyclerView
private lateinit var newSubtaskContainer: LinearLayout
@Inject lateinit var activity: Activity
@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
@ -111,8 +113,7 @@ class SubtaskControlSet : TaskEditControlFragment(), SubtaskViewHolder.Callbacks
localBroadcastManager.unregisterReceiver(refreshReceiver)
}
@OnClick(R.id.add_subtask)
fun addSubtask() {
private fun addSubtask() {
if (isGoogleTaskChild) {
context?.toast(R.string.subtasks_multilevel_google_task)
} else {

@ -8,7 +8,6 @@ import android.widget.ImageView
import android.widget.LinearLayout
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import butterknife.ButterKnife
import org.tasks.R
abstract class TaskEditControlFragment : Fragment() {
@ -19,13 +18,12 @@ abstract class TaskEditControlFragment : Fragment() {
val view = inflater.inflate(R.layout.control_set_template, null)
viewModel = ViewModelProvider(requireParentFragment()).get(TaskEditViewModel::class.java)
val content = view.findViewById<LinearLayout>(R.id.content)
inflater.inflate(layout, content)
bind(content)
val icon = view.findViewById<ImageView>(R.id.icon)
icon.setImageResource(this.icon)
if (isClickable) {
content.setOnClickListener { onRowClick() }
}
ButterKnife.bind(this, view)
createView(savedInstanceState)
@ -38,7 +36,7 @@ abstract class TaskEditControlFragment : Fragment() {
protected open val isClickable: Boolean
get() = false
protected abstract val layout: Int
protected abstract val icon: 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.widget.TextView
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.todoroo.astrid.api.Filter
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.Strings.isNullOrEmpty
import org.tasks.activities.FilterSelectionActivity
import org.tasks.databinding.ActivityWidgetShortcutLayoutBinding
import org.tasks.dialogs.ColorPalettePicker
import org.tasks.dialogs.ColorPalettePicker.Companion.newColorPalette
import org.tasks.dialogs.ColorPickerAdapter.Palette
@ -32,29 +29,31 @@ import javax.inject.Inject
class ShortcutConfigActivity : ThemedInjectingAppCompatActivity(), ColorPalettePicker.ColorPickedCallback {
@Inject lateinit var defaultFilterProvider: DefaultFilterProvider
@BindView(R.id.toolbar)
lateinit var toolbar: Toolbar
@BindView(R.id.shortcut_list)
lateinit var shortcutList: TextInputEditText
@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 lateinit var toolbar: Toolbar
private lateinit var shortcutList: TextInputEditText
private lateinit var shortcutName: TextInputEditText
private lateinit var colorIcon: TextView
private lateinit var clear: View
private var selectedFilter: Filter? = null
private var selectedTheme = 0
public override fun onCreate(savedInstanceState: Bundle?) {
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.navigationIcon = getDrawable(R.drawable.ic_outline_save_24px)
toolbar.setNavigationOnClickListener { save() }
@ -88,24 +87,21 @@ class ShortcutConfigActivity : ThemedInjectingAppCompatActivity(), ColorPaletteP
outState.putInt(EXTRA_THEME, selectedTheme)
}
@OnFocusChange(R.id.shortcut_list)
fun onListFocusChange(focused: Boolean) {
private fun onListFocusChange(focused: Boolean) {
if (focused) {
shortcutList.clearFocus()
showListPicker()
}
}
@OnClick(R.id.shortcut_list)
fun showListPicker() {
private fun showListPicker() {
val intent = Intent(this, FilterSelectionActivity::class.java)
intent.putExtra(FilterSelectionActivity.EXTRA_FILTER, selectedFilter)
intent.putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true)
startActivityForResult(intent, REQUEST_FILTER)
}
@OnClick(R.id.color_row)
fun showThemePicker() {
private fun showThemePicker() {
newColorPalette(null, 0, Palette.LAUNCHERS)
.show(supportFragmentManager, FRAG_TAG_COLOR_PICKER)
}

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

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

@ -12,7 +12,9 @@
app:layout_constraintStart_toStartOf="parent"
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>

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

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

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

@ -18,7 +18,9 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar"/>
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
<LinearLayout
android:layout_width="match_parent"
@ -31,9 +33,13 @@
android:layout_height="match_parent"
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>

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

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

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

@ -292,11 +292,6 @@
++--- io.noties.markwon:core:4.6.2
+| +--- androidx.annotation:annotation:1.1.0 -> 1.2.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.kotlinx:kotlinx-collections-immutable-jvm:0.3.3
+| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.0 -> 1.4.31 (*)

@ -406,11 +406,6 @@
++--- io.noties.markwon:core:4.6.2
+| +--- androidx.annotation:annotation:1.1.0 -> 1.2.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.kotlinx:kotlinx-collections-immutable-jvm:0.3.3
+| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.0 -> 1.4.31 (*)

Loading…
Cancel
Save