Use coroutines in widget

pull/1051/head
Alex Baker 4 years ago
parent d550063114
commit 275369c807

@ -4,9 +4,11 @@ import android.app.Activity
import android.appwidget.AppWidgetManager
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import androidx.preference.*
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
@ -93,10 +95,12 @@ class ScrollableWidget : InjectingPreferenceFragment() {
findPreference(R.string.p_widget_filter)
.setOnPreferenceClickListener {
val intent = Intent(context, FilterSelectionActivity::class.java)
intent.putExtra(FilterSelectionActivity.EXTRA_FILTER, getFilter())
intent.putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true)
startActivityForResult(intent, REQUEST_FILTER)
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)
}
false
}
@ -166,12 +170,12 @@ class ScrollableWidget : InjectingPreferenceFragment() {
tintColorPreference(R.string.p_widget_color_v2, widgetPreferences.color)
}
private fun updateFilter() {
findPreference(R.string.p_widget_filter).summary = getFilter()!!.listingTitle
private fun updateFilter() = lifecycleScope.launch {
findPreference(R.string.p_widget_filter).summary = getFilter().listingTitle
}
private fun getFilter(): Filter? {
return defaultFilterProvider.getFilterFromPreferenceBlocking(widgetPreferences.filterId)
private suspend fun getFilter(): Filter {
return defaultFilterProvider.getFilterFromPreference(widgetPreferences.filterId)
}
private fun setupSlider(resId: Int, defValue: Int): SeekBarPreference {

@ -12,12 +12,12 @@ import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.subtasks.SubtasksHelper
import kotlinx.coroutines.runBlocking
import org.tasks.BuildConfig
import org.tasks.R
import org.tasks.data.SubtaskInfo
import org.tasks.data.TaskContainer
import org.tasks.data.TaskListQuery.getQuery
import org.tasks.data.runBlocking
import org.tasks.locale.Locale
import org.tasks.preferences.DefaultFilterProvider
import org.tasks.preferences.Preferences
@ -59,10 +59,10 @@ internal class ScrollableViewsFactory(
override fun onCreate() {}
override fun onDataSetChanged() {
updateSettings()
tasks = runBlocking {
taskDao.fetchTasks {
subtasks: SubtaskInfo -> getQuery(filter, subtasks)
runBlocking {
updateSettings()
tasks = taskDao.fetchTasks { subtasks: SubtaskInfo ->
getQuery(filter, subtasks)
}
}
}
@ -239,7 +239,7 @@ internal class ScrollableViewsFactory(
}
}
private fun updateSettings() {
private suspend fun updateSettings() {
val widgetPreferences = WidgetPreferences(context, preferences, widgetId)
vPad = widgetPreferences.widgetSpacing
hPad = context.resources.getDimension(R.dimen.widget_padding).toInt()
@ -256,7 +256,7 @@ internal class ScrollableViewsFactory(
showCheckboxes = widgetPreferences.showCheckboxes()
textSize = widgetPreferences.fontSize.toFloat()
dueDateTextSize = max(10f, textSize - 2)
filter = defaultFilterProvider.getFilterFromPreferenceBlocking(widgetPreferences.filterId)
filter = defaultFilterProvider.getFilterFromPreference(widgetPreferences.filterId)
showDividers = widgetPreferences.showDividers()
showSubtasks = widgetPreferences.showSubtasks()
isRtl = locale.directionality == View.LAYOUT_DIRECTION_RTL
@ -265,6 +265,5 @@ internal class ScrollableViewsFactory(
init {
val metrics = context.resources.displayMetrics
indentPadding = (20 * metrics.density).toInt()
updateSettings()
}
}

@ -1,173 +0,0 @@
package org.tasks.widget;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.view.View;
import android.widget.RemoteViews;
import androidx.annotation.ColorInt;
import androidx.core.graphics.ColorUtils;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.dao.TaskDaoBlocking;
import dagger.hilt.android.AndroidEntryPoint;
import dagger.hilt.android.qualifiers.ApplicationContext;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.activities.FilterSelectionActivity;
import org.tasks.intents.TaskIntents;
import org.tasks.locale.Locale;
import org.tasks.preferences.DefaultFilterProvider;
import org.tasks.preferences.Preferences;
import org.tasks.themes.ThemeColor;
import timber.log.Timber;
@AndroidEntryPoint
public class TasksWidget extends AppWidgetProvider {
private static final int flags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP;
@Inject Preferences preferences;
@Inject DefaultFilterProvider defaultFilterProvider;
@Inject Locale locale;
@Inject TaskDaoBlocking taskDao;
@Inject @ApplicationContext Context context;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int id : appWidgetIds) {
try {
appWidgetManager.updateAppWidget(id, createScrollableWidget(context, id));
} catch (Exception e) {
Timber.e(e);
}
}
}
private RemoteViews createScrollableWidget(Context context, int id) {
WidgetPreferences widgetPreferences = new WidgetPreferences(context, preferences, id);
String filterId = widgetPreferences.getFilterId();
ThemeColor color = new ThemeColor(context, widgetPreferences.getColor());
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.scrollable_widget);
remoteViews.setInt(R.id.widget, "setLayoutDirection", locale.getDirectionality());
if (widgetPreferences.showHeader()) {
remoteViews.setViewVisibility(R.id.widget_header, View.VISIBLE);
remoteViews.setViewVisibility(
R.id.widget_change_list, widgetPreferences.showMenu() ? View.VISIBLE : View.GONE);
int widgetTitlePadding =
widgetPreferences.showMenu()
? 0
: (int) context.getResources().getDimension(R.dimen.widget_padding);
remoteViews.setViewPadding(R.id.widget_title, widgetTitlePadding, 0, 0, 0);
remoteViews.setViewVisibility(
R.id.widget_reconfigure, widgetPreferences.showSettings() ? View.VISIBLE : View.GONE);
remoteViews.setInt(R.id.widget_title, "setTextColor", color.getColorOnPrimary());
remoteViews.setInt(R.id.widget_button, "setColorFilter", color.getColorOnPrimary());
remoteViews.setInt(R.id.widget_reconfigure, "setColorFilter", color.getColorOnPrimary());
remoteViews.setInt(R.id.widget_change_list, "setColorFilter", color.getColorOnPrimary());
} else {
remoteViews.setViewVisibility(R.id.widget_header, View.GONE);
}
remoteViews.setInt(
R.id.widget_header,
"setBackgroundColor",
ColorUtils.setAlphaComponent(color.getPrimaryColor(), widgetPreferences.getHeaderOpacity()));
int bgColor = getBackgroundColor(widgetPreferences.getThemeIndex());
remoteViews.setInt(
R.id.list_view,
"setBackgroundColor",
ColorUtils.setAlphaComponent(bgColor, widgetPreferences.getRowOpacity()));
remoteViews.setInt(
R.id.empty_view,
"setBackgroundColor",
ColorUtils.setAlphaComponent(bgColor, widgetPreferences.getFooterOpacity()));
Filter filter = defaultFilterProvider.getFilterFromPreferenceBlocking(filterId);
remoteViews.setTextViewText(R.id.widget_title, filter.listingTitle);
Uri cacheBuster = Uri.parse("tasks://widget/" + System.currentTimeMillis());
remoteViews.setRemoteAdapter(
R.id.list_view,
new Intent(context, ScrollableWidgetUpdateService.class)
.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id)
.setData(cacheBuster));
setRipple(
remoteViews, color, R.id.widget_button, R.id.widget_change_list, R.id.widget_reconfigure);
remoteViews.setOnClickPendingIntent(R.id.widget_title, getOpenListIntent(context, filter, id));
remoteViews.setOnClickPendingIntent(R.id.widget_button, getNewTaskIntent(context, filter, id));
remoteViews.setOnClickPendingIntent(R.id.widget_change_list, getChooseListIntent(context, filter, id));
remoteViews.setOnClickPendingIntent(
R.id.widget_reconfigure, getWidgetConfigIntent(context, id));
if (widgetPreferences.openOnFooterClick()) {
remoteViews.setOnClickPendingIntent(R.id.empty_view, getOpenListIntent(context, filter, id));
} else {
remoteViews.setOnClickPendingIntent(R.id.empty_view, null);
}
remoteViews.setPendingIntentTemplate(R.id.list_view, getPendingIntentTemplate(context));
return remoteViews;
}
private void setRipple(RemoteViews rv, ThemeColor color, int... views) {
int drawableRes =
color.isDark()
? R.drawable.widget_ripple_circle_light
: R.drawable.widget_ripple_circle_dark;
for (int view : views) {
rv.setInt(view, "setBackgroundResource", drawableRes);
}
}
private @ColorInt int getBackgroundColor(int themeIndex) {
int background;
if (themeIndex == 1) {
background = android.R.color.black;
} else if (themeIndex == 2) {
background = R.color.md_background_dark;
} else {
background = android.R.color.white;
}
return context.getColor(background);
}
private PendingIntent getPendingIntentTemplate(Context context) {
return PendingIntent.getActivity(
context, 0, new Intent(context, WidgetClickActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
}
private PendingIntent getOpenListIntent(Context context, Filter filter, int widgetId) {
Intent intent = TaskIntents.getTaskListIntent(context, filter);
intent.setFlags(flags);
intent.setAction("open_list");
return PendingIntent.getActivity(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private PendingIntent getNewTaskIntent(Context context, Filter filter, int widgetId) {
Intent intent = TaskIntents.getNewTaskIntent(context, filter);
intent.setAction("new_task");
return PendingIntent.getActivity(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private PendingIntent getWidgetConfigIntent(Context context, final int widgetId) {
Intent intent = new Intent(context, WidgetConfigActivity.class);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
intent.setAction("widget_settings");
return PendingIntent.getActivity(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private PendingIntent getChooseListIntent(Context context, Filter filter, int widgetId) {
Intent intent = new Intent(context, FilterSelectionActivity.class);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra(FilterSelectionActivity.EXTRA_FILTER, filter);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
intent.setAction("choose_list");
return PendingIntent.getActivity(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}

@ -0,0 +1,157 @@
package org.tasks.widget
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.view.View
import android.widget.RemoteViews
import androidx.annotation.ColorInt
import androidx.core.graphics.ColorUtils
import com.todoroo.astrid.api.Filter
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.intents.TaskIntents
import org.tasks.locale.Locale
import org.tasks.preferences.DefaultFilterProvider
import org.tasks.preferences.Preferences
import org.tasks.themes.ThemeColor
import timber.log.Timber
import javax.inject.Inject
@AndroidEntryPoint
class TasksWidget : AppWidgetProvider() {
@Inject lateinit var preferences: Preferences
@Inject lateinit var defaultFilterProvider: DefaultFilterProvider
@Inject lateinit var locale: Locale
@Inject @ApplicationContext lateinit var context: Context
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
for (id in appWidgetIds) {
try {
appWidgetManager.updateAppWidget(id, createScrollableWidget(context, id))
} catch (e: Exception) {
Timber.e(e)
}
}
}
private fun createScrollableWidget(context: Context, id: Int): RemoteViews {
val widgetPreferences = WidgetPreferences(context, preferences, id)
val filterId = widgetPreferences.filterId
val color = ThemeColor(context, widgetPreferences.color)
val remoteViews = RemoteViews(context.packageName, R.layout.scrollable_widget)
remoteViews.setInt(R.id.widget, "setLayoutDirection", locale.directionality)
if (widgetPreferences.showHeader()) {
remoteViews.setViewVisibility(R.id.widget_header, View.VISIBLE)
remoteViews.setViewVisibility(
R.id.widget_change_list, if (widgetPreferences.showMenu()) View.VISIBLE else View.GONE)
val widgetTitlePadding = if (widgetPreferences.showMenu()) 0 else context.resources.getDimension(R.dimen.widget_padding).toInt()
remoteViews.setViewPadding(R.id.widget_title, widgetTitlePadding, 0, 0, 0)
remoteViews.setViewVisibility(
R.id.widget_reconfigure, if (widgetPreferences.showSettings()) View.VISIBLE else View.GONE)
remoteViews.setInt(R.id.widget_title, "setTextColor", color.colorOnPrimary)
remoteViews.setInt(R.id.widget_button, "setColorFilter", color.colorOnPrimary)
remoteViews.setInt(R.id.widget_reconfigure, "setColorFilter", color.colorOnPrimary)
remoteViews.setInt(R.id.widget_change_list, "setColorFilter", color.colorOnPrimary)
} else {
remoteViews.setViewVisibility(R.id.widget_header, View.GONE)
}
remoteViews.setInt(
R.id.widget_header,
"setBackgroundColor",
ColorUtils.setAlphaComponent(color.primaryColor, widgetPreferences.headerOpacity))
val bgColor = getBackgroundColor(widgetPreferences.themeIndex)
remoteViews.setInt(
R.id.list_view,
"setBackgroundColor",
ColorUtils.setAlphaComponent(bgColor, widgetPreferences.rowOpacity))
remoteViews.setInt(
R.id.empty_view,
"setBackgroundColor",
ColorUtils.setAlphaComponent(bgColor, widgetPreferences.footerOpacity))
val filter = runBlocking { defaultFilterProvider.getFilterFromPreference(filterId) }
remoteViews.setTextViewText(R.id.widget_title, filter.listingTitle)
val cacheBuster = Uri.parse("tasks://widget/" + System.currentTimeMillis())
remoteViews.setRemoteAdapter(
R.id.list_view,
Intent(context, ScrollableWidgetUpdateService::class.java)
.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id)
.setData(cacheBuster))
setRipple(
remoteViews, color, R.id.widget_button, R.id.widget_change_list, R.id.widget_reconfigure)
remoteViews.setOnClickPendingIntent(R.id.widget_title, getOpenListIntent(context, filter, id))
remoteViews.setOnClickPendingIntent(R.id.widget_button, getNewTaskIntent(context, filter, id))
remoteViews.setOnClickPendingIntent(R.id.widget_change_list, getChooseListIntent(context, filter, id))
remoteViews.setOnClickPendingIntent(
R.id.widget_reconfigure, getWidgetConfigIntent(context, id))
if (widgetPreferences.openOnFooterClick()) {
remoteViews.setOnClickPendingIntent(R.id.empty_view, getOpenListIntent(context, filter, id))
} else {
remoteViews.setOnClickPendingIntent(R.id.empty_view, null)
}
remoteViews.setPendingIntentTemplate(R.id.list_view, getPendingIntentTemplate(context))
return remoteViews
}
private fun setRipple(rv: RemoteViews, color: ThemeColor, vararg views: Int) {
val drawableRes = if (color.isDark) R.drawable.widget_ripple_circle_light else R.drawable.widget_ripple_circle_dark
for (view in views) {
rv.setInt(view, "setBackgroundResource", drawableRes)
}
}
@ColorInt
private fun getBackgroundColor(themeIndex: Int): Int {
val background: Int = when (themeIndex) {
1 -> android.R.color.black
2 -> R.color.md_background_dark
else -> android.R.color.white
}
return context.getColor(background)
}
private fun getPendingIntentTemplate(context: Context): PendingIntent {
return PendingIntent.getActivity(
context, 0, Intent(context, WidgetClickActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT)
}
private fun getOpenListIntent(context: Context, filter: Filter, widgetId: Int): PendingIntent {
val intent = TaskIntents.getTaskListIntent(context, filter)
intent.flags = flags
intent.action = "open_list"
return PendingIntent.getActivity(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
private fun getNewTaskIntent(context: Context, filter: Filter, widgetId: Int): PendingIntent {
val intent = TaskIntents.getNewTaskIntent(context, filter)
intent.action = "new_task"
return PendingIntent.getActivity(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
private fun getWidgetConfigIntent(context: Context, widgetId: Int): PendingIntent {
val intent = Intent(context, WidgetConfigActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId)
intent.action = "widget_settings"
return PendingIntent.getActivity(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
private fun getChooseListIntent(context: Context, filter: Filter, widgetId: Int): PendingIntent {
val intent = Intent(context, FilterSelectionActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
intent.putExtra(FilterSelectionActivity.EXTRA_FILTER, filter)
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId)
intent.action = "choose_list"
return PendingIntent.getActivity(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
companion object {
private const val flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
}
}
Loading…
Cancel
Save