parent
0d1b6fa33b
commit
f1b606d8e4
@ -10,7 +10,6 @@ import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
||||
@ -25,7 +24,7 @@ import de.mm20.launcher2.ui.ktx.toDp
|
||||
@Composable
|
||||
fun AppWidgetList(
|
||||
modifier: Modifier = Modifier,
|
||||
widgets: List<AppWidgetProviderInfo>,
|
||||
widgets: List<AppWidgetGroup>,
|
||||
onWidgetSelected: (AppWidgetProviderInfo) -> Unit = {}
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
@ -33,8 +32,20 @@ fun AppWidgetList(
|
||||
LazyColumn(
|
||||
modifier = modifier
|
||||
) {
|
||||
items(widgets) {
|
||||
key(it.provider.toShortString()) {
|
||||
for (group in widgets) {
|
||||
item() {
|
||||
Text(
|
||||
modifier = Modifier.padding(
|
||||
top = 16.dp,
|
||||
start = 8.dp,
|
||||
end = 8.dp,
|
||||
bottom = 8.dp
|
||||
),
|
||||
text = group.appName,
|
||||
style = MaterialTheme.typography.titleLarge
|
||||
)
|
||||
}
|
||||
items(group.widgets) {
|
||||
LauncherCard(
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
@ -81,10 +92,6 @@ fun AppWidgetList(
|
||||
modifier = mod
|
||||
) {
|
||||
drawIntoCanvas {
|
||||
val aspectRatio =
|
||||
image.intrinsicWidth / image.intrinsicHeight
|
||||
|
||||
|
||||
image.setBounds(
|
||||
0,
|
||||
0,
|
||||
@ -106,5 +113,6 @@ fun AppWidgetList(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -10,12 +10,16 @@ import androidx.activity.compose.setContent
|
||||
import androidx.activity.viewModels
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.ArrowBack
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import de.mm20.launcher2.ui.MdcLauncherTheme
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.base.BaseActivity
|
||||
import de.mm20.launcher2.ui.base.ProvideSettings
|
||||
|
||||
@ -27,6 +31,7 @@ class PickAppWidgetActivity : BaseActivity() {
|
||||
private lateinit var appWidgetManager: AppWidgetManager
|
||||
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
widgetHost = AppWidgetHost(this, 44203)
|
||||
@ -37,24 +42,44 @@ class PickAppWidgetActivity : BaseActivity() {
|
||||
setContent {
|
||||
MdcLauncherTheme {
|
||||
ProvideSettings {
|
||||
val available by availableWidgets.observeAsState()
|
||||
val selected by selectedAppWidget.observeAsState()
|
||||
val widgets = available
|
||||
if (selected == null) {
|
||||
if (widgets != null) {
|
||||
AppWidgetList(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
widgets = widgets,
|
||||
onWidgetSelected = {
|
||||
selectAppWidget(it)
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
title = {
|
||||
Text(stringResource(R.string.widget_add_widget))
|
||||
},
|
||||
navigationIcon = {
|
||||
IconButton(onClick = { finish() }) {
|
||||
Icon(
|
||||
imageVector = Icons.Rounded.ArrowBack,
|
||||
contentDescription = stringResource(
|
||||
id = R.string.menu_back
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
) {
|
||||
val available by availableWidgets.observeAsState()
|
||||
val selected by selectedAppWidget.observeAsState()
|
||||
val widgets = available
|
||||
if (selected == null) {
|
||||
if (widgets != null) {
|
||||
AppWidgetList(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
widgets = widgets,
|
||||
onWidgetSelected = {
|
||||
selectAppWidget(it)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,14 +3,24 @@ package de.mm20.launcher2.ui.launcher.widgets.picker
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetProviderInfo
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.compose.ui.text.toLowerCase
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.liveData
|
||||
import de.mm20.launcher2.crashreporter.CrashReporter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class PickAppWidgetVM: ViewModel() {
|
||||
typealias AppWidgetGroup = Pair<String, List<AppWidgetProviderInfo>>
|
||||
|
||||
inline val AppWidgetGroup.appName: String
|
||||
get() = this.first
|
||||
inline val AppWidgetGroup.widgets: List<AppWidgetProviderInfo>
|
||||
get() = this.second
|
||||
|
||||
class PickAppWidgetVM : ViewModel() {
|
||||
var appWidgetId: MutableLiveData<Int?> = MutableLiveData(null)
|
||||
val selectedAppWidget: MutableLiveData<AppWidgetProviderInfo?> = MutableLiveData(null)
|
||||
|
||||
@ -19,11 +29,24 @@ class PickAppWidgetVM: ViewModel() {
|
||||
this.selectedAppWidget.value = appWidget
|
||||
}
|
||||
|
||||
fun getAvailableWidgets(context: Context): LiveData<List<AppWidgetProviderInfo>?> = liveData {
|
||||
fun getAvailableWidgets(context: Context): LiveData<List<AppWidgetGroup>?> = liveData {
|
||||
emit(null)
|
||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
val widgets = withContext(Dispatchers.IO) {
|
||||
appWidgetManager.installedProviders.sortedBy { it.loadLabel(context.packageManager) }
|
||||
appWidgetManager.installedProviders
|
||||
.sortedBy { it.loadLabel(context.packageManager).lowercase() }
|
||||
.groupBy {
|
||||
val pkg = it.provider.packageName
|
||||
val appInfo = try {
|
||||
context.packageManager.getApplicationInfo(pkg, 0)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
CrashReporter.logException(e)
|
||||
return@groupBy ""
|
||||
}
|
||||
appInfo.loadLabel(context.packageManager).toString()
|
||||
}
|
||||
.toList()
|
||||
.sortedBy { it.first.lowercase() }
|
||||
}
|
||||
emit(widgets)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user