Annual refactor
This commit is contained in:
@@ -4,7 +4,7 @@ import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import de.mm20.launcher2.data.customattrs.CustomAttributesRepository
|
||||
import de.mm20.launcher2.searchable.SearchableRepository
|
||||
import de.mm20.launcher2.searchable.SavableSearchableRepository
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.preferences.export
|
||||
import de.mm20.launcher2.preferences.import
|
||||
@@ -22,7 +22,7 @@ import java.util.zip.ZipOutputStream
|
||||
class BackupManager(
|
||||
private val context: Context,
|
||||
private val dataStore: LauncherDataStore,
|
||||
private val searchableRepository: SearchableRepository,
|
||||
private val searchableRepository: SavableSearchableRepository,
|
||||
private val widgetRepository: WidgetRepository,
|
||||
private val searchActionRepository: SearchActionRepository,
|
||||
private val customAttrsRepository: CustomAttributesRepository,
|
||||
|
||||
+29
-47
@@ -4,10 +4,8 @@ import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import de.mm20.launcher2.badges.Badge
|
||||
import de.mm20.launcher2.graphics.BadgeDrawable
|
||||
import de.mm20.launcher2.search.data.LauncherShortcut
|
||||
import de.mm20.launcher2.search.data.LegacyShortcut
|
||||
import de.mm20.launcher2.search.AppShortcut
|
||||
import de.mm20.launcher2.search.Searchable
|
||||
import de.mm20.launcher2.search.data.UnavailableShortcut
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
@@ -17,53 +15,37 @@ class AppShortcutBadgeProvider(
|
||||
private val context: Context
|
||||
) : BadgeProvider {
|
||||
override fun getBadge(searchable: Searchable): Flow<Badge?> = channelFlow {
|
||||
if (searchable is LauncherShortcut) {
|
||||
val componentName = searchable.launcherShortcut.activity
|
||||
if (componentName == null) {
|
||||
if (searchable is AppShortcut) {
|
||||
val componentName = searchable.componentName
|
||||
val packageName = searchable.packageName
|
||||
if (componentName != null) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val icon = try {
|
||||
context.packageManager.getActivityIcon(
|
||||
componentName
|
||||
)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
return@withContext
|
||||
}
|
||||
val badge = Badge(icon = BadgeDrawable(context, icon))
|
||||
send(badge)
|
||||
}
|
||||
} else if (packageName != null) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val icon = try {
|
||||
context.packageManager.getApplicationIcon(
|
||||
packageName
|
||||
)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
return@withContext
|
||||
}
|
||||
val badge = Badge(icon = BadgeDrawable(context, icon))
|
||||
send(badge)
|
||||
}
|
||||
} else {
|
||||
send(null)
|
||||
return@channelFlow
|
||||
}
|
||||
withContext(Dispatchers.IO) {
|
||||
val icon = try {
|
||||
context.packageManager.getActivityIcon(
|
||||
componentName
|
||||
)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
return@withContext
|
||||
}
|
||||
val badge = Badge(icon = BadgeDrawable(context, icon))
|
||||
send(badge)
|
||||
}
|
||||
} else if (searchable is LegacyShortcut) {
|
||||
val packageName = searchable.packageName
|
||||
if (packageName == null) {
|
||||
send(null)
|
||||
return@channelFlow
|
||||
}
|
||||
withContext(Dispatchers.IO) {
|
||||
val icon = try {
|
||||
context.packageManager.getApplicationIcon(
|
||||
packageName
|
||||
)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
return@withContext
|
||||
}
|
||||
val badge = Badge(icon = BadgeDrawable(context, icon))
|
||||
send(badge)
|
||||
}
|
||||
} else if (searchable is UnavailableShortcut) {
|
||||
val packageName = searchable.packageName
|
||||
withContext(Dispatchers.IO) {
|
||||
val icon = try {
|
||||
context.packageManager.getApplicationIcon(
|
||||
packageName
|
||||
)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
return@withContext
|
||||
}
|
||||
val badge = Badge(icon = BadgeDrawable(context, icon))
|
||||
send(badge)
|
||||
}
|
||||
} else {
|
||||
send(null)
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package de.mm20.launcher2.badges.providers
|
||||
|
||||
import de.mm20.launcher2.badges.Badge
|
||||
import de.mm20.launcher2.search.data.File
|
||||
import de.mm20.launcher2.search.File
|
||||
import de.mm20.launcher2.search.Searchable
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@ package de.mm20.launcher2.badges.providers
|
||||
import de.mm20.launcher2.badges.Badge
|
||||
import de.mm20.launcher2.notifications.NotificationRepository
|
||||
import de.mm20.launcher2.search.Searchable
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import de.mm20.launcher2.search.Application
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
@@ -15,8 +15,8 @@ class NotificationBadgeProvider : BadgeProvider, KoinComponent {
|
||||
private val notificationRepository: NotificationRepository by inject()
|
||||
|
||||
override fun getBadge(searchable: Searchable): Flow<Badge?> = channelFlow {
|
||||
if (searchable is LauncherApp) {
|
||||
val packageName = searchable.`package`
|
||||
if (searchable is Application) {
|
||||
val packageName = searchable.componentName.packageName
|
||||
notificationRepository.notifications.map {
|
||||
it.filter { it.packageName == packageName }
|
||||
}.collectLatest {
|
||||
|
||||
+3
-18
@@ -1,33 +1,18 @@
|
||||
package de.mm20.launcher2.badges.providers
|
||||
|
||||
import de.mm20.launcher2.applications.AppRepository
|
||||
import de.mm20.launcher2.badges.Badge
|
||||
import de.mm20.launcher2.badges.R
|
||||
import de.mm20.launcher2.search.Application
|
||||
import de.mm20.launcher2.search.Searchable
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class SuspendedAppsBadgeProvider : BadgeProvider, KoinComponent {
|
||||
private val appRepository: AppRepository by inject()
|
||||
|
||||
override fun getBadge(searchable: Searchable): Flow<Badge?> = channelFlow {
|
||||
if (searchable is LauncherApp) {
|
||||
val packageName = searchable.`package`
|
||||
appRepository.getSuspendedPackages().collectLatest {
|
||||
if (it.contains(packageName)) {
|
||||
send(
|
||||
Badge(
|
||||
iconRes = R.drawable.ic_badge_suspended
|
||||
)
|
||||
)
|
||||
} else {
|
||||
send(null)
|
||||
}
|
||||
}
|
||||
if (searchable is Application && searchable.isSuspended) {
|
||||
send(Badge(iconRes = R.drawable.ic_badge_suspended))
|
||||
} else {
|
||||
send(null)
|
||||
}
|
||||
|
||||
+4
-3
@@ -2,15 +2,16 @@ package de.mm20.launcher2.badges.providers
|
||||
|
||||
import de.mm20.launcher2.badges.Badge
|
||||
import de.mm20.launcher2.badges.R
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import de.mm20.launcher2.search.data.LauncherShortcut
|
||||
import de.mm20.launcher2.search.AppProfile
|
||||
import de.mm20.launcher2.search.AppShortcut
|
||||
import de.mm20.launcher2.search.Application
|
||||
import de.mm20.launcher2.search.Searchable
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
|
||||
class WorkProfileBadgeProvider : BadgeProvider {
|
||||
override fun getBadge(searchable: Searchable): Flow<Badge?> = flow {
|
||||
if (searchable is LauncherApp && !searchable.isMainProfile || searchable is LauncherShortcut && !searchable.isMainProfile) {
|
||||
if (searchable is Application && searchable.profile == AppProfile.Work || searchable is AppShortcut && searchable.profile == AppProfile.Work) {
|
||||
emit(
|
||||
Badge(
|
||||
iconRes = R.drawable.ic_badge_workprofile
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
package de.mm20.launcher2.services.favorites
|
||||
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
import de.mm20.launcher2.searchable.SearchableRepository
|
||||
import de.mm20.launcher2.searchable.SavableSearchableRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class FavoritesService(
|
||||
val searchableRepository: SearchableRepository,
|
||||
val searchableRepository: SavableSearchableRepository,
|
||||
) {
|
||||
|
||||
|
||||
|
||||
@@ -32,15 +32,14 @@ import de.mm20.launcher2.icons.transformations.LegacyToAdaptiveTransformation
|
||||
import de.mm20.launcher2.icons.transformations.transform
|
||||
import de.mm20.launcher2.ktx.isAtLeastApiLevel
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.search.Application
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
@@ -283,9 +282,9 @@ class IconService(
|
||||
|
||||
val providerOptions = mutableListOf<CustomIcon>()
|
||||
|
||||
if (searchable is LauncherApp) {
|
||||
if (searchable is Application) {
|
||||
val iconPackIcons = iconPackManager.getAllIconPackIcons(
|
||||
searchable.launcherActivityInfo.componentName
|
||||
searchable.componentName
|
||||
)
|
||||
|
||||
providerOptions.addAll(
|
||||
|
||||
+3
-3
@@ -6,15 +6,15 @@ import android.content.pm.PackageManager
|
||||
import de.mm20.launcher2.icons.DynamicCalendarIcon
|
||||
import de.mm20.launcher2.icons.LauncherIcon
|
||||
import de.mm20.launcher2.ktx.obtainTypedArrayOrNull
|
||||
import de.mm20.launcher2.search.Application
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class CalendarIconProvider(val context: Context, val themed: Boolean): IconProvider {
|
||||
override suspend fun getIcon(searchable: SavableSearchable, size: Int): LauncherIcon? = withContext(Dispatchers.IO) {
|
||||
if(searchable !is LauncherApp) return@withContext null
|
||||
val component = ComponentName(searchable.`package`, searchable.activity)
|
||||
if(searchable !is Application) return@withContext null
|
||||
val component = searchable.componentName
|
||||
val pm = context.packageManager
|
||||
val ai = try {
|
||||
pm.getActivityInfo(component, PackageManager.GET_META_DATA)
|
||||
|
||||
+3
-3
@@ -6,8 +6,8 @@ import android.content.pm.PackageManager
|
||||
import de.mm20.launcher2.icons.LauncherIcon
|
||||
import de.mm20.launcher2.icons.compat.AdaptiveIconDrawableCompat
|
||||
import de.mm20.launcher2.icons.compat.toLauncherIcon
|
||||
import de.mm20.launcher2.search.Application
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@@ -16,8 +16,8 @@ class CompatIconProvider(
|
||||
private val themed: Boolean = false,
|
||||
) : IconProvider {
|
||||
override suspend fun getIcon(searchable: SavableSearchable, size: Int): LauncherIcon? {
|
||||
if (searchable !is LauncherApp) return null
|
||||
val component = ComponentName(searchable.`package`, searchable.activity)
|
||||
if (searchable !is Application) return null
|
||||
val component = searchable.componentName
|
||||
|
||||
val icon = withContext(Dispatchers.IO) {
|
||||
val activityInfo = try {
|
||||
|
||||
+4
-4
@@ -6,18 +6,18 @@ import de.mm20.launcher2.icons.LauncherIcon
|
||||
import de.mm20.launcher2.icons.compat.AdaptiveIconDrawableCompat
|
||||
import de.mm20.launcher2.icons.compat.ClockIconConfig
|
||||
import de.mm20.launcher2.icons.compat.toLauncherIcon
|
||||
import de.mm20.launcher2.search.Application
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class DynamicClockIconProvider(val context: Context, private val themed: Boolean) : IconProvider {
|
||||
override suspend fun getIcon(searchable: SavableSearchable, size: Int): LauncherIcon? = withContext(Dispatchers.IO) {
|
||||
if (searchable !is LauncherApp) return@withContext null
|
||||
if (searchable !is Application) return@withContext null
|
||||
val pm = context.packageManager
|
||||
val appInfo = try {
|
||||
pm.getApplicationInfo(
|
||||
searchable.`package`,
|
||||
searchable.componentName.packageName,
|
||||
PackageManager.GET_META_DATA
|
||||
)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
@@ -47,7 +47,7 @@ class DynamicClockIconProvider(val context: Context, private val themed: Boolean
|
||||
|
||||
// Workaround for Google Clock themed icon because it is weird and I don't understand
|
||||
// how to get the correct layers from the drawable without hardcoding them here.
|
||||
val clockConfig = if (themed && searchable.`package` == "com.google.android.deskclock") {
|
||||
val clockConfig = if (themed && searchable.componentName.packageName == "com.google.android.deskclock") {
|
||||
ClockIconConfig(
|
||||
hourLayer = 0,
|
||||
minuteLayer = 2,
|
||||
|
||||
+13
-6
@@ -1,10 +1,12 @@
|
||||
package de.mm20.launcher2.icons.providers
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.LauncherApps
|
||||
import androidx.core.content.getSystemService
|
||||
import de.mm20.launcher2.icons.*
|
||||
import de.mm20.launcher2.search.Application
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@@ -15,15 +17,20 @@ class IconPackIconProvider(
|
||||
private val allowThemed: Boolean,
|
||||
): IconProvider {
|
||||
override suspend fun getIcon(searchable: SavableSearchable, size: Int): LauncherIcon? {
|
||||
if (searchable !is LauncherApp) return null
|
||||
if (searchable !is Application) return null
|
||||
|
||||
return iconPackManager.getIcon(iconPack.packageName, searchable.`package`, searchable.activity, allowThemed)
|
||||
|
||||
return iconPackManager.getIcon(iconPack.packageName, searchable.componentName.packageName, searchable.componentName.className, allowThemed)
|
||||
?: iconPackManager.generateIcon(
|
||||
context,
|
||||
iconPack.packageName,
|
||||
baseIcon = withContext(Dispatchers.IO) {
|
||||
searchable.launcherActivityInfo.getIcon(context.resources.displayMetrics.densityDpi)
|
||||
},
|
||||
val ai = context.getSystemService<LauncherApps>()?.resolveActivity(
|
||||
Intent().setComponent(searchable.componentName),
|
||||
searchable.user
|
||||
)
|
||||
ai?.getIcon(context.resources.displayMetrics.densityDpi)
|
||||
} ?: return null,
|
||||
size = size,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -46,20 +46,12 @@ dependencies {
|
||||
implementation(libs.okhttp)
|
||||
implementation(libs.coil.core)
|
||||
|
||||
implementation(project(":data:applications"))
|
||||
implementation(project(":data:appshortcuts"))
|
||||
implementation(project(":data:calculator"))
|
||||
implementation(project(":data:calendar"))
|
||||
implementation(project(":data:contacts"))
|
||||
implementation(project(":data:files"))
|
||||
implementation(project(":data:unitconverter"))
|
||||
implementation(project(":data:websites"))
|
||||
implementation(project(":data:wikipedia"))
|
||||
implementation(project(":data:customattrs"))
|
||||
implementation(project(":data:search-actions"))
|
||||
|
||||
implementation(project(":core:base"))
|
||||
implementation(project(":core:database"))
|
||||
implementation(project(":core:preferences"))
|
||||
implementation(project(":core:crashreporter"))
|
||||
implementation(project(":core:ktx"))
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package de.mm20.launcher2.search
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.core.qualifier.named
|
||||
import org.koin.dsl.module
|
||||
|
||||
val searchModule = module {
|
||||
single<SearchService> {
|
||||
SearchServiceImpl(
|
||||
get(named<Application>()),
|
||||
get(named<AppShortcut>()),
|
||||
get(named<CalendarEvent>()),
|
||||
get(named<Contact>()),
|
||||
get(named<File>()),
|
||||
get(),
|
||||
get(),
|
||||
get(),
|
||||
get(),
|
||||
get(),
|
||||
get(),
|
||||
get(),
|
||||
get(),
|
||||
get(),
|
||||
get(named<Website>()),
|
||||
get(),
|
||||
get(),
|
||||
)
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
package de.mm20.launcher2.search
|
||||
|
||||
import de.mm20.launcher2.applications.AppRepository
|
||||
import de.mm20.launcher2.appshortcuts.AppShortcutRepository
|
||||
import de.mm20.launcher2.calculator.CalculatorRepository
|
||||
import de.mm20.launcher2.calendar.CalendarRepository
|
||||
import de.mm20.launcher2.contacts.ContactRepository
|
||||
import de.mm20.launcher2.data.customattrs.CustomAttributesRepository
|
||||
import de.mm20.launcher2.data.customattrs.utils.withCustomLabels
|
||||
import de.mm20.launcher2.files.FileRepository
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.Settings.AppShortcutSearchSettings
|
||||
import de.mm20.launcher2.preferences.Settings.CalculatorSearchSettings
|
||||
@@ -17,25 +12,11 @@ import de.mm20.launcher2.preferences.Settings.FilesSearchSettings
|
||||
import de.mm20.launcher2.preferences.Settings.UnitConverterSearchSettings
|
||||
import de.mm20.launcher2.preferences.Settings.WebsiteSearchSettings
|
||||
import de.mm20.launcher2.preferences.Settings.WikipediaSearchSettings
|
||||
import de.mm20.launcher2.search.data.AppShortcut
|
||||
import de.mm20.launcher2.search.data.Calculator
|
||||
import de.mm20.launcher2.search.data.CalendarEvent
|
||||
import de.mm20.launcher2.search.data.Contact
|
||||
import de.mm20.launcher2.search.data.File
|
||||
import de.mm20.launcher2.search.data.GDriveFile
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import de.mm20.launcher2.search.data.LocalFile
|
||||
import de.mm20.launcher2.search.data.NextcloudFile
|
||||
import de.mm20.launcher2.search.data.OneDriveFile
|
||||
import de.mm20.launcher2.search.data.OwncloudFile
|
||||
import de.mm20.launcher2.search.data.UnitConverter
|
||||
import de.mm20.launcher2.search.data.Website
|
||||
import de.mm20.launcher2.search.data.Wikipedia
|
||||
import de.mm20.launcher2.searchactions.SearchActionService
|
||||
import de.mm20.launcher2.searchactions.actions.SearchAction
|
||||
import de.mm20.launcher2.unitconverter.UnitConverterRepository
|
||||
import de.mm20.launcher2.websites.WebsiteRepository
|
||||
import de.mm20.launcher2.wikipedia.WikipediaRepository
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
@@ -84,15 +65,15 @@ interface SearchService {
|
||||
}
|
||||
|
||||
internal class SearchServiceImpl(
|
||||
private val appRepository: AppRepository,
|
||||
private val appShortcutRepository: AppShortcutRepository,
|
||||
private val calendarRepository: CalendarRepository,
|
||||
private val contactRepository: ContactRepository,
|
||||
private val fileRepository: FileRepository,
|
||||
private val wikipediaRepository: WikipediaRepository,
|
||||
private val appRepository: SearchableRepository<Application>,
|
||||
private val appShortcutRepository: SearchableRepository<AppShortcut>,
|
||||
private val calendarRepository: SearchableRepository<CalendarEvent>,
|
||||
private val contactRepository: SearchableRepository<Contact>,
|
||||
private val fileRepository: SearchableRepository<File>,
|
||||
private val wikipediaRepository: SearchableRepository<Article>,
|
||||
private val unitConverterRepository: UnitConverterRepository,
|
||||
private val calculatorRepository: CalculatorRepository,
|
||||
private val websiteRepository: WebsiteRepository,
|
||||
private val websiteRepository: SearchableRepository<Website>,
|
||||
private val searchActionService: SearchActionService,
|
||||
private val customAttributesRepository: CustomAttributesRepository,
|
||||
) : SearchService {
|
||||
@@ -184,7 +165,6 @@ internal class SearchServiceImpl(
|
||||
if (websites.enabled) {
|
||||
launch {
|
||||
websiteRepository.search(query)
|
||||
.map { it?.let { listOf(it) } ?: listOf() }
|
||||
.withCustomLabels(customAttributesRepository)
|
||||
.collectLatest { r ->
|
||||
results.update {
|
||||
@@ -196,8 +176,7 @@ internal class SearchServiceImpl(
|
||||
if (wikipedia.enabled) {
|
||||
launch {
|
||||
delay(750)
|
||||
wikipediaRepository.search(query, loadImages = wikipedia.images)
|
||||
.map { it?.let { listOf(it) } ?: listOf() }
|
||||
wikipediaRepository.search(query)
|
||||
.withCustomLabels(customAttributesRepository)
|
||||
.collectLatest { r ->
|
||||
results.update {
|
||||
@@ -210,11 +189,6 @@ internal class SearchServiceImpl(
|
||||
launch {
|
||||
fileRepository.search(
|
||||
query,
|
||||
local = files.localFiles,
|
||||
nextcloud = files.nextcloud,
|
||||
owncloud = files.owncloud,
|
||||
onedrive = files.onedrive,
|
||||
gdrive = files.gdrive,
|
||||
)
|
||||
.withCustomLabels(customAttributesRepository)
|
||||
.collectLatest { r ->
|
||||
@@ -229,22 +203,7 @@ internal class SearchServiceImpl(
|
||||
.withCustomLabels(customAttributesRepository)
|
||||
.collectLatest { r ->
|
||||
results.update {
|
||||
it.copy(
|
||||
other = r
|
||||
.filter {
|
||||
it is LauncherApp ||
|
||||
shortcuts.enabled && it is AppShortcut ||
|
||||
files.localFiles && it is LocalFile ||
|
||||
files.nextcloud && it is NextcloudFile ||
|
||||
files.owncloud && it is OwncloudFile ||
|
||||
files.onedrive && it is OneDriveFile ||
|
||||
files.gdrive && it is GDriveFile ||
|
||||
wikipedia.enabled && it is Wikipedia ||
|
||||
websites.enabled && it is Website ||
|
||||
calendars.enabled && it is CalendarEvent ||
|
||||
contacts.enabled && it is Contact
|
||||
}.toImmutableList()
|
||||
)
|
||||
it.copy(other = r.toImmutableList())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -257,7 +216,7 @@ internal class SearchServiceImpl(
|
||||
}
|
||||
|
||||
data class SearchResults(
|
||||
val apps: ImmutableList<LauncherApp>? = null,
|
||||
val apps: ImmutableList<Application>? = null,
|
||||
val shortcuts: ImmutableList<AppShortcut>? = null,
|
||||
val contacts: ImmutableList<Contact>? = null,
|
||||
val calendars: ImmutableList<CalendarEvent>? = null,
|
||||
@@ -265,7 +224,7 @@ data class SearchResults(
|
||||
val calculators: ImmutableList<Calculator>? = null,
|
||||
val unitConverters: ImmutableList<UnitConverter>? = null,
|
||||
val websites: ImmutableList<Website>? = null,
|
||||
val wikipedia: ImmutableList<Wikipedia>? = null,
|
||||
val wikipedia: ImmutableList<Article>? = null,
|
||||
val searchActions: ImmutableList<SearchAction>? = null,
|
||||
val other: ImmutableList<SavableSearchable>? = null,
|
||||
)
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
package de.mm20.launcher2.search.data
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import de.mm20.launcher2.database.entities.WebsearchEntity
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
class Websearch(
|
||||
var urlTemplate: String,
|
||||
var label: String,
|
||||
var color: Int,
|
||||
var icon: String?,
|
||||
var id: Long? = null,
|
||||
var encoding: QueryEncoding = QueryEncoding.UrlEncode,
|
||||
val query: String? = null,
|
||||
) {
|
||||
|
||||
constructor(entity: WebsearchEntity, query: String? = null) : this(
|
||||
urlTemplate = entity.urlTemplate,
|
||||
label = entity.label,
|
||||
icon = entity.icon,
|
||||
color = entity.color,
|
||||
id = entity.id,
|
||||
query = query,
|
||||
encoding = QueryEncoding.fromInt(entity.encoding)
|
||||
)
|
||||
|
||||
fun toDatabaseEntity(): WebsearchEntity {
|
||||
return WebsearchEntity(
|
||||
urlTemplate = urlTemplate,
|
||||
color = color,
|
||||
icon = icon,
|
||||
label = label,
|
||||
id = id,
|
||||
encoding = encoding.toInt()
|
||||
)
|
||||
}
|
||||
|
||||
fun getLaunchIntent(): Intent? {
|
||||
if (query == null) return null
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
val url = urlTemplate.replace("\${1}", encodeQuery(query, encoding))
|
||||
intent.data = Uri.parse(url)
|
||||
return intent
|
||||
}
|
||||
|
||||
private fun encodeQuery(query: String, encoding: QueryEncoding): String {
|
||||
return when(encoding) {
|
||||
QueryEncoding.UrlEncode -> Uri.encode(query)
|
||||
QueryEncoding.FormData -> URLEncoder.encode(query, "UTF-8")
|
||||
QueryEncoding.None -> query
|
||||
}
|
||||
}
|
||||
|
||||
enum class QueryEncoding {
|
||||
UrlEncode,
|
||||
FormData,
|
||||
None;
|
||||
|
||||
fun toInt(): Int {
|
||||
return when (this) {
|
||||
UrlEncode -> 0
|
||||
FormData -> 1
|
||||
None -> 2
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromInt(value: Int?): QueryEncoding {
|
||||
return when (value) {
|
||||
1 -> FormData
|
||||
2 -> None
|
||||
else -> UrlEncode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package de.mm20.launcher2.services.tags.impl
|
||||
|
||||
import de.mm20.launcher2.data.customattrs.CustomAttributesRepository
|
||||
import de.mm20.launcher2.searchable.SearchableRepository
|
||||
import de.mm20.launcher2.searchable.SavableSearchableRepository
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
import de.mm20.launcher2.search.data.Tag
|
||||
import de.mm20.launcher2.services.tags.TagsService
|
||||
@@ -14,7 +14,7 @@ import kotlinx.coroutines.launch
|
||||
|
||||
internal class TagsServiceImpl(
|
||||
private val customAttributesRepository: CustomAttributesRepository,
|
||||
private val searchableRepository: SearchableRepository,
|
||||
private val searchableRepository: SavableSearchableRepository,
|
||||
) : TagsService {
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
override fun getAllTags(startsWith: String?): Flow<List<String>> {
|
||||
|
||||
Reference in New Issue
Block a user