Use dependency injection for most singletons

This commit is contained in:
MM20
2021-10-10 12:15:54 +02:00
parent 023bb2cbb1
commit 087d4fd455
144 changed files with 1789 additions and 1277 deletions
@@ -29,6 +29,7 @@ import de.mm20.launcher2.favorites.FavoritesViewModel
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.theme.divider
import org.koin.androidx.compose.getViewModel
import kotlin.math.roundToInt
@OptIn(ExperimentalMaterialApi::class, ExperimentalAnimationApi::class)
@@ -39,7 +40,7 @@ fun DefaultSwipeActions(
enabled: Boolean = true,
content: @Composable RowScope.() -> Unit
) {
val viewModel: FavoritesViewModel = viewModel()
val viewModel: FavoritesViewModel = getViewModel()
val isPinned by viewModel.isPinned(item).observeAsState()
val isHidden by viewModel.isHidden(item).observeAsState()
@@ -19,16 +19,15 @@ import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.PagerState
import de.mm20.launcher2.search.SearchViewModel
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.locals.LocalNavController
import de.mm20.launcher2.ui.locals.LocalWindowSize
import org.koin.androidx.compose.getViewModel
/**
* Search bar
@@ -47,7 +46,7 @@ fun SearchBar(
) {
var searchQuery by remember { mutableStateOf("") }
val viewModel: SearchViewModel = viewModel()
val viewModel: SearchViewModel = getViewModel()
LaunchedEffect(searchQuery) {
viewModel.search(searchQuery)
@@ -16,6 +16,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.favorites.FavoritesViewModel
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.ui.R
import org.koin.androidx.compose.getViewModel
import kotlin.math.min
@Composable
@@ -162,7 +163,7 @@ data class ToggleToolbarAction(
@Composable
fun favoritesToolbarAction(item: Searchable): ToggleToolbarAction {
val viewModel = viewModel<FavoritesViewModel>()
val viewModel: FavoritesViewModel = getViewModel()
val isPinned by viewModel.isPinned(item).observeAsState(false)
return ToggleToolbarAction(
@@ -183,7 +184,7 @@ fun favoritesToolbarAction(item: Searchable): ToggleToolbarAction {
@Composable
fun hideToolbarAction(item: Searchable): ToggleToolbarAction {
val viewModel = viewModel<FavoritesViewModel>()
val viewModel: FavoritesViewModel = getViewModel()
val isHidden by viewModel.isHidden(item).observeAsState(false)
return ToggleToolbarAction(
@@ -27,6 +27,7 @@ import de.mm20.launcher2.ui.locals.LocalWindowSize
import de.mm20.launcher2.ui.widget.WidgetCard
import de.mm20.launcher2.widgets.Widget
import de.mm20.launcher2.widgets.WidgetViewModel
import org.koin.androidx.compose.getViewModel
@OptIn(ExperimentalAnimationApi::class, ExperimentalComposeUiApi::class, ExperimentalAnimationGraphicsApi::class
)
@@ -39,7 +40,7 @@ fun WidgetColumn(
var widgets by remember { mutableStateOf(listOf<Widget>()) }
val viewModel: WidgetViewModel = viewModel()
val viewModel: WidgetViewModel = getViewModel()
var editMode by remember { mutableStateOf(false) }
@@ -68,6 +68,8 @@ import de.mm20.launcher2.widgets.WidgetType
import de.mm20.launcher2.widgets.WidgetViewModel
import kotlinx.android.synthetic.main.activity_launcher.*
import kotlinx.coroutines.*
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.viewModel
import java.util.*
import kotlin.math.roundToInt
@@ -84,8 +86,9 @@ class LauncherActivity : AppCompatActivity() {
private lateinit var overlayView: ViewGroupOverlay
private lateinit var searchViewModel: SearchViewModel
private lateinit var widgetViewModel: WidgetViewModel
private val searchViewModel: SearchViewModel by viewModel()
private val widgetViewModel: WidgetViewModel by viewModel()
private val favoritesViewModel: FavoritesViewModel by viewModel()
private val preferences = LauncherPreferences.instance
@@ -205,8 +208,6 @@ class LauncherActivity : AppCompatActivity() {
overlayView = rootView.overlay
searchViewModel = ViewModelProvider(this)[SearchViewModel::class.java]
widgetViewModel = ViewModelProvider(this)[WidgetViewModel::class.java]
scrollContainer.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
@@ -302,8 +303,7 @@ class LauncherActivity : AppCompatActivity() {
}
hiddenItemsGrid.columnCount =
resources.getInteger(R.integer.config_columnCount)
val hiddenItems =
ViewModelProvider(this)[FavoritesViewModel::class.java].hiddenItems
val hiddenItems = favoritesViewModel.hiddenItems
hiddenItems.observe(this) {
hiddenItemsGrid.submitItems(it)
}
@@ -359,7 +359,9 @@ class LauncherActivity : AppCompatActivity() {
}
}
lifecycle.addObserver(DynamicIconController.getInstance(this))
val dynamicIconController: DynamicIconController by inject()
lifecycle.addObserver(dynamicIconController)
lifecycleScope.launch {
widgets.addAll(widgetViewModel.getWidgets())
@@ -399,10 +401,9 @@ class LauncherActivity : AppCompatActivity() {
}
private fun addWidget() {
val viewModel = ViewModelProvider(this)[WidgetViewModel::class.java]
val usedWidgets = widgets.filter { it.type == WidgetType.INTERNAL }.map { it.data }
val internalWidgets =
viewModel.getInternalWidgets().filter { !usedWidgets.contains(it.data) }
widgetViewModel.getInternalWidgets().filter { !usedWidgets.contains(it.data) }
if (internalWidgets.isNotEmpty()) {
MaterialDialog(this).show {
val widgetList =
@@ -652,11 +653,11 @@ class LauncherActivity : AppCompatActivity() {
ViewModelProvider(this).get(WeatherViewModel::class.java).requestUpdate(this)
}
PermissionsManager.CALENDAR -> {
ViewModelProvider(this)[WidgetViewModel::class.java].requestCalendarUpdate()
widgetViewModel.requestCalendarUpdate()
}
PermissionsManager.ALL -> {
ViewModelProvider(this).get(WeatherViewModel::class.java).requestUpdate(this)
ViewModelProvider(this)[WidgetViewModel::class.java].requestCalendarUpdate()
widgetViewModel.requestCalendarUpdate()
search(searchBar.getSearchQuery())
}
}
@@ -11,6 +11,7 @@ import de.mm20.launcher2.applications.AppViewModel
import de.mm20.launcher2.search.data.Application
import de.mm20.launcher2.ui.R
import kotlinx.android.synthetic.main.view_application.view.*
import org.koin.androidx.viewmodel.ext.android.viewModel
class ApplicationView : FrameLayout {
@@ -25,7 +26,8 @@ class ApplicationView : FrameLayout {
layoutTransition = LayoutTransition()
layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
applicationCard.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
applications = ViewModelProvider(context as AppCompatActivity).get(AppViewModel::class.java).applications
val viewModel: AppViewModel by (context as AppCompatActivity).viewModel()
applications = viewModel.applications
applications.observe(context as AppCompatActivity, Observer<List<Application>> {
visibility = if (it.isEmpty()) View.GONE else View.VISIBLE
applicationGrid.submitItems(it)
@@ -12,6 +12,7 @@ import de.mm20.launcher2.ui.R
import de.mm20.launcher2.calculator.CalculatorViewModel
import de.mm20.launcher2.search.data.Calculator
import kotlinx.android.synthetic.main.view_calculator.view.*
import org.koin.androidx.viewmodel.ext.android.viewModel
import kotlin.math.round
class CalculatorView : FrameLayout {
@@ -24,7 +25,8 @@ class CalculatorView : FrameLayout {
init {
View.inflate(context, R.layout.view_calculator, this)
calculator = ViewModelProvider(context as AppCompatActivity).get(CalculatorViewModel::class.java).calculator
val viewModel: CalculatorViewModel by (context as AppCompatActivity).viewModel()
calculator = viewModel.calculator
calculator.observe(context as AppCompatActivity, Observer {
if (it == null) visibility = View.GONE
else {
@@ -16,6 +16,7 @@ import de.mm20.launcher2.preferences.LauncherPreferences
import de.mm20.launcher2.search.data.CalendarEvent
import de.mm20.launcher2.search.data.MissingPermission
import de.mm20.launcher2.ui.legacy.search.SearchListView
import org.koin.androidx.viewmodel.ext.android.viewModel
class CalendarView : FrameLayout {
@@ -32,7 +33,8 @@ class CalendarView : FrameLayout {
val card = findViewById<ViewGroup>(R.id.card)
card.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
val list = findViewById<SearchListView>(R.id.list)
calendarEvents = ViewModelProvider(context as AppCompatActivity).get(CalendarViewModel::class.java).calendarEvents
val viewModel: CalendarViewModel by (context as AppCompatActivity).viewModel()
calendarEvents = viewModel.calendarEvents
calendarEvents.observe(context as AppCompatActivity, {
if (it == null) {
visibility = View.GONE
@@ -16,6 +16,7 @@ import de.mm20.launcher2.search.data.Contact
import de.mm20.launcher2.search.data.MissingPermission
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.legacy.search.SearchListView
import org.koin.androidx.viewmodel.ext.android.viewModel
class ContactView : FrameLayout {
private val contacts: LiveData<List<Contact>?>
@@ -30,7 +31,8 @@ class ContactView : FrameLayout {
layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
val card = findViewById<ViewGroup>(R.id.card)
card.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
contacts = ViewModelProvider(context as AppCompatActivity).get(ContactViewModel::class.java).contacts
val viewModel: ContactViewModel by (context as AppCompatActivity).viewModel()
contacts = viewModel.contacts
val list = findViewById<SearchListView>(R.id.list)
contacts.observe(context as AppCompatActivity, {
if (it == null) {
@@ -12,15 +12,20 @@ import de.mm20.launcher2.ui.R
import kotlinx.android.synthetic.main.edit_favorites_row.view.*
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class EditFavoritesRow @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, val favoritesItem: FavoritesItem
) : LinearLayout(context, attrs, defStyleAttr) {
) : LinearLayout(context, attrs, defStyleAttr), KoinComponent {
val iconRepository: IconRepository by inject()
init {
View.inflate(context, R.layout.edit_favorites_row, this)
label.text = favoritesItem.searchable?.label
lifecycleScope.launch {
IconRepository.getInstance(context).getIcon(favoritesItem.searchable!!, (48*dp).toInt()).collect{
iconRepository.getIcon(favoritesItem.searchable!!, (48*dp).toInt()).collect{
icon.icon = it
}
}
@@ -21,10 +21,14 @@ import kotlinx.android.synthetic.main.dialog_edit_favorites.view.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.androidx.viewmodel.ext.android.viewModel
class EditFavoritesView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : FrameLayout(context, attrs) {
val viewModel : FavoritesViewModel by (context as AppCompatActivity).viewModel()
init {
View.inflate(context, R.layout.dialog_edit_favorites, this)
lifecycleScope.launch {
@@ -35,7 +39,6 @@ class EditFavoritesView @JvmOverloads constructor(
private lateinit var favorites: MutableList<FavoritesItem>
suspend fun initView() {
val viewModel = ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java]
favorites = withContext(Dispatchers.IO) {
viewModel.getAllFavoriteItems().toMutableList()
}
@@ -117,7 +120,6 @@ class EditFavoritesView @JvmOverloads constructor(
}
fun save() {
val viewModel = ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java]
viewModel.saveFavorites(favorites)
}
@@ -11,6 +11,7 @@ import de.mm20.launcher2.favorites.FavoritesViewModel
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.ui.R
import kotlinx.android.synthetic.main.view_favorites.view.*
import org.koin.androidx.viewmodel.ext.android.viewModel
class FavoritesView : FrameLayout {
@@ -23,7 +24,7 @@ class FavoritesView : FrameLayout {
init {
View.inflate(context, R.layout.view_favorites, this)
val viewModel = ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java]
val viewModel: FavoritesViewModel by (context as AppCompatActivity).viewModel()
favorites = viewModel.getFavorites(context.resources.getInteger(R.integer.config_columnCount))
favorites.observe(context as AppCompatActivity, Observer {
visibility = if (it?.isEmpty() == true) View.GONE else View.VISIBLE
@@ -15,6 +15,7 @@ import de.mm20.launcher2.search.data.File
import de.mm20.launcher2.search.data.MissingPermission
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.legacy.search.SearchListView
import org.koin.androidx.viewmodel.ext.android.viewModel
class FileView : FrameLayout {
private val files: LiveData<List<File>?>
@@ -30,7 +31,8 @@ class FileView : FrameLayout {
val card = findViewById<ViewGroup>(R.id.card)
card.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
val list = findViewById<SearchListView>(R.id.list)
files = ViewModelProvider(context as AppCompatActivity).get(FilesViewModel::class.java).files
val viewModel: FilesViewModel by (context as AppCompatActivity).viewModel()
files = viewModel.files
files.observe(context as AppCompatActivity, {
if (it == null) {
visibility = View.GONE
@@ -26,6 +26,7 @@ import de.mm20.launcher2.transition.ChangingLayoutTransition
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.legacy.view.LauncherCardView
import kotlinx.android.synthetic.main.view_search_bar.view.*
import org.koin.androidx.viewmodel.ext.android.viewModel
class SearchBar @JvmOverloads constructor(
context: Context,
@@ -70,7 +71,9 @@ class SearchBar @JvmOverloads constructor(
})
ViewModelProvider(context as AppCompatActivity)[SearchViewModel::class.java].isSearching.observe(context, Observer {
val viewModel = (context as AppCompatActivity).viewModel<SearchViewModel>().value
viewModel.isSearching.observe(context, Observer {
searchProgressBar.visibility = if (it) View.VISIBLE else View.GONE
})
@@ -15,6 +15,7 @@ import androidx.browser.customtabs.CustomTabsIntent
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.afollestad.materialdialogs.MaterialDialog
@@ -31,6 +32,7 @@ import de.mm20.launcher2.ui.R
import de.mm20.launcher2.unitconverter.UnitConverterViewModel
import de.mm20.launcher2.unitconverter.UnitValue
import kotlinx.android.synthetic.main.view_unitconverter.view.*
import org.koin.androidx.viewmodel.ext.android.viewModel
import java.text.DateFormat
import java.util.*
import kotlin.math.min
@@ -46,7 +48,8 @@ class UnitConverterView : FrameLayout {
init {
View.inflate(context, R.layout.view_unitconverter, this)
unitConverter = ViewModelProvider(context as AppCompatActivity).get(UnitConverterViewModel::class.java).unitConverter
val unitConverterViewModel by (context as AppCompatActivity).viewModel<UnitConverterViewModel>()
unitConverter = unitConverterViewModel.unitConverter
unitConverter.observe(context as AppCompatActivity, Observer {
if (it == null) visibility = View.GONE
else {
@@ -21,6 +21,7 @@ import de.mm20.launcher2.search.WebsearchViewModel
import de.mm20.launcher2.search.data.Websearch
import de.mm20.launcher2.ui.R
import kotlinx.android.synthetic.main.view_websearch.view.*
import org.koin.androidx.viewmodel.ext.android.viewModel
class WebSearchView : FrameLayout {
constructor(context: Context) : super(context)
@@ -31,7 +32,7 @@ class WebSearchView : FrameLayout {
init {
View.inflate(context, R.layout.view_websearch, this)
val viewModel = ViewModelProvider(context as AppCompatActivity)[WebsearchViewModel::class.java]
val viewModel: WebsearchViewModel by (context as AppCompatActivity).viewModel()
websearches = viewModel.websearches
websearches.observe(context as AppCompatActivity, Observer {
updateWebsearches(it)
@@ -14,6 +14,7 @@ import de.mm20.launcher2.search.data.Website
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.legacy.searchable.SearchableView
import de.mm20.launcher2.websites.WebsiteViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
class WebsiteView : FrameLayout {
@@ -30,7 +31,8 @@ class WebsiteView : FrameLayout {
val card = findViewById<ViewGroup>(R.id.card)
websiteView.layoutParams = params
card.addView(websiteView)
website = ViewModelProvider(context as AppCompatActivity)[WebsiteViewModel::class.java].website
val viewModel: WebsiteViewModel by (context as AppCompatActivity).viewModel()
website = viewModel.website
website.observe(context as AppCompatActivity, Observer {
visibility = if (it == null) View.GONE else View.VISIBLE
card.setOnClickListener { _ ->
@@ -14,6 +14,7 @@ import de.mm20.launcher2.search.data.Wikipedia
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.legacy.searchable.SearchableView
import de.mm20.launcher2.wikipedia.WikipediaViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
class WikipediaView : FrameLayout {
@@ -30,7 +31,8 @@ class WikipediaView : FrameLayout {
val card = findViewById<ViewGroup>(R.id.card)
websiteView.layoutParams = params
card.addView(websiteView)
wikipedia = ViewModelProvider(context as AppCompatActivity)[WikipediaViewModel::class.java].wikipedia
val viewModel: WikipediaViewModel by (context as AppCompatActivity).viewModel()
wikipedia = viewModel.wikipedia
wikipedia.observe(context as AppCompatActivity, Observer {
visibility = if (it == null) View.GONE else View.VISIBLE
card.setOnClickListener { _ ->
@@ -18,9 +18,13 @@ import de.mm20.launcher2.preferences.AppStartAnimation
import de.mm20.launcher2.preferences.LauncherPreferences
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.ui.R
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.lang.ref.WeakReference
object ActivityStarter {
object ActivityStarter: KoinComponent {
val favoritesRepository: FavoritesRepository by inject()
private var initialized = false
private lateinit var overlayView: WeakReference<ViewGroupOverlay>
@@ -141,7 +145,7 @@ object ActivityStarter {
if (item != null) {
if (item.launch(context, bundle)) {
FavoritesRepository.getInstance(context).incrementLaunchCount(item)
favoritesRepository.incrementLaunchCount(item)
return true
}
return false
@@ -27,6 +27,7 @@ import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.core.content.getSystemService
import androidx.core.graphics.alpha
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.transition.Scene
@@ -52,10 +53,16 @@ import de.mm20.launcher2.ui.legacy.searchable.SearchableView
import de.mm20.launcher2.ui.legacy.view.*
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.util.concurrent.Executors
import kotlin.math.roundToInt
class ApplicationDetailRepresentation : Representation {
class ApplicationDetailRepresentation : Representation, KoinComponent {
private val iconRepository: IconRepository by inject()
private val badgeProvider: BadgeProvider by inject()
override fun getScene(
rootView: SearchableView,
@@ -71,12 +78,11 @@ class ApplicationDetailRepresentation : Representation {
setOnLongClickListener(null)
findViewById<TextView>(R.id.appName).text = application.label
findViewById<LauncherIconView>(R.id.icon).apply {
badge = BadgeProvider.getInstance(context).getLiveBadge(application.badgeKey)
badge = badgeProvider.getLiveBadge(application.badgeKey)
shape = LauncherIconView.getDefaultShape(context)
icon = IconRepository.getInstance(context).getIconIfCached(application)
icon = iconRepository.getIconIfCached(application)
lifecycleScope.launch {
IconRepository.getInstance(context)
.getIcon(application, (84 * rootView.dp).toInt()).collect {
iconRepository.getIcon(application, (84 * rootView.dp).toInt()).collect {
icon = it
}
}
@@ -264,8 +270,7 @@ class ApplicationDetailRepresentation : Representation {
if (launcherApps.hasShortcutHostPermission()) {
val shortcuts = app.shortcuts
val viewModel =
ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java]
val viewModel : FavoritesViewModel by (context as AppCompatActivity).viewModel()
for (si in shortcuts) {
val view = Chip(context)
@@ -292,7 +297,7 @@ class ApplicationDetailRepresentation : Representation {
)
val isPinned = viewModel.isPinned(si)
isPinned.observe(context, Observer {
isPinned.observe(context as LifecycleOwner, Observer {
view.isCloseIconVisible = isPinned.value == true
})
@@ -3,20 +3,30 @@ package de.mm20.launcher2.ui.legacy.search
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.transition.Scene
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.badges.BadgeProvider
import de.mm20.launcher2.ktx.dp
import de.mm20.launcher2.icons.IconRepository
import de.mm20.launcher2.ktx.dp
import de.mm20.launcher2.ktx.lifecycleScope
import de.mm20.launcher2.legacy.helper.ActivityStarter
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.legacy.searchable.SearchableView
import de.mm20.launcher2.ui.legacy.view.LauncherIconView
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class BasicGridRepresentation : Representation {
override fun getScene(rootView: SearchableView, searchable: Searchable, previousRepresentation: Int?): Scene {
class BasicGridRepresentation : Representation, KoinComponent {
private val iconRepository: IconRepository by inject()
private val badgeProvider: BadgeProvider by inject()
override fun getScene(
rootView: SearchableView,
searchable: Searchable,
previousRepresentation: Int?
): Scene {
val context = rootView.context as AppCompatActivity
val scene = Scene.getSceneForLayout(rootView, R.layout.view_basic_grid, rootView.context)
scene.setEnterAction {
@@ -30,16 +40,21 @@ class BasicGridRepresentation : Representation {
.alpha(1f)
.start()*/
findViewById<LauncherIconView>(R.id.icon).apply {
badge = BadgeProvider.getInstance(context).getLiveBadge(searchable.badgeKey)
badge = badgeProvider.getLiveBadge(searchable.badgeKey)
shape = LauncherIconView.getDefaultShape(context)
setOnClickListener {
if (!ActivityStarter.start(context, rootView.findViewById(R.id.card), item = searchable)) {
if (!ActivityStarter.start(
context,
rootView.findViewById(R.id.card),
item = searchable
)
) {
rootView.representation = SearchableView.REPRESENTATION_FULL
}
}
icon = IconRepository.getInstance(context).getIconIfCached(searchable)
icon = iconRepository.getIconIfCached(searchable)
lifecycleScope.launch {
IconRepository.getInstance(context).getIcon(searchable, (84 * rootView.dp).toInt()).collect {
iconRepository.getIcon(searchable, (84 * rootView.dp).toInt()).collect {
icon = it
}
}
@@ -27,9 +27,15 @@ import de.mm20.launcher2.ui.legacy.searchable.SearchableView
import de.mm20.launcher2.ui.legacy.view.*
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.net.URLEncoder
class ContactDetailRepresentation : Representation {
class ContactDetailRepresentation : Representation, KoinComponent {
val iconRepository: IconRepository by inject()
val badgeProvider: BadgeProvider by inject()
override fun getScene(
rootView: SearchableView,
searchable: Searchable,
@@ -42,12 +48,11 @@ class ContactDetailRepresentation : Representation {
scene.setEnterAction {
with(rootView) {
findViewById<LauncherIconView>(R.id.icon).apply {
badge = BadgeProvider.getInstance(context).getLiveBadge(contact.badgeKey)
badge = badgeProvider.getLiveBadge(contact.badgeKey)
shape = LauncherIconView.getDefaultShape(context)
icon = IconRepository.getInstance(context).getIconIfCached(contact)
icon = iconRepository.getIconIfCached(contact)
lifecycleScope.launch {
IconRepository.getInstance(context)
.getIcon(contact, (84 * rootView.dp).toInt()).collect {
iconRepository.getIcon(contact, (84 * rootView.dp).toInt()).collect {
icon = it
}
}
@@ -17,8 +17,14 @@ import de.mm20.launcher2.ui.legacy.view.LauncherIconView
import de.mm20.launcher2.ui.legacy.view.SwipeCardView
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class ContactListRepresentation : Representation, KoinComponent {
val iconRepository: IconRepository by inject()
val badgeProvider: BadgeProvider by inject()
class ContactListRepresentation : Representation {
override fun getScene(rootView: SearchableView, searchable: Searchable, previousRepresentation: Int?): Scene {
val contact = searchable as Contact
val context = rootView.context as AppCompatActivity
@@ -26,11 +32,11 @@ class ContactListRepresentation : Representation {
scene.setEnterAction {
with(rootView) {
findViewById<LauncherIconView>(R.id.icon).apply {
badge = BadgeProvider.getInstance(context).getLiveBadge(contact.badgeKey)
badge = badgeProvider.getLiveBadge(contact.badgeKey)
shape = LauncherIconView.getDefaultShape(context)
icon = IconRepository.getInstance(context).getIconIfCached(contact)
icon = iconRepository.getIconIfCached(contact)
lifecycleScope.launch {
IconRepository.getInstance(context).getIcon(contact, (84 * rootView.dp).toInt()).collect {
iconRepository.getIcon(contact, (84 * rootView.dp).toInt()).collect {
icon = it
}
}
@@ -22,9 +22,16 @@ import de.mm20.launcher2.ui.legacy.searchable.SearchableView
import de.mm20.launcher2.ui.legacy.view.*
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.text.DecimalFormat
class FileDetailRepresentation : Representation {
class FileDetailRepresentation : Representation, KoinComponent {
val iconRepository: IconRepository by inject()
val badgeProvider: BadgeProvider by inject()
override fun getScene(rootView: SearchableView, searchable: Searchable, previousRepresentation: Int?): Scene {
val file = searchable as File
val context = rootView.context as AppCompatActivity
@@ -34,11 +41,11 @@ class FileDetailRepresentation : Representation {
findViewById<TextView>(R.id.fileLabel).text = file.label
findViewById<TextView>(R.id.fileInfo).text = getInfo(context, file)
findViewById<LauncherIconView>(R.id.icon).apply {
badge = BadgeProvider.getInstance(context).getLiveBadge(file.badgeKey)
badge = badgeProvider.getLiveBadge(file.badgeKey)
shape = LauncherIconView.getDefaultShape(context)
icon = IconRepository.getInstance(context).getIconIfCached(file)
icon = iconRepository.getIconIfCached(file)
lifecycleScope.launch {
IconRepository.getInstance(context).getIcon(file, (84 * rootView.dp).toInt()).collect {
iconRepository.getIcon(file, (84 * rootView.dp).toInt()).collect {
icon = it
}
}
@@ -100,7 +107,7 @@ class FileDetailRepresentation : Representation {
"${MediaStore.Files.FileColumns._ID} = ?",
arrayOf(file.id.toString()))
it.dismiss()
val fileViewModel = ViewModelProvider(context as AppCompatActivity)[FilesViewModel::class.java]
val fileViewModel: FilesViewModel by (context as AppCompatActivity).viewModel()
fileViewModel.removeFile(file)
}
negativeButton(android.R.string.no) {
@@ -19,8 +19,14 @@ import de.mm20.launcher2.ui.legacy.view.LauncherIconView
import de.mm20.launcher2.ui.legacy.view.SwipeCardView
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class FileListRepresentation : Representation, KoinComponent {
val iconRepository: IconRepository by inject()
val badgeProvider: BadgeProvider by inject()
class FileListRepresentation : Representation {
override fun getScene(rootView: SearchableView, searchable: Searchable, previousRepresentation: Int?): Scene {
val file = searchable as File
val context = rootView.context as AppCompatActivity
@@ -30,11 +36,11 @@ class FileListRepresentation : Representation {
findViewById<TextView>(R.id.fileLabel).text = file.label
findViewById<TextView>(R.id.fileInfo).text = getFileType(context, file)
findViewById<LauncherIconView>(R.id.icon).apply {
badge = BadgeProvider.getInstance(context).getLiveBadge(file.badgeKey)
badge = badgeProvider.getLiveBadge(file.badgeKey)
shape = LauncherIconView.getDefaultShape(context)
icon = IconRepository.getInstance(context).getIconIfCached(file)
icon = iconRepository.getIconIfCached(file)
lifecycleScope.launch {
IconRepository.getInstance(context).getIcon(file, (84 * rootView.dp).toInt()).collect {
iconRepository.getIcon(file, (84 * rootView.dp).toInt()).collect {
icon = it
}
}
@@ -19,9 +19,15 @@ import de.mm20.launcher2.ui.legacy.view.ToolbarAction
import de.mm20.launcher2.ui.legacy.view.ToolbarView
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@RequiresApi(Build.VERSION_CODES.N_MR1)
class AppShortcutDetailRepresentation: Representation {
class AppShortcutDetailRepresentation: Representation, KoinComponent {
val iconRepository: IconRepository by inject()
val badgeProvider: BadgeProvider by inject()
override fun getScene(rootView: SearchableView, searchable: Searchable, previousRepresentation: Int?): Scene {
val appShortcut = searchable as AppShortcut
val context = rootView.context as AppCompatActivity
@@ -32,11 +38,11 @@ class AppShortcutDetailRepresentation: Representation {
setOnLongClickListener(null)
findViewById<TextView>(R.id.appName).text = appShortcut.label
findViewById<LauncherIconView>(R.id.icon).apply {
badge = BadgeProvider.getInstance(context).getLiveBadge(appShortcut.badgeKey)
badge = badgeProvider.getLiveBadge(appShortcut.badgeKey)
shape = LauncherIconView.getDefaultShape(context)
icon = IconRepository.getInstance(context).getIconIfCached(appShortcut)
icon = iconRepository.getIconIfCached(appShortcut)
lifecycleScope.launch {
IconRepository.getInstance(context).getIcon(appShortcut, (84 * rootView.dp).toInt()).collect {
iconRepository.getIcon(appShortcut, (84 * rootView.dp).toInt()).collect {
icon = it
}
}
@@ -24,8 +24,14 @@ import de.mm20.launcher2.ui.legacy.view.ToolbarAction
import de.mm20.launcher2.ui.legacy.view.ToolbarView
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class WebsiteDetailRepresentation : Representation, KoinComponent {
val iconRepository: IconRepository by inject()
val badgeProvider: BadgeProvider by inject()
class WebsiteDetailRepresentation : Representation {
override fun getScene(rootView: SearchableView, searchable: Searchable, previousRepresentation: Int?): Scene {
val website = searchable as Website
val context = rootView.context as AppCompatActivity
@@ -60,11 +66,11 @@ class WebsiteDetailRepresentation : Representation {
label.transitionName = null
websiteFavIcon.transitionName = "icon"
websiteFavIcon.apply {
badge = BadgeProvider.getInstance(context).getLiveBadge(website.badgeKey)
badge = badgeProvider.getLiveBadge(website.badgeKey)
shape = LauncherIconView.getDefaultShape(context)
icon = IconRepository.getInstance(context).getIconIfCached(website)
icon = iconRepository.getIconIfCached(website)
lifecycleScope.launch {
IconRepository.getInstance(context).getIcon(website, (84 * rootView.dp).toInt()).collect {
iconRepository.getIcon(website, (84 * rootView.dp).toInt()).collect {
icon = it
}
}
@@ -10,8 +10,8 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.transition.Scene
import com.bumptech.glide.Glide
import de.mm20.launcher2.badges.BadgeProvider
import de.mm20.launcher2.ktx.dp
import de.mm20.launcher2.icons.IconRepository
import de.mm20.launcher2.ktx.dp
import de.mm20.launcher2.ktx.lifecycleScope
import de.mm20.launcher2.legacy.helper.ActivityStarter
import de.mm20.launcher2.search.data.Searchable
@@ -24,9 +24,20 @@ import de.mm20.launcher2.ui.legacy.view.ToolbarAction
import de.mm20.launcher2.ui.legacy.view.ToolbarView
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class WebsiteListRepresentation : Representation {
override fun getScene(rootView: SearchableView, searchable: Searchable, previousRepresentation: Int?): Scene {
class WebsiteListRepresentation : Representation, KoinComponent {
val iconRepository: IconRepository by inject()
val badgeProvider: BadgeProvider by inject()
override fun getScene(
rootView: SearchableView,
searchable: Searchable,
previousRepresentation: Int?
): Scene {
val website = searchable as Website
val context = rootView.context as AppCompatActivity
val scene = Scene.getSceneForLayout(rootView, R.layout.view_website_list, rootView.context)
@@ -60,11 +71,11 @@ class WebsiteListRepresentation : Representation {
label.transitionName = null
websiteFavIcon.transitionName = "icon"
websiteFavIcon.apply {
badge = BadgeProvider.getInstance(context).getLiveBadge(website.badgeKey)
badge = badgeProvider.getLiveBadge(website.badgeKey)
shape = LauncherIconView.getDefaultShape(context)
icon = IconRepository.getInstance(context).getIconIfCached(website)
icon = iconRepository.getIconIfCached(website)
lifecycleScope.launch {
IconRepository.getInstance(context).getIcon(website, (84 * rootView.dp).toInt()).collect {
iconRepository.getIcon(website, (84 * rootView.dp).toInt()).collect {
icon = it
}
}
@@ -101,7 +112,10 @@ class WebsiteListRepresentation : Representation {
private fun share(context: Context, website: Website) {
val shareIntent = Intent(Intent.ACTION_SEND)
shareIntent.putExtra(Intent.EXTRA_TEXT, "${website.label}\n\n${website.description}\n\n${website.url}")
shareIntent.putExtra(
Intent.EXTRA_TEXT,
"${website.label}\n\n${website.description}\n\n${website.url}"
)
shareIntent.type = "text/plain"
context.startActivity(Intent.createChooser(shareIntent, null))
}
@@ -22,6 +22,7 @@ import de.mm20.launcher2.preferences.LauncherPreferences
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.transition.ChangingLayoutTransition
import de.mm20.launcher2.ui.R
import org.koin.androidx.viewmodel.ext.android.viewModel
import kotlin.math.abs
class SwipeCardView @JvmOverloads constructor(
@@ -376,10 +377,10 @@ class FavoriteSwipeAction(val context: Context, val searchable: Searchable) :
ContextCompat.getColor(context, R.color.amber),
{ false }
) {
val pinned =
ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java].isPinned(
searchable
)
val viewModel: FavoritesViewModel by (context as AppCompatActivity).viewModel()
private val pinned = viewModel.isPinned(searchable)
init {
pinned.observe(context as LifecycleOwner) {
@@ -391,7 +392,7 @@ class FavoriteSwipeAction(val context: Context, val searchable: Searchable) :
if (pinned) {
icon = R.drawable.ic_star_outline
action = {
ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java].unpinItem(
viewModel.unpinItem(
searchable
)
false
@@ -399,7 +400,7 @@ class FavoriteSwipeAction(val context: Context, val searchable: Searchable) :
} else {
icon = R.drawable.ic_star_solid
action = {
ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java].pinItem(
viewModel.pinItem(
searchable
)
false
@@ -413,10 +414,8 @@ class HideSwipeAction(val context: Context, val searchable: Searchable) : SwipeC
ContextCompat.getColor(context, R.color.blue),
{ false }
) {
val hidden =
ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java].isHidden(
searchable
)
val viewModel: FavoritesViewModel by (context as AppCompatActivity).viewModel()
private val hidden = viewModel.isHidden(searchable)
init {
hidden.observe(context as LifecycleOwner) {
@@ -428,7 +427,7 @@ class HideSwipeAction(val context: Context, val searchable: Searchable) : SwipeC
if (hidden) {
icon = R.drawable.ic_visibility
action = {
ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java].unhideItem(
viewModel.unhideItem(
searchable
)
true
@@ -436,7 +435,7 @@ class HideSwipeAction(val context: Context, val searchable: Searchable) : SwipeC
} else {
icon = R.drawable.ic_visibility_off
action = {
ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java].hideItem(
viewModel.hideItem(
searchable
)
true
@@ -11,16 +11,20 @@ import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.TooltipCompat
import androidx.core.view.setPadding
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.favorites.FavoritesViewModel
import de.mm20.launcher2.ktx.dp
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.ui.R
import org.koin.androidx.viewmodel.ext.android.viewModel
class ToolbarView : LinearLayout {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleRes: Int) : super(context, attrs, defStyleRes)
constructor(context: Context, attrs: AttributeSet?, defStyleRes: Int) : super(
context,
attrs,
defStyleRes
)
private val slots = context.resources.getInteger(R.integer.config_toolbarSlots)
@@ -53,7 +57,8 @@ class ToolbarView : LinearLayout {
overflowMenuIcon.isClickable = true
overflowMenuIcon.isFocusable = true
overflowMenuIcon.setPadding((12 * dp).toInt())
overflowMenuIcon.layoutParams = LayoutParams((48 * dp).toInt(), (48 * dp).toInt())
overflowMenuIcon.layoutParams =
LayoutParams((48 * dp).toInt(), (48 * dp).toInt())
overflowMenuIcon.setImageResource(R.drawable.ic_more_vert)
removeViewAt(leftActions.size - 1)
addView(overflowMenuIcon, leftActions.size - 1)
@@ -88,7 +93,8 @@ class ToolbarView : LinearLayout {
overflowMenuIcon.isClickable = true
overflowMenuIcon.isFocusable = true
overflowMenuIcon.setPadding((12 * dp).toInt())
overflowMenuIcon.layoutParams = LayoutParams((48 * dp).toInt(), (48 * dp).toInt())
overflowMenuIcon.layoutParams =
LayoutParams((48 * dp).toInt(), (48 * dp).toInt())
overflowMenuIcon.setImageResource(R.drawable.ic_more_vert)
removeViewAt(childCount - 1)
addView(overflowMenuIcon)
@@ -147,15 +153,16 @@ class ToolbarView : LinearLayout {
}
TooltipCompat.setTooltipText(imageView, action.title)
val submenu = if (action.subActions.isEmpty()) null else PopupMenu(context, imageView).apply {
for ((i, subAction) in action.subActions.withIndex()) {
menu.add(0, i, 0, subAction.title)
val submenu =
if (action.subActions.isEmpty()) null else PopupMenu(context, imageView).apply {
for ((i, subAction) in action.subActions.withIndex()) {
menu.add(0, i, 0, subAction.title)
}
setOnMenuItemClickListener {
action.subActions[it.itemId].clickAction.invoke()
true
}
}
setOnMenuItemClickListener {
action.subActions[it.itemId].clickAction.invoke()
true
}
}
imageView.setOnClickListener { _ ->
if (submenu != null) {
@@ -213,13 +220,12 @@ open class ToolbarSubaction(val title: String, var clickAction: (() -> Unit)) {
}
class FavoriteToolbarAction(val context: Context, val item: Searchable)
: ToolbarAction(
R.drawable.ic_star_outline,
context.getString(R.string.favorites_menu_pin)
class FavoriteToolbarAction(val context: Context, val item: Searchable) : ToolbarAction(
R.drawable.ic_star_outline,
context.getString(R.string.favorites_menu_pin)
) {
private val viewModel = ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java]
private val viewModel: FavoritesViewModel by (context as AppCompatActivity).viewModel()
private val isPinned = viewModel.isPinned(item)
init {
@@ -243,13 +249,12 @@ class FavoriteToolbarAction(val context: Context, val item: Searchable)
}
}
class VisibilityToolbarAction(val context: Context, val item: Searchable)
: ToolbarAction(
R.drawable.ic_visibility,
context.getString(R.string.menu_hide)
class VisibilityToolbarAction(val context: Context, val item: Searchable) : ToolbarAction(
R.drawable.ic_visibility,
context.getString(R.string.menu_hide)
) {
private val viewModel = ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java]
private val viewModel: FavoritesViewModel by (context as AppCompatActivity).viewModel()
private val isHidden = viewModel.isHidden(item)
init {
@@ -23,6 +23,7 @@ import de.mm20.launcher2.search.data.MissingPermission
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.ui.R
import kotlinx.android.synthetic.main.view_calendar_widget.view.*
import org.koin.androidx.viewmodel.ext.android.viewModel
import java.util.*
import kotlin.math.max
import kotlin.math.min
@@ -119,8 +120,8 @@ class CalendarWidget : LauncherWidget {
selectedDay = availableDays[i - 1]
}
val viewModel = ViewModelProvider(context as AppCompatActivity)[CalendarViewModel::class.java]
val favViewModel = ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java]
val viewModel: CalendarViewModel by (context as AppCompatActivity).viewModel()
val favViewModel: FavoritesViewModel by (context as AppCompatActivity).viewModel()
calendarEvents = viewModel.upcomingCalendarEvents
pinnedCalendarEvents = favViewModel.pinnedCalendarEvents
@@ -22,11 +22,13 @@ import de.mm20.launcher2.ktx.dp
import de.mm20.launcher2.legacy.helper.ActivityStarter
import de.mm20.launcher2.music.MusicViewModel
import de.mm20.launcher2.music.PlaybackState
import de.mm20.launcher2.search.SearchViewModel
import de.mm20.launcher2.ui.LegacyLauncherTheme
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.widget.MusicWidget
import de.mm20.launcher2.ui.widget.WeatherWidget
import kotlinx.android.synthetic.main.compact_music.view.*
import org.koin.androidx.viewmodel.ext.android.viewModel
class MusicWidget : LauncherWidget {
@@ -44,7 +46,7 @@ class MusicWidget : LauncherWidget {
override val name: String
get() = context.getString(R.string.widget_name_music)
private val viewModel = ViewModelProvider(context as AppCompatActivity)[MusicViewModel::class.java]
private val viewModel: MusicViewModel by (context as AppCompatActivity).viewModel()
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
@@ -79,7 +81,7 @@ class MusicWidget : LauncherWidget {
class MusicCompactView : FrameLayout, CompactView {
private val viewModel = ViewModelProvider(context as AppCompatActivity)[MusicViewModel::class.java]
private val viewModel: MusicViewModel by (context as AppCompatActivity).viewModel()
override fun setTranslucent(translucent: Boolean) {
if (translucent) {
@@ -217,63 +217,3 @@ class DateCompactView : TextClock, CompactView {
}
}
class RecommendedAppsCompactView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr), CompactView {
val viewModel = ViewModelProvider(context as AppCompatActivity)[FavoritesViewModel::class.java]
val items = viewModel.getTopFavorites(4)
init {
clipChildren = false
clipToPadding = false
layoutTransition = LayoutTransition()
items.observe(context as LifecycleOwner, Observer {
removeAllViews()
for (s in it) {
val searchableView = LauncherIconView(context)
searchableView.icon = s.getPlaceholderIcon(context)
lifecycleScope.launch {
IconRepository.getInstance(context).getIcon(s, (48 * dp).toInt()).collect {
searchableView.icon = it
}
}
val frameLayout = FrameLayout(context)
frameLayout.clipChildren = false
frameLayout.clipToPadding = false
searchableView.layoutParams = FrameLayout.LayoutParams(
(48 * dp).toInt(),
(48 * dp).toInt()
).also {
it.gravity = Gravity.CENTER
}
searchableView.badge = BadgeProvider.getInstance(context).getLiveBadge(s.badgeKey)
searchableView.elevation = 2 * dp
searchableView.setOnClickListener {
if(!ActivityStarter.start(context, searchableView, s)) {
searchableView.performLongClick()
}
}
searchableView.setOnLongClickListener {
SearchableBottomSheet(s).show((context as AppCompatActivity).supportFragmentManager, null)
return@setOnLongClickListener true
}
frameLayout.addView(searchableView)
frameLayout.layoutParams = LayoutParams(
0,
(48 * dp).toInt()
).also {
it.weight = 1f
}
addView(frameLayout)
}
})
}
override fun setTranslucent(translucent: Boolean) {
}
override var goToParent: (() -> Unit)? = null
}
@@ -7,10 +7,12 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.applications.AppViewModel
import org.koin.androidx.compose.getViewModel
@Composable
fun applicationResults(): LazyListScope.(listState: LazyListState) -> Unit {
val apps by viewModel<AppViewModel>().applications.observeAsState(emptyList())
val viewModel: AppViewModel = getViewModel()
val apps by viewModel.applications.observeAsState(emptyList())
return {
SearchableGrid(items = apps, listState = it)
}
@@ -16,10 +16,12 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.calculator.CalculatorViewModel
import de.mm20.launcher2.ui.component.SectionDivider
import org.koin.androidx.compose.getViewModel
@Composable
fun calculatorItem(): LazyListScope.() -> Unit {
val calculator by viewModel<CalculatorViewModel>().calculator.observeAsState()
val viewModel: CalculatorViewModel = getViewModel()
val calculator by viewModel.calculator.observeAsState()
return {
calculator?.let {
item {
@@ -7,10 +7,13 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.favorites.FavoritesViewModel
import org.koin.androidx.compose.getViewModel
@Composable
fun favoriteResults(): LazyListScope.(listState: LazyListState) -> Unit {
val favorites by viewModel<FavoritesViewModel>().getFavorites(5).observeAsState(emptyList())
val viewModel: FavoritesViewModel = getViewModel()
val favorites by viewModel.getFavorites(5).observeAsState(emptyList())
return {
SearchableGrid(items = favorites, listState = it)
}
@@ -6,10 +6,12 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.files.FilesViewModel
import org.koin.androidx.compose.getViewModel
@Composable
fun fileResults(): LazyListScope.() -> Unit {
val files by viewModel<FilesViewModel>().files.observeAsState(emptyList())
val viewModel: FilesViewModel = getViewModel()
val files by viewModel.files.observeAsState(emptyList())
return {
files?.let { SearchableList(items = it) }
}
@@ -6,13 +6,13 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.ui.component.SectionDivider
import de.mm20.launcher2.wikipedia.WikipediaViewModel
import org.koin.androidx.compose.getViewModel
@Composable
fun wikipediaResult(): LazyListScope.() -> Unit {
val viewModel = viewModel<WikipediaViewModel>()
val viewModel: WikipediaViewModel = getViewModel()
val wikipedia by viewModel.wikipedia.observeAsState()
return {
wikipedia?.let {
@@ -28,6 +28,7 @@ import de.mm20.launcher2.ui.LauncherTheme
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.pluralResource
import de.mm20.launcher2.ui.searchable.DeprecatedSearchableList
import org.koin.androidx.compose.getViewModel
import java.util.*
import kotlin.math.max
import kotlin.math.min
@@ -35,7 +36,7 @@ import kotlin.math.min
@Composable
fun CalendarWidget() {
val viewModel: CalendarViewModel = viewModel()
val viewModel: CalendarViewModel = getViewModel()
val favViewModel: FavoritesViewModel = viewModel()
val events by viewModel.upcomingCalendarEvents.observeAsState()
@@ -21,18 +21,16 @@ import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.music.MusicViewModel
import de.mm20.launcher2.music.PlaybackState
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.ktx.conditional
import de.mm20.launcher2.ui.locals.LocalColorScheme
import de.mm20.launcher2.ui.orange
import org.koin.androidx.compose.getViewModel
@OptIn(
ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class,
@@ -41,7 +39,7 @@ import de.mm20.launcher2.ui.orange
@Composable
fun MusicWidget() {
val viewModel: MusicViewModel = viewModel()
val viewModel: MusicViewModel = getViewModel()
val albumArt by viewModel.albumArt.observeAsState()
val title by viewModel.title.observeAsState()