From 2de618c251fbdc62eea05d771a3021c2964bc0a2 Mon Sep 17 00:00:00 2001 From: Graydyn Date: Tue, 23 Dec 2025 13:43:12 -0500 Subject: [PATCH 1/2] update versions and get lint passing --- .gitignore | 2 +- app/android.gradle | 47 +++--- app/build.gradle.kts | 12 +- app/src/main/AndroidManifest.xml | 5 +- app/src/main/java/com/movableink/app/App.kt | 2 +- .../main/java/com/movableink/app/AppState.kt | 21 +-- .../java/com/movableink/app/BrazeListener.kt | 38 ----- .../java/com/movableink/app/DeeplinkMapper.kt | 4 +- .../java/com/movableink/app/MainActivity.kt | 3 +- .../com/movableink/app/ShoppingCartApp.kt | 40 ++--- .../com/movableink/app/data/model/Product.kt | 137 +++++++++--------- .../app/data/model/SnackBarManager.kt | 4 +- .../app/data/repository/MovableRepository.kt | 3 +- .../app/ui/component/CheckoutDialog.kt | 14 +- .../app/ui/component/MovableSearchBar.kt | 30 ++-- .../app/ui/component/MovableSnackSnackBar.kt | 4 +- .../app/ui/component/MovableTopBar.kt | 4 +- .../app/ui/component/SearchResults.kt | 2 +- .../movableink/app/ui/navigation/BottomNav.kt | 106 +++++++------- .../movableink/app/ui/screens/cart/Cart.kt | 12 +- .../app/ui/screens/cart/CartItem.kt | 14 +- .../app/ui/screens/cart/CartViewModel.kt | 19 +-- .../app/ui/screens/home/CatalogScreen.kt | 74 ++++------ .../app/ui/screens/home/CategoryScreen.kt | 48 +++--- .../app/ui/screens/home/HomeScreen.kt | 34 ++--- .../app/ui/screens/home/HomeViewModel.kt | 23 +-- .../ui/screens/home/ProductDetailScreen.kt | 51 +++---- .../app/ui/screens/search/Search.kt | 13 +- .../app/ui/screens/search/SearchView.kt | 9 +- .../app/ui/screens/search/SearchViewModel.kt | 28 ++-- .../java/com/movableink/app/ui/theme/Color.kt | 2 +- .../java/com/movableink/app/ui/theme/Shape.kt | 2 +- .../java/com/movableink/app/ui/theme/Theme.kt | 16 +- .../java/com/movableink/app/ui/theme/Type.kt | 24 +-- .../app/utils/FetchDrawableByName.kt | 16 +- .../movableink/app/utils/FlowWithLifeCycle.kt | 10 +- .../com/movableink/app/utils/PriceFormat.kt | 12 +- .../java/com/movableink/app/utils/URIPath.kt | 4 +- build.gradle.kts | 7 +- gradle/libs.versions.toml | 31 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle.kts | 8 +- spotless.gradle | 8 +- 43 files changed, 391 insertions(+), 554 deletions(-) delete mode 100644 app/src/main/java/com/movableink/app/BrazeListener.kt diff --git a/.gitignore b/.gitignore index cf37e05..d9b4811 100644 --- a/.gitignore +++ b/.gitignore @@ -39,7 +39,7 @@ render.experimental.xml *.keystore # Google Services (e.g. APIs or Firebase) -google-services.json +app/google-services.json # Android Profiling *.hprof diff --git a/app/android.gradle b/app/android.gradle index 474fb02..396d588 100644 --- a/app/android.gradle +++ b/app/android.gradle @@ -1,48 +1,41 @@ def localProperties = new Properties() -localProperties.load(new FileInputStream(rootProject.file("local.properties"))) +def localPropertiesFile = rootProject.file("local.properties") +if (localPropertiesFile.exists()) { + localProperties.load(new FileInputStream(localPropertiesFile)) +} android { - namespace 'com.movableink.app' - compileSdk findProperty("compileSdkVersion") as Integer - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get() - } + namespace = 'com.movableink.app' + compileSdk = findProperty("compileSdkVersion") as Integer buildTypes { release { - minifyEnabled false + minifyEnabled = false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } - debug{ - minifyEnabled false + debug { + minifyEnabled = false } } defaultConfig { - applicationId findProperty("applicationId") - minSdkVersion findProperty("minSdkVersion") as Integer - targetSdkVersion findProperty("targetSdkVersion") - versionCode findProperty("versionCode") as Integer - versionName findProperty("versionName") - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - manifestPlaceholders ["MOVABLE_INK_SDK_API_KEY"] = localProperties['MOVABLE_INK_SDK_API_KEY'] + applicationId = findProperty("applicationId") + minSdk = findProperty("minSdkVersion") as Integer + targetSdk = findProperty("targetSdkVersion") as Integer + versionCode = findProperty("versionCode") as Integer + versionName = findProperty("versionName") + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + manifestPlaceholders["MOVABLE_INK_SDK_API_KEY"] = localProperties['MOVABLE_INK_SDK_API_KEY'] ?: "" vectorDrawables.useSupportLibrary = true - - - - } buildFeatures { - compose true - } - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get() + compose = true } - packagingOptions { + packaging { resources { excludes += '/META-INF/{AL2.0,LGPL2.1}' } } compileOptions { - sourceCompatibility 1.8 - targetCompatibility 1.8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } } \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 41feacc..a946278 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,18 +1,20 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - plugins { id("com.android.application") kotlin("android") + kotlin("plugin.compose") id("com.google.gms.google-services") } apply(from = "android.gradle") -tasks.withType().configureEach { - kotlinOptions.jvmTarget = "1.8" +kotlin { + jvmToolchain(17) } -@Suppress("DSL_SCOPE_VIOLATION") + dependencies { + // Compose BOM + implementation(platform(libs.compose.bom)) + implementation(platform(libs.firebase.bom)) implementation(libs.firebase.auth) implementation(libs.firebase.analytics) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7cb59e3..a0140fc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,9 +4,7 @@ - + diff --git a/app/src/main/java/com/movableink/app/App.kt b/app/src/main/java/com/movableink/app/App.kt index 83b748a..1969c07 100644 --- a/app/src/main/java/com/movableink/app/App.kt +++ b/app/src/main/java/com/movableink/app/App.kt @@ -15,7 +15,7 @@ class App : Application() { super.onCreate() MIClient.start() MIClient.registerDeeplinkDomains( - listOf("afra.io"), + listOf("afra.io") ) MIClient.appInstallEventEnabled(true) FirebaseApp.initializeApp(this) diff --git a/app/src/main/java/com/movableink/app/AppState.kt b/app/src/main/java/com/movableink/app/AppState.kt index 2b2ec47..6ed0c19 100644 --- a/app/src/main/java/com/movableink/app/AppState.kt +++ b/app/src/main/java/com/movableink/app/AppState.kt @@ -39,11 +39,10 @@ fun rememberAppState( navController: NavHostController = rememberNavController(), snackBarManager: SnackbarManager = SnackbarManager, resources: Resources = resources(), - coroutineScope: CoroutineScope = rememberCoroutineScope(), -) = - remember(scaffoldState, navController, snackBarManager, resources, coroutineScope) { - AppState(scaffoldState, navController, snackBarManager, resources, coroutineScope) - } + coroutineScope: CoroutineScope = rememberCoroutineScope() +) = remember(scaffoldState, navController, snackBarManager, resources, coroutineScope) { + AppState(scaffoldState, navController, snackBarManager, resources, coroutineScope) +} @Stable class AppState( @@ -51,7 +50,7 @@ class AppState( val navController: NavHostController, private val snackbarManager: SnackbarManager, private val resources: Resources, - coroutineScope: CoroutineScope, + coroutineScope: CoroutineScope ) { init { coroutineScope.launch { @@ -94,10 +93,7 @@ class AppState( } } - fun navigateToCategories( - gender: String, - from: NavBackStackEntry, - ) { + fun navigateToCategories(gender: String, from: NavBackStackEntry) { if (from.lifecycleIsResumed()) { navController.navigate("${MainDestinations.CATEGORIES_ROUTE}/$gender") } @@ -127,9 +123,8 @@ private fun NavBackStackEntry.lifecycleIsResumed() = this.lifecycle.currentState private val NavGraph.startDestination: NavDestination? get() = findNode(startDestinationId) -private tailrec fun findStartDestination(graph: NavDestination): NavDestination { - return if (graph is NavGraph) findStartDestination(graph.startDestination!!) else graph -} +private tailrec fun findStartDestination(graph: NavDestination): NavDestination = + if (graph is NavGraph) findStartDestination(graph.startDestination!!) else graph @Composable @ReadOnlyComposable diff --git a/app/src/main/java/com/movableink/app/BrazeListener.kt b/app/src/main/java/com/movableink/app/BrazeListener.kt deleted file mode 100644 index 7e259c0..0000000 --- a/app/src/main/java/com/movableink/app/BrazeListener.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* -package com.movableink.app - -import android.app.Activity -import com.braze.models.inappmessage.IInAppMessage -import com.braze.ui.inappmessage.InAppMessageOperation -import com.braze.ui.inappmessage.listeners.IInAppMessageManagerListener -import com.movableink.inked.MIClient -import com.movableink.inked.inAppMessage.MovableInAppClient - -private const val KEY_MI_LINK = "mi_link" -class BrazeListener(activity: Activity) : IInAppMessageManagerListener { - private val activity = activity - - override fun beforeInAppMessageDisplayed(inAppMessage: IInAppMessage): InAppMessageOperation { - if (inAppMessage.extras.containsKey(KEY_MI_LINK)) { - */ -/* let the MovableInk SDK handle this. - Log the impression to Braze, ask MIClient to show the message, and return .discard to - notify the Braze SDK that we don't want it to show anything.*/ -/* - - val movableLink = inAppMessage.extras[KEY_MI_LINK] as String - MIClient.showInAppBrowser( - activity, - movableLink, - listener = object : MovableInAppClient.OnUrlLoadingListener { - override fun onButtonClicked(value: String) { - // log button clicks to braze - // inAppMessage.logButtonClick(value) - } - }, - ) - } - return InAppMessageOperation.DISCARD - } -} -*/ diff --git a/app/src/main/java/com/movableink/app/DeeplinkMapper.kt b/app/src/main/java/com/movableink/app/DeeplinkMapper.kt index d105ab6..640d664 100644 --- a/app/src/main/java/com/movableink/app/DeeplinkMapper.kt +++ b/app/src/main/java/com/movableink/app/DeeplinkMapper.kt @@ -18,7 +18,7 @@ fun deepLinkToProductPage(url: String, context: Context, scheme: Scheme = Scheme Intent.ACTION_VIEW, "${DeepLinkPattern.baseDestination}/$productId".toUri(), context, - MainActivity::class.java, + MainActivity::class.java ).apply { flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP } @@ -65,5 +65,5 @@ fun urlScheme(urlString: String): Scheme { enum class Scheme { INTERNAL, GLOBAL, - OTHER, + OTHER } diff --git a/app/src/main/java/com/movableink/app/MainActivity.kt b/app/src/main/java/com/movableink/app/MainActivity.kt index 4731d16..421a259 100644 --- a/app/src/main/java/com/movableink/app/MainActivity.kt +++ b/app/src/main/java/com/movableink/app/MainActivity.kt @@ -18,7 +18,7 @@ private const val TAG = "MainActivity " class MainActivity : ComponentActivity() { private val requestPermissionLauncher = registerForActivityResult( - ActivityResultContracts.RequestPermission(), + ActivityResultContracts.RequestPermission() ) { isGranted: Boolean -> if (isGranted) { // FCM SDK (and your app) can post notifications. @@ -53,7 +53,6 @@ class MainActivity : ComponentActivity() { super.onWindowFocusChanged(hasFocus) } - private fun fetchClickableLink() { MIClient.checkPasteboardOnInstall { resolvedLink -> try { diff --git a/app/src/main/java/com/movableink/app/ShoppingCartApp.kt b/app/src/main/java/com/movableink/app/ShoppingCartApp.kt index 6766a26..4b1aa4e 100644 --- a/app/src/main/java/com/movableink/app/ShoppingCartApp.kt +++ b/app/src/main/java/com/movableink/app/ShoppingCartApp.kt @@ -42,7 +42,7 @@ fun ShoppingCartApp() { MovableBottomBar( tabs = appState.bottomBarTabs, currentRoute = appState.currentRoute!!, - navigateToRoute = appState::navigateToBottomBarRoute, + navigateToRoute = appState::navigateToBottomBarRoute ) } }, @@ -50,15 +50,15 @@ fun ShoppingCartApp() { SnackbarHost( hostState = it, modifier = Modifier.systemBarsPadding(), - snackbar = { snackbarData -> MovableSnackSnackBar(snackbarData) }, + snackbar = { snackbarData -> MovableSnackSnackBar(snackbarData) } ) }, - scaffoldState = appState.scaffoldState, + scaffoldState = appState.scaffoldState ) { innerPaddingModifier -> NavHost( navController = appState.navController, startDestination = MainDestinations.HOME_ROUTE, - modifier = Modifier.padding(innerPaddingModifier), + modifier = Modifier.padding(innerPaddingModifier) ) { appNavGraph( @@ -70,7 +70,7 @@ fun ShoppingCartApp() { cartViewModel = cartViewModel, navigateToCart = appState::navigateToCart, homeViewModel = homeViewModel, - searchViewModel = searchViewModel, + searchViewModel = searchViewModel ) } } @@ -85,11 +85,11 @@ private fun NavGraphBuilder.appNavGraph( cartViewModel: CartViewModel, navigateToCart: () -> Unit, homeViewModel: HomeViewModel, - searchViewModel: SearchViewModel, + searchViewModel: SearchViewModel ) { navigation( route = MainDestinations.HOME_ROUTE, - startDestination = HomeSections.HOME.route, + startDestination = HomeSections.HOME.route ) { addHomeGraph( onGenderSelected, @@ -97,25 +97,25 @@ private fun NavGraphBuilder.appNavGraph( cartViewModel = cartViewModel, homeViewModel = homeViewModel, searchViewModel = searchViewModel, - navigateToProductDetail = navigateToProductDetail, + navigateToProductDetail = navigateToProductDetail ) } composable( route = "${MainDestinations.CATEGORIES_ROUTE}/{${MainDestinations.SELECTED_GENDER}}", - arguments = listOf(navArgument(MainDestinations.SELECTED_GENDER) { type = NavType.StringType }), + arguments = listOf(navArgument(MainDestinations.SELECTED_GENDER) { type = NavType.StringType }) ) { CategoryScreen( onCategoryClick = onCategoryClick, upPress, - homeViewModel, + homeViewModel ) } composable( route = "${MainDestinations.CATALOG_ROUTE}/{${MainDestinations.SELECTED_CATEGORY}}/{${MainDestinations.SELECTED_GENDER}}", arguments = listOf( navArgument(MainDestinations.SELECTED_GENDER) { type = NavType.StringType }, - navArgument(MainDestinations.SELECTED_CATEGORY) { type = NavType.StringType }, - ), + navArgument(MainDestinations.SELECTED_CATEGORY) { type = NavType.StringType } + ) ) { backStackEntry -> val arguments = requireNotNull(backStackEntry.arguments) val selectedCategory = arguments.getString(MainDestinations.SELECTED_CATEGORY) @@ -125,25 +125,25 @@ private fun NavGraphBuilder.appNavGraph( upPress, cartViewModel, onViewCart = navigateToCart, - homeViewModel, + homeViewModel ) } composable( route = "${MainDestinations.PRODUCT_DETAIL_ROUTE}/{${MainDestinations.PRODUCT_ID}}", arguments = listOf( - navArgument(MainDestinations.PRODUCT_ID) { type = NavType.StringType }, - ), + navArgument(MainDestinations.PRODUCT_ID) { type = NavType.StringType } + ) ) { ProductDetailScreen( popBackStack = upPress, cartViewModel, - homeViewModel, + homeViewModel ) } composable( route = MainDestinations.PRODUCT_DETAIL_ROUTE, - deepLinks = listOf(navDeepLink { uriPattern = "$baseDestination/{productId}" }), + deepLinks = listOf(navDeepLink { uriPattern = "$baseDestination/{productId}" }) ) { backStackEntry -> val arguments = requireNotNull(backStackEntry.arguments) val selectedCategory = arguments.getString(MainDestinations.SELECTED_CATEGORY) @@ -152,17 +152,17 @@ private fun NavGraphBuilder.appNavGraph( ProductDetailScreen( popBackStack = upPress, cartViewModel, - homeViewModel, + homeViewModel ) } composable( - route = MainDestinations.SEARCH_UI_ROUTE, + route = MainDestinations.SEARCH_UI_ROUTE ) { SearchView( onBackClicked = upPress, searchViewModel, navigateToProductDetail, - homeViewModel, + homeViewModel ) } } diff --git a/app/src/main/java/com/movableink/app/data/model/Product.kt b/app/src/main/java/com/movableink/app/data/model/Product.kt index 5c1d8ad..cb86acd 100644 --- a/app/src/main/java/com/movableink/app/data/model/Product.kt +++ b/app/src/main/java/com/movableink/app/data/model/Product.kt @@ -3,14 +3,7 @@ package com.movableink.app.data.model import androidx.compose.runtime.Stable @Stable -data class Product( - val id: String, - val imageUrl: String, - val price: Long, - val name: String, - val gender: String, - val category: String, -) +data class Product(val id: String, val imageUrl: String, val price: Long, val name: String, val gender: String, val category: String) val productList = listOf( Product( @@ -19,7 +12,7 @@ val productList = listOf( 4450, "Women's Levi's® 505™ Straight Jeans", "women", - "jeans", + "jeans" ), Product( "1695762", @@ -27,7 +20,7 @@ val productList = listOf( 4000, "Women's Gloria Vanderbilt Amanda Classic Tapered Jeans", "women", - "jeans", + "jeans" ), Product( "1731442", @@ -35,7 +28,7 @@ val productList = listOf( 4400, "Women's Plus Size Gloria Vanderbilt Amanda Classic Tapered Jeans", "women", - "jeans", + "jeans" ), Product( "1833330", @@ -43,7 +36,7 @@ val productList = listOf( 17900, "Men's Jean-Paul Germain Classic-Fit Microsuede Blazer", "men", - "suitJackets", + "suitJackets" ), Product( "1878818", @@ -51,7 +44,7 @@ val productList = listOf( 4500, "Women's Lee Modern Fit Curvy Bootcut Jeans", "women", - "jeans", + "jeans" ), Product( "2263298", @@ -59,7 +52,7 @@ val productList = listOf( 4000, "Women's Lee Relaxed Fit Straight Leg Jeans", "women", - "jeans", + "jeans" ), Product( "2375187", @@ -67,7 +60,7 @@ val productList = listOf( 4200, "Women's Simply Vera Vera Wang Rivet Denim Leggings", "women", - "jeans", + "jeans" ), Product( "2403210", @@ -75,7 +68,7 @@ val productList = listOf( 22000, "Men's Chaps Performance Classic-Fit Wool-Blend Comfort Stretch Suit Jacket", "men", - "suitJackets", + "suitJackets" ), Product( "2426788", @@ -83,7 +76,7 @@ val productList = listOf( 30000, "Men's Apt. 9® Slim-Fit Unhemmed Suit", "men", - "dressSuit", + "dressSuit" ), Product( "2439667", @@ -91,7 +84,7 @@ val productList = listOf( 22000, "Men's Chaps Classic-Fit Wool-Blend Performance Suit Jacket", "men", - "suitJackets", + "suitJackets" ), Product( "2447810", @@ -99,7 +92,7 @@ val productList = listOf( 30000, "Men's Croft & Barrow Classic-Fit Unhemmed Suit", "men", - "dressSuit", + "dressSuit" ), Product( "2467840", @@ -107,7 +100,7 @@ val productList = listOf( 3600, "Women's Briggs Comfort Waistband A-Line Skirt", "women", - "skirts", + "skirts" ), Product( "2480979", @@ -115,7 +108,7 @@ val productList = listOf( 24000, "Men's Marc Anthony Slim-Fit Stretch Suit Jacket", "men", - "suitJackets", + "suitJackets" ), Product( "2481364", @@ -123,7 +116,7 @@ val productList = listOf( 3000, "Women's Tek Gear® Knit Workout Skort", "women", - "skirts", + "skirts" ), Product( "2516619", @@ -131,7 +124,7 @@ val productList = listOf( 3400, "Men's Croft & Barrow® Patterned Tie", "men", - "ties", + "ties" ), Product( "2527130", @@ -139,7 +132,7 @@ val productList = listOf( 22000, "Men's Van Heusen Flex Slim-Fit Suit Jacket", "men", - "suitJackets", + "suitJackets" ), Product( "2591560", @@ -147,7 +140,7 @@ val productList = listOf( 7498, "Women's Chaps Pleated Sheath Dress", "women", - "dresses", + "dresses" ), Product( "2599191", @@ -155,7 +148,7 @@ val productList = listOf( 6000, "Men's Columbia Flattop Ridge Fleece Jacket", "men", - "jackets", + "jackets" ), Product( "2608418", @@ -163,7 +156,7 @@ val productList = listOf( 12999, "Men's Columbia Rockaway Mountain Interchange Systems Jacket", "men", - "jackets", + "jackets" ), Product( "2694388", @@ -171,7 +164,7 @@ val productList = listOf( 13499, "Men's Towne Wool-Blend Double-Breasted Peacoat with Plaid Scarf", "men", - "jackets", + "jackets" ), Product( "2728436", @@ -179,7 +172,7 @@ val productList = listOf( 22000, "Men's J.M. Haggar Premium Slim-Fit Stretch Suit Coat", "men", - "suitJackets", + "suitJackets" ), Product( "2753275", @@ -187,7 +180,7 @@ val productList = listOf( 3699, "Women's White Mark Solid Midi Skirt", "women", - "skirts", + "skirts" ), Product( "2783785", @@ -195,7 +188,7 @@ val productList = listOf( 18000, "Men's Apt. 9® Premier Flex Slim-Fit Suit Coat", "men", - "suitJackets", + "suitJackets" ), Product( "2852223", @@ -203,7 +196,7 @@ val productList = listOf( 8999, "Men's Columbia Wister Slope Colorblock Thermal Coil Insulated Jacket", "men", - "jackets", + "jackets" ), Product( "2871342", @@ -211,7 +204,7 @@ val productList = listOf( 3999, "Men's ZeroXposur Rocker Softshell Jacket", "men", - "jackets", + "jackets" ), Product( "2874625", @@ -219,7 +212,7 @@ val productList = listOf( 3500, "Men's Champion Fleece Powerblend Top", "men", - "shirts", + "shirts" ), Product( "2877645", @@ -227,7 +220,7 @@ val productList = listOf( 9999, "Men's Columbia Rapid Excursion Thermal Coil Puffer Jacket", "men", - "jackets", + "jackets" ), Product( "2881280", @@ -235,7 +228,7 @@ val productList = listOf( 3500, "Women's Apt. 9® Embellished Bootcut Jeans", "men", - "jeans", + "jeans" ), Product( "2898455", @@ -243,7 +236,7 @@ val productList = listOf( 4999, "Men's Heat Keep Nano Modern-Fit Packable Puffer Jacket", "men", - "jackets", + "jackets" ), Product( "2900935", @@ -251,7 +244,7 @@ val productList = listOf( 1998, "Men's Urban Pipeline® Awesomely Soft Ultimate Plaid Flannel Shirt", "men", - "shirts", + "shirts" ), Product( "2939320", @@ -259,7 +252,7 @@ val productList = listOf( 9399, "Men's Andrew Marc Wool-Blend Peacoat", "men", - "jackets", + "jackets" ), Product( "2957101", @@ -267,7 +260,7 @@ val productList = listOf( 1499, "Men's Croft & Barrow® Classic-Fit Easy-Care Henley", "men", - "shirts", + "shirts" ), Product( "2957114", @@ -275,7 +268,7 @@ val productList = listOf( 1698, "Men's Croft & Barrow® Classic-Fit Easy-Care Interlock Polo", "men", - "shirts", + "shirts" ), Product( "2959247", @@ -283,7 +276,7 @@ val productList = listOf( 1499, "Men's Croft & Barrow® True Comfort Plaid Classic-Fit Flannel Button-Down Shirt", "men", - "shirts", + "shirts" ), Product( "2962920", @@ -291,7 +284,7 @@ val productList = listOf( 5000, "Women's Simply Vera Vera Wang Skinny Jeans", "women", - "jeans", + "jeans" ), Product( "2964013", @@ -299,7 +292,7 @@ val productList = listOf( 3199, "LC Lauren Conrad Runway Collection Pleated Velvet Skirt - Women's", "wommen", - "skirts", + "skirts" ), Product( "2964826", @@ -307,7 +300,7 @@ val productList = listOf( 2499, "Women's Apt. 9® Tummy Control Pull-On Pencil Skirt", "women", - "skirts", + "skirts" ), Product( "2971290", @@ -315,7 +308,7 @@ val productList = listOf( 6400, "Men's Chaps Classic-Fit Corduroy Stretch Sport Coat", "men", - "suitJackets", + "suitJackets" ), Product( "2972771", @@ -323,7 +316,7 @@ val productList = listOf( 6400, "Men's Van Heusen Flex Slim-Fit Sport Coat", "men", - "suitJackets", + "suitJackets" ), Product( "2980246", @@ -331,7 +324,7 @@ val productList = listOf( 1499, "Men's Croft & Barrow® Arctic Fleece Quarter-Zip Pullover", "men", - "shirts", + "shirts" ), Product( "2982007", @@ -339,7 +332,7 @@ val productList = listOf( 4000, "Women's Wallflower Luscious Curvy Bootcut Jeans", "women", - "jeans", + "jeans" ), Product( "2984389", @@ -347,7 +340,7 @@ val productList = listOf( 4000, "Women's Tek Gear® Hooded Long Sleeve Dress", "women", - "dresses", + "dresses" ), Product( "2995056", @@ -355,7 +348,7 @@ val productList = listOf( 1499, "Women's Croft & Barrow® Essential Ribbed Turtleneck Sweater", "women", - "sweaters", + "sweaters" ), Product( "2999682", @@ -363,7 +356,7 @@ val productList = listOf( 2499, "Women's Apt. 9® Cozy Shawl Collar Cardigan", "men", - "sweaters", + "sweaters" ), Product( "3003041", @@ -371,7 +364,7 @@ val productList = listOf( 2999, "Women's Apt. 9® Fit & Flare Dress", "men", - "dresses", + "dresses" ), Product( "3009587", @@ -379,7 +372,7 @@ val productList = listOf( 3699, "Men's New Balance Sherpa-Lined Polar Fleece Hooded Jacket", "men", - "jackets", + "jackets" ), Product( "3021766", @@ -387,7 +380,7 @@ val productList = listOf( 1499, "Women's SONOMA Goods for Life™ Lattice Sweater", "women", - "sweaters", + "sweaters" ), Product( "3024658", @@ -395,7 +388,7 @@ val productList = listOf( 9999, "Men's Free Country 3-in-1 Systems Jacket", "men", - "jackets", + "jackets" ), Product( "3028158", @@ -403,7 +396,7 @@ val productList = listOf( 2499, "Women's Apt. 9® Lace Yoke A-Line Dress", "men", - "dresses", + "dresses" ), Product( "3036618", @@ -411,7 +404,7 @@ val productList = listOf( 1199, "Big & Tall Croft & Barrow® Classic-Fit Easy-Care Interlock Polo", "men", - "shirts", + "shirts" ), Product( "3040746", @@ -419,7 +412,7 @@ val productList = listOf( 8800, "Women's Rock & Republic® Fever Denim Rx™ Pull-On Jean Leggings", "men", - "jeans", + "jeans" ), Product( "3054934", @@ -427,7 +420,7 @@ val productList = listOf( 3899, "Chaps Women's Metallic Faux-Suede Pleated Midi Skirt", "women", - "skirts", + "skirts" ), Product( "3057086", @@ -435,7 +428,7 @@ val productList = listOf( 3200, "Women's Dana Buchman Mitered Cowlneck Sweater Dress", "women", - "dresses", + "dresses" ), Product( "3063706", @@ -443,7 +436,7 @@ val productList = listOf( 8199, "Women's Chaps Satin Trim Jersey Dress", "women", - "dresses", + "dresses" ), Product( "567950", @@ -451,7 +444,7 @@ val productList = listOf( 7998, "Men's Croft & Barrow® True Comfort Classic-Fit Sport Coat", "men", - "suitJackets", + "suitJackets" ), Product( "825463", @@ -459,7 +452,7 @@ val productList = listOf( 3200, "Men's Croft & Barrow® Classic-Fit Easy Care Point-Collar Dress Shirt", "men", - "suitJackets", + "suitJackets" ), Product( "c1193954", @@ -467,7 +460,7 @@ val productList = listOf( 15000, "Men's Haggar Travel Tailored-Fit Performance Suit Separates", "men", - "dressSuit", + "dressSuit" ), Product( "c1193957", @@ -475,7 +468,7 @@ val productList = listOf( 14500, "Men's Marc Anthony Slim-Fit Stretch Suit Separates", "men", - "dressSuit", + "dressSuit" ), Product( "c1569952", @@ -483,7 +476,7 @@ val productList = listOf( 14000, "Men's Apt. 9® Premier Flex Extra-Slim Fit Suit Separates", "men", - "dressSuit", + "dressSuit" ), Product( "c1621950", @@ -491,7 +484,7 @@ val productList = listOf( 18000, "Men's J.M. Haggar Premium Slim-Fit Stretch Suit Separates", "men", - "dressSuit", + "dressSuit" ), Product( "c1672950", @@ -499,7 +492,7 @@ val productList = listOf( 13000, "Men's Apt. 9® Slim-Fit Stretch Suit Separates", "men", - "dressSuit", + "dressSuit" ), Product( "c1672951", @@ -507,7 +500,7 @@ val productList = listOf( 13500, "Men's Apt. 9® Extra-Slim Fit Stretch Suit Separates", "men", - "dressSuit", + "dressSuit" ), Product( "c890950", @@ -515,6 +508,6 @@ val productList = listOf( 15999, "Men's Chaps Performance Classic-Fit Wool-Blend Stretch Suit Separates", "men", - "dressSuit", - ), + "dressSuit" + ) ) diff --git a/app/src/main/java/com/movableink/app/data/model/SnackBarManager.kt b/app/src/main/java/com/movableink/app/data/model/SnackBarManager.kt index 7a26687..2542174 100644 --- a/app/src/main/java/com/movableink/app/data/model/SnackBarManager.kt +++ b/app/src/main/java/com/movableink/app/data/model/SnackBarManager.kt @@ -1,11 +1,11 @@ package com.movableink.app.data.model import androidx.annotation.StringRes +import java.util.UUID import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update -import java.util.UUID data class Message(val id: Long, @StringRes val messageId: Int) @@ -18,7 +18,7 @@ object SnackbarManager { _messages.update { currentMessages -> currentMessages + Message( id = UUID.randomUUID().mostSignificantBits, - messageId = messageTextId, + messageId = messageTextId ) } } diff --git a/app/src/main/java/com/movableink/app/data/repository/MovableRepository.kt b/app/src/main/java/com/movableink/app/data/repository/MovableRepository.kt index 0427756..a600643 100644 --- a/app/src/main/java/com/movableink/app/data/repository/MovableRepository.kt +++ b/app/src/main/java/com/movableink/app/data/repository/MovableRepository.kt @@ -12,6 +12,5 @@ object MovableRepository { fun getProductsByCategoryAndGender(selectedCategory: String, gender: String): List = productList.filter { it.category == selectedCategory && it.gender.contains(gender, ignoreCase = true) } - fun getProductById(id: String) = - productList.find { it.id == id } + fun getProductById(id: String) = productList.find { it.id == id } } diff --git a/app/src/main/java/com/movableink/app/ui/component/CheckoutDialog.kt b/app/src/main/java/com/movableink/app/ui/component/CheckoutDialog.kt index c3a0b27..423cd73 100644 --- a/app/src/main/java/com/movableink/app/ui/component/CheckoutDialog.kt +++ b/app/src/main/java/com/movableink/app/ui/component/CheckoutDialog.kt @@ -36,24 +36,24 @@ fun CheckoutDialog(setShowDialog: (Boolean) -> Unit, cartViewModel: CartViewMode Dialog(onDismissRequest = { setShowDialog(false) }) { Surface( shape = RoundedCornerShape(16.dp), - color = Color.White, + color = Color.White ) { Box( - contentAlignment = Alignment.Center, + contentAlignment = Alignment.Center ) { Column(modifier = Modifier.padding(16.dp)) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = "Buy Products?", style = TextStyle( fontSize = 24.sp, fontFamily = FontFamily.Default, - fontWeight = FontWeight.Bold, - ), + fontWeight = FontWeight.Bold + ) ) Icon( imageVector = Icons.Filled.Close, @@ -62,7 +62,7 @@ fun CheckoutDialog(setShowDialog: (Boolean) -> Unit, cartViewModel: CartViewMode modifier = Modifier .width(30.dp) .height(30.dp) - .clickable { setShowDialog(true) }, + .clickable { setShowDialog(true) } ) } @@ -79,7 +79,7 @@ fun CheckoutDialog(setShowDialog: (Boolean) -> Unit, cartViewModel: CartViewMode shape = RoundedCornerShape(50.dp), modifier = Modifier .fillMaxWidth() - .height(50.dp), + .height(50.dp) ) { Text(text = "Buy Items") } diff --git a/app/src/main/java/com/movableink/app/ui/component/MovableSearchBar.kt b/app/src/main/java/com/movableink/app/ui/component/MovableSearchBar.kt index a93a5be..9f37ccd 100644 --- a/app/src/main/java/com/movableink/app/ui/component/MovableSearchBar.kt +++ b/app/src/main/java/com/movableink/app/ui/component/MovableSearchBar.kt @@ -21,7 +21,7 @@ import androidx.compose.material.Text import androidx.compose.material.TextFieldDefaults import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Close import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -57,19 +57,19 @@ fun MovableSearchBar( matchesFound: Boolean, matchList: List, onResultClick: (product: String) -> Unit = {}, - homeViewModel: HomeViewModel, + homeViewModel: HomeViewModel ) { Box { Column( modifier = Modifier - .fillMaxSize(), + .fillMaxSize() ) { SearchBar( searchText, placeholderText, onSearchTextChanged, onClearClick, - onNavigateBack, + onNavigateBack ) if (matchesFound) { Text(stringResource(id = R.string.searchResults), modifier = Modifier.padding(8.dp), fontWeight = FontWeight.Bold) @@ -91,7 +91,7 @@ fun SearchBar( placeholderText: String = "", onSearchTextChanged: (String) -> Unit = {}, onClearClick: () -> Unit = {}, - onNavigateBack: () -> Unit = {}, + onNavigateBack: () -> Unit = {} ) { var showClearButton by remember { mutableStateOf(false) } val keyboardController = LocalSoftwareKeyboardController.current @@ -100,9 +100,9 @@ fun SearchBar( TopAppBar(title = { Text("") }, navigationIcon = { IconButton(onClick = { onNavigateBack() }) { Icon( - imageVector = Icons.Filled.ArrowBack, + imageVector = Icons.AutoMirrored.Filled.ArrowBack, modifier = Modifier, - contentDescription = stringResource(id = R.string.app_name), + contentDescription = stringResource(id = R.string.app_name) ) } }, actions = { @@ -123,18 +123,18 @@ fun SearchBar( focusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent, backgroundColor = Color.Transparent, - cursorColor = LocalContentColor.current.copy(alpha = LocalContentAlpha.current), + cursorColor = LocalContentColor.current.copy(alpha = LocalContentAlpha.current) ), trailingIcon = { AnimatedVisibility( visible = showClearButton, enter = fadeIn(), - exit = fadeOut(), + exit = fadeOut() ) { IconButton(onClick = { onClearClick() }) { Icon( imageVector = Icons.Filled.Close, - contentDescription = stringResource(id = R.string.app_name), + contentDescription = stringResource(id = R.string.app_name) ) } } @@ -144,7 +144,7 @@ fun SearchBar( keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done), keyboardActions = KeyboardActions(onDone = { keyboardController?.hide() - }), + }) ) }) @@ -158,18 +158,14 @@ fun NoSearchResults() { Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, - horizontalAlignment = CenterHorizontally, + horizontalAlignment = CenterHorizontally ) { Text(stringResource(id = R.string.noResults)) } } @Composable -fun ResultsFoundView( - products: List?, - onResultClick: (product: String) -> Unit, - homeViewModel: HomeViewModel, -) { +fun ResultsFoundView(products: List?, onResultClick: (product: String) -> Unit, homeViewModel: HomeViewModel) { SearchProductList(products = products) { product -> homeViewModel.updateSelectedProduct(product.id) onResultClick(product.id) diff --git a/app/src/main/java/com/movableink/app/ui/component/MovableSnackSnackBar.kt b/app/src/main/java/com/movableink/app/ui/component/MovableSnackSnackBar.kt index 853f229..24a0ad8 100644 --- a/app/src/main/java/com/movableink/app/ui/component/MovableSnackSnackBar.kt +++ b/app/src/main/java/com/movableink/app/ui/component/MovableSnackSnackBar.kt @@ -19,7 +19,7 @@ fun MovableSnackSnackBar( backgroundColor: Color = MaterialTheme.colors.onSecondary, contentColor: Color = Color.White, actionColor: Color = Color.Cyan, - elevation: Dp = 12.dp, + elevation: Dp = 12.dp ) { Snackbar( snackbarData = snackbarData, @@ -29,6 +29,6 @@ fun MovableSnackSnackBar( backgroundColor = backgroundColor, contentColor = contentColor, actionColor = actionColor, - elevation = elevation, + elevation = elevation ) } diff --git a/app/src/main/java/com/movableink/app/ui/component/MovableTopBar.kt b/app/src/main/java/com/movableink/app/ui/component/MovableTopBar.kt index af248d2..d9269a2 100644 --- a/app/src/main/java/com/movableink/app/ui/component/MovableTopBar.kt +++ b/app/src/main/java/com/movableink/app/ui/component/MovableTopBar.kt @@ -19,7 +19,7 @@ fun MovableTopBar(modifier: Modifier = Modifier, title: String) { TopAppBar( backgroundColor = MaterialTheme.colors.primaryVariant, contentColor = Color.Black, - elevation = 0.dp, + elevation = 0.dp ) { Text( text = title, @@ -30,7 +30,7 @@ fun MovableTopBar(modifier: Modifier = Modifier, title: String) { overflow = TextOverflow.Ellipsis, modifier = Modifier .weight(1f) - .align(Alignment.CenterVertically), + .align(Alignment.CenterVertically) ) } } diff --git a/app/src/main/java/com/movableink/app/ui/component/SearchResults.kt b/app/src/main/java/com/movableink/app/ui/component/SearchResults.kt index cbf0ec2..691b0b6 100644 --- a/app/src/main/java/com/movableink/app/ui/component/SearchResults.kt +++ b/app/src/main/java/com/movableink/app/ui/component/SearchResults.kt @@ -38,7 +38,7 @@ fun SearchRow(product: Product, onClick: () -> Unit) { modifier = Modifier .fillMaxWidth() .padding(8.dp) - .clickable { onClick() }, + .clickable { onClick() } ) { Text(product.name, fontSize = 14.sp, fontWeight = FontWeight.Bold) Spacer(modifier = Modifier.height(2.dp)) diff --git a/app/src/main/java/com/movableink/app/ui/navigation/BottomNav.kt b/app/src/main/java/com/movableink/app/ui/navigation/BottomNav.kt index b8f64d6..d550493 100644 --- a/app/src/main/java/com/movableink/app/ui/navigation/BottomNav.kt +++ b/app/src/main/java/com/movableink/app/ui/navigation/BottomNav.kt @@ -69,12 +69,12 @@ fun NavGraphBuilder.addHomeGraph( cartViewModel: CartViewModel, homeViewModel: HomeViewModel, searchViewModel: SearchViewModel, - navigateToProductDetail: (String) -> Unit, + navigateToProductDetail: (String) -> Unit ) { composable(HomeSections.HOME.route) { from -> HomeScreen( onGenderSelected = { gender -> onGenderSelected(gender, from) }, - homeViewModel = homeViewModel, + homeViewModel = homeViewModel ) } composable(HomeSections.SEARCH.route) { from -> @@ -82,7 +82,7 @@ fun NavGraphBuilder.addHomeGraph( onSearchBarClick = { onSearchBarClick(from) }, searchViewModel, homeViewModel, - navigateToProductDetail = { product -> navigateToProductDetail(product) }, + navigateToProductDetail = { product -> navigateToProductDetail(product) } ) } composable(HomeSections.CART.route) { @@ -90,14 +90,10 @@ fun NavGraphBuilder.addHomeGraph( } } -enum class HomeSections( - @StringRes val title: Int, - val icon: ImageVector, - val route: String, -) { +enum class HomeSections(@StringRes val title: Int, val icon: ImageVector, val route: String) { HOME(R.string.home_feed, Icons.Outlined.Home, "home/init"), SEARCH(R.string.home_search, Icons.Outlined.Search, "home/search"), - CART(R.string.home_cart, Icons.Outlined.ShoppingCart, "home/cart"), + CART(R.string.home_cart, Icons.Outlined.ShoppingCart, "home/cart") } @Suppress("ktlint:standard:function-naming") @@ -107,27 +103,27 @@ fun MovableBottomBar( currentRoute: String, navigateToRoute: (String) -> Unit, color: Color = MaterialTheme.colors.primaryVariant, - contentColor: Color = Color.Cyan, + contentColor: Color = Color.Cyan ) { val routes = remember { tabs.map { it.route } } val currentSection = tabs.first { it.route == currentRoute } Surface( color = color, - contentColor = contentColor, + contentColor = contentColor ) { val springSpec = SpringSpec( // Determined experimentally stiffness = 800f, - dampingRatio = 0.8f, + dampingRatio = 0.8f ) BottomNavLayout( selectedIndex = currentSection.ordinal, itemCount = routes.size, indicator = { BottomNavIndicator() }, animSpec = springSpec, - modifier = Modifier.navigationBarsPadding(), + modifier = Modifier.navigationBarsPadding() ) { val configuration = LocalConfiguration.current val currentLocale: Locale = @@ -141,7 +137,7 @@ fun MovableBottomBar( } else { Color.LightGray }, - label = "", + label = "" ) val text = stringResource(section.title).uppercase(currentLocale) @@ -151,7 +147,7 @@ fun MovableBottomBar( Icon( imageVector = section.icon, tint = tint, - contentDescription = text, + contentDescription = text ) }, text = { @@ -159,15 +155,15 @@ fun MovableBottomBar( text = text, color = tint, style = MaterialTheme.typography.button, - maxLines = 1, + maxLines = 1 ) }, selected = selected, onSelected = { navigateToRoute(section.route) }, animSpec = springSpec, modifier = - BottomNavigationItemPadding - .clip(BottomNavIndicatorShape), + BottomNavigationItemPadding + .clip(BottomNavIndicatorShape) ) } } @@ -181,7 +177,7 @@ private fun BottomNavLayout( animSpec: AnimationSpec, indicator: @Composable BoxScope.() -> Unit, modifier: Modifier = Modifier, - content: @Composable () -> Unit, + content: @Composable () -> Unit ) { val selectionFractions = remember(itemCount) { @@ -208,7 +204,7 @@ private fun BottomNavLayout( content = { content() Box(Modifier.layoutId("indicator"), content = indicator) - }, + } ) { measurables, constraints -> check(itemCount == (measurables.size - 1)) // account for indicator @@ -226,21 +222,21 @@ private fun BottomNavLayout( measurable.measure( constraints.copy( minWidth = width, - maxWidth = width, - ), + maxWidth = width + ) ) } val indicatorPlaceable = indicatorMeasurable.measure( constraints.copy( minWidth = selectedWidth, - maxWidth = selectedWidth, - ), + maxWidth = selectedWidth + ) ) layout( width = constraints.maxWidth, - height = itemPlaceables.maxByOrNull { it.height }?.height ?: 0, + height = itemPlaceables.maxByOrNull { it.height }?.height ?: 0 ) { val indicatorLeft = indicatorIndex.value * unselectedWidth indicatorPlaceable.placeRelative(x = indicatorLeft.toInt(), y = 0) @@ -260,7 +256,7 @@ fun BottomNavigationItem( selected: Boolean, onSelected: () -> Unit, animSpec: AnimationSpec, - modifier: Modifier = Modifier, + modifier: Modifier = Modifier ) { // Animate the icon/text positions within the item based on selection val animationProgress by animateFloatAsState(if (selected) 1f else 0f, animSpec) @@ -269,9 +265,9 @@ fun BottomNavigationItem( text = text, animationProgress = animationProgress, modifier = - modifier - .selectable(selected = selected, onClick = onSelected) - .wrapContentSize(), + modifier + .selectable(selected = selected, onClick = onSelected) + .wrapContentSize() ) } @@ -280,33 +276,33 @@ private fun BottomNavItemLayout( icon: @Composable BoxScope.() -> Unit, text: @Composable BoxScope.() -> Unit, @FloatRange(from = 0.0, to = 1.0) animationProgress: Float, - modifier: Modifier = Modifier, + modifier: Modifier = Modifier ) { Layout( modifier = modifier, content = { Box( modifier = - Modifier - .layoutId("icon") - .padding(horizontal = TextIconSpacing), - content = icon, + Modifier + .layoutId("icon") + .padding(horizontal = TextIconSpacing), + content = icon ) val scale = lerp(0.6f, 1f, animationProgress) Box( modifier = - Modifier - .layoutId("text") - .padding(horizontal = TextIconSpacing) - .graphicsLayer { - alpha = animationProgress - scaleX = scale - scaleY = scale - transformOrigin = BottomNavLabelTransformOrigin - }, - content = text, + Modifier + .layoutId("text") + .padding(horizontal = TextIconSpacing) + .graphicsLayer { + alpha = animationProgress + scaleX = scale + scaleY = scale + transformOrigin = BottomNavLabelTransformOrigin + }, + content = text ) - }, + } ) { measurables, constraints -> val iconPlaceable = measurables.first { it.layoutId == "icon" }.measure(constraints) val textPlaceable = measurables.first { it.layoutId == "text" }.measure(constraints) @@ -316,7 +312,7 @@ private fun BottomNavItemLayout( iconPlaceable, constraints.maxWidth, constraints.maxHeight, - animationProgress, + animationProgress ) } } @@ -326,7 +322,7 @@ private fun MeasureScope.placeTextAndIcon( iconPlaceable: Placeable, width: Int, height: Int, - @FloatRange(from = 0.0, to = 1.0) animationProgress: Float, + @FloatRange(from = 0.0, to = 1.0) animationProgress: Float ): MeasureResult { val iconY = (height - iconPlaceable.height) / 2 val textY = (height - textPlaceable.height) / 2 @@ -344,17 +340,13 @@ private fun MeasureScope.placeTextAndIcon( } @Composable -private fun BottomNavIndicator( - strokeWidth: Dp = 2.dp, - color: Color = Color.White, - shape: Shape = BottomNavIndicatorShape, -) { +private fun BottomNavIndicator(strokeWidth: Dp = 2.dp, color: Color = Color.White, shape: Shape = BottomNavIndicatorShape) { Spacer( modifier = - Modifier - .fillMaxSize() - .then(BottomNavigationItemPadding) - .border(strokeWidth, color, shape), + Modifier + .fillMaxSize() + .then(BottomNavigationItemPadding) + .border(strokeWidth, color, shape) ) } @@ -371,7 +363,7 @@ private fun BottomNavPreview() { MovableBottomBar( tabs = HomeSections.values(), currentRoute = "home/init", - navigateToRoute = { }, + navigateToRoute = { } ) } } diff --git a/app/src/main/java/com/movableink/app/ui/screens/cart/Cart.kt b/app/src/main/java/com/movableink/app/ui/screens/cart/Cart.kt index 20dbc35..8d41a44 100644 --- a/app/src/main/java/com/movableink/app/ui/screens/cart/Cart.kt +++ b/app/src/main/java/com/movableink/app/ui/screens/cart/Cart.kt @@ -32,9 +32,7 @@ import com.movableink.app.ui.screens.home.BottomBarHeight import com.movableink.app.ui.screens.home.ScreenDivider @Composable -fun Cart( - viewModel: CartViewModel, -) { +fun Cart(viewModel: CartViewModel) { val cartUiState by viewModel.uiState.collectAsState() val cartList = cartUiState.cart var showDialog by remember { mutableStateOf(false) } @@ -62,7 +60,7 @@ fun Cart( modifier = Modifier .navigationBarsPadding() .then(Modifier.padding(horizontal = 24.dp)) - .heightIn(min = BottomBarHeight), + .heightIn(min = BottomBarHeight) ) { Spacer(Modifier.width(16.dp)) Button( @@ -71,13 +69,13 @@ fun Cart( }, modifier = Modifier .weight(1f) - .padding(all = 16.dp), + .padding(all = 16.dp) ) { Text( text = "Checkout ", modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center, - maxLines = 1, + maxLines = 1 ) } Spacer(Modifier.width(16.dp)) @@ -92,7 +90,7 @@ fun Cart( text = stringResource(R.string.empty_cart), style = MaterialTheme.typography.h4, textAlign = TextAlign.Center, - modifier = Modifier.fillMaxWidth(), + modifier = Modifier.fillMaxWidth() ) } } diff --git a/app/src/main/java/com/movableink/app/ui/screens/cart/CartItem.kt b/app/src/main/java/com/movableink/app/ui/screens/cart/CartItem.kt index 982680e..5f2a04d 100644 --- a/app/src/main/java/com/movableink/app/ui/screens/cart/CartItem.kt +++ b/app/src/main/java/com/movableink/app/ui/screens/cart/CartItem.kt @@ -37,12 +37,12 @@ fun CartItem(product: Product) { .padding(8.dp) .clip(RoundedCornerShape(16.dp)), elevation = 0.dp, - backgroundColor = Color.Gray, + backgroundColor = Color.Gray ) { Row( modifier = Modifier .fillMaxWidth() - .padding(16.dp), + .padding(16.dp) ) { val drawable = getDrawableId(product.imageUrl) ?: R.drawable.placeholder @@ -54,7 +54,7 @@ fun CartItem(product: Product) { painter = image, alignment = Alignment.CenterStart, contentDescription = "", - contentScale = ContentScale.Crop, + contentScale = ContentScale.Crop ) Spacer(modifier = Modifier.width(16.dp)) @@ -65,18 +65,18 @@ fun CartItem(product: Product) { modifier = Modifier.padding(0.dp, 0.dp, 12.dp, 0.dp), color = MaterialTheme.colors.surface, fontWeight = FontWeight.Bold, - style = MaterialTheme.typography.subtitle1, + style = MaterialTheme.typography.subtitle1 ) Spacer(modifier = Modifier.height(8.dp)) Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.End, + horizontalArrangement = Arrangement.End ) { Text( text = formatPrice(product.price), modifier = Modifier.padding(8.dp, 12.dp, 12.dp, 0.dp), color = Color.Black, - style = MaterialTheme.typography.button, + style = MaterialTheme.typography.button ) } Text( @@ -87,7 +87,7 @@ fun CartItem(product: Product) { }, modifier = Modifier.padding(0.dp, 0.dp, 12.dp, 0.dp), color = MaterialTheme.colors.surface, - style = MaterialTheme.typography.caption, + style = MaterialTheme.typography.caption ) } } diff --git a/app/src/main/java/com/movableink/app/ui/screens/cart/CartViewModel.kt b/app/src/main/java/com/movableink/app/ui/screens/cart/CartViewModel.kt index 43168b6..5eca092 100644 --- a/app/src/main/java/com/movableink/app/ui/screens/cart/CartViewModel.kt +++ b/app/src/main/java/com/movableink/app/ui/screens/cart/CartViewModel.kt @@ -11,10 +11,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update -class CartViewModel( - private val snackbarManager: SnackbarManager, - repository: MovableRepository, -) : ViewModel() { +class CartViewModel(private val snackbarManager: SnackbarManager, repository: MovableRepository) : ViewModel() { private val _uiState = MutableStateFlow(CartState()) val uiState: StateFlow = _uiState.asStateFlow() @@ -22,7 +19,7 @@ class CartViewModel( val updatedCart = _uiState.value.cart.plus(product) _uiState.update { currentState -> currentState.copy( - cart = updatedCart, + cart = updatedCart ) } snackbarManager.showMessage(R.string.cart_updated) @@ -36,7 +33,7 @@ class CartViewModel( val updatedCart = listOf() _uiState.update { currentState -> currentState.copy( - cart = updatedCart, + cart = updatedCart ) } snackbarManager.showMessage(R.string.cart_checked_out) @@ -44,15 +41,11 @@ class CartViewModel( companion object { fun provideFactory( snackbarManager: SnackbarManager = SnackbarManager, - movableRepository: MovableRepository = MovableRepository, + movableRepository: MovableRepository = MovableRepository ): ViewModelProvider.Factory = object : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") - override fun create(modelClass: Class): T { - return CartViewModel(snackbarManager, movableRepository) as T - } + override fun create(modelClass: Class): T = CartViewModel(snackbarManager, movableRepository) as T } } } -data class CartState( - val cart: List = arrayListOf(), -) +data class CartState(val cart: List = arrayListOf()) diff --git a/app/src/main/java/com/movableink/app/ui/screens/home/CatalogScreen.kt b/app/src/main/java/com/movableink/app/ui/screens/home/CatalogScreen.kt index 5c28db4..79c4bcd 100644 --- a/app/src/main/java/com/movableink/app/ui/screens/home/CatalogScreen.kt +++ b/app/src/main/java/com/movableink/app/ui/screens/home/CatalogScreen.kt @@ -33,7 +33,7 @@ import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.ShoppingCart import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState @@ -69,7 +69,7 @@ fun CatalogScreen( onBackClicked: () -> Unit, viewModel: CartViewModel, onViewCart: () -> Unit, - homeViewModel: HomeViewModel, + homeViewModel: HomeViewModel ) { val homeUIState by homeViewModel.homeUIState.collectAsStateWithLifecycle() @@ -79,12 +79,12 @@ fun CatalogScreen( Column( modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(10.dp), + verticalArrangement = Arrangement.spacedBy(10.dp) ) { Spacer( Modifier.windowInsetsTopHeight( - WindowInsets.statusBars.add(WindowInsets(top = 60.dp)), - ), + WindowInsets.statusBars.add(WindowInsets(top = 60.dp)) + ) ) if (cartUiState.cart.isNotEmpty()) { CartItems(cartUiState.cart, onViewCart) @@ -95,15 +95,11 @@ fun CatalogScreen( } @Composable -private fun Products( - products: List, - onProductClick: (String) -> Unit, - homeViewModel: HomeViewModel, -) { +private fun Products(products: List, onProductClick: (String) -> Unit, homeViewModel: HomeViewModel) { LazyVerticalGrid( columns = GridCells.Fixed(2), verticalArrangement = Arrangement.spacedBy(16.dp), - horizontalArrangement = Arrangement.spacedBy(16.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp) ) { items(products) { product -> ProductItem(product, onProductClick, homeViewModel) @@ -112,19 +108,14 @@ private fun Products( } @Composable -fun ProductItem( - product: Product, - onProductClick: (String) -> Unit, - homeViewModel: HomeViewModel, - modifier: Modifier = Modifier, -) { +fun ProductItem(product: Product, onProductClick: (String) -> Unit, homeViewModel: HomeViewModel, modifier: Modifier = Modifier) { Card( modifier = modifier .size( width = 250.dp, - height = 250.dp, - ).padding(all = 10.dp), + height = 250.dp + ).padding(all = 10.dp) ) { Column( modifier = @@ -134,7 +125,7 @@ fun ProductItem( MIClient.productViewed(mapOf("id" to product.id)) onProductClick(product.id) }) - .fillMaxSize(), + .fillMaxSize() ) { Box( modifier = @@ -142,8 +133,8 @@ fun ProductItem( .height(160.dp) .fillMaxWidth() .background( - colorResource(id = android.R.color.transparent), - ), + colorResource(id = android.R.color.transparent) + ) ) { ProductImage( imageUrl = product.imageUrl, @@ -151,7 +142,7 @@ fun ProductItem( Modifier .size(120.dp) .padding(8.dp) - .align(Alignment.TopCenter), + .align(Alignment.TopCenter) ) } Text( @@ -160,7 +151,7 @@ fun ProductItem( overflow = TextOverflow.Ellipsis, style = MaterialTheme.typography.body2, color = Color.Black, - modifier = Modifier.padding(horizontal = 16.dp), + modifier = Modifier.padding(horizontal = 16.dp) ) // Spacer(modifier = Modifier.height(4.dp)) Text( @@ -170,21 +161,18 @@ fun ProductItem( modifier = Modifier .align(Alignment.End) - .padding(horizontal = 16.dp), + .padding(horizontal = 16.dp) ) } } } @Composable -fun ProductImage( - imageUrl: String, - modifier: Modifier = Modifier, -) { +fun ProductImage(imageUrl: String, modifier: Modifier = Modifier) { Surface( color = Color.Transparent, shape = RoundedCornerShape(10.dp), - modifier = modifier, + modifier = modifier ) { fetchDrawableByName(imageUrl, context = LocalContext.current).apply { val painter: Painter = painterResource(id = this) @@ -196,24 +184,19 @@ fun ProductImage( painter = painter, alignment = Alignment.CenterStart, contentDescription = "", - contentScale = ContentScale.Crop, + contentScale = ContentScale.Crop ) } } } @Composable -fun CatalogAppBar( - modifier: Modifier = Modifier, - gender: String?, - category: String, - onBackClicked: () -> Unit, -) { +fun CatalogAppBar(modifier: Modifier = Modifier, gender: String?, category: String, onBackClicked: () -> Unit) { Column(modifier = modifier.statusBarsPadding()) { TopAppBar( backgroundColor = MaterialTheme.colors.primaryVariant, contentColor = Color.Black, - elevation = 0.dp, + elevation = 0.dp ) { IconButton( onClick = onBackClicked, @@ -221,12 +204,12 @@ fun CatalogAppBar( Modifier .padding(all = 8.dp) .size(24.dp, 24.dp) - .align(Alignment.CenterVertically), + .align(Alignment.CenterVertically) ) { Icon( - imageVector = Icons.Default.ArrowBack, + imageVector = Icons.AutoMirrored.Filled.ArrowBack, tint = Color.White, - contentDescription = stringResource(R.string.app_name), + contentDescription = stringResource(R.string.app_name) ) } Text( @@ -240,21 +223,18 @@ fun CatalogAppBar( Modifier .weight(1f) .padding(8.dp, 0.dp, 0.dp, 0.dp) - .align(Alignment.CenterVertically), + .align(Alignment.CenterVertically) ) } } } @Composable -fun CartItems( - cart: List, - onViewCart: () -> Unit, -) { +fun CartItems(cart: List, onViewCart: () -> Unit) { ExtendedFloatingActionButton( icon = { Icon(Icons.Filled.ShoppingCart, "") }, text = { Text("View Cart ( ${cart.size} )") }, onClick = onViewCart, - elevation = FloatingActionButtonDefaults.elevation(8.dp), + elevation = FloatingActionButtonDefaults.elevation(8.dp) ) } diff --git a/app/src/main/java/com/movableink/app/ui/screens/home/CategoryScreen.kt b/app/src/main/java/com/movableink/app/ui/screens/home/CategoryScreen.kt index 92c6806..f0b9c1d 100644 --- a/app/src/main/java/com/movableink/app/ui/screens/home/CategoryScreen.kt +++ b/app/src/main/java/com/movableink/app/ui/screens/home/CategoryScreen.kt @@ -22,7 +22,7 @@ import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember @@ -39,11 +39,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.movableink.app.R @Composable -fun CategoryScreen( - onCategoryClick: (String, String) -> Unit, - onBackClicked: () -> Unit, - homeViewModel: HomeViewModel, -) { +fun CategoryScreen(onCategoryClick: (String, String) -> Unit, onBackClicked: () -> Unit, homeViewModel: HomeViewModel) { val homeUIState by homeViewModel.homeUIState.collectAsStateWithLifecycle() val selectedGender = remember { homeUIState.gender @@ -51,13 +47,13 @@ fun CategoryScreen( Column( modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(10.dp), + verticalArrangement = Arrangement.spacedBy(10.dp) ) { Spacer( Modifier.windowInsetsTopHeight( - WindowInsets.statusBars.add(WindowInsets(top = 60.dp)), - ), + WindowInsets.statusBars.add(WindowInsets(top = 60.dp)) + ) ) CategoryList(onCategoryClick, homeUIState.categories, homeUIState.gender, homeViewModel) } @@ -65,18 +61,13 @@ fun CategoryScreen( } @Composable -fun CategoryList( - onCategoryClick: (String, String) -> Unit, - categories: List, - gender: String, - homeViewModel: HomeViewModel, -) { +fun CategoryList(onCategoryClick: (String, String) -> Unit, categories: List, gender: String, homeViewModel: HomeViewModel) { LazyColumn { item { Spacer( Modifier.windowInsetsTopHeight( - WindowInsets.statusBars.add(WindowInsets(top = 28.dp)), - ), + WindowInsets.statusBars.add(WindowInsets(top = 28.dp)) + ) ) } @@ -85,19 +76,14 @@ fun CategoryList( category = category, onCategoryClick = onCategoryClick, gender, - homeViewModel, + homeViewModel ) } } } @Composable -fun CategoryRow( - category: String, - onCategoryClick: (category: String, gender: String) -> Unit, - gender: String, - homeViewModel: HomeViewModel, -) { +fun CategoryRow(category: String, onCategoryClick: (category: String, gender: String) -> Unit, gender: String, homeViewModel: HomeViewModel) { Card( modifier = Modifier .padding(all = 8.dp) @@ -105,14 +91,14 @@ fun CategoryRow( .clickable { homeViewModel.updateCatalogByCategory(category, gender) onCategoryClick(category, gender) - }, + } ) { Row(modifier = Modifier.padding(all = 10.dp)) { Text( text = category, fontSize = 20.sp, fontWeight = FontWeight.ExtraBold, - modifier = Modifier.padding(10.dp), + modifier = Modifier.padding(10.dp) ) } } @@ -124,7 +110,7 @@ fun CategoryBar(modifier: Modifier = Modifier, gender: String?, onBackClicked: ( TopAppBar( backgroundColor = MaterialTheme.colors.primaryVariant, contentColor = Color.Black, - elevation = 0.dp, + elevation = 0.dp ) { IconButton( @@ -132,12 +118,12 @@ fun CategoryBar(modifier: Modifier = Modifier, gender: String?, onBackClicked: ( modifier = Modifier .padding(all = 8.dp) .size(24.dp, 24.dp) - .align(Alignment.CenterVertically), + .align(Alignment.CenterVertically) ) { Icon( - imageVector = Icons.Default.ArrowBack, + imageVector = Icons.AutoMirrored.Filled.ArrowBack, tint = Color.White, - contentDescription = stringResource(R.string.app_name), + contentDescription = stringResource(R.string.app_name) ) } Text( @@ -150,7 +136,7 @@ fun CategoryBar(modifier: Modifier = Modifier, gender: String?, onBackClicked: ( modifier = Modifier .weight(1f) .padding(8.dp, 0.dp, 0.dp, 0.dp) - .align(Alignment.CenterVertically), + .align(Alignment.CenterVertically) ) } } diff --git a/app/src/main/java/com/movableink/app/ui/screens/home/HomeScreen.kt b/app/src/main/java/com/movableink/app/ui/screens/home/HomeScreen.kt index 1032493..02091d8 100644 --- a/app/src/main/java/com/movableink/app/ui/screens/home/HomeScreen.kt +++ b/app/src/main/java/com/movableink/app/ui/screens/home/HomeScreen.kt @@ -35,14 +35,11 @@ import com.movableink.app.R import com.movableink.app.ui.component.MovableTopBar @Composable -fun HomeScreen( - onGenderSelected: (String) -> Unit, - homeViewModel: HomeViewModel, -) { +fun HomeScreen(onGenderSelected: (String) -> Unit, homeViewModel: HomeViewModel) { Surface( modifier = Modifier - .fillMaxSize(), + .fillMaxSize() ) { Box { GenderList(onGenderSelected, homeViewModel) @@ -52,17 +49,14 @@ fun HomeScreen( } @Composable -fun GenderList( - onGenderClick: (String) -> Unit, - homeViewModel: HomeViewModel, -) { +fun GenderList(onGenderClick: (String) -> Unit, homeViewModel: HomeViewModel) { val genderList = remember { listOf("Men", "Women") } LazyColumn { item { Spacer( Modifier.windowInsetsTopHeight( - WindowInsets.statusBars.add(WindowInsets(top = 60.dp)), - ), + WindowInsets.statusBars.add(WindowInsets(top = 60.dp)) + ) ) } @@ -70,23 +64,19 @@ fun GenderList( GenderRow( gender = gender, onGenderClick = onGenderClick, - homeViewModel, + homeViewModel ) } } } @Composable -fun GenderRow( - gender: String, - onGenderClick: (gender: String) -> Unit, - homeViewModel: HomeViewModel, -) { +fun GenderRow(gender: String, onGenderClick: (gender: String) -> Unit, homeViewModel: HomeViewModel) { Row( modifier = Modifier .fillMaxWidth() - .padding(all = 8.dp), + .padding(all = 8.dp) ) { Surface( shape = RoundedCornerShape(8.dp), @@ -95,13 +85,13 @@ fun GenderRow( Modifier.clickable { homeViewModel.updateCategories(gender) onGenderClick(gender) - }, + } ) { Row( modifier = Modifier .fillMaxWidth() - .padding(all = 8.dp), + .padding(all = 8.dp) ) { Text( text = gender, @@ -109,7 +99,7 @@ fun GenderRow( Modifier .weight(1f) .align(Alignment.CenterVertically) - .padding(8.dp), + .padding(8.dp) ) Column(horizontalAlignment = Alignment.End) { Image( @@ -120,7 +110,7 @@ fun GenderRow( painter = painterResource(id = R.drawable.baseline_navigate_next_24), alignment = Alignment.Center, contentDescription = "", - contentScale = ContentScale.Crop, + contentScale = ContentScale.Crop ) } } diff --git a/app/src/main/java/com/movableink/app/ui/screens/home/HomeViewModel.kt b/app/src/main/java/com/movableink/app/ui/screens/home/HomeViewModel.kt index b750b79..77b1f25 100644 --- a/app/src/main/java/com/movableink/app/ui/screens/home/HomeViewModel.kt +++ b/app/src/main/java/com/movableink/app/ui/screens/home/HomeViewModel.kt @@ -11,21 +11,18 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update -class HomeViewModel( - private val repository: MovableRepository, -) : ViewModel() { +class HomeViewModel(private val repository: MovableRepository) : ViewModel() { private val _homeUIState = MutableStateFlow(HomeState()) val homeUIState: StateFlow = _homeUIState.asStateFlow() - private fun fetchCategories(gender: String) = - repository.getCategoriesByGender(gender) + private fun fetchCategories(gender: String) = repository.getCategoriesByGender(gender) fun updateCategories(gender: String) { val lowerCase = gender.toLowerCase(Locale.current) val categories = fetchCategories(lowerCase) _homeUIState.update { currentState -> currentState.copy( categories = categories, - gender = lowerCase, + gender = lowerCase ) } } @@ -35,14 +32,14 @@ class HomeViewModel( _homeUIState.update { currentState -> currentState.copy( - catalog = catalog, + catalog = catalog ) } } fun updateSelectedProduct(product: String) { _homeUIState.update { currentState -> currentState.copy( - selectedProductId = product, + selectedProductId = product ) } } @@ -51,13 +48,9 @@ class HomeViewModel( _homeUIState.value = HomeState() } companion object { - fun provideFactory( - movableRepository: MovableRepository = MovableRepository, - ): ViewModelProvider.Factory = object : ViewModelProvider.Factory { + fun provideFactory(movableRepository: MovableRepository = MovableRepository): ViewModelProvider.Factory = object : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") - override fun create(modelClass: Class): T { - return HomeViewModel(movableRepository) as T - } + override fun create(modelClass: Class): T = HomeViewModel(movableRepository) as T } } @@ -65,6 +58,6 @@ class HomeViewModel( val categories: List = arrayListOf(), val catalog: List = arrayListOf(), val gender: String = "", - val selectedProductId: String = "", + val selectedProductId: String = "" ) } diff --git a/app/src/main/java/com/movableink/app/ui/screens/home/ProductDetailScreen.kt b/app/src/main/java/com/movableink/app/ui/screens/home/ProductDetailScreen.kt index 7b116ba..1997de7 100644 --- a/app/src/main/java/com/movableink/app/ui/screens/home/ProductDetailScreen.kt +++ b/app/src/main/java/com/movableink/app/ui/screens/home/ProductDetailScreen.kt @@ -28,7 +28,7 @@ import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember @@ -54,11 +54,7 @@ import com.movableink.app.utils.getDrawableId val BottomBarHeight = 56.dp @Composable -fun ProductDetailScreen( - popBackStack: () -> Unit, - viewModel: CartViewModel, - homeViewModel: HomeViewModel, -) { +fun ProductDetailScreen(popBackStack: () -> Unit, viewModel: CartViewModel, homeViewModel: HomeViewModel) { val homeUIState by homeViewModel.homeUIState.collectAsStateWithLifecycle() val productId = homeUIState.selectedProductId val product = remember { MovableRepository.getProductById(productId) } @@ -67,18 +63,13 @@ fun ProductDetailScreen( CartBottomBar(modifier = Modifier.align(Alignment.BottomCenter), viewModel, product, popBackStack) DetailTopBar( product = product, - onBackClicked = popBackStack, + onBackClicked = popBackStack ) } } @Composable -private fun CartBottomBar( - modifier: Modifier = Modifier, - viewModel: CartViewModel, - product: Product?, - onCartUpdate: () -> Unit, -) { +private fun CartBottomBar(modifier: Modifier = Modifier, viewModel: CartViewModel, product: Product?, onCartUpdate: () -> Unit) { Surface(modifier) { Column { ScreenDivider() @@ -87,7 +78,7 @@ private fun CartBottomBar( modifier = Modifier .navigationBarsPadding() .then(Modifier.padding(horizontal = 24.dp)) - .heightIn(min = BottomBarHeight), + .heightIn(min = BottomBarHeight) ) { Spacer(Modifier.width(16.dp)) Button( @@ -98,13 +89,13 @@ private fun CartBottomBar( }, modifier = Modifier .weight(1f) - .padding(all = 18.dp), + .padding(all = 18.dp) ) { Text( text = stringResource(id = R.string.addToCart), modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center, - maxLines = 1, + maxLines = 1 ) } Spacer(Modifier.width(16.dp)) @@ -114,15 +105,11 @@ private fun CartBottomBar( } @Composable -fun ScreenDivider( - modifier: Modifier = Modifier, - color: Color = Color.Gray, - thickness: Dp = 1.dp, -) { +fun ScreenDivider(modifier: Modifier = Modifier, color: Color = Color.Gray, thickness: Dp = 1.dp) { Divider( modifier = modifier, color = color, - thickness = thickness, + thickness = thickness ) } @@ -131,13 +118,13 @@ fun DetailsView(product: Product?) { LazyColumn( modifier = Modifier .fillMaxSize() - .padding(16.dp, 16.dp, 16.dp, 0.dp), + .padding(16.dp, 16.dp, 16.dp, 0.dp) ) { item { Spacer( Modifier.windowInsetsTopHeight( - WindowInsets.statusBars.add(WindowInsets(top = 60.dp)), - ), + WindowInsets.statusBars.add(WindowInsets(top = 60.dp)) + ) ) product.apply { val drawable = getDrawableId(product?.imageUrl.toString()) ?: R.drawable.placeholder @@ -149,7 +136,7 @@ fun DetailsView(product: Product?) { painter = image, alignment = Alignment.CenterStart, contentDescription = "", - contentScale = ContentScale.Crop, + contentScale = ContentScale.Crop ) Spacer(modifier = Modifier.height(16.dp)) Text( @@ -157,7 +144,7 @@ fun DetailsView(product: Product?) { modifier = Modifier.padding(0.dp, 0.dp, 12.dp, 0.dp), color = Color.Black, fontWeight = FontWeight.Bold, - style = MaterialTheme.typography.h6, + style = MaterialTheme.typography.h6 ) } } @@ -170,7 +157,7 @@ fun DetailTopBar(modifier: Modifier = Modifier, product: Product?, onBackClicked TopAppBar( backgroundColor = MaterialTheme.colors.primaryVariant, contentColor = Color.Black, - elevation = 0.dp, + elevation = 0.dp ) { IconButton( @@ -178,12 +165,12 @@ fun DetailTopBar(modifier: Modifier = Modifier, product: Product?, onBackClicked modifier = Modifier .padding(all = 8.dp) .size(24.dp, 24.dp) - .align(Alignment.CenterVertically), + .align(Alignment.CenterVertically) ) { Icon( - imageVector = Icons.Default.ArrowBack, + imageVector = Icons.AutoMirrored.Filled.ArrowBack, tint = Color.White, - contentDescription = stringResource(R.string.app_name), + contentDescription = stringResource(R.string.app_name) ) } Text( @@ -196,7 +183,7 @@ fun DetailTopBar(modifier: Modifier = Modifier, product: Product?, onBackClicked modifier = Modifier .weight(1f) .padding(8.dp, 0.dp, 0.dp, 0.dp) - .align(Alignment.CenterVertically), + .align(Alignment.CenterVertically) ) } } diff --git a/app/src/main/java/com/movableink/app/ui/screens/search/Search.kt b/app/src/main/java/com/movableink/app/ui/screens/search/Search.kt index defad06..9d2b5c8 100644 --- a/app/src/main/java/com/movableink/app/ui/screens/search/Search.kt +++ b/app/src/main/java/com/movableink/app/ui/screens/search/Search.kt @@ -26,12 +26,7 @@ import com.movableink.app.ui.component.SearchProductList import com.movableink.app.ui.screens.home.HomeViewModel @Composable -fun Search( - onSearchBarClick: () -> Unit, - searchViewModel: SearchViewModel, - homeViewModel: HomeViewModel, - navigateToProductDetail: (String) -> Unit, -) { +fun Search(onSearchBarClick: () -> Unit, searchViewModel: SearchViewModel, homeViewModel: HomeViewModel, navigateToProductDetail: (String) -> Unit) { val products by searchViewModel.products.collectAsStateWithLifecycle() Column(modifier = Modifier.fillMaxSize()) { SearchViewBar(onSearchBarClick) @@ -43,7 +38,7 @@ fun Search( .padding(10.dp), fontWeight = FontWeight.Bold, fontSize = 18.sp, - textAlign = TextAlign.Center, + textAlign = TextAlign.Center ) SearchProductList(products = products) { product -> @@ -58,11 +53,11 @@ fun SearchViewBar(onSearchBarClick: () -> Unit) { TopAppBar(title = { Text("Search Products") }, actions = { IconButton( modifier = Modifier, - onClick = onSearchBarClick, + onClick = onSearchBarClick ) { Icon( Icons.Filled.Search, - contentDescription = stringResource(id = R.string.app_name), + contentDescription = stringResource(id = R.string.app_name) ) } }) diff --git a/app/src/main/java/com/movableink/app/ui/screens/search/SearchView.kt b/app/src/main/java/com/movableink/app/ui/screens/search/SearchView.kt index 358281c..22fef56 100644 --- a/app/src/main/java/com/movableink/app/ui/screens/search/SearchView.kt +++ b/app/src/main/java/com/movableink/app/ui/screens/search/SearchView.kt @@ -13,12 +13,7 @@ import com.movableink.app.utils.rememberFlowWithLifecycle @OptIn(ExperimentalAnimationApi::class, ExperimentalComposeUiApi::class) @Composable -fun SearchView( - onBackClicked: () -> Unit, - viewModel: SearchViewModel, - navigateToProductDetail: (String) -> Unit, - homeViewModel: HomeViewModel, -) { +fun SearchView(onBackClicked: () -> Unit, viewModel: SearchViewModel, navigateToProductDetail: (String) -> Unit, homeViewModel: HomeViewModel) { val productSearchModelState by rememberFlowWithLifecycle(viewModel.productSearchModelState) .collectAsState(initial = ProductSearchModelState.Empty) MovableSearchBar( @@ -32,6 +27,6 @@ fun SearchView( onResultClick = { navigateToProductDetail(it) }, - homeViewModel, + homeViewModel ) } diff --git a/app/src/main/java/com/movableink/app/ui/screens/search/SearchViewModel.kt b/app/src/main/java/com/movableink/app/ui/screens/search/SearchViewModel.kt index 8c97b23..aac49dc 100644 --- a/app/src/main/java/com/movableink/app/ui/screens/search/SearchViewModel.kt +++ b/app/src/main/java/com/movableink/app/ui/screens/search/SearchViewModel.kt @@ -4,14 +4,13 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import com.movableink.app.data.model.Product import com.movableink.app.data.repository.MovableRepository +import java.util.ArrayList import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine -import java.util.ArrayList class SearchViewModel -(private val repository: MovableRepository) : - ViewModel() { +(private val repository: MovableRepository) : ViewModel() { private val _products: MutableStateFlow> = MutableStateFlow(repository.getProducts()) @@ -26,13 +25,13 @@ class SearchViewModel val productSearchModelState = combine( searchText, matchedProducts, - showProgressBar, + showProgressBar ) { text, matchedProducts, showProgress -> ProductSearchModelState( text, matchedProducts, - showProgress, + showProgress ) } @@ -56,9 +55,10 @@ class SearchViewModel } val productsFromSearch = allProducts.filter { product -> product.name.contains(changedSearchText, true) || - product.category.contains(changedSearchText, true) || product.gender.contains( + product.category.contains(changedSearchText, true) || + product.gender.contains( changedSearchText, - true, + true ) } @@ -70,22 +70,14 @@ class SearchViewModel matchedProducts.value = arrayListOf() } companion object { - fun provideFactory( - movableRepository: MovableRepository = MovableRepository, - ): ViewModelProvider.Factory = object : ViewModelProvider.Factory { + fun provideFactory(movableRepository: MovableRepository = MovableRepository): ViewModelProvider.Factory = object : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") - override fun create(modelClass: Class): T { - return SearchViewModel(movableRepository) as T - } + override fun create(modelClass: Class): T = SearchViewModel(movableRepository) as T } } } -data class ProductSearchModelState( - val searchText: String = "", - val products: List = arrayListOf(), - val showProgressBar: Boolean = false, -) { +data class ProductSearchModelState(val searchText: String = "", val products: List = arrayListOf(), val showProgressBar: Boolean = false) { companion object { val Empty = ProductSearchModelState() diff --git a/app/src/main/java/com/movableink/app/ui/theme/Color.kt b/app/src/main/java/com/movableink/app/ui/theme/Color.kt index 865adbe..b5335e7 100644 --- a/app/src/main/java/com/movableink/app/ui/theme/Color.kt +++ b/app/src/main/java/com/movableink/app/ui/theme/Color.kt @@ -14,4 +14,4 @@ val pinkText = Color(0xFFF5CAC9) val card = Color(0xFFFFFFFF) val cardNight = Color(0xFF162544) -const val AlphaNearOpaque = 0.95f +const val ALPHA_NEAR_OPAQUE = 0.95f diff --git a/app/src/main/java/com/movableink/app/ui/theme/Shape.kt b/app/src/main/java/com/movableink/app/ui/theme/Shape.kt index 6b78b4b..91fc674 100644 --- a/app/src/main/java/com/movableink/app/ui/theme/Shape.kt +++ b/app/src/main/java/com/movableink/app/ui/theme/Shape.kt @@ -7,5 +7,5 @@ import androidx.compose.ui.unit.dp val Shapes = Shapes( small = RoundedCornerShape(4.dp), medium = RoundedCornerShape(4.dp), - large = RoundedCornerShape(0.dp), + large = RoundedCornerShape(0.dp) ) diff --git a/app/src/main/java/com/movableink/app/ui/theme/Theme.kt b/app/src/main/java/com/movableink/app/ui/theme/Theme.kt index d534c74..da2c716 100644 --- a/app/src/main/java/com/movableink/app/ui/theme/Theme.kt +++ b/app/src/main/java/com/movableink/app/ui/theme/Theme.kt @@ -14,13 +14,13 @@ import androidx.compose.ui.graphics.TileMode private val DarkColorPalette = darkColors( primary = Purple200, primaryVariant = Purple700, - secondary = Teal200, + secondary = Teal200 ) private val LightColorPalette = lightColors( primary = Purple500, primaryVariant = Purple700, - secondary = Teal200, + secondary = Teal200 ) @@ -36,18 +36,14 @@ fun ShoppingCartTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Comp colors = colors, typography = typography, shapes = Shapes, - content = content, + content = content ) } -fun Modifier.offsetGradientBackground( - colors: List, - width: Float, - offset: Float = 0f, -) = background( +fun Modifier.offsetGradientBackground(colors: List, width: Float, offset: Float = 0f) = background( Brush.horizontalGradient( colors, startX = -offset, endX = width - offset, - tileMode = TileMode.Mirror, - ), + tileMode = TileMode.Mirror + ) ) diff --git a/app/src/main/java/com/movableink/app/ui/theme/Type.kt b/app/src/main/java/com/movableink/app/ui/theme/Type.kt index 2a9f5db..5536c2d 100644 --- a/app/src/main/java/com/movableink/app/ui/theme/Type.kt +++ b/app/src/main/java/com/movableink/app/ui/theme/Type.kt @@ -11,7 +11,7 @@ import com.movableink.app.R private val fontFamily = FontFamily( Font(R.font.oswald_bold), Font(R.font.oswald_medium, FontWeight.W500), - Font(R.font.oswald_regular, FontWeight.Bold), + Font(R.font.oswald_regular, FontWeight.Bold) ) // Set of Material typography styles to start with @@ -19,52 +19,52 @@ val typography = Typography( h4 = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.W600, - fontSize = 30.sp, + fontSize = 30.sp ), h5 = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.W600, - fontSize = 24.sp, + fontSize = 24.sp ), h6 = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.W600, - fontSize = 20.sp, + fontSize = 20.sp ), subtitle1 = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.W500, - fontSize = 16.sp, + fontSize = 16.sp ), subtitle2 = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.W500, - fontSize = 14.sp, + fontSize = 14.sp ), body1 = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.Normal, - fontSize = 16.sp, + fontSize = 16.sp ), body2 = TextStyle( fontFamily = fontFamily, fontSize = 14.sp, - lineHeight = 20.sp, + lineHeight = 20.sp ), button = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.W500, - fontSize = 14.sp, + fontSize = 14.sp ), caption = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.Normal, - fontSize = 12.sp, + fontSize = 12.sp ), overline = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.W500, - fontSize = 12.sp, + fontSize = 12.sp - ), + ) ) diff --git a/app/src/main/java/com/movableink/app/utils/FetchDrawableByName.kt b/app/src/main/java/com/movableink/app/utils/FetchDrawableByName.kt index eb66887..c5fe266 100644 --- a/app/src/main/java/com/movableink/app/utils/FetchDrawableByName.kt +++ b/app/src/main/java/com/movableink/app/utils/FetchDrawableByName.kt @@ -12,17 +12,15 @@ fun fetchDrawableByName(name: String, context: Context): Int { return resources.getIdentifier( name.trim(), "drawable", - context.packageName, + context.packageName ) } // TODO refactor to this method -fun getDrawableId(name: String): Int? { - return try { - val res: Class<*> = R.drawable::class.java - val idField = res.getField(name) - idField.getInt(idField) - } catch (exception: Exception) { - Log.e("Movable Ink", "Failure to get drawable id.", exception) - } +fun getDrawableId(name: String): Int? = try { + val res: Class<*> = R.drawable::class.java + val idField = res.getField(name) + idField.getInt(idField) +} catch (exception: Exception) { + Log.e("Movable Ink", "Failure to get drawable id.", exception) } diff --git a/app/src/main/java/com/movableink/app/utils/FlowWithLifeCycle.kt b/app/src/main/java/com/movableink/app/utils/FlowWithLifeCycle.kt index 302c68a..4a1277e 100644 --- a/app/src/main/java/com/movableink/app/utils/FlowWithLifeCycle.kt +++ b/app/src/main/java/com/movableink/app/utils/FlowWithLifeCycle.kt @@ -1,4 +1,6 @@ -package com.movableink.app.utils // ktlint-disable filename +@file:Suppress("ktlint:standard:filename") + +package com.movableink.app.utils /* * Copyright 2021 Google LLC @@ -18,8 +20,8 @@ package com.movableink.app.utils // ktlint-disable filename import androidx.compose.runtime.Composable import androidx.compose.runtime.remember -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.lifecycle.Lifecycle +import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.flowWithLifecycle import kotlinx.coroutines.flow.Flow @@ -27,10 +29,10 @@ import kotlinx.coroutines.flow.Flow fun rememberFlowWithLifecycle( flow: Flow, lifecycle: Lifecycle = LocalLifecycleOwner.current.lifecycle, - minActiveState: Lifecycle.State = Lifecycle.State.STARTED, + minActiveState: Lifecycle.State = Lifecycle.State.STARTED ): Flow = remember(flow, lifecycle) { flow.flowWithLifecycle( lifecycle = lifecycle, - minActiveState = minActiveState, + minActiveState = minActiveState ) } diff --git a/app/src/main/java/com/movableink/app/utils/PriceFormat.kt b/app/src/main/java/com/movableink/app/utils/PriceFormat.kt index 7c7078d..c07305c 100644 --- a/app/src/main/java/com/movableink/app/utils/PriceFormat.kt +++ b/app/src/main/java/com/movableink/app/utils/PriceFormat.kt @@ -1,10 +1,10 @@ -package com.movableink.app.utils // ktlint-disable filename +@file:Suppress("ktlint:standard:filename") + +package com.movableink.app.utils import java.math.BigDecimal import java.text.NumberFormat -fun formatPrice(price: Long): String { - return NumberFormat.getCurrencyInstance().format( - BigDecimal(price).movePointLeft(2), - ) -} +fun formatPrice(price: Long): String = NumberFormat.getCurrencyInstance().format( + BigDecimal(price).movePointLeft(2) +) diff --git a/app/src/main/java/com/movableink/app/utils/URIPath.kt b/app/src/main/java/com/movableink/app/utils/URIPath.kt index 6ab3d20..522f184 100644 --- a/app/src/main/java/com/movableink/app/utils/URIPath.kt +++ b/app/src/main/java/com/movableink/app/utils/URIPath.kt @@ -20,7 +20,9 @@ object URIPath { return segments[2] } - else -> { return@runCatching } + else -> { + return@runCatching + } } } return null diff --git a/build.gradle.kts b/build.gradle.kts index 2793e1c..7f3216b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,6 +10,7 @@ buildscript { dependencies { classpath(libs.android.gradlePlugin) classpath(libs.kotlin.gradlePlugin) + classpath(libs.kotlin.compose.gradlePlugin) classpath(libs.spotless.gradlePlugin) classpath(libs.google.services) } @@ -35,9 +36,3 @@ subprojects { tasks.register("hello") { group = "Custom" } - -buildScan { - setTermsOfServiceUrl("https://gradle.com/terms-of-service") - setTermsOfServiceAgree("yes") - publishAlways() -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3a3452a..18e8c42 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,9 +1,9 @@ [versions] # Build tools and plugins -kotlin = "1.8.22" -spotless = "6.12.1" -google-services = "4.3.15" -agp = "8.2.0" +kotlin = "2.1.21" +spotless = "8.0.0" +google-services = "4.4.2" +agp = "8.13.0" # AndroidX and Material appcompat = "1.6.1" @@ -13,10 +13,9 @@ constraintlayout = "2.1.4" material = "1.11.0" browser = "1.8.0" -# Compose -compose = "1.4.3" -compose-compiler = "1.4.8" # Compatible with Kotlin 1.8.22 -navigation-compose = "2.7.6" +# Compose (using BOM for version management) +compose-bom = "2024.12.01" +navigation-compose = "2.8.5" # Lifecycle lifecycle = "2.7.0" @@ -45,6 +44,7 @@ movableink = "1.6.2-SNAPSHOT" # Build plugins android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "agp" } kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } +kotlin-compose-gradlePlugin = { group = "org.jetbrains.kotlin", name = "compose-compiler-gradle-plugin", version.ref = "kotlin" } spotless-gradlePlugin = { group = "com.diffplug.spotless", name = "spotless-plugin-gradle", version.ref = "spotless" } google-services = { group = "com.google.gms", name = "google-services", version.ref = "google-services" } @@ -54,11 +54,13 @@ androidx-activity-ktx = { group = "androidx.activity", name = "activity-ktx", ve androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" } androidx-browser = { group = "androidx.browser", name = "browser", version.ref = "browser" } -# Compose -compose-material = { group = "androidx.compose.material", name = "material", version.ref = "compose" } -compose-ui = { group = "androidx.compose.ui", name = "ui", version.ref = "compose" } -compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "compose" } -compose-ui-util = { group = "androidx.compose.ui", name = "ui-util", version.ref = "compose" } +# Compose (using BOM) +compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" } +compose-material = { group = "androidx.compose.material", name = "material" } +compose-material-icons = { group = "androidx.compose.material", name = "material-icons-core" } +compose-ui = { group = "androidx.compose.ui", name = "ui" } +compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +compose-ui-util = { group = "androidx.compose.ui", name = "ui-util" } # Lifecycle lifecycle-runtime = { group = "androidx.lifecycle", name = "lifecycle-runtime", version.ref = "lifecycle" } @@ -109,11 +111,12 @@ mockito-kotlin = { group = "org.mockito.kotlin", name = "mockito-kotlin", versio android-application = { id = "com.android.application", version.ref = "agp" } android-library = { id = "com.android.library", version.ref = "agp" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } google-services = { id = "com.google.gms.google-services", version.ref = "google-services" } [bundles] -compose = ["compose-material", "compose-ui", "compose-ui-tooling", "compose-ui-util"] +compose = ["compose-material", "compose-material-icons", "compose-ui", "compose-ui-tooling", "compose-ui-util"] lifecycle = ["lifecycle-runtime", "lifecycle-runtime-compose", "lifecycle-runtime-ktx", "lifecycle-viewmodel", "lifecycle-viewmodel-compose"] test-implementation = ["junit"] android-test-implementation = ["test-junit", "test-core", "test-arch-core", "test-runner", "test-rules", "test-espresso", "mockito-core", "mockito-android", "mockito-kotlin"] \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 09523c0..d4081da 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/settings.gradle.kts b/settings.gradle.kts index fc6c8a6..7f05e68 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,12 +1,12 @@ plugins { - id("com.gradle.enterprise").version("3.8") + id("com.gradle.develocity").version("3.19") // id("de.fayard.refreshVersions") version "0.51.0" } -gradleEnterprise { +develocity { buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" + termsOfUseUrl.set("https://gradle.com/help/legal-terms-of-use") + termsOfUseAgree.set("yes") } } diff --git a/spotless.gradle b/spotless.gradle index 95d01d2..2922fc5 100644 --- a/spotless.gradle +++ b/spotless.gradle @@ -6,10 +6,12 @@ spotless { kotlin { target "**/*.kt" - ktlint('0.43.2').userData([ + ktlint('1.5.0').editorConfigOverride([ 'max_line_length': '150', - 'ij_kotlin_allow_trailing_comma' : false, - 'ij_kotlin_allow_trailing_comma_on_call_site' : false + 'ktlint_code_style': 'android_studio', + 'ij_kotlin_allow_trailing_comma': 'false', + 'ij_kotlin_allow_trailing_comma_on_call_site': 'false', + 'ktlint_function_naming_ignore_when_annotated_with': 'Composable' ]) trimTrailingWhitespace() indentWithSpaces() From f92a9c054452270f67e9fd2065224ff6b72a0e9d Mon Sep 17 00:00:00 2001 From: Graydyn Date: Wed, 24 Dec 2025 15:32:40 -0500 Subject: [PATCH 2/2] remove redundant toolchain check --- app/build.gradle.kts | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a946278..c12b135 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -7,9 +7,6 @@ plugins { apply(from = "android.gradle") -kotlin { - jvmToolchain(17) -} dependencies { // Compose BOM