diff --git a/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt b/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt index b679d748..0e48ae54 100644 --- a/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt +++ b/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt @@ -113,5 +113,6 @@ fun createFactorySettings(context: Context): Settings { .setThemedIcons(false) .setIconPack("") ) + .setEasterEgg(false) .build() } \ No newline at end of file diff --git a/preferences/src/main/proto/settings.proto b/preferences/src/main/proto/settings.proto index 89bc132d..729146a6 100644 --- a/preferences/src/main/proto/settings.proto +++ b/preferences/src/main/proto/settings.proto @@ -157,4 +157,6 @@ message Settings { } IconSettings icons = 21; + bool easter_egg = 22; + } \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/legacy/view/LauncherIconView.kt b/ui/src/main/java/de/mm20/launcher2/ui/legacy/view/LauncherIconView.kt index b1775e57..61b33f18 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/legacy/view/LauncherIconView.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/legacy/view/LauncherIconView.kt @@ -579,9 +579,16 @@ class LauncherIconView : View, KoinComponent { fun getDefaultShape(): Flow = channelFlow { send(currentShape) val dataStore: LauncherDataStore = get() - dataStore.data.map { it.icons.shape }.distinctUntilChanged().collectLatest { - currentShape = it - send(it) + dataStore.data.map { it.icons.shape }.distinctUntilChanged().collectLatest { shape -> + dataStore.data.map { it.easterEgg }.distinctUntilChanged().collectLatest { ee -> + if (ee) { + currentShape = IconShape.EasterEgg + send(IconShape.EasterEgg) + } else { + currentShape = shape + send(shape) + } + } } } } diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/SettingsActivity.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/SettingsActivity.kt index db7ab48a..de6344fa 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/settings/SettingsActivity.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/SettingsActivity.kt @@ -2,8 +2,6 @@ package de.mm20.launcher2.ui.settings import android.os.Bundle import androidx.activity.compose.setContent -import androidx.activity.viewModels -import androidx.appcompat.app.AppCompatDelegate import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn @@ -16,9 +14,7 @@ import com.google.accompanist.navigation.animation.composable import com.google.accompanist.navigation.animation.rememberAnimatedNavController import de.mm20.launcher2.licenses.AppLicense import de.mm20.launcher2.licenses.OpenSourceLicenses -import de.mm20.launcher2.preferences.Settings import de.mm20.launcher2.ui.LegacyLauncherTheme -import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.base.BaseActivity import de.mm20.launcher2.ui.locals.LocalNavController import de.mm20.launcher2.ui.settings.about.AboutSettingsScreen @@ -33,6 +29,7 @@ import de.mm20.launcher2.ui.settings.musicwidget.MusicWidgetSettingsScreen import de.mm20.launcher2.ui.settings.search.SearchSettingsScreen import de.mm20.launcher2.ui.settings.accounts.AccountsSettingsScreen import de.mm20.launcher2.ui.settings.buildinfo.BuildInfoSettingsScreen +import de.mm20.launcher2.ui.settings.easteregg.EasterEggSettingsScreen import de.mm20.launcher2.ui.settings.filesearch.FileSearchSettingsScreen import de.mm20.launcher2.ui.settings.weatherwidget.WeatherWidgetSettingsScreen import de.mm20.launcher2.ui.settings.websearch.WebSearchSettingsScreen @@ -102,6 +99,9 @@ class SettingsActivity : BaseActivity() { composable("settings/about/buildinfo") { BuildInfoSettingsScreen() } + composable("settings/about/easteregg") { + EasterEggSettingsScreen() + } composable("settings/debug") { DebugSettingsScreen() } diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/about/AboutSettingsScreen.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/about/AboutSettingsScreen.kt index 252e4eee..00d8ec2f 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/settings/about/AboutSettingsScreen.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/about/AboutSettingsScreen.kt @@ -2,6 +2,7 @@ package de.mm20.launcher2.ui.settings.about import android.content.Intent import android.net.Uri +import android.widget.Toast import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Info import androidx.compose.runtime.* @@ -37,9 +38,22 @@ fun AboutSettingsScreen() { ).versionName } } + var easterEggCounter by remember { mutableStateOf(0) } Preference( title = stringResource(R.string.preference_version), - summary = appVersion + summary = appVersion, + onClick = { + when(easterEggCounter) { + 3 -> Toast.makeText(context, context.getString(R.string.easter_egg_1), Toast.LENGTH_SHORT).show() + 7 -> Toast.makeText(context, context.getString(R.string.easter_egg_2), Toast.LENGTH_SHORT).show() + 11 -> Toast.makeText(context, context.getString(R.string.easter_egg_3), Toast.LENGTH_SHORT).show() + } + easterEggCounter++ + if (easterEggCounter >= 14) { + navController?.navigate("settings/about/easteregg") + easterEggCounter = 0 + } + } ) Preference( title = stringResource(R.string.preference_screen_buildinfo), diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreen.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreen.kt new file mode 100644 index 00000000..10430a7a --- /dev/null +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreen.kt @@ -0,0 +1,82 @@ +package de.mm20.launcher2.ui.settings.easteregg + +import androidx.compose.animation.ExperimentalAnimationApi +import androidx.compose.animation.animateColorAsState +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.scaleIn +import androidx.compose.animation.scaleOut +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.* +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.lifecycle.viewmodel.compose.viewModel +import de.mm20.launcher2.ui.R +import de.mm20.launcher2.ui.component.preferences.PreferenceScreen + +@OptIn(ExperimentalAnimationApi::class) +@Composable +fun EasterEggSettingsScreen() { + val viewModel: EasterEggSettingsScreenVM = viewModel() + PreferenceScreen(title = stringResource(R.string.preference_screen_about)) { + item { + val easterEgg by viewModel.easterEgg.observeAsState(false) + val bgAlpha by animateFloatAsState(if (easterEgg) 1f else 0f) + val textColor by animateColorAsState(if (easterEgg) MaterialTheme.colorScheme.onSecondaryContainer else MaterialTheme.colorScheme.onBackground) + Column( + modifier = Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.secondaryContainer.copy(alpha = bgAlpha)) + .padding(16.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + modifier = Modifier.padding(16.dp), + text = stringResource(id = R.string.easter_egg_text), + textAlign = TextAlign.Center, + style = MaterialTheme.typography.headlineSmall.copy( + color = textColor + ) + ) + Box( + modifier = Modifier + .fillMaxWidth() + .height(400.dp) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null + ) { + viewModel.setEasterEgg(!easterEgg) + }, + contentAlignment = Alignment.Center + ) { + androidx.compose.animation.AnimatedVisibility( + visible = !easterEgg, + enter = scaleIn(), + exit = scaleOut() + ) { + Text(text = "\uD83C\uDF82", fontSize = 120.sp) + } + androidx.compose.animation.AnimatedVisibility( + visible = easterEgg, + enter = scaleIn(), + exit = scaleOut() + ) { + Text(text = "❤️", fontSize = 120.sp) + } + } + } + } + } +} \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreenVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreenVM.kt new file mode 100644 index 00000000..f57cf766 --- /dev/null +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreenVM.kt @@ -0,0 +1,25 @@ +package de.mm20.launcher2.ui.settings.easteregg + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.asLiveData +import androidx.lifecycle.viewModelScope +import de.mm20.launcher2.preferences.LauncherDataStore +import de.mm20.launcher2.preferences.Settings +import de.mm20.launcher2.preferences.Settings.IconSettings.IconShape +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject + +class EasterEggSettingsScreenVM: ViewModel(), KoinComponent { + private val dataStore: LauncherDataStore by inject() + + val easterEgg = dataStore.data.map { it.easterEgg }.asLiveData() + fun setEasterEgg(easterEgg: Boolean) { + viewModelScope.launch { + dataStore.updateData { + it.toBuilder().setEasterEgg(easterEgg).build() + } + } + } +} \ No newline at end of file