Replace FilterSelectionActivity

* Add FilterPicker DialogFragment
* Add FilterPicker compose component
* Rename FilterSelectionActivity to WidgetFilterSelectionActivity
pull/1964/head
Alex Baker 2 years ago
parent d157bbec53
commit 532fea0d29

@ -216,7 +216,7 @@
<activity
android:exported="true"
android:excludeFromRecents="true"
android:name=".activities.FilterSelectionActivity"
android:name=".widget.WidgetFilterSelectionActivity"
android:taskAffinity=""
android:theme="@style/TranslucentDialog"/>

@ -1,111 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.adapter
import android.app.Activity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import androidx.recyclerview.widget.RecyclerView
import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.FilterListItem
import com.todoroo.astrid.api.FilterListItem.Type.*
import org.tasks.billing.Inventory
import org.tasks.filters.NavigationDrawerSubheader
import org.tasks.themes.ColorProvider
import java.util.*
import javax.inject.Inject
class FilterAdapter @Inject constructor(
private val activity: Activity,
private val locale: Locale,
private val inventory: Inventory,
private val colorProvider: ColorProvider,
private val subheaderClickHandler: SubheaderClickHandler,
) : BaseAdapter() {
private var selected: Filter? = null
private var items: List<FilterListItem> = ArrayList()
fun save(outState: Bundle) {
outState.putParcelableArrayList(TOKEN_FILTERS, getItems())
outState.putParcelable(TOKEN_SELECTED, selected)
}
fun restore(savedInstanceState: Bundle) {
items = savedInstanceState.getParcelableArrayList(TOKEN_FILTERS) ?: ArrayList()
selected = savedInstanceState.getParcelable(TOKEN_SELECTED)
}
fun setData(items: List<FilterListItem>, selected: Filter?) {
AndroidUtilities.assertMainThread()
this.items = items
this.selected = selected
notifyDataSetChanged()
}
override fun getCount(): Int {
AndroidUtilities.assertMainThread()
return items.size
}
override fun getItem(position: Int): FilterListItem {
AndroidUtilities.assertMainThread()
return items[position]
}
override fun getItemId(position: Int) = position.toLong()
/** Create or reuse a view */
private fun newView(convertView: View?, parent: ViewGroup, viewType: FilterListItem.Type): View {
return if (convertView != null) {
convertView
} else {
val newView = LayoutInflater.from(parent.context).inflate(viewType.layout, parent, false)
newView.tag = when (viewType) {
ITEM -> FilterViewHolder(
newView, false, locale, activity, inventory, colorProvider, null)
ACTION -> ActionViewHolder(activity, newView, null)
SEPARATOR -> SeparatorViewHolder(newView)
SUBHEADER -> SubheaderViewHolder(newView, subheaderClickHandler)
}
newView
}
}
private fun getItems(): ArrayList<FilterListItem> {
AndroidUtilities.assertMainThread()
return ArrayList(items)
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val item = getItem(position)
val view = newView(convertView, parent, item.itemType)
val viewHolder = view.tag as RecyclerView.ViewHolder
when (item.itemType) {
ITEM -> (viewHolder as FilterViewHolder).bind(item, item == selected, 0)
ACTION -> (viewHolder as ActionViewHolder).bind(item)
SUBHEADER ->
(viewHolder as SubheaderViewHolder).bind((item as NavigationDrawerSubheader))
else -> {}
}
return view
}
override fun getViewTypeCount() = VIEW_TYPE_COUNT
override fun isEnabled(position: Int) = getItem(position).itemType == ITEM
override fun getItemViewType(position: Int) = getItem(position).itemType.ordinal
companion object {
private const val TOKEN_FILTERS = "token_filters"
private const val TOKEN_SELECTED = "token_selected"
private val VIEW_TYPE_COUNT = values().size
}
}

@ -0,0 +1,63 @@
package org.tasks.activities
import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.setFragmentResult
import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.astrid.api.Filter
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.compose.pickers.FilterPicker
import org.tasks.dialogs.DialogBuilder
import javax.inject.Inject
@AndroidEntryPoint
class FilterPicker : DialogFragment() {
@Inject lateinit var dialogBuilder: DialogBuilder
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return dialogBuilder
.newDialog()
.setNegativeButton(R.string.cancel, null)
.setContent {
FilterPicker(
selected = arguments?.getParcelable(EXTRA_FILTER),
onSelected = { filter ->
val data = Bundle()
data.putParcelable(EXTRA_FILTER, filter)
if (filter.valuesForNewTasks != null) {
data.putString(
EXTRA_FILTER_VALUES,
AndroidUtilities.mapToSerializedString(filter.valuesForNewTasks))
}
setFragmentResult(SELECT_FILTER, data)
dismiss()
}
)
}
.show()
}
override fun onCancel(dialog: DialogInterface) {
super.onCancel(dialog)
setFragmentResult(SELECT_FILTER, Bundle())
}
companion object {
const val SELECT_FILTER = "select_filter"
const val EXTRA_FILTER = "extra_filter"
const val EXTRA_FILTER_VALUES = "extra_filter_values"
fun newFilterPicker(
selected: Filter?,
): FilterPicker {
val dialog = FilterPicker()
val arguments = Bundle()
arguments.putParcelable(EXTRA_FILTER, selected)
dialog.arguments = arguments
return dialog
}
}
}

@ -0,0 +1,103 @@
package org.tasks.activities
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.FilterListItem
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.billing.Inventory
import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskDao
import org.tasks.filters.FilterProvider
import org.tasks.filters.NavigationDrawerSubheader
import org.tasks.preferences.Preferences
import org.tasks.themes.ColorProvider
import org.tasks.themes.CustomIcons
import javax.inject.Inject
@HiltViewModel
class FilterPickerViewModel @Inject constructor(
@ApplicationContext private val context: Context,
private val filterProvider: FilterProvider,
private val localBroadcastManager: LocalBroadcastManager,
private val inventory: Inventory,
private val colorProvider: ColorProvider,
private val preferences: Preferences,
private val googleTaskDao: GoogleTaskDao,
private val caldavDao: CaldavDao,
) : ViewModel() {
data class ViewState(
val filters: List<FilterListItem> = emptyList(),
)
private val _viewState = MutableStateFlow(ViewState())
val viewState: StateFlow<ViewState>
get() = _viewState.asStateFlow()
private val refreshReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
refresh()
}
}
private fun refresh() = viewModelScope.launch {
val items = filterProvider.filterPickerItems()
_viewState.update { it.copy(filters = items) }
}
fun onClick(subheader: NavigationDrawerSubheader) = viewModelScope.launch {
val collapsed = !subheader.isCollapsed
when (subheader.subheaderType) {
NavigationDrawerSubheader.SubheaderType.PREFERENCE ->
preferences.setBoolean(subheader.id.toInt(), collapsed)
NavigationDrawerSubheader.SubheaderType.GOOGLE_TASKS ->
googleTaskDao.setCollapsed(subheader.id, collapsed)
NavigationDrawerSubheader.SubheaderType.CALDAV,
NavigationDrawerSubheader.SubheaderType.TASKS,
NavigationDrawerSubheader.SubheaderType.ETESYNC ->
caldavDao.setCollapsed(subheader.id, collapsed)
}
localBroadcastManager.broadcastRefreshList()
}
fun getIcon(filter: Filter): Int {
if (filter.icon < 1000 || inventory.hasPro) {
val icon = CustomIcons.getIconResId(filter.icon)
if (icon != null) {
return icon
}
}
return R.drawable.ic_list_24px
}
fun getColor(filter: Filter): Int {
if (filter.tint != 0) {
val color = colorProvider.getThemeColor(filter.tint, true)
if (color.isFree || inventory.purchasedThemes()) {
return color.primaryColor
}
}
return context.getColor(R.color.text_primary)
}
override fun onCleared() {
localBroadcastManager.unregisterReceiver(refreshReceiver)
}
init {
localBroadcastManager.registerRefreshListReceiver(refreshReceiver)
refresh()
}
}

@ -1,105 +0,0 @@
package org.tasks.activities
import android.app.Activity
import android.appwidget.AppWidgetManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.astrid.adapter.FilterAdapter
import com.todoroo.astrid.api.Filter
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.tasks.LocalBroadcastManager
import org.tasks.dialogs.DialogBuilder
import org.tasks.filters.FilterProvider
import org.tasks.injection.InjectingAppCompatActivity
import org.tasks.preferences.DefaultFilterProvider
import org.tasks.preferences.Preferences
import org.tasks.widget.WidgetPreferences
import javax.inject.Inject
@AndroidEntryPoint
class FilterSelectionActivity : InjectingAppCompatActivity() {
@Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var filterAdapter: FilterAdapter
@Inject lateinit var filterProvider: FilterProvider
@Inject lateinit var localBroadcastManager: LocalBroadcastManager
@Inject lateinit var preferences: Preferences
@Inject lateinit var defaultFilterProvider: DefaultFilterProvider
private var selected: Filter? = null
private val refreshReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
refresh()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val intent = intent
val returnFilter = intent.getBooleanExtra(EXTRA_RETURN_FILTER, false)
val widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
selected = intent.getParcelableExtra(EXTRA_FILTER)
if (savedInstanceState != null) {
filterAdapter.restore(savedInstanceState)
}
dialogBuilder
.newDialog()
.setSingleChoiceItems(filterAdapter, -1) { dialog, which ->
val selectedFilter = filterAdapter.getItem(which) as Filter
val data = Intent()
if (returnFilter) {
data.putExtra(EXTRA_FILTER, selectedFilter)
}
if (widgetId != -1) {
WidgetPreferences(this, preferences, widgetId)
.setFilter(defaultFilterProvider.getFilterPreferenceValue(selectedFilter))
localBroadcastManager.reconfigureWidget(widgetId)
}
data.putExtra(EXTRA_FILTER_NAME, selectedFilter.listingTitle)
data.putExtra(EXTRA_FILTER_SQL, selectedFilter.getSqlQuery())
if (selectedFilter.valuesForNewTasks != null) {
data.putExtra(
EXTRA_FILTER_VALUES,
AndroidUtilities.mapToSerializedString(selectedFilter.valuesForNewTasks))
}
setResult(Activity.RESULT_OK, data)
dialog.dismiss()
}
.setOnDismissListener { finish() }
.show()
}
override fun onResume() {
super.onResume()
localBroadcastManager.registerRefreshListReceiver(refreshReceiver)
refresh()
}
override fun onPause() {
super.onPause()
localBroadcastManager.unregisterReceiver(refreshReceiver)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
filterAdapter.save(outState)
}
private fun refresh() = lifecycleScope.launch {
val items = filterProvider.filterPickerItems()
filterAdapter.setData(items, selected)
}
companion object {
const val EXTRA_RETURN_FILTER = "extra_include_filter"
const val EXTRA_FILTER = "extra_filter"
private const val EXTRA_FILTER_NAME = "extra_filter_name"
private const val EXTRA_FILTER_SQL = "extra_filter_query"
private const val EXTRA_FILTER_VALUES = "extra_filter_values"
}
}

@ -0,0 +1,82 @@
package org.tasks.compose.pickers
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ContentAlpha
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.todoroo.astrid.api.Filter
import org.tasks.R
import org.tasks.activities.FilterPickerViewModel
import org.tasks.compose.collectAsStateLifecycleAware
import org.tasks.filters.NavigationDrawerSubheader
@Composable
fun FilterPicker(
viewModel: FilterPickerViewModel = viewModel(),
selected: Filter?,
onSelected: (Filter) -> Unit,
) {
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
.padding(vertical = 12.dp)
) {
val filters = viewModel.viewState.collectAsStateLifecycleAware().value.filters
filters.forEach { filter ->
when (filter) {
is NavigationDrawerSubheader -> {
CollapsibleRow(
text = filter.listingTitle,
collapsed = filter.isCollapsed,
onClick = { viewModel.onClick(filter) },
)
}
is Filter -> {
CheckableIconRow(
icon = painterResource(id = viewModel.getIcon(filter)),
tint = Color(viewModel.getColor(filter)),
selected = filter == selected,
onClick = { onSelected(filter) },
) {
Row(verticalAlignment = CenterVertically) {
Text(
text = filter.listingTitle,
style = MaterialTheme.typography.body2.copy(
fontWeight = FontWeight.Medium
),
modifier = Modifier.weight(1f),
)
if (filter.principals > 0) {
Icon(
painter = painterResource(
id = when (filter.principals) {
1 -> R.drawable.ic_outline_perm_identity_24px
in 2..Int.MAX_VALUE -> R.drawable.ic_outline_people_outline_24
else -> 0
}
),
modifier = Modifier.alpha(ContentAlpha.medium),
contentDescription = null,
)
}
}
}
}
}
}
}
}

@ -1,21 +1,18 @@
package org.tasks.preferences.fragments
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import com.todoroo.astrid.api.Filter
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.activities.FilterSelectionActivity
import org.tasks.activities.FilterPicker
import org.tasks.activities.FilterPicker.Companion.SELECT_FILTER
import org.tasks.activities.FilterPicker.Companion.newFilterPicker
import org.tasks.injection.InjectingPreferenceFragment
import org.tasks.preferences.DefaultFilterProvider
import javax.inject.Inject
private const val REQUEST_SELECT_FILTER = 1005
@AndroidEntryPoint
class DashClock : InjectingPreferenceFragment() {
@ -24,39 +21,37 @@ class DashClock : InjectingPreferenceFragment() {
override fun getPreferenceXml() = R.xml.preferences_dashclock
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
childFragmentManager.setFragmentResultListener(
SELECT_FILTER,
this
) { _, data ->
defaultFilterProvider.dashclockFilter = data.getParcelable(FilterPicker.EXTRA_FILTER)!!
lifecycleScope.launch {
refreshPreferences()
}
localBroadcastManager.broadcastRefresh()
}
}
override suspend fun setupPreferences(savedInstanceState: Bundle?) {
findPreference(R.string.p_dashclock_filter)
.setOnPreferenceClickListener {
val intent = Intent(context, FilterSelectionActivity::class.java)
intent.putExtra(
FilterSelectionActivity.EXTRA_FILTER, defaultFilterProvider.dashclockFilter
)
intent.putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true)
startActivityForResult(intent, REQUEST_SELECT_FILTER)
newFilterPicker(defaultFilterProvider.dashclockFilter)
.show(childFragmentManager, FRAG_TAG_SELECT_PICKER)
false
}
refreshPreferences()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_SELECT_FILTER) {
if (resultCode == Activity.RESULT_OK) {
val filter: Filter =
data!!.getParcelableExtra(FilterSelectionActivity.EXTRA_FILTER)!!
defaultFilterProvider.dashclockFilter = filter
lifecycleScope.launch {
refreshPreferences()
}
localBroadcastManager.broadcastRefresh()
}
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}
private suspend fun refreshPreferences() {
val filter = defaultFilterProvider.getFilterFromPreference(R.string.p_dashclock_filter)
findPreference(R.string.p_dashclock_filter).summary = filter.listingTitle
}
companion object {
private const val FRAG_TAG_SELECT_PICKER = "frag_tag_select_picker"
}
}

@ -17,7 +17,8 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.activities.FilterSelectionActivity
import org.tasks.activities.FilterPicker
import org.tasks.activities.FilterPicker.Companion.newFilterPicker
import org.tasks.billing.Inventory
import org.tasks.billing.PurchaseActivity
import org.tasks.dialogs.ColorPalettePicker
@ -40,17 +41,6 @@ import org.tasks.ui.NavigationDrawerFragment.Companion.REQUEST_PURCHASE
import java.util.*
import javax.inject.Inject
private const val REQUEST_THEME_PICKER = 10001
private const val REQUEST_COLOR_PICKER = 10002
private const val REQUEST_ACCENT_PICKER = 10003
private const val REQUEST_LAUNCHER_PICKER = 10004
private const val REQUEST_DEFAULT_LIST = 10005
private const val REQUEST_LOCALE = 10006
private const val FRAG_TAG_LOCALE_PICKER = "frag_tag_locale_picker"
private const val FRAG_TAG_THEME_PICKER = "frag_tag_theme_picker"
private const val FRAG_TAG_COLOR_PICKER = "frag_tag_color_picker"
@AndroidEntryPoint
class LookAndFeel : InjectingPreferenceFragment() {
@ -65,6 +55,19 @@ class LookAndFeel : InjectingPreferenceFragment() {
override fun getPreferenceXml() = R.xml.preferences_look_and_feel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
childFragmentManager.setFragmentResultListener(
FilterPicker.SELECT_FILTER,
this
) { _, data ->
val filter: Filter = data.getParcelable(FilterPicker.EXTRA_FILTER)!!
defaultFilterProvider.setDefaultOpenFilter(filter)
findPreference(R.string.p_default_open_filter).summary = filter.listingTitle
localBroadcastManager.broadcastRefresh()
}
}
override suspend fun setupPreferences(savedInstanceState: Bundle?) {
val themePref = findPreference(R.string.p_theme)
val themeNames = resources.getStringArray(R.array.base_theme_names)
@ -87,13 +90,8 @@ class LookAndFeel : InjectingPreferenceFragment() {
defaultList.summary = filter.listingTitle
defaultList.onPreferenceClickListener = Preference.OnPreferenceClickListener {
lifecycleScope.launch {
val intent = Intent(context, FilterSelectionActivity::class.java)
intent.putExtra(
FilterSelectionActivity.EXTRA_FILTER,
defaultFilterProvider.getDefaultOpenFilter()
)
intent.putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true)
startActivityForResult(intent, REQUEST_DEFAULT_LIST)
newFilterPicker(defaultFilterProvider.getDefaultOpenFilter())
.show(childFragmentManager, FRAG_TAG_FILTER_PICKER)
}
true
}
@ -204,15 +202,6 @@ class LookAndFeel : InjectingPreferenceFragment() {
updateLauncherPreference()
}
}
REQUEST_DEFAULT_LIST -> {
if (resultCode == RESULT_OK) {
val filter: Filter =
data!!.getParcelableExtra(FilterSelectionActivity.EXTRA_FILTER)!!
defaultFilterProvider.setDefaultOpenFilter(filter)
findPreference(R.string.p_default_open_filter).summary = filter.listingTitle
localBroadcastManager.broadcastRefresh()
}
}
REQUEST_LOCALE -> {
if (resultCode == RESULT_OK) {
val languageTag = data!!.getStringExtra(LocalePickerDialog.EXTRA_LOCALE)
@ -255,4 +244,16 @@ class LookAndFeel : InjectingPreferenceFragment() {
false
}
}
companion object {
private const val REQUEST_THEME_PICKER = 10001
private const val REQUEST_COLOR_PICKER = 10002
private const val REQUEST_ACCENT_PICKER = 10003
private const val REQUEST_LAUNCHER_PICKER = 10004
private const val REQUEST_LOCALE = 10006
private const val FRAG_TAG_LOCALE_PICKER = "frag_tag_locale_picker"
private const val FRAG_TAG_THEME_PICKER = "frag_tag_theme_picker"
private const val FRAG_TAG_COLOR_PICKER = "frag_tag_color_picker"
private const val FRAG_TAG_FILTER_PICKER = "frag_tag_filter_picker"
}
}

@ -20,7 +20,8 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.activities.FilterSelectionActivity
import org.tasks.activities.FilterPicker
import org.tasks.activities.FilterPicker.Companion.newFilterPicker
import org.tasks.dialogs.MyTimePickerDialog.Companion.newTimePicker
import org.tasks.extensions.Context.getResourceUri
import org.tasks.injection.InjectingPreferenceFragment
@ -33,14 +34,6 @@ import org.tasks.ui.TimePreference
import timber.log.Timber
import javax.inject.Inject
private const val REQUEST_QUIET_START = 10001
private const val REQUEST_QUIET_END = 10002
private const val REQUEST_DEFAULT_REMIND = 10003
private const val REQUEST_BADGE_LIST = 10004
private const val REQUEST_CODE_ALERT_RINGTONE = 10005
private const val REQUEST_CODE_TTS_CHECK = 10006
private const val REQUEST_CODE_COMPLETION_SOUND = 10007
@AndroidEntryPoint
class Notifications : InjectingPreferenceFragment() {
@ -51,6 +44,19 @@ class Notifications : InjectingPreferenceFragment() {
override fun getPreferenceXml() = R.xml.preferences_notifications
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
childFragmentManager.setFragmentResultListener(
FilterPicker.SELECT_FILTER,
this
) { _, data ->
val filter: Filter = data.getParcelable(FilterPicker.EXTRA_FILTER)!!
defaultFilterProvider.setBadgeFilter(filter)
findPreference(R.string.p_badge_list).summary = filter.listingTitle
localBroadcastManager.broadcastRefresh()
}
}
override suspend fun setupPreferences(savedInstanceState: Bundle?) {
rescheduleNotificationsOnChange(
false,
@ -86,12 +92,8 @@ class Notifications : InjectingPreferenceFragment() {
badgePreference.summary = filter.listingTitle
badgePreference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
lifecycleScope.launch {
val intent = Intent(context, FilterSelectionActivity::class.java)
intent.putExtra(
FilterSelectionActivity.EXTRA_FILTER, defaultFilterProvider.getBadgeFilter()
)
intent.putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true)
startActivityForResult(intent, REQUEST_BADGE_LIST)
newFilterPicker(defaultFilterProvider.getBadgeFilter())
.show(childFragmentManager, FRAG_TAG_FILTER_PICKER)
}
true
}
@ -316,13 +318,6 @@ class Notifications : InjectingPreferenceFragment() {
REQUEST_DEFAULT_REMIND -> if (resultCode == RESULT_OK) {
getDefaultRemindTimePreference()!!.handleTimePickerActivityIntent(data)
}
REQUEST_BADGE_LIST -> if (resultCode == RESULT_OK) {
val filter: Filter =
data!!.getParcelableExtra(FilterSelectionActivity.EXTRA_FILTER)!!
defaultFilterProvider.setBadgeFilter(filter)
findPreference(R.string.p_badge_list).summary = filter.listingTitle
localBroadcastManager.broadcastRefresh()
}
REQUEST_CODE_TTS_CHECK -> if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) { // success, create the TTS instance
voiceOutputAssistant.initTTS()
} else { // missing data, install it
@ -333,4 +328,14 @@ class Notifications : InjectingPreferenceFragment() {
else -> super.onActivityResult(requestCode, resultCode, data)
}
}
companion object {
private const val REQUEST_QUIET_START = 10001
private const val REQUEST_QUIET_END = 10002
private const val REQUEST_DEFAULT_REMIND = 10003
private const val REQUEST_CODE_ALERT_RINGTONE = 10005
private const val REQUEST_CODE_TTS_CHECK = 10006
private const val REQUEST_CODE_COMPLETION_SOUND = 10007
private const val FRAG_TAG_FILTER_PICKER = "frag_tag_filter_picker"
}
}

@ -12,7 +12,8 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.activities.FilterSelectionActivity
import org.tasks.activities.FilterPicker
import org.tasks.activities.FilterPicker.Companion.newFilterPicker
import org.tasks.dialogs.ColorPalettePicker
import org.tasks.dialogs.ColorPalettePicker.Companion.newColorPalette
import org.tasks.dialogs.ColorPickerAdapter.Palette
@ -25,19 +26,19 @@ import org.tasks.preferences.Preferences
import org.tasks.widget.WidgetPreferences
import javax.inject.Inject
private const val REQUEST_FILTER = 1005
private const val REQUEST_THEME_SELECTION = 1006
private const val REQUEST_COLOR_SELECTION = 1007
private const val REQUEST_SORT = 1008
const val EXTRA_WIDGET_ID = "extra_widget_id"
@AndroidEntryPoint
class ScrollableWidget : InjectingPreferenceFragment() {
companion object {
private const val REQUEST_THEME_SELECTION = 1006
private const val REQUEST_COLOR_SELECTION = 1007
private const val REQUEST_SORT = 1008
const val EXTRA_WIDGET_ID = "extra_widget_id"
private const val FRAG_TAG_COLOR_PICKER = "frag_tag_color_picker"
private const val FRAG_TAG_SORT_DIALOG = "frag_tag_sort_dialog"
private const val FRAG_TAG_FILTER_PICKER = "frag_tag_filter_picker"
fun newScrollableWidget(appWidgetId: Int): ScrollableWidget {
val widget = ScrollableWidget()
@ -57,6 +58,18 @@ class ScrollableWidget : InjectingPreferenceFragment() {
override fun getPreferenceXml() = R.xml.preferences_widget
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
childFragmentManager.setFragmentResultListener(
FilterPicker.SELECT_FILTER,
this
) { _, data ->
val filter: Filter = data.getParcelable(FilterPicker.EXTRA_FILTER)!!
widgetPreferences.setFilter(defaultFilterProvider.getFilterPreferenceValue(filter))
updateFilter()
}
}
override suspend fun setupPreferences(savedInstanceState: Bundle?) {
appWidgetId = requireArguments().getInt(EXTRA_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)
widgetPreferences = WidgetPreferences(context, preferences, appWidgetId)
@ -116,10 +129,8 @@ class ScrollableWidget : InjectingPreferenceFragment() {
findPreference(R.string.p_widget_filter)
.setOnPreferenceClickListener {
lifecycleScope.launch {
val intent = Intent(context, FilterSelectionActivity::class.java)
intent.putExtra(FilterSelectionActivity.EXTRA_FILTER, getFilter())
intent.putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true)
startActivityForResult(intent, REQUEST_FILTER)
newFilterPicker(getFilter())
.show(childFragmentManager, FRAG_TAG_FILTER_PICKER)
}
false
}
@ -146,12 +157,6 @@ class ScrollableWidget : InjectingPreferenceFragment() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_FILTER -> if (resultCode == Activity.RESULT_OK) {
val filter: Filter =
data!!.getParcelableExtra(FilterSelectionActivity.EXTRA_FILTER)!!
widgetPreferences.setFilter(defaultFilterProvider.getFilterPreferenceValue(filter))
updateFilter()
}
REQUEST_THEME_SELECTION -> if (resultCode == Activity.RESULT_OK) {
widgetPreferences.setTheme(
data?.getIntExtra(

@ -1,12 +1,12 @@
package org.tasks.preferences.fragments
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.os.Bundle
import com.todoroo.astrid.api.Filter
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.activities.FilterSelectionActivity
import org.tasks.activities.FilterPicker
import org.tasks.activities.FilterPicker.Companion.newFilterPicker
import org.tasks.billing.Inventory
import org.tasks.billing.PurchaseActivity
import org.tasks.injection.InjectingPreferenceFragment
@ -14,14 +14,14 @@ import org.tasks.locale.bundle.ListNotificationBundle
import org.tasks.preferences.DefaultFilterProvider
import javax.inject.Inject
const val EXTRA_FILTER = "extra_filter"
private const val REQUEST_SELECT_FILTER = 10124
private const val REQUEST_SUBSCRIPTION = 10125
@AndroidEntryPoint
class TaskerListNotification : InjectingPreferenceFragment() {
companion object {
const val EXTRA_FILTER = "extra_filter"
private const val REQUEST_SUBSCRIPTION = 10125
private const val FRAG_TAG_FILTER_PICKER = "frag_tag_filter_picker"
fun newTaskerListNotification(filter: String?): TaskerListNotification {
val fragment = TaskerListNotification()
val args = Bundle()
@ -39,6 +39,17 @@ class TaskerListNotification : InjectingPreferenceFragment() {
override fun getPreferenceXml() = R.xml.preferences_tasker
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
childFragmentManager.setFragmentResultListener(
FilterPicker.SELECT_FILTER,
this
) { _, data ->
filter = data.getParcelable(FilterPicker.EXTRA_FILTER)!!
refreshPreferences()
}
}
override suspend fun setupPreferences(savedInstanceState: Bundle?) {
filter = if (savedInstanceState == null) {
defaultFilterProvider.getFilterFromPreferenceBlocking(arguments?.getString(EXTRA_FILTER))
@ -49,10 +60,8 @@ class TaskerListNotification : InjectingPreferenceFragment() {
refreshPreferences()
findPreference(R.string.filter).setOnPreferenceClickListener {
val intent = Intent(context, FilterSelectionActivity::class.java)
intent.putExtra(FilterSelectionActivity.EXTRA_FILTER, filter)
intent.putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true)
startActivityForResult(intent, REQUEST_SELECT_FILTER)
newFilterPicker(filter)
.show(childFragmentManager, FRAG_TAG_FILTER_PICKER)
false
}
@ -66,10 +75,6 @@ class TaskerListNotification : InjectingPreferenceFragment() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_SELECT_FILTER -> if (resultCode == RESULT_OK) {
filter = data!!.getParcelableExtra(FilterSelectionActivity.EXTRA_FILTER)!!
refreshPreferences()
}
REQUEST_SUBSCRIPTION -> if (!inventory.purchasedTasker()) {
cancelled = true
requireActivity().finish()

@ -13,7 +13,8 @@ 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.activities.FilterPicker
import org.tasks.activities.FilterPicker.Companion.newFilterPicker
import org.tasks.databinding.ActivityWidgetShortcutLayoutBinding
import org.tasks.dialogs.ColorPalettePicker
import org.tasks.dialogs.ColorPalettePicker.Companion.newColorPalette
@ -65,19 +66,16 @@ class ShortcutConfigActivity : ThemedInjectingAppCompatActivity(), ColorPaletteP
selectedTheme = savedInstanceState.getInt(EXTRA_THEME)
}
updateFilterAndTheme()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_FILTER) {
if (resultCode == Activity.RESULT_OK) {
if (selectedFilter != null && selectedFilter!!.listingTitle == getShortcutName()) {
shortcutName.text = null
}
selectedFilter = data!!.getParcelableExtra(FilterSelectionActivity.EXTRA_FILTER)
updateFilterAndTheme()
supportFragmentManager.setFragmentResultListener(
FilterPicker.SELECT_FILTER,
this
) { _, data ->
if (selectedFilter != null && selectedFilter!!.listingTitle == getShortcutName()) {
shortcutName.text = null
}
} else {
super.onActivityResult(requestCode, resultCode, data)
selectedFilter = data.getParcelable(FilterPicker.EXTRA_FILTER)
updateFilterAndTheme()
}
}
@ -95,10 +93,8 @@ class ShortcutConfigActivity : ThemedInjectingAppCompatActivity(), ColorPaletteP
}
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)
newFilterPicker(selectedFilter)
.show(supportFragmentManager, FRAG_TAG_FILTER_PICKER)
}
private fun showThemePicker() {
@ -150,6 +146,6 @@ class ShortcutConfigActivity : ThemedInjectingAppCompatActivity(), ColorPaletteP
private const val EXTRA_FILTER = "extra_filter"
private const val EXTRA_THEME = "extra_theme"
private const val FRAG_TAG_COLOR_PICKER = "frag_tag_color_picker"
private const val REQUEST_FILTER = 1019
private const val FRAG_TAG_FILTER_PICKER = "frag_tag_filter_picker"
}
}

@ -17,7 +17,7 @@ import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.runBlocking
import org.tasks.R
import org.tasks.activities.FilterSelectionActivity
import org.tasks.activities.FilterPicker
import org.tasks.intents.TaskIntents
import org.tasks.preferences.DefaultFilterProvider
import org.tasks.preferences.Preferences
@ -195,9 +195,9 @@ class TasksWidget : AppWidgetProvider() {
}
private fun getChooseListIntent(context: Context, filter: Filter, widgetId: Int): PendingIntent {
val intent = Intent(context, FilterSelectionActivity::class.java)
val intent = Intent(context, WidgetFilterSelectionActivity::class.java)
intent.flags = flags
intent.putExtra(FilterSelectionActivity.EXTRA_FILTER, filter)
intent.putExtra(FilterPicker.EXTRA_FILTER, filter)
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId)
intent.action = "choose_list"
return PendingIntent.getActivity(

@ -0,0 +1,50 @@
package org.tasks.widget
import android.appwidget.AppWidgetManager
import android.content.Intent
import android.os.Bundle
import com.todoroo.astrid.api.Filter
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.LocalBroadcastManager
import org.tasks.activities.FilterPicker.Companion.EXTRA_FILTER
import org.tasks.activities.FilterPicker.Companion.SELECT_FILTER
import org.tasks.activities.FilterPicker.Companion.newFilterPicker
import org.tasks.injection.InjectingAppCompatActivity
import org.tasks.preferences.DefaultFilterProvider
import org.tasks.preferences.Preferences
import javax.inject.Inject
@AndroidEntryPoint
class WidgetFilterSelectionActivity : InjectingAppCompatActivity() {
@Inject lateinit var preferences: Preferences
@Inject lateinit var defaultFilterProvider: DefaultFilterProvider
@Inject lateinit var localBroadcastManager: LocalBroadcastManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
if (widgetId == -1) {
throw RuntimeException("Missing ${AppWidgetManager.EXTRA_APPWIDGET_ID}")
}
supportFragmentManager
.setFragmentResultListener(SELECT_FILTER, this) { _, result ->
if (result.isEmpty) {
finish()
return@setFragmentResultListener
}
result.getParcelable<Filter>(EXTRA_FILTER)?.let { filter ->
WidgetPreferences(this, preferences, widgetId)
.setFilter(defaultFilterProvider.getFilterPreferenceValue(filter))
localBroadcastManager.reconfigureWidget(widgetId)
}
setResult(RESULT_OK, Intent().putExtras(result))
finish()
}
newFilterPicker(intent.getParcelableExtra(EXTRA_FILTER))
.show(supportFragmentManager, FRAG_TAG_FILTER_PICKER)
}
companion object {
private const val FRAG_TAG_FILTER_PICKER = "frag_tag_filter_picker"
}
}
Loading…
Cancel
Save