Add "Add widget to home screen" to list settings

pull/3207/head
Alex Baker 12 months ago
parent 1d74527bc4
commit f4863b813a

@ -323,6 +323,14 @@
android:resource="@xml/samsung_scrollable_flex_window_widget_meta_info"/> android:resource="@xml/samsung_scrollable_flex_window_widget_meta_info"/>
</receiver> </receiver>
<receiver
android:name=".widget.RequestPinWidgetReceiver"
android:exported="false">
<intent-filter>
<action android:name="org.tasks.CONFIGURE_WIDGET" />
</intent-filter>
</receiver>
<!-- ======================================================== Services = --> <!-- ======================================================== Services = -->
<service <service

@ -1,10 +1,14 @@
package org.tasks.activities package org.tasks.activities
import android.app.PendingIntent import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Paint import android.graphics.Paint
import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
@ -21,6 +25,7 @@ import androidx.lifecycle.lifecycleScope
import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp import com.mikepenz.iconics.utils.sizeDp
import com.todoroo.andlib.utility.AndroidUtilities
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.tasks.R import org.tasks.R
import org.tasks.analytics.Firebase import org.tasks.analytics.Firebase
@ -43,6 +48,10 @@ import org.tasks.themes.ColorProvider
import org.tasks.themes.Theme import org.tasks.themes.Theme
import org.tasks.themes.ThemeColor import org.tasks.themes.ThemeColor
import org.tasks.themes.contentColorFor import org.tasks.themes.contentColorFor
import org.tasks.widget.RequestPinWidgetReceiver
import org.tasks.widget.RequestPinWidgetReceiver.Companion.EXTRA_COLOR
import org.tasks.widget.RequestPinWidgetReceiver.Companion.EXTRA_FILTER
import org.tasks.widget.TasksWidget
import javax.inject.Inject import javax.inject.Inject
@ -164,6 +173,7 @@ abstract class BaseListSettingsActivity : AppCompatActivity(), ColorPalettePicke
clearColor = { clearColor() }, clearColor = { clearColor() },
pickIcon = { showIconPicker() }, pickIcon = { showIconPicker() },
addShortcutToHome = { createShortcut() }, addShortcutToHome = { createShortcut() },
addWidgetToHome = { createWidget() },
extensionContent = extensionContent, extensionContent = extensionContent,
) )
} }
@ -221,6 +231,28 @@ abstract class BaseListSettingsActivity : AppCompatActivity(), ColorPalettePicke
} }
} }
protected fun createWidget() {
val appWidgetManager = getSystemService(AppWidgetManager::class.java)
if (AndroidUtilities.atLeastOreo() && appWidgetManager.isRequestPinAppWidgetSupported) {
val provider = ComponentName(this, TasksWidget::class.java)
val configIntent = Intent(this, RequestPinWidgetReceiver::class.java).apply {
action = RequestPinWidgetReceiver.ACTION_CONFIGURE_WIDGET
filter?.let {
putExtra(EXTRA_FILTER, defaultFilterProvider.getFilterPreferenceValue(it))
}
putExtra(EXTRA_COLOR, baseViewModel.color)
}
val successCallback = PendingIntent.getBroadcast(
this,
0,
configIntent,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_MUTABLE else PendingIntent.FLAG_UPDATE_CURRENT
)
appWidgetManager.requestPinAppWidget(provider, null, successCallback)
firebase.logEvent(R.string.event_create_widget, R.string.param_type to "settings_activity")
}
}
companion object { companion object {
private const val FRAG_TAG_COLOR_PICKER = "frag_tag_color_picker" private const val FRAG_TAG_COLOR_PICKER = "frag_tag_color_picker"

@ -0,0 +1,69 @@
package org.tasks.compose.settings
import android.appwidget.AppWidgetManager
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Home
import androidx.compose.material.icons.outlined.Widgets
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.content.pm.ShortcutManagerCompat
import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.andlib.utility.AndroidUtilities.atLeastOreo
import org.tasks.R
import org.tasks.compose.Constants
import org.tasks.kmp.org.tasks.compose.settings.SettingRow
import org.tasks.themes.TasksTheme
@Composable
fun AddWidgetToHomeRow(onClick: () -> Unit) {
val context = LocalContext.current
val isRequestPinAppWidgetSupported = LocalInspectionMode.current || remember {
atLeastOreo() &&
context.getSystemService(AppWidgetManager::class.java).isRequestPinAppWidgetSupported
}
if (isRequestPinAppWidgetSupported) {
SettingRow(
modifier = Modifier.clickable(onClick = onClick),
left = {
Box(
modifier = Modifier.size(48.dp),
contentAlignment = Alignment.Center
) {
Icon(
imageVector = Icons.Outlined.Widgets,
contentDescription = null,
tint = colorResource(R.color.icon_tint_with_alpha),
)
}
},
center = {
Text(
text = stringResource(R.string.add_widget_to_home_screen),
modifier = Modifier.padding(start = Constants.KEYLINE_FIRST)
)
}
)
}
}
@Composable
@Preview(showBackground = true)
private fun AddToHomePreview() {
TasksTheme {
AddShortcutToHomeRow(onClick = {})
}
}

@ -20,6 +20,7 @@ fun ColumnScope.ListSettingsContent(
clearColor: () -> Unit, clearColor: () -> Unit,
pickIcon: () -> Unit, pickIcon: () -> Unit,
addShortcutToHome: () -> Unit, addShortcutToHome: () -> Unit,
addWidgetToHome: () -> Unit,
extensionContent: @Composable ColumnScope.() -> Unit, extensionContent: @Composable ColumnScope.() -> Unit,
) { ) {
TitleInput( TitleInput(
@ -43,6 +44,9 @@ fun ColumnScope.ListSettingsContent(
AddShortcutToHomeRow( AddShortcutToHomeRow(
onClick = { addShortcutToHome() }, onClick = { addShortcutToHome() },
) )
AddWidgetToHomeRow(
onClick = { addWidgetToHome() }
)
} }
extensionContent() extensionContent()
} }

@ -9,6 +9,7 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.tasks.caldav.BaseCaldavCalendarSettingsActivity import org.tasks.caldav.BaseCaldavCalendarSettingsActivity
import org.tasks.compose.settings.AddShortcutToHomeRow import org.tasks.compose.settings.AddShortcutToHomeRow
import org.tasks.compose.settings.AddWidgetToHomeRow
import org.tasks.compose.settings.ListSettingsScaffold import org.tasks.compose.settings.ListSettingsScaffold
import org.tasks.compose.settings.SelectIconRow import org.tasks.compose.settings.SelectIconRow
import org.tasks.compose.settings.Toaster import org.tasks.compose.settings.Toaster
@ -39,6 +40,7 @@ class OpenTasksListSettingsActivity : BaseCaldavCalendarSettingsActivity() {
) { ) {
SelectIconRow(icon = viewState.icon ?: defaultIcon) { showIconPicker() } SelectIconRow(icon = viewState.icon ?: defaultIcon) { showIconPicker() }
AddShortcutToHomeRow(onClick = { createShortcut() }) AddShortcutToHomeRow(onClick = { createShortcut() })
AddWidgetToHomeRow(onClick = { createWidget() })
} }
Toaster(state = snackbar) Toaster(state = snackbar)
} }

@ -0,0 +1,35 @@
package org.tasks.widget
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.preferences.Preferences
import timber.log.Timber
import javax.inject.Inject
@AndroidEntryPoint
class RequestPinWidgetReceiver : BroadcastReceiver() {
@Inject lateinit var preferences: Preferences
@Inject lateinit var appWidgetManager: AppWidgetManager
override fun onReceive(context: Context, intent: Intent) {
val widgetId = intent.getIntExtra(android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
if (widgetId == -1) {
Timber.e("Missing widgetId")
return
}
val filter = intent.getStringExtra(EXTRA_FILTER)
val color = intent.getIntExtra(EXTRA_COLOR, 0)
val widgetPreferences = WidgetPreferences(context, preferences, widgetId)
widgetPreferences.setFilter(filter)
widgetPreferences.setColor(color)
appWidgetManager.reconfigureWidgets()
}
companion object {
const val ACTION_CONFIGURE_WIDGET = "org.tasks.CONFIGURE_WIDGET"
const val EXTRA_FILTER = "extra_filter"
const val EXTRA_COLOR = "extra_color"
}
}

@ -425,6 +425,7 @@
<string name="event_complete_task">complete_task</string> <string name="event_complete_task">complete_task</string>
<string name="event_request_review">request_review</string> <string name="event_request_review">request_review</string>
<string name="event_create_shortcut">create_shortcut</string> <string name="event_create_shortcut">create_shortcut</string>
<string name="event_create_widget">create_widget</string>
<string name="param_type">type</string> <string name="param_type">type</string>
<string name="p_map_theme">map_theme</string> <string name="p_map_theme">map_theme</string>
<string name="p_picker_mode_date">picker_mode_date</string> <string name="p_picker_mode_date">picker_mode_date</string>

@ -735,4 +735,5 @@ File %1$s contained %2$s.\n\n
<string name="sort_descending">Descending</string> <string name="sort_descending">Descending</string>
<string name="sort_not_available">Not available for tags, filters, or places</string> <string name="sort_not_available">Not available for tags, filters, or places</string>
<string name="add_shortcut_to_home_screen">Add shortcut to home screen</string> <string name="add_shortcut_to_home_screen">Add shortcut to home screen</string>
<string name="add_widget_to_home_screen">Add widget to home screen</string>
</resources> </resources>

Loading…
Cancel
Save