This commit is contained in:
MM20 2022-06-21 18:37:38 +02:00
parent 26995c1141
commit 96e70da913
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
98 changed files with 61 additions and 891 deletions

View File

@ -9,8 +9,6 @@ import de.mm20.launcher2.owncloud.OwncloudClient
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
interface AccountsRepository { interface AccountsRepository {
@ -26,7 +24,7 @@ interface AccountsRepository {
} }
internal class AccountsRepositoryImpl( internal class AccountsRepositoryImpl(
private val context: Context context: Context
) : AccountsRepository { ) : AccountsRepository {
private val scope = CoroutineScope(Job() + Dispatchers.Default) private val scope = CoroutineScope(Job() + Dispatchers.Default)

View File

@ -2,7 +2,6 @@ package de.mm20.launcher2.debug
import android.os.StrictMode import android.os.StrictMode
import android.util.Log import android.util.Log
import de.mm20.launcher2.BuildConfig
class Debug { class Debug {
init { init {

View File

@ -1,4 +1,4 @@
package de.mm20.launcher2.activity; package de.mm20.launcher2.activity
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.applications package de.mm20.launcher2.applications
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module
val applicationsModule = module { val applicationsModule = module {

View File

@ -4,5 +4,5 @@ import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module import org.koin.dsl.module
val backupModule = module { val backupModule = module {
single<BackupManager> { BackupManager(androidContext(), get(), get(), get(), get()) } single { BackupManager(androidContext(), get(), get(), get(), get()) }
} }

View File

@ -1,8 +1,6 @@
package de.mm20.launcher2.badges.providers package de.mm20.launcher2.badges.providers
import android.util.Log
import de.mm20.launcher2.badges.Badge import de.mm20.launcher2.badges.Badge
import de.mm20.launcher2.badges.R
import de.mm20.launcher2.search.data.File import de.mm20.launcher2.search.data.File
import de.mm20.launcher2.search.data.Searchable import de.mm20.launcher2.search.data.Searchable
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow

View File

@ -4,7 +4,6 @@ import de.mm20.launcher2.applications.AppRepository
import de.mm20.launcher2.badges.Badge import de.mm20.launcher2.badges.Badge
import de.mm20.launcher2.badges.R import de.mm20.launcher2.badges.R
import de.mm20.launcher2.search.data.Application import de.mm20.launcher2.search.data.Application
import de.mm20.launcher2.search.data.LauncherApp
import de.mm20.launcher2.search.data.Searchable import de.mm20.launcher2.search.data.Searchable
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.flow.channelFlow

View File

@ -1,50 +0,0 @@
package de.mm20.launcher2.graphics
import android.content.res.ColorStateList
import android.graphics.*
import android.graphics.drawable.Drawable
class TextDrawable(
val text: String,
val color: Int = Color.WHITE,
val height: Int? = null,
val fontSize: Float = 13f,
typeface: Typeface = Typeface.DEFAULT
): Drawable() {
private val paint = Paint()
private val rect = Rect()
init {
paint.textAlign = Paint.Align.CENTER
paint.textSize = fontSize
paint.color = color
paint.isAntiAlias = true
paint.typeface = typeface
paint.style = Paint.Style.FILL
}
override fun draw(canvas: Canvas) {
val bounds = bounds
if (height != null) paint.textSize = fontSize * bounds.height().toFloat() / height.toFloat()
else paint.textSize = fontSize
paint.getTextBounds(text, 0, text.length, rect)
canvas.drawText(text, bounds.exactCenterX(), bounds.exactCenterY() + rect.height() / 2f, paint)
}
override fun setAlpha(alpha: Int) {
paint.alpha = alpha
}
override fun setColorFilter(colorFilter: ColorFilter?) {
paint.colorFilter = colorFilter
}
override fun getOpacity(): Int {
return PixelFormat.TRANSLUCENT
}
override fun setTintList(tint: ColorStateList?) {
paint.color = tint?.defaultColor ?: color
}
}

View File

@ -1,7 +1,5 @@
package de.mm20.launcher2.icons package de.mm20.launcher2.icons
import android.content.res.Resources
sealed interface LauncherIcon sealed interface LauncherIcon
data class StaticLauncherIcon( data class StaticLauncherIcon(

View File

@ -48,7 +48,7 @@ class Calculator(
} }
formattedOctString = s.toString() formattedOctString = s.toString()
s = StringBuffer(solution.roundToInt().toString(16).toUpperCase()) s = StringBuffer(solution.roundToInt().toString(16).uppercase(Locale.getDefault()))
while (s.length % 2 != 0) { while (s.length % 2 != 0) {
s = s.insert(0, '0') s = s.insert(0, '0')
} }
@ -62,7 +62,7 @@ class Calculator(
fun getBeatifiedTerm(): String { fun getBeatifiedTerm(): String {
if(term.matches(Regex("0x[0-9a-fA-F]+"))) { if(term.matches(Regex("0x[0-9a-fA-F]+"))) {
return term.substring(2).toUpperCase(Locale.ROOT) + "₁₆" return term.substring(2).uppercase(Locale.ROOT) + "₁₆"
} }
if(term.matches(Regex("0b[01]+"))) { if(term.matches(Regex("0b[01]+"))) {
return term.substring(2) + "" return term.substring(2) + ""

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.calendar package de.mm20.launcher2.calendar
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module
val calendarModule = module { val calendarModule = module {

View File

@ -3,16 +3,10 @@ package de.mm20.launcher2.search.data
import android.content.ContentUris import android.content.ContentUris
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Color
import android.graphics.Typeface
import android.graphics.drawable.ColorDrawable
import android.provider.CalendarContract import android.provider.CalendarContract
import de.mm20.launcher2.graphics.TextDrawable
import de.mm20.launcher2.icons.ColorLayer import de.mm20.launcher2.icons.ColorLayer
import de.mm20.launcher2.icons.StaticLauncherIcon import de.mm20.launcher2.icons.StaticLauncherIcon
import de.mm20.launcher2.icons.TextLayer import de.mm20.launcher2.icons.TextLayer
import de.mm20.launcher2.ktx.dp
import palettes.TonalPalette
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
class CalendarEvent( class CalendarEvent(

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.contacts package de.mm20.launcher2.contacts
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module
val contactsModule = module { val contactsModule = module {

View File

@ -9,7 +9,6 @@ import android.os.Build;
import android.util.Log; import android.util.Log;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.UUID;
import static com.balsikandar.crashreporter.utils.AppUtilsKt.getAppSignature; import static com.balsikandar.crashreporter.utils.AppUtilsKt.getAppSignature;
@ -68,26 +67,6 @@ public class AppUtils {
return tz.getID(); return tz.getID();
} }
private static String getDeviceId(Context context) {
String androidDeviceId = getAndroidDeviceId(context);
if (androidDeviceId == null)
androidDeviceId = UUID.randomUUID().toString();
return androidDeviceId;
}
private static String getAndroidDeviceId(Context context) {
final String INVALID_ANDROID_ID = "9774d56d682e549c";
final String androidId = android.provider.Settings.Secure.getString(
context.getContentResolver(),
android.provider.Settings.Secure.ANDROID_ID);
if (androidId == null
|| androidId.toLowerCase().equals(INVALID_ANDROID_ID)) {
return null;
}
return androidId;
}
private static int getAppVersionCode(Context context) { private static int getAppVersionCode(Context context) {
try { try {
PackageInfo packageInfo = context.getPackageManager() PackageInfo packageInfo = context.getPackageManager()

View File

@ -31,7 +31,7 @@ class CurrencyRepository(
toCurrency: String? = null toCurrency: String? = null
): List<Pair<String, Double>> { ): List<Pair<String, Double>> {
return withContext<List<Pair<String, Double>>>(Dispatchers.IO) { return withContext(Dispatchers.IO) {
val dao = AppDatabase.getInstance(context) val dao = AppDatabase.getInstance(context)
.currencyDao() .currencyDao()

View File

@ -16,7 +16,7 @@ android {
javaCompileOptions { javaCompileOptions {
annotationProcessorOptions { annotationProcessorOptions {
arguments.put("room.schemaLocation", "$projectDir/schemas") arguments["room.schemaLocation"] = "$projectDir/schemas"
} }
} }
} }

View File

@ -1,3 +1,5 @@
@file:Suppress("ClassName")
package de.mm20.launcher2.database package de.mm20.launcher2.database
import android.content.Context import android.content.Context

View File

@ -1,6 +1,5 @@
package de.mm20.launcher2.database package de.mm20.launcher2.database
import android.content.ComponentName
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.room.* import androidx.room.*
import de.mm20.launcher2.database.entities.IconEntity import de.mm20.launcher2.database.entities.IconEntity

View File

@ -1,10 +1,6 @@
package de.mm20.launcher2.database package de.mm20.launcher2.database
import androidx.room.Dao import androidx.room.*
import androidx.room.Insert
import androidx.room.OnConflictStrategy.REPLACE
import androidx.room.Query
import androidx.room.Transaction
import de.mm20.launcher2.database.entities.ForecastEntity import de.mm20.launcher2.database.entities.ForecastEntity
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -13,7 +9,7 @@ interface WeatherDao {
@Query("SELECT * FROM ${ForecastEntity.TABLE_NAME} ORDER BY timestamp ASC") @Query("SELECT * FROM ${ForecastEntity.TABLE_NAME} ORDER BY timestamp ASC")
fun getForecasts(): Flow<List<ForecastEntity>> fun getForecasts(): Flow<List<ForecastEntity>>
@Insert(onConflict = REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(forecasts: List<ForecastEntity>) fun insertAll(forecasts: List<ForecastEntity>)
@Query("DELETE FROM ${ForecastEntity.TABLE_NAME}") @Query("DELETE FROM ${ForecastEntity.TABLE_NAME}")

View File

@ -1,12 +1,8 @@
package de.mm20.launcher2.favorites package de.mm20.launcher2.favorites
import android.content.Context
import de.mm20.launcher2.database.entities.FavoritesItemEntity import de.mm20.launcher2.database.entities.FavoritesItemEntity
import de.mm20.launcher2.search.SearchableSerializer import de.mm20.launcher2.search.SearchableSerializer
import de.mm20.launcher2.search.data.Searchable import de.mm20.launcher2.search.data.Searchable
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.koin.core.parameter.parametersOf
data class FavoritesItem( data class FavoritesItem(
val key: String, val key: String,

View File

@ -1,19 +1,5 @@
package de.mm20.launcher2.favorites package de.mm20.launcher2.favorites
import de.mm20.launcher2.appshortcuts.AppShortcutDeserializer
import de.mm20.launcher2.appshortcuts.AppShortcutSerializer
import de.mm20.launcher2.calendar.CalendarEventDeserializer
import de.mm20.launcher2.calendar.CalendarEventSerializer
import de.mm20.launcher2.contacts.ContactDeserializer
import de.mm20.launcher2.contacts.ContactSerializer
import de.mm20.launcher2.files.*
import de.mm20.launcher2.search.NullDeserializer
import de.mm20.launcher2.search.NullSerializer
import de.mm20.launcher2.search.data.*
import de.mm20.launcher2.websites.WebsiteDeserializer
import de.mm20.launcher2.websites.WebsiteSerializer
import de.mm20.launcher2.wikipedia.WikipediaDeserializer
import de.mm20.launcher2.wikipedia.WikipediaSerializer
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module import org.koin.dsl.module

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.files package de.mm20.launcher2.files
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module
val filesModule = module { val filesModule = module {

View File

@ -6,7 +6,6 @@ import android.os.Build
import android.os.CancellationSignal import android.os.CancellationSignal
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Size import android.util.Size
import androidx.core.content.ContentResolverCompat
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException

View File

@ -114,7 +114,7 @@ abstract class File(
} }
} }
if (resource == R.string.file_type_none && label.matches(Regex(".+\\..+"))) { if (resource == R.string.file_type_none && label.matches(Regex(".+\\..+"))) {
val extension = label.substringAfterLast(".").toUpperCase(Locale.getDefault()) val extension = label.substringAfterLast(".").uppercase(Locale.getDefault())
if (extension == "kvaesitso") return context.getString( if (extension == "kvaesitso") return context.getString(
R.string.file_type_launcherbackup, R.string.file_type_launcherbackup,
context.getString(R.string.app_name) context.getString(R.string.app_name)

View File

@ -4,10 +4,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import de.mm20.launcher2.files.R import de.mm20.launcher2.files.R
import de.mm20.launcher2.gservices.DriveFileMeta
import de.mm20.launcher2.gservices.GoogleApiHelper
import de.mm20.launcher2.helper.NetworkUtils
import de.mm20.launcher2.icons.LauncherIcon
class GDriveFile( class GDriveFile(
val fileId: String, val fileId: String,

View File

@ -114,8 +114,8 @@ open class LocalFile(
val icon = withContext(Dispatchers.IO) { val icon = withContext(Dispatchers.IO) {
pkgInfo?.applicationInfo?.loadIcon(context.packageManager) pkgInfo?.applicationInfo?.loadIcon(context.packageManager)
} ?: return null } ?: return null
when { when (icon) {
icon is AdaptiveIconDrawable -> { is AdaptiveIconDrawable -> {
return StaticLauncherIcon( return StaticLauncherIcon(
foregroundLayer = icon.foreground?.let { foregroundLayer = icon.foreground?.let {
StaticIconLayer( StaticIconLayer(

View File

@ -3,10 +3,7 @@ package de.mm20.launcher2.search.data
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import de.mm20.launcher2.msservices.DriveItem
import de.mm20.launcher2.files.R import de.mm20.launcher2.files.R
import de.mm20.launcher2.msservices.MicrosoftGraphApiHelper
import de.mm20.launcher2.icons.LauncherIcon
class OneDriveFile( class OneDriveFile(
val fileId: String, val fileId: String,

View File

@ -4,8 +4,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import de.mm20.launcher2.files.R import de.mm20.launcher2.files.R
import de.mm20.launcher2.helper.NetworkUtils
import de.mm20.launcher2.owncloud.OwncloudClient
class OwncloudFile( class OwncloudFile(
fileId: Long, fileId: Long,

View File

@ -26,7 +26,7 @@ data class DriveFile(
width = file.imageMediaMetadata?.width ?: file.videoMediaMetadata?.width, width = file.imageMediaMetadata?.width ?: file.videoMediaMetadata?.width,
height = file.imageMediaMetadata?.height ?: file.videoMediaMetadata?.height height = file.imageMediaMetadata?.height ?: file.videoMediaMetadata?.height
), ),
directoryColor = file.folderColorRgb?.toLowerCase(Locale.ROOT), directoryColor = file.folderColorRgb.lowercase(Locale.ROOT),
viewUri = file.webViewLink ?: "" viewUri = file.webViewLink ?: ""
) )
} }

View File

@ -69,10 +69,10 @@ class GoogleClockIconProvider(val context: Context) : IconProvider {
} }
ClockSublayer( ClockSublayer(
drawable = drw, drawable = drw,
role = when { role = when (it) {
it == hourLayer -> ClockSublayerRole.Hour hourLayer -> ClockSublayerRole.Hour
it == minuteLayer -> ClockSublayerRole.Minute minuteLayer -> ClockSublayerRole.Minute
it == secondLayer -> ClockSublayerRole.Second secondLayer -> ClockSublayerRole.Second
else -> ClockSublayerRole.Static else -> ClockSublayerRole.Static
} }
) )

View File

@ -44,8 +44,8 @@ class IconPackIconProvider(
val resId = res.getIdentifier(drawableName, "drawable", iconPack).takeIf { it != 0 } val resId = res.getIdentifier(drawableName, "drawable", iconPack).takeIf { it != 0 }
?: return generateIcon(context, searchable.launcherActivityInfo, size) ?: return generateIcon(context, searchable.launcherActivityInfo, size)
val drawable = ResourcesCompat.getDrawable(res, resId, context.theme) ?: return null val drawable = ResourcesCompat.getDrawable(res, resId, context.theme) ?: return null
return when { return when (drawable) {
drawable is AdaptiveIconDrawable -> { is AdaptiveIconDrawable -> {
return StaticLauncherIcon( return StaticLauncherIcon(
foregroundLayer = drawable.foreground?.let { foregroundLayer = drawable.foreground?.let {
StaticIconLayer( StaticIconLayer(
@ -135,7 +135,7 @@ class IconPackIconProvider(
} }
if (upon != null) { if (upon != null) {
res.getIdentifier(upon, "drawable", pack).takeIf { it != 0 }?.let { res.getIdentifier(upon, "drawable", pack).takeIf { it != 0 }?.let {
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_OVER); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)
val maskDrawable = ResourcesCompat.getDrawable(res, it, null) ?: return null val maskDrawable = ResourcesCompat.getDrawable(res, it, null) ?: return null
val maskBmp = maskDrawable.toBitmap(size, size) val maskBmp = maskDrawable.toBitmap(size, size)
inBounds = Rect(0, 0, maskBmp.width, maskBmp.height) inBounds = Rect(0, 0, maskBmp.width, maskBmp.height)
@ -145,7 +145,7 @@ class IconPackIconProvider(
} }
if (back != null) { if (back != null) {
res.getIdentifier(back, "drawable", pack).takeIf { it != 0 }?.let { res.getIdentifier(back, "drawable", pack).takeIf { it != 0 }?.let {
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OVER); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OVER)
val maskDrawable = ResourcesCompat.getDrawable(res, it, null) ?: return null val maskDrawable = ResourcesCompat.getDrawable(res, it, null) ?: return null
val maskBmp = maskDrawable.toBitmap(size, size) val maskBmp = maskDrawable.toBitmap(size, size)
inBounds = Rect(0, 0, maskBmp.width, maskBmp.height) inBounds = Rect(0, 0, maskBmp.width, maskBmp.height)

View File

@ -2,7 +2,6 @@ package de.mm20.launcher2.icons.providers
import android.content.Context import android.content.Context
import de.mm20.launcher2.icons.LauncherIcon import de.mm20.launcher2.icons.LauncherIcon
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.search.data.Searchable import de.mm20.launcher2.search.data.Searchable
class SystemIconProvider( class SystemIconProvider(

View File

@ -112,9 +112,9 @@ internal class ThemedIconProvider(
} }
ClockSublayer( ClockSublayer(
drawable = drw, drawable = drw,
role = when { role = when (it) {
it == hourIndex -> ClockSublayerRole.Hour hourIndex -> ClockSublayerRole.Hour
it == minuteIndex -> ClockSublayerRole.Minute minuteIndex -> ClockSublayerRole.Minute
else -> ClockSublayerRole.Static else -> ClockSublayerRole.Static
} }
) )

View File

@ -1,7 +1,5 @@
package de.mm20.launcher2.ktx package de.mm20.launcher2.ktx
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
val Fragment.dp: Float val Fragment.dp: Float

View File

@ -4,7 +4,6 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import kotlin.coroutines.CoroutineContext
val View.dp: Float val View.dp: Float
get() = context.dp get() = context.dp

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.music package de.mm20.launcher2.music
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module
val musicModule = module { val musicModule = module {

View File

@ -51,7 +51,7 @@ interface MusicRepository {
internal class MusicRepositoryImpl( internal class MusicRepositoryImpl(
private val context: Context, private val context: Context,
private val notificationRepository: NotificationRepository notificationRepository: NotificationRepository
) : MusicRepository, KoinComponent { ) : MusicRepository, KoinComponent {
private val scope = CoroutineScope(Job() + Dispatchers.Default) private val scope = CoroutineScope(Job() + Dispatchers.Default)

View File

@ -31,7 +31,7 @@ interface NotificationRepository {
fun cancelNotification(notification: StatusBarNotification) fun cancelNotification(notification: StatusBarNotification)
} }
internal class NotificationRepositoryImpl() : NotificationRepository { internal class NotificationRepositoryImpl : NotificationRepository {
private val scope = CoroutineScope(Job() + Dispatchers.Default) private val scope = CoroutineScope(Job() + Dispatchers.Default)
override val notifications: MutableStateFlow<List<StatusBarNotification>> = MutableStateFlow( override val notifications: MutableStateFlow<List<StatusBarNotification>> = MutableStateFlow(
emptyList() emptyList()

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.preferences package de.mm20.launcher2.preferences
import android.content.Context import android.content.Context
import android.util.Log
import androidx.datastore.core.DataMigration import androidx.datastore.core.DataMigration
import androidx.datastore.core.DataStore import androidx.datastore.core.DataStore
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.search package de.mm20.launcher2.search
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module
val searchModule = module { val searchModule = module {

View File

@ -1,25 +0,0 @@
package de.mm20.launcher2.search
import androidx.lifecycle.MutableLiveData
class SearchRepository {
val isSearching = MutableLiveData<Boolean>(false)
val currentQuery = MutableLiveData<String>()
private var runningSearches = 0
set(value) {
synchronized(runningSearches) {
field = value
isSearching.value = value > 0
}
}
@Synchronized
fun startSearch() {
synchronized(runningSearches) {
runningSearches++
}
}
}

View File

@ -3,7 +3,6 @@ package de.mm20.launcher2.search.data
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import de.mm20.launcher2.database.entities.WebsearchEntity import de.mm20.launcher2.database.entities.WebsearchEntity
import java.net.URLEncoder
class Websearch( class Websearch(
var urlTemplate: String, var urlTemplate: String,

View File

@ -41,7 +41,7 @@ dependencyResolutionManagement {
version("targetSdk", "32") version("targetSdk", "32")
} }
create("libs") { create("libs") {
version("kotlin", "1.7.0") version("kotlin", "1.6.21")
version("kotlinx.coroutines", "1.6.3") version("kotlinx.coroutines", "1.6.3")
alias("kotlin.stdlib") alias("kotlin.stdlib")
.to("org.jetbrains.kotlin", "kotlin-stdlib") .to("org.jetbrains.kotlin", "kotlin-stdlib")
@ -60,7 +60,7 @@ dependencyResolutionManagement {
listOf("kotlin.stdlib", "kotlinx.coroutines.core", "kotlinx.coroutines.android") listOf("kotlin.stdlib", "kotlinx.coroutines.core", "kotlinx.coroutines.android")
) )
version("androidx.compose", "1.2.0-rc01") version("androidx.compose", "1.2.0-rc02")
alias("androidx.compose.runtime") alias("androidx.compose.runtime")
.to("androidx.compose.runtime", "runtime") .to("androidx.compose.runtime", "runtime")
.versionRef("androidx.compose") .versionRef("androidx.compose")
@ -206,7 +206,7 @@ dependencyResolutionManagement {
.to("androidx.datastore", "datastore") .to("androidx.datastore", "datastore")
.version("1.0.0") .version("1.0.0")
version("androidx.room", "2.4.2") version("androidx.room", "2.5.0-alpha02")
alias("androidx.roomruntime") alias("androidx.roomruntime")
.to("androidx.room", "room-runtime") .to("androidx.room", "room-runtime")
.versionRef("androidx.room") .versionRef("androidx.room")

View File

@ -1,399 +0,0 @@
package de.mm20.launcher2.transition
import android.animation.*
import android.content.Context
import android.graphics.*
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.transition.Transition
import androidx.transition.TransitionValues
/**
* Transitions a TextView from one font size to another. This does not
* do any animation of TextView content and if the text changes, this
* transition will not run.
*
*
* The animation works by capturing a bitmap of the text at the startLegacy
* and end states. It then scales the startLegacy bitmap until it reaches
* a threshold and switches to the scaled end bitmap for the remainder
* of the animation. This keeps the jump in bitmaps in the middle of
* the animation, where it is less noticeable than at the beginning
* or end of the animation. This transition does not work well with
* cropped text. TextResize also does not work with changes in
* TextView gravity.
*/
class TextResize : Transition {
constructor() {
addTarget(TextView::class.java)
}
/**
* Constructor used from XML.
*/
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
addTarget(TextView::class.java)
}
override fun captureStartValues(transitionValues: TransitionValues) {
captureValues(transitionValues)
}
override fun captureEndValues(transitionValues: TransitionValues) {
captureValues(transitionValues)
}
override fun getTransitionProperties(): Array<String> {
return PROPERTIES
}
private fun captureValues(transitionValues: TransitionValues) {
if (transitionValues.view !is TextView) {
return
}
val view = transitionValues.view as TextView
val fontSize = view.textSize
transitionValues.values.put(FONT_SIZE, fontSize)
val data = TextResizeData(view)
transitionValues.values.put(DATA, data)
}
override fun createAnimator(sceneRoot: ViewGroup, startValues: TransitionValues?,
endValues: TransitionValues?): Animator? {
if (startValues == null || endValues == null) {
return null
}
val startData = startValues.values.get(DATA) as TextResizeData
val endData = endValues.values.get(DATA) as TextResizeData
if (startData.gravity != endData.gravity) {
return null // Can't deal with changes in gravity
}
val textView = endValues.view as TextView
var startFontSize = startValues.values.get(FONT_SIZE) as Float
// Capture the startLegacy bitmap -- we need to set the values to the startLegacy values first
setTextViewData(textView, startData, startFontSize)
val startWidth = textView.paint.measureText(textView.text.toString())
val startBitmap = captureTextBitmap(textView)
if (startBitmap == null) {
startFontSize = 0f
}
var endFontSize = endValues.values.get(FONT_SIZE) as Float
// Set the values to the end values
setTextViewData(textView, endData, endFontSize)
val endWidth = textView.paint.measureText(textView.text.toString())
// Capture the end bitmap
val endBitmap = captureTextBitmap(textView)
if (endBitmap == null) {
endFontSize = 0f
}
if (startFontSize == 0f && endFontSize == 0f) {
return null // Can't animate null bitmaps
}
// Set the colors of the TextView so that nothing is drawn.
// Only draw the bitmaps in the overlay.
val textColors = textView.textColors
val hintColors = textView.hintTextColors
val highlightColor = textView.highlightColor
val linkColors = textView.linkTextColors
textView.setTextColor(Color.TRANSPARENT)
textView.setHintTextColor(Color.TRANSPARENT)
textView.highlightColor = Color.TRANSPARENT
textView.setLinkTextColor(Color.TRANSPARENT)
if (startBitmap == null || endBitmap == null) return null
// Create the drawable that will be animated in the TextView's overlay.
// Ensure that it is showing the startLegacy state now.
val drawable = SwitchBitmapDrawable(textView, startData.gravity,
startBitmap, startFontSize, startWidth, endBitmap, endFontSize, endWidth)
textView.overlay.add(drawable)
// Properties: left, top, font size, text color
val leftProp = PropertyValuesHolder.ofFloat("left", startData.paddingLeft.toFloat(), endData.paddingLeft.toFloat())
val topProp = PropertyValuesHolder.ofFloat("top", startData.paddingTop.toFloat(), endData.paddingTop.toFloat())
val rightProp = PropertyValuesHolder.ofFloat("right",
(startData.width - startData.paddingRight).toFloat(), (endData.width - endData.paddingRight).toFloat())
val bottomProp = PropertyValuesHolder.ofFloat("bottom",
(startData.height - startData.paddingBottom).toFloat(), (endData.height - endData.paddingBottom).toFloat())
val fontSizeProp = PropertyValuesHolder.ofFloat("fontSize", startFontSize, endFontSize)
val animator: ObjectAnimator
if (startData.textColor != endData.textColor) {
val textColorProp = PropertyValuesHolder.ofObject("textColor",
ArgbEvaluator(), startData.textColor, endData.textColor)
animator = ObjectAnimator.ofPropertyValuesHolder(drawable,
leftProp, topProp, rightProp, bottomProp, fontSizeProp, textColorProp)
} else {
animator = ObjectAnimator.ofPropertyValuesHolder(drawable,
leftProp, topProp, rightProp, bottomProp, fontSizeProp)
}
val finalFontSize = endFontSize
val listener = object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
textView.overlay.remove(drawable)
textView.setTextColor(textColors)
textView.setHintTextColor(hintColors)
textView.highlightColor = highlightColor
textView.setLinkTextColor(linkColors)
}
override fun onAnimationPause(animation: Animator) {
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, drawable.fontSize)
val paddingLeft = Math.round(drawable.left)
val paddingTop = Math.round(drawable.top)
val fraction = animator.getAnimatedFraction()
val paddingRight = Math.round(interpolate(startData.paddingRight.toFloat(),
endData.paddingRight.toFloat(), fraction))
val paddingBottom = Math.round(interpolate(startData.paddingBottom.toFloat(),
endData.paddingBottom.toFloat(), fraction))
textView.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom)
textView.setTextColor(drawable.textColor)
}
override fun onAnimationResume(animation: Animator) {
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, finalFontSize)
textView.setPadding(endData.paddingLeft, endData.paddingTop,
endData.paddingRight, endData.paddingBottom)
textView.setTextColor(endData.textColor)
}
}
animator.addListener(listener)
animator.addPauseListener(listener)
return animator
}
/**
* This Drawable is used to scale the startLegacy and end bitmaps and switch between them
* at the appropriate progress.
*/
private class SwitchBitmapDrawable(private val view: TextView, gravity: Int,
private val startBitmap: Bitmap, private val startFontSize: Float, private val startWidth: Float,
private val endBitmap: Bitmap, private val endFontSize: Float, private val endWidth: Float) : Drawable() {
private val horizontalGravity: Int
private val verticalGravity: Int
private val paint = Paint()
/**
* @return The font size of the text in the displayed bitmap.
*/
/**
* Sets the font size that the text should be displayed at.
*
* @param fontSize The font size in pixels of the scaled bitmap text.
*/
var fontSize: Float = 0.toFloat()
set(fontSize) {
field = fontSize
invalidateSelf()
}
/**
* @return The left side of the text.
*/
/**
* Sets the left side of the text. This should be the same as the left padding.
*
* @param left The left side of the text in pixels.
*/
var left: Float = 0.toFloat()
set(left) {
field = left
invalidateSelf()
}
/**
* @return The top of the text.
*/
/**
* Sets the top of the text. This should be the same as the top padding.
*
* @param top The top of the text in pixels.
*/
var top: Float = 0.toFloat()
set(top) {
field = top
invalidateSelf()
}
/**
* @return The right side of the text.
*/
/**
* Sets the right of the drawable.
*
* @param right The right pixel of the drawn area.
*/
var right: Float = 0.toFloat()
set(right) {
field = right
invalidateSelf()
}
/**
* @return The bottom of the text.
*/
/**
* Sets the bottom of the drawable.
*
* @param bottom The bottom pixel of the drawn area.
*/
var bottom: Float = 0.toFloat()
set(bottom) {
field = bottom
invalidateSelf()
}
/**
* @return The color of the text being displayed.
*/
/**
* Sets the color of the text to be displayed.
*
* @param textColor The color of the text to be displayed.
*/
var textColor: Int = 0
set(textColor) {
field = textColor
colorFilter = PorterDuffColorFilter(textColor, PorterDuff.Mode.SRC_IN)
invalidateSelf()
}
override fun getOpacity(): Int {
return PixelFormat.TRANSLUCENT
}
init {
this.horizontalGravity = gravity and Gravity.HORIZONTAL_GRAVITY_MASK
this.verticalGravity = gravity and Gravity.VERTICAL_GRAVITY_MASK
}
override fun invalidateSelf() {
super.invalidateSelf()
view.invalidate()
}
override fun draw(canvas: Canvas) {
val saveCount = canvas.save()
// The threshold changes depending on the target font sizes. Because scaled-up
// fonts look bad, we want to switch when closer to the smaller font size. This
// algorithm ensures that null bitmaps (font size = 0) are never used.
val threshold = startFontSize / (startFontSize + endFontSize)
val fontSize = fontSize
val progress = (fontSize - startFontSize) / (endFontSize - startFontSize)
// The drawn text width is a more accurate scale than font size. This avoids
// jump when switching bitmaps.
val expectedWidth = interpolate(startWidth, endWidth, progress)
if (progress < threshold) {
// draw startLegacy bitmap
val scale = expectedWidth / startWidth
val tx = getTranslationPoint(horizontalGravity, this.left, this.right,
startBitmap.width.toFloat(), scale)
val ty = getTranslationPoint(verticalGravity, this.top, this.bottom,
startBitmap.height.toFloat(), scale)
canvas.translate(tx, ty)
canvas.scale(scale, scale)
canvas.drawBitmap(startBitmap, 0f, 0f, paint)
} else {
// draw end bitmap
val scale = expectedWidth / endWidth
val tx = getTranslationPoint(horizontalGravity, this.left, this.right,
endBitmap.width.toFloat(), scale)
val ty = getTranslationPoint(verticalGravity, this.top, this.bottom,
endBitmap.height.toFloat(), scale)
canvas.translate(tx, ty)
canvas.scale(scale, scale)
canvas.drawBitmap(endBitmap, 0f, 0f, paint)
}
canvas.restoreToCount(saveCount)
}
override fun setAlpha(alpha: Int) {}
override fun setColorFilter(colorFilter: ColorFilter?) {
paint.colorFilter = colorFilter
}
private fun getTranslationPoint(gravity: Int, start: Float, end: Float, dim: Float,
scale: Float): Float {
return when (gravity) {
Gravity.CENTER_HORIZONTAL, Gravity.CENTER_VERTICAL -> (start + end - dim * scale) / 2f
Gravity.RIGHT, Gravity.BOTTOM -> end - dim * scale
Gravity.LEFT, Gravity.TOP -> start
else -> start
}
}
}
/**
* Contains all the non-font-size data used by the TextResize transition.
* None of these values should trigger the transition, so they are not listed
* in PROPERTIES. These are captured together to avoid boxing of all the
* primitives while adding to TransitionValues.
*/
internal class TextResizeData(textView: TextView) {
val paddingLeft = textView.paddingLeft
val paddingTop = textView.paddingTop
val paddingRight = textView.paddingRight
val paddingBottom = textView.paddingBottom
val width = textView.width
val height = textView.height
val gravity = textView.gravity
val textColor = textView.currentTextColor
}
companion object {
private val FONT_SIZE = "TextResize:fontSize"
private val DATA = "TextResize:data"
private val PROPERTIES = arrayOf(
// We only care about FONT_SIZE. If anything else changes, we don't
// want this transition to be called to create an Animator.
FONT_SIZE)
private fun setTextViewData(view: TextView, data: TextResizeData, fontSize: Float) {
view.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize)
view.setPadding(data.paddingLeft, data.paddingTop, data.paddingRight, data.paddingBottom)
view.right = view.left + data.width
view.bottom = view.top + data.height
view.setTextColor(data.textColor)
val widthSpec = View.MeasureSpec.makeMeasureSpec(view.width, View.MeasureSpec.EXACTLY)
val heightSpec = View.MeasureSpec.makeMeasureSpec(view.height, View.MeasureSpec.EXACTLY)
view.measure(widthSpec, heightSpec)
view.layout(view.left, view.top, view.right, view.bottom)
}
private fun captureTextBitmap(textView: TextView): Bitmap? {
val background = textView.background
textView.background = null
val width = textView.width - textView.paddingLeft - textView.paddingRight
val height = textView.height - textView.paddingTop - textView.paddingBottom
if (width <= 0 || height <= 0) {
return null
}
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
canvas.translate((-textView.paddingLeft).toFloat(), (-textView.paddingTop).toFloat())
textView.draw(canvas)
textView.background = background
return bitmap
}
private fun interpolate(start: Float, end: Float, fraction: Float): Float {
return start + fraction * (end - start)
}
}
}

View File

@ -3,7 +3,6 @@ package de.mm20.launcher2.ui.animation
import androidx.compose.animation.core.* import androidx.compose.animation.core.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.ExperimentalUnitApi import androidx.compose.ui.unit.ExperimentalUnitApi
import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType import androidx.compose.ui.unit.TextUnitType

View File

@ -27,7 +27,7 @@ import de.mm20.launcher2.ui.component.BottomSheetDialog
import de.mm20.launcher2.ui.component.LargeMessage import de.mm20.launcher2.ui.component.LargeMessage
import de.mm20.launcher2.ui.component.SmallMessage import de.mm20.launcher2.ui.component.SmallMessage
@OptIn(ExperimentalComposeUiApi::class, ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun RestoreBackupSheet( fun RestoreBackupSheet(
uri: Uri, uri: Uri,

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.ui.component package de.mm20.launcher2.ui.component
import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable

View File

@ -42,6 +42,7 @@ import de.mm20.launcher2.ui.locals.LocalDarkTheme
import palettes.TonalPalette import palettes.TonalPalette
import java.time.Instant import java.time.Instant
import java.time.ZoneId import java.time.ZoneId
import kotlin.math.abs
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -389,12 +390,12 @@ private val SquircleShape: Shape
for (x in -radius.roundToInt()..radius.roundToInt()) for (x in -radius.roundToInt()..radius.roundToInt())
lineTo( lineTo(
x.toFloat(), x.toFloat(),
Math.cbrt(radiusToPow - Math.abs(x * x * x)).toFloat() Math.cbrt(radiusToPow - abs(x * x * x)).toFloat()
) )
for (x in radius.roundToInt() downTo -radius.roundToInt()) for (x in radius.roundToInt() downTo -radius.roundToInt())
lineTo( lineTo(
x.toFloat(), x.toFloat(),
(-Math.cbrt(radiusToPow - Math.abs(x * x * x))).toFloat() (-Math.cbrt(radiusToPow - abs(x * x * x))).toFloat()
) )
translate(Offset(size.width / 2f, size.height / 2f)) translate(Offset(size.width / 2f, size.height / 2f))
} }

View File

@ -3,7 +3,6 @@ package de.mm20.launcher2.ui.component.preferences
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Switch import androidx.compose.material3.Switch
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.ui.component.preferences package de.mm20.launcher2.ui.component.preferences
import androidx.compose.material3.Switch import androidx.compose.material3.Switch
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector

View File

@ -613,6 +613,7 @@ private fun Precipitation(icon: WeatherIcon) {
tint = colorResource(id = R.color.weather_snow) tint = colorResource(id = R.color.weather_snow)
) )
} }
else -> {}
} }
} }
} }

View File

@ -181,14 +181,6 @@ class LauncherActivity : BaseActivity() {
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
} }
override fun onResume() {
super.onResume()
/*binding.container.doOnNextLayout {
WallpaperManager.getInstance(this).setWallpaperOffsets(it.windowToken, 0.5f, 0.5f)
}*/
}
override fun onNewIntent(intent: Intent?) { override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent) super.onNewIntent(intent)
val navContract = intent?.let { GestureNavContract.fromIntent(it) } val navContract = intent?.let { GestureNavContract.fromIntent(it) }

View File

@ -6,7 +6,7 @@ import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.slideIn import androidx.compose.animation.slideIn
import androidx.compose.animation.slideOut import androidx.compose.animation.slideOut
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.LocalOverScrollConfiguration import androidx.compose.foundation.LocalOverscrollConfiguration
import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
@ -46,8 +46,7 @@ import de.mm20.launcher2.ui.utils.rememberNotificationShadeController
import kotlin.math.roundToInt import kotlin.math.roundToInt
@OptIn( @OptIn(
ExperimentalMaterialApi::class, ExperimentalMaterialApi::class, ExperimentalFoundationApi::class
ExperimentalFoundationApi::class
) )
@Composable @Composable
fun PagerScaffold( fun PagerScaffold(
@ -216,7 +215,7 @@ fun PagerScaffold(
CompositionLocalProvider( CompositionLocalProvider(
LocalOverScrollConfiguration provides null LocalOverscrollConfiguration provides null
) { ) {
Row( Row(

View File

@ -7,7 +7,7 @@ import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.slideIn import androidx.compose.animation.slideIn
import androidx.compose.animation.slideOut import androidx.compose.animation.slideOut
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.LocalOverScrollConfiguration import androidx.compose.foundation.LocalOverscrollConfiguration
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
@ -231,7 +231,7 @@ fun PullDownScaffold(
derivedStateOf { maxHeight } derivedStateOf { maxHeight }
} }
CompositionLocalProvider( CompositionLocalProvider(
LocalOverScrollConfiguration provides null LocalOverscrollConfiguration provides null
) { ) {
val offset by animateFloatAsState(if (isSearchOpen) 1f else 0f) val offset by animateFloatAsState(if (isSearchOpen) 1f else 0f)
Column( Column(

View File

@ -1,9 +1,6 @@
package de.mm20.launcher2.ui.launcher.modals package de.mm20.launcher2.ui.launcher.modals
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import de.mm20.launcher2.favorites.FavoritesItem import de.mm20.launcher2.favorites.FavoritesItem
import de.mm20.launcher2.favorites.FavoritesRepository import de.mm20.launcher2.favorites.FavoritesRepository
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent

View File

@ -3,19 +3,13 @@ package de.mm20.launcher2.ui.launcher.modals
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Edit import androidx.compose.material.icons.rounded.Edit
import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource

View File

@ -3,11 +3,7 @@ package de.mm20.launcher2.ui.launcher.modals
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import de.mm20.launcher2.favorites.FavoritesRepository
import de.mm20.launcher2.ui.settings.SettingsActivity import de.mm20.launcher2.ui.settings.SettingsActivity
import kotlinx.coroutines.flow.map
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class HiddenItemsSheetVM: ViewModel() { class HiddenItemsSheetVM: ViewModel() {

View File

@ -1,21 +1,9 @@
package de.mm20.launcher2.ui.launcher.search package de.mm20.launcher2.ui.launcher.search
import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.Column
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.VisibilityOff
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
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.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.ui.launcher.LauncherActivityVM
import de.mm20.launcher2.ui.launcher.search.apps.AppResults import de.mm20.launcher2.ui.launcher.search.apps.AppResults
import de.mm20.launcher2.ui.launcher.search.appshortcuts.AppShortcutResults import de.mm20.launcher2.ui.launcher.search.appshortcuts.AppShortcutResults
import de.mm20.launcher2.ui.launcher.search.calculator.CalculatorResults import de.mm20.launcher2.ui.launcher.search.calculator.CalculatorResults
@ -29,7 +17,6 @@ import de.mm20.launcher2.ui.launcher.search.website.WebsiteResults
import de.mm20.launcher2.ui.launcher.search.wikipedia.WikipediaResults import de.mm20.launcher2.ui.launcher.search.wikipedia.WikipediaResults
import de.mm20.launcher2.ui.layout.BottomReversed import de.mm20.launcher2.ui.layout.BottomReversed
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun SearchColumn( fun SearchColumn(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,

View File

@ -37,7 +37,6 @@ import kotlin.math.min
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.roundToInt import kotlin.math.roundToInt
@OptIn(ExperimentalMaterialApi::class)
@Composable @Composable
fun AppItem( fun AppItem(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,

View File

@ -1,4 +1,4 @@
package de.mm20.launcher2.ui.search package de.mm20.launcher2.ui.launcher.search.calculator
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth

View File

@ -11,7 +11,6 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.ui.component.LauncherCard import de.mm20.launcher2.ui.component.LauncherCard
import de.mm20.launcher2.ui.launcher.search.SearchVM import de.mm20.launcher2.ui.launcher.search.SearchVM
import de.mm20.launcher2.ui.search.CalculatorItem
@Composable @Composable
fun ColumnScope.CalculatorResults(reverse: Boolean = false) { fun ColumnScope.CalculatorResults(reverse: Boolean = false) {

View File

@ -109,7 +109,7 @@ fun GridItem(modifier: Modifier = Modifier, item: Searchable, showLabels: Boolea
} }
} }
@OptIn(ExperimentalComposeUiApi::class, ExperimentalAnimationApi::class) @OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
fun ItemPopup(origin: Rect, searchable: Searchable, onDismissRequest: () -> Unit) { fun ItemPopup(origin: Rect, searchable: Searchable, onDismissRequest: () -> Unit) {
var show by remember { mutableStateOf(false) } var show by remember { mutableStateOf(false) }

View File

@ -1,19 +1,8 @@
package de.mm20.launcher2.ui.launcher.search.common.grid package de.mm20.launcher2.ui.launcher.search.common.grid
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.toAndroidRect
import androidx.core.app.ActivityOptionsCompat
import de.mm20.launcher2.badges.BadgeRepository
import de.mm20.launcher2.favorites.FavoritesRepository
import de.mm20.launcher2.icons.IconRepository
import de.mm20.launcher2.icons.LauncherIcon
import de.mm20.launcher2.search.data.Searchable import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
import kotlinx.coroutines.flow.Flow
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class GridItemVM( class GridItemVM(
private val searchable: Searchable searchable: Searchable
): SearchableItemVM(searchable) ): SearchableItemVM(searchable)

View File

@ -16,7 +16,7 @@ import de.mm20.launcher2.ui.launcher.search.contacts.ContactItem
import de.mm20.launcher2.ui.launcher.search.files.FileItem import de.mm20.launcher2.ui.launcher.search.files.FileItem
import de.mm20.launcher2.ui.launcher.search.shortcut.AppShortcutItem import de.mm20.launcher2.ui.launcher.search.shortcut.AppShortcutItem
@OptIn(ExperimentalMaterialApi::class, androidx.compose.foundation.ExperimentalFoundationApi::class) @OptIn(androidx.compose.foundation.ExperimentalFoundationApi::class)
@Composable @Composable
fun ListItem(modifier: Modifier = Modifier, item: Searchable) { fun ListItem(modifier: Modifier = Modifier, item: Searchable) {
var showDetails by remember { mutableStateOf(false) } var showDetails by remember { mutableStateOf(false) }

View File

@ -4,6 +4,5 @@ import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
class ListItemVM( class ListItemVM(
private val searchable: Searchable searchable: Searchable
): SearchableItemVM(searchable) { ): SearchableItemVM(searchable)
}

View File

@ -43,7 +43,6 @@ import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
import de.mm20.launcher2.ui.modifier.scale import de.mm20.launcher2.ui.modifier.scale
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@OptIn(ExperimentalUnitApi::class)
@Composable @Composable
fun ContactItem( fun ContactItem(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,

View File

@ -38,7 +38,6 @@ import kotlinx.coroutines.launch
import java.text.DecimalFormat import java.text.DecimalFormat
import kotlin.math.roundToInt import kotlin.math.roundToInt
@OptIn(ExperimentalUnitApi::class)
@Composable @Composable
fun FileItem( fun FileItem(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,

View File

@ -40,7 +40,6 @@ import kotlinx.coroutines.launch
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.roundToInt import kotlin.math.roundToInt
@OptIn(ExperimentalMaterialApi::class)
@Composable @Composable
fun AppShortcutItem( fun AppShortcutItem(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,

View File

@ -1,9 +1,8 @@
package de.mm20.launcher2.ui.search package de.mm20.launcher2.ui.launcher.search.unitconverter
import android.icu.text.DateFormat import android.icu.text.DateFormat
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.* import androidx.compose.material.icons.rounded.*
import androidx.compose.material3.* import androidx.compose.material3.*
@ -12,11 +11,9 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import de.mm20.launcher2.search.data.CurrencyUnitConverter import de.mm20.launcher2.search.data.CurrencyUnitConverter
import de.mm20.launcher2.search.data.UnitConverter import de.mm20.launcher2.search.data.UnitConverter
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R

View File

@ -11,7 +11,6 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.ui.component.LauncherCard import de.mm20.launcher2.ui.component.LauncherCard
import de.mm20.launcher2.ui.launcher.search.SearchVM import de.mm20.launcher2.ui.launcher.search.SearchVM
import de.mm20.launcher2.ui.search.UnitConverterItem
@Composable @Composable
fun ColumnScope.UnitConverterResults(reverse: Boolean = false) { fun ColumnScope.UnitConverterResults(reverse: Boolean = false) {

View File

@ -1,6 +1,5 @@
package de.mm20.launcher2.ui.launcher.transitions package de.mm20.launcher2.ui.launcher.transitions
import android.content.ComponentName
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import com.android.launcher3.GestureNavContract import com.android.launcher3.GestureNavContract

View File

@ -1,9 +1,6 @@
package de.mm20.launcher2.ui.launcher.transitions package de.mm20.launcher2.ui.launcher.transitions
import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.toAndroidRectF import androidx.compose.ui.graphics.toAndroidRectF
import com.android.launcher3.GestureNavContract import com.android.launcher3.GestureNavContract
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow

View File

@ -16,7 +16,6 @@ import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Add import androidx.compose.material.icons.rounded.Add
import androidx.compose.material3.* import androidx.compose.material3.*
@ -36,7 +35,7 @@ import androidx.compose.ui.window.Dialog
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.repeatOnLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.ui.ClockWidget import de.mm20.launcher2.ui.launcher.widgets.clock.ClockWidget
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.ktx.animateTo import de.mm20.launcher2.ui.ktx.animateTo
import de.mm20.launcher2.ui.launcher.widgets.picker.PickAppWidgetActivity import de.mm20.launcher2.ui.launcher.widgets.picker.PickAppWidgetActivity

View File

@ -145,7 +145,7 @@ fun CalendarWidget() {
) )
} }
val pinnedEvents by viewModel.pinnedCalendarEvents.observeAsState(emptyList()) val pinnedEvents by viewModel.pinnedCalendarEvents.observeAsState(emptyList())
if (pinnedEvents.size > 0) { if (pinnedEvents.isNotEmpty()) {
Text( Text(
stringResource(R.string.calendar_widget_pinned_events), stringResource(R.string.calendar_widget_pinned_events),
modifier = Modifier.padding(start = 4.dp, end = 4.dp, top = 8.dp, bottom = 4.dp), modifier = Modifier.padding(start = 4.dp, end = 4.dp, top = 8.dp, bottom = 4.dp),

View File

@ -1,4 +1,4 @@
package de.mm20.launcher2.ui package de.mm20.launcher2.ui.launcher.widgets.clock
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -19,7 +19,6 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockStyle import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockStyle
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout
import de.mm20.launcher2.ui.base.LocalTime import de.mm20.launcher2.ui.base.LocalTime
import de.mm20.launcher2.ui.launcher.widgets.clock.ClockWidgetVM
import de.mm20.launcher2.ui.launcher.widgets.clock.clocks.* import de.mm20.launcher2.ui.launcher.widgets.clock.clocks.*
import de.mm20.launcher2.ui.launcher.widgets.clock.parts.PartProvider import de.mm20.launcher2.ui.launcher.widgets.clock.parts.PartProvider

View File

@ -2,7 +2,6 @@ package de.mm20.launcher2.ui.launcher.widgets.clock.parts
import android.content.Context import android.content.Context
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow

View File

@ -33,7 +33,7 @@ fun AppWidgetList(
modifier = modifier modifier = modifier
) { ) {
for (group in widgets) { for (group in widgets) {
item() { item {
Text( Text(
modifier = Modifier.padding( modifier = Modifier.padding(
top = 16.dp, top = 16.dp,

View File

@ -10,6 +10,7 @@ import androidx.activity.compose.setContent
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ArrowBack import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material3.* import androidx.compose.material3.*
@ -67,7 +68,7 @@ class PickAppWidgetActivity : BaseActivity() {
if (selected == null) { if (selected == null) {
if (widgets != null) { if (widgets != null) {
AppWidgetList( AppWidgetList(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize().padding(it),
widgets = widgets, widgets = widgets,
onWidgetSelected = { onWidgetSelected = {
selectAppWidget(it) selectAppWidget(it)
@ -75,7 +76,7 @@ class PickAppWidgetActivity : BaseActivity() {
) )
} else { } else {
Box( Box(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize().padding(it),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
CircularProgressIndicator() CircularProgressIndicator()

View File

@ -39,7 +39,6 @@ import java.text.DecimalFormat
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import kotlin.math.roundToInt import kotlin.math.roundToInt
@OptIn(ExperimentalAnimationApi::class)
@Composable @Composable
fun WeatherWidget() { fun WeatherWidget() {
val viewModel: WeatherWidgetWM = viewModel() val viewModel: WeatherWidgetWM = viewModel()

View File

@ -1,22 +0,0 @@
package de.mm20.launcher2.ui.legacy.helper
import android.graphics.*
import android.util.LruCache
import androidx.annotation.MainThread
/**
* Helper object to store temporary bitmaps to draw on so they don't have to be allocated every
* time and can be reused by different classes and methods.
*/
object BitmapHolder {
private val cache = LruCache<Int, Pair<Bitmap, Canvas>>(8)
@MainThread
fun getBitmapAndCanvas(size: Int): Pair<Bitmap, Canvas> {
return cache[size]?.apply { second.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR) }
?: Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888).let {
Pair(it, Canvas(it)).also { pair -> cache.put(size, pair) }
}
}
}

View File

@ -1,137 +0,0 @@
package de.mm20.launcher2.ui.legacy.view
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.os.BatteryManager
import android.util.AttributeSet
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.*
import de.mm20.launcher2.ktx.dp
import java.util.*
class BatteryChargingView : View, DefaultLifecycleObserver {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleRes: Int) : super(context, attrs, defStyleRes)
private var animating = false
private val activity = context as AppCompatActivity
init {
activity.lifecycle.addObserver(this)
}
private val batteryReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action != Intent.ACTION_BATTERY_CHANGED) return
update(intent, true)
}
}
override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
val intent = activity.registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
start()
intent?.let { update(it, true) }
}
override fun onPause(owner: LifecycleOwner) {
super.onPause(owner)
stop()
try {
activity.unregisterReceiver(batteryReceiver)
} catch (e: IllegalArgumentException) {
}
}
private fun update(intent: Intent, retryOnZeroCurrent: Boolean = false) {
val status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
val charging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL
if (charging) {
val bm = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val current = bm.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_NOW)
if (current <= 0) {
intensity = 5
start()
//Workaround for delayed current updates
if (retryOnZeroCurrent) postDelayed({ update(intent) }, 1000)
return
}
intensity = Math.round(current / 100000f).takeIf { it > 0 } ?: 1
start()
} else {
intensity = 0
}
}
var intensity = 0
set(value) {
if (field == 0 && value > 0) start()
if (value == 0) stop()
field = when {
value > 100 -> 100
value < 0 -> 0
else -> value
}
for (i in field until bubbles.size) {
bubbles.pop()
}
for (i in bubbles.size until field) {
bubbles.push(FloatArray(6) { 0f })
}
}
fun start() {
if (animating || intensity == 0) return
animating = true
invalidate()
}
fun stop() {
animating = false
}
/**
* 0: Pos X
* 1: Pos Y
* 2: Delta X
* 3: Delta Y
* 4: Radius
* 5: Lifetime left
*/
private var bubbles = ArrayDeque<FloatArray>()
private val paint = Paint()
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (!animating) return
for (b in bubbles) {
if (b[5] <= 0f) {
b[0] = (Math.random() * width).toFloat()
b[1] = height.toFloat()
b[2] = ((Math.random() - 0.5) * width / 120f).toFloat() * dp
b[3] = -(Math.random() * height / 90f).toFloat() * dp
b[4] = (Math.random() * 2 + 2).toFloat() * dp
b[5] = (Math.random() * 80 + 40).toInt().toFloat()
}
paint.color = Color.argb((b[5] / 120f * 120).toInt(), 255, 255, 255)
canvas.drawCircle(b[0], b[1], b[4], paint)
b[0] += b[2]
b[1] += b[3]
b[5]--
}
postInvalidate()
}
}

View File

@ -1,15 +0,0 @@
package de.mm20.launcher2.ui.settings
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class SettingsActivityVM: ViewModel(), KoinComponent {
}

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.ui.settings.accounts package de.mm20.launcher2.ui.settings.accounts
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope

View File

@ -318,7 +318,6 @@ fun SearchBarStylePreference(
} }
} }
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun IconShapePreference( fun IconShapePreference(
title: String, title: String,

View File

@ -1,6 +1,5 @@
package de.mm20.launcher2.ui.settings.backup package de.mm20.launcher2.ui.settings.backup
import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.runtime.* import androidx.compose.runtime.*

View File

@ -1,19 +1,9 @@
package de.mm20.launcher2.ui.settings.backup package de.mm20.launcher2.ui.settings.backup
import android.content.Context
import android.content.Intent
import android.net.Uri import android.net.Uri
import androidx.core.content.FileProvider
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.backup.BackupManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.io.File
class BackupSettingsScreenVM : ViewModel(), KoinComponent { class BackupSettingsScreenVM : ViewModel(), KoinComponent {

View File

@ -1,17 +1,12 @@
package de.mm20.launcher2.ui.settings.buildinfo package de.mm20.launcher2.ui.settings.buildinfo
import android.content.pm.PackageManager
import android.os.Build
import android.util.Base64
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import de.mm20.launcher2.accounts.AccountType import de.mm20.launcher2.accounts.AccountType
import de.mm20.launcher2.accounts.AccountsRepository import de.mm20.launcher2.accounts.AccountsRepository
import de.mm20.launcher2.preferences.Settings.WeatherSettings.WeatherProvider import de.mm20.launcher2.preferences.Settings.WeatherSettings.WeatherProvider
import de.mm20.launcher2.weather.WeatherRepository import de.mm20.launcher2.weather.WeatherRepository
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.inject import org.koin.core.component.inject
import java.security.MessageDigest
class BuildInfoSettingsScreenVM : ViewModel(), KoinComponent { class BuildInfoSettingsScreenVM : ViewModel(), KoinComponent {
private val accountsRepository: AccountsRepository by inject() private val accountsRepository: AccountsRepository by inject()

View File

@ -20,7 +20,7 @@ import com.google.accompanist.pager.HorizontalPagerIndicator
import com.google.accompanist.pager.rememberPagerState import com.google.accompanist.pager.rememberPagerState
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockStyle import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockStyle
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout
import de.mm20.launcher2.ui.Clock import de.mm20.launcher2.ui.launcher.widgets.clock.Clock
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.preferences.* import de.mm20.launcher2.ui.component.preferences.*

View File

@ -2,7 +2,6 @@ package de.mm20.launcher2.ui.settings.crashreporter
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.crashreporter.BuildConfig import de.mm20.launcher2.crashreporter.BuildConfig
import de.mm20.launcher2.crashreporter.CrashReport import de.mm20.launcher2.crashreporter.CrashReport

View File

@ -4,8 +4,6 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.preferences.LauncherDataStore import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.preferences.Settings.IconSettings.IconShape
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent

View File

@ -82,7 +82,7 @@ fun HiddenItemsSettingsScreen() {
DropdownMenuItem( DropdownMenuItem(
text = { Text(stringResource(R.string.menu_app_info)) }, text = { Text(stringResource(R.string.menu_app_info)) },
onClick = { onClick = {
viewModel.openAppInfo(context, searchable as Application) viewModel.openAppInfo(context, searchable)
showPopup = false showPopup = false
}) })

View File

@ -1,17 +1,9 @@
package de.mm20.launcher2.ui.settings.websearch package de.mm20.launcher2.ui.settings.websearch
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri import android.net.Uri
import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.scale
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import coil.imageLoader
import coil.request.ImageRequest
import coil.size.Scale
import de.mm20.launcher2.search.WebsearchRepository import de.mm20.launcher2.search.WebsearchRepository
import de.mm20.launcher2.search.data.Websearch import de.mm20.launcher2.search.data.Websearch
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -20,7 +12,6 @@ import kotlinx.coroutines.withContext
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.inject import org.koin.core.component.inject
import java.io.File import java.io.File
import java.io.FileOutputStream
class WebSearchSettingsScreenVM: ViewModel(), KoinComponent { class WebSearchSettingsScreenVM: ViewModel(), KoinComponent {
private val repository: WebsearchRepository by inject() private val repository: WebsearchRepository by inject()

View File

@ -2,7 +2,6 @@ package de.mm20.launcher2.unitconverter
import de.mm20.launcher2.currencies.CurrencyRepository import de.mm20.launcher2.currencies.CurrencyRepository
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module
val unitConverterModule = module { val unitConverterModule = module {

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.websites package de.mm20.launcher2.websites
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module
val websitesModule = module { val websitesModule = module {

View File

@ -94,8 +94,8 @@ internal class WebsiteRepositoryImpl(val context: Context) : WebsiteRepository,
if (favicon.isBlank()) favicon = doc.select("link[rel=icon]").attr("href") if (favicon.isBlank()) favicon = doc.select("link[rel=icon]").attr("href")
if (favicon.isBlank()) favicon = if (favicon.isBlank()) favicon =
doc.head().select("link[href~=.*\\.(ico|png)]").attr("href") doc.head().select("link[href~=.*\\.(ico|png)]").attr("href")
if (!favicon.isBlank()) favicon = resolveUrl(response.request.url, favicon) if (favicon.isNotBlank()) favicon = resolveUrl(response.request.url, favicon)
if (!image.isBlank()) image = resolveUrl(response.request.url, image) if (image.isNotBlank()) image = resolveUrl(response.request.url, image)
return@withContext Website( return@withContext Website(
label = title, label = title,
url = url, url = url,

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.widgets package de.mm20.launcher2.widgets
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module
val widgetsModule = module { val widgetsModule = module {

View File

@ -7,7 +7,6 @@ import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import de.mm20.launcher2.icons.ColorLayer import de.mm20.launcher2.icons.ColorLayer
import de.mm20.launcher2.icons.StaticIconLayer
import de.mm20.launcher2.icons.StaticLauncherIcon import de.mm20.launcher2.icons.StaticLauncherIcon
import de.mm20.launcher2.icons.TintedIconLayer import de.mm20.launcher2.icons.TintedIconLayer
import de.mm20.launcher2.wikipedia.R import de.mm20.launcher2.wikipedia.R
@ -43,8 +42,4 @@ class Wikipedia(
intent.intent.data = Uri.parse(uri) intent.intent.data = Uri.parse(uri)
return intent.intent return intent.intent
} }
companion object {
}
} }

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.wikipedia package de.mm20.launcher2.wikipedia
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module
val wikipediaModule = module { val wikipediaModule = module {