From 811808c00fb2d4721c022e20f925cd98930712ee Mon Sep 17 00:00:00 2001 From: FunkyMuse Date: Tue, 19 Sep 2023 15:31:32 +0200 Subject: [PATCH] feat: start migrating to compose --- app/build.gradle.kts | 21 ++++ .../thankyou/activities/MainActivity.kt | 55 ++++------ .../thankyou/activities/SettingsActivity.kt | 3 +- .../thankyou/helpers/Constants.kt | 2 +- .../thankyou/screens/MainScreen.kt | 101 ++++++++++++++++++ .../thankyou/screens/SettingsScreen.kt | 17 +++ gradle/libs.versions.toml | 58 +++++++++- gradle/wrapper/gradle-wrapper.properties | 2 +- 8 files changed, 220 insertions(+), 39 deletions(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/thankyou/screens/MainScreen.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/thankyou/screens/SettingsScreen.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1e1d4f1..04bc2e6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -43,6 +43,22 @@ android { buildFeatures { viewBinding = true buildConfig = true + compose = true + } + + composeOptions { + kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get() + } + + tasks.withType { + kotlinOptions.jvmTarget = project.libs.versions.app.build.kotlinJVMTarget.get() + kotlinOptions.freeCompilerArgs = listOf( + "-opt-in=kotlin.RequiresOptIn", + "-opt-in=androidx.compose.material3.ExperimentalMaterial3Api", + "-opt-in=androidx.compose.material.ExperimentalMaterialApi", + "-opt-in=androidx.compose.foundation.ExperimentalFoundationApi", + "-Xcontext-receivers" + ) } buildTypes { @@ -91,5 +107,10 @@ android { } dependencies { + implementation(libs.kotlin.immutable.collections) + implementation(libs.simple.tools.commons) + implementation(libs.bundles.lifecycle) + implementation(libs.bundles.compose) + debugImplementation(libs.bundles.compose.preview) } diff --git a/app/src/main/kotlin/com/simplemobiletools/thankyou/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/thankyou/activities/MainActivity.kt index fd50b09..7b09372 100644 --- a/app/src/main/kotlin/com/simplemobiletools/thankyou/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/thankyou/activities/MainActivity.kt @@ -2,51 +2,38 @@ package com.simplemobiletools.thankyou.activities import android.content.Intent import android.os.Bundle -import com.simplemobiletools.commons.extensions.* +import androidx.activity.compose.setContent +import com.simplemobiletools.commons.compose.extensions.enableEdgeToEdgeSimple +import com.simplemobiletools.commons.compose.extensions.onEventValue +import com.simplemobiletools.commons.compose.theme.AppThemeSurface +import com.simplemobiletools.commons.extensions.appLaunched +import com.simplemobiletools.commons.extensions.checkWhatsNew +import com.simplemobiletools.commons.extensions.hideKeyboard +import com.simplemobiletools.commons.extensions.launchMoreAppsFromUsIntent import com.simplemobiletools.commons.models.FAQItem import com.simplemobiletools.commons.models.Release import com.simplemobiletools.thankyou.BuildConfig import com.simplemobiletools.thankyou.R -import com.simplemobiletools.thankyou.databinding.ActivityMainBinding +import com.simplemobiletools.thankyou.screens.MainScreen class MainActivity : SimpleActivity() { - private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivityMainBinding.inflate(layoutInflater) } - override fun onCreate(savedInstanceState: Bundle?) { - isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(binding.root) - appLaunched(BuildConfig.APPLICATION_ID) - refreshMenuItems() - setupOptionsMenu() - checkWhatsNewDialog() - updateMaterialActivityViews(binding.mainCoordinator, binding.activityMain, useTransparentNavigation = true, useTopSearchMenu = false) - } - - override fun onResume() { - super.onResume() - updateTextColors(binding.activityMain) - setupToolbar(binding.mainToolbar, statusBarColor = getProperBackgroundColor()) - } - - private fun refreshMenuItems() { - binding.mainToolbar.menu.apply { - findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations) - } - } - - private fun setupOptionsMenu() { - binding.mainToolbar.setOnMenuItemClickListener { menuItem -> - when (menuItem.itemId) { - R.id.more_apps_from_us -> launchMoreAppsFromUsIntent() - R.id.settings -> launchSettings() - R.id.about -> launchAbout() - else -> return@setOnMenuItemClickListener false + enableEdgeToEdgeSimple() + setContent { + AppThemeSurface { + val showMoreApps = onEventValue { !resources.getBoolean(R.bool.hide_google_relations) } + MainScreen( + showMoreApps = showMoreApps, + openSettings = ::launchSettings, + openAbout = ::launchAbout, + moreAppsFromUs = ::launchMoreAppsFromUsIntent + ) } - return@setOnMenuItemClickListener true } + appLaunched(BuildConfig.APPLICATION_ID) + checkWhatsNewDialog() } - private fun launchSettings() { hideKeyboard() startActivity(Intent(this, SettingsActivity::class.java)) diff --git a/app/src/main/kotlin/com/simplemobiletools/thankyou/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/thankyou/activities/SettingsActivity.kt index 5c0797a..78d6cc0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/thankyou/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/thankyou/activities/SettingsActivity.kt @@ -10,6 +10,7 @@ import com.simplemobiletools.thankyou.R import com.simplemobiletools.thankyou.databinding.ActivitySettingsBinding import com.simplemobiletools.thankyou.extensions.config import java.util.Locale +import kotlin.system.exitProcess class SettingsActivity : SimpleActivity() { private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivitySettingsBinding.inflate(layoutInflater) } @@ -55,7 +56,7 @@ class SettingsActivity : SimpleActivity() { settingsUseEnglishHolder.setOnClickListener { settingsUseEnglish.toggle() config.useEnglish = settingsUseEnglish.isChecked - System.exit(0) + exitProcess(0) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/thankyou/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/thankyou/helpers/Constants.kt index fce9bb2..872bc73 100644 --- a/app/src/main/kotlin/com/simplemobiletools/thankyou/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/thankyou/helpers/Constants.kt @@ -1,4 +1,4 @@ package com.simplemobiletools.thankyou.helpers // Shared Preferences -val HIDE_LAUNCHER_ICON = "hide_launcher_icon" +const val HIDE_LAUNCHER_ICON = "hide_launcher_icon" diff --git a/app/src/main/kotlin/com/simplemobiletools/thankyou/screens/MainScreen.kt b/app/src/main/kotlin/com/simplemobiletools/thankyou/screens/MainScreen.kt new file mode 100644 index 0000000..ca3f528 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/thankyou/screens/MainScreen.kt @@ -0,0 +1,101 @@ +@file:OptIn(ExperimentalMaterial3Api::class) + +package com.simplemobiletools.thankyou.screens + +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.* +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Info +import androidx.compose.material.icons.filled.Settings +import androidx.compose.material.icons.outlined.Info +import androidx.compose.material.icons.outlined.Settings +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.simplemobiletools.commons.R +import com.simplemobiletools.commons.compose.extensions.MyDevices +import com.simplemobiletools.commons.compose.menus.ActionItem +import com.simplemobiletools.commons.compose.menus.ActionMenu +import com.simplemobiletools.commons.compose.menus.OverflowMode +import com.simplemobiletools.commons.compose.screens.LinkifyText +import com.simplemobiletools.commons.compose.screens.stringFromHTML +import com.simplemobiletools.commons.compose.settings.scaffold.* +import com.simplemobiletools.commons.compose.theme.AppThemeSurface +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList + +@Composable +internal fun MainScreen( + showMoreApps: Boolean, + openSettings: () -> Unit, + openAbout: () -> Unit, + moreAppsFromUs: () -> Unit, +) { + + SettingsLazyScaffold(customTopBar = { scrolledColor: Color, _: MutableInteractionSource, scrollBehavior: TopAppBarScrollBehavior, statusBarColor: Int, colorTransitionFraction: Float, contrastColor: Color -> + TopAppBar( + title = {}, + actions = { + val actionMenus = remember { + val list = listOf( + ActionItem(R.string.settings, icon = Icons.Outlined.Settings, doAction = openSettings, overflowMode = OverflowMode.NEVER_OVERFLOW), + ActionItem(R.string.about, icon = Icons.Outlined.Info, doAction = openAbout, overflowMode = OverflowMode.NEVER_OVERFLOW), + ) + if (showMoreApps) { + list + ActionItem(R.string.more_apps_from_us, doAction = moreAppsFromUs, overflowMode = OverflowMode.ALWAYS_OVERFLOW) + } + list.toImmutableList() + } + var isMenuVisible by remember { mutableStateOf(false) } + ActionMenu(items = actionMenus, numIcons = 2, isMenuVisible = isMenuVisible, onMenuToggle = { isMenuVisible = it }, iconsColor = scrolledColor) + }, + scrollBehavior = scrollBehavior, + colors = topAppBarColors(statusBarColor, colorTransitionFraction, contrastColor), + modifier = Modifier.topAppBarPaddings(), + windowInsets = topAppBarInsets() + ) + }) { + val source = stringResource(id = com.simplemobiletools.thankyou.R.string.main_text) + LinkifyText(modifier = Modifier.padding(40.dp), fontSize = 16.sp) { + stringFromHTML(source) + } + } +} + +@Composable +fun topAppBarColors( + statusBarColor: Int, + colorTransitionFraction: Float, + contrastColor: Color +) = TopAppBarDefaults.topAppBarColors( + scrolledContainerColor = Color(statusBarColor), + containerColor = if (colorTransitionFraction == 1f) contrastColor else MaterialTheme.colorScheme.surface, + navigationIconContentColor = if (colorTransitionFraction == 1f) contrastColor else MaterialTheme.colorScheme.surface +) + +@Composable +private fun ActionMenuMainScreen( +) { + var isMenuVisible by remember { mutableStateOf(false) } + val actionMenus: ImmutableList = remember { + listOf( + ActionItem(nameRes = R.string.settings, icon = Icons.Default.Settings, overflowMode = OverflowMode.NEVER_OVERFLOW, doAction = {}), + ActionItem(nameRes = R.string.about, icon = Icons.Default.Info, overflowMode = OverflowMode.NEVER_OVERFLOW, doAction = {}), + ActionItem(nameRes = R.string.more_apps_from_us, icon = null, overflowMode = OverflowMode.ALWAYS_OVERFLOW, doAction = {}), + ).toImmutableList() + } + ActionMenu(items = actionMenus, numIcons = 2, isMenuVisible = isMenuVisible, onMenuToggle = { isMenuVisible = !isMenuVisible }) +} + + +@Composable +@MyDevices +private fun MainScreenPreview() { + AppThemeSurface { + MainScreen(showMoreApps = true, openSettings = {}, openAbout = {}, moreAppsFromUs = {}) + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/thankyou/screens/SettingsScreen.kt b/app/src/main/kotlin/com/simplemobiletools/thankyou/screens/SettingsScreen.kt new file mode 100644 index 0000000..c98f430 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/thankyou/screens/SettingsScreen.kt @@ -0,0 +1,17 @@ +package com.simplemobiletools.thankyou.screens + +import androidx.compose.runtime.Composable +import com.simplemobiletools.commons.compose.extensions.MyDevices +import com.simplemobiletools.commons.compose.theme.AppThemeSurface + +@Composable +internal fun SettingsScreen() { + +} + +@Composable +@MyDevices +private fun SettingsScreenPreview() { + AppThemeSurface { SettingsScreen() } +} + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1cbb23e..c6c1dc6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,8 +1,18 @@ [versions] #jetbrains -kotlin = "1.9.0" +kotlin = "1.9.10" +kotlin-immutable-collections = "0.3.5" #todo remove #Simple tools -simple-commons = "de113ad025" +simple-commons = "eceb48949e" +#Compose +composeActivity = "1.8.0-beta01" +compose = "1.6.0-alpha05" +composeCompiler = "1.5.3" +composeMaterial3 = "1.2.0-alpha07" +#Androidx +androidx-customView = "1.2.0-alpha02" +androidx-customViewPooling = "1.0.0" +androidx-lifecycle = "2.7.0-alpha02" #Gradle gradlePlugins-agp = "8.1.1" app-build-compileSDKVersion = "34" @@ -15,8 +25,52 @@ app-version-appId = "com.simplemobiletools.thankyou" app-version-versionCode = "31" app-version-versionName = "5.7.3" [libraries] +#Android X +androidx-customView = { module = "androidx.customview:customview", version.ref = "androidx-customView" } +androidx-customViewPooling = { module = "androidx.customview:customview-poolingcontainer", version.ref = "androidx-customViewPooling" } #Simple Mobile Tools simple-tools-commons = { module = "com.github.SimpleMobileTools:Simple-Commons", version.ref = "simple-commons" } +#Android X lifecycle +androidx-lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidx-lifecycle" } +androidx-lifecycle-viewModel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" } +androidx-lifecycle-viewModel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" } +androidx-lifecycle-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" } +#Compose +compose-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "composeCompiler" } +compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" } +compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "composeMaterial3" } +compose-material2 = { module = "androidx.compose.material:material", version.ref = "compose" } +compose-material-icons = { module = "androidx.compose.material:material-icons-extended", version.ref = "compose" } +compose-animation = { module = "androidx.compose.animation:animation", version.ref = "compose" } +compose-activity = { module = "androidx.activity:activity-compose", version.ref = "composeActivity" } +compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" } +compose-runtime = { module = "androidx.compose.runtime:runtime", version.ref = "compose" } +compose-uiTooling-debug = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" } +compose-uiTooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" } +kotlin-immutable-collections = {module = "org.jetbrains.kotlinx:kotlinx-collections-immutable", version.ref = "kotlin-immutable-collections"} #todo remove +[bundles] +compose = [ + "compose-activity", + "compose-animation", + "compose-compiler", + "compose-foundation", + "compose-material-icons", + "compose-material3", + "compose-runtime", + "compose-ui", + "compose-uiTooling-preview", +] +compose-preview = [ + "androidx-customView", + "androidx-customViewPooling", + "compose-uiTooling-debug", +] +lifecycle = [ + "androidx-lifecycle-compose", + "androidx-lifecycle-runtime", + "androidx-lifecycle-viewModel", + "androidx-lifecycle-viewModel-compose", +] [plugins] android = { id = "com.android.application", version.ref = "gradlePlugins-agp" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5ca6ae3..ad77464 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip