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.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)
|
||||||
|
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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()) }
|
||||||
}
|
}
|
||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
package de.mm20.launcher2.icons
|
||||||
|
|
||||||
import android.content.res.Resources
|
|
||||||
|
|
||||||
sealed interface LauncherIcon
|
sealed interface LauncherIcon
|
||||||
|
|
||||||
data class StaticLauncherIcon(
|
data class StaticLauncherIcon(
|
||||||
|
|||||||
@ -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) + "₂"
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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()
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ android {
|
|||||||
|
|
||||||
javaCompileOptions {
|
javaCompileOptions {
|
||||||
annotationProcessorOptions {
|
annotationProcessorOptions {
|
||||||
arguments.put("room.schemaLocation", "$projectDir/schemas")
|
arguments["room.schemaLocation"] = "$projectDir/schemas"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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}")
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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 ?: ""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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.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,
|
||||||
|
|||||||
@ -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")
|
||||||
|
|||||||
@ -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.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
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -613,6 +613,7 @@ private fun Precipitation(icon: WeatherIcon) {
|
|||||||
tint = colorResource(id = R.color.weather_snow)
|
tint = colorResource(id = R.color.weather_snow)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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) }
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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() {
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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) }
|
||||||
|
|||||||
@ -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)
|
||||||
@ -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) }
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
|
||||||
@ -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,
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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),
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
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
|
||||||
|
|||||||
@ -318,7 +318,6 @@ fun SearchBarStylePreference(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
fun IconShapePreference(
|
fun IconShapePreference(
|
||||||
title: String,
|
title: String,
|
||||||
|
|||||||
@ -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.*
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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.*
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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 {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -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 {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user