Clean up
This commit is contained in:
parent
26995c1141
commit
96e70da913
@ -9,8 +9,6 @@ import de.mm20.launcher2.owncloud.OwncloudClient
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
interface AccountsRepository {
|
||||
@ -26,7 +24,7 @@ interface AccountsRepository {
|
||||
}
|
||||
|
||||
internal class AccountsRepositoryImpl(
|
||||
private val context: Context
|
||||
context: Context
|
||||
) : AccountsRepository {
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@ package de.mm20.launcher2.debug
|
||||
|
||||
import android.os.StrictMode
|
||||
import android.util.Log
|
||||
import de.mm20.launcher2.BuildConfig
|
||||
|
||||
class Debug {
|
||||
init {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package de.mm20.launcher2.activity;
|
||||
package de.mm20.launcher2.activity
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.applications
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val applicationsModule = module {
|
||||
|
||||
@ -4,5 +4,5 @@ import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.dsl.module
|
||||
|
||||
val backupModule = module {
|
||||
single<BackupManager> { BackupManager(androidContext(), get(), get(), get(), get()) }
|
||||
single { BackupManager(androidContext(), get(), get(), get(), get()) }
|
||||
}
|
||||
@ -1,8 +1,6 @@
|
||||
package de.mm20.launcher2.badges.providers
|
||||
|
||||
import android.util.Log
|
||||
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.Searchable
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@ -4,7 +4,6 @@ import de.mm20.launcher2.applications.AppRepository
|
||||
import de.mm20.launcher2.badges.Badge
|
||||
import de.mm20.launcher2.badges.R
|
||||
import de.mm20.launcher2.search.data.Application
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import de.mm20.launcher2.search.data.Searchable
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,5 @@
|
||||
package de.mm20.launcher2.icons
|
||||
|
||||
import android.content.res.Resources
|
||||
|
||||
sealed interface LauncherIcon
|
||||
|
||||
data class StaticLauncherIcon(
|
||||
|
||||
@ -48,7 +48,7 @@ class Calculator(
|
||||
}
|
||||
formattedOctString = s.toString()
|
||||
|
||||
s = StringBuffer(solution.roundToInt().toString(16).toUpperCase())
|
||||
s = StringBuffer(solution.roundToInt().toString(16).uppercase(Locale.getDefault()))
|
||||
while (s.length % 2 != 0) {
|
||||
s = s.insert(0, '0')
|
||||
}
|
||||
@ -62,7 +62,7 @@ class Calculator(
|
||||
|
||||
fun getBeatifiedTerm(): String {
|
||||
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]+"))) {
|
||||
return term.substring(2) + "₂"
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.calendar
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val calendarModule = module {
|
||||
|
||||
@ -3,16 +3,10 @@ package de.mm20.launcher2.search.data
|
||||
import android.content.ContentUris
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.provider.CalendarContract
|
||||
import de.mm20.launcher2.graphics.TextDrawable
|
||||
import de.mm20.launcher2.icons.ColorLayer
|
||||
import de.mm20.launcher2.icons.StaticLauncherIcon
|
||||
import de.mm20.launcher2.icons.TextLayer
|
||||
import de.mm20.launcher2.ktx.dp
|
||||
import palettes.TonalPalette
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
class CalendarEvent(
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.contacts
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val contactsModule = module {
|
||||
|
||||
@ -9,7 +9,6 @@ import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.balsikandar.crashreporter.utils.AppUtilsKt.getAppSignature;
|
||||
|
||||
@ -68,26 +67,6 @@ public class AppUtils {
|
||||
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) {
|
||||
try {
|
||||
PackageInfo packageInfo = context.getPackageManager()
|
||||
|
||||
@ -31,7 +31,7 @@ class CurrencyRepository(
|
||||
toCurrency: String? = null
|
||||
): List<Pair<String, Double>> {
|
||||
|
||||
return withContext<List<Pair<String, Double>>>(Dispatchers.IO) {
|
||||
return withContext(Dispatchers.IO) {
|
||||
val dao = AppDatabase.getInstance(context)
|
||||
.currencyDao()
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ android {
|
||||
|
||||
javaCompileOptions {
|
||||
annotationProcessorOptions {
|
||||
arguments.put("room.schemaLocation", "$projectDir/schemas")
|
||||
arguments["room.schemaLocation"] = "$projectDir/schemas"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
@file:Suppress("ClassName")
|
||||
|
||||
package de.mm20.launcher2.database
|
||||
|
||||
import android.content.Context
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package de.mm20.launcher2.database
|
||||
|
||||
import android.content.ComponentName
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.*
|
||||
import de.mm20.launcher2.database.entities.IconEntity
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
package de.mm20.launcher2.database
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy.REPLACE
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.*
|
||||
import de.mm20.launcher2.database.entities.ForecastEntity
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@ -13,7 +9,7 @@ interface WeatherDao {
|
||||
@Query("SELECT * FROM ${ForecastEntity.TABLE_NAME} ORDER BY timestamp ASC")
|
||||
fun getForecasts(): Flow<List<ForecastEntity>>
|
||||
|
||||
@Insert(onConflict = REPLACE)
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertAll(forecasts: List<ForecastEntity>)
|
||||
|
||||
@Query("DELETE FROM ${ForecastEntity.TABLE_NAME}")
|
||||
|
||||
@ -1,12 +1,8 @@
|
||||
package de.mm20.launcher2.favorites
|
||||
|
||||
import android.content.Context
|
||||
import de.mm20.launcher2.database.entities.FavoritesItemEntity
|
||||
import de.mm20.launcher2.search.SearchableSerializer
|
||||
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(
|
||||
val key: String,
|
||||
|
||||
@ -1,19 +1,5 @@
|
||||
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.dsl.module
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.files
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val filesModule = module {
|
||||
|
||||
@ -6,7 +6,6 @@ import android.os.Build
|
||||
import android.os.CancellationSignal
|
||||
import android.provider.MediaStore
|
||||
import android.util.Size
|
||||
import androidx.core.content.ContentResolverCompat
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ abstract class File(
|
||||
}
|
||||
}
|
||||
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(
|
||||
R.string.file_type_launcherbackup,
|
||||
context.getString(R.string.app_name)
|
||||
|
||||
@ -4,10 +4,6 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
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(
|
||||
val fileId: String,
|
||||
|
||||
@ -114,8 +114,8 @@ open class LocalFile(
|
||||
val icon = withContext(Dispatchers.IO) {
|
||||
pkgInfo?.applicationInfo?.loadIcon(context.packageManager)
|
||||
} ?: return null
|
||||
when {
|
||||
icon is AdaptiveIconDrawable -> {
|
||||
when (icon) {
|
||||
is AdaptiveIconDrawable -> {
|
||||
return StaticLauncherIcon(
|
||||
foregroundLayer = icon.foreground?.let {
|
||||
StaticIconLayer(
|
||||
|
||||
@ -3,10 +3,7 @@ package de.mm20.launcher2.search.data
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import de.mm20.launcher2.msservices.DriveItem
|
||||
import de.mm20.launcher2.files.R
|
||||
import de.mm20.launcher2.msservices.MicrosoftGraphApiHelper
|
||||
import de.mm20.launcher2.icons.LauncherIcon
|
||||
|
||||
class OneDriveFile(
|
||||
val fileId: String,
|
||||
|
||||
@ -4,8 +4,6 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import de.mm20.launcher2.files.R
|
||||
import de.mm20.launcher2.helper.NetworkUtils
|
||||
import de.mm20.launcher2.owncloud.OwncloudClient
|
||||
|
||||
class OwncloudFile(
|
||||
fileId: Long,
|
||||
|
||||
@ -26,7 +26,7 @@ data class DriveFile(
|
||||
width = file.imageMediaMetadata?.width ?: file.videoMediaMetadata?.width,
|
||||
height = file.imageMediaMetadata?.height ?: file.videoMediaMetadata?.height
|
||||
),
|
||||
directoryColor = file.folderColorRgb?.toLowerCase(Locale.ROOT),
|
||||
directoryColor = file.folderColorRgb.lowercase(Locale.ROOT),
|
||||
viewUri = file.webViewLink ?: ""
|
||||
)
|
||||
}
|
||||
|
||||
@ -69,10 +69,10 @@ class GoogleClockIconProvider(val context: Context) : IconProvider {
|
||||
}
|
||||
ClockSublayer(
|
||||
drawable = drw,
|
||||
role = when {
|
||||
it == hourLayer -> ClockSublayerRole.Hour
|
||||
it == minuteLayer -> ClockSublayerRole.Minute
|
||||
it == secondLayer -> ClockSublayerRole.Second
|
||||
role = when (it) {
|
||||
hourLayer -> ClockSublayerRole.Hour
|
||||
minuteLayer -> ClockSublayerRole.Minute
|
||||
secondLayer -> ClockSublayerRole.Second
|
||||
else -> ClockSublayerRole.Static
|
||||
}
|
||||
)
|
||||
|
||||
@ -44,8 +44,8 @@ class IconPackIconProvider(
|
||||
val resId = res.getIdentifier(drawableName, "drawable", iconPack).takeIf { it != 0 }
|
||||
?: return generateIcon(context, searchable.launcherActivityInfo, size)
|
||||
val drawable = ResourcesCompat.getDrawable(res, resId, context.theme) ?: return null
|
||||
return when {
|
||||
drawable is AdaptiveIconDrawable -> {
|
||||
return when (drawable) {
|
||||
is AdaptiveIconDrawable -> {
|
||||
return StaticLauncherIcon(
|
||||
foregroundLayer = drawable.foreground?.let {
|
||||
StaticIconLayer(
|
||||
@ -135,7 +135,7 @@ class IconPackIconProvider(
|
||||
}
|
||||
if (upon != null) {
|
||||
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 maskBmp = maskDrawable.toBitmap(size, size)
|
||||
inBounds = Rect(0, 0, maskBmp.width, maskBmp.height)
|
||||
@ -145,7 +145,7 @@ class IconPackIconProvider(
|
||||
}
|
||||
if (back != null) {
|
||||
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 maskBmp = maskDrawable.toBitmap(size, size)
|
||||
inBounds = Rect(0, 0, maskBmp.width, maskBmp.height)
|
||||
|
||||
@ -2,7 +2,6 @@ package de.mm20.launcher2.icons.providers
|
||||
|
||||
import android.content.Context
|
||||
import de.mm20.launcher2.icons.LauncherIcon
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.search.data.Searchable
|
||||
|
||||
class SystemIconProvider(
|
||||
|
||||
@ -112,9 +112,9 @@ internal class ThemedIconProvider(
|
||||
}
|
||||
ClockSublayer(
|
||||
drawable = drw,
|
||||
role = when {
|
||||
it == hourIndex -> ClockSublayerRole.Hour
|
||||
it == minuteIndex -> ClockSublayerRole.Minute
|
||||
role = when (it) {
|
||||
hourIndex -> ClockSublayerRole.Hour
|
||||
minuteIndex -> ClockSublayerRole.Minute
|
||||
else -> ClockSublayerRole.Static
|
||||
}
|
||||
)
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
package de.mm20.launcher2.ktx
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
val Fragment.dp: Float
|
||||
|
||||
@ -4,7 +4,6 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
val View.dp: Float
|
||||
get() = context.dp
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.music
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val musicModule = module {
|
||||
|
||||
@ -51,7 +51,7 @@ interface MusicRepository {
|
||||
|
||||
internal class MusicRepositoryImpl(
|
||||
private val context: Context,
|
||||
private val notificationRepository: NotificationRepository
|
||||
notificationRepository: NotificationRepository
|
||||
) : MusicRepository, KoinComponent {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
|
||||
@ -31,7 +31,7 @@ interface NotificationRepository {
|
||||
fun cancelNotification(notification: StatusBarNotification)
|
||||
}
|
||||
|
||||
internal class NotificationRepositoryImpl() : NotificationRepository {
|
||||
internal class NotificationRepositoryImpl : NotificationRepository {
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
override val notifications: MutableStateFlow<List<StatusBarNotification>> = MutableStateFlow(
|
||||
emptyList()
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.preferences
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.datastore.core.DataMigration
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.search
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val searchModule = module {
|
||||
|
||||
@ -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++
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,7 +3,6 @@ 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
|
||||
|
||||
class Websearch(
|
||||
var urlTemplate: String,
|
||||
|
||||
@ -41,7 +41,7 @@ dependencyResolutionManagement {
|
||||
version("targetSdk", "32")
|
||||
}
|
||||
create("libs") {
|
||||
version("kotlin", "1.7.0")
|
||||
version("kotlin", "1.6.21")
|
||||
version("kotlinx.coroutines", "1.6.3")
|
||||
alias("kotlin.stdlib")
|
||||
.to("org.jetbrains.kotlin", "kotlin-stdlib")
|
||||
@ -60,7 +60,7 @@ dependencyResolutionManagement {
|
||||
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")
|
||||
.to("androidx.compose.runtime", "runtime")
|
||||
.versionRef("androidx.compose")
|
||||
@ -206,7 +206,7 @@ dependencyResolutionManagement {
|
||||
.to("androidx.datastore", "datastore")
|
||||
.version("1.0.0")
|
||||
|
||||
version("androidx.room", "2.4.2")
|
||||
version("androidx.room", "2.5.0-alpha02")
|
||||
alias("androidx.roomruntime")
|
||||
.to("androidx.room", "room-runtime")
|
||||
.versionRef("androidx.room")
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,6 @@ package de.mm20.launcher2.ui.animation
|
||||
import androidx.compose.animation.core.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.ExperimentalUnitApi
|
||||
import androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.TextUnitType
|
||||
|
||||
@ -27,7 +27,7 @@ import de.mm20.launcher2.ui.component.BottomSheetDialog
|
||||
import de.mm20.launcher2.ui.component.LargeMessage
|
||||
import de.mm20.launcher2.ui.component.SmallMessage
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class, ExperimentalMaterial3Api::class)
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun RestoreBackupSheet(
|
||||
uri: Uri,
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.ui.component
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
@ -42,6 +42,7 @@ import de.mm20.launcher2.ui.locals.LocalDarkTheme
|
||||
import palettes.TonalPalette
|
||||
import java.time.Instant
|
||||
import java.time.ZoneId
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@ -389,12 +390,12 @@ private val SquircleShape: Shape
|
||||
for (x in -radius.roundToInt()..radius.roundToInt())
|
||||
lineTo(
|
||||
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())
|
||||
lineTo(
|
||||
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))
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ package de.mm20.launcher2.ui.component.preferences
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.ui.component.preferences
|
||||
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
|
||||
|
||||
@ -613,6 +613,7 @@ private fun Precipitation(icon: WeatherIcon) {
|
||||
tint = colorResource(id = R.color.weather_snow)
|
||||
)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,14 +181,6 @@ class LauncherActivity : BaseActivity() {
|
||||
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?) {
|
||||
super.onNewIntent(intent)
|
||||
val navContract = intent?.let { GestureNavContract.fromIntent(it) }
|
||||
|
||||
@ -6,7 +6,7 @@ import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.slideIn
|
||||
import androidx.compose.animation.slideOut
|
||||
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.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
@ -46,8 +46,7 @@ import de.mm20.launcher2.ui.utils.rememberNotificationShadeController
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@OptIn(
|
||||
ExperimentalMaterialApi::class,
|
||||
ExperimentalFoundationApi::class
|
||||
ExperimentalMaterialApi::class, ExperimentalFoundationApi::class
|
||||
)
|
||||
@Composable
|
||||
fun PagerScaffold(
|
||||
@ -216,7 +215,7 @@ fun PagerScaffold(
|
||||
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalOverScrollConfiguration provides null
|
||||
LocalOverscrollConfiguration provides null
|
||||
) {
|
||||
|
||||
Row(
|
||||
|
||||
@ -7,7 +7,7 @@ import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.slideIn
|
||||
import androidx.compose.animation.slideOut
|
||||
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.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
@ -231,7 +231,7 @@ fun PullDownScaffold(
|
||||
derivedStateOf { maxHeight }
|
||||
}
|
||||
CompositionLocalProvider(
|
||||
LocalOverScrollConfiguration provides null
|
||||
LocalOverscrollConfiguration provides null
|
||||
) {
|
||||
val offset by animateFloatAsState(if (isSearchOpen) 1f else 0f)
|
||||
Column(
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
package de.mm20.launcher2.ui.launcher.modals
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.liveData
|
||||
import de.mm20.launcher2.favorites.FavoritesItem
|
||||
import de.mm20.launcher2.favorites.FavoritesRepository
|
||||
import org.koin.core.component.KoinComponent
|
||||
|
||||
@ -3,19 +3,13 @@ package de.mm20.launcher2.ui.launcher.modals
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Edit
|
||||
import androidx.compose.material.icons.rounded.Settings
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.Text
|
||||
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.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
||||
@ -3,11 +3,7 @@ package de.mm20.launcher2.ui.launcher.modals
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.lifecycle.ViewModel
|
||||
import de.mm20.launcher2.favorites.FavoritesRepository
|
||||
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() {
|
||||
|
||||
|
||||
@ -1,21 +1,9 @@
|
||||
package de.mm20.launcher2.ui.launcher.search
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.layout.*
|
||||
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.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
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.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.appshortcuts.AppShortcutResults
|
||||
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.layout.BottomReversed
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun SearchColumn(
|
||||
modifier: Modifier = Modifier,
|
||||
|
||||
@ -37,7 +37,6 @@ import kotlin.math.min
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun AppItem(
|
||||
modifier: Modifier = Modifier,
|
||||
|
||||
@ -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.fillMaxWidth
|
||||
|
||||
@ -11,7 +11,6 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.ui.component.LauncherCard
|
||||
import de.mm20.launcher2.ui.launcher.search.SearchVM
|
||||
import de.mm20.launcher2.ui.search.CalculatorItem
|
||||
|
||||
@Composable
|
||||
fun ColumnScope.CalculatorResults(reverse: Boolean = false) {
|
||||
|
||||
@ -109,7 +109,7 @@ fun GridItem(modifier: Modifier = Modifier, item: Searchable, showLabels: Boolea
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class, ExperimentalAnimationApi::class)
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
fun ItemPopup(origin: Rect, searchable: Searchable, onDismissRequest: () -> Unit) {
|
||||
var show by remember { mutableStateOf(false) }
|
||||
|
||||
@ -1,19 +1,8 @@
|
||||
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.ui.launcher.search.common.SearchableItemVM
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class GridItemVM(
|
||||
private val searchable: Searchable
|
||||
searchable: Searchable
|
||||
): SearchableItemVM(searchable)
|
||||
@ -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.shortcut.AppShortcutItem
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class, androidx.compose.foundation.ExperimentalFoundationApi::class)
|
||||
@OptIn(androidx.compose.foundation.ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun ListItem(modifier: Modifier = Modifier, item: Searchable) {
|
||||
var showDetails by remember { mutableStateOf(false) }
|
||||
|
||||
@ -4,6 +4,5 @@ import de.mm20.launcher2.search.data.Searchable
|
||||
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
|
||||
|
||||
class ListItemVM(
|
||||
private val searchable: Searchable
|
||||
): SearchableItemVM(searchable) {
|
||||
}
|
||||
searchable: Searchable
|
||||
): SearchableItemVM(searchable)
|
||||
@ -43,7 +43,6 @@ import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
|
||||
import de.mm20.launcher2.ui.modifier.scale
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalUnitApi::class)
|
||||
@Composable
|
||||
fun ContactItem(
|
||||
modifier: Modifier = Modifier,
|
||||
|
||||
@ -38,7 +38,6 @@ import kotlinx.coroutines.launch
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@OptIn(ExperimentalUnitApi::class)
|
||||
@Composable
|
||||
fun FileItem(
|
||||
modifier: Modifier = Modifier,
|
||||
|
||||
@ -40,7 +40,6 @@ import kotlinx.coroutines.launch
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun AppShortcutItem(
|
||||
modifier: Modifier = Modifier,
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
package de.mm20.launcher2.ui.search
|
||||
package de.mm20.launcher2.ui.launcher.search.unitconverter
|
||||
|
||||
import android.icu.text.DateFormat
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.*
|
||||
import androidx.compose.material3.*
|
||||
@ -12,11 +11,9 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
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.UnitConverter
|
||||
import de.mm20.launcher2.ui.R
|
||||
|
||||
@ -11,7 +11,6 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.ui.component.LauncherCard
|
||||
import de.mm20.launcher2.ui.launcher.search.SearchVM
|
||||
import de.mm20.launcher2.ui.search.UnitConverterItem
|
||||
|
||||
@Composable
|
||||
fun ColumnScope.UnitConverterResults(reverse: Boolean = false) {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package de.mm20.launcher2.ui.launcher.transitions
|
||||
|
||||
import android.content.ComponentName
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import com.android.launcher3.GestureNavContract
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
package de.mm20.launcher2.ui.launcher.transitions
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.compose.ui.geometry.Rect
|
||||
import androidx.compose.ui.graphics.toAndroidRectF
|
||||
import com.android.launcher3.GestureNavContract
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
|
||||
@ -16,7 +16,6 @@ import androidx.compose.foundation.gestures.rememberDraggableState
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Add
|
||||
import androidx.compose.material3.*
|
||||
@ -36,7 +35,7 @@ import androidx.compose.ui.window.Dialog
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
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.ktx.animateTo
|
||||
import de.mm20.launcher2.ui.launcher.widgets.picker.PickAppWidgetActivity
|
||||
|
||||
@ -145,7 +145,7 @@ fun CalendarWidget() {
|
||||
)
|
||||
}
|
||||
val pinnedEvents by viewModel.pinnedCalendarEvents.observeAsState(emptyList())
|
||||
if (pinnedEvents.size > 0) {
|
||||
if (pinnedEvents.isNotEmpty()) {
|
||||
Text(
|
||||
stringResource(R.string.calendar_widget_pinned_events),
|
||||
modifier = Modifier.padding(start = 4.dp, end = 4.dp, top = 8.dp, bottom = 4.dp),
|
||||
|
||||
@ -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.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.ClockWidgetLayout
|
||||
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.parts.PartProvider
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@ package de.mm20.launcher2.ui.launcher.widgets.clock.parts
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.runtime.Composable
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ fun AppWidgetList(
|
||||
modifier = modifier
|
||||
) {
|
||||
for (group in widgets) {
|
||||
item() {
|
||||
item {
|
||||
Text(
|
||||
modifier = Modifier.padding(
|
||||
top = 16.dp,
|
||||
|
||||
@ -10,6 +10,7 @@ import androidx.activity.compose.setContent
|
||||
import androidx.activity.viewModels
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.ArrowBack
|
||||
import androidx.compose.material3.*
|
||||
@ -67,7 +68,7 @@ class PickAppWidgetActivity : BaseActivity() {
|
||||
if (selected == null) {
|
||||
if (widgets != null) {
|
||||
AppWidgetList(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize().padding(it),
|
||||
widgets = widgets,
|
||||
onWidgetSelected = {
|
||||
selectAppWidget(it)
|
||||
@ -75,7 +76,7 @@ class PickAppWidgetActivity : BaseActivity() {
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize().padding(it),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
CircularProgressIndicator()
|
||||
|
||||
@ -39,7 +39,6 @@ import java.text.DecimalFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@OptIn(ExperimentalAnimationApi::class)
|
||||
@Composable
|
||||
fun WeatherWidget() {
|
||||
val viewModel: WeatherWidgetWM = viewModel()
|
||||
|
||||
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.ui.settings.accounts
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
|
||||
@ -318,7 +318,6 @@ fun SearchBarStylePreference(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun IconShapePreference(
|
||||
title: String,
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package de.mm20.launcher2.ui.settings.backup
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.runtime.*
|
||||
|
||||
@ -1,19 +1,9 @@
|
||||
package de.mm20.launcher2.ui.settings.backup
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
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.inject
|
||||
import java.io.File
|
||||
|
||||
class BackupSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
|
||||
|
||||
@ -1,17 +1,12 @@
|
||||
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.liveData
|
||||
import de.mm20.launcher2.accounts.AccountType
|
||||
import de.mm20.launcher2.accounts.AccountsRepository
|
||||
import de.mm20.launcher2.preferences.Settings.WeatherSettings.WeatherProvider
|
||||
import de.mm20.launcher2.weather.WeatherRepository
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import java.security.MessageDigest
|
||||
|
||||
class BuildInfoSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
private val accountsRepository: AccountsRepository by inject()
|
||||
|
||||
@ -20,7 +20,7 @@ import com.google.accompanist.pager.HorizontalPagerIndicator
|
||||
import com.google.accompanist.pager.rememberPagerState
|
||||
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockStyle
|
||||
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.component.preferences.*
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@ package de.mm20.launcher2.ui.settings.crashreporter
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.liveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import de.mm20.launcher2.crashreporter.BuildConfig
|
||||
import de.mm20.launcher2.crashreporter.CrashReport
|
||||
|
||||
@ -4,8 +4,6 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
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.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
|
||||
@ -82,7 +82,7 @@ fun HiddenItemsSettingsScreen() {
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(R.string.menu_app_info)) },
|
||||
onClick = {
|
||||
viewModel.openAppInfo(context, searchable as Application)
|
||||
viewModel.openAppInfo(context, searchable)
|
||||
showPopup = false
|
||||
})
|
||||
|
||||
|
||||
@ -1,17 +1,9 @@
|
||||
package de.mm20.launcher2.ui.settings.websearch
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.core.graphics.scale
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
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.data.Websearch
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -20,7 +12,6 @@ import kotlinx.coroutines.withContext
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
|
||||
class WebSearchSettingsScreenVM: ViewModel(), KoinComponent {
|
||||
private val repository: WebsearchRepository by inject()
|
||||
|
||||
@ -2,7 +2,6 @@ package de.mm20.launcher2.unitconverter
|
||||
|
||||
import de.mm20.launcher2.currencies.CurrencyRepository
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val unitConverterModule = module {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.websites
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val websitesModule = module {
|
||||
|
||||
@ -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.head().select("link[href~=.*\\.(ico|png)]").attr("href")
|
||||
if (!favicon.isBlank()) favicon = resolveUrl(response.request.url, favicon)
|
||||
if (!image.isBlank()) image = resolveUrl(response.request.url, image)
|
||||
if (favicon.isNotBlank()) favicon = resolveUrl(response.request.url, favicon)
|
||||
if (image.isNotBlank()) image = resolveUrl(response.request.url, image)
|
||||
return@withContext Website(
|
||||
label = title,
|
||||
url = url,
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.widgets
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val widgetsModule = module {
|
||||
|
||||
@ -7,7 +7,6 @@ import android.net.Uri
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import androidx.core.content.ContextCompat
|
||||
import de.mm20.launcher2.icons.ColorLayer
|
||||
import de.mm20.launcher2.icons.StaticIconLayer
|
||||
import de.mm20.launcher2.icons.StaticLauncherIcon
|
||||
import de.mm20.launcher2.icons.TintedIconLayer
|
||||
import de.mm20.launcher2.wikipedia.R
|
||||
@ -43,8 +42,4 @@ class Wikipedia(
|
||||
intent.intent.data = Uri.parse(uri)
|
||||
return intent.intent
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
package de.mm20.launcher2.wikipedia
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val wikipediaModule = module {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user